[ios] [android] Add default marker sprites

This commit is contained in:
Nicki Dlugash
2015-09-28 18:10:49 -04:00
committed by Leith Bade
parent eb59bccfc1
commit 21b42eea44
14 changed files with 87 additions and 53 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -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);

View 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

View File

@@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB