Android Maps API V2 with Custom Markers

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.

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.

Multiple markers with text on Android Google Maps API v2

to do that you'll have to customize the icon of each individual marker to be what you need.
Here's the link: https://developers.google.com/maps/documentation/android/marker#customize_a_marker

Then you can put some PNG resources (a blue, a yellow and a red), and at runtime get correct Bitmap, write the text on the bitmap by code, and then set as the custom-marker with the fromBitmap (Bitmap image) method.

Creating a custom marker menu in google maps api V2

You can customize the pop up with an Adapter, just call the setInfoWindowAdapter method and override the following methods, like this:

mGoogleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker arg0) {
return null;
}

@Override
public View getInfoContents(Marker marker) {
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.item_marker_location, null);
TextView tvTitle = (TextView) rowView.findViewById(R.id.tvMarkerTitle);
TextView tvSnippet = (TextView) rowView.findViewById(R.id.tvMarkerSnippet);
tvTitle.setText(marker.getTitle());
tvSnippet.setText(marker.getSnippet());
return rowView;
}
});

You can read the documentation of the InfoWindowAdapter interface.

Google maps api v2 customize location marker

I've found a solution.
Neseccery to disable build-in position listener and implement it over standart location manager.

Disabling build-in location manager:

mMap = mapView.getMap();
mMap.setMyLocationEnabled(false);

Implementing standart android location manager:

    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy( Criteria.ACCURACY_COARSE );
String provider = lm.getBestProvider( criteria, true );
lm.requestLocationUpdates(provider, 0, 0, this);

Inside onLocationChanged metod draw your position on map

@Override
public void onLocationChanged(Location location) {
// draw custom marker
MarkerOptions mp = new MarkerOptions();
mp.position(new LatLng(location.getLatitude(), location.getLongitude()));
mp.icon(myLocationBitmap);
mMap.addMarker(mp);

}

Custom Markers on Google Map, API V2 android

In Previous map implementation we created mapOverlay class(Data class), that was used to hold the details, but i dont know how to create in API V2.

You cannot do the same thing in Maps V2, as Marker is final and cannot be extended.

My best recommendation is for you to not use snippet() for the actual text snippet, but instead use it to hold the key to a HashMap or similar data structure. You can override the drawing of the info window so it does not display the snippet. I have an example of that here: https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2/Models

Adding multiple markers in Google Maps API v2 Android

ArrayList<MarkerData> markersArray = new ArrayList<MarkerData>();

for(int i = 0 ; i < markersArray.size() ; i++) {

createMarker(markersArray.get(i).getLatitude(), markersArray.get(i).getLongitude(), markersArray.get(i).getTitle(), markersArray.get(i).getSnippet(), markersArray.get(i).getIconResID());
}

protected Marker createMarker(double latitude, double longitude, String title, String snippet, int iconResID) {

return googleMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title(title)
.snippet(snippet)
.icon(BitmapDescriptorFactory.fromResource(iconResID)));
}

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


Related Topics



Leave a reply



Submit