react-native-google-maps-plus 1.4.1 → 1.6.0-dev.1
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/README.md +21 -0
- package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +41 -144
- package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +38 -36
- package/android/src/main/java/com/rngooglemapsplus/extensions/CameraPositionExtension.kt +12 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/IntExtension.kt +28 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/LatLngBounds.kt +15 -0
- package/android/src/main/java/com/rngooglemapsplus/extensions/LocationExtension.kt +59 -0
- package/app.plugin.js +1 -0
- package/expoConfig/build/android/withAndroidGoogleMapsPlus.js +21 -0
- package/expoConfig/build/index.js +17 -0
- package/expoConfig/build/ios/withIosGoogleMapsPlus.js +91 -0
- package/expoConfig/build/types.js +2 -0
- package/ios/GoogleMapViewImpl.swift +28 -138
- package/ios/LocationHandler.swift +5 -13
- package/ios/MapHelper.swift +20 -0
- package/ios/MapMarkerBuilder.swift +44 -69
- package/ios/RNGoogleMapsPlusView.swift +12 -8
- package/ios/extensions/CLError+Extension.swift +14 -0
- package/ios/extensions/CLLocation+Extension.swift +27 -0
- package/ios/extensions/GMSCameraPosition+Extension.swift +12 -0
- package/ios/extensions/GMSCoordinateBounds+Extension.swift +19 -0
- package/ios/extensions/RNMarker+Extension.swift +2 -3
- package/lib/module/GoogleMapsPlus.js +7 -0
- package/lib/module/GoogleMapsPlus.js.map +1 -0
- package/lib/module/index.js +3 -5
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +44 -0
- package/lib/typescript/src/GoogleMapsPlus.d.ts +5 -0
- package/lib/typescript/src/GoogleMapsPlus.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +25 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_RNLocation.hpp +6 -0
- package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +8 -0
- package/nitrogen/generated/android/c++/JRNAndroidLocationConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNCamera.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNCircle.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNHeatmap.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNHeatmapGradient.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNHeatmapPoint.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNIOSLocationConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNIndoorBuilding.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNIndoorLevel.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNInitialProps.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNKMLayer.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNLatLng.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNLatLngBounds.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNLocation.hpp +37 -3
- package/nitrogen/generated/android/c++/JRNLocationAndroid.hpp +86 -0
- package/nitrogen/generated/android/c++/JRNLocationConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNLocationIOS.hpp +81 -0
- package/nitrogen/generated/android/c++/JRNLocationPermissionResult.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNMapPadding.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNMapZoomConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNMarker.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNMarkerSvg.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNPolygon.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNPolygonHole.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNPolyline.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNPosition.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNRegion.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNSize.hpp +5 -1
- package/nitrogen/generated/android/c++/JRNSnapshotOptions.hpp +5 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusModuleSpec.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationConfig.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCamera.kt +22 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCircle.kt +36 -28
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNHeatmap.kt +31 -23
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNHeatmapGradient.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNHeatmapPoint.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationConfig.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIndoorBuilding.kt +22 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIndoorLevel.kt +22 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNKMLayer.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLng.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLngBounds.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocation.kt +34 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationAndroid.kt +58 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationConfig.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationIOS.kt +55 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationPermissionResult.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapPadding.kt +22 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +43 -35
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapZoomConfig.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +49 -41
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarkerSvg.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygon.kt +39 -31
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygonHole.kt +13 -5
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolyline.kt +39 -31
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPosition.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNRegion.kt +19 -11
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSize.kt +16 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNSnapshotOptions.kt +22 -14
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewManager.kt +7 -2
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +36 -0
- package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +6 -0
- package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +6 -0
- package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +8 -0
- package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +56 -7
- package/nitrogen/generated/ios/swift/RNCircle.swift +8 -1
- package/nitrogen/generated/ios/swift/RNHeatmap.swift +8 -1
- package/nitrogen/generated/ios/swift/RNIndoorBuilding.swift +8 -1
- package/nitrogen/generated/ios/swift/RNIndoorLevel.swift +8 -1
- package/nitrogen/generated/ios/swift/RNInitialProps.swift +8 -1
- package/nitrogen/generated/ios/swift/RNLocation.swift +92 -2
- package/nitrogen/generated/ios/swift/RNLocationAndroid.swift +222 -0
- package/nitrogen/generated/ios/swift/RNLocationIOS.swift +192 -0
- package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +88 -11
- package/nitrogen/generated/ios/swift/RNMarker.swift +24 -3
- package/nitrogen/generated/ios/swift/RNPolygon.swift +16 -2
- package/nitrogen/generated/ios/swift/RNPolyline.swift +16 -2
- package/nitrogen/generated/shared/c++/RNLocation.hpp +33 -2
- package/nitrogen/generated/shared/c++/RNLocationAndroid.hpp +104 -0
- package/nitrogen/generated/shared/c++/RNLocationIOS.hpp +99 -0
- package/package.json +20 -17
- package/src/GoogleMapsPlus.tsx +20 -0
- package/src/index.tsx +6 -14
- package/src/types.ts +27 -0
- package/lib/module/package.json +0 -1
- package/lib/typescript/package.json +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
+
var generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
|
|
5
|
+
var withIosGoogleMapsPlus = function (config, props) {
|
|
6
|
+
config = (0, config_plugins_1.withInfoPlist)(config, function (conf) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
var apiKey = (_b = (_a = props.googleMapsIosApiKey) !== null && _a !== void 0 ? _a : process.env.GOOGLE_MAPS_API_KEY_IOS) !== null && _b !== void 0 ? _b : null;
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
console.warn('[react-native-google-maps-plus] No iOS API key provided. Google Maps may fail to initialize.');
|
|
11
|
+
}
|
|
12
|
+
if (apiKey) {
|
|
13
|
+
conf.modResults.MAPS_API_KEY = apiKey;
|
|
14
|
+
}
|
|
15
|
+
return conf;
|
|
16
|
+
});
|
|
17
|
+
config = (0, config_plugins_1.withPodfile)(config, function (conf) {
|
|
18
|
+
var src = conf.modResults.contents;
|
|
19
|
+
if (!src.includes('use_modular_headers!')) {
|
|
20
|
+
src = (0, generateCode_1.mergeContents)({
|
|
21
|
+
tag: 'react-native-google-maps-modular-headers',
|
|
22
|
+
src: src,
|
|
23
|
+
newSrc: 'use_modular_headers!',
|
|
24
|
+
anchor: /use_frameworks!|platform\s+:ios.*/,
|
|
25
|
+
offset: 1,
|
|
26
|
+
comment: '#',
|
|
27
|
+
}).contents;
|
|
28
|
+
}
|
|
29
|
+
var patchSnippet = "\n # Force iOS 16+ to avoid deployment target warnings\n installer.pods_project.targets.each do |target|\n target.build_configurations.each do |config|\n config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'\n end\n end\n\n # --- SVGKit Patch ---\n require 'fileutils'\n svgkit_path = File.join(installer.sandbox.pod_dir('SVGKit'), 'Source')\n\n # --- Patch Node.h imports ---\n Dir.glob(File.join(svgkit_path, '**', '*.{h,m}')).each do |file|\n FileUtils.chmod(\"u+w\", file)\n text = File.read(file)\n new_contents = text.gsub('#import \"Node.h\"', '#import \"SVGKit/Node.h\"')\n File.open(file, 'w') { |f| f.write(new_contents) }\n end\n\n # --- Patch CSSValue.h imports ---\n Dir.glob(File.join(svgkit_path, '**', '*.{h,m}')).each do |file|\n FileUtils.chmod(\"u+w\", file)\n text = File.read(file)\n new_contents = text.gsub('#import \"CSSValue.h\"', '#import \"SVGKit/CSSValue.h\"')\n File.open(file, 'w') { |f| f.write(new_contents) }\n end\n\n # --- Patch SVGLength.h imports ---\n Dir.glob(File.join(svgkit_path, '**', '*.{h,m}')).each do |file|\n FileUtils.chmod(\"u+w\", file)\n text = File.read(file)\n new_contents = text.gsub('#import \"SVGLength.h\"', '#import \"SVGKit/SVGLength.h\"')\n File.open(file, 'w') { |f| f.write(new_contents) }\n end\n ";
|
|
30
|
+
if (src.includes('post_install do |installer|')) {
|
|
31
|
+
src = src.replace(/post_install do \|installer\|([\s\S]*?)end/, function (match, inner) {
|
|
32
|
+
if (inner.includes('SVGKit Patch'))
|
|
33
|
+
return match; // idempotent
|
|
34
|
+
return "post_install do |installer|".concat(inner, "\n").concat(patchSnippet, "\nend");
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
src += "\npost_install do |installer|\n".concat(patchSnippet, "\nend\n");
|
|
39
|
+
}
|
|
40
|
+
conf.modResults.contents = src;
|
|
41
|
+
return conf;
|
|
42
|
+
});
|
|
43
|
+
config = (0, config_plugins_1.withAppDelegate)(config, function (conf) {
|
|
44
|
+
var language = conf.modResults.language;
|
|
45
|
+
if (language !== 'swift') {
|
|
46
|
+
console.warn('[react-native-google-maps-plus] AppDelegate is not Swift; skipping GMSServices injection.');
|
|
47
|
+
return conf;
|
|
48
|
+
}
|
|
49
|
+
var src = conf.modResults.contents;
|
|
50
|
+
if (!src.includes('import GoogleMaps')) {
|
|
51
|
+
src = (0, generateCode_1.mergeContents)({
|
|
52
|
+
tag: 'react-native-google-maps-import',
|
|
53
|
+
src: src,
|
|
54
|
+
newSrc: 'import GoogleMaps',
|
|
55
|
+
anchor: /^import React/m,
|
|
56
|
+
offset: 1,
|
|
57
|
+
comment: '//',
|
|
58
|
+
}).contents;
|
|
59
|
+
}
|
|
60
|
+
var initSnippet = "\n if let apiKey = Bundle.main.object(forInfoDictionaryKey: \"MAPS_API_KEY\") as? String {\n GMSServices.provideAPIKey(apiKey)\n }";
|
|
61
|
+
try {
|
|
62
|
+
src = (0, generateCode_1.mergeContents)({
|
|
63
|
+
tag: 'react-native-google-maps-init',
|
|
64
|
+
src: src,
|
|
65
|
+
newSrc: initSnippet,
|
|
66
|
+
anchor: /return\s+super\.application\s*\(\s*application\s*,\s*didFinishLaunchingWithOptions:\s*launchOptions\s*\)/,
|
|
67
|
+
offset: -1,
|
|
68
|
+
comment: '//',
|
|
69
|
+
}).contents;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === 'ERR_NO_MATCH') {
|
|
73
|
+
src = (0, generateCode_1.mergeContents)({
|
|
74
|
+
tag: 'react-native-google-maps-init',
|
|
75
|
+
src: src,
|
|
76
|
+
newSrc: initSnippet,
|
|
77
|
+
anchor: /didFinishLaunchingWithOptions[^{]*\{/,
|
|
78
|
+
offset: 1,
|
|
79
|
+
comment: '//',
|
|
80
|
+
}).contents;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
conf.modResults.contents = src;
|
|
87
|
+
return conf;
|
|
88
|
+
});
|
|
89
|
+
return config;
|
|
90
|
+
};
|
|
91
|
+
exports.default = withIosGoogleMapsPlus;
|
|
@@ -11,6 +11,7 @@ GMSIndoorDisplayDelegate {
|
|
|
11
11
|
private var mapView: GMSMapView?
|
|
12
12
|
private var initialized = false
|
|
13
13
|
private var mapReady = false
|
|
14
|
+
private var deInitialized = false
|
|
14
15
|
|
|
15
16
|
private var pendingMarkers: [(id: String, marker: GMSMarker)] = []
|
|
16
17
|
private var pendingPolylines: [(id: String, polyline: GMSPolyline)] = []
|
|
@@ -28,7 +29,6 @@ GMSIndoorDisplayDelegate {
|
|
|
28
29
|
|
|
29
30
|
private var cameraMoveReasonIsGesture: Bool = false
|
|
30
31
|
private var lastSubmittedCameraPosition: GMSCameraPosition?
|
|
31
|
-
private var lastSubmittedLocation: CLLocation?
|
|
32
32
|
|
|
33
33
|
init(
|
|
34
34
|
frame: CGRect = .zero,
|
|
@@ -72,8 +72,8 @@ GMSIndoorDisplayDelegate {
|
|
|
72
72
|
mapView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
73
73
|
mapView?.paddingAdjustmentBehavior = .never
|
|
74
74
|
mapView.map { addSubview($0) }
|
|
75
|
+
applyProps()
|
|
75
76
|
initLocationCallbacks()
|
|
76
|
-
applyPending()
|
|
77
77
|
onMapReady?(true)
|
|
78
78
|
mapReady = true
|
|
79
79
|
}
|
|
@@ -82,18 +82,7 @@ GMSIndoorDisplayDelegate {
|
|
|
82
82
|
private func initLocationCallbacks() {
|
|
83
83
|
locationHandler.onUpdate = { [weak self] loc in
|
|
84
84
|
guard let self = self else { return }
|
|
85
|
-
|
|
86
|
-
!= loc.coordinate.latitude
|
|
87
|
-
|| self.lastSubmittedLocation?.coordinate.longitude
|
|
88
|
-
!= loc.coordinate.longitude {
|
|
89
|
-
self.onLocationUpdate?(
|
|
90
|
-
RNLocation(
|
|
91
|
-
loc.coordinate.toRNLatLng(),
|
|
92
|
-
loc.course
|
|
93
|
-
)
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
self.lastSubmittedLocation = loc
|
|
85
|
+
self.onLocationUpdate?(loc.toRnLocation())
|
|
97
86
|
}
|
|
98
87
|
locationHandler.onError = { [weak self] error in
|
|
99
88
|
self?.onLocationError?(error)
|
|
@@ -102,55 +91,19 @@ GMSIndoorDisplayDelegate {
|
|
|
102
91
|
}
|
|
103
92
|
|
|
104
93
|
@MainActor
|
|
105
|
-
private func
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
v.compassEnabled.map { mapView?.settings.compassButton = $0 }
|
|
118
|
-
v.indoorLevelPickerEnabled.map { mapView?.settings.indoorPicker = $0 }
|
|
119
|
-
v.mapToolbarEnabled.map { _ in /* not supported */ }
|
|
120
|
-
v.myLocationButtonEnabled.map { mapView?.settings.myLocationButton = $0 }
|
|
121
|
-
v.rotateEnabled.map { mapView?.settings.rotateGestures = $0 }
|
|
122
|
-
v.scrollEnabled.map { mapView?.settings.scrollGestures = $0 }
|
|
123
|
-
v.scrollDuringRotateOrZoomEnabled.map {
|
|
124
|
-
mapView?.settings.allowScrollGesturesDuringRotateOrZoom = $0
|
|
125
|
-
}
|
|
126
|
-
v.tiltEnabled.map { mapView?.settings.tiltGestures = $0 }
|
|
127
|
-
v.zoomControlsEnabled.map { _ in /* not supported */ }
|
|
128
|
-
v.zoomGesturesEnabled.map { mapView?.settings.zoomGestures = $0 }
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
myLocationEnabled.map { mapView?.isMyLocationEnabled = $0 }
|
|
132
|
-
buildingEnabled.map { mapView?.isBuildingsEnabled = $0 }
|
|
133
|
-
trafficEnabled.map { mapView?.isTrafficEnabled = $0 }
|
|
134
|
-
indoorEnabled.map {
|
|
135
|
-
mapView?.isIndoorEnabled = $0
|
|
136
|
-
mapView?.indoorDisplay.delegate = $0 == true ? self : nil
|
|
137
|
-
}
|
|
138
|
-
customMapStyle.map { mapView?.mapStyle = $0 }
|
|
139
|
-
mapType.map { mapView?.mapType = $0 }
|
|
140
|
-
userInterfaceStyle.map { mapView?.overrideUserInterfaceStyle = $0 }
|
|
94
|
+
private func applyProps() {
|
|
95
|
+
({ self.uiSettings = self.uiSettings })()
|
|
96
|
+
({ self.mapPadding = self.mapPadding })()
|
|
97
|
+
({ self.myLocationEnabled = self.myLocationEnabled })()
|
|
98
|
+
({ self.buildingEnabled = self.buildingEnabled })()
|
|
99
|
+
({ self.trafficEnabled = self.trafficEnabled })()
|
|
100
|
+
({ self.indoorEnabled = self.indoorEnabled })()
|
|
101
|
+
({ self.customMapStyle = self.customMapStyle })()
|
|
102
|
+
({ self.mapType = self.mapType })()
|
|
103
|
+
({ self.userInterfaceStyle = self.userInterfaceStyle })()
|
|
104
|
+
({ self.mapZoomConfig = self.mapZoomConfig })()
|
|
105
|
+
({ self.locationConfig = self.locationConfig })()
|
|
141
106
|
|
|
142
|
-
mapZoomConfig.map {
|
|
143
|
-
mapView?.setMinZoom(
|
|
144
|
-
Float($0.min ?? 2),
|
|
145
|
-
maxZoom: Float($0.max ?? 21)
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
locationConfig.map {
|
|
150
|
-
locationHandler.desiredAccuracy =
|
|
151
|
-
$0.ios?.desiredAccuracy?.toCLLocationAccuracy
|
|
152
|
-
locationHandler.distanceFilterMeters = $0.ios?.distanceFilterMeters
|
|
153
|
-
}
|
|
154
107
|
if !pendingMarkers.isEmpty {
|
|
155
108
|
pendingMarkers.forEach { addMarkerInternal(id: $0.id, marker: $0.marker) }
|
|
156
109
|
pendingMarkers.removeAll()
|
|
@@ -402,7 +355,7 @@ GMSIndoorDisplayDelegate {
|
|
|
402
355
|
) -> NitroModules.Promise<String?> {
|
|
403
356
|
let promise = Promise<String?>()
|
|
404
357
|
|
|
405
|
-
|
|
358
|
+
onMainAsync {
|
|
406
359
|
guard let mapView = self.mapView else {
|
|
407
360
|
promise.resolve(withResult: nil)
|
|
408
361
|
return
|
|
@@ -435,7 +388,6 @@ GMSIndoorDisplayDelegate {
|
|
|
435
388
|
return
|
|
436
389
|
}
|
|
437
390
|
|
|
438
|
-
// Rückgabe
|
|
439
391
|
if resultIsFile {
|
|
440
392
|
let filename =
|
|
441
393
|
"map_snapshot_\(Int(Date().timeIntervalSince1970)).\(format)"
|
|
@@ -660,6 +612,8 @@ GMSIndoorDisplayDelegate {
|
|
|
660
612
|
}
|
|
661
613
|
|
|
662
614
|
func deinitInternal() {
|
|
615
|
+
guard !deInitialized else { return }
|
|
616
|
+
deInitialized = true
|
|
663
617
|
onMain {
|
|
664
618
|
self.locationHandler.stop()
|
|
665
619
|
self.markerBuilder.cancelAllIconTasks()
|
|
@@ -703,33 +657,14 @@ GMSIndoorDisplayDelegate {
|
|
|
703
657
|
|
|
704
658
|
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
|
|
705
659
|
onMain {
|
|
660
|
+
self.cameraMoveReasonIsGesture = gesture
|
|
706
661
|
let visibleRegion = mapView.projection.visibleRegion()
|
|
707
662
|
let bounds = GMSCoordinateBounds(region: visibleRegion)
|
|
708
663
|
|
|
709
|
-
let
|
|
710
|
-
|
|
711
|
-
longitude: (bounds.northEast.longitude + bounds.southWest.longitude)
|
|
712
|
-
/ 2.0
|
|
713
|
-
)
|
|
664
|
+
let region = bounds.toRNRegion()
|
|
665
|
+
let camera = mapView.camera.toRNCamera()
|
|
714
666
|
|
|
715
|
-
|
|
716
|
-
let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
|
|
717
|
-
|
|
718
|
-
let cp = mapView.camera
|
|
719
|
-
let region = RNRegion(
|
|
720
|
-
center: center.toRNLatLng(),
|
|
721
|
-
latitudeDelta: latDelta,
|
|
722
|
-
longitudeDelta: lngDelta
|
|
723
|
-
)
|
|
724
|
-
let cam = RNCamera(
|
|
725
|
-
center: cp.target.toRNLatLng(),
|
|
726
|
-
zoom: Double(cp.zoom),
|
|
727
|
-
bearing: cp.bearing,
|
|
728
|
-
tilt: cp.viewingAngle
|
|
729
|
-
)
|
|
730
|
-
self.cameraMoveReasonIsGesture = gesture
|
|
731
|
-
|
|
732
|
-
self.onCameraChangeStart?(region, cam, gesture)
|
|
667
|
+
self.onCameraChange?(region, camera, gesture)
|
|
733
668
|
}
|
|
734
669
|
}
|
|
735
670
|
|
|
@@ -748,28 +683,10 @@ GMSIndoorDisplayDelegate {
|
|
|
748
683
|
let visibleRegion = mapView.projection.visibleRegion()
|
|
749
684
|
let bounds = GMSCoordinateBounds(region: visibleRegion)
|
|
750
685
|
|
|
751
|
-
let
|
|
752
|
-
|
|
753
|
-
longitude: (bounds.northEast.longitude + bounds.southWest.longitude)
|
|
754
|
-
/ 2.0
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
let latDelta = bounds.northEast.latitude - bounds.southWest.latitude
|
|
758
|
-
let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
|
|
686
|
+
let region = bounds.toRNRegion()
|
|
687
|
+
let camera = mapView.camera.toRNCamera()
|
|
759
688
|
|
|
760
|
-
|
|
761
|
-
let region = RNRegion(
|
|
762
|
-
center: center.toRNLatLng(),
|
|
763
|
-
latitudeDelta: latDelta,
|
|
764
|
-
longitudeDelta: lngDelta
|
|
765
|
-
)
|
|
766
|
-
let cam = RNCamera(
|
|
767
|
-
center: cp.target.toRNLatLng(),
|
|
768
|
-
zoom: Double(cp.zoom),
|
|
769
|
-
bearing: cp.bearing,
|
|
770
|
-
tilt: cp.viewingAngle
|
|
771
|
-
)
|
|
772
|
-
self.onCameraChange?(region, cam, self.cameraMoveReasonIsGesture)
|
|
689
|
+
self.onCameraChange?(region, camera, self.cameraMoveReasonIsGesture)
|
|
773
690
|
}
|
|
774
691
|
}
|
|
775
692
|
|
|
@@ -778,28 +695,10 @@ GMSIndoorDisplayDelegate {
|
|
|
778
695
|
let visibleRegion = mapView.projection.visibleRegion()
|
|
779
696
|
let bounds = GMSCoordinateBounds(region: visibleRegion)
|
|
780
697
|
|
|
781
|
-
let
|
|
782
|
-
|
|
783
|
-
longitude: (bounds.northEast.longitude + bounds.southWest.longitude)
|
|
784
|
-
/ 2.0
|
|
785
|
-
)
|
|
786
|
-
|
|
787
|
-
let latDelta = bounds.northEast.latitude - bounds.southWest.latitude
|
|
788
|
-
let lngDelta = bounds.northEast.longitude - bounds.southWest.longitude
|
|
698
|
+
let region = bounds.toRNRegion()
|
|
699
|
+
let camera = mapView.camera.toRNCamera()
|
|
789
700
|
|
|
790
|
-
|
|
791
|
-
let region = RNRegion(
|
|
792
|
-
center: center.toRNLatLng(),
|
|
793
|
-
latitudeDelta: latDelta,
|
|
794
|
-
longitudeDelta: lngDelta
|
|
795
|
-
)
|
|
796
|
-
let cam = RNCamera(
|
|
797
|
-
center: cp.target.toRNLatLng(),
|
|
798
|
-
zoom: Double(cp.zoom),
|
|
799
|
-
bearing: cp.bearing,
|
|
800
|
-
tilt: cp.viewingAngle
|
|
801
|
-
)
|
|
802
|
-
self.onCameraChangeComplete?(region, cam, self.cameraMoveReasonIsGesture)
|
|
701
|
+
self.onCameraChange?(region, camera, self.cameraMoveReasonIsGesture)
|
|
803
702
|
}
|
|
804
703
|
}
|
|
805
704
|
|
|
@@ -893,12 +792,3 @@ GMSIndoorDisplayDelegate {
|
|
|
893
792
|
}
|
|
894
793
|
}
|
|
895
794
|
}
|
|
896
|
-
|
|
897
|
-
@inline(__always)
|
|
898
|
-
func onMain(_ block: @escaping () -> Void) {
|
|
899
|
-
if Thread.isMainThread {
|
|
900
|
-
block()
|
|
901
|
-
} else {
|
|
902
|
-
DispatchQueue.main.async { block() }
|
|
903
|
-
}
|
|
904
|
-
}
|
|
@@ -34,7 +34,7 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
func showLocationDialog() {
|
|
37
|
-
|
|
37
|
+
onMainAsync { [weak self] in
|
|
38
38
|
guard let vc = Self.topMostViewController() else { return }
|
|
39
39
|
let title =
|
|
40
40
|
Bundle.main.object(forInfoDictionaryKey: "LocationNotAvailableTitle")
|
|
@@ -61,7 +61,7 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
|
|
|
61
61
|
title: openLocationSettingsButton ?? "Open settings",
|
|
62
62
|
style: .default
|
|
63
63
|
) { _ in
|
|
64
|
-
self
|
|
64
|
+
self?.openLocationSettings()
|
|
65
65
|
}
|
|
66
66
|
)
|
|
67
67
|
vc.present(alert, animated: true, completion: nil)
|
|
@@ -78,7 +78,7 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
func openLocationSettings() {
|
|
81
|
-
|
|
81
|
+
onMainAsync {
|
|
82
82
|
let openSettings = {
|
|
83
83
|
if #available(iOS 18.3, *) {
|
|
84
84
|
guard
|
|
@@ -114,18 +114,10 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
|
|
|
114
114
|
didFailWithError error: Error
|
|
115
115
|
) {
|
|
116
116
|
let code: RNLocationErrorCode
|
|
117
|
-
|
|
118
117
|
if let clError = error as? CLError {
|
|
119
|
-
|
|
120
|
-
case .denied:
|
|
121
|
-
code = RNLocationErrorCode.permissionDenied
|
|
122
|
-
case .locationUnknown, .network:
|
|
123
|
-
code = RNLocationErrorCode.positionUnavailable
|
|
124
|
-
default:
|
|
125
|
-
code = RNLocationErrorCode.internalError
|
|
126
|
-
}
|
|
118
|
+
code = clError.code.toRNLocationErrorCode
|
|
127
119
|
} else {
|
|
128
|
-
code =
|
|
120
|
+
code = .internalError
|
|
129
121
|
}
|
|
130
122
|
onError?(code)
|
|
131
123
|
}
|
package/ios/MapHelper.swift
CHANGED
|
@@ -18,3 +18,23 @@ func withCATransaction(
|
|
|
18
18
|
body()
|
|
19
19
|
CATransaction.commit()
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
@MainActor @inline(__always)
|
|
23
|
+
func onMain(_ block: @escaping @MainActor () -> Void) {
|
|
24
|
+
if Thread.isMainThread {
|
|
25
|
+
block()
|
|
26
|
+
} else {
|
|
27
|
+
Task { @MainActor in block() }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@inline(__always)
|
|
32
|
+
func onMainAsync(
|
|
33
|
+
_ block: @MainActor @escaping () async -> Void
|
|
34
|
+
) {
|
|
35
|
+
if Thread.isMainThread {
|
|
36
|
+
Task { @MainActor in await block() }
|
|
37
|
+
} else {
|
|
38
|
+
Task { @MainActor in await block() }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -3,13 +3,12 @@ import SVGKit
|
|
|
3
3
|
import UIKit
|
|
4
4
|
|
|
5
5
|
final class MapMarkerBuilder {
|
|
6
|
-
private let iconCache
|
|
6
|
+
private let iconCache: NSCache<NSNumber, UIImage> = {
|
|
7
|
+
let c = NSCache<NSNumber, UIImage>()
|
|
8
|
+
c.countLimit = 512
|
|
9
|
+
return c
|
|
10
|
+
}()
|
|
7
11
|
private var tasks: [String: Task<Void, Never>] = [:]
|
|
8
|
-
private let queue = DispatchQueue(
|
|
9
|
-
label: "map.marker.render",
|
|
10
|
-
qos: .userInitiated,
|
|
11
|
-
attributes: .concurrent
|
|
12
|
-
)
|
|
13
12
|
|
|
14
13
|
func build(_ m: RNMarker, icon: UIImage?) -> GMSMarker {
|
|
15
14
|
let marker = GMSMarker(
|
|
@@ -35,7 +34,8 @@ final class MapMarkerBuilder {
|
|
|
35
34
|
}
|
|
36
35
|
m.zIndex.map { marker.zIndex = Int32($0) }
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
onMainAsync { [weak marker] in
|
|
38
|
+
try? await Task.sleep(nanoseconds: 250_000_000)
|
|
39
39
|
marker?.tracksViewChanges = false
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -84,7 +84,7 @@ final class MapMarkerBuilder {
|
|
|
84
84
|
m.tracksViewChanges = true
|
|
85
85
|
m.icon = img
|
|
86
86
|
|
|
87
|
-
if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y{
|
|
87
|
+
if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y {
|
|
88
88
|
m.groundAnchor = CGPoint(
|
|
89
89
|
x: next.anchor?.x ?? 0.5,
|
|
90
90
|
y: next.anchor?.y ?? 1
|
|
@@ -99,12 +99,13 @@ final class MapMarkerBuilder {
|
|
|
99
99
|
)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
onMainAsync { [weak m] in
|
|
103
|
+
try? await Task.sleep(nanoseconds: 250_000_000)
|
|
103
104
|
m?.tracksViewChanges = false
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
} else {
|
|
107
|
-
if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y{
|
|
108
|
+
if prev.anchor?.x != next.anchor?.x || prev.anchor?.y != next.anchor?.y {
|
|
108
109
|
m.groundAnchor = CGPoint(
|
|
109
110
|
x: next.anchor?.x ?? 0.5,
|
|
110
111
|
y: next.anchor?.y ?? 1
|
|
@@ -144,7 +145,8 @@ final class MapMarkerBuilder {
|
|
|
144
145
|
guard let self else { return }
|
|
145
146
|
defer { self.tasks.removeValue(forKey: id) }
|
|
146
147
|
|
|
147
|
-
let
|
|
148
|
+
let scale = UIScreen.main.scale
|
|
149
|
+
let img = await self.renderUIImage(m, scale)
|
|
148
150
|
guard let img, !Task.isCancelled else { return }
|
|
149
151
|
|
|
150
152
|
self.iconCache.setObject(img, forKey: key)
|
|
@@ -172,65 +174,38 @@ final class MapMarkerBuilder {
|
|
|
172
174
|
iconCache.removeAllObjects()
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
private func renderUIImage(_ m: RNMarker) async -> UIImage? {
|
|
176
|
-
guard let iconSvg = m.iconSvg
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return await withTaskCancellationHandler(
|
|
181
|
-
operation: {
|
|
182
|
-
await withCheckedContinuation {
|
|
183
|
-
(cont: CheckedContinuation<UIImage?, Never>) in
|
|
184
|
-
queue.async {
|
|
185
|
-
if Task.isCancelled {
|
|
186
|
-
cont.resume(returning: nil)
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
let targetW = max(1, Int(CGFloat(iconSvg.width)))
|
|
191
|
-
let targetH = max(1, Int(CGFloat(iconSvg.height)))
|
|
192
|
-
let size = CGSize(width: targetW, height: targetH)
|
|
193
|
-
|
|
194
|
-
guard
|
|
195
|
-
let data = iconSvg.svgString.data(using: .utf8),
|
|
196
|
-
let svgImg = SVGKImage(data: data)
|
|
197
|
-
else {
|
|
198
|
-
cont.resume(returning: nil)
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
svgImg.size = size
|
|
203
|
-
|
|
204
|
-
if Task.isCancelled {
|
|
205
|
-
cont.resume(returning: nil)
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
guard let base = svgImg.uiImage else {
|
|
210
|
-
cont.resume(returning: nil)
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
let scale = UIScreen.main.scale
|
|
215
|
-
let img: UIImage
|
|
216
|
-
if let cg = base.cgImage {
|
|
217
|
-
img = UIImage(cgImage: cg, scale: scale, orientation: .up)
|
|
218
|
-
} else {
|
|
219
|
-
let fmt = UIGraphicsImageRendererFormat.default()
|
|
220
|
-
fmt.opaque = false
|
|
221
|
-
fmt.scale = scale
|
|
222
|
-
let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
|
|
223
|
-
img = renderer.image { _ in
|
|
224
|
-
base.draw(in: CGRect(origin: .zero, size: size))
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
cont.resume(returning: img)
|
|
229
|
-
}
|
|
230
|
-
}
|
|
177
|
+
private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) async -> UIImage? {
|
|
178
|
+
guard let iconSvg = m.iconSvg,
|
|
179
|
+
let data = iconSvg.svgString.data(using: .utf8)
|
|
180
|
+
else { return nil }
|
|
231
181
|
|
|
232
|
-
|
|
233
|
-
|
|
182
|
+
let size = CGSize(
|
|
183
|
+
width: max(1, CGFloat(iconSvg.width)),
|
|
184
|
+
height: max(1, CGFloat(iconSvg.height))
|
|
234
185
|
)
|
|
186
|
+
|
|
187
|
+
return await Task.detached(priority: .userInitiated) {
|
|
188
|
+
autoreleasepool {
|
|
189
|
+
guard let svgImg = SVGKImage(data: data) else { return nil }
|
|
190
|
+
svgImg.size = size
|
|
191
|
+
|
|
192
|
+
guard !Task.isCancelled else { return nil }
|
|
193
|
+
guard let base = svgImg.uiImage else { return nil }
|
|
194
|
+
|
|
195
|
+
if let cg = base.cgImage {
|
|
196
|
+
return UIImage(cgImage: cg, scale: scale, orientation: .up)
|
|
197
|
+
}
|
|
198
|
+
guard !Task.isCancelled else { return nil }
|
|
199
|
+
let fmt = UIGraphicsImageRendererFormat.default()
|
|
200
|
+
fmt.opaque = false
|
|
201
|
+
fmt.scale = scale
|
|
202
|
+
guard !Task.isCancelled else { return nil }
|
|
203
|
+
let renderer = UIGraphicsImageRenderer(size: size, format: fmt)
|
|
204
|
+
return renderer.image { _ in
|
|
205
|
+
base.draw(in: CGRect(origin: .zero, size: size))
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}.value
|
|
235
209
|
}
|
|
210
|
+
|
|
236
211
|
}
|
|
@@ -30,21 +30,25 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec {
|
|
|
30
30
|
)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
@MainActor
|
|
33
34
|
func afterUpdate() {
|
|
34
35
|
if !propsInitialized {
|
|
35
36
|
propsInitialized = true
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
options.camera = $0.toGMSCameraPosition(current: nil)
|
|
42
|
-
}
|
|
43
|
-
impl.initMapView(googleMapOptions: options)
|
|
37
|
+
let options = GMSMapViewOptions()
|
|
38
|
+
initialProps?.mapId.map { options.mapID = GMSMapID(identifier: $0) }
|
|
39
|
+
initialProps?.liteMode.map { _ in /* not supported */ }
|
|
40
|
+
initialProps?.camera.map {
|
|
41
|
+
options.camera = $0.toGMSCameraPosition(current: nil)
|
|
44
42
|
}
|
|
43
|
+
impl.initMapView(googleMapOptions: options)
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
@MainActor
|
|
48
|
+
func dispose() {
|
|
49
|
+
impl.deinitInternal()
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
@MainActor
|
|
49
53
|
var initialProps: RNInitialProps? {
|
|
50
54
|
didSet {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import CoreLocation
|
|
2
|
+
|
|
3
|
+
extension CLError.Code {
|
|
4
|
+
var toRNLocationErrorCode: RNLocationErrorCode {
|
|
5
|
+
switch self {
|
|
6
|
+
case .denied:
|
|
7
|
+
return .permissionDenied
|
|
8
|
+
case .locationUnknown, .network:
|
|
9
|
+
return .positionUnavailable
|
|
10
|
+
default:
|
|
11
|
+
return .internalError
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import CoreLocation
|
|
2
|
+
|
|
3
|
+
extension CLLocation {
|
|
4
|
+
func toRnLocation() -> RNLocation {
|
|
5
|
+
return RNLocation(
|
|
6
|
+
center: RNLatLng(
|
|
7
|
+
latitude: coordinate.latitude,
|
|
8
|
+
longitude: coordinate.longitude
|
|
9
|
+
),
|
|
10
|
+
altitude: altitude,
|
|
11
|
+
accuracy: horizontalAccuracy,
|
|
12
|
+
bearing: course,
|
|
13
|
+
speed: speed,
|
|
14
|
+
time: timestamp.timeIntervalSince1970 * 1000,
|
|
15
|
+
android: nil,
|
|
16
|
+
ios: RNLocationIOS(
|
|
17
|
+
horizontalAccuracy: horizontalAccuracy,
|
|
18
|
+
verticalAccuracy: verticalAccuracy,
|
|
19
|
+
speedAccuracy: speedAccuracy,
|
|
20
|
+
courseAccuracy: courseAccuracy,
|
|
21
|
+
floor: floor.map { Double($0.level)},
|
|
22
|
+
isFromMockProvider: false,
|
|
23
|
+
timestamp: timestamp.timeIntervalSince1970 * 1000
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
}
|