@granite-js/naver-map 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/GraniteNaverMap.podspec +81 -0
- package/android/build.gradle +160 -0
- package/android/gradle.properties +5 -0
- package/android/src/builtinProvider/java/run/granite/navermap/builtinProvider/BuiltInGraniteNaverMapProvider.kt +549 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/run/granite/navermap/GraniteNaverMapEvents.kt +91 -0
- package/android/src/main/java/run/granite/navermap/GraniteNaverMapPackage.kt +16 -0
- package/android/src/main/java/run/granite/navermap/GraniteNaverMapProvider.kt +242 -0
- package/android/src/main/java/run/granite/navermap/GraniteNaverMapRegistry.kt +116 -0
- package/android/src/main/java/run/granite/navermap/GraniteNaverMapView.kt +732 -0
- package/android/src/newarch/java/run/granite/navermap/GraniteNaverMapViewManager.kt +446 -0
- package/android/src/oldarch/java/run/granite/navermap/GraniteNaverMapViewManager.kt +249 -0
- package/dist/module/NaverMapView.js +110 -0
- package/dist/module/NaverMapView.js.map +1 -0
- package/dist/module/index.js +6 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/internals/colorUtils.js +624 -0
- package/dist/module/internals/colorUtils.js.map +1 -0
- package/dist/module/internals/context.js +8 -0
- package/dist/module/internals/context.js.map +1 -0
- package/dist/module/internals/id.js +10 -0
- package/dist/module/internals/id.js.map +1 -0
- package/dist/module/internals/useMapOverlay.js +44 -0
- package/dist/module/internals/useMapOverlay.js.map +1 -0
- package/dist/module/internals/usePreservedReference.js +36 -0
- package/dist/module/internals/usePreservedReference.js.map +1 -0
- package/dist/module/overlays/ArrowheadPath.js +37 -0
- package/dist/module/overlays/ArrowheadPath.js.map +1 -0
- package/dist/module/overlays/Circle.js +35 -0
- package/dist/module/overlays/Circle.js.map +1 -0
- package/dist/module/overlays/GroundOverlay.js +30 -0
- package/dist/module/overlays/GroundOverlay.js.map +1 -0
- package/dist/module/overlays/InfoWindow.js +32 -0
- package/dist/module/overlays/InfoWindow.js.map +1 -0
- package/dist/module/overlays/Marker.js +37 -0
- package/dist/module/overlays/Marker.js.map +1 -0
- package/dist/module/overlays/Path.js +41 -0
- package/dist/module/overlays/Path.js.map +1 -0
- package/dist/module/overlays/Polygon.js +51 -0
- package/dist/module/overlays/Polygon.js.map +1 -0
- package/dist/module/overlays/Polyline.js +60 -0
- package/dist/module/overlays/Polyline.js.map +1 -0
- package/dist/module/overlays/index.js +11 -0
- package/dist/module/overlays/index.js.map +1 -0
- package/dist/module/package.json +1 -0
- package/dist/module/specs/GraniteNaverMapViewNativeComponent.ts +352 -0
- package/dist/module/types/Coord.js +2 -0
- package/dist/module/types/Coord.js.map +1 -0
- package/dist/module/types/index.js +29 -0
- package/dist/module/types/index.js.map +1 -0
- package/dist/typescript/NaverMapView.d.ts +41 -0
- package/dist/typescript/index.d.ts +3 -0
- package/dist/typescript/internals/colorUtils.d.ts +10 -0
- package/dist/typescript/internals/context.d.ts +8 -0
- package/dist/typescript/internals/id.d.ts +1 -0
- package/dist/typescript/internals/useMapOverlay.d.ts +15 -0
- package/dist/typescript/internals/usePreservedReference.d.ts +6 -0
- package/dist/typescript/overlays/ArrowheadPath.d.ts +11 -0
- package/dist/typescript/overlays/Circle.d.ts +10 -0
- package/dist/typescript/overlays/GroundOverlay.d.ts +11 -0
- package/dist/typescript/overlays/InfoWindow.d.ts +14 -0
- package/dist/typescript/overlays/Marker.d.ts +16 -0
- package/dist/typescript/overlays/Path.d.ts +15 -0
- package/dist/typescript/overlays/Polygon.d.ts +10 -0
- package/dist/typescript/overlays/Polyline.d.ts +11 -0
- package/dist/typescript/overlays/index.d.ts +16 -0
- package/dist/typescript/specs/GraniteNaverMapViewNativeComponent.d.ts +92 -0
- package/dist/typescript/types/Coord.d.ts +4 -0
- package/dist/typescript/types/index.d.ts +55 -0
- package/ios/GraniteNaverMap-Bridging-Header.h +20 -0
- package/ios/GraniteNaverMapProvider.swift +312 -0
- package/ios/GraniteNaverMapRegistry.swift +91 -0
- package/ios/GraniteNaverMapView.h +15 -0
- package/ios/GraniteNaverMapView.mm +390 -0
- package/ios/GraniteNaverMapViewImpl.swift +496 -0
- package/ios/GraniteNaverMapViewManager.m +67 -0
- package/ios/GraniteNaverMapViewManager.swift +133 -0
- package/ios/GraniteNaverMapViewWrapper.swift +215 -0
- package/ios/builtinProvider/BuiltInNaverMapProvider.swift +489 -0
- package/ios/builtinProvider/GraniteNaverMapMarkerData.swift +66 -0
- package/ios/builtinProvider/NMFMarker+Extension.swift +65 -0
- package/ios/builtinProvider/RCTConvert+NMFMapView.h +17 -0
- package/ios/builtinProvider/RCTConvert+NMFMapView.m +67 -0
- package/package.json +103 -0
- package/src/NaverMapView.tsx +168 -0
- package/src/index.tsx +3 -0
- package/src/internals/colorUtils.ts +697 -0
- package/src/internals/context.ts +14 -0
- package/src/internals/id.ts +9 -0
- package/src/internals/useMapOverlay.ts +59 -0
- package/src/internals/usePreservedReference.ts +41 -0
- package/src/overlays/ArrowheadPath.ts +71 -0
- package/src/overlays/Circle.ts +68 -0
- package/src/overlays/GroundOverlay.ts +62 -0
- package/src/overlays/InfoWindow.ts +68 -0
- package/src/overlays/Marker.ts +83 -0
- package/src/overlays/Path.ts +87 -0
- package/src/overlays/Polygon.ts +83 -0
- package/src/overlays/Polyline.ts +93 -0
- package/src/overlays/index.ts +23 -0
- package/src/specs/GraniteNaverMapViewNativeComponent.ts +352 -0
- package/src/types/Coord.ts +4 -0
- package/src/types/index.ts +78 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
//
|
|
2
|
+
// GraniteNaverMapViewWrapper.swift
|
|
3
|
+
// granite-naver-map
|
|
4
|
+
//
|
|
5
|
+
// Provider-based wrapper for Old Architecture (no direct NMapsMap dependency)
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import React
|
|
9
|
+
import UIKit
|
|
10
|
+
|
|
11
|
+
class GraniteNaverMapView: UIView {
|
|
12
|
+
weak var bridge: RCTBridge?
|
|
13
|
+
|
|
14
|
+
@objc var onInitialized: RCTDirectEventBlock?
|
|
15
|
+
@objc var onCameraChange: RCTDirectEventBlock?
|
|
16
|
+
@objc var onTouch: RCTDirectEventBlock?
|
|
17
|
+
@objc var onMapClick: RCTDirectEventBlock?
|
|
18
|
+
@objc var onMarkerClick: RCTDirectEventBlock?
|
|
19
|
+
|
|
20
|
+
private var provider: GraniteNaverMapProvidable?
|
|
21
|
+
private var mapContentView: UIView?
|
|
22
|
+
|
|
23
|
+
override init(frame: CGRect) {
|
|
24
|
+
super.init(frame: frame)
|
|
25
|
+
setupProvider()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
required init?(coder: NSCoder) {
|
|
29
|
+
fatalError("init(coder:) has not been implemented")
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private func setupProvider() {
|
|
33
|
+
// Create a new provider instance for this view
|
|
34
|
+
guard let provider = GraniteNaverMapRegistry.shared.createProvider() else {
|
|
35
|
+
// No provider factory available - show placeholder or error
|
|
36
|
+
let label = UILabel(frame: bounds)
|
|
37
|
+
label.text = "NaverMap provider not registered"
|
|
38
|
+
label.textAlignment = .center
|
|
39
|
+
label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
40
|
+
addSubview(label)
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
self.provider = provider
|
|
45
|
+
provider.setDelegate(self)
|
|
46
|
+
|
|
47
|
+
let mapView = provider.createMapView(frame: bounds)
|
|
48
|
+
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
49
|
+
addSubview(mapView)
|
|
50
|
+
self.mapContentView = mapView
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// MARK: - Property Setters
|
|
54
|
+
|
|
55
|
+
@objc func setMapType(_ type: Int) {
|
|
56
|
+
guard let mapType = GraniteNaverMapType(rawValue: type) else { return }
|
|
57
|
+
provider?.setMapType(mapType)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@objc var mapPadding: UIEdgeInsets = .zero {
|
|
61
|
+
didSet {
|
|
62
|
+
provider?.setMapPadding(mapPadding)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@objc var compass: Bool = true {
|
|
67
|
+
didSet {
|
|
68
|
+
provider?.setCompassEnabled(compass)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@objc var scaleBar: Bool = true {
|
|
73
|
+
didSet {
|
|
74
|
+
provider?.setScaleBarEnabled(scaleBar)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@objc var zoomControl: Bool = true {
|
|
79
|
+
didSet {
|
|
80
|
+
provider?.setZoomControlEnabled(zoomControl)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@objc var buildingHeight: Float = 1.0 {
|
|
85
|
+
didSet {
|
|
86
|
+
provider?.setBuildingHeight(buildingHeight)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@objc var nightMode: Bool = false {
|
|
91
|
+
didSet {
|
|
92
|
+
provider?.setNightModeEnabled(nightMode)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@objc var minZoomLevel: Double = 0 {
|
|
97
|
+
didSet {
|
|
98
|
+
provider?.setMinZoomLevel(minZoomLevel)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@objc var maxZoomLevel: Double = 21 {
|
|
103
|
+
didSet {
|
|
104
|
+
provider?.setMaxZoomLevel(maxZoomLevel)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@objc var scrollGesturesEnabled: Bool = true {
|
|
109
|
+
didSet {
|
|
110
|
+
provider?.setScrollGesturesEnabled(scrollGesturesEnabled)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@objc var tiltGesturesEnabled: Bool = true {
|
|
115
|
+
didSet {
|
|
116
|
+
provider?.setTiltGesturesEnabled(tiltGesturesEnabled)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@objc var rotateGesturesEnabled: Bool = true {
|
|
121
|
+
didSet {
|
|
122
|
+
provider?.setRotateGesturesEnabled(rotateGesturesEnabled)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@objc var stopGesturesEnabled: Bool = true {
|
|
127
|
+
didSet {
|
|
128
|
+
provider?.setStopGesturesEnabled(stopGesturesEnabled)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@objc var tilt: Bool = true {
|
|
133
|
+
didSet {
|
|
134
|
+
provider?.setTiltGesturesEnabled(tilt)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@objc var locationTrackingMode: UInt = 0 {
|
|
139
|
+
didSet {
|
|
140
|
+
guard let mode = GraniteNaverMapLocationTrackingMode(rawValue: Int(locationTrackingMode)) else { return }
|
|
141
|
+
provider?.setLocationTrackingMode(mode)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@objc var showsMyLocationButton: Bool = false {
|
|
146
|
+
didSet {
|
|
147
|
+
provider?.setLocationButtonEnabled(showsMyLocationButton)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@objc var zoomGesturesEnabled: Bool = true {
|
|
152
|
+
didSet {
|
|
153
|
+
provider?.setZoomGesturesEnabled(zoomGesturesEnabled)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// MARK: - Commands
|
|
158
|
+
|
|
159
|
+
func animateToCoordinate(_ coord: GraniteNaverMapCoordinate) {
|
|
160
|
+
provider?.animateToCoordinate(coord)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
func animateToBounds(_ bounds: GraniteNaverMapBounds, padding: CGFloat) {
|
|
164
|
+
provider?.animateToBounds(bounds, padding: padding)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
func setLayerGroupEnabled(group: String, enabled: Bool) {
|
|
168
|
+
provider?.setLayerGroupEnabled(group: group, enabled: enabled)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
func addMarker(_ data: ProviderMarkerData) {
|
|
172
|
+
provider?.addMarker(data)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
func updateMarker(_ data: ProviderMarkerData) {
|
|
176
|
+
provider?.updateMarker(data)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
func removeMarker(identifier: String) {
|
|
180
|
+
provider?.removeMarker(identifier: identifier)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// MARK: - GraniteNaverMapProviderDelegate
|
|
185
|
+
|
|
186
|
+
extension GraniteNaverMapView: GraniteNaverMapProviderDelegate {
|
|
187
|
+
func mapViewDidInitialize() {
|
|
188
|
+
onInitialized?([:])
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
func mapViewDidChangeCamera(position: GraniteNaverMapCameraPosition) {
|
|
192
|
+
onCameraChange?([
|
|
193
|
+
"latitude": position.target.latitude,
|
|
194
|
+
"longitude": position.target.longitude,
|
|
195
|
+
"zoom": position.zoom
|
|
196
|
+
])
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
func mapViewDidTouch(reason: Int, animated: Bool) {
|
|
200
|
+
onTouch?(["animated": animated, "reason": reason])
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
func mapViewDidClick(x: Double, y: Double, latitude: Double, longitude: Double) {
|
|
204
|
+
onMapClick?([
|
|
205
|
+
"x": x,
|
|
206
|
+
"y": y,
|
|
207
|
+
"latitude": latitude,
|
|
208
|
+
"longitude": longitude
|
|
209
|
+
])
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
func mapViewDidClickMarker(id: String) {
|
|
213
|
+
onMarkerClick?(["id": id])
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BuiltInNaverMapProvider.swift
|
|
3
|
+
// granite-naver-map
|
|
4
|
+
//
|
|
5
|
+
// Built-in provider using NMapsMap SDK
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import UIKit
|
|
9
|
+
import NMapsMap
|
|
10
|
+
|
|
11
|
+
/// Factory for creating BuiltInNaverMapProvider instances.
|
|
12
|
+
/// Each call to createProvider() returns a new instance.
|
|
13
|
+
@objc public class BuiltInNaverMapProviderFactory: NSObject, GraniteNaverMapProviderFactory {
|
|
14
|
+
@objc public func createProvider() -> GraniteNaverMapProvidable {
|
|
15
|
+
return BuiltInNaverMapProvider()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc public class BuiltInNaverMapProvider: NSObject, GraniteNaverMapProvidable {
|
|
20
|
+
private var mapView: NMFNaverMapView?
|
|
21
|
+
private weak var delegate: GraniteNaverMapProviderDelegate?
|
|
22
|
+
private var isInitialized = false
|
|
23
|
+
|
|
24
|
+
private var markers: [String: NMFMarker] = [:]
|
|
25
|
+
private var polylines: [String: NMFPolylineOverlay] = [:]
|
|
26
|
+
private var polygons: [String: NMFPolygonOverlay] = [:]
|
|
27
|
+
private var circles: [String: NMFCircleOverlay] = [:]
|
|
28
|
+
private var paths: [String: NMFPath] = [:]
|
|
29
|
+
|
|
30
|
+
// MARK: - GraniteNaverMapProvidable
|
|
31
|
+
|
|
32
|
+
@objc public func createMapView(frame: CGRect) -> UIView {
|
|
33
|
+
let view = NMFNaverMapView(frame: frame)
|
|
34
|
+
self.mapView = view
|
|
35
|
+
setupMap(view)
|
|
36
|
+
return view
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@objc public func setDelegate(_ delegate: GraniteNaverMapProviderDelegate?) {
|
|
40
|
+
self.delegate = delegate
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private func setupMap(_ view: NMFNaverMapView) {
|
|
44
|
+
view.mapView.touchDelegate = self
|
|
45
|
+
view.mapView.addCameraDelegate(delegate: self)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// MARK: - Camera
|
|
49
|
+
|
|
50
|
+
@objc public func moveCamera(to position: GraniteNaverMapCameraPosition, animated: Bool) {
|
|
51
|
+
guard let mapView = mapView else { return }
|
|
52
|
+
let cameraPosition = NMFCameraPosition(
|
|
53
|
+
NMGLatLng(lat: position.target.latitude, lng: position.target.longitude),
|
|
54
|
+
zoom: position.zoom,
|
|
55
|
+
tilt: position.tilt,
|
|
56
|
+
heading: position.bearing
|
|
57
|
+
)
|
|
58
|
+
let update = NMFCameraUpdate(position: cameraPosition)
|
|
59
|
+
if animated {
|
|
60
|
+
update.animation = .easeIn
|
|
61
|
+
}
|
|
62
|
+
mapView.mapView.moveCamera(update)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@objc public func animateToCoordinate(_ coordinate: GraniteNaverMapCoordinate) {
|
|
66
|
+
guard let mapView = mapView else { return }
|
|
67
|
+
let cameraUpdate = NMFCameraUpdate(scrollTo: NMGLatLng(lat: coordinate.latitude, lng: coordinate.longitude))
|
|
68
|
+
cameraUpdate.animation = .easeIn
|
|
69
|
+
mapView.mapView.moveCamera(cameraUpdate)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@objc public func animateToBounds(_ bounds: GraniteNaverMapBounds, padding: CGFloat) {
|
|
73
|
+
guard let mapView = mapView else { return }
|
|
74
|
+
let nmgBounds = NMGLatLngBounds(
|
|
75
|
+
southWest: NMGLatLng(lat: bounds.southWest.latitude, lng: bounds.southWest.longitude),
|
|
76
|
+
northEast: NMGLatLng(lat: bounds.northEast.latitude, lng: bounds.northEast.longitude)
|
|
77
|
+
)
|
|
78
|
+
let cameraUpdate = NMFCameraUpdate(fit: nmgBounds, padding: padding)
|
|
79
|
+
cameraUpdate.animation = .easeIn
|
|
80
|
+
mapView.mapView.moveCamera(cameraUpdate)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// MARK: - Map Properties
|
|
84
|
+
|
|
85
|
+
@objc public func setMapType(_ type: GraniteNaverMapType) {
|
|
86
|
+
guard let mapView = mapView, let nmfType = NMFMapType(rawValue: type.rawValue) else { return }
|
|
87
|
+
mapView.mapView.mapType = nmfType
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@objc public func setMapPadding(_ padding: UIEdgeInsets) {
|
|
91
|
+
mapView?.mapView.contentInset = padding
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@objc public func setCompassEnabled(_ enabled: Bool) {
|
|
95
|
+
mapView?.showCompass = enabled
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@objc public func setScaleBarEnabled(_ enabled: Bool) {
|
|
99
|
+
mapView?.showScaleBar = enabled
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@objc public func setZoomControlEnabled(_ enabled: Bool) {
|
|
103
|
+
mapView?.showZoomControls = enabled
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@objc public func setLocationButtonEnabled(_ enabled: Bool) {
|
|
107
|
+
mapView?.showLocationButton = enabled
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@objc public func setBuildingHeight(_ height: Float) {
|
|
111
|
+
mapView?.mapView.buildingHeight = height
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@objc public func setNightModeEnabled(_ enabled: Bool) {
|
|
115
|
+
mapView?.mapView.isNightModeEnabled = enabled
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@objc public func setMinZoomLevel(_ level: Double) {
|
|
119
|
+
mapView?.mapView.minZoomLevel = level
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@objc public func setMaxZoomLevel(_ level: Double) {
|
|
123
|
+
mapView?.mapView.maxZoomLevel = level
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@objc public func setScrollGesturesEnabled(_ enabled: Bool) {
|
|
127
|
+
mapView?.mapView.isScrollGestureEnabled = enabled
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@objc public func setZoomGesturesEnabled(_ enabled: Bool) {
|
|
131
|
+
mapView?.mapView.isZoomGestureEnabled = enabled
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@objc public func setTiltGesturesEnabled(_ enabled: Bool) {
|
|
135
|
+
mapView?.mapView.isTiltGestureEnabled = enabled
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@objc public func setRotateGesturesEnabled(_ enabled: Bool) {
|
|
139
|
+
mapView?.mapView.isRotateGestureEnabled = enabled
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@objc public func setStopGesturesEnabled(_ enabled: Bool) {
|
|
143
|
+
mapView?.mapView.isStopGestureEnabled = enabled
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@objc public func setLocationTrackingMode(_ mode: GraniteNaverMapLocationTrackingMode) {
|
|
147
|
+
guard let mapView = mapView else { return }
|
|
148
|
+
mapView.mapView.positionMode = NMFMyPositionMode(rawValue: UInt(mode.rawValue)) ?? .disabled
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@objc public func setLayerGroupEnabled(group: String, enabled: Bool) {
|
|
152
|
+
guard let mapView = mapView else { return }
|
|
153
|
+
let layerGroups: [String: String] = [
|
|
154
|
+
"building": NMF_LAYER_GROUP_BUILDING,
|
|
155
|
+
"ctt": NMF_LAYER_GROUP_TRAFFIC,
|
|
156
|
+
"transit": NMF_LAYER_GROUP_TRANSIT,
|
|
157
|
+
"bike": NMF_LAYER_GROUP_BICYCLE,
|
|
158
|
+
"mountain": NMF_LAYER_GROUP_MOUNTAIN,
|
|
159
|
+
"landparcel": NMF_LAYER_GROUP_CADASTRAL
|
|
160
|
+
]
|
|
161
|
+
guard let layerGroup = layerGroups[group] else { return }
|
|
162
|
+
mapView.mapView.setLayerGroup(layerGroup, isEnabled: enabled)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// MARK: - Markers
|
|
166
|
+
|
|
167
|
+
@objc public func addMarker(_ data: ProviderMarkerData) {
|
|
168
|
+
guard let mapView = mapView else { return }
|
|
169
|
+
|
|
170
|
+
let marker = NMFMarker()
|
|
171
|
+
marker.position = NMGLatLng(lat: data.coordinate.latitude, lng: data.coordinate.longitude)
|
|
172
|
+
marker.width = CGFloat(data.width)
|
|
173
|
+
marker.height = CGFloat(data.height)
|
|
174
|
+
marker.zIndex = data.zIndex
|
|
175
|
+
marker.angle = CGFloat(data.rotation)
|
|
176
|
+
marker.isFlat = data.flat
|
|
177
|
+
marker.alpha = CGFloat(data.alpha)
|
|
178
|
+
|
|
179
|
+
marker.mapView = mapView.mapView
|
|
180
|
+
markers[data.identifier] = marker
|
|
181
|
+
|
|
182
|
+
let identifier = data.identifier
|
|
183
|
+
marker.touchHandler = { [weak self] _ -> Bool in
|
|
184
|
+
self?.delegate?.mapViewDidClickMarker(id: identifier)
|
|
185
|
+
return true
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if !data.image.isEmpty {
|
|
189
|
+
loadMarkerImage(marker: marker, image: data.image)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@objc public func updateMarker(_ data: ProviderMarkerData) {
|
|
194
|
+
guard let marker = markers[data.identifier] else { return }
|
|
195
|
+
|
|
196
|
+
marker.position = NMGLatLng(lat: data.coordinate.latitude, lng: data.coordinate.longitude)
|
|
197
|
+
marker.width = CGFloat(data.width)
|
|
198
|
+
marker.height = CGFloat(data.height)
|
|
199
|
+
marker.zIndex = data.zIndex
|
|
200
|
+
marker.angle = CGFloat(data.rotation)
|
|
201
|
+
marker.isFlat = data.flat
|
|
202
|
+
marker.alpha = CGFloat(data.alpha)
|
|
203
|
+
|
|
204
|
+
if !data.image.isEmpty {
|
|
205
|
+
loadMarkerImage(marker: marker, image: data.image)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@objc public func removeMarker(identifier: String) {
|
|
210
|
+
guard let marker = markers[identifier] else { return }
|
|
211
|
+
marker.mapView = nil
|
|
212
|
+
markers[identifier] = nil
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private func loadMarkerImage(marker: NMFMarker, image: String) {
|
|
216
|
+
if image.hasPrefix("http://") || image.hasPrefix("https://") {
|
|
217
|
+
guard let url = URL(string: image) else { return }
|
|
218
|
+
Task {
|
|
219
|
+
guard let (data, _) = try? await URLSession.shared.data(from: url),
|
|
220
|
+
let uiImage = UIImage(data: data) else { return }
|
|
221
|
+
await MainActor.run {
|
|
222
|
+
marker.iconImage = NMFOverlayImage(image: uiImage)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
marker.iconImage = NMFOverlayImage(name: image)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// MARK: - Polylines
|
|
231
|
+
|
|
232
|
+
private func colorFromInt(_ value: Int) -> UIColor {
|
|
233
|
+
let uValue = UInt32(bitPattern: Int32(truncatingIfNeeded: value))
|
|
234
|
+
let alpha = CGFloat((uValue >> 24) & 0xFF) / 255.0
|
|
235
|
+
let red = CGFloat((uValue >> 16) & 0xFF) / 255.0
|
|
236
|
+
let green = CGFloat((uValue >> 8) & 0xFF) / 255.0
|
|
237
|
+
let blue = CGFloat(uValue & 0xFF) / 255.0
|
|
238
|
+
return UIColor(red: red, green: green, blue: blue, alpha: alpha)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private func lineCapType(_ value: Int) -> NMFOverlayLineCap {
|
|
242
|
+
switch value {
|
|
243
|
+
case 1: return .round
|
|
244
|
+
case 2: return .square
|
|
245
|
+
default: return .butt
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private func lineJoinType(_ value: Int) -> NMFOverlayLineJoin {
|
|
250
|
+
switch value {
|
|
251
|
+
case 1: return .miter
|
|
252
|
+
case 2: return .round
|
|
253
|
+
default: return .bevel
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@objc public func addPolyline(_ data: ProviderPolylineData) {
|
|
258
|
+
guard let mapView = mapView else { return }
|
|
259
|
+
|
|
260
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
261
|
+
guard coords.count >= 2 else { return }
|
|
262
|
+
|
|
263
|
+
let polyline = NMFPolylineOverlay(NMGLineString(points: coords))
|
|
264
|
+
polyline?.width = CGFloat(data.strokeWidth)
|
|
265
|
+
polyline?.color = colorFromInt(data.strokeColor)
|
|
266
|
+
polyline?.zIndex = data.zIndex
|
|
267
|
+
polyline?.capType = lineCapType(data.lineCap)
|
|
268
|
+
polyline?.joinType = lineJoinType(data.lineJoin)
|
|
269
|
+
|
|
270
|
+
if !data.pattern.isEmpty {
|
|
271
|
+
polyline?.pattern = data.pattern.map { NSNumber(value: $0) }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
polyline?.mapView = mapView.mapView
|
|
275
|
+
if let polyline = polyline {
|
|
276
|
+
polylines[data.identifier] = polyline
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
@objc public func updatePolyline(_ data: ProviderPolylineData) {
|
|
281
|
+
guard let polyline = polylines[data.identifier] else { return }
|
|
282
|
+
|
|
283
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
284
|
+
if coords.count >= 2 {
|
|
285
|
+
polyline.line = NMGLineString(points: coords)
|
|
286
|
+
}
|
|
287
|
+
polyline.width = CGFloat(data.strokeWidth)
|
|
288
|
+
polyline.color = colorFromInt(data.strokeColor)
|
|
289
|
+
polyline.zIndex = data.zIndex
|
|
290
|
+
polyline.capType = lineCapType(data.lineCap)
|
|
291
|
+
polyline.joinType = lineJoinType(data.lineJoin)
|
|
292
|
+
|
|
293
|
+
if !data.pattern.isEmpty {
|
|
294
|
+
polyline.pattern = data.pattern.map { NSNumber(value: $0) }
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@objc public func removePolyline(identifier: String) {
|
|
299
|
+
guard let polyline = polylines[identifier] else { return }
|
|
300
|
+
polyline.mapView = nil
|
|
301
|
+
polylines[identifier] = nil
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// MARK: - Polygons
|
|
305
|
+
|
|
306
|
+
@objc public func addPolygon(_ data: ProviderPolygonData) {
|
|
307
|
+
guard let mapView = mapView else { return }
|
|
308
|
+
|
|
309
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
310
|
+
guard coords.count >= 3 else { return }
|
|
311
|
+
|
|
312
|
+
let exteriorRing = NMGLineString(points: coords)
|
|
313
|
+
|
|
314
|
+
let nmgPolygon: NMGPolygon<AnyObject>
|
|
315
|
+
if data.holes.isEmpty {
|
|
316
|
+
nmgPolygon = unsafeBitCast(NMGPolygon(ring: exteriorRing), to: NMGPolygon<AnyObject>.self)
|
|
317
|
+
} else {
|
|
318
|
+
let interiorRings = data.holes.map { hole in
|
|
319
|
+
NMGLineString(points: hole.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) })
|
|
320
|
+
}
|
|
321
|
+
nmgPolygon = unsafeBitCast(NMGPolygon(ring: exteriorRing, interiorRings: interiorRings), to: NMGPolygon<AnyObject>.self)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let polygon = NMFPolygonOverlay(nmgPolygon)
|
|
325
|
+
polygon?.fillColor = colorFromInt(data.fillColor)
|
|
326
|
+
polygon?.outlineColor = colorFromInt(data.strokeColor)
|
|
327
|
+
polygon?.outlineWidth = UInt(data.strokeWidth)
|
|
328
|
+
polygon?.zIndex = data.zIndex
|
|
329
|
+
polygon?.mapView = mapView.mapView
|
|
330
|
+
if let polygon = polygon {
|
|
331
|
+
polygons[data.identifier] = polygon
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
@objc public func updatePolygon(_ data: ProviderPolygonData) {
|
|
336
|
+
guard let polygon = polygons[data.identifier] else { return }
|
|
337
|
+
|
|
338
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
339
|
+
if coords.count >= 3 {
|
|
340
|
+
let exteriorRing = NMGLineString(points: coords)
|
|
341
|
+
|
|
342
|
+
if data.holes.isEmpty {
|
|
343
|
+
let nmgPolygon = NMGPolygon(ring: exteriorRing)
|
|
344
|
+
polygon.polygon = unsafeBitCast(nmgPolygon, to: NMGPolygon<AnyObject>.self)
|
|
345
|
+
} else {
|
|
346
|
+
let interiorRings = data.holes.map { hole in
|
|
347
|
+
NMGLineString(points: hole.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) })
|
|
348
|
+
}
|
|
349
|
+
let nmgPolygon = NMGPolygon(ring: exteriorRing, interiorRings: interiorRings)
|
|
350
|
+
polygon.polygon = unsafeBitCast(nmgPolygon, to: NMGPolygon<AnyObject>.self)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
polygon.fillColor = colorFromInt(data.fillColor)
|
|
355
|
+
polygon.outlineColor = colorFromInt(data.strokeColor)
|
|
356
|
+
polygon.outlineWidth = UInt(data.strokeWidth)
|
|
357
|
+
polygon.zIndex = data.zIndex
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@objc public func removePolygon(identifier: String) {
|
|
361
|
+
guard let polygon = polygons[identifier] else { return }
|
|
362
|
+
polygon.mapView = nil
|
|
363
|
+
polygons[identifier] = nil
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// MARK: - Circles
|
|
367
|
+
|
|
368
|
+
@objc public func addCircle(_ data: ProviderCircleData) {
|
|
369
|
+
guard let mapView = mapView else { return }
|
|
370
|
+
|
|
371
|
+
let circle = NMFCircleOverlay(NMGLatLng(lat: data.center.latitude, lng: data.center.longitude), radius: data.radius)
|
|
372
|
+
circle.fillColor = colorFromInt(data.fillColor)
|
|
373
|
+
circle.outlineColor = colorFromInt(data.strokeColor)
|
|
374
|
+
circle.outlineWidth = Double(data.strokeWidth)
|
|
375
|
+
circle.zIndex = data.zIndex
|
|
376
|
+
circle.mapView = mapView.mapView
|
|
377
|
+
circles[data.identifier] = circle
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
@objc public func updateCircle(_ data: ProviderCircleData) {
|
|
381
|
+
guard let circle = circles[data.identifier] else { return }
|
|
382
|
+
|
|
383
|
+
circle.center = NMGLatLng(lat: data.center.latitude, lng: data.center.longitude)
|
|
384
|
+
circle.radius = data.radius
|
|
385
|
+
circle.fillColor = colorFromInt(data.fillColor)
|
|
386
|
+
circle.outlineColor = colorFromInt(data.strokeColor)
|
|
387
|
+
circle.outlineWidth = Double(data.strokeWidth)
|
|
388
|
+
circle.zIndex = data.zIndex
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
@objc public func removeCircle(identifier: String) {
|
|
392
|
+
guard let circle = circles[identifier] else { return }
|
|
393
|
+
circle.mapView = nil
|
|
394
|
+
circles[identifier] = nil
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// MARK: - Paths
|
|
398
|
+
|
|
399
|
+
@objc public func addPath(_ data: ProviderPathData) {
|
|
400
|
+
guard let mapView = mapView else { return }
|
|
401
|
+
|
|
402
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
403
|
+
guard coords.count >= 2 else { return }
|
|
404
|
+
|
|
405
|
+
let path = NMFPath(points: coords)
|
|
406
|
+
path?.width = CGFloat(data.width)
|
|
407
|
+
path?.outlineWidth = CGFloat(data.outlineWidth)
|
|
408
|
+
path?.color = colorFromInt(data.color)
|
|
409
|
+
path?.outlineColor = colorFromInt(data.outlineColor)
|
|
410
|
+
path?.passedColor = colorFromInt(data.passedColor)
|
|
411
|
+
path?.passedOutlineColor = colorFromInt(data.passedOutlineColor)
|
|
412
|
+
path?.progress = Double(data.progress)
|
|
413
|
+
path?.zIndex = data.zIndex
|
|
414
|
+
|
|
415
|
+
if !data.patternImage.isEmpty {
|
|
416
|
+
path?.patternIcon = NMFOverlayImage(name: data.patternImage)
|
|
417
|
+
path?.patternInterval = UInt(data.patternInterval)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
path?.mapView = mapView.mapView
|
|
421
|
+
if let path = path {
|
|
422
|
+
paths[data.identifier] = path
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
@objc public func updatePath(_ data: ProviderPathData) {
|
|
427
|
+
guard let path = paths[data.identifier] else { return }
|
|
428
|
+
|
|
429
|
+
let coords = data.coordinates.map { NMGLatLng(lat: $0.latitude, lng: $0.longitude) }
|
|
430
|
+
if coords.count >= 2 {
|
|
431
|
+
path.path = NMGLineString(points: coords)
|
|
432
|
+
}
|
|
433
|
+
path.width = CGFloat(data.width)
|
|
434
|
+
path.outlineWidth = CGFloat(data.outlineWidth)
|
|
435
|
+
path.color = colorFromInt(data.color)
|
|
436
|
+
path.outlineColor = colorFromInt(data.outlineColor)
|
|
437
|
+
path.passedColor = colorFromInt(data.passedColor)
|
|
438
|
+
path.passedOutlineColor = colorFromInt(data.passedOutlineColor)
|
|
439
|
+
path.progress = Double(data.progress)
|
|
440
|
+
path.zIndex = data.zIndex
|
|
441
|
+
|
|
442
|
+
if !data.patternImage.isEmpty {
|
|
443
|
+
path.patternIcon = NMFOverlayImage(name: data.patternImage)
|
|
444
|
+
path.patternInterval = UInt(data.patternInterval)
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
@objc public func removePath(identifier: String) {
|
|
449
|
+
guard let path = paths[identifier] else { return }
|
|
450
|
+
path.mapView = nil
|
|
451
|
+
paths[identifier] = nil
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// MARK: - Internal
|
|
455
|
+
|
|
456
|
+
func notifyInitialized() {
|
|
457
|
+
if !isInitialized {
|
|
458
|
+
isInitialized = true
|
|
459
|
+
delegate?.mapViewDidInitialize()
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// MARK: - NMFMapViewTouchDelegate
|
|
465
|
+
|
|
466
|
+
extension BuiltInNaverMapProvider: NMFMapViewTouchDelegate {
|
|
467
|
+
public func mapView(_ mapView: NMFMapView, didTapMap latlng: NMGLatLng, point: CGPoint) {
|
|
468
|
+
delegate?.mapViewDidClick(x: point.x, y: point.y, latitude: latlng.lat, longitude: latlng.lng)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// MARK: - NMFMapViewCameraDelegate
|
|
473
|
+
|
|
474
|
+
extension BuiltInNaverMapProvider: NMFMapViewCameraDelegate {
|
|
475
|
+
public func mapView(_ mapView: NMFMapView, cameraWillChangeByReason reason: Int, animated: Bool) {
|
|
476
|
+
delegate?.mapViewDidTouch(reason: reason, animated: animated)
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
public func mapViewCameraIdle(_ mapView: NMFMapView) {
|
|
480
|
+
let position = mapView.cameraPosition
|
|
481
|
+
let cameraPosition = GraniteNaverMapCameraPosition(
|
|
482
|
+
target: GraniteNaverMapCoordinate(latitude: position.target.lat, longitude: position.target.lng),
|
|
483
|
+
zoom: position.zoom,
|
|
484
|
+
tilt: position.tilt,
|
|
485
|
+
bearing: position.heading
|
|
486
|
+
)
|
|
487
|
+
delegate?.mapViewDidChangeCamera(position: cameraPosition)
|
|
488
|
+
}
|
|
489
|
+
}
|