Maps v2 tint a Marker - android

I'm trying to get Marker tinted using Google Maps v2. Following solution is not working:
Drawable d = getResources().getDrawable(R.drawable.my_drawable);
d.setColorFilter(getResources().getColor(
R.color.tint_color), Mode.MULTIPLY);
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromBitmap(((BitmapDrawable) d).getBitmap());
myMap.addMarker(new MarkerOptions().icon(bitmap).position(latLon));
Is there alternative solution to get Markerstinted?

The problem is that you're tinting the drawable (changing its paint, really) but you're then passing the underlying Bitmap. One way to fix this outside the Maps API (with which I'm unfamiliar) is to draw the Drawable to a Canvas with a new Bitmap.
Bitmap filtered = Bitmap.createBitmap(d.getBitmap());
Canvas canvas = new Canvas(filtered);
d.draw(canvas);
(This is just an example, it's not doing any error handling - you should handle the case when Android gives you back the same Bitmap instead of a new one. It's also not handling bounds)

Related

OpenStreetMap add marker to Nutiteq MapView with custom Xfermode

I need to put some markers on top of a Nutiteq MapView. In order to create these markers I create a bitmap with a semi-transparent circle.
int size = (int)(30*mDisplayMetrics.density);
Bitmap androidMarkerBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
paint.setColor(Color.argb(150, 255, 0, 0));
Canvas canvas = new Canvas(androidMarkerBitmap);
canvas.drawCircle(size / 2, size / 2, size / 2, paint);
com.nutiteq.graphics.Bitmap markerBitmap = BitmapUtils.createBitmapFromAndroidBitmap(androidMarkerBitmap);
androidMarkerBitmap.recycle();
Each marker has the same bitmap. The problem is the transparency of the bitmap (as you can see alpha is not 0). When I add many markers all the bitmaps are simply ADDED one over the another... The problem is that I do not want the "add" effect for transparency, but instead I need to obtain the "darken" one.
(source: csdn.net)
Is there a way to change the default Xfermode used when mapView draws markers on it?
No, there is no such option in Nutiteq SDK. The effect you describe would require rendering markers to a separate surface (with 'darken' effect) and then layering the rendered surface (with markers) atop of other layers. Such functionality is pretty expensive and is not implemented in the SDK.

Android - Dynamic Custom Map Marker

I am using Google Maps V2. I am trying to create custom markers at run time with images and text that come from a server. I would like to have a balloon like marker that would stretch accordingly to the size of the image bitmap with a text on top of it.
For example:
Lets say I have a balloon image like this:
A image like this:
What I am trying to achieve would be to place this image inside the balloon with some text above the image, something like this:
If it is possible, how can I achieve this?
I have to place the final image as a icon for the marker option in google maps, something like this:
// Resource ID from the drawable folder
int balloon_id = getResources().getInteger(R.drawable.balloon_image);
// A bitmap image that came from the server (I got this done)
Bitmap image_from_server;
// Some text that came from the server (I got this done too)
String some_text;
// A method that will return the final resulted image to be placed to the marker options
// What I need is to find out the work out of this method (This is where I am struggling
BitmapDescriptor result_image = some_method(balloon_id, image_from_server, some_text);
// Marker Options for the custom marker
MarkerOptions mo = new MarkerOptions()
.position(latlng)
.icon(result_image);
// Then I can have my marker
Marker my_marker = google_map.addMarker(mo);
I have looked into StackOverflow for similar solutions to no avail. The accepted answer would contain the method that I am struggling to build or a very good direction to where I can achieve the solution on my own (but please take a look at the parameters of my method and what it returns, if I need to adjust that is not a big problem), thanks in advance!
Well, you can draw your images on canvas, overlaying each other. This function would do just that.
so you just put your images/text in the correct position and create them as bitmap, then overlay them in order.
private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}

android Maps API v2 with custom markers

I want to make maps with custom markers. In API v2 I can set icon, title, etc for markers. But I want to display title with marker at the first onset. Now title displays only when I taping the marker. In v1 was overlays, but in v2 I didn't found anything similar.
Edited:
Maybe I was not clear enough. Something like Marker.showInfoWindow() in API works only for one marker. I can't show info windows for all of my markers at the same time. Anyway I need to show titles for all of my markers, without waiting while user will tap on it.
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.
Finally did it. So what you do is have a background image (in my case i just use a blue rectangle).
Create a marker like so:
Marker myLocMarker = map.addMarker(new MarkerOptions()
.position(myLocation)
.icon(BitmapDescriptorFactory.fromBitmap(writeTextOnDrawable(R.drawable.bluebox, "your text goes here"))));
Notice the writeTextOnDrawable() Method:
private Bitmap writeTextOnDrawable(int drawableId, String text) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
.copy(Bitmap.Config.ARGB_8888, true);
Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.WHITE);
paint.setTypeface(tf);
paint.setTextAlign(Align.CENTER);
paint.setTextSize(convertToPixels(context, 11));
Rect textRect = new Rect();
paint.getTextBounds(text, 0, text.length(), textRect);
Canvas canvas = new Canvas(bm);
//If the text is bigger than the canvas , reduce the font size
if(textRect.width() >= (canvas.getWidth() - 4)) //the padding on either sides is considered as 4, so as to appropriately fit in the text
paint.setTextSize(convertToPixels(context, 7)); //Scaling needs to be used for different dpi's
//Calculate the positions
int xPos = (canvas.getWidth() / 2) - 2; //-2 is for regulating the x position offset
//"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
canvas.drawText(text, xPos, yPos, paint);
return bm;
}
public static int convertToPixels(Context context, int nDP)
{
final float conversionScale = context.getResources().getDisplayMetrics().density;
return (int) ((nDP * conversionScale) + 0.5f) ;
}
Thanks to Arun George:
Add text to image in android programmatically
Seems like your question was finally answered at a Google I/O session.
Have a look at http://googlemaps.github.io/android-maps-utils/
It has:
Marker clustering — handles the display of a large number of points
Heat maps — display a large number of points as a heat map
IconGenerator — display text on your Markers (see screenshot)
Very importantly it can be modified on any thread so handling many markers is a breeze
I am not sure which you are trying to achieve: having the info window show up without the user have to tap on the marker, or using a completely different view for the info window (or perhaps both).
To show the info window without requiring a user tap:
I haven't tested this myself, but I'm guessing Marker.showInfoWindow() would do the trick (assuming the Marker's visibility is already true.
To provide a custom view for the InfoWindow
There are two options here and you should refer to the documentation on GoogleMap.InfoWindowAdapter:
public static interface GoogleMap.InfoWindowAdapter
Provides views for
customized rendering of info-windows.
Methods on this provider are called when it is time to show an info
window for a marker, regardless of the cause (either a user gesture or
a programmatic call to showInfoWindow(). Since there is only one info
window shown at any one time, this provider may choose to reuse views,
or it may choose to create new views on each method invocation.
When constructing an info-window, methods in this class are called in
a defined order. To replace the default info-window, override
getInfoWindow(Marker) with your custom rendering. To replace just the
info-window contents, inside the default info-window frame (the
callout bubble), leave the default implementation of
getInfoWindow(Marker) in place and override getInfoContents(Marker)
instead.
Basically, whether you override getInfoWindow() or getInfoContents() will depend on whether or not you just wish to customize what you see inside the callout bubble, or whether you wish to customize the entire info window view, including an alternative to the callout bubble.
One caveat: I believe when you override these methods, it performs a simple rendering of what the view looks like at the time getInfoWindow() or getInfoContents() is called. I myself am interested in trying to replicate the look of the native Google Maps Android app which has a little "directions" icon next to the name of the place. One of the problems I believe (see here: https://stackoverflow.com/a/13713536/129475) is that if you have something like a button in your view, it may not behave like a button because of the static rendering.
Customize the marker image
You can replace the default marker image with a custom marker image, often called an icon. Custom icons are always set as a BitmapDescriptor, and defined using one of four methods in the BitmapDescriptorFactory class.
fromAsset(String assetName)
Creates a custom marker using an image in the assets directory.
fromBitmap (Bitmap image)
Creates a custom marker from a Bitmap image.
fromFile (String path)
Creates a custom icon from a file at the specified path.
fromResource (int resourceId)
Creates a custom marker using an existing resource.
The below snippet creates a marker with a custom icon.
private static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
private Marker melbourne = mMap.addMarker(new MarkerOptions()
.position(MELBOURNE)
.title("Melbourne")
.snippet("Population: 4,137,400")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
This simple code works to display the title without requiring a click event:
googleMap.addMarker(new MarkerOptions()
.position(latLng)
.title(String title))
.showInfoWindow();
Google has come out with the IconGenerator class which makes adding custom icon easy.
IconGenerator iconGenerator = new IconGenerator(mContext);
Bitmap bitmap = iconGenerator.makeIcon("Text Of Icon");
mMap.addMarker(new MarkerOptions()
.position(latlng)
.title("Location")
.icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
Why don't you keep an array of the markers then when it comes to laoding the markers, iterate through them calling showInfoWindow(). May not be the most elegant solution but it does what you are saying I think.
I solved this problem by making my own markers with a picture editor which has the details below. It took some time to make, but it works.
I used Photoshop and 53x110px markers.

Android: How to to set imageView as a marker in google map API android?

till now i was using drawable to populate marker on my map .Now i was wondering it would be cool if i could display custom imageview as a marker in map.
till now i am doing it like
itemized= new Itemazide(drawable, mContext);
i want to achieve something like
I might be a bit late but I'll post a solution for others who have faced/are facing a similar issue. So basically what you have to do (at least for the solution you are seeking, i.e a custom image imposed on a box-like background) is impose the customImage on the background box with the help of a canvas. Using this implementation you can effectively create a BitmapDrawable from the canvas that you can then assign as a marker for your 'Overlay' / 'ItemizedOverlay'.
Also, please refrain from creating an ImageView for each overlay as this will utterly destroy your memory/ your app if you have to deal with thousands of such ImageViews simultaneously. Instead, use BitmapDrawables that can be assigned to the overlays during their construction and don't consume nearly enough memory as an ImageView.
public BitmapDrawable imageOnDrawable(int drawableBackground, Bitmap customImage)
{
//The following line is optional but I'd advise you to minimize the size of
//the size of the bitmap (using a thumbnail) in order to improve draw
//performance of the overlays (especially if you are creating a lot of overlays).
Bitmap customImageThumbnail = ThumbnailUtils.extractThumbnail(
customImage, 100, 100);
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId);
bm = Bitmap.createScaledBitmap(bm, 112, 120, false);
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(bm, 0, 0, null);
// The 6,6 in the below line refer to the offset of the customImage/Thumbnail
// from the top-left corner of the background box (or whatever you want to use
// as your background)
canvas.drawBitmap(customImageThumbnail, 6, 6, null);
return new BitmapDrawable(bm);
}
Yeah I was wondering if I could do something like this, i.e. show a custom View instead of drawable. You can override draw() method, but unfortunately it always (someone please tell me I'm wrong) has to be drawable. I think it's because custom View would take too much memory.
That being said, depending on what you're trying to achieve it's probably possible to hack mapview-baloon library to achieve some similar effect.
EDIT:
Now that you've shown what you're trying to achieve I think you should override draw() in your OverlayItem and in this method inflate your ImageView. But I didn't try to do it this way, so there may be some drawbacks (I remember a SO thread on a similar matter that claimed, that it would interrupt all touch events on this OverlayItem).
In google mapv2, map-view ballon like functionality is provided by default.
Just, you have to write some lines for it :
private GoogleMap mapView;
if (mapView == null)
mapView = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map_view)).getMap();
mapView.getUiSettings().setMyLocationButtonEnabled(false);
mapView.setMyLocationEnabled(true);
MarkerOptions markerDestinationOptions;
markerDestinationOptions = new MarkerOptions()
.position(latLngDestination) .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker));
mapView.addMarker(markerDestinationOptions);

Set Opacity of Custom Tiles Over Google Maps Android

I have loaded my custom tiles to display over Google Maps. Any ideas how to set the opacity of them? I retrieve my image tiles from a URL, add this as a drawable to my itemizedOverlay, then add the itemizedOverlays to my Overlay object. There is no draw method.
I make my bitmap a BitmapDrawable and then set the alpha.
Bitmap bit = some bitmap;
BitmapDrawable bd;
bd = new BitmapDrawable(bit);
bd.setAlpha(128);

Categories

Resources