Printing Markers, Polylines, and Polygons
Adding elements on an embedded map is done in a similar way using the coordinates that are contained in the KML file; see Listing Three.
We've taken it a step further to register listeners every time an element is printed and also have added every element in an array. This way we are able to reference these element in the future, while our application is executed; for example, to remove them from the map using the map.removeOverlay() function, you would use map.removeOverlay(permarkers[4]). The API has several facilities for customizing the way the different kinds of elements appear on the map. The markers can have custom size, icon, and shadows, and we can assign specific color, width, and transparency for polylines and polygons.
For a small number of locations, it is fairly easy to copy the coordinates by hand and insert them in JavaScript code. But as the number of locations increase, it is harder to manipulate these 16-digit numbers and it becomes necessary to use programming to extract them for the KML file. In our project, the number of locations was big! There were several polylines that were described using more than 60 different points that accounted for 100+ different 16-digit numbers. To overcome this, we had to develop XSL filters for the KML file that contained recipes for producing JavaScript code; see Listing Four.
// Adding a Marker point = new GLatLng(GLat, GLng); var marker = new GMarker(point, icon); GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(PopupMessage); }); gmarkers.push(marker); marker.type = myBox; map.addOverlay(marker); map.getInfoWindow().hide(); marker.openInfoWindowHtml(PopupMessage); // Adding a Polyline var polyline = new GPolyline( [new GLatLng(37.97790952936251,23.78223936561216), new GLatLng(37.97791762387,23.78145356303465)], "#FF0000", 10); GEvent.addListener(polyline, "click", function() { }); rmarkers.push(polyline); polyline.type = 'polyline'; map.addOverlay(polyline); // Adding a Polygon var perimeter = new GPolygon( [new GLatLng(37.97635717824197,23.78899058286345), new GLatLng(37.97708237409014 ,23.7884251217523), new GLatLng(37.97747123844004,23.78810420996354)], "#003300", 5, 0.5,"#84FF84", 0.5); GEvent.addListener(perimeter, "click", function() { }); rmarkers.push(perimeter); perimeter.type = 'perimeter'; map.addOverlay(perimeter);
<! A KML polygon definition> <Placemark> <name>ntua</name> <Polygon> <tessellate>1</tessellate> <outerBoundaryIs> <LinearRing> <coordinates> 23.77640524972817,37.97997329891562,0 23.77662966873682,37.98001305553392,0 23.77648054859569,37.97997328228906,0 <!- 185+ similar lines with coordinates > </coordinates> </LinearRing> </outerBoundaryIs> </Polygon> </Placemark> <!-The XSL to process the coordinates > <xsl:template match="Placemark"> <xsl:variable name="curpos" select="position()"/> <xsl:text>var polygon</xsl:text> <xsl:value-of select="$curpos"/> <xsl:text> = new GPolygon([</xsl:text> <xsl:apply-templates select="Polygon/outerBoundaryIs/LinearRing/coordinates"/> <xsl:text>], "#0000FF", 5,0.5,"#8A8AFF", 0.5); map.addOverlay(polygon</xsl:text> <xsl:value-of select="$curpos"/><xsl:text>);</xsl:text> </xsl:template> <xsl:template match="coordinates"> <xsl:variable name="in" select="."/> <xsl:for-each select="tokenize($in, ' ')"> <xsl:text>new GLatLng(</xsl:text> <xsl:variable name="tokenizedSample" select="tokenize(.,',')"/> <xsl:variable name="before" select="substring-before(.,',')"/> <xsl:variable name="after" select="substring-after(.,',')"/> <xsl:value-of select="$after"/><xsl:text>,</xsl:text> <xsl:value-of select="$before"/> <xsl:text>),</xsl:text> </xsl:for-each> </xsl:template>
In some situations, it is possible to move the XML-specific processing tasks over to the client and have the browser initially call the original KML file with the XMLHttpRequest API. However, this approach is not advisable in most cases because the overhead on the client's machine may cause the system to respond slowly or even freeze for a considerable amount of time.