develop/Flutter

Flutter naver map 현재 위치 표시 및 방향 나타내기

방뎁 2025. 4. 8. 23:02

NLocationOverlay 는 아래 공식 문서에 따라 현재 위치 오버레이이다. 

https://navermaps.github.io/android-map-sdk/guide-ko/5-5.html

 

위치 오버레이 · 네이버 지도 안드로이드 SDK

위치 오버레이 위치 오버레이는 사용자의 위치를 나타내는 데 특화된 오버레이이로, 지도상에 단 하나만 존재합니다. 마커와 유사하게 아이콘을 사용해 사용자의 위치를 나타낼 수 있습니다.

navermaps.github.io

 

flutter 에서도 동일하게 사용할 수 있다. 

 

필요한 패키지는 2개

flutter_naver_map

https://pub.dev/packages/flutter_naver_map

 

flutter_naver_map | Flutter package

Naver Map plugin for Flutter, which provides map service of Korea.

pub.dev

 

geolocator

https://pub.dev/packages/geolocator

 

geolocator | Flutter package

Geolocation plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API for generic location (GPS etc.) functions.

pub.dev

 

Geolocator.getPositionStream 을 사용한다면 아래와 같이 사용하면 된다.

이건 해당 패키지 확인하여 사용하면 된다.

  getPositionStream(context).listen((Position position) async {
    locationOverlay.value?.setPosition(NLatLng(position.latitude, position.longitude));
    locationOverlay.value?.setBearing(position.heading);
  });

 

객체 가져오기

locationOverlay = mapController.getLocationOverlay();

 

locationOverlay.setIcon(NOverlayImage.fromAssetImage("")); // 현재 위치 아이콘 - 아이콘 설정 안하면 기본 
locationOverlay.setIconSize(const Size.square(24)); // 현재 위치 아이콘 사이즈
locationOverlay.setCircleRadius(20.0); // 현재 위치 근처 Circle
locationOverlay.setCircleColor(Colors.blue.withOpacity(0.3)); // 현재 위치 근처 Circle 색상
locationOverlay.setSubIcon(NOverlayImage.fromAssetImage(""));
locationOverlay.setSubIconSize(const Size(15, 15)); // 방향 아이콘 (sub icon)
locationOverlay.setSubAnchor(const NPoint(0.5, 1)); // 방향 아이콘 Anchor
if (currentLocation.heading != null) {
	// 방향
	locationOverlay.setBearing(currentLocation.heading); // Position heading 호출 
} else {
	locationOverlay.setBearing(0);
}
locationOverlay.setIsVisible(true);
// 현재 위치 전달
locationOverlay.setPosition(NLatLng(currentLocation.latitude, currentLocation.longitude));

 

 

종합적으로 정리하자면, 

import 'package:flutter/material.dart';
import 'package:flutter_naver_map/flutter_naver_map.dart';
import 'package:geolocator/geolocator.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late NaverMapController mapController;
  late LocationPermission permission;
  Position? position;
  late NLocationOverlay locationOverlay;

  @override
  void initState() {
    super.initState();
    getCurrentPosition();
  }

  getCurrentPosition() async {
    bool serviceEnabled;
    serviceEnabled = await Geolocator.isLocationServiceEnabled();

    if (!serviceEnabled) {
      await Geolocator.openAppSettings();
    }

    permission = await Geolocator.checkPermission();

    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        await Geolocator.openAppSettings();
      }
    }

    if (permission == LocationPermission.deniedForever) {
      await Geolocator.openAppSettings();
    }

    position = await Geolocator.getCurrentPosition();
  }

  @override
  Widget build(BuildContext context) {
    return NaverMap(
      options: const NaverMapViewOptions(locationButtonEnable: true),
      onMapReady: (controller) {
        mapController = controller;

        locationOverlay = mapController.getLocationOverlay();

        // locationOverlay.setIcon(NOverlayImage.fromAssetImage("")); // 현재 위치 아이콘 - 아이콘 설정 안하면 기본
        locationOverlay.setIconSize(const Size.square(24)); // 현재 위치 아이콘 사이즈
        locationOverlay.setCircleRadius(20.0); // 현재 위치 근처 Circle
        locationOverlay
            .setCircleColor(Colors.blue.withOpacity(0.3)); // 현재 위치 근처 Circle 색상
        locationOverlay
            .setSubIcon(NOverlayImage.fromAssetImage("assets/sub.png"));
        locationOverlay.setSubIconSize(const Size(15, 15)); // 방향 아이콘 (sub icon)
        locationOverlay.setSubAnchor(const NPoint(0.5, 1)); // 방향 아이콘 Anchor
        if (position?.heading != null) {
          // 방향
          locationOverlay.setBearing(position!.heading!); // Position heading 호출
          locationOverlay
              .setPosition(NLatLng(position!.latitude, position!.longitude));
        } else {
          locationOverlay.setBearing(0);
        }
        locationOverlay.setIsVisible(true);
      },
    );
  }
}

 

setBearing 이 방향을 결정한다.