inavi_map_flutter 1.0.0 copy "inavi_map_flutter: ^1.0.0" to clipboard
inavi_map_flutter: ^1.0.0 copied to clipboard

Flutter plugin for iNavi Maps SDK — map display, camera, markers on Android and iOS.

Changelog #

1.0.0 #

첫 공개 릴리스 / Initial public release.

Added #

  • InaviMapsView PlatformView를 통한 Android·iOS 네이티브 지도 렌더링. / Native map rendering via InaviMapsView on Android and iOS.
  • 이벤트 기반 인증 결과 스트림 InaviMapsSdk.instance.onInit (AuthSuccess / AuthFailure / MapReady). / Event-driven auth result stream.
  • 카메라 제어 — animateCamera · moveCamera · getCameraPosition · getVisibleBounds · bounds fit · 공통 Easing. / Camera controls with shared easing.
  • 선언형 도형 API — 마커 · 폴리라인 · 폴리곤 · 원 · InfoWindow · 클러스터 · 경로(Route). / Declarative shape APIs.
  • 지도 이벤트 — 클릭 · 롱클릭 · 더블클릭 · 카메라 이동/정지 · 마커/도형/클러스터 탭. / Map interaction events.
  • 사용자 위치 추적(UserTrackingMode)과 현위치 아이콘 커스터마이징·onLocationTap. / User location tracking and location icon customization.
  • 좌표계 변환(WGS84 · KATEC · UTM-K · TM · GRS80)과 화면↔지도 좌표 Projection. / Coordinate conversion and screen/map projection.
  • 지도 옵션 — 제스처 4종 · UI 컨트롤 · 실내지도 · 라벨 다국어(MapLanguage) · 커스텀 스타일(MapStyle) · Pick POIs. / Map options.

Platform Support #

  • Android 6.0 (API 23) 이상. / Android 6.0 (API 23) and later.
  • iOS 15.0 이상. / iOS 15.0 and later.

Notes #

  • 사용 전 Android manifest metadata 또는 iOS Info.plist에 iNavi APP KEY를 설정해야 합니다. / An iNavi app key must be configured before use.
  • Android SDK 아티팩트는 https://repo.inavi.com/artifactory/maps에서 해석됩니다. / Android artifacts resolve from the iNavi Maven repository.
  • iOS SDK 아티팩트는 CocoaPods trunk의 inavi-maps-sdk로 해석됩니다. / iOS artifacts resolve via the inavi-maps-sdk CocoaPods dependency.
  • Native SDK 의존성 버전: 0.22.0 (Android · iOS). / Native SDK dependency version 0.22.0.

개발 상세 이력 (Detailed development notes)

커스텀 지도 스타일 (Map Custom Style, 2026-06-05) #

  • MapStyle — index: int, styleName: String, styleId: String 필드를 가진 커스텀 지도 스타일 모델 신규. index는 savedCustomMapStyles 배열 내 위치(native 역참조에 사용). / New model for custom map styles from Map Studio.
  • InaviMapsController.getCustomMapStyles() — Map Studio로 배포된 커스텀 지도 스타일 목록을 반환. 인증 완료 전 또는 배포된 스타일이 없으면 빈 목록 반환. Android InaviMapSdk.savedCustomMapStyles · iOS INVMapSdk.savedCustomMapStyles index 기반 접근. / Returns available custom map styles for the current AppKey.
  • InaviMapsController.setCustomMapStyle(MapStyle?) — 커스텀 지도 스타일을 적용. null 전달 시 기본 스타일로 복원. / Applies a custom map style; null resets to the default style.
  • Example MapCustomStyleScreen 추가 (지도 옵션 > Map Custom Style) — 기본 스타일 진입 시 마커 3개(빨강·파랑·초록) + 폴리라인 표출, 커스텀 스타일 전환 시 제거, 기본 스타일 복귀 시 재표출. 스타일 선택 드롭다운은 화면 하단 바(bottomNavigationBar)에 배치. 배포된 스타일 없으면 SnackBar 안내. / Adds Map Custom Style demo screen under 지도 옵션 category. Default style shows 3 markers and a polyline; switching to a custom style clears them, returning to default restores them. Style selector is in the bottom bar.

Pick POIs (2026-06-05) #

  • InaviMapsController.pickPois(Offset, {touchRadius}) — 지도 탭 지점 주변의 POI(관심지점) 목록을 반환. PoiInfo {name, poiId, position} 모델 신규. Android inaviMap.pickPois(RectF) density 보정, iOS mapView.pickPois(CGRect) 무보정. / Returns POIs near a tapped screen point. New PoiInfo model (name, poiId, position). Android applies density scaling; iOS uses logical pts directly.
  • PoiInfo — name: String, poiId: String, position: Coordinate 필드를 가진 POI 정보 모델. / New data class holding POI name, ID, and WGS-84 position.
  • Example PickPoisScreen 추가 (기타 > Pick POIs) — 탭 지점에 반투명 빨간 사각형 오버레이, POI 조회 결과 SnackBar 표시, 각 POI에 빨간 마커 배치, 카메라 이동 시 초기화. / Adds a Pick POIs demo screen under the 기타 category.

폴리라인 점선 간격 density 보정 (Polyline pattern, 2026-06-05) #

  • Android 점선 간격 수정 — Android 가 폴리라인 pattern(dash/gap 길이)에 화면 density 를 적용하지 않아 고해상도 기기에서 iOS 보다 점선이 density 배 촘촘하게 표출되던 문제를 수정. width 와 동일하게 pattern 각 값에 density 를 곱해 logical px → physical px 로 변환한다. / Fixes Android polyline dash pattern appearing denser than iOS; pattern lengths are now scaled by display density (logical px → physical px), consistent with stroke width.

지도 라벨 다국어 표기·SDK 0.22.0 업그레이드 (Map Language, 2026-06-05) #

  • SDK 0.22.0 업그레이드 — Android com.inavi.mapsdk:inavi-maps-sdk:0.22.0 · iOS inavi-maps-sdk ~> 0.22.0 으로 업데이트. / Upgraded native SDK dependency to 0.22.0 on both platforms.
  • MapLanguage enum 추가 — ko · en · ja · zh 4개 언어 코드를 타입 안전하게 래핑. MapLanguage.fromCode 로 SDK 반환값을 역매핑하며 미지원 코드는 ko 로 폴백. / Adds a MapLanguage enum wrapping the four supported language codes; unknown codes fall back to ko.
  • InaviMapsController.setLanguage(MapLanguage) — 지도 라벨 표기 언어를 실행 중 변경. Android InaviMap.language, iOS InaviMapView.language 에 코드 문자열을 직접 전달. / Sets the map label language at runtime.
  • InaviMapsController.getLanguage() — 현재 라벨 표기 언어를 MapLanguage 로 반환. / Returns the current map label language.
  • Example MapLanguageScreen 추가 (지도 옵션 > Map Language) — 4개 언어 칩 선택 시 즉시 지도 라벨이 전환됨. onMapCreated 직후 현재 언어 동기화. / Adds a Map Language demo screen with 4 language chips.

현위치 아이콘 커스터마이징·탭 이벤트 (LocationIcon·onLocationTap, 2026-06-05) #

  • LocationIcon 커스터마이징 — LocationOptions.icon(scale·circleRadius·circleColor·imageTracking·imageTrackingCompass·image)을 Android/iOS 네이티브에 실제 적용. null 이미지 지정 시 SDK 기본 이미지로 자동 복귀(LocationIcon.DEFAULT_IMAGE* / INV_LOCATION_ICON_IMAGE*). / Location icon customization (scale, circleRadius, circleColor, per-mode images) is now applied natively on both platforms. Setting an image to null resets to the SDK default image.
  • onLocationTap — 현위치 점 탭 시 콜백이 실제 발화됨 (Android LocationIcon.setOnClickListener, iOS INVLocationIcon.touchEvent). / Tapping the location dot now fires the onLocationTap callback on both platforms.
  • iOS circleRadius 보정 — iOS SDK 는 circleRadius 를 pt 단위로 처리하므로 플러그인이 radius ÷ UIScreen.main.scale 로 Dart logical px → pt 변환을 수행한다(Android 는 SDK 가 scale 자동 반영 안 하여 circleRadius × scale 수동 계산). / iOS plugin divides circleRadius by UIScreen.main.scale (logical px → pt); Android multiplies by scale manually since the Android SDK does not auto-apply it.
  • Example LocationIconScreen 추가 (위치 > Location Icon) — scale·circleRadius·circleColor 슬라이더/칩 + Custom Image 토글 + 현위치 탭 스낵바. / Adds a Location Icon demo screen under the Location category.

실내지도 (IndoorMap, 2026-06-04) #

  • MapOptions.indoorMapEnabled (기본 true) 추가 — PlatformView 생성 시 실내지도 표출 여부를 1회 적용한다(런타임 변경은 setIndoorMapEnabled). / Adds an initial indoor-map toggle.
  • InaviMapsController.setIndoorMapEnabled(bool) / isIndoorMapEnabled() — 실내지도 표출을 런타임에 켜고 끈다. Android InaviMap.enabledIndoorMap, iOS InaviMapView.isIndoorMapEnabled (둘 다 SDK 기본 true). / Toggles indoor map at runtime.
  • InaviMapsController.onIndoorChanged → Stream<IndoorChangeEvent> — 실내 영역 진입/이탈/층 변경 이벤트. IndoorChangeEvent {placeId, floors, currentFloorIndex} (이탈 시 placeId == null, isInside getter 제공), floors 는 IndoorFloor {name, index} 목록. Android setOnIndoorChangedListener, iOS INVMapViewDelegate.didChangeIndoor 사용. / Indoor enter/exit/floor-change events.
  • InaviMapsController.setIndoorFloor(IndoorFloor) — 층 전환. onIndoorChanged 가 제공한 floors 의 항목을 그대로 전달하면 해당 층으로 전환된다. native 가 viewId 별로 floors 를 캐시하고 index 로 매칭하므로 이름이 같은 층도 정확히 구분된다. / Switches the active indoor floor by its list index.
  • 진행 이벤트는 기존 event/map 채널 + 신규 indoor.changed 타입(ChannelKeys 3-way, 채널 신설 없음)으로 발신. route.progress 와 동일 구조.
  • Example IndoorMapScreen 신규 (기타 / IndoorMap) — 실내지도 활성화 스위치 + 실내 영역 진입 시 층 휠 피커(CupertinoPicker)로 층 전환. Native IndoorActivity/IndoorMapController 미러링(초기 카메라 코엑스 인근 (37.49380, 127.11573) zoom 16, placeId 변경 시 피커 표시/숨김; 같은 장소 내 층 변경은 fling 모멘텀 피드백 루프 방지를 위해 피커 동기화 제외). 이로써 기타 카테고리가 Native 메뉴와 한층 더 정합.
  • 단위 테스트 추가 — IndoorFloor/IndoorChangeEvent 직렬화·진입/이탈·floors null 방어 · MapOptions.indoorMapEnabled · 컨트롤러 3 메서드 채널 인자/true 폴백 · Example 레이아웃 회귀(피커 표시 게이트 포함).

경로 (InvRoute, 2026-06-04) #

  • Route · RouteLink 모델 추가 — 지도 위에 경로를 그리는 셰이프. RouteLink(coords, lineColor?, strokeColor?) 로 구간(링크)별 좌표열·색상을 지정하고, Route(routeId, links, lineWidth, strokeWidth, globalZIndex?, patternImage?, patternMargin?, patternScale?, passRatio, passLineColor?, passStrokeColor?, onProgress?) 로 경로를 구성한다. links 가 비었거나 링크의 coords 가 2개 미만이면 ArgumentError 로 fail-fast(SDK 의 InvalidLatLngException 사전 방지). / Adds Route/RouteLink shapes mirroring the SDK InvRoute.
  • InaviMapsController.updateRoutes(Set<Route>) — 경로 집합을 지도와 동기화(추가/갱신/제거 리컨실). patternImage 로 AssetMarkerIcon 사용 시 해상도별 variant 가 선택된다.
  • InaviMapsController.setRoutePassRatio(routeId, passRatio) — 경로 진행률(0.0~1.0, clamp)을 런타임에 변경. 전체 리컨실 없이 단일 경로만 갱신하므로 애니메이션에 적합.
  • 진행률 변경 이벤트 — Route.onProgress 콜백 및 InaviMapsController.onRouteProgress 스트림으로 진행 위치(Coordinate)·각도·지나온 거리(RouteProgressEvent)를 수신. 이를 활용해 경로를 따라 움직이는 마커를 그릴 수 있다. onProgress 가 설정된 경로에만 네이티브가 리스너를 등록한다(hasProgressListener). Android setOnRouteChangeListener, iOS INVRouteDelegate 사용. / route.progress events expose position/angle/distance for a marker moving along the route.
  • patternImage 는 기존 MarkerIcon(asset/bytes/builtIn) 을 재사용 — 방향 화살표 등 패턴을 경로 위에 일정 간격(patternMargin)·배율(patternScale)로 반복 표출.
  • lineWidth/strokeWidth/patternMargin 은 logical px(Android dp·iOS pt) — Android 는 density 보정, iOS 는 pt 직접 사용.
  • Marker.isIconFlat 추가(기본 false, 3-way) — true 면 아이콘이 지도 평면에 눕혀져 지도 회전/기울기에 따라 함께 회전하고 rotation 이 지도 기준 방위각으로 해석된다(경로 진행 방향 마커 등). Android InvMarker.isIconFlat · iOS INVMarker.isIconFlat. / Adds Marker.isIconFlat (default false) for map-flat icons.
  • 마커 갱신 성능·정확성 수정 — updateMarkers 가 매 호출마다 아이콘을 재디코드·재할당하던 것을 아이콘 스펙(종류/색/에셋/배율/바이트)이 바뀐 경우에만 재할당하도록 변경. 경로 진행 마커처럼 마커를 빠르게(고빈도) 갱신할 때 asset 아이콘이 텍스처 재업로드로 인해 비표시 상태에 머물던 버그를 해결하고, 불필요한 디코드/업로드를 제거한다(양 플랫폼). / updateMarkers now reassigns a marker's icon only when its spec changes — fixes asset-icon markers vanishing under rapid updates and avoids redundant texture uploads.
  • Example RouteScreen 를 Native InvRouteActivity 와 동일하게 정비 — 카메라가 진행 위치를 추적, 마커 표출·플랫 마커 체크박스(미표출 시 플랫 비활성), 데모 마커/화살표 패턴 에셋·LINKS·스타일 반영.
  • Example RouteScreen 신규 (셰이프 / InvRoute) — 링크별 색상(빨강·초록·파랑) 경로 + 별 패턴 이미지 + 진행률 슬라이더/재생 버튼으로 경로를 따라 움직이는 마커 시연 (가이드 미러링). 이로써 셰이프 카테고리가 Native 메뉴와 완전히 정합.
  • 단위 테스트 추가 — Route/RouteLink 직렬화(링크별 색 ARGB·null-aware·patternImage 위임·검증) · RouteProgressEvent 디코드 · updateRoutes/setRoutePassRatio 채널 인자·passRatio clamp.

마커 예제 화면 정비 + getVisibleBounds · isTransitionEnabled (2026-06-02) #

  • InaviMapsController.getVisibleBounds() → LatLngBounds? 추가 — 현재 지도에 보이는 영역 경계 반환. Android InaviMap.getVisibleBounds(), iOS InaviMapView.contentBounds 사용. / Returns the current visible map bounds.
  • Marker.isTransitionEnabled 추가 — 마커 표출 상태 변경(겹침 해소 등) 시 Fade 전환 애니메이션 적용 여부. SDK 기본값과 동일하게 false (iOS INVMarker.isTransitionEnabled 기본 NO). 3-way 직렬화. / Controls fade transition on display-state change; defaults to false to match the SDK.
  • InvMarker 화면 — 5종 마커로 주요 속성 시연: Yellow 반투명(alpha 0.5), Green 타이틀 파란색(titleColor), Blue 타이틀 크기 16(titleSize), Gray → 별 모양 asset 마커(iconScale 2.0, anchor (0.5,0.5))로 변경. 별 asset 1x/2x/3x 추가.
  • InvMarker Overlap 화면 — 50개 마커를 getVisibleBounds() 기반 현재 가시 영역에 랜덤 배치 + 5색 순환 + Fade 애니메이션(isTransitionEnabled) 토글 + 마커 재생성 버튼 추가.
  • InfoWindow 화면 — Native 방식(단일 InfoWindow 재사용)으로 변경: 마커 탭 → 마커 부착 + "마커 : RED/BLUE", 지도 탭 → 좌표로 이동 + 좌표 표시, InfoWindow 탭 → 닫기. iOS 핸들러가 좌표 재사용 시 이전 marker 참조를 해제하도록 수정(Android 와 대칭).
  • 마커 탭 이벤트 소비 동작 변경 — 마커 탭 시 마커 클릭 리스너(onMarkerTap)만 발생하고 지도 클릭 리스너(onMapTapped)로는 더 이상 전파되지 않도록 수정(Android·iOS 네이티브 리스너가 탭을 소비). 기존에는 두 이벤트가 동시에 발생했으므로, 마커 탭과 지도 탭을 함께 구독하던 앱은 동작을 확인할 것. / Marker taps are now consumed by the marker listener and no longer propagate to the map click listener on both platforms.

셰이프 전역 Z-Index · 마커 겹침 정책 (2026-06-02) #

  • Global Z-Index — Marker/Polyline/Polygon/Circle 에 int? globalZIndex 추가. 셰이프 종류·지도 심볼/배경 대비 표출 우선순위를 제어한다. null(기본)이면 SDK 기본값(마커 1000 · 폴리곤/폴리라인/원 -1000) 유지, 값 지정 시 setGlobalZIndex. 직렬화는 null-aware(미지정 시 키 생략) — 양 플랫폼 핸들러는 값이 있을 때만 적용.
  • InvMarker Overlap — Marker 에 allowOverlapTitle(isAllowOverlapTitle)·allowOverlapSymbols(isAllowOverlapSymbols) 추가 (기존 allowOverlap = isAllowOverlapMarkers 유지). 3종 모두 SDK 기본 true. 마커 겹침 시 아이콘/타이틀/심벌 표출 정책을 개별 제어.
  • Example GlobalZIndexScreen(원+폴리라인 우선순위 토글) · MarkerOverlapScreen(촘촘한 마커 + 3종 토글) 신규 (셰이프) — Native GlobalZIndexActivity/InvMarkerOverlapActivity 미러링. 셰이프 카테고리가 Native 메뉴(InvMarker Overlap·Global Z-Index 포함)와 정합.

지도 제한 · 심볼 배율 + Example 메뉴 설명 (2026-06-02) #

  • Map Restriction — InaviMapsController.setMapRestriction({bounds, minZoom, maxZoom}) / clearMapRestriction() 추가. 카메라 이동 가능 영역(LatLngBounds)과 줌 범위를 제한한다. Android inaviMap.constraintBounds/setMinZoom/setMaxZoom, iOS mapView.constraintBounds/minimumZoomLevel/maximumZoomLevel 사용. 해제 시 Android 는 InvConstants.BOUNDS_KOREA/MINIMUM_ZOOM/MAXIMUM_ZOOM, iOS 는 전국 영역 좌표 + 기본 줌 범위(1~21)로 복원. 전달한 인자만 적용(나머지 유지).
  • Map Symbol Scale — InaviMapsController.setSymbolScale(double) / getSymbolScale() + MapOptions.symbolScale 초기 옵션(기본 1.0) 추가. 지도 라벨·POI 심볼 배율 조절. Android·iOS symbolScale property. 0 이하 값은 0.1 로 clamp.
  • Example MapRestrictionScreen · MapSymbolScaleScreen 신규 (지도 옵션) — Native MapRestrictionActivity/MapSymbolScaleActivity 미러링. 이로써 지도 옵션 카테고리는 Map Custom Style(인증 확장 필요)만 남고 Native 메뉴와 정합.
  • Example 메뉴에 영문 타이틀 + 한국어 설명(subtitle) 추가 — FeatureEntry.description 필드 신설, 각 항목 설명을 Native Demo strings.xml 한국어 표기로 통일(예: Map Type / 지도 타입, Map Restriction / 지도 제한). FeatureListScreen 타일이 subtitle 로 설명 표출 — Native Demo 메뉴와 동일한 2단 표기.
  • 폴리라인 점선↔실선 토글 Android 회귀 수정 — Android InvPolyline.setPattern() 빈 배열 호출이 IllegalArgumentException("pattern must be greater than 2") 을 던져 ① 실선 폴리라인 추가 실패(Map Restriction 경계 박스 미표출) ② 점선→실선 미전환을 유발하던 버그. 수정: 빈 패턴은 setPattern 미호출(실선 = SDK 기본), 점선→실선 전환은 폴리라인 재생성으로 처리. 이전 "M4 회귀 수정"의 가정("빈 배열 전달 시 SDK 가 실선 처리")이 Android 에서 틀렸던 점 정정 (iOS 는 pattern property 가 빈 배열을 허용해 정상).

지도 유형 (Map Type, 2026-06-02) #

  • MapType enum 신규 — normal(0) · hybrid(1) · satellite(2) · normalWithHillshade(3) · hybridWithHillshade(4) · satelliteWithHillshade(5). 선언 순서(index)가 양 플랫폼 네이티브 ordinal(Android InaviMap.MapType / iOS INVMapType)과 1:1 로 일치하며 그대로 직렬화된다.
  • MapOptions.mapType 필드 추가 (기본값 MapType.normal) — PlatformView 생성 시 초기 유형으로 1회 적용. toMap() 반환 타입이 Map<String, bool> → Map<String, Object> 로 확장됨.
  • InaviMapsController.setMapType(MapType) / getMapType() → MapType 추가 — 다른 MapOptions 항목과 달리 SDK 가 런타임 변경을 정식 지원하므로 PlatformView 재생성 없이 실행 중 유형 전환 가능. Android inaviMap.mapType · iOS mapView.mapType 사용.
  • Example MapTypeScreen 신규 (지도 옵션) — 6종 유형을 칩으로 전환하며 setMapType 런타임 변경 시연 (Native MapTypeActivity 미러링).
  • 단위 테스트 추가 — MapType index 매핑 · MapOptions.mapType 직렬화/copyWith/동등성 · setMapType/getMapType 채널 메서드명·인자·역매핑·폴백.

Example 메뉴 Native Demo 1:1 미러링 + 신규 화면 2종 (2026-06-02) #

  • example/lib/features.dart 메뉴를 본 SDK Android Native iNavi Maps Demo 기준으로 재정렬 — 카테고리 순서·이름(지도 · 셰이프 · 클러스터링 · 카메라 · 지도 옵션 · 클릭 이벤트 · 위치 · 기타) 및 항목 라벨을 Native 영문 표기(InvMarker · InvPolyline · Camera Move · Projection …)로 통일. 기존 자매 플러그인 미러링에서 Native 미러링으로 전환 (마스터 계획 §9.1).
  • 클릭 이벤트 카테고리 신설 — Map Click · Shape Click 을 지도/셰이프 카테고리에서 분리.
  • Example MapPaddingScreen 신규 (지도 옵션) — InaviMapsController.setPadding 으로 25/25/100/100 패딩 토글 + 패딩 영역 오버레이 시각화 + 중심 재정렬 (Native MapPaddingActivity 미러링).
  • Example CameraUpdateBuilderScreen 신규 (카메라) — Target/Zoom/Tilt/Bearing 토글 선택 후 getCameraPosition 으로 현재 값을 읽어 델타를 더한 CameraUpdate.newCameraPosition 으로 이동 (Native CameraUpdateBuilderActivity 의 composite builder 동등 재현, 신규 네이티브 API 없이 구현).
  • 본 플러그인이 아직 미지원하는 Native 항목(InvRoute · Global Z-Index · Map Custom Style · Map Restriction · Map Symbol Scale · InvMarker Overlap · Location Icon · IndoorMap · Pick POIs)은 메뉴에서 제외 — 신규 네이티브 API 필요 (마스터 계획 §9.1.1 표로 분리). (Map Type 은 이후 구현되어 메뉴에 추가됨)

M7 — 좌표계 변환 + Projection (2026-06-01) #

  • CoordinateSystemType enum 신규 — katec(0) · tm(1) · utmk(2) · grs80(3). ordinal 이 채널로 직렬화되므로 순서 고정.
  • CoordinatePoint {x, y} 모델 신규 — 투영 좌표계 변환 결과(KATEC/TM/UTM-K 는 미터 easting/northing, GRS80 은 경도/위도).
  • InaviMapsController.convertFromWgs84({latitude, longitude, to}) → CoordinatePoint 추가 — WGS-84 → KATEC/UTM-K/TM/GRS80 단방향 변환. Native Demo (CoordinatesConversionActivity) 미러링이며 역방향(toLatLng / convertToWgs84)은 노출하지 않는다. 위경도 범위([-90,90] / [-180,180]) 초과 시 ArgumentError.
  • InaviMapsController.latLngToScreenLocation(Coordinate) → Offset? / screenLocationToLatLng(Offset) → Coordinate? 추가 — 화면 좌표(논리 px) ↔ 지도 좌표 양방향 Projection. SDK projection.getPointFromLatLng/getLatLngFromPoint (Android) · projection.point(from:)/latlng(from:) (iOS) 사용.
  • density/scale 처리 — Android 는 SDK PointF 가 physical px 이므로 *density(screen→map) / /density(map→screen) 보정, iOS 는 CGPoint 가 logical point(== Flutter 논리 px)이므로 보정 없음. 기존 M3 클릭 이벤트 핸들러와 동일 컨벤션.
  • Example CoordinatesConversionScreen · ProjectionScreen 추가 (기타 카테고리) — Native Demo 미러링: 지도 중앙 crosshair 의 WGS84 좌표 실시간 표시 + 4좌표계 변환 다이얼로그 / 화면 좌표 ↔ 지도 좌표 실시간 표시.
  • 단위 테스트 12건 추가 (누계 83) — CoordinatePoint 직렬화 · CoordinateSystemType ordinal · 3개 컨트롤러 메서드의 채널 메서드명/인자/범위 검증.

M6 — 지도 옵션 (제스처 + UI 컨트롤, 2026-06-01) #

  • MapOptions Dart 모델 신규 — 9 필드 (scrollGesturesEnabled · zoomGesturesEnabled · tiltGesturesEnabled · rotateGesturesEnabled · compassVisible · scaleBarVisible · zoomControlVisible · locationButtonVisible · logoClickEnabled).
  • InaviMapsView.mapOptions 파라미터 추가 — PlatformView 생성 시 native 에 1회 전달되어 적용. runtime mutation 미지원 (본 SDK 한계) — 재적용이 필요하면 widget key 를 바꿔 PlatformView 재생성.
  • 본 SDK 실제 API 기준으로 자매 플러그인의 logoVisible 대신 logoClickEnabled 채택 — Android UiSettings.setLogoClickEnabled, iOS InaviMapView.isLogoClickEnabled. 비활성화 시 호스트 앱이 별도 라이선스/법적 고지 페이지를 직접 제공해야 한다 (SDK 약관 §책무).
  • Example MapOptionsScreen 추가 — 9 토글 + 변경 시 PlatformView 재생성 패턴 데모.

M4 폴리라인 점선↔실선 토글 회귀 수정 (2026-06-01) #

  • updatePolylines 핸들러의 if (pattern.size >= 2) (Android) / if a.pattern.count >= 2 (iOS) 가드가 빈 배열을 무시하여, 캐시된 polyline 인스턴스의 점선 패턴이 reset 되지 않던 버그 수정. 가드 제거 후 빈 배열도 그대로 SDK 에 전달 → SDK 가 패턴 해제(실선) 로 처리. 자매 플러그인 패턴 미러링.
  • 폴리라인 데모 화면 (example/lib/screens/shape/polyline_screen.dart) 의 토글 FAB 아이콘을 Icons.more_horiz (점선 — ● ● ●) / Icons.horizontal_rule (실선 — ━) 로 변경하여 점선/실선 시각적 의미 명확화.

Android PlatformView 렌더링 모드 변경 (ADR-0004, 2026-06-01) #

  • InaviMapsView 의 Android 분기를 단순 AndroidView (Virtual Display) 에서 PlatformViewLink + AndroidViewSurface + PlatformViewsService.initExpensiveAndroidView (= TLHC, Texture Layer Hybrid Composition) 로 변경. iOS 측은 변경 없음.
  • 동기 — iOS 와 달리 Android 에서는 지도 회전 시 SDK 가 자동 표출하는 compass overlay 가 보이지 않던 증상 보고. 원인은 SDK 기본값(양 플랫폼 모두 표출 ON)이 아니라 PlatformView 합성 모드 — Virtual Display 는 SDK 가 동적으로 추가하는 child view (compass · logo · scale bar · info-window popup 등) 를 보존하지 않는다. 자매 inavi-global-map-sdk-flutter-plugin 의 동일 패턴 미러링.
  • 부가 효과 — 향후 SDK overlay UI 변경에 대해 합성 누락 위험 제거. 호스트 Activity 는 그대로 FlutterActivity 사용 (추가 제약 없음).
  • 사용자 API 변경 없음 — gestureRecognizers 파라미터는 그대로 AndroidViewSurface 로 위임.

UserTrackingMode.none 의미 통일 (2026-06-01) #

  • UserTrackingMode.none (ordinal 0) 의 의미를 "위치 점 숨김 + 추적 완전 비활성화" 로 명확화. 기존 Dart doc 은 "위치 점 보임 + 카메라 추적 안 함" 이라고 적혀 있었으나 Android 실제 동작은 위치 점 숨김이었고, iOS 는 .noTracking 로 매핑되어 위치 점이 보이는 비대칭 상태였다.
  • iOS MethodChannelHandler.displayUserTrackingMode 에서 ordinal 0 → .none 매핑으로 변경 (Android 와 대칭). 카메라 추적 없이 위치 점만 표시하려면 UserTrackingMode.noTracking 사용.

iOS MapReady 이벤트 race condition 수정 (2026-06-01) #

  • InaviMapsView 가 initState() 에서 InaviMapsSdk.onInit 스트림을 미리 구독하고, _onPlatformViewCreated 이전에 도착한 MapReady 이벤트를 _bufferedReady 에 보관해 viewId 확정 후 처리하도록 변경. 두 번째 이후 지도 화면 진입 시 iOS PlatformView.init() 에서 즉시 발신되는 map.ready 이벤트가 Dart 구독 등록 전에 도착해 손실되던 문제 해결 → onMapCreated 콜백 미수신 / _controller == null → 모든 기능 무반응 증상 제거.

M5 — 사용자 위치 (sibling-port Phase D, 부분 이식) #

리뷰 반영 (2026-05-28, docs/reviews/2026-05-28-m5-user-location-review.md):

  • P1 수정 — location.permissionDenied envelope 을 ListenerBridge.initSink (event/init) 대신 ListenerBridge.sendMapEvent(viewId, ...) (event/map) 로 발신. Dart InaviMapsEventDispatcher 는 event/map 만 구독하므로 기존 코드로는 controller.onLocationPermissionDenied Stream 에 도달하지 못하던 라우팅 버그를 해결. Android/iOS 양쪽 동일 변경.

  • P2 수정 — PlatformView dispose 시 위치 cache 정리 hook 추가. ListenerBridge 에 addViewDisposeCallback((Int) -> Unit) 등록점을 두고, unregisterMap(viewId) 가 등록된 콜백을 fanout. MethodChannelHandler 가 attach() 시 위치 cache(locationEnabledViewIds / locationModeCache / lastKnownLocations / locationProviders) 정리 콜백을 등록 → view 재생성이 잦은 화면에서의 메모리 leak 가능성 제거. iOS ListenerBridge.lastKnownLocations 도 unregisterMap 에서 함께 정리.

  • iOS 권한 다이얼로그 미표출 버그 수정 — example/ios/Podfile post_install 블록에 GCC_PREPROCESSOR_DEFINITIONS << 'PERMISSION_LOCATION=1' 매크로 추가. permission_handler iOS 구현이 컴파일 타임 매크로로 권한 종류를 활성화하기 때문에, 누락 시 Permission.locationWhenInUse.request() 가 no-op 으로 컴파일되어 다이얼로그가 표출되지 않던 문제 해결. 자매 inavi_global_map_flutter 의 Podfile 패턴 미러링.

  • LocationOptions / LocationIcon / UserTrackingMode Dart 모델 신규 — 자매 플러그인 inavi_global_map_flutter 의 동일 구조를 본 컨벤션(InaviMaps*)으로 이식

  • InaviMapsController 에 위치 API 추가 — updateLocationOptions(LocationOptions?), setTrackingMode(UserTrackingMode), getTrackingMode(), getCurrentLocation(), Stream onLocationTap / onLocationPermissionDenied

  • InaviMapsView 에 locationOptions 파라미터 추가 — didUpdateWidget 에서 updateLocationOptions 자동 호출, LocationOptions.onLocationTap 콜백은 View 가 책임

  • InaviMapsEventDispatcher 에 locationTap / locationPermissionDenied Stream 분기 + removeView 정리

  • 채널 키 3-way 동기화 — location.tap / location.permissionDenied (Dart + Android + iOS)

  • Android — MethodChannelHandler 에 FusedLocationProvider(com.inavi.mapsdk.maps.FusedLocationProvider) + inaviMap.locationProvider + userTrackingMode property 패턴 적용. hasLocationPermission 가드 + addOnLocationChangedListener 캐시. Plugin 에서 activityProvider 주입

  • iOS — MethodChannelHandler 에 mapView.userTrackingMode property + displayUserTrackingMode(fromOrdinal:) 헬퍼(.none → .noTracking 승격), CLLocationManager().authorizationStatus 권한 체크. InaviMapViewProxy 에 mapView(_:didUpdateUserLocation:) delegate 추가 (위치 캐시)

  • Example 앱 — permission_handler ^11.0.0 의존성 추가(ADR-0013), LocationPermissionMixin 신규(Permission.locationWhenInUse 래핑), UserTrackingModeScreen 신규(4 추적 모드 ChoiceChip + 권한 요청 버튼 + onLocationPermissionDenied SnackBar)

  • 단위 테스트 추가 — UserTrackingMode ordinal(1), LocationIcon toMap/copyWith/equality/inequality(5), LocationOptions toMap/equality/copyWith(5) — 총 11건 추가, 누계 66개 통과

  • 본 SDK 한계 메모 — Maps SDK 0.21.1 은 자매 Global Maps SDK 의 LocationIcon (image/circleRadius/circleColor 등) 커스터마이징 API 를 미문서화 상태로 제공 안 함. Dart LocationIcon 옵션은 받아 두지만 native 측에서 적용되지 않으며, 향후 SDK 업데이트 시 확장 지점이 된다 — LocationIconScreen 화면 미구현 (follow-up)

  • 본 SDK 한계 메모 — onLocationTap (위치 점 탭 콜백) 도 본 SDK 미지원. Stream 자체는 channel 인프라로 보존하되 native 가 발신할 일이 없다 (follow-up: SDK 업데이트 시 활성화)

M4 — 마커/도형/클러스터 (sibling-port Phase C) #

  • 도형 모델 — Polyline / Polygon / Circle / LineCap / LineJoin + InaviMapsController.updatePolylines / updatePolygons / updateCircles API
  • 마커 — Marker / MarkerIcon(AssetMarkerIcon / BuiltInMarkerIcon) / BuiltInMarkerColor 모델 + updateMarkers API + onMarkerTap Stream
  • InfoWindow — InfoWindow 모델 + updateInfoWindows API + onInfoWindowTap Stream
  • Clustering — ClusterItem / ClusterOptions / ClusterTapEvent / ClusterItemTapEvent 모델 + setClusterItems / clearClusterItems API + onClusterTap / onClusterItemTap Stream
  • asset_manifest_cache.dart 신규 — AssetMarkerIcon resolution-aware variant 로드 (ensureLoaded 게이트)
  • 채널 키 3-way 동기화 — shape.click / marker.tap / infoWindow.click / cluster.tap / clusterItem.tap
  • Android — ListenerBridge.kt / MethodChannelHandler.kt 에 도형·마커·InfoWindow·Cluster 핸들러 추가 (InvMarker / InvPolyline / InvPolygon / InvCircle / InvInfoWindow / ClusterManager)
  • iOS — MethodChannelHandler.swift 동등 구현 (INVMarker / INVPolyline / INVPolygon / INVCircle / INVInfoWindow / INVClusterManager)
  • Example 앱 화면 8종 신규 — 도형 시연(Polyline/Polygon/Circle), 마커 시연(Marker/MarkerOverlap), InfoWindow, Clustering, 도형 클릭 이벤트
  • 단위 테스트 추가 — 모델 직렬화/역직렬화 round-trip

M3 — 지도 클릭 이벤트 (sibling-port Phase B) #

  • MapClickEvent 모델 신규 — coordinate(Coordinate) + screenPoint(Offset) + fromMap factory
  • InaviMapsController 에 onMapClick / onMapLongClick / onMapDoubleClick Stream getter 추가
  • InaviMapsEventDispatcher 에 click stream 분기 (map.click / map.longClick / map.doubleClick)
  • Android ListenerBridge.kt — mapClickListener / mapLongClickListener / mapDoubleClickListener factory 추가 (physical px → logical px 변환)
  • Android InaviMapsPlatformView.kt — setOnMapClickListener / setOnMapLongClickListener / setOnMapDoubleClickListener 등록 + dispose 시 null 해제
  • iOS ListenerBridge.swift proxy — didTapMapView / didLongTapMapView / didDoubleTapMapView delegate 메서드 추가 (INVMapViewDelegate)
  • 채널 키 3-way 동기화 — typeMapClick / typeMapLongClick / typeMapDoubleClick (Dart + Android + iOS)
  • Example 앱 MapClickEventScreen 신규 — 탭/길게 탭/두 번 탭 토글 칩 + SnackBar 시연
  • 단위 테스트 추가 — MapClickEvent.fromMap (4건)

M2-R2 — fitBounds + LatLngBounds (sibling-port 첫 적용) #

  • CameraUpdate.fitBounds(LatLngBounds, padding) factory + LatLngBounds 모델 신규 (자매 플러그인 inavi_global_map_flutter 의 동일 구조 이식)
  • Android MethodChannelHandler.kt 에 fitBounds case 추가 — com.inavi.mapsdk.geometry.LatLngBounds + density 기반 padding px 변환
  • iOS MethodChannelHandler.swift 에 fitBounds case 추가 — INVLatLngBounds + UIEdgeInsets per-side padding 보존
  • Example 앱 CameraFitBoundsScreen 신규 — 강남역↔청주 두 위치 viewport fit 토글 (FAB)
  • 단위 테스트 추가 — LatLngBounds (3건), CameraUpdate.fitBounds toMap (1건)

Example — Native SDK 데모 미러링 메뉴 시스템 (Example app menu) #

  • Example 앱에 Native SDK 데모 미러링 메뉴 시스템 도입 — FeatureListScreen + FeatureEntry (카테고리 그룹 + 타일 네비게이션)
  • Example 화면 분리 — InaviMapViewScreen(지도 표출, 강남역 기본), CameraMoveScreen(두 위치 왕복 + 4종 애니메이션), CameraEventsScreen(실시간 위치/Zoom/Tilt/Bearing + 이동/취소 FAB)
  • 공유 데모 상수 — m1_demo_data.dart (강남역 / 청주 좌표 + 기본 카메라 위치)
  • main.dart 단순화 — MaterialApp + FeatureListScreen 진입점, AuthFailure 다이얼로그 라우팅
  • FitBounds / CameraUpdateBuilder 화면은 CameraUpdate SDK 확장(M2-R2 / M2-R3) 완료 후 추가 예정

M2 — 카메라 제어 (Camera control) #

  • InaviMapsController (per-view 컨트롤러) — InaviMapsView.onMapCreated 콜백으로 전달
    • animateCamera(CameraUpdate, duration, animation) / moveCamera(CameraUpdate)
    • getCameraPosition() / cancelTransitions()
    • setPadding(EdgeInsets) — Android는 dp→px 변환, iOS는 logical pt 그대로 (contentInset)
    • onCameraMove / onCameraIdle 이벤트 Stream — viewId별 broadcast
  • Public 모델 — Coordinate, CameraPosition, CameraUpdate(sealed), CameraAnimation, CameraMoveReasonKind
    • CameraAnimation 4값: none, linear, easing, fly
    • CameraUpdate factory: newCameraPosition, targetTo, targetAndZoom, zoomTo, zoomBy, zoomIn, zoomOut
    • CameraMoveReasonKind 5값: unknown, gesture, api, control, locationChanged
  • InaviMapsView.onMapCreated 콜백 — 네이티브 map.ready 도달 이후에만 호출 (ADR-0001)
  • 채널 키 추가 — event/map envelope 의 type 디스크리미네이터 camera.move / camera.idle (3-way 동기화)
  • Android — MethodChannelHandler.kt 분리 + ListenerBridge 에 카메라 listener factory + SDK reason int → Dart ordinal 정규화 switch
  • iOS — MethodChannelHandler.swift 분리 + InaviMapViewProxy: INVMapViewDelegate per-view 프록시 + regionIsChangingWithReason: / mapViewDidBecomeIdle: 라우팅 + reason 정규화 switch
  • Codec 헬퍼 — Android DtoCodec.kt (MethodCall.argMap()), iOS DtoCodec.swift (argMap(_:))
  • ADR-0001 (onMapCreated post map.ready) · ADR-0003 (camera reason 명시 매핑) · ADR-0005 (camera animation 공통 Easing 표면) — ADR-0005는 ADR-0003의 CameraAnimation 5값 정책 supersede

M1 — 지도 표시 (Map display) #

  • 빈 지도 PlatformView 표출 — Android InvMapView(FrameLayout) 직접 호스팅 + DefaultLifecycleObserver 위임, iOS InaviMapView(UIView) 직접 노출
  • InaviMapsSdk 싱글톤 진입점 — broadcast Stream<InitEvent> onInit 노출
  • InaviMapsView StatefulWidget — Android AndroidView / iOS UiKitView
  • InitEvent sealed class — AuthSuccess / AuthFailure(errorCode, errorMessage) / MapReady(viewId)
  • SDK 인증 콜백 라우팅 — Android InaviMapSdk.authFailureCallback/authSuccessCallback, iOS INVMapSdk.delegate (INVMapSdkDelegate)
  • ListenerBridge (Android object / iOS singleton) — SDK 콜백 → EventChannel 메인 스레드 보장 + 큐잉
  • EventChannelHandler — com.inavi.maps/event/init, com.inavi.maps/event/map 라우터
  • Example 앱 — InaviMapsView + Status 라벨로 인증·map.ready 시각화

0.0.1 — 2026-05-27 #

M0 Scaffold (initial) #

  • 프로젝트 스캐폴딩 (flutter create --template=plugin --platforms=android,ios)
  • Android 패키지 com.inavi.maps.flutter 정리
  • Android Maven repo (https://repo.inavi.com/artifactory/maps) 및 SDK 의존성 (com.inavi.mapsdk:inavi-maps-sdk:0.21.1) 연결
  • iOS Pod 의존성 (inavi-maps-sdk ~> 0.21.0) 연결
  • 채널 키 3-way 동기화 (Dart / Kotlin / Swift) — com.inavi.maps/ prefix
  • Example 앱에 AppKey 메타데이터 (Android AndroidManifest.xml / iOS Info.plist) 자리 마련
  • 자매 플러그인 inavi_global_map_flutter 컨벤션 미러링
  • docs/plans/flutter-plugin-development-plan.md — 마스터 플랜 작성
0
likes
150
points
11
downloads

Documentation

API reference

Publisher

verified publisherinavi.kr

Weekly Downloads

Flutter plugin for iNavi Maps SDK — map display, camera, markers on Android and iOS.

Homepage

Topics

#inavi-map #inavi-map-flutter #map

License

Apache-2.0 (license)

Dependencies

flutter, meta, plugin_platform_interface

More

Packages that depend on inavi_map_flutter

Packages that implement inavi_map_flutter