diff --git a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CapacitorGoogleMaps.java b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CapacitorGoogleMaps.java index 366b8cea..b8d421d2 100644 --- a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CapacitorGoogleMaps.java +++ b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CapacitorGoogleMaps.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.graphics.Color; import android.graphics.Rect; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -19,6 +18,7 @@ import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.VisibleRegion; import java.util.ArrayList; import java.util.HashMap; @@ -278,7 +278,7 @@ public void run() { call.resolve(result); } else { - call.reject("map not found"); + call.reject("updateMap: map not found, mapId: " + mapId); } } }); @@ -298,7 +298,7 @@ public void run() { call.resolve(result); } else { - call.reject("map not found"); + call.reject("getMap: map not found, mapId: " + mapId); } } }); @@ -318,7 +318,7 @@ public void run() { customMapViews.remove(mapId); call.resolve(); } else { - call.reject("map not found"); + call.reject("removeMap: map not found, mapId: " + mapId); } } }); @@ -327,6 +327,7 @@ public void run() { @PluginMethod(returnType = PluginMethod.RETURN_NONE) public void clearMap(final PluginCall call) { final String mapId = call.getString("mapId"); + final boolean hide = Boolean.TRUE.equals(call.getBoolean("hide", false)); getBridge().getActivity().runOnUiThread(new Runnable() { @Override @@ -334,10 +335,10 @@ public void run() { CustomMapView customMapView = customMapViews.get(mapId); if (customMapView != null) { - customMapView.clear(); + customMapView.clear(hide); call.resolve(); } else { - call.reject("map not found"); + call.reject("clearMap: map not found, mapId: " + mapId); } } }); @@ -371,7 +372,60 @@ public void run() { call.resolve(); } else { - call.reject("map not found"); + call.reject("moveCamera: map not found, mapId: " + mapId); + } + } + }); + } + + @PluginMethod() + public void getRegionInfo(final PluginCall call) { + final String mapId = call.getString("mapId"); + + getBridge().getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + CustomMapView customMapView = customMapViews.get(mapId); + + if (customMapView != null) { + VisibleRegion region = customMapView.googleMap.getProjection().getVisibleRegion(); + + JSObject topLeft = new JSObject(); + JSObject topRight = new JSObject(); + JSObject bottomLeft = new JSObject(); + JSObject bottomRight = new JSObject(); + + topLeft.put("latitude", region.latLngBounds.northeast.latitude); + topLeft.put("longitude", region.latLngBounds.southwest.longitude); + + topRight.put("latitude", region.latLngBounds.northeast.latitude); + topRight.put("longitude", region.latLngBounds.northeast.longitude); + + bottomLeft.put("latitude", region.latLngBounds.southwest.latitude); + bottomLeft.put("longitude", region.latLngBounds.southwest.longitude); + + bottomRight.put("latitude", region.latLngBounds.southwest.latitude); + bottomRight.put("longitude", region.latLngBounds.northeast.longitude); + + JSObject bounds = new JSObject(); + bounds.put("topLeft", topLeft); + bounds.put("topRight", topRight); + bounds.put("bottomLeft", bottomLeft); + bounds.put("bottomRight", bottomRight); + + JSObject center = new JSObject(); + center.put("latitude", region.latLngBounds.getCenter().latitude); + center.put("longitude", region.latLngBounds.getCenter().longitude); + + CameraPosition camera = customMapView.googleMap.getCameraPosition(); + JSObject result = new JSObject(); + result.put("bounds", bounds); + result.put("center", center); + result.put("zoom", camera.zoom); + + call.resolve(result); + } else { + call.reject("getRegionInfo: map not found, mapId: " + mapId); } } }); @@ -500,7 +554,7 @@ public void run() { } ); } else { - call.reject("map not found"); + call.reject("addMarker: map not found, mapId: " + mapId); } } }); @@ -511,7 +565,7 @@ public void addMarkers(final PluginCall call) { final String mapId = call.getString("mapId"); CustomMapView customMapView = customMapViews.get(mapId); if (customMapView == null) { - call.reject("map not found"); + call.reject("addMarkers: map not found, mapId: " + mapId); return; } try { @@ -539,7 +593,7 @@ public void run() { call.resolve(); } else { - call.reject("map not found"); + call.reject("removeMarker: map not found, mapId: " + mapId); } } }); @@ -562,7 +616,7 @@ public void run() { call.resolve(customPolygon.getResultForPolygon(polygon, mapId)); }); } else { - call.reject("map not found"); + call.reject("addPolygon: map not found, mapId: " + mapId); } } }); @@ -584,7 +638,7 @@ public void run() { call.resolve(); } else { - call.reject("map not found"); + call.reject("removePolygon: map not found, mapId: " + mapId); } } }); diff --git a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CustomMapView.java b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CustomMapView.java index 13690d96..5839008b 100644 --- a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CustomMapView.java +++ b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/CustomMapView.java @@ -4,6 +4,7 @@ import android.annotation.SuppressLint; import android.content.pm.PackageManager; import android.location.Location; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -359,6 +360,8 @@ public void createMap(String callbackId, BoundingRect boundingRect, MapCameraPos GoogleMapOptions googleMapOptions = this.mapPreferences.generateGoogleMapOptions(); googleMapOptions.camera(this.mapCameraPosition.cameraPosition); + googleMapOptions.minZoomPreference(mapPreferences.minZoom); + googleMapOptions.maxZoomPreference(mapPreferences.maxZoom); mapView = new MapView(activity, googleMapOptions); @@ -444,9 +447,10 @@ public void removeFromView(ViewGroup parent) { parent.removeView(mapView); } - public void clear() { + public void clear(boolean hide) { googleMap.clear(); markers.clear(); + mapView.setVisibility(hide ? View.INVISIBLE : View.VISIBLE); } public void addMarker(CustomMarker customMarker, @Nullable Consumer consumer) { diff --git a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/MapPreferences.java b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/MapPreferences.java index d02e431b..f6cc6fcc 100644 --- a/android/src/main/java/com/hemangkumar/capacitorgooglemaps/MapPreferences.java +++ b/android/src/main/java/com/hemangkumar/capacitorgooglemaps/MapPreferences.java @@ -9,6 +9,8 @@ public class MapPreferences { public MapPreferencesGestures gestures; public MapPreferencesControls controls; public MapPreferencesAppearance appearance; + public Integer minZoom; + public Integer maxZoom; public MapPreferences() { this.gestures = new MapPreferencesGestures(); @@ -27,6 +29,9 @@ public void updateFromJSObject(@Nullable JSObject preferences) { // update appearance JSObject appearanceObject = preferences.getJSObject("appearance"); this.appearance.updateFromJSObject(appearanceObject); + // update zoom + this.minZoom = preferences.getInteger("minZoom", 1); + this.maxZoom = preferences.getInteger("maxZoom", 21); } } diff --git a/ios/Plugin/CustomMapView.swift b/ios/Plugin/CustomMapView.swift index 9e56ecbb..3a2b102a 100644 --- a/ios/Plugin/CustomMapView.swift +++ b/ios/Plugin/CustomMapView.swift @@ -111,6 +111,9 @@ class CustomMapView: UIViewController, GMSMapViewDelegate { self.GMapView.isMyLocationEnabled = self.mapPreferences.appearance.isMyLocationDotShown; self.GMapView.isTrafficEnabled = self.mapPreferences.appearance.isTrafficShown; + // set zoom + self.GMapView.setMinZoom(self.mapPreferences.minZoom, maxZoom: self.mapPreferences.maxZoom); + return self.getResultForMap(); } @@ -118,9 +121,10 @@ class CustomMapView: UIViewController, GMSMapViewDelegate { return self.getResultForMap(); } - func clearMap() { + func clearMap(hide: Bool) { if (self.GMapView != nil) { self.GMapView.clear(); + self.GMapView.isHidden = hide == true; } } diff --git a/ios/Plugin/MapPreferences.swift b/ios/Plugin/MapPreferences.swift index 81bf0420..2e764eed 100644 --- a/ios/Plugin/MapPreferences.swift +++ b/ios/Plugin/MapPreferences.swift @@ -4,6 +4,8 @@ class MapPreferences { public var gestures: MapPreferencesGestures! public var controls: MapPreferencesControls! public var appearance: MapPreferencesAppearance! + public var minZoom: Float! + public var maxZoom: Float! public init() { self.gestures = MapPreferencesGestures(); @@ -22,6 +24,9 @@ class MapPreferences { // update appearance let appearanceObject: JSObject! = preferences["appearance"] as? JSObject ?? JSObject(); self.appearance.updateFromJSObject(object: appearanceObject); + // update zoom + self.minZoom = preferences["minZoom"] as? Float ?? 1.0; + self.maxZoom = preferences["maxZoom"] as? Float ?? 21.0; } } } diff --git a/ios/Plugin/Plugin.m b/ios/Plugin/Plugin.m index 617794f3..3f4a7072 100644 --- a/ios/Plugin/Plugin.m +++ b/ios/Plugin/Plugin.m @@ -10,6 +10,7 @@ CAP_PLUGIN_METHOD(clearMap, CAPPluginReturnNone); CAP_PLUGIN_METHOD(removeMap, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(moveCamera, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(getRegionInfo, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(addMarker, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(addMarkers, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(removeMarker, CAPPluginReturnPromise); diff --git a/ios/Plugin/Plugin.swift b/ios/Plugin/Plugin.swift index b19c6611..9794556b 100644 --- a/ios/Plugin/Plugin.swift +++ b/ios/Plugin/Plugin.swift @@ -134,14 +134,15 @@ public class CapacitorGoogleMaps: CustomMapViewEvents { @objc func clearMap(_ call: CAPPluginCall) { let mapId: String = call.getString("mapId", "") + let hide: Bool = call.getBool("hide", false) DispatchQueue.main.async { guard let customMapView = self.customWebView?.customMapViews[mapId] else { call.reject("map not found") return } - - let result = customMapView.clearMap() + + let result = customMapView.clearMap(hide: hide) call.resolve() } @@ -178,6 +179,46 @@ public class CapacitorGoogleMaps: CustomMapViewEvents { } } + @objc func getRegionInfo(_ call: CAPPluginCall) { + let mapId: String = call.getString("mapId", "") + + DispatchQueue.main.async { + guard let customMapView = self.customWebView?.customMapViews[mapId] else { + call.reject("map not found") + return + } + + let region = customMapView.GMapView.projection.visibleRegion(); + let centerCoords = customMapView.GMapView.projection.coordinate(for: customMapView.GMapView.center) + + call.resolve([ + "bounds": [ + "topLeft": [ + "latitude": region.farLeft.latitude as Any, + "longitude": region.farLeft.longitude as Any + ], + "topRight": [ + "latitude": region.farRight.latitude as Any, + "longitude": region.farRight.longitude as Any + ], + "bottomLeft": [ + "latitude": region.nearLeft.latitude as Any, + "longitude": region.nearLeft.longitude as Any + ], + "bottomRight": [ + "latitude": region.nearRight.latitude as Any, + "longitude": region.nearRight.longitude as Any + ] + ], + "center": [ + "latitude": centerCoords.latitude as Any, + "longitude": centerCoords.longitude as Any + ], + "zoom": customMapView.GMapView.camera.zoom + ]) + } + } + @objc func addMarker(_ call: CAPPluginCall) { let mapId: String = call.getString("mapId", "") diff --git a/src/definitions.ts b/src/definitions.ts index 814b1bfc..d00b8f3f 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -10,6 +10,8 @@ import { RemoveMapOptions, ClearMapOptions, MoveCameraOptions, + GetRegionInfoOptions, + GetRegionInfoResult, ElementFromPointResultOptions, AddMarkerOptions, AddMarkerResult, @@ -68,6 +70,8 @@ export interface CapacitorGoogleMapsPlugin { moveCamera(options: MoveCameraOptions): Promise; + getRegionInfo(options: GetRegionInfoOptions): Promise; + addMarker(options: AddMarkerOptions): Promise; addMarkers(options: AddMarkersOptions): Promise; diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 2f1146f1..c3255473 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -5,6 +5,7 @@ export { UpdateMapOptions, UpdateMapResult } from "./methods/UpdateMap"; export { RemoveMapOptions } from "./methods/RemoveMap"; export { ClearMapOptions } from "./methods/ClearMap"; export { MoveCameraOptions } from "./methods/MoveCamera"; +export { GetRegionInfoOptions, GetRegionInfoResult } from './methods/GetRegionInfo'; export { ElementFromPointResultOptions } from "./methods/ElementFromPointResult"; export { AddMarkerOptions, AddMarkerResult } from "./methods/AddMarker"; export { diff --git a/src/interfaces/methods/ClearMap.ts b/src/interfaces/methods/ClearMap.ts index 454f11ec..b12964d5 100644 --- a/src/interfaces/methods/ClearMap.ts +++ b/src/interfaces/methods/ClearMap.ts @@ -3,4 +3,9 @@ export interface ClearMapOptions { * @since 2.0.0 */ mapId: string; + /** + * @since 2.0.0 + * if set to true MapView will become invisible. default false. + */ + hide?: boolean; } diff --git a/src/interfaces/methods/GetRegionInfo.ts b/src/interfaces/methods/GetRegionInfo.ts new file mode 100644 index 00000000..b00bef85 --- /dev/null +++ b/src/interfaces/methods/GetRegionInfo.ts @@ -0,0 +1,36 @@ +import { LatLng } from "../models/LatLng"; + +export interface GetRegionInfoOptions { + /** + * @since 2.0.0 + */ + mapId: string; +} + +export interface Bounds { + /** + * @since 2.0.0 + */ + topLeft: LatLng; + /** + * @since 2.0.0 + */ + topRight: LatLng; + /** + * @since 2.0.0 + */ + bottomLeft: LatLng; + /** + * @since 2.0.0 + */ + bottomRight: LatLng; +} + +export interface GetRegionInfoResult { + /** + * @since 2.0.0 + */ + bounds: Bounds; + center: LatLng; + zoom: number; +} diff --git a/src/interfaces/models/GoogleMap/Preferences.ts b/src/interfaces/models/GoogleMap/Preferences.ts index da9a5c3d..2c5957ce 100644 --- a/src/interfaces/models/GoogleMap/Preferences.ts +++ b/src/interfaces/models/GoogleMap/Preferences.ts @@ -17,10 +17,14 @@ export interface MapPreferences { * @since 2.0.0 */ appearance?: MapAppearance; - - maxZoom?: number; // @todo: Sets a preferred upper bound for the camera zoom. - - minZoom?: number; // @todo: Sets a preferred lower bound for the camera zoom. + /** + * @since 2.0.0 + */ + minZoom?: number; + /** + * @since 2.0.0 + */ + maxZoom?: number; padding?: any; // @todo: Sets padding on the map. diff --git a/src/web.ts b/src/web.ts index 517e4f69..95b9dedd 100644 --- a/src/web.ts +++ b/src/web.ts @@ -11,6 +11,8 @@ import { RemoveMapOptions, ClearMapOptions, MoveCameraOptions, + GetRegionInfoOptions, + GetRegionInfoResult, ElementFromPointResultOptions, AddMarkerOptions, AddMarkerResult, @@ -73,6 +75,10 @@ export class CapacitorGoogleMapsWeb throw this.unimplemented("Not implemented on web."); } + async getRegionInfo(_options: GetRegionInfoOptions): Promise { + throw new Error('Method not implemented on web.'); + } + async addMarker(_options: AddMarkerOptions): Promise { throw this.unimplemented("Not implemented on web."); }