diff --git a/android/manifest b/android/manifest index 6c6ce06c..949a175a 100644 --- a/android/manifest +++ b/android/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 5.6.1 +version: 5.7.0 apiversion: 4 architectures: arm64-v8a armeabi-v7a x86 x86_64 description: External version of Map module using native Google Maps library diff --git a/android/src/ti/map/MapModule.java b/android/src/ti/map/MapModule.java index ff21d374..7e9c82c8 100644 --- a/android/src/ti/map/MapModule.java +++ b/android/src/ti/map/MapModule.java @@ -60,6 +60,7 @@ public class MapModule extends KrollModule implements OnMapsSdkInitializedCallba public static final String PROPERTY_STROKE_COLOR = "strokeColor"; public static final String PROPERTY_STROKE_WIDTH = "strokeWidth"; public static final String PROPERTY_FILL_COLOR = "fillColor"; + public static final String PROPERTY_OVERLAY_COLOR = "overlayColor"; public static final String PROPERTY_ZINDEX = "zIndex"; public static final String PROPERTY_POLYGON = "polygon"; public static final String PROPERTY_POLYGONS = "polygons"; diff --git a/android/src/ti/map/TiMapUtils.java b/android/src/ti/map/TiMapUtils.java index 9dd8168a..c6d52782 100644 --- a/android/src/ti/map/TiMapUtils.java +++ b/android/src/ti/map/TiMapUtils.java @@ -53,4 +53,41 @@ public static ArrayList processPoints(Object points) } return locationArray; } + + public static List createOuterBounds() { + float delta = 0.01f; + + return new ArrayList() {{ + add(new LatLng(90 - delta, -180 + delta)); + add(new LatLng(0, -180 + delta)); + add(new LatLng(-90 + delta, -180 + delta)); + add(new LatLng(-90 + delta, 0)); + add(new LatLng(-90 + delta, 180 - delta)); + add(new LatLng(0, 180 - delta)); + add(new LatLng(90 - delta, 180 - delta)); + add(new LatLng(90 - delta, 0)); + add(new LatLng(90 - delta, -180 + delta)); + }}; + } + + public static Iterable createHole(LatLng center, int radius) { + int points = 50; // number of corners of inscribed polygon + + double radiusLatitude = Math.toDegrees(radius / 1000 / 6371.0); + double radiusLongitude = radiusLatitude / Math.cos(Math.toRadians(center.latitude)); + + List result = new ArrayList<>(points); + + double anglePerCircleRegion = 2 * Math.PI / points; + + for (int i = 0; i < points; i++) { + double theta = i * anglePerCircleRegion; + double latitude = center.latitude + (radiusLatitude * Math.sin(theta)); + double longitude = center.longitude + (radiusLongitude * Math.cos(theta)); + + result.add(new LatLng(latitude, longitude)); + } + + return result; + } } diff --git a/android/src/ti/map/TiUIMapView.java b/android/src/ti/map/TiUIMapView.java index f52b68c5..5d53e49d 100644 --- a/android/src/ti/map/TiUIMapView.java +++ b/android/src/ti/map/TiUIMapView.java @@ -7,6 +7,10 @@ package ti.map; +import static ti.map.TiMapUtils.createHole; +import static ti.map.TiMapUtils.createOuterBounds; +import static ti.map.TiMapUtils.parseLocation; + import android.Manifest; import android.app.Activity; import android.content.Context; @@ -34,6 +38,7 @@ import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.MapStyleOptions; import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.TileOverlayOptions; import com.google.maps.android.clustering.Cluster; import com.google.maps.android.clustering.ClusterManager; @@ -894,6 +899,32 @@ public void removeAllPolylines() currentPolylines.clear(); } + /** + * Cutout Circle + */ + protected void addCutoutCircle(KrollDict circleConfig) { + if (map == null) { + return; + } + + Activity currentActivity = TiApplication.getAppCurrentActivity(); + + LatLng center = parseLocation(circleConfig); + int radius = circleConfig.getInt(MapModule.PROPERTY_RADIUS); + float strokeWidth = circleConfig.getDouble(MapModule.PROPERTY_STROKE_WIDTH).floatValue(); + int strokeColor = TiConvert.toColor(circleConfig.getString(MapModule.PROPERTY_STROKE_COLOR), currentActivity); + int overlayColor = TiConvert.toColor(circleConfig.getString(MapModule.PROPERTY_OVERLAY_COLOR), currentActivity); + + PolygonOptions options = new PolygonOptions() + .fillColor(overlayColor) + .addAll(createOuterBounds()) + .addHole(createHole(center, radius)) + .strokeColor(strokeColor) + .strokeWidth(strokeWidth); + + map.addPolygon(options); + } + /** * Circle */ diff --git a/android/src/ti/map/ViewProxy.java b/android/src/ti/map/ViewProxy.java index a09b9faf..45d5dd3d 100644 --- a/android/src/ti/map/ViewProxy.java +++ b/android/src/ti/map/ViewProxy.java @@ -77,6 +77,7 @@ public class ViewProxy extends TiViewProxy implements AnnotationDelegate private static final int MSG_ADD_CIRCLE = MSG_FIRST_ID + 921; private static final int MSG_REMOVE_CIRCLE = MSG_FIRST_ID + 922; private static final int MSG_REMOVE_ALL_CIRCLES = MSG_FIRST_ID + 923; + private static final int MSG_ADD_CUTOUT_CIRCLE = MSG_FIRST_ID + 924; private static final int MSG_ADD_IMAGE_OVERLAY = MSG_FIRST_ID + 931; private static final int MSG_REMOVE_IMAGE_OVERLAY = MSG_FIRST_ID + 932; @@ -289,6 +290,13 @@ public boolean handleMessage(Message msg) return true; } + case MSG_ADD_CUTOUT_CIRCLE: { + result = (AsyncResult) msg.obj; + handleAddCutoutCircle((KrollDict) result.getArg()); + result.setResult(null); + return true; + } + case MSG_REMOVE_CIRCLE: { result = (AsyncResult) msg.obj; handleRemoveCircle((CircleProxy) result.getArg()); @@ -1105,6 +1113,23 @@ public void handleAddCircle(CircleProxy circle) } } + @Kroll.method + public void addCutoutCircle(KrollDict circleConfiguration) + { + handleAddCutoutCircle(circleConfiguration); + } + + public void handleAddCutoutCircle(KrollDict circleConfiguration) + { + TiUIView view = peekView(); + if (view instanceof TiUIMapView) { + TiUIMapView mapView = (TiUIMapView) view; + if (mapView.getMap() != null) { + mapView.addCutoutCircle(circleConfiguration); + } + } + } + public void addPreloadCircle(CircleProxy c) { if (!preloadCircles.contains(c)) { diff --git a/apidoc/Map.yml b/apidoc/Map.yml index 37b783d1..52b3a5aa 100644 --- a/apidoc/Map.yml +++ b/apidoc/Map.yml @@ -821,7 +821,7 @@ properties: --- name: CutoutCircleConfiguration -summary: Options to configure a cutout circle (iOS only right now). +summary: Options to configure a cutout circle. properties: - name: longitude summary: Longitude value of the map point, in decimal degrees. diff --git a/apidoc/View.yml b/apidoc/View.yml index e42c3568..abfb713f 100644 --- a/apidoc/View.yml +++ b/apidoc/View.yml @@ -286,8 +286,7 @@ methods: A cutout circle represents a special polygon that spans over the whole world and has a cutout in the shape of a circle. The radius of the shape, the overlay color and stroke properties can be configured. - exclude-platforms: [android] - since: { iphone: "12.3.0", ipad: "12.3.0", macos: "12.3.0" } + since: "12.4.0" parameters: - name: circleConfiguration summary: A object.