Hack 59. Show Lots of StuffQuickly

Lots of Google Maps overlays means lots of time spent waiting for them to draw on the mapunless you're smart.

When dealing with nontrivial numbers of overlays to draw on a Google Mapas in more than a hundred or so markers or vertices in a polylinethe drawing time required for a GMap object becomes really noticable. The inclination is to want to show markers as quickly as possible, so that the user gets immediate feedback on what's going on, but it's been discovered that if you buffer the objects and then manually trigger the redraw, it is much faster.

6.10.1. The Code

We can accomplish this buffering by adding a custom method of our own to the Google Maps API, which we'll call addOverlays( ). By assigning it to the GMap class prototype, it becomes available on any GMap objects we create. The code looks like this:

// This is a bit of a trick for the 1.0 API. The 'addoverlay' method // is agonizingly slow, so we buffer up the markers in the 'overlays' // array and then deliver them to GMAP in one shot. GMap.prototype.addOverlays=function(a) { var b=this; for (i=0;i

The addOverlays() method can be used directly in your code or included via a script element in your HTML, after you include the Google Maps library.

Using this technique is really easyinstead of calling map.addOverlay( ) for each marker or polyline we create, we'll push each overlay onto an array, and then pass the array to map.addOverlays( ). Here's a fragment of a simple GPX reader that displays waypoint data using this idea:

var wpts = GPX.documentElement.getElementsByTagName("wpt"); var markers = []; for (var k = 0; k < wpts.length; k++) { var point = new GPoint(trkPts[k].getAttribute("lon"), trkPts[k].getAttribute("lat"))); var marker = new Gmarker(point); // … we could do things with the marker here, // like set a custom icon or configure an info window … markers.push( marker ); } // Now let gmap have the waypoints all in one chunk. map.addOverlays(points);

 

In a similar fashion, if you have multiple contiguous lines to draw, it's smarter to compress them all into a single polyline, rather than ask the GMap object to render each one separately:

// Coalesce each GPX trk/trkseg/trkpts section into a single object. // Each trkseg is a different object so that the lines don't get all // glommed together. var tracks = GPX.documentElement.getElementsByTagName("trk"); var trkpts = [], polylines = []; for (var i = 0; i < tracks.length; i++) { var trkSeg = tracks[i].getElementsByTagName("trkseg"); for (var j = 0; j < trkSeg.length; j++) { var trkPts = trkSeg[j].getElementsByTagName("trkpt"); for (var k = 0; k < trkPts.length; k++) { trkpts.push(new GPoint(trkPts[k].getAttribute("lon"), trkPts[k].getAttribute("lat"))); } polylines.push(new GPolyline(trkpts, trkcolor, 5)); trkpts = []; } } map.addOverlays(polylines);

 

In testing one GPX file with 1,700 trackpoints, using this technique reduced the time required to display from 48 seconds to 6 seconds.

Be careful not to get carried away with this idea, as lines will be drawn between every point in a single GPolyline. If your intent is to preserve breaks in the drawn line, be sure to preserve them as multiple GPolyline objects.

 

Additional optimizations are possible. For example, are all those track-points really necessary? Tools such as GPSBabel's arc filter can simplify the polyline, while retaining its basic shape. Different GPolyline objects with different amounts of detail could be chosen based on the current zoom level. As a rule, the less data Google Maps is obliged to work with, the faster it will perform.

6.10.2. See Also

Robert Lipe

Категории