[ios] [android] Add default marker sprites
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1010 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
@@ -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<Marker> 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);
|
||||
|
||||
10
platform/default/resources/default_marker.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="20px" height="56px" viewBox="0 0 20 56" enable-background="new 0 0 20 56" xml:space="preserve">
|
||||
<ellipse opacity="0.2" fill="#262626" cx="10" cy="27" rx="9" ry="5"/>
|
||||
<path id="path5359" fill="#D84E4E" stroke="#7F1919" stroke-width="1.0229" stroke-linecap="round" stroke-linejoin="round" d="
|
||||
M19.5,10.4c0,6.3-9.5,17.1-9.5,17.1S0.5,16.6,0.5,10.4c0-5.5,4.3-9.9,9.5-9.9S19.5,4.9,19.5,10.4z"/>
|
||||
<circle id="path5990" fill="#FFFFFF" stroke="#7C2525" stroke-linecap="round" stroke-linejoin="round" cx="10" cy="10" r="3.8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 902 B |
@@ -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 <MGLAnnotation> 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<char *>(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<mbgl::SpriteImage>(
|
||||
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<char *>(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<mbgl::SpriteImage>(
|
||||
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 <MGLAnnotation>)annotation
|
||||
{
|
||||
if ( ! annotation) return;
|
||||
|
||||
BIN
platform/ios/resources/default_marker.png
Normal file
|
After Width: | Height: | Size: 1010 B |
BIN
platform/ios/resources/default_marker@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
platform/ios/resources/default_marker@3x.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |