네이버 지도 API v3는 Flutter에서 IOS와 Android는 플러그인과 WebView를 이용해 사용할 수 있지만, 플러그인이 웹 환경을 지원하지 않아 네이버 지도를 띄울 수 없습니다.
Web Dynamic Map 서비스가 있지만, JavaScript로만 작동해서 Flutter에서 바로 사용할 수가 없습니다.
하지만 IFrameElement를 이용하면 웹 환경에서도 네이버 지도를 사용할 수 있게 됩니다.
이번 포스트에서는 API 사용 설정부터 웹 환경에서 네이버 지도 사용하는 방법까지 작성해보겠습니다.
https://www.ncloud.com/product/applicationService/maps
네이버 지도 API
이용 신청하기 및 결제 수단 등록이 끝나면 콘솔 창으로 넘어가게 됩니다.우측 화면 하단 Application 등록 버튼을 눌러줍니다.
Application 이름과 사용할 API인 Web Dynamic Map을 선택해줍니다.
서비스 환경 등록 부분은 반드시 웹서버 URL일 필요는 없습니다. Flutter Web 빌드 시의 #을 제외한 localhost와 포트 번호를 적어주면 됩니다.
(이 말은 빌드할 때마다 설정에서 URL을 변경해주셔야 한다는 말이기도 합니다.)
저장 버튼을 누르면 API 설정은 끝났습니다.
설정 후, 콘솔 화면에서 인증 정보 버튼을 클릭해줍니다.인증 정보의 Client ID가 있어야 지도 API를 사용할 수 있습니다. 나중에 사용할 정보이기 때문에 일단 저장해두도록 하겠습니다.
assets:
- assets/
pubspec.yaml 파일에서 에셋 경로를 추가해주고, Flutter 프로젝트 Root 폴더에도 assets 폴더를 생성해줍니다.
다음, assets/map.html 파일을 생성해준 다음, 아래와 같이 작성해줍니다.
<script type="text/javascript" src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=CLIENT_ID"></script>
<div id="map" style="width:100%;height:400px;"></div>
<script>
var mapOptions = {
center: new naver.maps.LatLng(35.855746, 128.489024),
zoom: 16
};
var map = new naver.maps.Map('map', mapOptions);
var marker = new naver.maps.Marker({
position: new naver.maps.LatLng(35.855746, 128.489024),
title: '계명대학교',
map: map
});
var contentString = [
'<div class="iw_inner" style="padding: 0px 20px 0px 20px">',
' <h3>계명대학교</h3>',
' <p>대구 달서구 신당동 산40-1<br>053-580-5114',
' </p>',
'</div>'
].join('');
var infowindow = new naver.maps.InfoWindow({
content: contentString
});
naver.maps.Event.addListener(marker, "click", function (e) {
if (infowindow.getMap()) {
infowindow.close();
} else {
infowindow.open(map, marker);
}
});
infowindow.open(map, marker);
</script>
필자는 계명대학교 출신이 아닐겁니다.
src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=CLIENT_ID"
이 부분의 CLIENT_ID에 아까 네이버 API 콘솔에서 저장해 둔 Client ID를 입력해줍니다.
자세한 API 사용법은 NAVER Maps JavaScript API v3를 참고해주세요.
import 'dart:ui' as ui;
import 'dart:html';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
// assets/map.html에서 작성한 네이버 지도 API 호출 후
// 응답받은 iframe을 IFrameElement라는 Flutter Widget으로 등록
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'naver-map',
(int viewId) => IFrameElement()
..style.width = '100%'
..style.height = '100%'
..src = 'assets/map.html'
..style.border = 'none',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('네이버 지도 API'),
),
body: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: double.infinity,
// 등록된 IFrameElement Widget들 중
//'naver-map'라는 이름을 가진 개체를 Widget으로 임베딩
child: HtmlElementView(viewType: 'naver-map'),
),
),
);
}
}
간단하게 다음과 같이 구현한 뒤, 실행해보면...
정상적으로 지도를 불러왔고, 확대 및 축소와 같은 기능도 정상적으로 작동합니다.
배포를 하고 싶다면 배포하기 전 web/assets/map.html 경로로 넣어두고 빌드해야 누락되지 않고 함께 배포됩니다.
👍🏻👍🏻