I really like how Trulia.com has created their custom Google Map InfoWindows.
What I like in particular about Trulia's implementation of the InfoWindow is:
Extends beyond the map border: Google Maps InfoWindows are contained within the map border whereas Trulia's seems to be able to float on-top of the map
Always displays InfoWindow near map Center: Google Maps InfoWindows always display the InfoWindow above the marker whereas Trulia InfoWindows always display the InfoWindow as close the center of the map as possible. For example, if the map marker icon is on the top of the map near the border, the Trulia InfoWindow is displayed below the map marker icon
InfoWindow is displayed on mouse hover (not 'click'): With the default Google Maps InfoWindow, you have to 'click' the map marker icon to display the InfoWindow whereas Trulia InfoWindows are display simply by hovering over the map marker icon.
I found the PdMarker, which is a 3rd party extension for Google Map InfoWindows that accomplishes most of the above bullets but not all. 1) It does not extend beyond the map border, 2) it does not work with Google Maps API version 3 (only version 2).
Anyone know how Trulia is accomplishing their InfoWindow-like implementation on Google Maps API v3?
That's an interesting question. I've been playing with maps recently too. I'm far from expert but I can tell you what I know.
I think the site you mentioned uses a custom div overlay rather than google's info window.
1. InfoWindow is displayed on mouse hover (not 'click')
This can be done with event listeners. For example in maps API v3:
google.maps.event.addListener(marker, 'mouseover', function() {
// myDiv.style.visibility = 'visible'
});
google.maps.event.addListener(marker, 'mouseout', function() {
// myDiv.style.visibility = 'hidden'
});
Here's is a pretty good example of how this can be done.
2. Extends beyond the map border
3. Always displays InfoWindow near map Center
Both of these can be achieved using CSS: (2) using z-index and (3) with position.
There is a similar example of using custom marker tooltips which you can find here. It also shows how you can utilize mouseovers to pop-up tooltips by hovering other elements on your page.
myElement.onmouseover = function(){
google.maps.event.trigger(marker, 'mouseover');
}
myElement.onmouseout = function(){
google.maps.event.trigger(marker, 'mouseout');
}
Finally, another site that makes a good use of maps, although this one uses V2 of the API. Hope this helps.
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/examples.html
is an extension to google maps which allows you to create custom infowindows
Related
I have a map that has markers programmatically placed on it based on values in my database. When you click on a marker, it will go to a detail page for that location.
My problem is that when the map is sufficiently zoomed out, markers that are close enough to each other appear as a single marker, in effect hiding some of the markers. Is there a way to tell programmatically whether a marker is part of a group of markers or is hidden/covered up by other markers?
My intention is to do something like this for each dynamically generated marker:
marker.addListener('click', function() {
// if marker is not hiding any other markers
window.location.href = markerURL;
// else if it is hiding markers/is part of a group of markers
map.setZoom(15);
map.setCenter(marker.getPosition());
});
I have checked the Marker API documentation, but can't seem to find any useful methods. getClickable and getVisible always return true in my case, regardless of whether a marker is covered by another marker. Any suggestions? Thank you!
I ended up going with MarkerClusterer to solve my problem. I was hoping for a simpler solution, but this turned out to be pretty simple after all.
The only thing I needed to add to my existing marker-generating code was a list: var markers = [];, and then I called markers.push(marker); on all of my markers. The final step was to create a new MarkerClusterer object:
var markerCluster = new MarkerClusterer(map, markers, options);
And MarkerClusterer handles the rest more or less (the options parameter is optional, but I used it to set the path to my images and set the maximum zoom level). Now, in the situations where previously my markers were stacked on top of each other, making it impossible to see or click certain markers at certain zoom levels, I instead see a cluster with a number indicating the number of markers in that cluster. Clicking the cluster icon will further zoom in, revealing my markers.
All of this was done following the simple usage example on their github page, but they have pretty good documentation too. Most of my time getting this to work right was actually spent styling the cluster icons to match my site's color scheme...
I'm not using the Markers in Google Maps because I wish to render custom text and images on my marker, so what I did is a custom marker using Overlays.
The Overlay position is not exactly like the marker so I played a bit with it and now it is rendering exactly like a marker.
The problem now is the infowindow because it doesn't open on top of the overlay but exactly on the position of the overlay, I wish it to be on top of it, around 32px less on the top position.
Looking at the documentation it looks like the infowindow position is related to the object and on the LatLng, so how can I move it?
Here is the code I'm using:
var marker;
marker = new CustomMarker(markerPosition, map, {}); // custom marker is a class I wrote to prototype the overlay.
google.maps.event.addListener(marker, 'click', function() {
myInfowindow.open(map, marker);
});
Quite simple but unfortunately the infowindow is over the marker and not on top of it like if I use a marker.
Set the pixelOffset of the InfoWindow appropriately:
From the documentation on InfoWindows
pixelOffset | Type:Size | The offset, in pixels, of the tip of the info window from the point on the map at whose geographical coordinates the info window is anchored. If an InfoWindow is opened with an anchor, the pixelOffset will be calculated from the anchor's anchorPoint property.
I'm trying to put a google.maps.Marker object over (z-index positioning) an Infobubble object
but i am having no success.
Basically what i'm doing is assigning zIndex: n to the markerOptions object which I pass to the Marker constructor as follow:
var markerOptions = {
position: store.getLocation(),
title: store.getDetails().title,
icon: DEFAULT_MARKER,
anchorPoint: new google.maps.Point(20,5),
zIndex: 2
};
var marker = new google.maps.Marker(markerOptions);
I have already read this answer Google Maps v3 marker over infowindow but actually it has not got any votes. Can somebody tell me more about?
Thanks a lot
The problem, as commented by shaunhusain is the fixed pane where particular elements will be drawn.
It's correct that you need to use a custom overlay, but you must use it to draw the marker, not the infobubble.
The reason: infobubble is an implementation of a custom overlay, it will be drawn inside the floatPane. To put the marker on top the infobubble must be drawn into a pane with a zIndex equal or lower than the zIndex of the pane where the marker will be drawn.
But here comes the problem: all these panes do not receive mouse-events, you wouldn't be able to interact with the infobubble(select tabs, select text, click links, close the infobubble).
Therefore you must use a custom overlay to draw the markers, and you must put these overlays into the floatPane(it's the pane with the highest zIndex)
I'm trying to make sure that my maps center point is with in the boundaries of a kml layer, I've not been able to find much about this but I modified some code from here which seems like it could work, but of course doesn't.
From the Google Maps API I can't tell whether or not .contains() is meant to work with kml layers, or if there is a similar method. Any ideas?
// bounds of the desired area
var kmlLayer = new google.maps.KmlLayer(kmlLayerURL, {map:map, suppressInfoWindows: true, preserveViewport:true});
google.maps.event.addListener(map, 'center_changed', function() {
if (kmlLayer.contains(map.getCenter())) {
alert("withnin kml layer bounds");
}
});
The KmlLayer has a method getDefaultViewport which will give you the default viewport for the overlay (the bounds the map will be centered on to display all the contents.
getDefaultViewport() LatLngBounds Get the default viewport for the layer being displayed.
The returned LatLngBounds has a contains method.
You can't access any of the internal content of the KmlLayer.
I have a Google V3 map which uses steetView and some map markers.
The little yellow streetView pegman sits on the map on top of the markers.
Is there a way to change the z-indexes so that my markers will be above the pegman
(so that they can be easlly clicked on without having to zoom in)?
In case anything is not clear, here is a fiddle....
http://jsfiddle.net/spiderplant0/BRkCA/
After a bit of experimenting I came up with this...
$("#map_canvas img[src*=cb_scout]").parent("div").css({'zIndex': -200});
$($("#map_canvas img[src*=cb_scout]")[1]).parent("div").parent("div").css({'zIndex': -200});
This forces the pegman to sit beneath the markers but now the pegman is no longer dragable and each time the map is moved etc, the pegman jumps above the markers again.
To keep the pegman under your markers you can watch for the pov_changed event and reset the z-index after a short delay
$google.maps.event.addListener(panorama, 'pov_changed', function() {
var func=function(){
$("#map_canvas img[src*=cb_scout]").parent("div").css({'zIndex': -200});
}
setTimeout(func,1000);
}
});
You will also need to change the depth of the pegman after the maps moves, which can be accomplished with the following snippet
google.maps.event.addListener(map, 'idle', function() {
google.maps.event.trigger(panorama, 'pov_changed');
})
If you want to be able to drag the pegman, you must first place it above the markers by having a toggle button swap the pegman's depth and add an exception to the pov_changed event handler preventing the pagman from dropping depths when the toggle button is active.
Okay, this may be a bit hacky... (and I hope I understood what you were doing)
1) Disable street view control
2) Make another control with a lower zIndex than the marker you have.
3) Update street view control with the position of the fake street view marker.
http://jsfiddle.net/z7Lp8/
You can set the zIndex of the marker above google.maps.Marker.MAX_ZINDEX in order for the pegman to remain under the marker. MAX_ZINDEX is the maximum default z-index that the API will assign to a marker. Marker z-indexes only work when optimizations are turned off on all markers on the map.
Forked fiddle from question to illustrate: http://jsfiddle.net/brendaz/t4v8nhoq/
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(54.975, -2.020),
map: map,
zIndex: google.maps.Marker.MAX_ZINDEX + 1,
optimized: false
});