diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java index 78043c403..59d3bc90c 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java @@ -1,10 +1,12 @@ package com.mapbox.mapboxsdk.annotations; import android.graphics.Point; +import android.support.annotation.Nullable; import android.view.View; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.views.InfoWindow; +import com.mapbox.mapboxsdk.views.MapView; public class Marker extends Annotation { @@ -17,7 +19,7 @@ public class Marker extends Annotation { LatLng position; float rotation; String snippet; - String sprite = "default_marker"; + String sprite; String title; private InfoWindow infoWindow = null; @@ -133,9 +135,11 @@ public class Marker extends Annotation { * * https://github.com/mapbox/mapbox-gl-styles/blob/mb-pages/sprites/mapbox-streets.json * - * @param sprite + * If null you will get the default marker. + * + * @param sprite The name of the sprite. */ - public void setSprite(String sprite) { + public void setSprite(@Nullable String sprite) { this.sprite = sprite; } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java index 8e8b196d1..46451eda9 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java @@ -1,5 +1,7 @@ package com.mapbox.mapboxsdk.annotations; +import android.support.annotation.Nullable; + import com.mapbox.mapboxsdk.geometry.LatLng; public class MarkerOptions extends AnnotationOptions { @@ -98,7 +100,7 @@ public class MarkerOptions extends AnnotationOptions { return this; } - public MarkerOptions sprite(String sprite) { + public MarkerOptions sprite(@Nullable String sprite) { ((Marker)annotation).sprite = sprite; return this; } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java index ad7204a3d..c31380400 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java @@ -16,6 +16,7 @@ import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.SurfaceTexture; +import android.graphics.drawable.BitmapDrawable; import android.location.Location; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -142,6 +143,9 @@ public final class MapView extends FrameLayout implements LocationListener, Comp // Index into R.arrays.attribution_links private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2; + // Used for loading default marker sprite + private static final String DEFAULT_SPRITE = "com.mapbox.sprites.default"; + // // Instance members // @@ -154,6 +158,7 @@ public final class MapView extends FrameLayout implements LocationListener, Comp // Used to handle DPI scaling private float mScreenDensity = 1.0f; + private float mScreenDensityDpi = 1.0f; // Touch gesture detectors private GestureDetectorCompat mGestureDetector; @@ -482,8 +487,7 @@ public final class MapView extends FrameLayout implements LocationListener, Comp // Get the screen's density mScreenDensity = context.getResources().getDisplayMetrics().density; - int tenDp = (int) (10 * mScreenDensity); - int sixteenDp = (int) (16 * mScreenDensity); + mScreenDensityDpi = context.getResources().getDisplayMetrics().densityDpi; // Get the cache path String cachePath = context.getCacheDir().getAbsolutePath(); @@ -1322,18 +1326,31 @@ public final class MapView extends FrameLayout implements LocationListener, Comp // Annotations // - public void setSprite(String symbol, float scale, Bitmap bitmap) { + public void setSprite(String symbol, Bitmap bitmap) { if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) { bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false); } ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight()); bitmap.copyPixelsToBuffer(buffer); + //float scale = mScreenDensityDpi / bitmap.getDensity() * mScreenDensity; + float scale = 1.0f; + mNativeMapView.setSprite(symbol, bitmap.getWidth(), bitmap.getHeight(), scale, buffer.array()); } public Marker addMarker(MarkerOptions markerOptions) { Marker marker = markerOptions.getMarker(); + + // Load the default marker sprite + if (marker.getSprite() == null) { + BitmapDrawable bitmapDrawable = (BitmapDrawable) ContextCompat.getDrawable(mContext, R.drawable.default_marker); + Bitmap bitmap = bitmapDrawable.getBitmap(); + setSprite(DEFAULT_SPRITE, bitmap); + + marker.setSprite(DEFAULT_SPRITE); + } + 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 diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png new file mode 100644 index 000000000..8b0af4c6a Binary files /dev/null and b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png differ diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png new file mode 100644 index 000000000..b112096c1 Binary files /dev/null and b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png differ diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png new file mode 100644 index 000000000..d05c82bfe Binary files /dev/null and b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png differ diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png new file mode 100644 index 000000000..703b172c1 Binary files /dev/null and b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png differ diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png new file mode 100644 index 000000000..8331ffef7 Binary files /dev/null and b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png differ diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java index 7d44bbe76..499c942af 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java @@ -129,7 +129,7 @@ public class MainActivity extends AppCompatActivity { .title("Dropped Pin") .snippet(new DecimalFormat("#.#####").format(position.getLatitude()) + ", " + new DecimalFormat("#.#####").format(position.getLongitude())) - .sprite("default_marker")); + .sprite(null)); } }); @@ -417,7 +417,7 @@ public class MainActivity extends AppCompatActivity { private void addMarkers() { List markerList = new ArrayList<>(); - final Marker backLot = generateMarker("Back Lot", "The back lot behind my house", "default_marker", 38.649441, -121.369064); + final Marker backLot = generateMarker("Back Lot", "The back lot behind my house", null, 38.649441, -121.369064); markerList.add(backLot); final Marker cheeseRoom = generateMarker("Cheese Room", "The only air conditioned room on the property", "dog-park-15", 38.531577, -122.010646); diff --git a/platform/default/resources/default_marker.svg b/platform/default/resources/default_marker.svg new file mode 100644 index 000000000..3cb5af09a --- /dev/null +++ b/platform/default/resources/default_marker.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index b4bb1ba8f..3906dd84b 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -55,6 +55,7 @@ const CLLocationDegrees MGLAngularFieldOfView = M_PI / 6.; NSString *const MGLAnnotationIDKey = @"MGLAnnotationIDKey"; NSString *const MGLAnnotationSymbolKey = @"MGLAnnotationSymbolKey"; +NSString *const MGLAnnotationSpritePrefix = @"com.mapbox.sprites."; static NSURL *MGLURLForBundledStyleNamed(NSString *styleName) { @@ -2087,8 +2088,6 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) BOOL delegateImplementsFillColorForPolygon = [self.delegate respondsToSelector:@selector(mapView:fillColorForPolygonAnnotation:)]; BOOL delegateImplementsLineWidthForPolyline = [self.delegate respondsToSelector:@selector(mapView:lineWidthForPolylineAnnotation:)]; - const std::string spritePrefix = "com.mapbox.sprites."; - for (id annotation in annotations) { NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"annotation should conform to MGLAnnotation"); @@ -2169,51 +2168,24 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) } else { - MGLAnnotationImage *annotationImage = nil; - NSString *symbolName = nil; - - if (delegateImplementsImageForPoint) + MGLAnnotationImage *annotationImage = delegateImplementsImageForPoint ? [self.delegate mapView:self imageForAnnotation:annotation] : nil; + if ( ! annotationImage) { - annotationImage = [self.delegate mapView:self imageForAnnotation:annotation]; - - if (annotationImage) - { - const std::string cSymbolName = spritePrefix + std::string(annotationImage.reuseIdentifier.UTF8String); - symbolName = [NSString stringWithUTF8String:cSymbolName.c_str()]; - - if ( ! [self.annotationImages objectForKey:annotationImage.reuseIdentifier]) - { - // store image & symbol name - [self.annotationImages setObject:annotationImage forKey:annotationImage.reuseIdentifier]; - - // retrieve pixels - CGImageRef image = annotationImage.image.CGImage; - size_t width = CGImageGetWidth(image); - size_t height = CGImageGetHeight(image); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - std::string pixels(width * height * 4, '\0'); - size_t bytesPerPixel = 4; - size_t bytesPerRow = bytesPerPixel * width; - size_t bitsPerComponent = 8; - char *pixelData = const_cast(pixels.data()); - CGContextRef context = CGBitmapContextCreate(pixelData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); - CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); - CGContextRelease(context); - CGColorSpaceRelease(colorSpace); - - // add sprite - auto cSpriteImage = std::make_shared( - uint16_t(annotationImage.image.size.width), - uint16_t(annotationImage.image.size.height), - float(annotationImage.image.scale), - std::move(pixels)); - - // sprite upload - _mbglMap->setSprite(cSymbolName, cSpriteImage); - } - } + UIImage *defaultAnnotationImage = [MGLMapView resourceImageNamed:MGLDefaultStyleMarkerSymbolName]; + annotationImage = [MGLAnnotationImage annotationImageWithImage:defaultAnnotationImage + reuseIdentifier:MGLDefaultStyleMarkerSymbolName]; } + if ( ! [self.annotationImages objectForKey:annotationImage.reuseIdentifier]) + { + // store image & symbol name + [self.annotationImages setObject:annotationImage forKey:annotationImage.reuseIdentifier]; + + [self installAnnotationImage:annotationImage]; + } + + NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier]; + points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName ? [symbolName UTF8String] : ""); } } @@ -2243,6 +2215,35 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) } } +- (void)installAnnotationImage:(MGLAnnotationImage *)annotationImage +{ + // retrieve pixels + CGImageRef image = annotationImage.image.CGImage; + size_t width = CGImageGetWidth(image); + size_t height = CGImageGetHeight(image); + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + std::string pixels(width * height * 4, '\0'); + size_t bytesPerPixel = 4; + size_t bytesPerRow = bytesPerPixel * width; + size_t bitsPerComponent = 8; + char *pixelData = const_cast(pixels.data()); + CGContextRef context = CGBitmapContextCreate(pixelData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); + CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); + CGContextRelease(context); + CGColorSpaceRelease(colorSpace); + + // add sprite + auto cSpriteImage = std::make_shared( + uint16_t(annotationImage.image.size.width), + uint16_t(annotationImage.image.size.height), + float(annotationImage.image.scale), + std::move(pixels)); + + // sprite upload + NSString *symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier]; + _mbglMap->setSprite(symbolName.UTF8String, cSpriteImage); +} + - (void)removeAnnotation:(id )annotation { if ( ! annotation) return; diff --git a/platform/ios/resources/default_marker.png b/platform/ios/resources/default_marker.png new file mode 100644 index 000000000..b112096c1 Binary files /dev/null and b/platform/ios/resources/default_marker.png differ diff --git a/platform/ios/resources/default_marker@2x.png b/platform/ios/resources/default_marker@2x.png new file mode 100644 index 000000000..d05c82bfe Binary files /dev/null and b/platform/ios/resources/default_marker@2x.png differ diff --git a/platform/ios/resources/default_marker@3x.png b/platform/ios/resources/default_marker@3x.png new file mode 100644 index 000000000..703b172c1 Binary files /dev/null and b/platform/ios/resources/default_marker@3x.png differ