Subclass google.maps.Marker: How to call parent methods?

913 views
Skip to first unread message

Canam Group

unread,
Nov 24, 2010, 8:58:14 AM11/24/10
to google-map...@googlegroups.com
Hi,

I'm trying to convert the very useful LabeledMarker class to Google Maps API V3:
http://gmaps-utility-library-dev.googlecode.com/svn/tags/labeledmarker/

I used it in my V2 map... but I want something similar in my V3 map.
I read Mike's article about extending GMarker:
http://www.googlemapsbook.com/2007/01/22/extending-gmarker/

I'm trying to do the same with google.maps.Marker, but I'm running into some problems.

Here's my very simple code:

function LabeledMarker(opts) { // constructor
    google.maps.Marker.apply(this, arguments); // call parent constructor (google.maps.Marker)*/
}

LabeledMarker.prototype = new google.maps.Marker();

LabeledMarker.prototype.onAdd = function() {
    alert('onAdd1');
    google.maps.Marker.prototype.onAdd.apply(this, arguments);   
    alert('onAdd2');
}

LabeledMarker.prototype.draw = function() {
    alert('draw1');
    google.maps.Marker.prototype.draw.apply(this, arguments);
    alert('draw2');
}

LabeledMarker.prototype.onRemove = function() {
    alert('onRemove1');
    google.maps.Marker.prototype.onRemove.apply(this, arguments);
    alert('onRemove2');
}

Here's how I call it:
var point = new google.maps.LatLng(37, -59);       
var labeledMarker = new LabeledMarker({
     map: map,
     position: point,
     labelText: 'Label'
});

Here's a URL:
http://www.canamgroup.ws/GM.nsf/Map2?OpenPage

My Marker is displayed on the map (so I assume that my constructor is successfully calling the google.maps.Marker constructor) but my alerts in onAdd, draw and onRemove are never triggered (so I assume that my methods are not successfully calling the google.maps.Marker methods).

This is the way Mike was doing it though in V2 (except the method names were different).
I tried:
google.maps.Marker.prototype.draw.apply(this, arguments);
google.maps.Marker.prototype.draw.apply(this);
google.maps.Marker.prototype.draw.call(this);
google.maps.Marker.prototype.draw.call(this, arguments);

I'm just beginning to code OO Javascript, so I might be missing something?
Or maybe I have to do something different in V3?
Can someone help?

Thanks!

Canam Group

unread,
Nov 24, 2010, 10:38:00 AM11/24/10
to google-map...@googlegroups.com
My question should be more "How to override the onAdd(), draw() and onRemove() methods of google.maps.Maker?".

I did a test with the "setTitle" method and my alert is displayed (and the parent method called):
LabeledMarker.prototype.setTitle = function(title) {
    alert('setTitle');
    google.maps.Marker.prototype.setTitle.apply(this, arguments);
}

Does that mean that google.maps.Marker doesn't have onAdd(), draw() and onRemove() methods?
A Marker is an Overlay, so I thought I could override those methods as well.

Am I trying to do something impossible?
Thanks!

Esa

unread,
Nov 24, 2010, 12:25:18 PM11/24/10
to Google Maps JavaScript API v3


On Nov 24, 5:38 pm, Canam Group <canamgr...@gmail.com> wrote:
> My question should be more "How to override the onAdd(), draw() and
> onRemove() methods of google.maps.Maker?".

Those are methods of OverlayView not of Marker, Polygon, Circle or any
native overlays.
http://koti.mbnet.fi/ojalesa/v3/v3_methods_nightly.htm#Marker


> Does that mean that google.maps.Marker doesn't have onAdd(), draw() and
> onRemove() methods?

Right.


> Am I trying to do something impossible?

Not at all but you should go for OverlayView instead. You can use
google.maps.Marker as a building block of your special OverlayView
marker.

There are several OverlayView examples out there. This is one of them
http://koti.mbnet.fi/ojalesa/boundsbox/tiptool_trains.htm

Canam Group

unread,
Nov 24, 2010, 1:38:46 PM11/24/10
to google-map...@googlegroups.com
Hi Esa,

I did create one custom Overlay in the past (subclass of OverlayView) to display a tooltip over a marker, and the link your provided was one of the examples which I based my code upon.  In fact, I did try to use a custom Overlay again to display a label on the marker... see my example here:
http://www.canamgroup.ws/GM.nsf/Map3?OpenPage

However, now, when I want to open the InfoWindow (or my tooltip), I must click either above or below the custom Overlay (label) otherwise it won't show up.

I thought that by subclassing Marker (instead of OverlayView) and just displaying a div (label) on the marker (and set its position in the draw() method) it would be easier and more logical. How come google.maps.Marker doesn't have a onAdd(), draw(), onRemove()?

Could you elaborate a bit more about "You can use google.maps.Marker as a building block of your special OverlayView marker"?
Maybe I'm missing something obvious.

Thanks for your help!

Esa

unread,
Nov 24, 2010, 2:58:14 PM11/24/10
to Google Maps JavaScript API v3
I think that example would work perfect if you try to append the label
on a lower pane. Now the label is appended on floatPane (pane 6) that
is above overlayMouseTarget (pane 5) that gathers clicks and
mouseovers.

Try floatShadow (pane 4) or overlayImage (pane 3).
http://code.google.com/apis/maps/documentation/javascript/reference.html#MapPanes

"You can use google.maps.Marker as a building block of your special
OverlayView marker"?

You can create a Marker in your CustomOverlayView() constructor just
as you create Marker and Label in your createMarker() function.

Canam Group

unread,
Nov 24, 2010, 3:10:00 PM11/24/10
to google-map...@googlegroups.com
floatShadow did it!
overlayImage displays the label behind the image, so I can't see it.

I have only one more issue then.

In my example above, I added three markers.
The InfoWindow now display correctly when I click anywhere on the marker (thanks to you)... but all labels are stack on top of each other when markers are close by (they are impossible to read).

Do you have an idea on how to prevent this?

Thanks again!

Esa

unread,
Nov 24, 2010, 4:00:20 PM11/24/10
to Google Maps JavaScript API v3
I think that overlayImage pane might fix that issue. So the labels and
markers would lay on the same pane (div). Currently all the markers
are behind all the labels.

Your createMarker() first appends a marker and then the label on it.
Second time createMarker is called a new marker would be layed over
those and then a new label over all of those etc. A new marker would
cover previous labels if they would share a common parent div (pane).

Canam Group

unread,
Nov 24, 2010, 4:11:07 PM11/24/10
to google-map...@googlegroups.com
... but when I use overlayImage, all the labels are behind the markers (I updated my example).

That's my only issue left... and I don't know what to do to solve this.

Thanks, I appreciate your help!


Esa

unread,
Nov 24, 2010, 4:19:01 PM11/24/10
to Google Maps JavaScript API v3
Sorry, I forgot z-index.

API sets the the z-index of the marker depending on latitude. You
cannot read that z-index value by getZindex (for some reason). It
returns 'undefined' unless you set the value yourself by setZindex().

My idea above assumes that marker and its label have equal z-index.
You should set them equal but depending on latitude so that markers
overlap the right way. I don't know the formula that API v3 is using
for z-index / latitude relationship. I am sure someone knows it.

Canam Group

unread,
Nov 24, 2010, 4:47:44 PM11/24/10
to google-map...@googlegroups.com
You're right about getZIndex(), it returns 'undefined' unless I specified something manually.

Using overlayImage...

...I tried to manually set a zIndex of 1 to the markers and a zIndex of 1 to the labels and it doesn't change a thing, labels are still hidden behind markers (and obviously markers are not overlapped correctly based on their latitude)

...I tried to manually set a zIndex of 1 to the markers and a zIndex of 2 to the labels and now labels are in front of markers, but the labels are still overlapping all markers, exactly like when I was using floatShadow (and markers are not overlapped correctly based on their latitude as well).

So far, zIndex doesn't seem to help me...

Thanks again!

geoco...@gmail.com

unread,
Nov 24, 2010, 6:23:05 PM11/24/10
to Google Maps JavaScript API v3
I don't think API v3 sets the z-index by default (or at least I don't
think it used to, it is hard to keep up with all the "updates"). I
have been using this formula so the markers act like they did in API
v2 (I don't remember where I got it from, probably from an old post
of Mike Williams' on the v2 group):

zIndex: Math.round(latlng.lat()*-100000)<<5

-- Larry

Esa

unread,
Nov 24, 2010, 6:32:27 PM11/24/10
to Google Maps JavaScript API v3
> So far, zIndex doesn't seem to help me...

Yes. This is tricky. The markers are created after labels in DOM
though they are created before labels in the code.

So you should set individual increasing z-index for each element like
- first marker: 0
- its label: 1
- second marker: 2
- its label: 3
- etc...

Marker icon is a div element and the image is a background image. The
div is empty (no innerHTML). The label could simply be put as
innerHTML to the div. The problem is how to access that div.

When you create a marker, its div will be lastChild of overlayImage
pane ,so it should be simple to access. However you have to wait that
the div appears in DOM.

Canam Group

unread,
Nov 25, 2010, 9:28:32 AM11/25/10
to google-map...@googlegroups.com
I think I got it working!

I use Larry's formula to set the zIndex of my markers... and in my custom overlay (label), I do this (based on Esa's suggestion):
this._div.style.zIndex = this._zIndex+1;

where this._div is my Overlay <div> (label) and this._zIndex is the zIndex of the current marker.

Now everything seems to behave the way I want :)

Thanks a lot to both of you for your help!

Frank Lippes

unread,
Jan 17, 2011, 1:48:52 PM1/17/11
to google-map...@googlegroups.com
Hi Camam

Are you willing to share the code? 

--FDL
Reply all
Reply to author
Forward
0 new messages