window.setUserCurPosition = function (userCurPosition) {
if (vMap.value) {
vMap.value.removeLayer(uerVectorLayer.value);
}
const resultList = userCurPosition.split(" ");
// 여기서 부터
userCurPositionData.value[0] = resultList[1] ?? 최도위도;
userCurPositionData.value[1] = resultList[3] ?? 최초경도;
userCurHeading.value = resultList[5];
// 여기까지는 본인이 JS channel로 넘겨줄 양식에 맞춰 데이터를 뽑으면 됨.
userStore.refreshUserPosition();
if (vMap.value) {
vMap.value.addLayer(uerVectorLayer.value);
}
};
parse()
함수를 이용하여 json 객체를 처리하면 된다.userStore.refreshUserPosition();
함수가 그 역할을 맡고있다.const refreshUserPosition = () => {
userFeature.value = new Feature({
geometry: new Point(fromLonLat([userCurPositionData.value[0], userCurPositionData.value[1]],
getProjection("EPSG:3857"))),
});
userFeature.value.setStyle(
new Style({
image: new Icon({
src: "/assets/ico_wind_S.png",
rotation: userCurHeading.value * Math.PI / 180
}),
})
);
userVectorSource.value = new VectorSource({
features: [userFeature.value],
});
uerVectorLayer.value = new VectorLayer({
source: userVectorSource.value,
});
}
userCurPositionData 변수에 저장되어있는 값을 가져와서 Feature를 만들어주고 해당 피쳐에 스타일을 입혀주는데 여기서 ratation 속성값을 이용하여 사용자가 보는 방향을 라디안을 쳐서 계산해주면 된다.
그리고 벡터 소스를 만들고 해당 소스로 벡터 레이어를 만든다음 그 레이러를 map 객체에 추가하면 되는데 이 과정은 이전 포스팅을 참조하면 된다.
@override
Widget build(BuildContext context) {
return DefaultLayout(
// futurubuild를 이용하여 permission에 따라 다른 UI 뿌려주기
child: FutureBuilder(
future: checkPermission(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
// 여기가 snapshot(checkPermission 반환 값)으로 확인하는 부분.
if (snapshot.data == '위치 권한이 허가되었습니다.') {
// 여기서 future와 한 끝 차이인 streambuilder로 값을 지속적으로 보내기
return StreamBuilder<Position>(
stream: Geolocator.getPositionStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
curPosition = snapshot.data;
// 바로 이부분이 web의 window함수로 값을 던져주는 부분.
webViewController.runJavaScript(
'window.setUserCurPosition("lon: ${curPosition?.longitude} lat: ${curPosition?.latitude} heading: ${curPosition?.heading}")');
}
// permission ok 라면 웹뷰 보여주기
return WebViewWidget(
controller: webViewController,
);
},
);
}
// 위치 권한이 주어지지 않았다면(permission not ok 라면) setting으로 안내
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
title: const Column(
children: <Widget>[
Text("알림"),
],
),
content: const Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"위치 서비스를 동의해 주세요. \n설정 -> Temp -> Location -> 허용",
),
],
),
actions: <Widget>[
TextButton(
child: const Text("설정"),
onPressed: () {
AppSettings.openAppSettings();
},
),
],
);
}),
);
}
}
Future checkPermission() async {
final isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnabled) {
return '위치 서비스를 활성화 해주세요.';
}
LocationPermission checkPermission = await Geolocator.checkPermission();
if (checkPermission == LocationPermission.denied) {
checkPermission = await Geolocator.requestPermission();
if (checkPermission == LocationPermission.denied) {
return '위치 권한을 허가해주세요.';
}
}
if (checkPermission == LocationPermission.deniedForever) {
return '앱의 위치 권한을 세팅에서 허가해주세요.';
}
return '위치 권한이 허가되었습니다.';
}