Skip to content

Commit 36a1291

Browse files
authored
feat: add polygon holes support
## Pull request ### Before submitting - [x] This PR targets the `dev` branch (not `main`) - [x] Commit messages follow the semantic-release format - [x] No debug logs or sensitive data included --- ### Summary Short description of what this PR changes or adds. --- ### Type of change - [x] Feature - [ ] Fix - [ ] Refactor - [ ] Internal / CI - [ ] Documentation --- ### Scope - [x] Android - [x] iOS - [ ] Core - [x] Example App - [ ] Docs
2 parents 66ba52f + ae53e17 commit 36a1291

20 files changed

+183
-132
lines changed

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

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ import com.google.android.gms.maps.model.TileOverlayOptions
3535
import com.google.maps.android.data.kml.KmlLayer
3636
import com.margelo.nitro.core.Promise
3737
import com.rngooglemapsplus.extensions.toGooglePriority
38+
import com.rngooglemapsplus.extensions.toLatLng
3839
import com.rngooglemapsplus.extensions.toLocationErrorCode
3940
import com.rngooglemapsplus.extensions.toRNIndoorBuilding
4041
import com.rngooglemapsplus.extensions.toRNIndoorLevel
42+
import com.rngooglemapsplus.extensions.toRnLatLng
4143
import java.io.ByteArrayInputStream
4244
import java.io.ByteArrayOutputStream
4345
import java.io.File
@@ -88,11 +90,7 @@ class GoogleMapsViewImpl(
8890
reactContext.addLifecycleEventListener(this)
8991
}
9092

91-
fun initMapView(
92-
mapId: String?,
93-
liteMode: Boolean?,
94-
cameraPosition: CameraPosition?,
95-
) {
93+
fun initMapView(googleMapsOptions: GoogleMapOptions) {
9694
if (initialized) return
9795
initialized = true
9896
val result = playServiceHandler.playServicesAvailability()
@@ -126,13 +124,7 @@ class GoogleMapsViewImpl(
126124
mapView =
127125
MapView(
128126
reactContext,
129-
GoogleMapOptions().apply {
130-
mapId?.let { mapId(it) }
131-
liteMode?.let { liteMode(it) }
132-
cameraPosition?.let {
133-
camera(it)
134-
}
135-
},
127+
googleMapsOptions,
136128
)
137129

138130
super.addView(mapView)
@@ -173,12 +165,12 @@ class GoogleMapsViewImpl(
173165

174166
onCameraChangeStart?.invoke(
175167
RNRegion(
176-
center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
168+
center = bounds.center.toRnLatLng(),
177169
latitudeDelta = latDelta,
178170
longitudeDelta = lngDelta,
179171
),
180172
RNCamera(
181-
center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
173+
center = cameraPosition.target.toRnLatLng(),
182174
zoom = cameraPosition.zoom.toDouble(),
183175
bearing = cameraPosition.bearing.toDouble(),
184176
tilt = cameraPosition.tilt.toDouble(),
@@ -205,12 +197,12 @@ class GoogleMapsViewImpl(
205197

206198
onCameraChange?.invoke(
207199
RNRegion(
208-
center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
200+
center = bounds.center.toRnLatLng(),
209201
latitudeDelta = latDelta,
210202
longitudeDelta = lngDelta,
211203
),
212204
RNCamera(
213-
center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
205+
center = cameraPosition.target.toRnLatLng(),
214206
zoom = cameraPosition.zoom.toDouble(),
215207
bearing = cameraPosition.bearing.toDouble(),
216208
tilt = cameraPosition.tilt.toDouble(),
@@ -233,12 +225,12 @@ class GoogleMapsViewImpl(
233225

234226
onCameraChangeComplete?.invoke(
235227
RNRegion(
236-
center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
228+
center = bounds.center.toRnLatLng(),
237229
latitudeDelta = latDelta,
238230
longitudeDelta = lngDelta,
239231
),
240232
RNCamera(
241-
center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
233+
center = cameraPosition.target.toRnLatLng(),
242234
zoom = cameraPosition.zoom.toDouble(),
243235
bearing = cameraPosition.bearing.toDouble(),
244236
tilt = cameraPosition.tilt.toDouble(),
@@ -544,7 +536,7 @@ class GoogleMapsViewImpl(
544536
onUi {
545537
val builder = LatLngBounds.Builder()
546538
coordinates.forEach { coord ->
547-
builder.include(LatLng(coord.latitude, coord.longitude))
539+
builder.include(coord.toLatLng())
548540
}
549541
val bounds = builder.build()
550542

@@ -1069,28 +1061,28 @@ class GoogleMapsViewImpl(
10691061

10701062
override fun onMapClick(coordinates: LatLng) {
10711063
onMapPress?.invoke(
1072-
RNLatLng(coordinates.latitude, coordinates.longitude),
1064+
coordinates.toRnLatLng(),
10731065
)
10741066
}
10751067

10761068
override fun onMarkerDragStart(marker: Marker) {
10771069
onMarkerDragStart?.invoke(
10781070
marker.tag?.toString(),
1079-
RNLatLng(marker.position.latitude, marker.position.longitude),
1071+
marker.position.toRnLatLng(),
10801072
)
10811073
}
10821074

10831075
override fun onMarkerDrag(marker: Marker) {
10841076
onMarkerDrag?.invoke(
10851077
marker.tag?.toString(),
1086-
RNLatLng(marker.position.latitude, marker.position.longitude),
1078+
marker.position.toRnLatLng(),
10871079
)
10881080
}
10891081

10901082
override fun onMarkerDragEnd(marker: Marker) {
10911083
onMarkerDragEnd?.invoke(
10921084
marker.tag?.toString(),
1093-
RNLatLng(marker.position.latitude, marker.position.longitude),
1085+
marker.position.toRnLatLng(),
10941086
)
10951087
}
10961088

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import android.graphics.Color
44
import com.facebook.react.uimanager.PixelUtil.dpToPx
55
import com.google.android.gms.maps.model.Circle
66
import com.google.android.gms.maps.model.CircleOptions
7-
import com.google.android.gms.maps.model.LatLng
87
import com.rngooglemapsplus.extensions.toColor
8+
import com.rngooglemapsplus.extensions.toLatLng
99

1010
class MapCircleBuilder {
1111
fun build(circle: RNCircle): CircleOptions =
1212
CircleOptions().apply {
13-
center(LatLng(circle.center.latitude, circle.center.longitude))
13+
center(circle.center.toLatLng())
1414
radius(circle.radius)
1515
circle.strokeWidth?.let { strokeWidth(it.dpToPx()) }
1616
circle.strokeColor?.let { strokeColor(it.toColor()) }
@@ -23,11 +23,12 @@ class MapCircleBuilder {
2323
circle: Circle,
2424
next: RNCircle,
2525
) {
26-
circle.center = LatLng(next.center.latitude, next.center.longitude)
26+
circle.center = next.center.toLatLng()
2727
circle.radius = next.radius
2828
circle.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
2929
circle.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
3030
circle.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
31+
circle.isClickable = next.pressable ?: false
3132
circle.zIndex = next.zIndex?.toFloat() ?: 0f
3233
}
3334
}

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import com.caverock.androidsvg.SVG
88
import com.facebook.react.uimanager.PixelUtil.dpToPx
99
import com.google.android.gms.maps.model.BitmapDescriptor
1010
import com.google.android.gms.maps.model.BitmapDescriptorFactory
11-
import com.google.android.gms.maps.model.LatLng
1211
import com.google.android.gms.maps.model.Marker
1312
import com.google.android.gms.maps.model.MarkerOptions
1413
import com.rngooglemapsplus.extensions.markerStyleEquals
1514
import com.rngooglemapsplus.extensions.styleHash
15+
import com.rngooglemapsplus.extensions.toLatLng
1616
import kotlinx.coroutines.CoroutineScope
1717
import kotlinx.coroutines.Dispatchers
1818
import kotlinx.coroutines.Job
@@ -40,13 +40,15 @@ class MapMarkerBuilder(
4040
icon: BitmapDescriptor?,
4141
): MarkerOptions =
4242
MarkerOptions().apply {
43-
position(LatLng(m.coordinate.latitude, m.coordinate.longitude))
43+
position(m.coordinate.toLatLng())
4444
icon(icon)
4545
m.title?.let { title(it) }
4646
m.snippet?.let { snippet(it) }
4747
m.opacity?.let { alpha(it.toFloat()) }
4848
m.flat?.let { flat(it) }
4949
m.draggable?.let { draggable(it) }
50+
m.rotation?.let { rotation(it.toFloat()) }
51+
m.infoWindowAnchor?.let { infoWindowAnchor(it.x.toFloat(), it.y.toFloat()) }
5052
m.anchor?.let { anchor((m.anchor.x).toFloat(), (m.anchor.y).toFloat()) }
5153
m.zIndex?.let { zIndex(it.toFloat()) }
5254
}
@@ -57,10 +59,7 @@ class MapMarkerBuilder(
5759
next: RNMarker,
5860
) {
5961
marker.position =
60-
LatLng(
61-
next.coordinate.latitude,
62-
next.coordinate.longitude,
63-
)
62+
next.coordinate.toLatLng()
6463

6564
if (!prev.markerStyleEquals(next)) {
6665
buildIconAsync(marker.id, next) { icon ->
@@ -72,6 +71,11 @@ class MapMarkerBuilder(
7271
marker.alpha = next.opacity?.toFloat() ?: 0f
7372
marker.isFlat = next.flat ?: false
7473
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+
)
7579
marker.setAnchor(
7680
(next.anchor?.x ?: 0.5).toFloat(),
7781
(next.anchor?.y ?: 1.0).toFloat(),

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

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,46 @@ package com.rngooglemapsplus
22

33
import android.graphics.Color
44
import com.facebook.react.uimanager.PixelUtil.dpToPx
5-
import com.google.android.gms.maps.model.LatLng
65
import com.google.android.gms.maps.model.Polygon
76
import com.google.android.gms.maps.model.PolygonOptions
87
import com.rngooglemapsplus.extensions.toColor
8+
import com.rngooglemapsplus.extensions.toLatLng
99

1010
class MapPolygonBuilder {
1111
fun build(poly: RNPolygon): PolygonOptions =
1212
PolygonOptions().apply {
1313
poly.coordinates.forEach { pt ->
1414
add(
15-
com.google.android.gms.maps.model
16-
.LatLng(pt.latitude, pt.longitude),
15+
pt.toLatLng(),
1716
)
1817
}
1918
poly.fillColor?.let { fillColor(it.toColor()) }
2019
poly.strokeColor?.let { strokeColor(it.toColor()) }
2120
poly.strokeWidth?.let { strokeWidth(it.dpToPx()) }
2221
poly.pressable?.let { clickable(it) }
22+
poly.geodesic?.let { geodesic(it) }
23+
poly.holes?.forEach { hole ->
24+
addHole(hole.coordinates.map { it.toLatLng() })
25+
}
2326
poly.zIndex?.let { zIndex(it.toFloat()) }
2427
}
2528

2629
fun update(
27-
gmsPoly: Polygon,
30+
poly: Polygon,
2831
next: RNPolygon,
2932
) {
30-
gmsPoly.points =
33+
poly.points =
3134
next.coordinates.map {
32-
LatLng(it.latitude, it.longitude)
35+
it.toLatLng()
3336
}
34-
gmsPoly.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
35-
gmsPoly.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
36-
gmsPoly.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
37-
gmsPoly.zIndex = next.zIndex?.toFloat() ?: 0f
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
3846
}
3947
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import com.facebook.react.uimanager.PixelUtil.dpToPx
55
import com.google.android.gms.maps.model.ButtCap
66
import com.google.android.gms.maps.model.Cap
77
import com.google.android.gms.maps.model.JointType
8-
import com.google.android.gms.maps.model.LatLng
98
import com.google.android.gms.maps.model.Polyline
109
import com.google.android.gms.maps.model.PolylineOptions
1110
import com.google.android.gms.maps.model.RoundCap
1211
import com.google.android.gms.maps.model.SquareCap
1312
import com.rngooglemapsplus.extensions.toColor
13+
import com.rngooglemapsplus.extensions.toLatLng
1414

1515
class MapPolylineBuilder {
1616
fun build(pl: RNPolyline): PolylineOptions =
1717
PolylineOptions().apply {
1818
pl.coordinates.forEach { pt ->
19-
add(LatLng(pt.latitude, pt.longitude))
19+
add(pt.toLatLng())
2020
}
2121
pl.width?.let { width(it.dpToPx()) }
2222
pl.lineCap?.let {
@@ -25,6 +25,7 @@ class MapPolylineBuilder {
2525
}
2626
pl.lineJoin?.let { jointType(mapLineJoin(it)) }
2727
pl.color?.let { color(it.toColor()) }
28+
pl.geodesic?.let { geodesic(it) }
2829
pl.pressable?.let { clickable(it) }
2930
pl.zIndex?.let { zIndex(it.toFloat()) }
3031
}
@@ -33,14 +34,15 @@ class MapPolylineBuilder {
3334
polyline: Polyline,
3435
next: RNPolyline,
3536
) {
36-
polyline.points = next.coordinates.map { LatLng(it.latitude, it.longitude) }
37-
37+
polyline.points = next.coordinates.map { it.toLatLng() }
3838
polyline.width = next.width?.dpToPx() ?: 1f
3939
val cap = mapLineCap(next.lineCap ?: RNLineCapType.BUTT)
4040
polyline.startCap = cap
4141
polyline.endCap = cap
4242
polyline.jointType = mapLineJoin(next.lineJoin ?: RNLineJoinType.MITER)
4343
polyline.color = next.color?.toColor() ?: Color.BLACK
44+
polyline.isClickable = next.pressable ?: false
45+
polyline.isGeodesic = next.geodesic ?: false
4446
polyline.zIndex = next.zIndex?.toFloat() ?: 0f
4547
}
4648

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.rngooglemapsplus
33
import com.facebook.proguard.annotations.DoNotStrip
44
import com.facebook.react.bridge.UiThreadUtil
55
import com.facebook.react.uimanager.ThemedReactContext
6+
import com.google.android.gms.maps.GoogleMapOptions
67
import com.google.android.gms.maps.model.MapStyleOptions
78
import com.margelo.nitro.core.Promise
89
import com.rngooglemapsplus.extensions.circleEquals
@@ -40,11 +41,13 @@ class RNGoogleMapsPlusView(
4041
super.afterUpdate()
4142
if (!propsInitialized) {
4243
propsInitialized = true
43-
view.initMapView(
44-
initialProps?.mapId,
45-
initialProps?.liteMode,
46-
initialProps?.camera?.toCameraPosition(),
47-
)
44+
val options =
45+
GoogleMapOptions().apply {
46+
initialProps?.mapId?.let { mapId(it) }
47+
initialProps?.liteMode?.let { liteMode(it) }
48+
initialProps?.camera?.let { camera(it.toCameraPosition()) }
49+
}
50+
view.initMapView(options)
4851
}
4952
}
5053

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.rngooglemapsplus.extensions
2+
3+
import com.google.android.gms.maps.model.LatLng
4+
import com.rngooglemapsplus.RNLatLng
5+
6+
fun LatLng.toRnLatLng(): RNLatLng = RNLatLng(latitude, longitude)

android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package com.rngooglemapsplus.extensions
22

33
import com.google.android.gms.maps.model.CameraPosition
4-
import com.google.android.gms.maps.model.LatLng
54
import com.rngooglemapsplus.RNCamera
65

76
fun RNCamera.toCameraPosition(): CameraPosition {
87
val builder = CameraPosition.builder()
98

109
center?.let {
11-
builder.target(LatLng(it.latitude, it.longitude))
10+
builder.target(it.toLatLng())
1211
}
1312

1413
zoom?.let { builder.zoom(it.toFloat()) }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.rngooglemapsplus.extensions
2+
3+
import com.google.android.gms.maps.model.LatLng
4+
import com.rngooglemapsplus.RNLatLng
5+
6+
fun RNLatLng.toLatLng(): LatLng = LatLng(latitude, longitude)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { useRef } from 'react';
22
import MapWrapper from '../components/MapWrapper';
3-
import { makePolygon } from '../utils/mapGenerators';
3+
import { makePolygon, makePolygonWithHoles } from '../utils/mapGenerators';
44
import type { GoogleMapsViewRef } from 'react-native-google-maps-plus';
55

66
export default function PolygonsScreen() {
77
const mapRef = useRef<GoogleMapsViewRef | null>(null);
88

9-
const polygons = [makePolygon(1)];
9+
const polygons = [makePolygon(1), makePolygonWithHoles(2)];
1010
return <MapWrapper mapRef={mapRef} polygons={polygons} />;
1111
}

0 commit comments

Comments
 (0)