@maydon_tech/react-native-nitro-maps 0.1.4 → 0.2.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/LICENSE +1 -1
- package/NitroMap.podspec +1 -1
- package/README.md +82 -9
- package/android/CMakeLists.txt +4 -1
- package/android/gradle.properties +4 -4
- package/android/src/main/cpp/ClusterEngineJNI.cpp +198 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMap.kt +397 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapConfig.kt +53 -0
- package/android/src/main/{java → kotlin}/com/margelo/nitro/nitromap/NitroMapPackage.kt +4 -4
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapView.kt +73 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/UserLocationManager.kt +295 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusterIconRenderer.kt +111 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusteringManager.kt +104 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +166 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerIconFactory.kt +303 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerSelectionHandler.kt +72 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/PriceMarkerRenderer.kt +159 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderFactory.kt +24 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +128 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapDelegate.kt +317 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Clustering.kt +524 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Markers.kt +358 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Overlays.kt +272 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+UserLocation.kt +296 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider.kt +815 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/MarkerTagData.kt +19 -0
- package/ios/Location/NitroLocationManager.swift +116 -0
- package/ios/MarkerRenderer/MarkerIconFactory.swift +1 -3
- package/ios/MarkerRenderer/PriceMarkerRenderer.swift +10 -6
- package/ios/NitroMap.swift +279 -13
- package/ios/NitroMapConfig/NitroMapConfig.swift +45 -0
- package/ios/Providers/{GoogleMapDelegate.swift → Google/GoogleMapDelegate.swift} +48 -23
- package/ios/Providers/Google/GoogleMapProvider+Camera.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider+Clustering.swift +541 -0
- package/ios/Providers/Google/GoogleMapProvider+Markers.swift +270 -0
- package/ios/Providers/Google/GoogleMapProvider+Overlays.swift +245 -0
- package/ios/Providers/Google/GoogleMapProvider+UserLocation.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider.swift +342 -0
- package/ios/Providers/MapProviderFactory.swift +17 -0
- package/ios/Providers/MapProviderProtocol.swift +48 -1
- package/ios/Shared/ClusterConfig+Factory.swift +2 -2
- package/ios/Shared/MapStyleProvider.swift +6 -4
- package/ios/Shared/MarkerSelectionHandler.swift +4 -1
- package/ios/Utils/ColorValueExtension.swift +46 -67
- package/lib/module/components/ImageMarker.js +39 -29
- package/lib/module/components/ImageMarker.js.map +1 -1
- package/lib/module/components/Marker.js +118 -0
- package/lib/module/components/Marker.js.map +1 -0
- package/lib/module/components/NitroCircle.js +92 -0
- package/lib/module/components/NitroCircle.js.map +1 -0
- package/lib/module/components/NitroMap.js +216 -76
- package/lib/module/components/NitroMap.js.map +1 -1
- package/lib/module/components/NitroPolygon.js +135 -0
- package/lib/module/components/NitroPolygon.js.map +1 -0
- package/lib/module/components/NitroPolyline.js +115 -0
- package/lib/module/components/NitroPolyline.js.map +1 -0
- package/lib/module/components/PriceMarker.js +16 -29
- package/lib/module/components/PriceMarker.js.map +1 -1
- package/lib/module/context/NitroMapContext.js.map +1 -1
- package/lib/module/hooks/useNitroCircle.js +18 -0
- package/lib/module/hooks/useNitroCircle.js.map +1 -0
- package/lib/module/hooks/useNitroMarker.js +26 -9
- package/lib/module/hooks/useNitroMarker.js.map +1 -1
- package/lib/module/hooks/useNitroOverlay.js +59 -0
- package/lib/module/hooks/useNitroOverlay.js.map +1 -0
- package/lib/module/hooks/useNitroPolygon.js +18 -0
- package/lib/module/hooks/useNitroPolygon.js.map +1 -0
- package/lib/module/hooks/useNitroPolyline.js +18 -0
- package/lib/module/hooks/useNitroPolyline.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/overlay.js +4 -0
- package/lib/module/types/overlay.js.map +1 -0
- package/lib/module/types/theme.js +4 -0
- package/lib/module/types/theme.js.map +1 -0
- package/lib/module/utils/colors.js +41 -13
- package/lib/module/utils/colors.js.map +1 -1
- package/lib/module/utils/validation.js +45 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/typescript/src/components/ImageMarker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.d.ts +34 -0
- package/lib/typescript/src/components/Marker.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroCircle.d.ts +70 -0
- package/lib/typescript/src/components/NitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroMap.d.ts +60 -3
- package/lib/typescript/src/components/NitroMap.d.ts.map +1 -1
- package/lib/typescript/src/components/NitroPolygon.d.ts +86 -0
- package/lib/typescript/src/components/NitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts +84 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/components/PriceMarker.d.ts +0 -5
- package/lib/typescript/src/components/PriceMarker.d.ts.map +1 -1
- package/lib/typescript/src/context/NitroMapContext.d.ts +2 -0
- package/lib/typescript/src/context/NitroMapContext.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroCircle.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts +20 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts +26 -0
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts +248 -6
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/map.d.ts +34 -4
- package/lib/typescript/src/types/map.d.ts.map +1 -1
- package/lib/typescript/src/types/marker.d.ts +24 -36
- package/lib/typescript/src/types/marker.d.ts.map +1 -1
- package/lib/typescript/src/types/overlay.d.ts +75 -0
- package/lib/typescript/src/types/overlay.d.ts.map +1 -0
- package/lib/typescript/src/types/theme.d.ts +93 -0
- package/lib/typescript/src/types/theme.d.ts.map +1 -0
- package/lib/typescript/src/utils/colors.d.ts +6 -8
- package/lib/typescript/src/utils/colors.d.ts.map +1 -1
- package/lib/typescript/src/utils/validation.d.ts +12 -0
- package/lib/typescript/src/utils/validation.d.ts.map +1 -0
- package/nitrogen/generated/android/c++/JCircleData.hpp +94 -0
- package/nitrogen/generated/android/c++/JClusterConfig.hpp +5 -7
- package/nitrogen/generated/android/c++/JFunc_void_UserLocationChangeEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_UserTrackingMode.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.cpp +328 -21
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.hpp +53 -2
- package/nitrogen/generated/android/c++/JMarkerAnimation.hpp +3 -6
- package/nitrogen/generated/android/c++/JMarkerData.hpp +15 -3
- package/nitrogen/generated/android/c++/JPolygonData.hpp +149 -0
- package/nitrogen/generated/android/c++/JPolylineData.hpp +113 -0
- package/nitrogen/generated/android/c++/JUserLocationChangeEvent.hpp +70 -0
- package/nitrogen/generated/android/c++/JUserTrackingMode.hpp +62 -0
- package/nitrogen/generated/android/c++/views/JHybridNitroMapStateUpdater.cpp +72 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/CircleData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/ClusterConfig.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserLocationChangeEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserTrackingMode.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/HybridNitroMapSpec.kt +228 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerAnimation.kt +1 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerData.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolygonData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolylineData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/UserLocationChangeEvent.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/{ClusterAnimationStyle.kt → UserTrackingMode.kt} +6 -8
- package/nitrogen/generated/android/nitromapOnLoad.cpp +6 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.cpp +24 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.hpp +175 -17
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Umbrella.hpp +15 -3
- package/nitrogen/generated/ios/c++/HybridNitroMapSpecSwift.hpp +249 -16
- package/nitrogen/generated/ios/c++/views/HybridNitroMapComponent.mm +90 -5
- package/nitrogen/generated/ios/swift/CircleData.swift +143 -0
- package/nitrogen/generated/ios/swift/ClusterConfig.swift +22 -15
- package/nitrogen/generated/ios/swift/Func_void_UserLocationChangeEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_UserTrackingMode.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec.swift +35 -1
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec_cxx.swift +582 -8
- package/nitrogen/generated/ios/swift/MarkerAnimation.swift +4 -8
- package/nitrogen/generated/ios/swift/MarkerData.swift +54 -2
- package/nitrogen/generated/ios/swift/PolygonData.swift +179 -0
- package/nitrogen/generated/ios/swift/PolylineData.swift +155 -0
- package/nitrogen/generated/ios/swift/UserLocationChangeEvent.swift +69 -0
- package/nitrogen/generated/ios/swift/UserTrackingMode.swift +44 -0
- package/nitrogen/generated/shared/c++/CircleData.hpp +113 -0
- package/nitrogen/generated/shared/c++/ClusterConfig.hpp +5 -8
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.cpp +53 -2
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.hpp +75 -6
- package/nitrogen/generated/shared/c++/MarkerAnimation.hpp +4 -8
- package/nitrogen/generated/shared/c++/MarkerData.hpp +14 -2
- package/nitrogen/generated/shared/c++/PolygonData.hpp +114 -0
- package/nitrogen/generated/shared/c++/PolylineData.hpp +114 -0
- package/nitrogen/generated/shared/c++/UserLocationChangeEvent.hpp +88 -0
- package/nitrogen/generated/shared/c++/UserTrackingMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.cpp +216 -12
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.hpp +23 -1
- package/nitrogen/generated/shared/json/NitroMapConfig.json +18 -1
- package/package.json +36 -5
- package/src/components/ImageMarker.tsx +58 -42
- package/src/components/Marker.tsx +161 -0
- package/src/components/NitroCircle.tsx +183 -0
- package/src/components/NitroMap.tsx +328 -78
- package/src/components/NitroPolygon.tsx +229 -0
- package/src/components/NitroPolyline.tsx +208 -0
- package/src/components/PriceMarker.tsx +23 -48
- package/src/context/NitroMapContext.tsx +4 -0
- package/src/hooks/useNitroCircle.ts +25 -0
- package/src/hooks/useNitroMarker.ts +49 -10
- package/src/hooks/useNitroOverlay.ts +68 -0
- package/src/hooks/useNitroPolygon.ts +25 -0
- package/src/hooks/useNitroPolyline.ts +25 -0
- package/src/index.tsx +23 -2
- package/src/specs/NitroMap.nitro.ts +294 -5
- package/src/types/map.ts +36 -4
- package/src/types/marker.ts +24 -44
- package/src/types/overlay.ts +77 -0
- package/src/types/theme.ts +101 -0
- package/src/utils/colors.ts +48 -16
- package/src/utils/validation.ts +69 -0
- package/android/src/main/java/com/margelo/nitro/nitromap/ClusterIconGenerator.kt +0 -108
- package/android/src/main/java/com/margelo/nitro/nitromap/ColorUtils.kt +0 -63
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMap.kt +0 -408
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMapConfig.kt +0 -68
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconCache.kt +0 -176
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconFactory.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/QuadTree.kt +0 -195
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/GoogleMapProvider.kt +0 -912
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +0 -70
- package/cpp/QuadTree.hpp +0 -246
- package/ios/NitroMapConfig/HybridNitroMapConfig.swift +0 -33
- package/ios/Providers/GoogleMapProvider+Camera.swift +0 -164
- package/ios/Providers/GoogleMapProvider.swift +0 -924
- package/nitrogen/generated/android/c++/JClusterAnimationStyle.hpp +0 -68
- package/nitrogen/generated/ios/swift/ClusterAnimationStyle.swift +0 -52
- package/nitrogen/generated/shared/c++/ClusterAnimationStyle.hpp +0 -88
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { MapStyle } from './map';
|
|
2
|
+
|
|
3
|
+
// ============ Provider-Specific Theme Types ============
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Google Maps theme — JSON-based styling.
|
|
7
|
+
* Array of style elements targeting map features with visual modifiers.
|
|
8
|
+
*
|
|
9
|
+
* @see https://mapstyle.withgoogle.com/
|
|
10
|
+
* @see https://developers.google.com/maps/documentation/javascript/style-reference
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const darkTheme: GoogleMapTheme = [
|
|
15
|
+
* { featureType: 'water', stylers: [{ color: '#0e171d' }] },
|
|
16
|
+
* { featureType: 'road', stylers: [{ visibility: 'simplified' }] },
|
|
17
|
+
* ];
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export type GoogleMapTheme = MapStyle;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Apple Maps theme — configuration-based styling.
|
|
24
|
+
*
|
|
25
|
+
* Maps to `MKMapConfiguration` on iOS. Unlike Google's element-level JSON
|
|
26
|
+
* styling, Apple Maps uses high-level configuration categories.
|
|
27
|
+
*
|
|
28
|
+
* **Not yet implemented** — will be available when the Apple Maps provider
|
|
29
|
+
* is added (Phase 3).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const appleTheme: AppleMapTheme = {
|
|
34
|
+
* colorScheme: 'dark',
|
|
35
|
+
* emphasisStyle: 'muted',
|
|
36
|
+
* showsTraffic: true,
|
|
37
|
+
* pointOfInterestFilter: {
|
|
38
|
+
* includes: ['restaurant', 'cafe', 'hotel'],
|
|
39
|
+
* },
|
|
40
|
+
* };
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export type AppleMapTheme = {
|
|
44
|
+
/** Color scheme for the map. @default 'light' */
|
|
45
|
+
colorScheme?: 'light' | 'dark';
|
|
46
|
+
/** Emphasis style — 'muted' reduces visual clutter. @default 'default' */
|
|
47
|
+
emphasisStyle?: 'default' | 'muted';
|
|
48
|
+
/** Show real-time traffic overlay. @default false */
|
|
49
|
+
showsTraffic?: boolean;
|
|
50
|
+
/** Filter which points of interest are visible. */
|
|
51
|
+
pointOfInterestFilter?: {
|
|
52
|
+
/** Only show these POI categories. Mutually exclusive with `excludes`. */
|
|
53
|
+
includes?: string[];
|
|
54
|
+
/** Hide these POI categories. Mutually exclusive with `includes`. */
|
|
55
|
+
excludes?: string[];
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Yandex Maps theme — style URI or night mode toggle.
|
|
61
|
+
*
|
|
62
|
+
* **Not yet implemented** — will be available when the Yandex Maps provider
|
|
63
|
+
* is added (Phase 4).
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const yandexTheme: YandexMapTheme = {
|
|
68
|
+
* nightModeEnabled: true,
|
|
69
|
+
* };
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export type YandexMapTheme = {
|
|
73
|
+
/** Custom style URI (e.g., from Yandex Style Editor). */
|
|
74
|
+
styleUri?: string;
|
|
75
|
+
/** Enable built-in night/dark mode. @default false */
|
|
76
|
+
nightModeEnabled?: boolean;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// ============ Provider → Theme Mapping ============
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Maps each provider to its theme type.
|
|
83
|
+
* Used by the generic `NitroMapProps<P>` to enforce type-safe themes.
|
|
84
|
+
*
|
|
85
|
+
* When you write `<NitroMap provider="google" theme={...} />`,
|
|
86
|
+
* TypeScript narrows `theme` to `GoogleMapTheme`.
|
|
87
|
+
*
|
|
88
|
+
* When you write `<NitroMap provider="apple" theme={...} />`,
|
|
89
|
+
* TypeScript narrows `theme` to `AppleMapTheme`.
|
|
90
|
+
*/
|
|
91
|
+
export type ThemeForProvider = {
|
|
92
|
+
google: GoogleMapTheme;
|
|
93
|
+
apple: AppleMapTheme;
|
|
94
|
+
yandex: YandexMapTheme;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Union of all possible theme types.
|
|
99
|
+
* Use `ThemeForProvider[P]` for type-safe narrowing instead.
|
|
100
|
+
*/
|
|
101
|
+
export type MapTheme = GoogleMapTheme | AppleMapTheme | YandexMapTheme;
|
package/src/utils/colors.ts
CHANGED
|
@@ -53,21 +53,6 @@ export const parseColor = (
|
|
|
53
53
|
return undefined;
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
/**
|
|
57
|
-
* Parse a ColorValue with a fallback default color
|
|
58
|
-
* @param color - Color value (hex string or MarkerColor)
|
|
59
|
-
* @param fallback - Fallback MarkerColor if parsing fails
|
|
60
|
-
* @returns MarkerColor object
|
|
61
|
-
* @internal
|
|
62
|
-
*/
|
|
63
|
-
export const parseColorWithFallback = (
|
|
64
|
-
color: ColorValue | undefined,
|
|
65
|
-
fallback: MarkerColor
|
|
66
|
-
): MarkerColor => {
|
|
67
|
-
const parsed = parseColor(color);
|
|
68
|
-
return parsed ?? fallback;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
56
|
/**
|
|
72
57
|
* Create a MarkerColor from RGB values
|
|
73
58
|
* @param r - Red component (0-255)
|
|
@@ -106,7 +91,20 @@ export const rgb = (
|
|
|
106
91
|
* ```
|
|
107
92
|
*/
|
|
108
93
|
export const hex = (hexStr: string, alpha: number = 255): MarkerColor => {
|
|
109
|
-
// Try
|
|
94
|
+
// Try 8-char hex first (#RRGGBBAA or RRGGBBAA)
|
|
95
|
+
const result8 = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(
|
|
96
|
+
hexStr
|
|
97
|
+
);
|
|
98
|
+
if (result8) {
|
|
99
|
+
return {
|
|
100
|
+
r: parseInt(result8[1]!, 16),
|
|
101
|
+
g: parseInt(result8[2]!, 16),
|
|
102
|
+
b: parseInt(result8[3]!, 16),
|
|
103
|
+
a: parseInt(result8[4]!, 16),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Try 6-char hex (#RRGGBB or RRGGBB)
|
|
110
108
|
const result6 = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexStr);
|
|
111
109
|
if (result6) {
|
|
112
110
|
return {
|
|
@@ -117,6 +115,17 @@ export const hex = (hexStr: string, alpha: number = 255): MarkerColor => {
|
|
|
117
115
|
};
|
|
118
116
|
}
|
|
119
117
|
|
|
118
|
+
// Try 4-char hex (#RGBA or RGBA)
|
|
119
|
+
const result4 = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])$/i.exec(hexStr);
|
|
120
|
+
if (result4) {
|
|
121
|
+
return {
|
|
122
|
+
r: parseInt(result4[1]! + result4[1]!, 16),
|
|
123
|
+
g: parseInt(result4[2]! + result4[2]!, 16),
|
|
124
|
+
b: parseInt(result4[3]! + result4[3]!, 16),
|
|
125
|
+
a: parseInt(result4[4]! + result4[4]!, 16),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
120
129
|
// Try 3-char hex (#RGB or RGB)
|
|
121
130
|
const result3 = /^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(hexStr);
|
|
122
131
|
if (result3) {
|
|
@@ -129,6 +138,11 @@ export const hex = (hexStr: string, alpha: number = 255): MarkerColor => {
|
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
// Fallback to black
|
|
141
|
+
if (__DEV__) {
|
|
142
|
+
console.warn(
|
|
143
|
+
`hex(): invalid hex color string "${hexStr}". Falling back to black.`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
132
146
|
return { r: 0, g: 0, b: 0, a: alpha };
|
|
133
147
|
};
|
|
134
148
|
|
|
@@ -157,3 +171,21 @@ export const Colors = {
|
|
|
157
171
|
/** Light gray (240, 240, 240) */
|
|
158
172
|
lightGray: rgb(240, 240, 240),
|
|
159
173
|
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Compare two ColorValue values for equality.
|
|
177
|
+
* Handles both hex strings and MarkerColor objects.
|
|
178
|
+
* @internal Used by component memo comparators to avoid duplication.
|
|
179
|
+
*/
|
|
180
|
+
export const areColorsEqual = (
|
|
181
|
+
a: ColorValue | undefined,
|
|
182
|
+
b: ColorValue | undefined
|
|
183
|
+
): boolean => {
|
|
184
|
+
if (a === b) return true;
|
|
185
|
+
if (!a || !b) return false;
|
|
186
|
+
if (typeof a !== typeof b) return false;
|
|
187
|
+
if (typeof a === 'string' && typeof b === 'string') return a === b;
|
|
188
|
+
const ca = a as MarkerColor;
|
|
189
|
+
const cb = b as MarkerColor;
|
|
190
|
+
return ca.r === cb.r && ca.g === cb.g && ca.b === cb.b && ca.a === cb.a;
|
|
191
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// src/utils/validation.ts
|
|
2
|
+
|
|
3
|
+
import type { Coordinate } from '../types/map';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Validate a coordinate in __DEV__ mode.
|
|
7
|
+
* Warns on NaN, Infinity, or out-of-range values.
|
|
8
|
+
*/
|
|
9
|
+
export function validateCoordinate(
|
|
10
|
+
coordinate: Coordinate,
|
|
11
|
+
context: string
|
|
12
|
+
): void {
|
|
13
|
+
if (!__DEV__) return;
|
|
14
|
+
|
|
15
|
+
const { latitude, longitude } = coordinate;
|
|
16
|
+
|
|
17
|
+
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
|
18
|
+
console.warn(
|
|
19
|
+
`[NitroMap] Invalid coordinate in ${context}: ` +
|
|
20
|
+
`latitude=${latitude}, longitude=${longitude}. ` +
|
|
21
|
+
'Coordinates must be finite numbers.'
|
|
22
|
+
);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (latitude < -90 || latitude > 90) {
|
|
27
|
+
console.warn(
|
|
28
|
+
`[NitroMap] Out-of-range latitude in ${context}: ${latitude}. ` +
|
|
29
|
+
'Latitude must be between -90 and 90.'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (longitude < -180 || longitude > 180) {
|
|
34
|
+
console.warn(
|
|
35
|
+
`[NitroMap] Out-of-range longitude in ${context}: ${longitude}. ` +
|
|
36
|
+
'Longitude must be between -180 and 180.'
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validate an array of coordinates in __DEV__ mode.
|
|
43
|
+
* Only reports the first invalid coordinate to avoid console spam.
|
|
44
|
+
*/
|
|
45
|
+
export function validateCoordinates(
|
|
46
|
+
coordinates: Coordinate[],
|
|
47
|
+
context: string
|
|
48
|
+
): void {
|
|
49
|
+
if (!__DEV__) return;
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < coordinates.length; i++) {
|
|
52
|
+
const coord = coordinates[i]!;
|
|
53
|
+
const { latitude, longitude } = coord;
|
|
54
|
+
if (
|
|
55
|
+
!Number.isFinite(latitude) ||
|
|
56
|
+
!Number.isFinite(longitude) ||
|
|
57
|
+
latitude < -90 ||
|
|
58
|
+
latitude > 90 ||
|
|
59
|
+
longitude < -180 ||
|
|
60
|
+
longitude > 180
|
|
61
|
+
) {
|
|
62
|
+
console.warn(
|
|
63
|
+
`[NitroMap] Invalid coordinate at index ${i} in ${context}: ` +
|
|
64
|
+
`latitude=${latitude}, longitude=${longitude}.`
|
|
65
|
+
);
|
|
66
|
+
return; // report first invalid only
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.nitromap
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.graphics.*
|
|
5
|
-
import com.google.android.gms.maps.model.BitmapDescriptor
|
|
6
|
-
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
|
7
|
-
import kotlin.math.roundToInt
|
|
8
|
-
import androidx.core.graphics.toColorInt
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Generator for cluster marker icons
|
|
12
|
-
*/
|
|
13
|
-
class ClusterIconGenerator(private val context: Context) {
|
|
14
|
-
|
|
15
|
-
private var backgroundColor = "#007AFF".toColorInt() // iOS blue
|
|
16
|
-
private var textColor = Color.WHITE
|
|
17
|
-
private var borderColor = Color.WHITE
|
|
18
|
-
private var borderWidth = 2f
|
|
19
|
-
|
|
20
|
-
private val iconCache = mutableMapOf<Int, BitmapDescriptor>()
|
|
21
|
-
|
|
22
|
-
fun updateConfig(config: ClusterConfig?) {
|
|
23
|
-
config?.let {
|
|
24
|
-
backgroundColor = ColorUtils.fromColorValue(it.backgroundColor)
|
|
25
|
-
textColor = ColorUtils.fromColorValue(it.textColor)
|
|
26
|
-
borderColor = ColorUtils.fromColorValue(it.borderColor)
|
|
27
|
-
borderWidth = it.borderWidth.toFloat()
|
|
28
|
-
// Clear cache when config changes
|
|
29
|
-
iconCache.clear()
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
fun getClusterIcon(count: Int): BitmapDescriptor {
|
|
34
|
-
// Check cache first
|
|
35
|
-
iconCache[count]?.let { return it }
|
|
36
|
-
|
|
37
|
-
val density = context.resources.displayMetrics.density
|
|
38
|
-
|
|
39
|
-
// Size based on count
|
|
40
|
-
val baseSize = when {
|
|
41
|
-
count < 10 -> 40
|
|
42
|
-
count < 100 -> 48
|
|
43
|
-
count < 1000 -> 56
|
|
44
|
-
else -> 64
|
|
45
|
-
}
|
|
46
|
-
val size = (baseSize * density).roundToInt()
|
|
47
|
-
|
|
48
|
-
val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
|
49
|
-
val canvas = Canvas(bitmap)
|
|
50
|
-
|
|
51
|
-
// Draw background circle
|
|
52
|
-
val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
53
|
-
color = backgroundColor
|
|
54
|
-
style = Paint.Style.FILL
|
|
55
|
-
}
|
|
56
|
-
canvas.drawCircle(size / 2f, size / 2f, size / 2f - borderWidth * density, bgPaint)
|
|
57
|
-
|
|
58
|
-
// Draw border
|
|
59
|
-
if (borderWidth > 0) {
|
|
60
|
-
val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
61
|
-
color = borderColor
|
|
62
|
-
style = Paint.Style.STROKE
|
|
63
|
-
strokeWidth = borderWidth * density
|
|
64
|
-
}
|
|
65
|
-
canvas.drawCircle(
|
|
66
|
-
size / 2f,
|
|
67
|
-
size / 2f,
|
|
68
|
-
size / 2f - borderWidth * density / 2,
|
|
69
|
-
borderPaint
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Draw count text
|
|
74
|
-
val text = formatCount(count)
|
|
75
|
-
val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
76
|
-
color = textColor
|
|
77
|
-
textSize = when {
|
|
78
|
-
count < 10 -> 16 * density
|
|
79
|
-
count < 100 -> 14 * density
|
|
80
|
-
count < 1000 -> 12 * density
|
|
81
|
-
else -> 10 * density
|
|
82
|
-
}
|
|
83
|
-
typeface = Typeface.DEFAULT_BOLD
|
|
84
|
-
textAlign = Paint.Align.CENTER
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
val textBounds = Rect()
|
|
88
|
-
textPaint.getTextBounds(text, 0, text.length, textBounds)
|
|
89
|
-
val textY = size / 2f + textBounds.height() / 2f
|
|
90
|
-
canvas.drawText(text, size / 2f, textY, textPaint)
|
|
91
|
-
|
|
92
|
-
val descriptor = BitmapDescriptorFactory.fromBitmap(bitmap)
|
|
93
|
-
iconCache[count] = descriptor
|
|
94
|
-
return descriptor
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private fun formatCount(count: Int): String {
|
|
98
|
-
return when {
|
|
99
|
-
count >= 1000000 -> "${count / 1000000}M"
|
|
100
|
-
count >= 1000 -> "${count / 1000}K"
|
|
101
|
-
else -> count.toString()
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
fun clearCache() {
|
|
106
|
-
iconCache.clear()
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.nitromap
|
|
2
|
-
|
|
3
|
-
import android.graphics.Color
|
|
4
|
-
import androidx.core.graphics.toColorInt
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Utility functions for converting color types to Android color integers
|
|
8
|
-
*/
|
|
9
|
-
object ColorUtils {
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Convert MarkerColor (RGBA) to Android color int
|
|
13
|
-
*/
|
|
14
|
-
fun fromMarkerColor(color: MarkerColor): Int {
|
|
15
|
-
// Handle alpha: if <= 1.0, treat as 0-1 range and scale to 0-255
|
|
16
|
-
val alpha = if (color.a <= 1.0) (color.a * 255).toInt() else color.a.toInt()
|
|
17
|
-
return Color.argb(
|
|
18
|
-
alpha.coerceIn(0, 255),
|
|
19
|
-
color.r.toInt().coerceIn(0, 255),
|
|
20
|
-
color.g.toInt().coerceIn(0, 255),
|
|
21
|
-
color.b.toInt().coerceIn(0, 255)
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Convert ColorValue (String | MarkerColor variant) to Android color int
|
|
27
|
-
*/
|
|
28
|
-
fun fromColorValue(colorValue: ColorValue): Int {
|
|
29
|
-
return colorValue.match(
|
|
30
|
-
first = { hexString -> parseHexColor(hexString) },
|
|
31
|
-
second = { markerColor -> fromMarkerColor(markerColor) }
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Convert Variant_String_MarkerColor to Android color int
|
|
37
|
-
*/
|
|
38
|
-
fun fromVariant(variant: Variant_String_MarkerColor): Int {
|
|
39
|
-
return variant.match(
|
|
40
|
-
first = { hexString -> parseHexColor(hexString) },
|
|
41
|
-
second = { markerColor -> fromMarkerColor(markerColor) }
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Parse hex color string to Android color int
|
|
47
|
-
* Supports formats: #RGB, #RRGGBB, #AARRGGBB, and color names
|
|
48
|
-
*/
|
|
49
|
-
private fun parseHexColor(hexString: String): Int {
|
|
50
|
-
return try {
|
|
51
|
-
hexString.toColorInt()
|
|
52
|
-
} catch (e: Exception) {
|
|
53
|
-
Color.BLACK // Default fallback
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Create a default ColorValue from a MarkerColor
|
|
59
|
-
*/
|
|
60
|
-
fun defaultColorValue(r: Double, g: Double, b: Double, a: Double = 255.0): ColorValue {
|
|
61
|
-
return ColorValue.create(MarkerColor(r, g, b, a))
|
|
62
|
-
}
|
|
63
|
-
}
|