How to Create a Custom-Shaped Bitmap Marker With Android Map API V2

How to create a custom-shaped bitmap marker with Android map API v2

In the Google Maps API v2 Demo there is a MarkerDemoActivity class in which you can see how a custom Image is set to a GoogleMap.

// Uses a custom icon.
mSydney = mMap.addMarker(new MarkerOptions()
.position(SYDNEY)
.title("Sydney")
.snippet("Population: 4,627,300")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

As this just replaces the marker with an image you might want to use a Canvas to draw more complex and fancier stuff:

Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(80, 80, conf);
Canvas canvas1 = new Canvas(bmp);

// paint defines the text color, stroke width and size
Paint color = new Paint();
color.setTextSize(35);
color.setColor(Color.BLACK);

// modify canvas
canvas1.drawBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.user_picture_image), 0,0, color);
canvas1.drawText("User Name!", 30, 40, color);

// add marker to Map
mMap.addMarker(new MarkerOptions()
.position(USER_POSITION)
.icon(BitmapDescriptorFactory.fromBitmap(bmp))
// Specifies the anchor to be at a particular point in the marker image.
.anchor(0.5f, 1));

This draws the Canvas canvas1 onto the GoogleMap mMap. The code should (mostly) speak for itself, there are many tutorials out there how to draw a Canvas. You can start by looking at the Canvas and Drawables from the Android Developer page.

Now you also want to download a picture from an URL.

URL url = new URL(user_image_url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);

You must download the image from an background thread (you could use AsyncTask or Volley or RxJava for that).

After that you can replace the BitmapFactory.decodeResource(getResources(), R.drawable.user_picture_image) with your downloaded image bmImg.

Custom marker in google maps in android with vector asset icon

I was looking for exact same requirement, and seeing this question made me happy at first, but same as @Shuddh I wasn't happy with the given answers.

To make my story short, I am using following code for this requirement:

private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes  int vectorDrawableResourceId) {
Drawable background = ContextCompat.getDrawable(context, R.drawable.ic_map_pin_filled_blue_48dp);
background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId);
vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20);
Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
background.draw(canvas);
vectorDrawable.draw(canvas);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}

and a usage example:

.icon(bitmapDescriptorFromVector(this, R.drawable.ic_car_white_24dp));

Note: you may wish to use different bounding for your vectors, my vectors were 24dp in size and I've used a 48dp png image(blue-part, which can be a vector too) as background.

UPDATE: Adding screenshot as it was requested.

Screenshot for end result

android Maps API v2 with custom markers

I have also stumbled upon this problem. V2 API is a step forward, two steps back. Google, please add an overridable 'draw' method on the Marker or GoogleMap classes so we can customize the drawing ourselves.

A possible solution is to generate the bitmap on the fly and attach it to the marker. i.e. Create a canvas, insert the marker bitmap, draw the text next to the marker. This involves some painful calculations (the appropriate canvas size with the marker bitmap and the text next to each other). Unfortunately, there's no setIcon method in Marker, so every time the text changes, a new marker has to be created. It may be fine if you just have a marker on the map, but with dozens of markers, this may not be feasible. Also there may be memory issue on creating those bitmaps dynamically. A sample code (with just the text):

Bitmap.Config conf = Bitmap.Config.ARGB_8888; 
Bitmap bmp = Bitmap.createBitmap(200, 50, conf);
Canvas canvas = new Canvas(bmp);

canvas.drawText("TEXT", 0, 50, paint); // paint defines the text color, stroke width, size
mMap.addMarker(new MarkerOptions()
.position(clickedPosition)
//.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker2))
.icon(BitmapDescriptorFactory.fromBitmap(bmp))
.anchor(0.5f, 1)
);

Hopefully, Google will add the appropriate methods so we can do this easily. Damn, I really like the new Map rotate feature in V2 API.

Add Custom Marker to Google Maps in Android

public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

setLatLng(1.0,1.0);
}

Try this. You have to call setLatLng method in onMapReady

public void setLatLng(double latitude , double longitude){
LatLng location = new LatLng(latitude, longitude);
mMap.addMarker(new MarkerOptions().position(location).title("Marker in Your Location"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location,15));
}

Google maps custom marker android

using bitmapscale

Bitmap markerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_marker,options);
markerBitmap = SubUtils.scaleBitmap(markerBitmap, 70, 70);

then set it to your Markeroptions

MarkerOptions marker = new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(markerBitmap));
Marker mark = googleMap.addMarker(marker);

EDIT

here is scaleBitmap method

public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) {
Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);

float scaleX = newWidth / (float) bitmap.getWidth();
float scaleY = newHeight / (float) bitmap.getHeight();
float pivotX = 0;
float pivotY = 0;

Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);

Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));

return scaledBitmap;
}

Centering bitmap Marker (Google Maps Android API v2)

Simply set anchor point for you marker to 0.5 and 0.5 (middle of your icon).

...
MarkerOptions m = new MarkerOptions();
m.anchor(0.5f, 0.5f);
...

The default anchor value is (0.5f, 1.0f).
You can read about marker here.

create custom marker icons on runtime using android xml

I got the answer for my above problem
I created a bitmap from view and then placed it on marker. my xml is below

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/img_id"
android:layout_width="@dimen/custom_profile_image"
android:layout_height="@dimen/custom_profile_image"
android:contentDescription="@string/content"
android:scaleType="centerCrop" />
</RelativeLayout>

inflating above xml

    View viewMarker = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.custom_marker_layout, null);
ImageView myImage = (ImageView) viewMarker.findViewById(R.id.img_id);

set Imagebitmap on imageview which you download from url on runtime

    myImage.setImageBitmap(Imagebitmap);

now pass view object to the method and return the bitmap out of it. like this

    Bitmap bmp=createDrawableFromView(context,viewMarker);

googleMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude)).title(title)
.snippet(snippet)
.icon(BitmapDescriptorFactory.fromBitmap(bmp)));

now you can use returned bitmap anywhere, thats you'll be able to make custom marker icons using xmls.

    public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay()
.getMetrics(displayMetrics);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels,
displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}

Its working for me. Thanks!!!

Adding custom property to marker (Google Map Android API V2)

You cannot directly extend Marker, because it is a final class, but you have some options:

0) As of Google Maps Android API v2 version 9.4.0, you can use Marker::getTag and Marker::setTag. This is most likely the preferred option.

1) Create a map to store all additional information:

private Map<Marker, MyData> allMarkersMap = new HashMap<Marker, MyData>();

When creating a marker, add it to this map with your data:

Marker marker = map.addMarker(...);
allMarkersMap.put(marker, myDataObj);

Later in your render function:

MyData myDataObj = allMarkersMap.get(marker);
if (myDataObj.customProp) { ...

2) Another way would be to use Marker.snippet to store all the info as a String and later parse it, but that's kinda ugly and unmaintainable solution.

3) Switch from plain Google Maps Android API v2 to Android Maps Extensions.

This is very similar to point 1, but you can directly store MyData into marker, using

marker.setData(myDataObj);

and later:

MyData myDataObj = (MyData) marker.getData();

Custom coloured drawable as map marker in Google Maps API v2 - Android

I fount the answer here: https://groups.google.com/forum/#!topic/android-developers/KLaDMMxSkLs The ColorFilter you apply to a Drawable isn't applied directly to the Bitmap, it's applied to the Paint used to render the Bitmap. So the modified working code would look like this:

String color = db.getCategoryColor(e.getCategoryId());
Bitmap ob = BitmapFactory.decodeResource(this.getResources(),R.drawable.event_location);
Bitmap obm = Bitmap.createBitmap(ob.getWidth(), ob.getHeight(), ob.getConfig());
Canvas canvas = new Canvas(obm);
Paint paint = new Paint();
paint.setColorFilter(new PorterDuffColorFilter(Color.parseColor(Model.parseColor(color)),PorterDuff.Mode.SRC_ATOP));
canvas.drawBitmap(ob, 0f, 0f, paint);

...and now we can add obm as the coloured map marker:

map.addMarker(new MarkerOptions().position(eventLocation)
.title(e.getName()).snippet(e.getLocation())
.icon(BitmapDescriptorFactory.fromBitmap(obm)));


Related Topics



Leave a reply



Submit