flutter openlayers vue.js 사용자 위치 표시하기

강정우·2023년 11월 2일
0

Flutter&Dart

목록 보기
76/87

프로젝트 시작점에 미리 window 함수 등록해두기

  • front-end 프레임웤이 시작되는 지점에서 flutter에서 넘겨줄 값을 저장하는 코드를 작성해 둔다.
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);
  }
};
  • 참고로 위 코드에서는 변리하게 문자열 공백을 기준으로 나누었다. 왜냐하면 flutter에서 넘겨줄 값이 항상 같은 양식으로 넘올 것이기 때문이다.
    만약 양식이 변동이 있는 경우에는 flutter에서 string으로 json객체를 만들어서 넘겨준 다음
    주석 사이의 코드를 삭제하고 parse() 함수를 이용하여 json 객체를 처리하면 된다.

넘어온 값을 UI에 반영하기 위한 함수 작성하기

  • 위에서 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 객체에 추가하면 되는데 이 과정은 이전 포스팅을 참조하면 된다.

flutter에서 geolocator를 이용하여 사용자 정보를 가져오기

  • 우선 여기서 고려해봐야할 것은 1. 사용자의 위치정보를 받을 때 마다 web 단으로 던져줘야한다. 2. 사용자의 위치 permission을 요청하고 요청 되어야만 동작할 수 있도록 해야한다.

@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 '위치 권한이 허가되었습니다.';
}
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글