Skip to content

Commit b65cabf

Browse files
authored
chore: merge dev into main
2 parents 8c24762 + 06528dd commit b65cabf

18 files changed

Lines changed: 563 additions & 126 deletions

android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,38 @@ class MapCircleBuilder {
2020
}
2121

2222
fun update(
23-
circle: Circle,
23+
prev: RNCircle,
2424
next: RNCircle,
25+
circle: Circle,
2526
) {
26-
circle.center = next.center.toLatLng()
27-
circle.radius = next.radius
28-
circle.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
29-
circle.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
30-
circle.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
31-
circle.isClickable = next.pressable ?: false
32-
circle.zIndex = next.zIndex?.toFloat() ?: 0f
27+
if (prev.center.latitude != next.center.latitude ||
28+
prev.center.longitude != next.center.longitude
29+
) {
30+
circle.center = next.center.toLatLng()
31+
}
32+
33+
if (prev.radius != next.radius) {
34+
circle.radius = next.radius
35+
}
36+
37+
if (prev.strokeWidth != next.strokeWidth) {
38+
circle.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
39+
}
40+
41+
if (prev.strokeColor != next.strokeColor) {
42+
circle.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
43+
}
44+
45+
if (prev.fillColor != next.fillColor) {
46+
circle.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
47+
}
48+
49+
if (prev.pressable != next.pressable) {
50+
circle.isClickable = next.pressable ?: false
51+
}
52+
53+
if (prev.zIndex != next.zIndex) {
54+
circle.zIndex = next.zIndex?.toFloat() ?: 0f
55+
}
3356
}
3457
}

android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,33 +54,84 @@ class MapMarkerBuilder(
5454
}
5555

5656
fun update(
57-
marker: Marker,
5857
prev: RNMarker,
5958
next: RNMarker,
59+
marker: Marker,
6060
) {
61-
marker.position =
62-
next.coordinate.toLatLng()
61+
if (prev.coordinate.latitude != next.coordinate.latitude ||
62+
prev.coordinate.longitude != next.coordinate.longitude
63+
) {
64+
marker.position = next.coordinate.toLatLng()
65+
}
6366

6467
if (!prev.markerStyleEquals(next)) {
6568
buildIconAsync(marker.id, next) { icon ->
6669
marker.setIcon(icon)
70+
if (prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x ||
71+
prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
72+
) {
73+
marker.setInfoWindowAnchor(
74+
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
75+
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
76+
)
77+
}
78+
79+
if (prev.anchor?.x != next.anchor?.x ||
80+
prev.anchor?.y != next.anchor?.y
81+
) {
82+
marker.setAnchor(
83+
(next.anchor?.x ?: 0.5f).toFloat(),
84+
(next.anchor?.y ?: 1.0f).toFloat(),
85+
)
86+
}
6787
}
88+
} else {
89+
if (prev.infoWindowAnchor?.x != next.infoWindowAnchor?.x ||
90+
prev.infoWindowAnchor?.y != next.infoWindowAnchor?.y
91+
) {
92+
marker.setInfoWindowAnchor(
93+
(next.infoWindowAnchor?.x ?: 0.5f).toFloat(),
94+
(next.infoWindowAnchor?.y ?: 0f).toFloat(),
95+
)
96+
}
97+
98+
if (prev.anchor?.x != next.anchor?.x ||
99+
prev.anchor?.y != next.anchor?.y
100+
) {
101+
marker.setAnchor(
102+
(next.anchor?.x ?: 0.5f).toFloat(),
103+
(next.anchor?.y ?: 1.0f).toFloat(),
104+
)
105+
}
106+
}
107+
108+
if (prev.title != next.title) {
109+
marker.title = next.title
110+
}
111+
112+
if (prev.snippet != next.snippet) {
113+
marker.snippet = next.snippet
114+
}
115+
116+
if (prev.opacity != next.opacity) {
117+
marker.alpha = next.opacity?.toFloat() ?: 1f
118+
}
119+
120+
if (prev.flat != next.flat) {
121+
marker.isFlat = next.flat ?: false
122+
}
123+
124+
if (prev.draggable != next.draggable) {
125+
marker.isDraggable = next.draggable ?: false
126+
}
127+
128+
if (prev.rotation != next.rotation) {
129+
marker.rotation = next.rotation?.toFloat() ?: 0f
130+
}
131+
132+
if (prev.zIndex != next.zIndex) {
133+
marker.zIndex = next.zIndex?.toFloat() ?: 0f
68134
}
69-
marker.title = next.title
70-
marker.snippet = next.snippet
71-
marker.alpha = next.opacity?.toFloat() ?: 1f
72-
marker.isFlat = next.flat ?: false
73-
marker.isDraggable = next.draggable ?: false
74-
marker.rotation = next.rotation?.toFloat() ?: 0f
75-
marker.setInfoWindowAnchor(
76-
(next.infoWindowAnchor?.x ?: 0.5).toFloat(),
77-
(next.infoWindowAnchor?.y ?: 0).toFloat(),
78-
)
79-
marker.setAnchor(
80-
(next.anchor?.x ?: 0.5).toFloat(),
81-
(next.anchor?.y ?: 1.0).toFloat(),
82-
)
83-
marker.zIndex = next.zIndex?.toFloat() ?: 0f
84135
}
85136

86137
fun buildIconAsync(

android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,60 @@ class MapPolygonBuilder {
2727
}
2828

2929
fun update(
30-
poly: Polygon,
30+
prev: RNPolygon,
3131
next: RNPolygon,
32+
poly: Polygon,
3233
) {
33-
poly.points =
34-
next.coordinates.map {
35-
it.toLatLng()
36-
}
37-
poly.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
38-
poly.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
39-
poly.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
40-
poly.isClickable = next.pressable ?: false
41-
poly.isGeodesic = next.geodesic ?: false
42-
poly.holes = next.holes?.map { hole ->
43-
hole.coordinates.map { it.toLatLng() }
44-
} ?: emptyList()
45-
poly.zIndex = next.zIndex?.toFloat() ?: 0f
34+
val coordsChanged =
35+
prev.coordinates.size != next.coordinates.size ||
36+
!prev.coordinates.zip(next.coordinates).all { (a, b) ->
37+
a.latitude == b.latitude && a.longitude == b.longitude
38+
}
39+
40+
if (coordsChanged) {
41+
poly.points = next.coordinates.map { it.toLatLng() }
42+
}
43+
44+
val prevHoles = prev.holes?.toList() ?: emptyList()
45+
val nextHoles = next.holes?.toList() ?: emptyList()
46+
val holesChanged =
47+
prevHoles.size != nextHoles.size ||
48+
!prevHoles.zip(nextHoles).all { (ha, hb) ->
49+
ha.coordinates.size == hb.coordinates.size &&
50+
ha.coordinates.zip(hb.coordinates).all { (a, b) ->
51+
a.latitude == b.latitude && a.longitude == b.longitude
52+
}
53+
}
54+
55+
if (holesChanged) {
56+
poly.holes =
57+
nextHoles.map { hole ->
58+
hole.coordinates.map { it.toLatLng() }
59+
}
60+
}
61+
62+
if (prev.fillColor != next.fillColor) {
63+
poly.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
64+
}
65+
66+
if (prev.strokeColor != next.strokeColor) {
67+
poly.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
68+
}
69+
70+
if (prev.strokeWidth != next.strokeWidth) {
71+
poly.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
72+
}
73+
74+
if (prev.pressable != next.pressable) {
75+
poly.isClickable = next.pressable ?: false
76+
}
77+
78+
if (prev.geodesic != next.geodesic) {
79+
poly.isGeodesic = next.geodesic ?: false
80+
}
81+
82+
if (prev.zIndex != next.zIndex) {
83+
poly.zIndex = next.zIndex?.toFloat() ?: 0f
84+
}
4685
}
4786
}

android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,52 @@ class MapPolylineBuilder {
3131
}
3232

3333
fun update(
34-
polyline: Polyline,
34+
prev: RNPolyline,
3535
next: RNPolyline,
36+
polyline: Polyline,
3637
) {
37-
polyline.points = next.coordinates.map { it.toLatLng() }
38-
polyline.width = next.width?.dpToPx() ?: 1f
39-
val cap = mapLineCap(next.lineCap ?: RNLineCapType.BUTT)
40-
polyline.startCap = cap
41-
polyline.endCap = cap
42-
polyline.jointType = mapLineJoin(next.lineJoin ?: RNLineJoinType.MITER)
43-
polyline.color = next.color?.toColor() ?: Color.BLACK
44-
polyline.isClickable = next.pressable ?: false
45-
polyline.isGeodesic = next.geodesic ?: false
46-
polyline.zIndex = next.zIndex?.toFloat() ?: 0f
38+
val coordsChanged =
39+
prev.coordinates.size != next.coordinates.size ||
40+
!prev.coordinates.zip(next.coordinates).all { (a, b) ->
41+
a.latitude == b.latitude && a.longitude == b.longitude
42+
}
43+
44+
if (coordsChanged) {
45+
polyline.points = next.coordinates.map { it.toLatLng() }
46+
}
47+
48+
if (prev.width != next.width) {
49+
polyline.width = next.width?.dpToPx() ?: 1f
50+
}
51+
52+
val newCap = mapLineCap(next.lineCap ?: RNLineCapType.BUTT)
53+
val prevCap = mapLineCap(prev.lineCap ?: RNLineCapType.BUTT)
54+
if (newCap != prevCap) {
55+
polyline.startCap = newCap
56+
polyline.endCap = newCap
57+
}
58+
59+
val newJoin = mapLineJoin(next.lineJoin ?: RNLineJoinType.MITER)
60+
val prevJoin = mapLineJoin(prev.lineJoin ?: RNLineJoinType.MITER)
61+
if (newJoin != prevJoin) {
62+
polyline.jointType = newJoin
63+
}
64+
65+
if (prev.color != next.color) {
66+
polyline.color = next.color?.toColor() ?: Color.BLACK
67+
}
68+
69+
if (prev.pressable != next.pressable) {
70+
polyline.isClickable = next.pressable ?: false
71+
}
72+
73+
if (prev.geodesic != next.geodesic) {
74+
polyline.isGeodesic = next.geodesic ?: false
75+
}
76+
77+
if (prev.zIndex != next.zIndex) {
78+
polyline.zIndex = next.zIndex?.toFloat() ?: 0f
79+
}
4780
}
4881

4982
private fun mapLineCap(type: RNLineCapType?): Cap =

android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class RNGoogleMapsPlusView(
157157
} else if (!prev.markerEquals(next)) {
158158
view.updateMarker(id) { marker ->
159159
onUi {
160-
markerBuilder.update(marker, next, prev)
160+
markerBuilder.update(prev, next, marker)
161161
}
162162
}
163163
}
@@ -181,7 +181,7 @@ class RNGoogleMapsPlusView(
181181
} else if (!prev.polylineEquals(next)) {
182182
view.updatePolyline(id) { polyline ->
183183
onUi {
184-
polylineBuilder.update(polyline, next)
184+
polylineBuilder.update(prev, next, polyline)
185185
}
186186
}
187187
}
@@ -205,7 +205,7 @@ class RNGoogleMapsPlusView(
205205
view.addPolygon(id, polygonBuilder.build(next))
206206
} else if (!prev.polygonEquals(next)) {
207207
view.updatePolygon(id) { polygon ->
208-
onUi { polygonBuilder.update(polygon, next) }
208+
onUi { polygonBuilder.update(prev, next, polygon) }
209209
}
210210
}
211211
}
@@ -229,7 +229,7 @@ class RNGoogleMapsPlusView(
229229
} else if (!prev.circleEquals(next)) {
230230
view.updateCircle(id) { circle ->
231231
onUi {
232-
circleBuilder.update(circle, next)
232+
circleBuilder.update(prev, next, circle)
233233
}
234234
}
235235
}

example/ios/Podfile.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,8 @@ PODS:
18191819
- React-RCTFBReactNativeSpec
18201820
- ReactCommon/turbomodule/core
18211821
- SocketRocket
1822+
- react-native-clusterer (4.0.0):
1823+
- React-Core
18221824
- react-native-safe-area-context (5.6.1):
18231825
- boost
18241826
- DoubleConversion
@@ -2795,6 +2797,7 @@ DEPENDENCIES:
27952797
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
27962798
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
27972799
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
2800+
- react-native-clusterer (from `../node_modules/react-native-clusterer`)
27982801
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
27992802
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
28002803
- React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`)
@@ -2928,6 +2931,8 @@ EXTERNAL SOURCES:
29282931
:path: "../node_modules/react-native/ReactCommon"
29292932
React-microtasksnativemodule:
29302933
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
2934+
react-native-clusterer:
2935+
:path: "../node_modules/react-native-clusterer"
29312936
react-native-safe-area-context:
29322937
:path: "../node_modules/react-native-safe-area-context"
29332938
React-NativeModulesApple:
@@ -3052,6 +3057,7 @@ SPEC CHECKSUMS:
30523057
React-logger: 30adf849117e87cf86e88dca1824bb0f18f87e10
30533058
React-Mapbuffer: 2a5edca6905cb1b3a40fb7ed3f4496df4f1bc60e
30543059
React-microtasksnativemodule: 6d775fdf71445f58dbedbd66ed9cb08b48ae2797
3060+
react-native-clusterer: a9526b8fb1d6be10cd9a6d05d7d8b982da7c6abc
30553061
react-native-safe-area-context: ee1e8e2a7abf737a8d4d9d1a5686a7f2e7466236
30563062
React-NativeModulesApple: b2ee5b48020439fd81d1fd9cba40ebf0c3af5636
30573063
React-oscompat: 80ca388c4831481cd03a6b45ecfc82739ca9a95e

example/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@react-navigation/stack": "7.4.9",
1717
"react": "19.1.1",
1818
"react-native": "0.82.0",
19+
"react-native-clusterer": "4.0.0",
1920
"react-native-gesture-handler": "2.28.0",
2021
"react-native-google-maps-plus": "workspace:*",
2122
"react-native-nitro-modules": "0.30.0",

example/src/App.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import IndoorLevelMapScreen from './screens/IndoorLevelMapScreen';
2424
import CameraTestScreen from './screens/CameraTestScreen';
2525
import type { RootStackParamList } from './types/navigation';
2626
import SnapshotTestScreen from './screens/SnaptshotTestScreen';
27+
import ClusteringScreen from './screens/ClsuteringScreen';
2728

2829
const Stack = createStackNavigator<RootStackParamList>();
2930

@@ -112,6 +113,11 @@ export default function App() {
112113
component={SnapshotTestScreen}
113114
options={{ title: 'Snapshot test' }}
114115
/>
116+
<Stack.Screen
117+
name="Clustering"
118+
component={ClusteringScreen}
119+
options={{ title: 'Clustering test' }}
120+
/>
115121
<Stack.Screen
116122
name="Stress"
117123
component={StressTestScreen}

0 commit comments

Comments
 (0)