diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Hole.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Hole.java new file mode 100644 index 00000000000..cabe16cc5c2 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Hole.java @@ -0,0 +1,53 @@ +package com.mapbox.mapboxsdk.annotations; + + +import android.os.Parcel; +import android.os.Parcelable; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import java.util.ArrayList; +import java.util.List; + +/** + * Encapsulates a {@link List} of {@link LatLng} points defining a hole + */ +public class Hole extends ArrayList implements Parcelable { + + public Hole() { + super(); + } + + /** + * Creates a Hole. + * + * @param holePoints {@link List} list of {@link LatLng} points defining a hole + */ + public Hole(List holePoints) { + super(holePoints); + } + + protected Hole(Parcel in) { + in.readTypedList(this, LatLng.CREATOR); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeTypedList(this); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Hole createFromParcel(Parcel in) { + return new Hole(in); + } + + public Hole[] newArray(int size) { + return new Hole[size]; + } + }; +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java index 4a72cb7d89c..9245d9cdc80 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java @@ -4,6 +4,9 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; +import java.util.ArrayList; +import java.util.List; + /** * Polygon is a geometry annotation that's a closed loop of coordinates. */ @@ -11,9 +14,11 @@ public final class Polygon extends BasePointCollection { private int fillColor = Color.BLACK; // default fillColor is black private int strokeColor = Color.BLACK; // default strokeColor is black + private List holes; Polygon() { super(); + holes = new ArrayList<>(); } /** @@ -26,7 +31,7 @@ public int getFillColor() { } /** - * Get the color fo the stroke of the polygon. + * Get the color of the stroke of the polygon. * * @return The color of the stroke. */ @@ -34,6 +39,15 @@ public int getStrokeColor() { return strokeColor; } + /** + * Returns a copy of the holes. + * + * @return A {@link List} of holes. + */ + public List getHoles() { + return new ArrayList<>(holes); + } + /** * Sets the color of the fill region of the polygon. * @@ -54,6 +68,27 @@ public void setStrokeColor(int color) { update(); } + /** + * Sets the holes of this polygon. This method will take a copy of the holes, so further + * mutations to holes will have no effect on this polygon. + * + * @param holes A {@link List} of {@link Hole} points making up the holes. + */ + public void setHoles(List holes) { + this.holes = new ArrayList<>(holes); + update(); + } + + /** + * Add a hole to the polygon. + * + * @param hole A {@link Hole} hole to be added. + */ + void addHole(Hole hole) { + holes.add(hole); + update(); + } + @Override void update() { MapboxMap mapboxMap = getMapboxMap(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java index 22f1258fc71..7405ebfb4a1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java @@ -30,6 +30,9 @@ private PolygonOptions(Parcel in) { ArrayList pointsList = new ArrayList<>(); in.readList(pointsList, LatLng.class.getClassLoader()); addAll(pointsList); + ArrayList holes = new ArrayList<>(); + in.readTypedList(holes, Hole.CREATOR); + addAllHoles(holes); alpha(in.readFloat()); fillColor(in.readInt()); strokeColor(in.readInt()); @@ -56,6 +59,7 @@ public int describeContents() { @Override public void writeToParcel(Parcel out, int flags) { out.writeList(getPoints()); + out.writeTypedList(getHoles()); out.writeFloat(getAlpha()); out.writeInt(getFillColor()); out.writeInt(getStrokeColor()); @@ -108,6 +112,43 @@ public PolygonOptions addAll(Iterable points) { return this; } + /** + * Adds a hole to the outline of the polygon being built. + * + * @param hole {@link Hole} list made up of {@link LatLng} points defining the hole + * @return This {@link PolygonOptions} object with the given hole added to the outline. + */ + public PolygonOptions addHole(Hole hole) { + polygon.addHole(hole); + return this; + } + + /** + * Adds holes to the outline of the polygon being built. + * + * @param holes {@link Hole} holes to be added to polygon geometry. + * @return This {@link PolygonOptions} object with the given holes added to the outline. + */ + public PolygonOptions addHole(Hole... holes) { + for (Hole hole : holes) { + addHole(hole); + } + return this; + } + + /** + * Adds holes to the outline of the polygon being built. + * + * @param holes {@link Iterable} list made up of {@link Hole} holes defining the hole geometry + * @return This {@link PolygonOptions} object with the given holes added to the outline. + */ + public PolygonOptions addAllHoles(Iterable holes) { + for (Hole hole : holes) { + addHole(hole); + } + return this; + } + /** * Set the alpha value of the polyline. * @@ -177,18 +218,33 @@ public int getStrokeColor() { return polygon.getStrokeColor(); } + /** + * Gets the points set for this {@link PolygonOptions} object. + * + * @return The list made up of {@link LatLng} points defining the polygon. + */ public List getPoints() { // the getter gives us a copy, which is the safe thing to do... return polygon.getPoints(); } + /** + * Gets the holes set for this {@link PolygonOptions} object. + * + * @return The list made up of {@link List} of {@link LatLng} points defining the holes. + */ + public List getHoles() { + return polygon.getHoles(); + } + + /** * Compares this {@link PolygonOptions} object with another {@link PolygonOptions} and * determines if their color, alpha, stroke color, and vertices match. * * @param o Another {@link PolygonOptions} to compare with this object. - * @return True if color, alpha, stroke color, and vertices match this {@link PolygonOptions} - * object. Else, false. + * @return True if color, alpha, stroke color, vertices and holes match this {@link PolygonOptions} + * {@link PolygonOptions} object. Else, false. */ @Override public boolean equals(Object o) { @@ -210,7 +266,10 @@ public boolean equals(Object o) { if (getStrokeColor() != polygon.getStrokeColor()) { return false; } - return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null); + if (getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null) { + return false; + } + return !(getHoles() != null ? !getHoles().equals(polygon.getHoles()) : polygon.getHoles() != null); } /** @@ -228,6 +287,7 @@ public int hashCode() { result = 31 * result + getFillColor(); result = 31 * result + getStrokeColor(); result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0); + result = 31 * result + (getHoles() != null ? getHoles().hashCode() : 0); return result; } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java index a2245a28e0c..429509e1d23 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java @@ -6,6 +6,7 @@ import android.view.Menu; import android.view.MenuItem; +import com.mapbox.mapboxsdk.annotations.Hole; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -18,6 +19,7 @@ import com.mapbox.mapboxsdk.testapp.R; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.BLUE_COLOR; @@ -26,6 +28,7 @@ import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.NO_ALPHA; import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.PARTIAL_ALPHA; import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.RED_COLOR; +import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.STAR_SHAPE_HOLES; import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.STAR_SHAPE_POINTS; /** @@ -44,6 +47,7 @@ public class PolygonActivity extends AppCompatActivity implements OnMapReadyCall private boolean visible = true; private boolean color = true; private boolean allPoints; + private boolean holes; @Override protected void onCreate(Bundle savedInstanceState) { @@ -140,6 +144,10 @@ public boolean onOptionsItemSelected(MenuItem item) { color = !color; polygon.setFillColor(color ? BLUE_COLOR : RED_COLOR); return true; + case R.id.action_id_holes: + holes = !holes; + polygon.setHoles(holes ? STAR_SHAPE_HOLES : Collections.emptyList()); + return true; default: return super.onOptionsItemSelected(item); } @@ -179,5 +187,27 @@ static final class Config { static final List BROKEN_SHAPE_POINTS = STAR_SHAPE_POINTS.subList(0, STAR_SHAPE_POINTS.size() - 3); + + static final List STAR_SHAPE_HOLES = new ArrayList() { + { + add(new Hole(new ArrayList() { + { + add(new LatLng(45.521743, -122.669091)); + add(new LatLng(45.530483, -122.676833)); + add(new LatLng(45.520483, -122.676833)); + add(new LatLng(45.521743, -122.669091)); + } + })); + add(new Hole(new ArrayList() { + { + add(new LatLng(45.529743, -122.662791)); + add(new LatLng(45.525543, -122.662791)); + add(new LatLng(45.525543, -122.660)); + add(new LatLng(45.527743, -122.660)); + add(new LatLng(45.529743, -122.662791)); + } + })); + } + }; } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_polygon.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_polygon.xml index a7fdf56be51..f2cd9aedbcb 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_polygon.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_polygon.xml @@ -17,4 +17,8 @@ android:id="@+id/action_id_color" android:title="@string/action_color_polygon" mapbox:showAsAction="never" /> + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index ac5c528c389..d2442fb161b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -132,6 +132,7 @@ Change alpha Change points Change color + Change holes Change width diff --git a/platform/android/src/annotation/polygon.cpp b/platform/android/src/annotation/polygon.cpp index ba82fc34dcb..fbd849432a6 100644 --- a/platform/android/src/annotation/polygon.cpp +++ b/platform/android/src/annotation/polygon.cpp @@ -9,13 +9,26 @@ jni::Class Polygon::javaClass; mbgl::FillAnnotation Polygon::toAnnotation(jni::JNIEnv& env, jni::Object polygon) { auto points = Polygon::getPoints(env, polygon); + auto holes = Polygon::getHoles(env, polygon); - mbgl::FillAnnotation annotation { mbgl::Polygon { MultiPoint::toGeometry>(env, points) } }; + mbgl::Polygon geometry { MultiPoint::toGeometry>(env, points) }; + + auto jHoleListsArray = java::util::List::toArray(env, holes); + std::size_t jHoleListsSize = jHoleListsArray.Length(env); + for (std::size_t i = 0; i < jHoleListsSize; i++) { + auto jHoleList = jHoleListsArray.Get(env, i); + geometry.push_back(MultiPoint::toGeometry>(env, jHoleList)); + jni::DeleteLocalRef(env, jHoleList); + } + jni::DeleteLocalRef(env, jHoleListsArray); + + mbgl::FillAnnotation annotation { geometry }; annotation.opacity = { Polygon::getOpacity(env, polygon) }; annotation.color = { Polygon::getFillColor(env, polygon) }; annotation.outlineColor = { Polygon::getOutlineColor(env, polygon) }; jni::DeleteLocalRef(env, points); + jni::DeleteLocalRef(env, holes); return annotation; } @@ -25,6 +38,11 @@ jni::Object Polygon::getPoints(jni::JNIEnv& env, jni::Object

Polygon::getHoles(jni::JNIEnv& env, jni::Object polygon) { + static auto field = Polygon::javaClass.GetField>(env, "holes"); + return polygon.Get(env, field); +} + float Polygon::getOpacity(jni::JNIEnv& env, jni::Object polygon) { static auto field = Polygon::javaClass.GetField(env, "alpha"); return polygon.Get(env, field); diff --git a/platform/android/src/annotation/polygon.hpp b/platform/android/src/annotation/polygon.hpp index 658aa5344b1..a98b2822cf2 100644 --- a/platform/android/src/annotation/polygon.hpp +++ b/platform/android/src/annotation/polygon.hpp @@ -28,6 +28,8 @@ class Polygon : private MultiPoint { static jni::Object getPoints(jni::JNIEnv&, jni::Object); + static jni::Object getHoles(jni::JNIEnv&, jni::Object); + static float getOpacity(jni::JNIEnv&, jni::Object); static mbgl::Color getFillColor(jni::JNIEnv&, jni::Object);