Marker.setIcon()

12,461 views
Skip to first unread message

dexter

unread,
Jun 16, 2010, 6:51:43 AM6/16/10
to Google Maps JavaScript API v3
Hi All,

I am having problem with Marker.setIcon(MarkerImage), and it is as
follows:

I want to be able to change a marker's icon when needed, i.e., on zoom
out, scale it down.

I created a script to simplify the prototyping process (excluding the
zoom_changed handler).

I initially set marker's icon via constructor. Then later, I change
icon via setIcon(MarkerImage). The marker will then have the new image
but it's cropped. Here's the script i used to test the behavior.

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Complex Icons</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?
sensor=false"></script>
<script type="text/javascript">
function initialize() {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(-33.9, 151.2),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new
google.maps.Map(document.getElementById("map_canvas"),
myOptions);

setMarkers(map, beaches);
}

/**
* Data for the markers consisting of a name, a LatLng and a zIndex
for
* the order in which these markers should display on top of each
* other.
*/
var beaches = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];

var markers = [];

function setMarkers(map, locations) {
// Add markers to the map

// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.

// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var image = new google.maps.MarkerImage("http://google-maps-
icons.googlecode.com/files/home.png",
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(32, 37),
// The origin for this image is 0,0.
new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole
at 0,32.
new google.maps.Point(16, 37),
// set scaledSize:
new google.maps.Size(32, 37));


// Shapes define the clickable region of the icon.
// The type defines an HTML &lt;area&gt; element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
// shadow: shadow,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
markers[i] = marker;
}
}

function setMarkerImage() {
// http://code.google.com/apis/maps/documentation/javascript/reference.html#MarkerImage:
// "To scale the image, whether sprited or not, set the value
of scaledSize to the size of the whole image and set size,
// origin and anchor in scaled values. The MarkerImage cannot
be changed once constructed."
//
var newImage = new google.maps.MarkerImage(
// url:
"http://google-maps-icons.googlecode.com/files/home.png",
// size:
new google.maps.Size(16, 16),
// origin:
new google.maps.Point(0, 0),
// anchor:
new google.maps.Point(8, 16),
// set scaledSize:
new google.maps.Size(32, 37));

for (var i = 0; i < markers.length; i++) {
markers[i].setIcon(null);
markers[i].setIcon(newImage);
}

}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
<input type="button" value="Set Marker Image"
onclick="setMarkerImage()">
</body>
</html>

Nathan Raley

unread,
Jun 16, 2010, 9:46:56 AM6/16/10
to google-map...@googlegroups.com
I may be mistaken but once you create a marker and define its size I don't think you cannot resize the marker, you would have to create a new one entirely.  You are changing the image but the marker size remains the same and thus it just scales the image you are changing to the size of the marker.

Something you might look into is marker manager.  You can specify different markers to be shown at different zoom levels and you can load up arrays of markers into a single marker manager so its easy to remove and add markers to the map like you are wanting to do.

       // The type defines an HTML <area> element 'poly' which

--
You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
To post to this group, send email to google-map...@googlegroups.com.
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.


dexter

unread,
Jun 16, 2010, 10:17:39 PM6/16/10
to Google Maps JavaScript API v3
Yes, sort of a marker manager is what I'm trying to make, but above
the scripting layer. The script was just a means of testing the marker
behavior when it's icon is replaced with a MarkerImage of a different
scaled size.

The effect I have observed is the image/icon got cropped.

Does anybody know or experienced this behavior, and would you kindly
show the correct way of scaling a Marker object's MarkerImage?

Thanks,


Dexter
> >http://code.google.com/apis/maps/documentation/javascript/reference.h...
> > :
> > google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2B­unsub...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/google-maps-js-api-v3?hl=en.- Hide quoted text -
>
> - Show quoted text -

dexter

unread,
Jun 16, 2010, 11:28:45 PM6/16/10
to Google Maps JavaScript API v3
Here's a repro of the behavior contrasting the effect of
a) Merely replacing an existing Marker's icon with a new scaled
MarkerImage
b) Creating a new Marker and using the new scaled MarkerImage

for a), the image got cropped.
for b), the image got scaled correctly

But using this work-around is a very resource-intensive activity,
i.e., replacing every Marker with a new Marker that uses the scaled
MarkerImage.

code.maps.google team, I implore, please enlighten me, and in advance,
thanks a lot!!!

For those who want to see the behavior, copy/paste the script in
notepad
and name it <anyName>.htm. Open in IE or any browser. Click the button
on the bottom. == Just a modified sample script, but highlighting the
problem

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Complex Icons</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?
sensor=false"></script>
<script type="text/javascript">

var _markers = [];
var _map;

function initialize() {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(-33.9, 151.2),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
_map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);

setMarkers(_map, beaches);
}

/**
* Data for the markers consisting of a name, a LatLng and a zIndex
for
* the order in which these markers should display on top of each
* other.
*/
var beaches = [
['Bondi Beach', -33.890542, 151.274856, 4],
['Coogee Beach', -33.923036, 151.259052, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
// Add markers to the map

// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.

// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var image = new google.maps.MarkerImage("http://google-maps-
icons.googlecode.com/files/home.png",
// This marker is 32 pixels wide by 37 pixels tall.
new google.maps.Size(32, 37),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at
0,32.
new google.maps.Point(16, 37),
new google.maps.Size(32, 37));
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
// shadow: shadow,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
_markers[i] = marker;
}
}

function setIcons() {
var myLatLng;
var marker;

for (var i = 0; i < _markers.length; i++) {
// we create a new MarkerImage that will only replace the
existing Markers' icon:
var newImage = new google.maps.MarkerImage("http://google-maps-
icons.googlecode.com/files/home.png",
// This marker is 32 pixels wide by 37 pixels tall.
new google.maps.Size(16, 18),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole
at 0,32.
new google.maps.Point(8, 18),
new google.maps.Size(16, 18));
// replace the existing Markers' icon:
_markers[i].setIcon(newImage);
_markers[i].setTitle("Image got cropped");
// we test the behavior by creating a new Marker using the new
// MarkerImage, and see that the image got scaled correctly
for
// new Markers that use the newly-created scaled MarkerImage:
// create new markers using the new MarkerImage:
myLatLng = new
google.maps.LatLng(_markers[i].getPosition().lat(),
_markers[i].getPosition().lng() + 0.05);
marker = new google.maps.Marker({
position: myLatLng,
map: _map,
icon: newImage,
title: "New Marker using the newly-created scaled
MarkerImage"
});

}

}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width:100%; height:90%"></div>
<button onclick = "setIcons()">Test setIcon()</button>
</body>
</html>
> > >http://groups.google.com/group/google-maps-js-api-v3?hl=en.-Hide quoted text -
>
> > - Show quoted text -- Hide quoted text -

Nathan Raley

unread,
Jun 17, 2010, 9:11:29 AM6/17/10
to google-map...@googlegroups.com
I know in v2 of the API once you create a Marker the Marker Size is set in stone unless you completely destroy it and recreate it.  This is why the image is getting cropped to the previous Marker Image size.

What you need to do is create copies of your original marker with different MarkerImages for the different image sizes you want at your various zoom levels.  Make sure you define the new marker size that fits the new image size as well when you are setting the marker options.

Now push these into an array, I like to keep a separate array for each marker type I use.  Then add them to the MarkerManager and set the Min and Max zoom options to which markers you want to be visible at which zoom levels, thus accomplishing your original goal.

To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.

Nathan Raley

unread,
Jun 17, 2010, 9:20:51 AM6/17/10
to google-map...@googlegroups.com
Yea, looking through your code that appears to be what is happening, and I doubt the functionality for resizing markers has changed between the api v2 and v3, although I may be mistaken.  The simplest solution is to create additional markers with the same position of the original and just setting different image options for the copies of the markers.  Add these markers to  the marker manager with the zoom levels you want them to be displayed at and you should be good to go.

Rossko

unread,
Jun 17, 2010, 9:25:30 AM6/17/10
to Google Maps JavaScript API v3
Or make all your images the same size, but some can have transparent
'margins' to look smaller.
You'd need to take account of the icon anchors to keep it looking
right.

dexter

unread,
Jun 17, 2010, 10:50:59 AM6/17/10
to Google Maps JavaScript API v3
Hi All,

Many thanks for all your replies.

Coming home from work, I got on a whim that maybe the map needs to
refresh to be able to show the new MarkerImage correctly.

Using the same script in my previous post, after I clicked the test
button, I panned the map so that it won't show the images. Then I
panned it back and PRESTO!!! the MarkerImages showed correctly.

Still, I consider this as something on the v3 API that needs working
on.

Thanks,


Dexter

Rossko

unread,
Jun 17, 2010, 11:10:21 AM6/17/10
to Google Maps JavaScript API v3
> Still, I consider this as something on the v3 API that needs working
> on.

Then you shold lodge an enhancement request

dexter

unread,
Jun 17, 2010, 11:34:29 AM6/17/10
to Google Maps JavaScript API v3
Yes. I just found that I can submit an issue. It is issue #2500.

I hope it will be acknowledged by the team.

Thank you all!
Reply all
Reply to author
Forward
0 new messages