Centering bitmap Marker (Google Maps Android API v2)

AndroidCenteringGoogle Maps-Android-Api-2Android Drawable

Android Problem Overview


When I add a marker from a custom Bitmap, the marker is not centered at the point I specify.

I'm adding it like this:

    // ID tramo
	final int tramoId = tr.getId();
	// Nodos
	final Nodo[] nodos = tr.getNodos();

	final PolylineOptions p = new PolylineOptions();
	MarkerOptions m = new MarkerOptions();
	// Seteamos posicion de linea y marker
	m.position(semisuma(nodos));
	for (final Nodo n : nodos) {
		p.add(n.getLatLng());
	}
	// Color de linea y marker
	BitmapDescriptor icon = null;
	if (tr.getCapacidad() == 0) {
		p.color(0xFF000000);
		m = null;
	} else if (tr.getCapacidad() - tr.getPlazasOcupadas() == 0) {
		p.color(0xEEFF0000);
		final TextDrawable drawable = new TextDrawable(0, 0xEEFF0000,
				0xFFFFFFFF);
		icon = BitmapDescriptorFactory.fromBitmap(fromDrawable(drawable));
	} else {
		p.color(0xEE00FFFF);
		final TextDrawable drawable = new TextDrawable(0, 0xEE00FFFF,
				0xFFFFFFFF);
		icon = BitmapDescriptorFactory.fromBitmap(fromDrawable(drawable));
	}
	if (m != null) {
		m.title(String.valueOf(tramoId));
		m.icon(icon);
	}
	if (polylinesTramo.get(idTramo) != null) {
		polylinesTramo.get(idTramo).remove();
	}
	if (markersTramo.get(idTramo) != null) {
		markersTramo.get(idTramo).remove();
	}
	polylinesTramo.put(idTramo, map.getMap().addPolyline(p));
	if (marker != null) {
		markersTramo.put(idTramo, map.getMap().addMarker(m));
	}

This is the code of TextDrawable:

package com.cidaut.blueparking.ui;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;

public class TextDrawable extends Drawable {

	private final String text;
	private final Paint paint;
	private final int centroX = 13;
	private final int centroY = 16;
	private final float textSize;
	private final float whereToDrawX;
	private final int bgColor;

	public TextDrawable(final int text, final int bgColor, final int textColor) {
		this(String.valueOf(text), bgColor, textColor);
	}

	public TextDrawable(final String text, final int bgColor, final int textColor) {
		this.text = text;
		this.bgColor = bgColor;
		this.paint = new Paint();
		paint.setColor(textColor);
		paint.setTextSize(14f);
		paint.setAntiAlias(true);
		paint.setFakeBoldText(true);
		paint.setStyle(Paint.Style.FILL);
		paint.setTextAlign(Paint.Align.LEFT);
		textSize = paint.measureText(text);
		whereToDrawX = centroX - (textSize / 2);
	}

	@Override
	public void draw(final Canvas canvas) {
		canvas.drawColor(bgColor);
		canvas.drawText(text, whereToDrawX, centroY, paint);
	}

	@Override
	public void setAlpha(final int alpha) {
		paint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(final ColorFilter cf) {
		paint.setColorFilter(cf);
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSLUCENT;
	}
}

and here's the fromDrawable method

protected Bitmap fromDrawable(final Drawable drawable) {
	final Bitmap bitmap = Bitmap.createBitmap(25, 25, Config.ARGB_8888);
	final Canvas canvas = new Canvas(bitmap);
	drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
	drawable.draw(canvas);
	return bitmap;
}

What should I add to my code to get the markers centered in their positions?

Android Solutions


Solution 1 - Android

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.

Solution 2 - Android

If you use Marker you'll need to respecify the Anchor in order to center your image. As the documentation says : "Anchor : The point on the image that will be placed at the LatLng position of the marker. This defaults to 50% from the left of the image and at the bottom of the image.".

You should maybe consider using GroundOverlay instead of Marker if you want the image to be centered by default. See GroundOverlay, "The anchor is by default 50% from the top of the image and 50% from the left of the image. "

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCharlie-BlakeView Question on Stackoverflow
Solution 1 - Androidstevo.mitView Answer on Stackoverflow
Solution 2 - AndroidFr4nzView Answer on Stackoverflow