본문 바로가기

프론트엔드/Flutter

[Flutter] Flutter_map package를 사용해 지도 구현하기

안녕하세요, 황대성입니다.

이번 글에서는 Flutter_map package를 사용하여 지도를 구현하는 방법에 대해 포스팅하려합니다.

 

준비물

Flutter Map Package:   pub.dev/packages/flutter_map

Geolocator Package:   pub.dev/packages/geolocator

 

위 두 Package를 설치합니다.

Flutter Map은 leaflet기반으로 구성되어있는 지도를 그려주는 라이브러리입니다.

Geolocator는 현재 사용자의 위치를 받아오기 위해 사용하는 라이브러리입니다.


제일 먼저 현재 위치를 받아오는 코드를 구현해봅시다.

import 'package:geolocator/geolocator.dart';

class Map extends StatefulWidget{
  _MapState createState() => _MapState();
}

class _MapState extends State<Map>{
  double centerLng;
  double centerLat;
    
  @override
  void initState() {
    super.initState();
    loading = true;
    getPosition();
  }

  getPosition() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.best);
    try {
      setState(() {
        centerLng = position.longitude;
        centerLat = position.latitude;
        loading = false;
      });
    } on PlatformException catch (e) {
      print(e);
    }
  }
}

getPosition 함수를 initState에서 불러옴으로써 Widget이 빌드되기전에 현재 위치를 받아옵니다.

getCurrentPosition함수로 현재 위치를 받아오고,

try & catch문을 사용하여 받아오면 현재 위치를 state에 저장하고, 오류가 발생하면 print합니다.

 

사용자가 위치정보를 받아오는 것을 허용해주어야 현재 위치를 불러올 수 있습니다.

그래서 사용자에게 위치정보를 받아오는 것을 허용할 것인지 물어봐야합니다.

 

IOS

Info.plist 파일에 아래의 코드를 복사하여 붙여넣어줍니다.

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>

Android

AndroidMainfest.xml의 아래의 코드를 복사하여 붙여넣어줍니다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

위 단계까지 한다면 성공적으로 현재 위치를 불러올 수 있습니다.


이제 지도를 붙여봅시다.

 

저는 줌버튼과 현재 위치를 불러오는 버튼을 사용하기위해 Stack으로 구현하였습니다.

지도만 사용하실 분은 Stack 코드 안에 FlutterMap코드만 사용하면 됩니다.

Stack(
  alignment: Alignment.bottomRight,
  children: <Widget>[
    FlutterMap(
      mapController: mapController,
      options: MapOptions(
        zoom: currentZoom,
        maxZoom: 18.0,
        minZoom: 2.0,
        center: LatLng(centerLat, centerLng)),
        layers: [
          TileLayerOptions(
            urlTemplate:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
            subdomains: ['a', 'b', 'c']),
            MarkerLayerOptions(markers: [
              Marker(
                width: 30.0,
                height: 30.0,
                point: LatLng(centerLat, centerLng),
                builder: (context) => Container(
                  child: Image.asset('images/map/blue.blank.png'),
                ))
            ])
         ],
    ),
    Container(
      padding: EdgeInsets.only(right: 9),
      child: Column(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.only(
              top: MediaQuery.of(context).size.height *0.34)),
          Zoom(
            onClickIn: () {
              if (currentZoom == 18.0) {
                return null;
              } else {
                this.setState(() {
                  currentZoom += 1;
              });
            }
          mapController.move(mapController.center, currentZoom);
          },
          onClickOut: () {
            if (currentZoom == 2.0) {
              return null;
            } else {
              this.setState(() {
                currentZoom -= 1;
              });
          }
          mapController.move(mapController.center, currentZoom);
        },
      ),
     ],
   )),
   Container(
     padding: EdgeInsets.only(right: 9),
     child: Column(
       mainAxisAlignment: MainAxisAlignment.end,
       children: <Widget>[
         Location(onClickLocation: () {
           mapController.move(LatLng(centerLat, centerLng), currentZoom);}),
           Padding(padding: EdgeInsets.only(bottom: 85))
        ],
      ),
    )
  ],
)

위 코드를 사용하여 지도를 구현합니다.


이상으로 Flutter_Map Package를 사용하여 Flutter에서 지도를 구현하는 방법이였습니다.

본문을 읽다가 궁금한점이 생기면 편안하게 댓글 남겨주세요!

최대한 자세하게 설명드리겠습니다!

오늘도 긴 글 읽어주셔서 감사합니다.

 

참고한 사이트

Flutter Map Package:   pub.dev/packages/flutter_map

Geolocator Package:   pub.dev/packages/geolocator

 

Flutter: Getting a User's Location with the Geolocator Plugin

 www.digitalocean.com/community/tutorials/flutter-geolocator-plugin