Polygon with large XML set of points - google-maps

I have a map that I built 4 years ago with API v2. I'm now trying to upgrade it to API v3, but all I get is the infamous blank gray box where the map should be. I have done console.log all over the place and all the data and variables look correct to me, but I am not a Google Maps expert.
Here is the map in it's current broken state:
https://www.idahopower.com/AboutUs/serviceMap/
The map is supposed to show 4 shaded polygons representing my company's service area divided into regions. The points that make up the polygon borders come from a large XML file (1573 lines) on my server, which is here:
https://www.idahopower.com/AboutUs/serviceMap/serviceMap.xml
I am not sure if I am doing this in the best way, but I am using XMLHttpRequest() to load the XML data.
This was all working with API v2. Any help would be appreciated!

This will not initialize the map correctly (center and zoom are required MapOptions):
// Create map object
//
var map = new google.maps.Map(document.getElementById("map"));
from the documentation
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
working example, your code with center and zoom set

There is nothing wrong with your Polygon, you didn't set the required options zoom and center for the map.
Related to the XML: 1500 vertices isn't that much, but when you want to improve the performance you may send the data as JSON(it should reduce the amount of data to the half)

Related

Change color of markers for each KML Layer?

I have many different KML layers on a Google Map (v3). Random colors of markers were assigned to each set of markers. I would like to be able to control this, however.
So far, this is what I have:
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var kmlLayerOptions = { preserveViewport: true, suppressInfoWindows: true };
var Layer1 = new google.maps.KmlLayer('http://myurl.com/1.xml', kmlLayerOptions);
Layer1.setMap(map);
var Layer2 = new google.maps.KmlLayer('http://myurl.com/2.xml', kmlLayerOptions);
Layer2.setMap(map);
I need to be able to say I want Layer 1 to use blue markers and layer 2 to use red markers, but I can't seem to figure this out.
From what I can tell, there is no way to do this with the kmlLayerOptions, which is where it would seem like it would happen, so I don't see where else I could logically make this change other than directly on the layer object.
You can't change it with KmlLayer (at least currently, you could create an Enhancement request to add the functionality).
You can do it with FusionTablesLayers (import your KML into FusionTables, then use either the User Interface to set the icons or dynamic styling in the Google Maps API v3 (assuming you need less than 5 different icons, and the ones you want are available in FusionTables).
A final option would be to edit the existing KML to use the icons you want.
The KmlLayer renders according to the styling in the KML document itself, and you cannot override this in any layer options.
If you don't want to modify the KML itself, you could use a third party library such as http://code.google.com/p/geoxml3/ to render the KML on the clientside rather than having Google's servers render it, and this would give you the ability to override the rendering defaults.

How to render multiple markers at the exact same coordinates in Google Maps API?

I have multiple addresses on the same street with the same house number, but with different apartment numbers. Google Maps Geocoding Service (v2) doesn't go down to apartment level accuracy for many addresses and just returned me the exact same geocode coordinates for them.
So the problem is that when I go to display them, only one pushpin shows up no matter how much you zoom in. And my question is; what is a good way to render multiple pushpins at the exact same house address? I've seen how craigslist.org creates a spiral out of the pushpins on their new map feature, but was wondering what my other options are as that seems like a workaround at best.
Ideas?
I solved this using Google's dynamic chart icons which allow you to put a number in the pin identifying that there are multiple markers on this exact some point. Basically, you call their "chart" url with some query params and they give you back your numbered icon which you can then place/set in the existing marker you have on that spot.
var markerImage = createMarkerImage(numDuplicates + 1);
existingMarker.setIcon(markerImage);
function createMarkerImage(text)
{
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + text + "|FF8985|000000",
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
return pinImage;
}
NOTE: This solution uses a deprecated google API with no end date posted.
"Important: The Image Charts portion of Google Chart Tools has been
officially deprecated as of April 20, 2012. It will continue to work
as per our deprecation policy."
UPDATE:
I have moved away from the above solution since it's deprecated (and has performance impact for many markers) in leiu of the same end effect of a numbered marker, but using a path of coordinates defining polygon in the shape of a marker along with a .png for the marker shadow. Only reason I used my own custom marker is because I needed to create individual markers, each with a unique color (and possibly an embedded number), which the vanilla markers don't support.

Need tips on data structure/model design regarding Google Maps Marker objects

I am working on a prototype bike parking map for my school using Google Maps API.
I have saved all the bike rack locations in MYSQL with only attributes being lattitude
and longitude of the location. Now I'm trying to add a feature where when the users click
on the markers, they would show the pictures of the corresponding bike racks.
I am trying to do this using InfoWindow object.
Now the problem is, although InfoWindow is almost exclusively used with Markers, a Marker object cannot have an InfoWindow object as one of its properties/attributes.
So I was thinking creating a fresh new InfoWindow every time users click on markers. But i feel like it's going to create some lagging.
Another option I had in mind was creating another table or a column in the current table
which contains all the InfoWindow object.
However, I really want to make the InfoWindow objects to be part of Marker objects because
intuitively it makes the most sense.
Not saying the best way to do it is this, but a marker object sure can have an infoWindow as one of it's properties! Google's API doesn't restrict/throw errors when you put random properties/methods on it's marker objects. The following is perfectly valid code:
var someMarker = new google.maps.Marker(properties);
someMarker.infoWindow = new google.maps.InfoWindow(properties);
someMarker.infoWindow.setMap(map);
someMarker.infoWindow.open();
That being said, on a lot of google maps implantations there's generally only a single infoWindow object on the map. The reason for this if you opened up 4 or 5 infoWindows in a single map view, they tend to clutter up the map and you can't see any of the base map tiles anymore.
For that reason, you can have a single infoWindow object, and just change the contents of it, depending on which marker is clicked:
var yourGlobalInfoWindow = new google.map.InfoWindow(properties);
var someMarkerA = new google.maps.Marker(properties);
var someMarkerB = new google.maps.Marker(properties);
someMarkerA.infoWindowContent = 'some A HTML content here';
someMarkerB.infoWindowContent = 'some B HTML content here';
google.maps.event.addListener(someMarkerA,'click',function() { yourGlobalInfoWindow.setContent(someMarkerA.infoWindowContent); });
google.maps.event.addListener(someMarkerB,'click',function() { yourGlobalInfoWindow.setContent(someMarkerB.infoWindowContent); });
Note that the code above is for illustrative purposes only and is far from optimized or elegant, but it gets the point across.

Marker Clustering - Fusion Table Layer - Google Maps v3

Is there a way to get marker clustering (ie makerclusterer) to work with a Fusion Table layer? It seems that you have to assign markers to markerclusterer yet when using a fusion table layer, Google is handling the markers/infowindows? Still trying to figure this fusion table thing out.
Basically looking for a way to cluster large amounts of markers being provided via a Fusion Table
Fusion Table Layers render an additional png image for each tile that gets overlaid on top of the map tile, containing the data points for that tile, this is the server side rendering part. So it's multiple data points per tile that contains data points.
Generating your own markers from data, which is necessary for MarkerClusterer, doesn't overlay an image per tile, it creates an individual Marker on the map for each data point and overlays a sprite image on to that.
Based on this, it is not possible to use MarkerClusterer and a FusionTablesLayer.
This is my own code. I was trying the technique in the earlier link but it didn't work for me. So this is how i did it.
First i queried the fusion table with the regular chart api query
function initialize() {
mapMain = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(37.4, -100.1),
zoom: 3,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
mc = new MarkerClusterer(mapMain);
var queryText = encodeURIComponent("select wikipedia_article, xy from "+tableid);
var query = new google.visualization.Query("https://www.google.com/fusiontables/gvizdata?tq="+queryText);
query.send(handleQueryResponse);
}
Next, in my handleQueryResponse, I dynamically created markers and added it to the Mapclusterer
function handleQueryResponse(response){
dataTable = response.getDataTable();
for(var i=0; i< dataTable.getNumberOfRows();i++){
var hrefval = dataTable.getValue(i,0).toString();
var arr = dataTable.getValue(i,1).toString().split(" ");
var latlng = new google.maps.LatLng(arr[0], arr[1]);
var marker = new google.maps.Marker({
position: latlng,
map:mapMain
});
fn = markerClick(i, marker);
google.maps.event.addListener(marker,'click', fn);
markers.push(marker);
}
mc.addMarkers(markers);
}
In this case, the main map, the array of markers (mc in the code below) are global variables. You can see the full working example here.
I don't think you will get it work with a fusion table. IMO the fusion table is lacking the support for a spatial index. A si helps reduce the 2d complexity to a 1d complexity. It's uses in a lot of applications like heatmaps, treemaps, post code search, maps application. You want to look for Nick's hilbert curve spatial index quadtree blog.
Fusion Tables allows you to view thousands of points at once by using server side rendering (from the google servers). Marker Clusterer solves the problem by building a set of clusters from nearest points (from the clients browser). I wouldn't necessarily use them both at the same time, but it might work for your use case it's up to you.
You can read more information about how they work here:
http://code.google.com/apis/maps/articles/toomanymarkers.html
If you really wanted too you could use the Fusion Tables API to feed the data from Fusion Tables to the Marker Clusterer.
Hope this helps.

Marking streets in Google Maps

I want to create an overlay on top of Google Maps that displays different streets in different colors.
In the Google Maps API it is possible to create markers and polygons that cover certain areas.
Is there a way to somehow mark different streets?
It sounds to me like you are interested in showing some application specific coloring for your Google maps display (rather than traffic maps).
If so , then you should check out custom overlays. You can create your own transparent background overlay tiles (with your colored streets), match them up with the Google maps tiles and then overlay them on the map. You can find a description of this stuff in the Maps API reference - Overlays.
I have actually been interested in trying this out, and this question might be a good excuse. I'll let you know how I go.
Edit: Ok, I tried this and it was pretty straightforward. You just need to grab the tiles images when the google maps page load (for the area you would like to overlay). Make sure you keep track of the origional urls, because these have the x,y coordinates that you will need to write your tile overlay method.
Edit the tiles with your colored roads then upload them to your web server. Add the following code to use your overlay on the regular map:
var myCopyright = new GCopyrightCollection("© ");
myCopyright.addCopyright(new GCopyright('Demo',
new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)),
0,'©2007 Google'));
// Create the tile layer overlay and
// implement the three abstract methods
var tilelayer = new GTileLayer(myCopyright);
// properties of the tile I based my tile on
// v=w2.97&hl=en&x=38598&s=&y=49259&z=17&s=Galil.png
tilelayer.getTileUrl = function(point, zoom) {
if (zoom == 17 && point.x == 38598 && point.y == 49259)
return "../pics/times_square.png";
};
tilelayer.isPng = function() { return true;};
tilelayer.getOpacity = function() { return 1.0; }
var myTileLayer = new GTileLayerOverlay(tilelayer);
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(40.75740, -73.98590), 17);
map.addOverlay(myTileLayer)
This code overlays my Thing eats NY tile:
at x = 38598 and y = 49259 at zoom level 17.
It is possible to create markers and polygons in the Google Maps API. You need to create GPolygon and/or GPolyline objects
Have a look to these tutorials
And if you want to obtain the coordinate (latitude, longitude) of certain streets, you may have a look to the source code of this page
I am not sure to fully understand your question: do you want to mark some given streets ?
in that case, a quick-and-dirty way could be to get the coordinates of all the addresses of the street and build a GPolygon according to them...
Have you concidered using OpenStreeMaps?
Try digging into the code used to show the traffic overlay on the normal Google Maps site.
Edit: I just looked at the code, and it appears that even Google decided it was easier to implement this by just generating the traffic lines on the server and pulling them down as transparent PNG overlays.
I just found this link, and I think this could interest you. It is a JavaScript package that provides functionality for displaying multiple routes on Google Maps.
Is it what you were looking for ??