diff --git a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt index ad55a07..1e859b6 100644 --- a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +++ b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt @@ -35,9 +35,11 @@ import com.google.android.gms.maps.model.TileOverlayOptions import com.google.maps.android.data.kml.KmlLayer import com.margelo.nitro.core.Promise import com.rngooglemapsplus.extensions.toGooglePriority +import com.rngooglemapsplus.extensions.toLatLng import com.rngooglemapsplus.extensions.toLocationErrorCode import com.rngooglemapsplus.extensions.toRNIndoorBuilding import com.rngooglemapsplus.extensions.toRNIndoorLevel +import com.rngooglemapsplus.extensions.toRnLatLng import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File @@ -88,11 +90,7 @@ class GoogleMapsViewImpl( reactContext.addLifecycleEventListener(this) } - fun initMapView( - mapId: String?, - liteMode: Boolean?, - cameraPosition: CameraPosition?, - ) { + fun initMapView(googleMapsOptions: GoogleMapOptions) { if (initialized) return initialized = true val result = playServiceHandler.playServicesAvailability() @@ -126,13 +124,7 @@ class GoogleMapsViewImpl( mapView = MapView( reactContext, - GoogleMapOptions().apply { - mapId?.let { mapId(it) } - liteMode?.let { liteMode(it) } - cameraPosition?.let { - camera(it) - } - }, + googleMapsOptions, ) super.addView(mapView) @@ -173,12 +165,12 @@ class GoogleMapsViewImpl( onCameraChangeStart?.invoke( RNRegion( - center = RNLatLng(bounds.center.latitude, bounds.center.longitude), + center = bounds.center.toRnLatLng(), latitudeDelta = latDelta, longitudeDelta = lngDelta, ), RNCamera( - center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude), + center = cameraPosition.target.toRnLatLng(), zoom = cameraPosition.zoom.toDouble(), bearing = cameraPosition.bearing.toDouble(), tilt = cameraPosition.tilt.toDouble(), @@ -205,12 +197,12 @@ class GoogleMapsViewImpl( onCameraChange?.invoke( RNRegion( - center = RNLatLng(bounds.center.latitude, bounds.center.longitude), + center = bounds.center.toRnLatLng(), latitudeDelta = latDelta, longitudeDelta = lngDelta, ), RNCamera( - center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude), + center = cameraPosition.target.toRnLatLng(), zoom = cameraPosition.zoom.toDouble(), bearing = cameraPosition.bearing.toDouble(), tilt = cameraPosition.tilt.toDouble(), @@ -233,12 +225,12 @@ class GoogleMapsViewImpl( onCameraChangeComplete?.invoke( RNRegion( - center = RNLatLng(bounds.center.latitude, bounds.center.longitude), + center = bounds.center.toRnLatLng(), latitudeDelta = latDelta, longitudeDelta = lngDelta, ), RNCamera( - center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude), + center = cameraPosition.target.toRnLatLng(), zoom = cameraPosition.zoom.toDouble(), bearing = cameraPosition.bearing.toDouble(), tilt = cameraPosition.tilt.toDouble(), @@ -544,7 +536,7 @@ class GoogleMapsViewImpl( onUi { val builder = LatLngBounds.Builder() coordinates.forEach { coord -> - builder.include(LatLng(coord.latitude, coord.longitude)) + builder.include(coord.toLatLng()) } val bounds = builder.build() @@ -1069,28 +1061,28 @@ class GoogleMapsViewImpl( override fun onMapClick(coordinates: LatLng) { onMapPress?.invoke( - RNLatLng(coordinates.latitude, coordinates.longitude), + coordinates.toRnLatLng(), ) } override fun onMarkerDragStart(marker: Marker) { onMarkerDragStart?.invoke( marker.tag?.toString(), - RNLatLng(marker.position.latitude, marker.position.longitude), + marker.position.toRnLatLng(), ) } override fun onMarkerDrag(marker: Marker) { onMarkerDrag?.invoke( marker.tag?.toString(), - RNLatLng(marker.position.latitude, marker.position.longitude), + marker.position.toRnLatLng(), ) } override fun onMarkerDragEnd(marker: Marker) { onMarkerDragEnd?.invoke( marker.tag?.toString(), - RNLatLng(marker.position.latitude, marker.position.longitude), + marker.position.toRnLatLng(), ) } diff --git a/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt b/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt index 07a98f5..45e2104 100644 --- a/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt +++ b/android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt @@ -4,13 +4,13 @@ import android.graphics.Color import com.facebook.react.uimanager.PixelUtil.dpToPx import com.google.android.gms.maps.model.Circle import com.google.android.gms.maps.model.CircleOptions -import com.google.android.gms.maps.model.LatLng import com.rngooglemapsplus.extensions.toColor +import com.rngooglemapsplus.extensions.toLatLng class MapCircleBuilder { fun build(circle: RNCircle): CircleOptions = CircleOptions().apply { - center(LatLng(circle.center.latitude, circle.center.longitude)) + center(circle.center.toLatLng()) radius(circle.radius) circle.strokeWidth?.let { strokeWidth(it.dpToPx()) } circle.strokeColor?.let { strokeColor(it.toColor()) } @@ -23,11 +23,12 @@ class MapCircleBuilder { circle: Circle, next: RNCircle, ) { - circle.center = LatLng(next.center.latitude, next.center.longitude) + circle.center = next.center.toLatLng() circle.radius = next.radius circle.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f circle.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK circle.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT + circle.isClickable = next.pressable ?: false circle.zIndex = next.zIndex?.toFloat() ?: 0f } } diff --git a/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt b/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt index 1e2fe56..583383e 100644 --- a/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt +++ b/android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt @@ -8,11 +8,11 @@ import com.caverock.androidsvg.SVG import com.facebook.react.uimanager.PixelUtil.dpToPx import com.google.android.gms.maps.model.BitmapDescriptor import com.google.android.gms.maps.model.BitmapDescriptorFactory -import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.Marker import com.google.android.gms.maps.model.MarkerOptions import com.rngooglemapsplus.extensions.markerStyleEquals import com.rngooglemapsplus.extensions.styleHash +import com.rngooglemapsplus.extensions.toLatLng import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -40,13 +40,15 @@ class MapMarkerBuilder( icon: BitmapDescriptor?, ): MarkerOptions = MarkerOptions().apply { - position(LatLng(m.coordinate.latitude, m.coordinate.longitude)) + position(m.coordinate.toLatLng()) icon(icon) m.title?.let { title(it) } m.snippet?.let { snippet(it) } m.opacity?.let { alpha(it.toFloat()) } m.flat?.let { flat(it) } m.draggable?.let { draggable(it) } + m.rotation?.let { rotation(it.toFloat()) } + m.infoWindowAnchor?.let { infoWindowAnchor(it.x.toFloat(), it.y.toFloat()) } m.anchor?.let { anchor((m.anchor.x).toFloat(), (m.anchor.y).toFloat()) } m.zIndex?.let { zIndex(it.toFloat()) } } @@ -57,10 +59,7 @@ class MapMarkerBuilder( next: RNMarker, ) { marker.position = - LatLng( - next.coordinate.latitude, - next.coordinate.longitude, - ) + next.coordinate.toLatLng() if (!prev.markerStyleEquals(next)) { buildIconAsync(marker.id, next) { icon -> @@ -72,6 +71,11 @@ class MapMarkerBuilder( marker.alpha = next.opacity?.toFloat() ?: 0f marker.isFlat = next.flat ?: false marker.isDraggable = next.draggable ?: false + marker.rotation = next.rotation?.toFloat() ?: 0f + marker.setInfoWindowAnchor( + (next.infoWindowAnchor?.x ?: 0.5).toFloat(), + (next.infoWindowAnchor?.y ?: 0).toFloat(), + ) marker.setAnchor( (next.anchor?.x ?: 0.5).toFloat(), (next.anchor?.y ?: 1.0).toFloat(), diff --git a/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt b/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt index f3173ae..a69e88e 100644 --- a/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt +++ b/android/src/main/java/com/rngooglemapsplus/MapPolygonBuilder.kt @@ -2,38 +2,46 @@ package com.rngooglemapsplus import android.graphics.Color import com.facebook.react.uimanager.PixelUtil.dpToPx -import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.Polygon import com.google.android.gms.maps.model.PolygonOptions import com.rngooglemapsplus.extensions.toColor +import com.rngooglemapsplus.extensions.toLatLng class MapPolygonBuilder { fun build(poly: RNPolygon): PolygonOptions = PolygonOptions().apply { poly.coordinates.forEach { pt -> add( - com.google.android.gms.maps.model - .LatLng(pt.latitude, pt.longitude), + pt.toLatLng(), ) } poly.fillColor?.let { fillColor(it.toColor()) } poly.strokeColor?.let { strokeColor(it.toColor()) } poly.strokeWidth?.let { strokeWidth(it.dpToPx()) } poly.pressable?.let { clickable(it) } + poly.geodesic?.let { geodesic(it) } + poly.holes?.forEach { hole -> + addHole(hole.coordinates.map { it.toLatLng() }) + } poly.zIndex?.let { zIndex(it.toFloat()) } } fun update( - gmsPoly: Polygon, + poly: Polygon, next: RNPolygon, ) { - gmsPoly.points = + poly.points = next.coordinates.map { - LatLng(it.latitude, it.longitude) + it.toLatLng() } - gmsPoly.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT - gmsPoly.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK - gmsPoly.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f - gmsPoly.zIndex = next.zIndex?.toFloat() ?: 0f + poly.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT + poly.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK + poly.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f + poly.isClickable = next.pressable ?: false + poly.isGeodesic = next.geodesic ?: false + poly.holes = next.holes?.map { hole -> + hole.coordinates.map { it.toLatLng() } + } ?: emptyList() + poly.zIndex = next.zIndex?.toFloat() ?: 0f } } diff --git a/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt b/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt index f5571a9..d4bb76f 100644 --- a/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt +++ b/android/src/main/java/com/rngooglemapsplus/MapPolylineBuilder.kt.kt @@ -5,18 +5,18 @@ import com.facebook.react.uimanager.PixelUtil.dpToPx import com.google.android.gms.maps.model.ButtCap import com.google.android.gms.maps.model.Cap import com.google.android.gms.maps.model.JointType -import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.Polyline import com.google.android.gms.maps.model.PolylineOptions import com.google.android.gms.maps.model.RoundCap import com.google.android.gms.maps.model.SquareCap import com.rngooglemapsplus.extensions.toColor +import com.rngooglemapsplus.extensions.toLatLng class MapPolylineBuilder { fun build(pl: RNPolyline): PolylineOptions = PolylineOptions().apply { pl.coordinates.forEach { pt -> - add(LatLng(pt.latitude, pt.longitude)) + add(pt.toLatLng()) } pl.width?.let { width(it.dpToPx()) } pl.lineCap?.let { @@ -25,6 +25,7 @@ class MapPolylineBuilder { } pl.lineJoin?.let { jointType(mapLineJoin(it)) } pl.color?.let { color(it.toColor()) } + pl.geodesic?.let { geodesic(it) } pl.pressable?.let { clickable(it) } pl.zIndex?.let { zIndex(it.toFloat()) } } @@ -33,14 +34,15 @@ class MapPolylineBuilder { polyline: Polyline, next: RNPolyline, ) { - polyline.points = next.coordinates.map { LatLng(it.latitude, it.longitude) } - + polyline.points = next.coordinates.map { it.toLatLng() } polyline.width = next.width?.dpToPx() ?: 1f val cap = mapLineCap(next.lineCap ?: RNLineCapType.BUTT) polyline.startCap = cap polyline.endCap = cap polyline.jointType = mapLineJoin(next.lineJoin ?: RNLineJoinType.MITER) polyline.color = next.color?.toColor() ?: Color.BLACK + polyline.isClickable = next.pressable ?: false + polyline.isGeodesic = next.geodesic ?: false polyline.zIndex = next.zIndex?.toFloat() ?: 0f } diff --git a/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt b/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt index d31d24e..899dbf4 100644 --- a/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +++ b/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt @@ -3,6 +3,7 @@ package com.rngooglemapsplus import com.facebook.proguard.annotations.DoNotStrip import com.facebook.react.bridge.UiThreadUtil import com.facebook.react.uimanager.ThemedReactContext +import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.model.MapStyleOptions import com.margelo.nitro.core.Promise import com.rngooglemapsplus.extensions.circleEquals @@ -40,11 +41,13 @@ class RNGoogleMapsPlusView( super.afterUpdate() if (!propsInitialized) { propsInitialized = true - view.initMapView( - initialProps?.mapId, - initialProps?.liteMode, - initialProps?.camera?.toCameraPosition(), - ) + val options = + GoogleMapOptions().apply { + initialProps?.mapId?.let { mapId(it) } + initialProps?.liteMode?.let { liteMode(it) } + initialProps?.camera?.let { camera(it.toCameraPosition()) } + } + view.initMapView(options) } } diff --git a/android/src/main/java/com/rngooglemapsplus/extensions/LatLngExtension.kt b/android/src/main/java/com/rngooglemapsplus/extensions/LatLngExtension.kt new file mode 100644 index 0000000..7042edb --- /dev/null +++ b/android/src/main/java/com/rngooglemapsplus/extensions/LatLngExtension.kt @@ -0,0 +1,6 @@ +package com.rngooglemapsplus.extensions + +import com.google.android.gms.maps.model.LatLng +import com.rngooglemapsplus.RNLatLng + +fun LatLng.toRnLatLng(): RNLatLng = RNLatLng(latitude, longitude) diff --git a/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt b/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt index ed29245..65c87e4 100644 --- a/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt +++ b/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt @@ -1,14 +1,13 @@ package com.rngooglemapsplus.extensions import com.google.android.gms.maps.model.CameraPosition -import com.google.android.gms.maps.model.LatLng import com.rngooglemapsplus.RNCamera fun RNCamera.toCameraPosition(): CameraPosition { val builder = CameraPosition.builder() center?.let { - builder.target(LatLng(it.latitude, it.longitude)) + builder.target(it.toLatLng()) } zoom?.let { builder.zoom(it.toFloat()) } diff --git a/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngExtension.kt b/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngExtension.kt new file mode 100644 index 0000000..0925f6a --- /dev/null +++ b/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngExtension.kt @@ -0,0 +1,6 @@ +package com.rngooglemapsplus.extensions + +import com.google.android.gms.maps.model.LatLng +import com.rngooglemapsplus.RNLatLng + +fun RNLatLng.toLatLng(): LatLng = LatLng(latitude, longitude) diff --git a/example/src/screens/PolygonsScreen.tsx b/example/src/screens/PolygonsScreen.tsx index 8f2df34..d6251df 100644 --- a/example/src/screens/PolygonsScreen.tsx +++ b/example/src/screens/PolygonsScreen.tsx @@ -1,11 +1,11 @@ import React, { useRef } from 'react'; import MapWrapper from '../components/MapWrapper'; -import { makePolygon } from '../utils/mapGenerators'; +import { makePolygon, makePolygonWithHoles } from '../utils/mapGenerators'; import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; export default function PolygonsScreen() { const mapRef = useRef(null); - const polygons = [makePolygon(1)]; + const polygons = [makePolygon(1), makePolygonWithHoles(2)]; return ; } diff --git a/example/src/utils/mapGenerators.ts b/example/src/utils/mapGenerators.ts index af0720d..5c9038e 100644 --- a/example/src/utils/mapGenerators.ts +++ b/example/src/utils/mapGenerators.ts @@ -59,6 +59,31 @@ export const makePolygon = (id: number): RNPolygon => ({ strokeWidth: 1 + (id % 5), }); +export const makePolygonWithHoles = (id: number): RNPolygon => ({ + id: id.toString(), + zIndex: id, + pressable: true, + coordinates: [ + { latitude: 37.7749, longitude: -122.4194 }, + { latitude: 37.7799, longitude: -122.4194 }, + { latitude: 37.7799, longitude: -122.4144 }, + { latitude: 37.7749, longitude: -122.4144 }, + ], + holes: [ + { + coordinates: [ + { latitude: 37.776, longitude: -122.418 }, + { latitude: 37.778, longitude: -122.418 }, + { latitude: 37.778, longitude: -122.416 }, + { latitude: 37.776, longitude: -122.416 }, + ], + }, + ], + fillColor: '#0000ff', + strokeColor: '#ff0000', + strokeWidth: 1 + (id % 5), +}); + export const makePolyline = (id: number): RNPolyline => ({ id: id.toString(), zIndex: id, diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index 4fcedc2..5da6af7 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -62,17 +62,12 @@ GMSIndoorDisplayDelegate { } @MainActor - func initMapView(mapId: String?, liteMode: Bool?, camera: GMSCameraPosition?) { + func initMapView(googleMapOptions: GMSMapViewOptions) { if initialized { return } initialized = true - let options = GMSMapViewOptions() - options.frame = bounds + googleMapOptions.frame = bounds - mapId.map { options.mapID = GMSMapID(identifier: $0) } - liteMode.map { _ in /* not supported */ } - camera.map { options.camera = $0 } - - mapView = GMSMapView.init(options: options) + mapView = GMSMapView.init(options: googleMapOptions) mapView?.delegate = self mapView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView?.paddingAdjustmentBehavior = .never @@ -93,10 +88,7 @@ GMSIndoorDisplayDelegate { != loc.coordinate.longitude { self.onLocationUpdate?( RNLocation( - RNLatLng( - latitude: loc.coordinate.latitude, - longitude: loc.coordinate.longitude - ), + loc.coordinate.toRNLatLng(), loc.course ) ) @@ -348,27 +340,16 @@ GMSIndoorDisplayDelegate { animated: Bool, durationMs: Double ) { - if coordinates.isEmpty { + guard let firstCoordinates = coordinates.first else { return } var bounds = GMSCoordinateBounds( - coordinate: CLLocationCoordinate2D( - latitude: coordinates[0].latitude, - longitude: coordinates[0].longitude - ), - coordinate: CLLocationCoordinate2D( - latitude: coordinates[0].latitude, - longitude: coordinates[0].longitude - ) + coordinate: firstCoordinates.toCLLocationCoordinate2D(), + coordinate: firstCoordinates.toCLLocationCoordinate2D() ) for coord in coordinates.dropFirst() { - bounds = bounds.includingCoordinate( - CLLocationCoordinate2D( - latitude: coord.latitude, - longitude: coord.longitude - ) - ) + bounds = bounds.includingCoordinate(coord.toCLLocationCoordinate2D()) } let insets = UIEdgeInsets( @@ -736,15 +717,12 @@ GMSIndoorDisplayDelegate { let cp = mapView.camera let region = RNRegion( - center: RNLatLng(center.latitude, center.longitude), + center: center.toRNLatLng(), latitudeDelta: latDelta, longitudeDelta: lngDelta ) let cam = RNCamera( - center: RNLatLng( - latitude: cp.target.latitude, - longitude: cp.target.longitude - ), + center: cp.target.toRNLatLng(), zoom: Double(cp.zoom), bearing: cp.bearing, tilt: cp.viewingAngle @@ -781,15 +759,12 @@ GMSIndoorDisplayDelegate { let cp = mapView.camera let region = RNRegion( - center: RNLatLng(center.latitude, center.longitude), + center: center.toRNLatLng(), latitudeDelta: latDelta, longitudeDelta: lngDelta ) let cam = RNCamera( - center: RNLatLng( - latitude: cp.target.latitude, - longitude: cp.target.longitude - ), + center: cp.target.toRNLatLng(), zoom: Double(cp.zoom), bearing: cp.bearing, tilt: cp.viewingAngle @@ -814,15 +789,12 @@ GMSIndoorDisplayDelegate { let cp = mapView.camera let region = RNRegion( - center: RNLatLng(center.latitude, center.longitude), + center: center.toRNLatLng(), latitudeDelta: latDelta, longitudeDelta: lngDelta ) let cam = RNCamera( - center: RNLatLng( - latitude: cp.target.latitude, - longitude: cp.target.longitude - ), + center: cp.target.toRNLatLng(), zoom: Double(cp.zoom), bearing: cp.bearing, tilt: cp.viewingAngle @@ -837,10 +809,7 @@ GMSIndoorDisplayDelegate { ) { onMain { self.onMapPress?( - RNLatLng( - latitude: coordinate.latitude, - longitude: coordinate.longitude - ) + coordinate.toRNLatLng(), ) } } @@ -875,7 +844,7 @@ GMSIndoorDisplayDelegate { onMain { self.onMarkerDragStart?( marker.userData as? String, - RNLatLng(marker.position.latitude, marker.position.longitude) + marker.position.toRNLatLng() ) } } @@ -884,7 +853,7 @@ GMSIndoorDisplayDelegate { onMain { self.onMarkerDrag?( marker.userData as? String, - RNLatLng(marker.position.latitude, marker.position.longitude) + marker.position.toRNLatLng() ) } } @@ -893,7 +862,7 @@ GMSIndoorDisplayDelegate { onMain { self.onMarkerDragEnd?( marker.userData as? String, - RNLatLng(marker.position.latitude, marker.position.longitude) + marker.position.toRNLatLng() ) } } diff --git a/ios/MapCircleBuilder.swift b/ios/MapCircleBuilder.swift index 729c7f6..50377bd 100644 --- a/ios/MapCircleBuilder.swift +++ b/ios/MapCircleBuilder.swift @@ -3,11 +3,7 @@ import GoogleMaps final class MapCircleBuilder { func build(_ c: RNCircle) -> GMSCircle { let circle = GMSCircle() - circle.position = CLLocationCoordinate2D( - latitude: c.center.latitude, - longitude: c.center.longitude - ) - + circle.position = c.center.toCLLocationCoordinate2D() circle.radius = c.radius c.fillColor.map { circle.fillColor = $0.toUIColor() } c.strokeColor.map { circle.strokeColor = $0.toUIColor() } @@ -19,11 +15,7 @@ final class MapCircleBuilder { } func update(_ next: RNCircle, _ c: GMSCircle) { - c.position = CLLocationCoordinate2D( - latitude: next.center.latitude, - longitude: next.center.longitude - ) - + c.position = next.center.toCLLocationCoordinate2D() c.radius = next.radius c.fillColor = next.fillColor?.toUIColor() ?? nil c.strokeColor = next.strokeColor?.toUIColor() ?? .black diff --git a/ios/MapMarkerBuilder.swift b/ios/MapMarkerBuilder.swift index d0e5803..5afb7e5 100644 --- a/ios/MapMarkerBuilder.swift +++ b/ios/MapMarkerBuilder.swift @@ -13,10 +13,7 @@ final class MapMarkerBuilder { func build(_ m: RNMarker, icon: UIImage?) -> GMSMarker { let marker = GMSMarker( - position: CLLocationCoordinate2D( - latitude: m.coordinate.latitude, - longitude: m.coordinate.longitude - ) + position: m.coordinate.toCLLocationCoordinate2D() ) marker.userData = m.id marker.tracksViewChanges = true @@ -26,6 +23,10 @@ final class MapMarkerBuilder { m.opacity.map { marker.iconView?.alpha = CGFloat($0) } m.flat.map { marker.isFlat = $0 } m.draggable.map { marker.isDraggable = $0 } + m.rotation.map { marker.rotation = $0 } + m.infoWindowAnchor.map { + marker.infoWindowAnchor = CGPoint(x: $0.x, y: $0.y) + } m.anchor.map { marker.groundAnchor = CGPoint( x: $0.x, @@ -43,16 +44,17 @@ final class MapMarkerBuilder { @MainActor func update(_ prev: RNMarker, _ next: RNMarker, _ m: GMSMarker) { - m.position = CLLocationCoordinate2D( - latitude: next.coordinate.latitude, - longitude: next.coordinate.longitude - ) - + m.position = next.coordinate.toCLLocationCoordinate2D() m.title = next.title m.snippet = next.snippet m.iconView?.alpha = CGFloat(next.opacity ?? 0) m.isFlat = next.flat ?? false m.isDraggable = next.draggable ?? false + m.rotation = next.rotation ?? 0 + m.infoWindowAnchor = CGPoint( + x: next.infoWindowAnchor?.x ?? 0.5, + y: next.infoWindowAnchor?.y ?? 0 + ) m.zIndex = Int32(next.zIndex ?? 0) m.groundAnchor = CGPoint( x: next.anchor?.x ?? 0.5, diff --git a/ios/MapPolygonBuilder.swift b/ios/MapPolygonBuilder.swift index 2dcd68e..c8c840b 100644 --- a/ios/MapPolygonBuilder.swift +++ b/ios/MapPolygonBuilder.swift @@ -5,7 +5,7 @@ final class MapPolygonBuilder { let path = GMSMutablePath() p.coordinates.forEach { path.add( - CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) + $0.toCLLocationCoordinate2D() ) } @@ -15,6 +15,14 @@ final class MapPolygonBuilder { p.strokeColor.map { pg.strokeColor = $0.toUIColor() } p.strokeWidth.map { pg.strokeWidth = CGFloat($0) } p.pressable.map { pg.isTappable = $0 } + p.geodesic.map { pg.geodesic = $0 } + p.holes.map { + pg.holes = $0.map { hole in + let path = GMSMutablePath() + hole.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) } + return path + } + } p.zIndex.map { pg.zIndex = Int32($0) } return pg @@ -24,7 +32,7 @@ final class MapPolygonBuilder { let path = GMSMutablePath() next.coordinates.forEach { path.add( - CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) + $0.toCLLocationCoordinate2D() ) } pg.path = path @@ -33,6 +41,13 @@ final class MapPolygonBuilder { pg.strokeColor = next.strokeColor?.toUIColor() ?? .black pg.strokeWidth = CGFloat(next.strokeWidth ?? 1.0) pg.isTappable = next.pressable ?? false + pg.geodesic = next.geodesic ?? false + pg.holes = + next.holes?.map { hole in + let path = GMSMutablePath() + hole.coordinates.forEach { path.add($0.toCLLocationCoordinate2D()) } + return path + } ?? [] pg.zIndex = Int32(next.zIndex ?? 0) } } diff --git a/ios/MapPolylineBuilder.swift b/ios/MapPolylineBuilder.swift index 0fdf0a3..ba41dc2 100644 --- a/ios/MapPolylineBuilder.swift +++ b/ios/MapPolylineBuilder.swift @@ -5,7 +5,7 @@ final class MapPolylineBuilder { let path = GMSMutablePath() p.coordinates.forEach { path.add( - CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) + $0.toCLLocationCoordinate2D() ) } @@ -16,6 +16,7 @@ final class MapPolylineBuilder { p.lineCap.map { _ in /* not supported */ } p.lineJoin.map { _ in /* not supported */ } p.pressable.map { pl.isTappable = $0 } + p.geodesic.map { pl.geodesic = $0 } p.zIndex.map { pl.zIndex = Int32($0) } return pl @@ -25,7 +26,7 @@ final class MapPolylineBuilder { let path = GMSMutablePath() next.coordinates.forEach { path.add( - CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) + $0.toCLLocationCoordinate2D() ) } pl.path = path @@ -35,6 +36,7 @@ final class MapPolylineBuilder { pl.strokeWidth = CGFloat(next.width ?? 1.0) pl.strokeColor = next.color?.toUIColor() ?? .black pl.isTappable = next.pressable ?? false + pl.geodesic = next.geodesic ?? false pl.zIndex = Int32(next.zIndex ?? 0) } } diff --git a/ios/RNGoogleMapsPlusView.swift b/ios/RNGoogleMapsPlusView.swift index 13b7e87..0fd68ee 100644 --- a/ios/RNGoogleMapsPlusView.swift +++ b/ios/RNGoogleMapsPlusView.swift @@ -34,11 +34,13 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec { if !propsInitialized { propsInitialized = true Task { @MainActor in - impl.initMapView( - mapId: self.initialProps?.mapId, - liteMode: self.initialProps?.liteMode, - camera: self.initialProps?.camera?.toGMSCameraPosition(current: nil) - ) + let options = GMSMapViewOptions() + initialProps?.mapId.map { options.mapID = GMSMapID(identifier: $0) } + initialProps?.liteMode.map { _ in /* not supported */ } + initialProps?.camera.map { + options.camera = $0.toGMSCameraPosition(current: nil) + } + impl.initMapView(googleMapOptions: options) } } } diff --git a/ios/extensions/CLLocationCoordinate2D+Extension.swift b/ios/extensions/CLLocationCoordinate2D+Extension.swift new file mode 100644 index 0000000..a8281e7 --- /dev/null +++ b/ios/extensions/CLLocationCoordinate2D+Extension.swift @@ -0,0 +1,7 @@ +import CoreLocation + +extension CLLocationCoordinate2D { + func toRNLatLng() -> RNLatLng { + RNLatLng(latitude: latitude, longitude: longitude) + } +} diff --git a/ios/extensions/RNLatLng+Extension.swift b/ios/extensions/RNLatLng+Extension.swift new file mode 100644 index 0000000..36f7e66 --- /dev/null +++ b/ios/extensions/RNLatLng+Extension.swift @@ -0,0 +1,7 @@ +import CoreLocation + +extension RNLatLng { + func toCLLocationCoordinate2D() -> CLLocationCoordinate2D { + CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + } +} diff --git a/src/types.ts b/src/types.ts index 3746c6e..b88b69c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -164,6 +164,8 @@ export type RNMarker = { opacity?: number; flat?: boolean; draggable?: boolean; + rotation?: number; + infoWindowAnchor?: RNPosition; iconSvg?: RNMarkerSvg; }; @@ -181,6 +183,12 @@ export type RNPolygon = { fillColor?: string; strokeColor?: string; strokeWidth?: number; + holes?: RNPolygonHole[]; + geodesic?: boolean; +}; + +export type RNPolygonHole = { + coordinates: RNLatLng[]; }; export type RNPolyline = { @@ -190,6 +198,7 @@ export type RNPolyline = { coordinates: RNLatLng[]; lineCap?: RNLineCapType; lineJoin?: RNLineJoinType; + geodesic?: boolean; color?: string; width?: number; };