How to update kml file/layer dynamically?

1.9k views Asked by At

I am using a kml file for displaying map with custom boundary lines. That kml file is downloaded from some website. In that file, inside the placemark tag there is no point tag for display icons. Eg:

<Placemark>
    <name>Spot 2</name>
    <description>.....</description>
    <styleUrl>....</styleUrl>
    <MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>
    .........
    </coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
</Placemark>

That is what placemark tag contains in my kml file. And I need,

1) How can I add point tag for all placemark tag. Is there any way to add dynamically?. My kml file has 5000 and above placemarks. 2) Point tag coordinates will refers to the center of the polygon.

i.e) I need the following

<Placemark>
    <name>Spot 2</name>
    <description>.....</description>
    <styleUrl>....</styleUrl>
    <MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>
    .........
    </coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
    <Point>
        <coordinates>144.253,-36.6632,0</coordinates>
    </Point>
</Placemark> 

Note:

I am using geoxml3 parser to display kml layer in google maps.

This is my html file,

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>KML Layers</title>
    <style>
      html, body, #map-canvas {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script type="text/javascript" src="http://geoxml3.googlecode.com/svn/branches/polys/geoxml3.js"></script>
    <script type="text/javascript" src="http://geoxml3.googlecode.com/svn/trunk/ProjectedOverlay.js"></script>
    <script>
function initialize() {
  var usa = new google.maps.LatLng(41.875696,-87.624207);
  var mapOptions = {
    zoom: 4,
    center: usa,
    mapTypeId: google.maps.MapTypeId.HYBRID
  }
  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

var myParser = new geoXML3.parser({
    map: map
  });
    var kml = myParser.parse('http://localhost/test/DFWNorth.kml');
}
google.maps.event.addDomListener(window, 'load', initialize);
    </script>
  </head>
  <body>
    <div id="map-canvas"></div>
  </body>
</html>

This is my sample kml file,

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
  xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document>
  <name>Real Estate Portal USA Parcels</name>
  <open>1</open>

  <Style id="parcel">
    <LineStyle>
      <color>ff48a7ff</color>
      <width>1</width>
    </LineStyle>
    <PolyStyle>
      <outline>1</outline>
      <color>00ffffff</color>
    </PolyStyle>
  </Style>

  <Style id="hl_parcel">
    <IconStyle>
      <scale>0.3</scale>
      <Icon>
        <href>http://bus.w.pw/R.png</href>
      </Icon>
    </IconStyle>
    <LabelStyle>
      <color>9900ffff</color>
      <scale>1</scale>
    </LabelStyle>
    <LineStyle>
      <color>ff00ffff</color>
      <width>1.5</width>
    </LineStyle>
    <PolyStyle>
      <outline>1</outline>
      <color>5f000000</color>
    </PolyStyle>
  </Style> 
  <Folder>
    <open>1</open>
    <name>Selected Parcels</name>
    <Placemark>
      <name><![CDATA[1100 N 27TH Ave]]></name>
      <description>
............
</description>
      <styleUrl>#hl_parcel</styleUrl>
      <MultiGeometry>
        <Polygon>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>-97.032117983752471,32.928768626517076 -97.024643584146915,32.923035186813181 -97.024619516424863,32.923056622674181 -97.023311876445746,32.922172553473487 -97.023027365973348,32.921986354508512 -97.022978167636879,32.921954156605246 -97.022101518923066,32.921458657105333 -97.021852382220004,32.921328433111441 -97.021603007761968,32.921212207649802 -97.021353262564418,32.921103685381986 -97.020040739077089,32.92059307329437 -97.019977072943703,32.920561642411542 -97.019978949582082,32.920357989560173 -97.019981935486342,32.920034178750491 -97.032338461906804,32.92018039810069 -97.03217983292177,32.928807043604458 -97.032117983752471,32.928768626517076</coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
    </MultiGeometry>
    </Placemark>
.........
...........
2

There are 2 answers

0
geocodezip On BEST ANSWER

geoxml3 parses the KML to native google.maps.Polygon objects. You can process those polygons in the afterParse function:

var myParser = new geoXML3.parser({
  map: map,
  afterParse: useTheData
});
var kml = myParser.parse('kml/SO_20150619a.kml');
function useTheData(doc) {
  for (var i=0; i < doc[0].gpolygons.length; i++) {
    var centroid = new google.maps.Marker({map:map,position: get_polygon_centroid(doc[0].gpolygons[i].getPath().getArray())});
  }
}

To get the centroid of the polygon:

// from http://stackoverflow.com/questions/9692448/how-can-you-find-the-centroid-of-a-concave-irregular-polygon-in-javascript
function get_polygon_centroid(pts) {
   var first = pts[0], last = pts[pts.length-1];
   if (first.lat() != last.lat() || first.lng() != last.lng()) pts.push(first);
   var twicearea=0,
   x=0, y=0,
   nPts = pts.length,
   p1, p2, f;
   for ( var i=0, j=nPts-1 ; i<nPts ; j=i++ ) {
      p1 = pts[i]; p2 = pts[j];
      f = p1.lat()*p2.lng() - p2.lat()*p1.lng();
      twicearea += f;          
      x += ( p1.lng() + p2.lng() ) * f;
      y += ( p1.lat() + p2.lat() ) * f;
   }
   f = twicearea * 3;
   return new google.maps.LatLng(y/f, x/f);
}

Note that the above only "really works" for regular polygons, so irregular polygons with concave edges the center might not be "in" the polygon.

Working example

2
ScaisEdge On

KML is an XML document then you can add with normal xmlDOC manipulation function eg

xmlDoc=loadXMLDoc("yourfile.klm");

newel=xmlDoc.createElement("yourElementToAdd");

x=xmlDoc.getElementsByTagName("yourElementToAppend")[0];
x.appendChild(newel);