diff options
author | Brad Leege <bleege@gmail.com> | 2015-07-22 10:15:34 -0500 |
---|---|---|
committer | Brad Leege <bleege@gmail.com> | 2015-07-22 10:15:34 -0500 |
commit | 93e1ced3bb0f204ff7747bd13e563959be8d35ae (patch) | |
tree | 825b40aaaf8ff7d4645353041a23d04778de5ff7 | |
parent | 38f3bed63ece0214d02a755991ee7f1d7b54ba10 (diff) | |
parent | 0f56c2b0d5766996d51c73f5e131ec8df21d5fca (diff) | |
download | qtlocation-mapboxgl-93e1ced3bb0f204ff7747bd13e563959be8d35ae.tar.gz |
Merge branch 'android-annotations' of git://github.com/hallahan/mapbox-gl-native into hallahan-android-annotations
22 files changed, 1584 insertions, 6 deletions
diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index cfb1291bcd..1e2288c61b 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -16,6 +16,8 @@ #include <mbgl/android/jni.hpp> #include <mbgl/android/native_map_view.hpp> #include <mbgl/map/map.hpp> +#include <mbgl/annotation/point_annotation.hpp> +#include <mbgl/annotation/shape_annotation.hpp> #include <mbgl/platform/event.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/storage/network_status.hpp> @@ -39,6 +41,30 @@ jmethodID latLngConstructorId = nullptr; jfieldID latLngLatitudeId = nullptr; jfieldID latLngLongitudeId = nullptr; +jclass markerClass = nullptr; +jmethodID markerConstructorId = nullptr; +jfieldID markerPositionId = nullptr; +jfieldID markerSpriteId = nullptr; + +jclass polylineClass = nullptr; +jmethodID polylineConstructorId = nullptr; +jfieldID polylineAlphaId = nullptr; +jfieldID polylineVisibleId = nullptr; +jfieldID polylineColorId = nullptr; +jfieldID polylineWidthId = nullptr; +jfieldID polylinePointsId = nullptr; + +jclass polygonClass = nullptr; +jmethodID polygonConstructorId = nullptr; +jfieldID polygonAlphaId = nullptr; +jfieldID polygonVisibleId = nullptr; +jfieldID polygonFillColorId = nullptr; +jfieldID polygonStrokeColorId = nullptr; +jfieldID polygonStrokeWidthId = nullptr; +jfieldID polygonPointsId = nullptr; +jfieldID polygonHolesId = nullptr; + + jclass latLngZoomClass = nullptr; jmethodID latLngZoomConstructorId = nullptr; jfieldID latLngZoomLatitudeId = nullptr; @@ -155,6 +181,56 @@ std::vector<std::string> std_vector_string_from_jobject(JNIEnv *env, jobject jli return vector; } +mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jobject jlist) { + mbgl::AnnotationSegment segment; + + if (jlist == nullptr) { + if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { + env->ExceptionDescribe(); + return segment; + } + return segment; + } + + jobjectArray array = + reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId)); + if (env->ExceptionCheck() || (array == nullptr)) { + env->ExceptionDescribe(); + return segment; + } + + jsize len = env->GetArrayLength(array); + if (len < 0) { + env->ExceptionDescribe(); + return segment; + } + + segment.reserve(len); + + for (jsize i = 0; i < len; i++) { + jobject latLng = reinterpret_cast<jobject>(env->GetObjectArrayElement(array, i)); + if (latLng == nullptr) { + env->ExceptionDescribe(); + return segment; + } + + jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return segment; + } + + jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return segment; + } + + segment.push_back(mbgl::LatLng(latitude, longitude)); + } + return segment; +} + jobject std_vector_string_to_jobject(JNIEnv *env, std::vector<std::string> vector) { jobject jlist = env->NewObject(arrayListClass, arrayListConstructorId); if (jlist == nullptr) { @@ -433,6 +509,176 @@ void JNICALL nativeSetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j nativeMapView->getMap().setLatLng(mbgl::LatLng(latitude, longitude), std::chrono::milliseconds(duration)); } +jlong JNICALL nativeAddMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject marker) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarker"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr); + + jobject position = env->GetObjectField(marker, markerPositionId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jstring jsprite = (jstring)env->GetObjectField(marker, markerSpriteId); + std::string sprite = std_string_from_jstring(env, jsprite); + + jdouble latitude = env->GetDoubleField(position, latLngLatitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jdouble longitude = env->GetDoubleField(position, latLngLongitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long. + return (jlong) nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), sprite)); +} + +jlong JNICALL nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polyline) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolyline"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr); + + // ***** Java fields ***** // + // float alpha; + // boolean visible; + // int color + // float width + // List<LatLng> points + + jfloat alpha = env->GetFloatField(polyline, polylineAlphaId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jboolean visible = env->GetBooleanField(polyline, polylineVisibleId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + visible = JNI_TRUE; + + jint color = env->GetIntField(polyline, polylineColorId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + int r = (color>>16)&0xFF; + int g = (color>>8)&0xFF; + int b = (color)&0xFF; + int a = (color>>24)&0xFF; + + jfloat width = env->GetFloatField(polyline, polylineWidthId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + mbgl::StyleProperties shapeProperties; + mbgl::LineProperties lineProperties; + lineProperties.opacity = alpha; + lineProperties.color = {{ (float)r, (float)g, (float)b, (float)a }}; + lineProperties.width = width; + shapeProperties.set<mbgl::LineProperties>(lineProperties); + + jobject points = env->GetObjectField(polyline, polylinePointsId); + mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); + + std::vector<mbgl::ShapeAnnotation> shapes; + shapes.emplace_back(mbgl::AnnotationSegments {{ segment }}, shapeProperties); + + std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); + uint32_t id = shapeAnnotationIDs.at(0); + return (jlong) id; +} + +jlong JNICALL nativeAddPolygon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polygon) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolygon"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr); + + // ***** Java fields ***** // + // float alpha; + // boolean visible; + // int fillColor + // int strokeColor + // float strokeWidth + // List<LatLng> points + // List<List<LatLng>> holes + + jfloat alpha = env->GetFloatField(polygon, polygonAlphaId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jboolean visible = env->GetBooleanField(polygon, polygonVisibleId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + visible = JNI_TRUE; + + jint fillColor = env->GetIntField(polygon, polygonFillColorId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jint strokeColor = env->GetIntField(polygon, polygonStrokeColorId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + int rF = (fillColor>>16)&0xFF; + int gF = (fillColor>>8)&0xFF; + int bF = (fillColor)&0xFF; + int aF = (fillColor>>24)&0xFF; + + int rS = (strokeColor>>16)&0xFF; + int gS = (strokeColor>>8)&0xFF; + int bS = (strokeColor)&0xFF; + int aS = (strokeColor>>24)&0xFF; + + // jfloat strokeWidth = env->GetFloatField(polygon, polygonStrokeWidthId); + // if (env->ExceptionCheck()) { + // env->ExceptionDescribe(); + // return -1; + // } + + mbgl::StyleProperties shapeProperties; + mbgl::FillProperties fillProperties; + fillProperties.opacity = alpha; + fillProperties.stroke_color = {{ (float)rS, (float)gS, (float)bS, (float)aS }}; + fillProperties.fill_color = {{ (float)rF, (float)gF, (float)bF, (float)aF }}; + shapeProperties.set<mbgl::FillProperties>(fillProperties); + + jobject points = env->GetObjectField(polygon, polygonPointsId); + mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); + + std::vector<mbgl::ShapeAnnotation> shapes; + shapes.emplace_back(mbgl::AnnotationSegments {{ segment }}, shapeProperties); + + std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); + uint32_t id = shapeAnnotationIDs.at(0); + return (jlong) id; +} + +void JNICALL nativeRemoveAnnotation(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlong annotationId) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotation"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr); + nativeMapView->getMap().removeAnnotation((uint32_t)annotationId); +} + jobject JNICALL nativeGetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLatLng"); assert(nativeMapViewPtr != 0); @@ -783,6 +1029,126 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + markerClass = env->FindClass("com/mapbox/mapboxgl/annotations/Marker"); + if (markerClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + markerConstructorId = env->GetMethodID(markerClass, "<init>", "()V"); + if (markerConstructorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + markerPositionId = env->GetFieldID(markerClass, "position", "Lcom/mapbox/mapboxgl/geometry/LatLng;"); + if (markerPositionId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + markerSpriteId = env->GetFieldID(markerClass, "sprite", "Ljava/lang/String;"); + if (markerSpriteId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineClass = env->FindClass("com/mapbox/mapboxgl/annotations/Polyline"); + if (polylineClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineConstructorId = env->GetMethodID(polylineClass, "<init>", "()V"); + if (polylineConstructorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineAlphaId = env->GetFieldID(polylineClass, "alpha", "F"); + if (polylineAlphaId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineVisibleId = env->GetFieldID(polylineClass, "visible", "Z"); + if (polylineVisibleId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineColorId = env->GetFieldID(polylineClass, "color", "I"); + if (polylineColorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineWidthId = env->GetFieldID(polylineClass, "width", "F"); + if (polylineWidthId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylinePointsId = env->GetFieldID(polylineClass, "points", "Ljava/util/List;"); + if (polylineWidthId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonClass = env->FindClass("com/mapbox/mapboxgl/annotations/Polygon"); + if (polygonClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonConstructorId = env->GetMethodID(polygonClass, "<init>", "()V"); + if (polygonConstructorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonAlphaId = env->GetFieldID(polygonClass, "alpha", "F"); + if (polygonAlphaId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonVisibleId = env->GetFieldID(polygonClass, "visible", "Z"); + if (polygonVisibleId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonFillColorId = env->GetFieldID(polygonClass, "fillColor", "I"); + if (polygonFillColorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonStrokeColorId = env->GetFieldID(polygonClass, "strokeColor", "I"); + if (polygonStrokeColorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonStrokeWidthId = env->GetFieldID(polygonClass, "strokeWidth", "F"); + if (polygonStrokeWidthId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonPointsId = env->GetFieldID(polygonClass, "points", "Ljava/util/List;"); + if (polygonPointsId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonHolesId = env->GetFieldID(polygonClass, "holes", "Ljava/util/List;"); + if (polygonHolesId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + latLngZoomClass = env->FindClass("com/mapbox/mapboxgl/geometry/LatLngZoom"); if (latLngZoomClass == nullptr) { env->ExceptionDescribe(); @@ -976,6 +1342,13 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativeMoveBy", "(JDDJ)V", reinterpret_cast<void *>(&nativeMoveBy)}, {"nativeSetLatLng", "(JLcom/mapbox/mapboxgl/geometry/LatLng;J)V", reinterpret_cast<void *>(&nativeSetLatLng)}, + {"nativeAddMarker", "(JLcom/mapbox/mapboxgl/annotations/Marker;)J", + reinterpret_cast<void *>(&nativeAddMarker)}, + {"nativeAddPolyline", "(JLcom/mapbox/mapboxgl/annotations/Polyline;)J", + reinterpret_cast<void *>(&nativeAddPolyline)}, + {"nativeAddPolygon", "(JLcom/mapbox/mapboxgl/annotations/Polygon;)J", + reinterpret_cast<void *>(&nativeAddPolygon)}, + {"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast<void *>(&nativeRemoveAnnotation)}, {"nativeGetLatLng", "(J)Lcom/mapbox/mapboxgl/geometry/LatLng;", reinterpret_cast<void *>(&nativeGetLatLng)}, {"nativeResetPosition", "(J)V", reinterpret_cast<void *>(&nativeResetPosition)}, @@ -1026,6 +1399,24 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + markerClass = reinterpret_cast<jclass>(env->NewGlobalRef(markerClass)); + if (markerClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polylineClass = reinterpret_cast<jclass>(env->NewGlobalRef(polylineClass)); + if (polylineClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + polygonClass = reinterpret_cast<jclass>(env->NewGlobalRef(polygonClass)); + if (polygonClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + latLngZoomClass = reinterpret_cast<jclass>(env->NewGlobalRef(latLngZoomClass)); if (latLngZoomClass == nullptr) { env->ExceptionDescribe(); @@ -1109,6 +1500,33 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { latLngLongitudeId = nullptr; latLngLatitudeId = nullptr; + env->DeleteGlobalRef(markerClass); + markerClass = nullptr; + markerConstructorId = nullptr; + markerPositionId = nullptr; + markerSpriteId = nullptr; + + env->DeleteGlobalRef(polylineClass); + polylineClass = nullptr; + polylineConstructorId = nullptr; + polylineAlphaId = nullptr; + polylineVisibleId = nullptr; + polylineColorId = nullptr; + polylineWidthId = nullptr; + polylinePointsId = nullptr; + + env->DeleteGlobalRef(polygonClass); + polygonClass = nullptr; + polygonConstructorId = nullptr; + polygonAlphaId = nullptr; + polygonVisibleId = nullptr; + polygonFillColorId = nullptr; + polygonStrokeColorId = nullptr; + polygonStrokeWidthId = nullptr; + polygonPointsId = nullptr; + polygonHolesId = nullptr; + + env->DeleteGlobalRef(latLngZoomClass); latLngZoomClass = nullptr; latLngZoomConstructorId = nullptr; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java new file mode 100644 index 0000000000..e38af77cd8 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java @@ -0,0 +1,64 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.views.MapView; + + +public abstract class Annotation { + + /** + * The annotation id + * + * Internal C++ id is stored as unsigned int. + */ + protected Long id; // null unless added to a MapView + private MapView mapView; + + float alpha = 1; + boolean visible = true; + + + public Annotation() {} + + public float getAlpha() { + return alpha; + } + + public long getId() { + return id; + } + + public boolean isVisible() { + return visible; + } + + public void remove() { + if (mapView == null) return; + mapView.removeAnnotation(this); + } + + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + public void setId(Long id) { + this.id = id; + } + + public void setMapView(MapView mapView) { + this.mapView = mapView; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + // TODO: Implement getZIndex of Google Maps Android API +// public float getZIndex() { +// +// } + + // TODO: Implement setZIndex of Google Maps Android API +// public void setZIndex(float zIndex) { +// +// } +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/AnnotationOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/AnnotationOptions.java new file mode 100644 index 0000000000..f03ff45f76 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/AnnotationOptions.java @@ -0,0 +1,22 @@ +package com.mapbox.mapboxgl.annotations; + +public abstract class AnnotationOptions { + + protected Annotation annotation; + + public AnnotationOptions() {} + + public AnnotationOptions alpha(float alpha) { + annotation.alpha = alpha; + return this; + } + + public float getAlpha() { + return annotation.alpha; + } + + public boolean isVisible() { + return annotation.visible; + } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Circle.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Circle.java new file mode 100644 index 0000000000..f8908465b9 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Circle.java @@ -0,0 +1,67 @@ +package com.mapbox.mapboxgl.annotations; + + +import android.graphics.Color; + +import com.mapbox.mapboxgl.geometry.LatLng; + +/** + * UNIMPLEMENTED: Needs implementation in Native. + * + * https://github.com/mapbox/mapbox-gl-native/issues/1882 + * https://github.com/mapbox/mapbox-gl-native/issues/1726 + */ +public class Circle extends Annotation { + + LatLng center; + int fillColor = Color.BLACK; + double radius; + int strokeColor = Color.BLACK; + float strokeWidth = 10; // Google Maps API defaults to 10 + + public LatLng getCenter() { + return center; + } + + public int getFillColor() { + return fillColor; + } + + /** + * Returns the circle's radius, in meters. + * + * @return radius in meters + */ + public double getRadius() { + return radius; + } + + public int getStrokeColor() { + return strokeColor; + } + + public float getStrokeWidth() { + return strokeWidth; + } + + public void setCenter(LatLng center) { + this.center = center; + } + + public void setFillColor(int color) { + fillColor = color; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public void setStrokeColor (int color) { + strokeColor = color; + } + + public void setStrokeWidth (float width) { + strokeWidth = width; + } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/CircleOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/CircleOptions.java new file mode 100644 index 0000000000..5e97d5b5e4 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/CircleOptions.java @@ -0,0 +1,64 @@ +package com.mapbox.mapboxgl.annotations; + + +import com.mapbox.mapboxgl.geometry.LatLng; + +/** + * UNIMPLEMENTED: Needs implementation in Native. + * + * https://github.com/mapbox/mapbox-gl-native/issues/1882 + * https://github.com/mapbox/mapbox-gl-native/issues/1726 + */ +public class CircleOptions extends AnnotationOptions { + + private Circle circle; + + public CircleOptions() { + circle = new Circle(); + } + public CircleOptions center(LatLng center) { + circle.center = center; + return this; + } + + public CircleOptions fillColor(int color) { + circle.fillColor = color; + return this; + } + + public LatLng getCenter() { + return circle.center; + } + + public int getFillColor() { + return circle.fillColor; + } + + public double getRadius() { + return circle.radius; + } + + public int getStrokeColor () { + return circle.strokeColor; + } + + public float getStrokeWidth() { + return circle.strokeWidth; + } + + public CircleOptions radius (double radius) { + circle.radius = radius; + return this; + } + + public CircleOptions strokeColor(int color) { + circle.strokeColor = color; + return this; + } + + public CircleOptions strokeWidth (float width) { + circle.strokeWidth = width; + return this; + } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Marker.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Marker.java new file mode 100644 index 0000000000..f0c53a36c0 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Marker.java @@ -0,0 +1,154 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.geometry.LatLng; + + +public class Marker extends Annotation { + + float anchorU; + float anchorV; + boolean draggable; + boolean flat; + float infoWindowAnchorU; + float infoWindowAnchorV; + LatLng position; + float rotation; + String snippet; + String sprite = "default_marker"; + String title; + + private boolean infoWindowShown = false; + + public Marker() {} + + /** + * If two markers have the same LatLng, they are equal. + * + * @param other object + * @return boolean - do they have the same LatLng + */ + public boolean equals(Object other) { + if (!(other instanceof Marker)) return false; + double lat = position.getLatitude(); + double lng = position.getLongitude(); + LatLng otherPosition = ((Marker)other).getPosition(); + double otherLat = otherPosition.getLatitude(); + double otherLng = otherPosition.getLongitude(); + return (lat == otherLat && otherLng == lng); + } + + public float getAlpha() { + return alpha; + } + + public float getAnchorU() { + return anchorU; + } + + public float getAnchorV() { + return anchorV; + } + + /** + * NOTE: Google Maps Android API uses String for IDs. + * + * Internal C++ id is stored as unsigned int. + * + * @return the annotation id + */ + public long getId() { + return id; + } + + public LatLng getPosition() { + return position; + } + + public float getRotation() { + return rotation; + } + + public String getSnippet() { + return snippet; + } + + public String getTitle() { + return title; + } + + public void hideInfoWindow() { + //TODO hideInfoWindow + infoWindowShown = false; + } + + public boolean isDraggable() { + return draggable; + } + + public boolean isFlat() { + return flat; + } + + public boolean isInfoWindowShown () { + return infoWindowShown; + } + + void setAnchor(float u, float v) { + this.anchorU = u; + this.anchorV = v; + } + + void setDraggable(boolean draggable) { + this.draggable = draggable; + } + + void setFlat(boolean flat) { + this.flat = flat; + } + + void setInfoWindowAnchor(float u, float v) { + infoWindowAnchorU = u; + infoWindowAnchorV = v; + } + + void setPosition(LatLng latlng) { + this.position = position; + } + + void setRotation(float rotation) { + this.rotation = rotation; + } + + void setSnippet(String snippet) { + this.snippet = snippet; + } + + /** + * You can specify the name of a sprite to get a marker other than the default marker. + * This name can be found in the sprite json file: + * + * https://github.com/mapbox/mapbox-gl-styles/blob/mb-pages/sprites/mapbox-streets.json + * + * @param sprite + */ + void setSprite(String sprite) { + this.sprite = sprite; + } + + void setTitle(String title) { + this.title = title; + } + + void showInfoWindow() { + infoWindowShown = true; + } + + + // TODO Method in Google Maps Android API +// public int hashCode() + + // TODO: Implement this method of Google Maps Android API +// void setIcon(BitmapDescriptor icon) { +// +// } +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MarkerOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MarkerOptions.java new file mode 100644 index 0000000000..2e577067db --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MarkerOptions.java @@ -0,0 +1,125 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.geometry.LatLng; + +public class MarkerOptions extends AnnotationOptions { + + public MarkerOptions() { + annotation = new Marker(); + } + + public MarkerOptions anchor(float u, float v) { + ((Marker)annotation).anchorU = u; + ((Marker)annotation).anchorV = v; + return this; + } + + public MarkerOptions draggable(boolean draggable) { + ((Marker)annotation).draggable = draggable; + return this; + } + + public MarkerOptions flat(boolean flat) { + ((Marker)annotation).flat = flat; + return this; + } + + public float getAnchorU() { + return ((Marker)annotation).anchorU; + } + + public float getAnchorV() { + return ((Marker)annotation).anchorV; + } + + // TODO: Implement this method of Google Maps Android API +// public BitmapDescriptor getIcon () { +// +// } + + public float getInfoWindowAnchorU() { + return ((Marker)annotation).infoWindowAnchorU; + } + + public float getInfoWindowAnchorV() { + return ((Marker)annotation).infoWindowAnchorV; + } + + public Marker getMarker() { + return (Marker)annotation; + } + + public LatLng getPosition() { + return ((Marker)annotation).position; + } + + public float getRotation() { + return ((Marker)annotation).rotation; + } + + public String getSnippet() { + return ((Marker)annotation).snippet; + } + + public String getTitle() { + return ((Marker)annotation).title; + } + + public MarkerOptions infoWindowAnchor(float u, float v) { + ((Marker)annotation).infoWindowAnchorU = u; + ((Marker)annotation).infoWindowAnchorV = v; + return this; + } + + public boolean isDraggable() { + return ((Marker)annotation).draggable; + } + + public boolean isFlat() { + return ((Marker)annotation).flat; + } + + public boolean isVisible() { + return ((Marker)annotation).visible; + } + + public MarkerOptions position(LatLng position) { + ((Marker)annotation).position = position; + return this; + } + + public MarkerOptions rotation(float rotation) { + ((Marker)annotation).rotation = rotation; + return this; + } + + public MarkerOptions snippet(String snippet) { + ((Marker)annotation).snippet = snippet; + return this; + } + + public MarkerOptions sprite(String sprite) { + ((Marker)annotation).sprite = sprite; + return this; + } + + public MarkerOptions title(String title) { + ((Marker)annotation).title = title; + return this; + } + + public MarkerOptions visible(boolean visible) { + annotation.visible = visible; + return this; + } + + + // TODO: Implement this method of Google Maps Android API +// public MarkerOptions icon(BitmapDescriptor icon) { +// +// } + + // TODO: Implement this method of Google Maps Android API +// public void writeToParcel (Parcel out, int flags) + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPoint.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPoint.java new file mode 100644 index 0000000000..4ebdd5071f --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPoint.java @@ -0,0 +1,53 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.ArrayList; +import java.util.List; + +public abstract class MultiPoint extends Annotation { + + List<LatLng> points; + + public MultiPoint() { + super(); + points = new ArrayList<>(); + } + + /** + * Returns a copy of the points. + * + * @return points - as a copy + */ + public List<LatLng> getPoints() { + return new ArrayList<>(points); + } + + /** + * Sets the points of this polyline. This method will take a copy + * of the points, so further mutations to points will have no effect + * on this polyline. + * + * @param points + */ + void setPoints(List<LatLng> points) { + this.points = new ArrayList<>(points); + } + + + // TODO: Implement hashCode of Google Maps Android API +// public int hashCode() { +// +// } + + // TODO: Implement isGeodesic of Google Maps Android API +// public boolean isGeodesic() { +// +// } + + // TODO: Implement setGeodesic of Google Maps Android API +// public void setGeodesic(boolean geodesic) { +// +// } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPointOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPointOptions.java new file mode 100644 index 0000000000..581c42bfdd --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/MultiPointOptions.java @@ -0,0 +1,15 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.List; + +public abstract class MultiPointOptions extends AnnotationOptions { + + public MultiPointOptions() {} + + public List<LatLng> getPoints() { + // the getter gives us a copy, which is the safe thing to do... + return ((MultiPoint)annotation).getPoints(); + } +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polygon.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polygon.java new file mode 100644 index 0000000000..41edb2a5d7 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polygon.java @@ -0,0 +1,99 @@ +package com.mapbox.mapboxgl.annotations; + + +import android.graphics.Color; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.ArrayList; +import java.util.List; + +public class Polygon extends MultiPoint { + + int fillColor = Color.BLACK; // default fillColor is black + float strokeAlpha = 1; + int strokeColor = Color.BLACK; // default strokeColor is black + float strokeWidth = 10; // As specified by Google API Docs (in pixels) + + List<List<LatLng>> holes; + + public Polygon() { + super(); + holes = new ArrayList<>(); + } + + public int getFillColor() { + return fillColor; + } + + public List<List<LatLng>> getHoles () { + return holes; + } + + public int getStrokeColor() { + return strokeColor; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1737 + * @return stroke width as float + */ + public float getStrokeWidth() { + return strokeWidth; + } + + public void setFillAlpha(float alpha) { + this.alpha = alpha; + } + + public void setFillColor(int color) { + fillColor = color; + } + + /** + * Sets the holes of this polygon. This method will take a copy of the holes, + * so further mutations to holes parameter will have no effect on this polygon. + * + * @param holes + */ + public void setHoles(List<? extends List<LatLng>> holes) { + this.holes = new ArrayList<>(); + for (List<LatLng> hole : holes) { + this.holes.add(new ArrayList<>(hole)); + } + } + + /** + * Sets the alpha (opacity) of the stroke + * + * UNIMPLEMENTED: Needs implementation in Native. + */ + public void setStrokeAlpha(float alpha) { + strokeAlpha = alpha; + } + + public void setStrokeColor(int color) { + strokeColor = color; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1737 + * @return stroke width as float + */ + public void setStrokeWidth(float width) { + strokeWidth = width; + } + + + // TODO: Implement equals of Google Maps Android API +// public boolean equals (Object other) { +// +// } + + // TODO: Implement hashCode of Google Maps Android API +// public int hashCode () { +// +// } +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolygonOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolygonOptions.java new file mode 100644 index 0000000000..25ee750196 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolygonOptions.java @@ -0,0 +1,125 @@ +package com.mapbox.mapboxgl.annotations; + + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.ArrayList; +import java.util.List; + +public class PolygonOptions extends MultiPointOptions { + + public PolygonOptions() { + annotation = new Polygon(); + } + + public PolygonOptions add(LatLng point) { + ((MultiPoint)annotation).points.add(point); + return this; + } + + public PolygonOptions add(LatLng... points) { + for (LatLng point : points) { + add(point); + } + return this; + } + + public PolygonOptions addAll(Iterable<LatLng> points) { + for (LatLng point : points) { + add(point); + } + return this; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1729 + * + * @param points - an iterable (list) of points for cutting a hole + * @return PolygonOptions - the options object + */ + public PolygonOptions addHole (Iterable<LatLng> points) { + List<LatLng> hole = new ArrayList<>(); + for (LatLng point : points) { + hole.add(point); + } + ((Polygon)annotation).holes.add(hole); + return this; + } + + /** + * Sets the color of the polygon. + * + * @param color - the color in ARGB format + * @return PolygonOptions - the options object + */ + public PolygonOptions fillColor(int color) { + ((Polygon)annotation).fillColor = color; + return this; + } + + public int getFillColor() { + return ((Polygon)annotation).fillColor; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1729 + * + * @return a list of lists of points for cutting holes + */ + public List<List<LatLng>> getHoles() { + return ((Polygon)annotation).holes; + } + + public Polygon getPolygon() { + return ((Polygon)annotation); + } + + public int getStrokeColor() { + return ((Polygon)annotation).strokeColor; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1737 + * + * @return stroke width as float + */ + public float getStrokeWidth() { + return ((Polygon)annotation).strokeWidth; + } + + /** + * Sets the color of the stroke of the polygon. + * + * @param color - the color in ARGB format + * @return PolygonOptions - the options object + */ + public PolygonOptions strokeColor(int color) { + ((Polygon)annotation).strokeColor = color; + return this; + } + + /** + * UNIMPLEMENTED: Needs implementation in Native. + * https://github.com/mapbox/mapbox-gl-native/issues/1737 + * + * @return stroke width as float + */ + public PolygonOptions strokeWidth(float width) { + ((Polygon)annotation).strokeWidth = width; + return this; + } + + public PolygonOptions visible(boolean visible) { + annotation.visible = visible; + return this; + } + + // TODO: Implement writeToParcel of Google Maps Android API +// public void writeToParcel(Parcel out, int flags) { +// +// } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polyline.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polyline.java new file mode 100644 index 0000000000..7647238331 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Polyline.java @@ -0,0 +1,51 @@ +package com.mapbox.mapboxgl.annotations; + +import android.graphics.Color; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.List; + +public class Polyline extends MultiPoint { + + int color = Color.BLACK; // default color is black + float width = 10; // As specified by Google API Docs (in pixels) + + public Polyline() { + super(); + } + + public int getColor() { + return color; + } + + public float getWidth() { + return width; + } + + + /** + * Sets the color of the polyline. + * + * @param color - the color in ARGB format + */ + public void setColor(int color) { + this.color = color; + } + + + /** + * Sets the width of the polyline. + * + * @param width in pixels + * @return + */ + public void setWidth(float width) { + this.width = width; + } + + // TODO: Implement equals of Google Maps Android API +// public boolean equals(Object other) { +// +// } +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolylineOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolylineOptions.java new file mode 100644 index 0000000000..d825399f7d --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/PolylineOptions.java @@ -0,0 +1,75 @@ +package com.mapbox.mapboxgl.annotations; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import java.util.List; + +public class PolylineOptions extends MultiPointOptions { + + public PolylineOptions() { + annotation = new Polyline(); + } + + public PolylineOptions add(LatLng point) { + ((MultiPoint)annotation).points.add(point); + return this; + } + + public PolylineOptions add(LatLng... points) { + for (LatLng point : points) { + add(point); + } + return this; + } + + public PolylineOptions addAll(Iterable<LatLng> points) { + for (LatLng point : points) { + add(point); + } + return this; + } + + /** + * Sets the color of the polyline. + * + * @param color - the color in ARGB format + */ + public PolylineOptions color(int color) { + ((Polyline)annotation).color = color; + return this; + } + + public int getColor() { + return ((Polyline)annotation).color; + } + + public Polyline getPolyline() { + return ((Polyline)annotation); + } + + public float getWidth() { + return ((Polyline)annotation).width; + } + + public PolylineOptions visible(boolean visible) { + annotation.visible = visible; + return this; + } + + /** + * Sets the width of the polyline. + * + * @param width in pixels + * @return + */ + public PolylineOptions width(float width) { + ((Polyline)annotation).width = width; + return this; + } + + // TODO: Implement writeToParcel of Google Maps Android API +// public void writeToParcel(Parcel out, int flags) { +// +// } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java index 0f359ab100..4a8ed42a54 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java @@ -26,10 +26,16 @@ import android.view.SurfaceView; import android.view.View; import android.view.ViewConfiguration; import android.widget.ZoomButtonsController; -import android.util.Log; import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector; import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector; +import com.mapbox.mapboxgl.annotations.Annotation; +import com.mapbox.mapboxgl.annotations.Marker; +import com.mapbox.mapboxgl.annotations.MarkerOptions; +import com.mapbox.mapboxgl.annotations.Polygon; +import com.mapbox.mapboxgl.annotations.PolygonOptions; +import com.mapbox.mapboxgl.annotations.Polyline; +import com.mapbox.mapboxgl.annotations.PolylineOptions; import com.mapbox.mapboxgl.geometry.LatLng; import com.mapbox.mapboxgl.geometry.LatLngZoom; @@ -63,6 +69,11 @@ public class MapView extends SurfaceView { private static final String STATE_CLASSES = "classes"; private static final String STATE_DEFAULT_TRANSITION_DURATION = "defaultTransitionDuration"; + /** + * Every annotation that has been added to the map. + */ + private List<Annotation> annotations = new ArrayList<>(); + // // Instance members // @@ -205,6 +216,48 @@ public class MapView extends SurfaceView { } } + public Marker addMarker(MarkerOptions markerOptions) { + Marker marker = markerOptions.getMarker(); + Long id = mNativeMapView.addMarker(marker); + marker.setId(id); // the annotation needs to know its id + marker.setMapView(this); // the annotation needs to know which map view it is in + annotations.add(marker); + return marker; + } + + public Polyline addPolyline(PolylineOptions polylineOptions) { + Polyline polyline = polylineOptions.getPolyline(); + Long id = mNativeMapView.addPolyline(polyline); + polyline.setId(id); + polyline.setMapView(this); + annotations.add(polyline); + return polyline; + } + + public Polygon addPolygon(PolygonOptions polygonOptions) { + Polygon polygon = polygonOptions.getPolygon(); + Long id = mNativeMapView.addPolygon(polygon); + polygon.setId(id); + polygon.setMapView(this); + annotations.add(polygon); + return polygon; + } + + public void removeAnnotation(Annotation annotation) { + long id = annotation.getId(); + mNativeMapView.removeAnnotation(id); + } + + public void removeAnnotation(long annotationId) { + mNativeMapView.removeAnnotation(annotationId); + } + + public void removeAnnotations() { + for (Annotation annotation : annotations) { + annotation.remove(); + } + } + // // Property methods // diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java index 643fcbd720..6cab4bbd0f 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java @@ -2,8 +2,10 @@ package com.mapbox.mapboxgl.views; import android.graphics.PointF; import android.view.Surface; -import android.util.Log; +import com.mapbox.mapboxgl.annotations.Marker; +import com.mapbox.mapboxgl.annotations.Polygon; +import com.mapbox.mapboxgl.annotations.Polyline; import com.mapbox.mapboxgl.geometry.LatLng; import com.mapbox.mapboxgl.geometry.LatLngZoom; import com.mapbox.mapboxgl.geometry.ProjectedMeters; @@ -214,6 +216,24 @@ class NativeMapView { nativeSetLatLng(mNativeMapViewPtr, latLng, duration); } + public long addMarker(Marker marker) { + return nativeAddMarker(mNativeMapViewPtr, marker); + } + + public long addPolyline(Polyline polyline) { + // NH TODO Throw exception if returns -1 + return nativeAddPolyline(mNativeMapViewPtr, polyline); + } + + public long addPolygon(Polygon polygon) { + // NH TODO Throw exception if returns -1 + return nativeAddPolygon(mNativeMapViewPtr, polygon); + } + + public void removeAnnotation(long id) { + nativeRemoveAnnotation(mNativeMapViewPtr, id); + } + public LatLng getLatLng() { return nativeGetLatLng(mNativeMapViewPtr); } @@ -446,6 +466,14 @@ class NativeMapView { private native void nativeSetLatLng(long nativeMapViewPtr, LatLng latLng, long duration); + private native long nativeAddMarker(long nativeMapViewPtr, Marker marker); + + private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline); + + private native long nativeAddPolygon(long mNativeMapViewPtr, Polygon polygon); + + private native void nativeRemoveAnnotation(long nativeMapViewPtr, long id); + private native LatLng nativeGetLatLng(long nativeMapViewPtr); private native void nativeResetPosition(long nativeMapViewPtr); diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_line.geojson b/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_line.geojson new file mode 100644 index 0000000000..ef76eaf56d --- /dev/null +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_line.geojson @@ -0,0 +1 @@ +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[-121.3714599609375,38.64583568648869],[-121.48681640624999,38.64047263931154],[-121.53076171875,38.61579745317875],[-121.56509399414061,38.57823196583313],[-121.75186157226561,38.533127435052776],[-121.97021484374999,38.35350340353833],[-122.08007812499999,38.24680876017446],[-122.16796875,38.19718009396176],[-122.23800659179686,38.09457899232253],[-122.27371215820312,38.01455819225337],[-122.33551025390625,37.94094845586459],[-122.27371215820312,37.81846319511331],[-122.4151611328125,37.7652868250379]]}}]}
\ No newline at end of file diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_poly.geojson b/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_poly.geojson new file mode 100644 index 0000000000..ec61303c72 --- /dev/null +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/assets/small_poly.geojson @@ -0,0 +1 @@ +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-122.28813171386719,38.617406963286136],[-122.26959228515624,38.6833657775237],[-122.18238830566406,38.55568323796419],[-122.10617065429688,38.51378825951165],[-122.11509704589845,38.50465406475561],[-122.18307495117188,38.542795073979015],[-122.19955444335938,38.496593518947556],[-122.28813171386719,38.617406963286136]]]}}]}
\ No newline at end of file diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java index 65cb17462f..f8c35897c2 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxgl.testapp; import android.content.Context; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.PointF; import android.hardware.GeomagneticField; @@ -23,6 +24,12 @@ import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import com.mapbox.mapboxgl.annotations.Marker; +import com.mapbox.mapboxgl.annotations.MarkerOptions; +import com.mapbox.mapboxgl.annotations.Polygon; +import com.mapbox.mapboxgl.annotations.PolygonOptions; +import com.mapbox.mapboxgl.annotations.Polyline; +import com.mapbox.mapboxgl.annotations.PolylineOptions; import com.mapbox.mapboxgl.geometry.LatLng; import com.mapbox.mapboxgl.views.MapView; import com.mapzen.android.lost.api.LocationListener; @@ -30,6 +37,9 @@ import com.mapzen.android.lost.api.LocationRequest; import com.mapzen.android.lost.api.LocationServices; import com.mapzen.android.lost.api.LostApiClient; +import org.json.JSONException; + +import java.io.IOException; import java.util.ArrayList; public class MainActivity extends ActionBarActivity { @@ -77,6 +87,11 @@ public class MainActivity extends ActionBarActivity { private float mCompassBearing; private boolean mCompassValid = false; + // Used for markers + private boolean mIsMarkersOn = false; + + private Marker marker; + // // Lifecycle events // @@ -210,6 +225,10 @@ public class MainActivity extends ActionBarActivity { } return true; + case R.id.action_markers: + // Toggle markers + toggleMarkers(!mIsMarkersOn); + default: return super.onOptionsItemSelected(item); } @@ -249,6 +268,80 @@ public class MainActivity extends ActionBarActivity { } } + /** + * Enable / Disable markers. + * + * @param enableMarkers + */ + private void toggleMarkers(boolean enableMarkers) { + if (enableMarkers) { + if (!mIsMarkersOn) { + mIsMarkersOn = true; + addMarkers(); + addPolyline(); + addPolygon(); + } + } else { + if (mIsMarkersOn) { + mIsMarkersOn = false; + removeAnnotations(); + } + } + } + + private void addMarkers() { + LatLng backLot = new LatLng(38.649441, -121.369064); + MapView map = mMapFragment.getMap(); + marker = map.addMarker(new MarkerOptions() + .position(backLot) + .title("Back Lot") + .snippet("The back lot behind my house")); + + LatLng cheeseRoom = new LatLng(38.531577,-122.010646); + map.addMarker(new MarkerOptions() + .position(cheeseRoom) + .sprite("dog-park-15") + .title("Cheese Room") + .snippet("The only air conditioned room on the property!")); + } + + private void addPolyline() { + try { + String geojsonStr = Util.loadStringFromAssets(this, "small_line.geojson"); + LatLng[] latLngs = Util.parseGeoJSONCoordinates(geojsonStr); + MapView map = mMapFragment.getMap(); + Polyline line = map.addPolyline(new PolylineOptions() + .add(latLngs) + .width(2) + .color(Color.RED)); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void addPolygon() { + String geojsonStr = null; + try { + geojsonStr = Util.loadStringFromAssets(this, "small_poly.geojson"); + LatLng[] latLngs = Util.parseGeoJSONCoordinates(geojsonStr); + MapView map = mMapFragment.getMap(); + Polygon polygon = map.addPolygon(new PolygonOptions() + .add(latLngs) + .strokeColor(Color.MAGENTA) + .fillColor(Color.BLUE)); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void removeAnnotations() { + mMapFragment.getMap().removeAnnotations(); + } + // This class forwards location updates to updateLocation() private class GpsListener implements LocationListener { diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MapFragment.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MapFragment.java index b78926b9e1..d3a6d2ad1f 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MapFragment.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MapFragment.java @@ -7,6 +7,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import com.mapbox.mapboxgl.geometry.LatLng; import com.mapbox.mapboxgl.views.MapView; import java.io.BufferedReader; @@ -77,6 +78,8 @@ public class MapFragment extends Fragment { // Need to pass on to view mMap.onStart(); + mMap.setCenterCoordinate(new LatLng(38.247887,-121.843872)); + mMap.setZoomLevel(7); } // Called when the fragment is invisible diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/Util.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/Util.java new file mode 100644 index 0000000000..74b909cec5 --- /dev/null +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/Util.java @@ -0,0 +1,61 @@ +package com.mapbox.mapboxgl.testapp; + +import android.content.Context; +import android.text.TextUtils; + +import com.mapbox.mapboxgl.geometry.LatLng; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; + +public class Util { + + public static String loadStringFromAssets(final Context context, final String fileName) throws IOException { + if (TextUtils.isEmpty(fileName)) { + throw new NullPointerException("No GeoJSON File Name passed in."); + } + InputStream is = context.getAssets().open(fileName); + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + return readAll(rd); + } + + public static LatLng[] parseGeoJSONCoordinates(String geojsonStr) throws JSONException { + JSONObject jsonObject = new JSONObject(geojsonStr); + JSONArray features = jsonObject.getJSONArray("features"); + JSONObject feature = features.getJSONObject(0); + JSONObject geometry = feature.getJSONObject("geometry"); + String type = geometry.getString("type"); + JSONArray coordinates; + if (type.equals("Polygon")) { + coordinates = geometry.getJSONArray("coordinates").getJSONArray(0); + } else { + coordinates = geometry.getJSONArray("coordinates"); + } + int len = coordinates.length(); + LatLng[] latLngs = new LatLng[coordinates.length()]; + for (int i = 0; i < len; ++i) { + JSONArray coord = coordinates.getJSONArray(i); + double lng = coord.getDouble(0); + double lat = coord.getDouble(1); + latLngs[i] = new LatLng(lat, lng); + } + return latLngs; + } + + private static String readAll(Reader rd) throws IOException { + StringBuilder sb = new StringBuilder(); + int cp; + while ((cp = rd.read()) != -1) { + sb.append((char) cp); + } + return sb.toString(); + } +} diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_main.xml b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_main.xml index bf6dbbf36d..f16522d99c 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_main.xml +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_main.xml @@ -1,11 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> - <item android:id="@+id/action_gps" - android:icon="@drawable/ic_action_location_searching" - android:title="@string/action_gps" - app:showAsAction="ifRoom" /> <item android:id="@+id/action_debug" android:icon="@drawable/ic_action_about" android:title="@string/action_debug" app:showAsAction="ifRoom" /> + <item android:id="@+id/action_markers" + android:icon="@android:drawable/ic_menu_myplaces" + android:title="@string/action_point_annotations" + app:showAsAction="ifRoom" /> + <item android:id="@+id/action_gps" + android:icon="@drawable/ic_action_location_searching" + android:title="@string/action_gps" + app:showAsAction="ifRoom" /> </menu> diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index 901e231929..cddf228bf6 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -7,6 +7,8 @@ <string name="action_debug">Toggle debug mode</string> + <string name="action_point_annotations">Toggle point annotations</string> + <string name="label_fps">FPS:</string> <string name="compass_desc">Map compass. Click to reset the map rotation to North.</string> |