Overlapping markers/labels in Google Map API v3 - javascript

I have a google map with several markers/labels placed very very close to eachother.
So close, that if the zoom-level is at a certain level all the labels are overlapping.
In order to be able to read all the labels when the map loads and when the zoom-level changes, I want to place the marker with a certain offset of the actually point with a line drawn to it.
I have tried to implement the "OverlappingMarkerSpiderfier" by George MacKerron, but according to the author himself, it can't be done using his code (due to the fact that his code is tied to an "onClick" listener and can't be executed during loading of the map or change of zoom-level)
I hope the above description is understandable dispite the fact that english is not my native language.

Related

Google map showing only states of USA and shows only cities of corresponding state when clicked along with zoom [duplicate]

I am using Google Maps in a project and I want to display only a country map in my map window i.e. I want only the US to show on my map not Canda and Mexico and so on, cutting away the superflous information for the app I am building.
I found some stuff where you can restrict the area covered with some javascript however this still gives me a lot of extra map area as geographic areas usually do not conform to squares.
Further on I am limited by time, $, php and javascript so I can't really do some fancy custom solution that involves lots of work i.e. the usual setting.
Check out one of Mike Williams' great GMaps tutorials: in there, he shows how to limit zoom and pan in your map.
If you want some areas to be non-visible, try this one: I think that's closest to what you want (the example actually does the same thing you want, but it seems to be geared towards Canadians ;)).

Google Maps markers ontop of each other

So I have a probably not so unique scenario. The simplest way to explain it is a google map with all 50 US states, each state will have two markers. The markers are both driven by the same lat/long value. The problem Im having is that the markers are rendering ontop of one another. I somehow need to have them render next to one another or offset so that I can see both. The problem is how do I get it to not overlap into another state.
I saw some really neat "spider" functionality where it renders one marker and then if you click on it the others fan out, but the website was in another language.
I am going to try and use the following library.
https://github.com/jawj/OverlappingMarkerSpiderfier
The problem with the above implementation is that I am using a combination of KML and google maps client-side. I dont see a way to implement that for the kml markers
The Overlapping Marker Spiderfier project on GitHub will probably accomplish what you need.
Otherwise you can play around with the Marker's icon property. The icon can accept a Symbol which has and anchor that can be shifted from the default location (0,0).
Symbol documentation: https://developers.google.com/maps/documentation/javascript/reference#Symbol

Google Maps - Changing the pane order of tile overlays?

A continuation of my previous question: How to change the layering of KML and Tile Overlays in Google Maps?
I am currently rewriting some of the code regarding the buttons which enable and disable tile overlays using arrays. In doing so, I'm trying to combine all of the button's individual functions into a single function, but since I have two methods of rendering the overlays, I was hoping to try and simply focus on only one method. The first uses "overlayMapTypes":
map.overlayMapTypes.insertAt(0, beloitMapType);
The second, using a script provided in my previous question:
this.getPanes().overlayShadow.appendChild(this.settings.div_);
The former method is my original approach; however, since I use polygons on the Satellite view I needed a way to place icon/name overlays above the colored polygons. To achieve this, I sought something akin to the latter method where certain overlays could be placed onto a pane higher than the polygons and thus appear above them.
However, in the time between my previous question and now, as well as through some of my own research, I've come to realize that the latter method, rather than placing the tiles into their places, estimates the location of the tile and places it as an image overlay. As a result, a part of my accessibility layer which colors in inaccessible paths had been misaligned by a pixel or two, or my building name overlay currently has names on the border of two tiles which have a sharp line through them as those two tiles overlap slightly. In addition, these two issues come and go each time the map is loaded with each tile being placed on the map with a variance of 1-2 pixels in any direction.
Thus, I would very much prefer to use the former method with overlayMapTypes, which is more reliable and accurate, on all of the overlays, but I also need a way to bring some of these overlays higher than the "overlayLayer" pane and above the polygons. Is this possible and, if so, how could it be done?
Addition: I have an additional need to try and find a method to achieve the reassignment of panes with the overlayMapType method: the script I'm using to achieve this doesn't appear to work in IE7/8. I'm going to investigate this angle myself, but I'd still prefer to drop the script entirely if possible.
Well, I've hit upon a possible solution and, for the sake of sharing it, allow me to explain:
Polygons do not necessarily need to be visible to still have click and hover events.
Since the polygons are used to color the buildings and poi in Satellite view, such a visual component could easily be done by an overlay.
Thus, a possible solution is to have all polygons invisible and simply use them for click and hover events. Likewise, a second overlay, or a modification of an existing one, would replace the polygon's original visual component. Since this visual component is now an overlay like everything else, it can be easily layered with any other overlay using the "MapType" method.
(This however doesn't answer the question; namely, can tile overlays and polygons be layered only with the MapType method? I would still like to know that, but in the event that there is no answer, this hopefully is a possible alternative.)

Google Maps Points do not appear until low zoom levels

I'm working on a (Perl) program that uses the Google Maps API and a KML file to pull data from a database that creates points on the map. I have that much done, but the points only appear after I zoom pretty much all the way in, to a zoom level where only one point is showing.
The default zoom only shows my small city (3-5 miles) so I thought all the points would be able to show. Does anybody know how to get all of the points to show up at city-wide level as opposed to only showing up when zoomed all the way in?
Any help is greatly appreciated. Thanks!
Edit: Added a JavaScript tag because I've seen a lot of work done with Google Maps using JS, and considering the problem really isn't language-specific, I figured some of those developers might be able to offer some insight.
Try to incorporate the <Lod> tag in your KML, which is child of a <Region>. You can define this once per placemark you get from your DB. or only once per query (defined by minLat, maxLat, minLong, maxLong). In the first case the LodPixels is a constant whereas in the latter case you must calculate it as a function of the region size. It sure works in Google Earth and may work as well in Maps. Look here to see it work in Earth API (JS)
....
<Region>
<LatLonAltBox>
<north>###</north>
<south>###</south>
<east>###</east>
<west>###</west>
<minAltitude>###</minAltitude>
<maxAltitude>###</maxAltitude>
</LatLonAltBox>
<Lod>
<minLodPixels>###</minLodPixels>
<maxLodPixels>###</maxLodPixels>
<minFadeExtent>###</minFadeExtent>
<maxFadeExtent>###</maxFadeExtent>
</Lod>
</Region>
....

Hybrid static/dynamic Google Map

Ever noticed that when you go to maps.google.com and do a search (say, car wash), it renders a lot of results (represented by small circles) and a few prominent ones (seen as regular-size pins)?
Notice how quickly it does this?
From what I can tell from analyzing this in Firebug, much of this is generated on the server and sent to the client as a static image.
However, it's still dynamic. You can still zoom in and out, or click on a result and see a dynamic InfoWindow rendered.
Google have made the map quick and smooth using static images, while still making it flexible.
Is there a way to do this kind of 'pre-loading' with my own Google Map (implemented with the Google Maps API)?
The technology that maps.google.com uses is similar to that used in a GLayer. The server dynamically builds tiles and "hotspot" info. The GLayer tiles are also constructed dynamically (and possibly cached) even though the underlying data is fairly static. From the client side, the searched dots technology is identical to the Wikipedia or Panoramio GLayer. The only new trick is that the dot information is generated dynamically on Google's big fast servers.
The API does not (yet) provide any tools for creating custom GLayers. If you want to do the same sort of thing yourself, using your own database of locations, there are three steps that you need to code:
Create your own custom tileserver
which searches your database for
items in the tile area and uses a
graphics library like gd or
imagemagic to place dots on the
tile. Use those tiles to create a
GTileLayerOverlay on the client.
When the user clicks on the map,
send the location of that click to a
second server. That server should
check your database and return the
infowindow text for the dot at that
location, if any. Returning all the infowindow contents from all the dots imaged by the tileserver would be unacceptably slow, so you have to fetch them one by one, as needed.
Changing the cursor when the mouse
is over a dot is more tricky. What Google
do is return a list of hotspot
coordinates for all the dots on each
tile. Whenever the mouse moves, the
API determines which tile the
pointer is over and uses a quadtree
algorithm to see if the pointer is
over a hotspot, and change the
cursor if necessary. If you only
have a modest number of hotspots per
tile, then a linear search would
probably be acceptably fast. If you might have thousands of dots per tile, then you'll probably need to write your own quadtree algorithm. The Google quadtree code is not exposed, so you can't use it.
Here's a page where somebody has done all that. In this case the hotspots are calculated as circles, by comparing the distance from the centre point, even though the dots are square. On maps.google.com the hotspots are calculated as rectangles, by using GBounds.containsPoint(), even though the dots are round.
I'm doing something similar - but instead using a tile layer, I just send server-clustered markers to the browser whenever the view changes. If your data is static, you can pre-cluster your markers and it would be incredibly fast with tens of thousands of markers.
Our site can't use pre-clustering because the markers can be searched and filtered, but it's still pretty fast up to about 20,000 markers. Still working on it...

Categories