Select to view content in your preferred language

KML layer extents

2493
6
04-04-2012 02:30 AM
ManuelGarcia
Emerging Contributor
I want to set the Extent of the map automatically to focus on the layer shown by the kml, with an appropriate zoom.

I am using the following snippet, which is specified in here: http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi_start.htm#jsapi/kmllayer.htm

var kmlExtent, layers = kml.getLayers();
  dojo.forEach(layers, function(lyr) {
    if ( lyr.graphics && lyr.graphics.length > 0 ) {
      var lyrExtent = esri.geometry.geographicToWebMercator(
        esri.graphicsExtent(lyr.graphics)
      );
      if ( globals.kmlExtent ) {
        kmlExtent = kmlExtent.union(lyrExtent);
      } else {
        kmlExtent = lyrExtent;
      }
  });
  map.setExtent(kmlExtent);



However it does not seems to work, the element seems to have no layers.
This is my complete code:

[HTML]
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title></title>
<link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/esri/dijit/css/Popup.css"/>

<style>
  html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
  #map { margin: 0; padding: 0; }
  #meta {
    position: absolute;
    left: 20px;
    bottom: 20px;
    width: 300px;
    height: 100px;
    z-index: 40;
    background: #fff;
    color: #777;
    padding: 5px;
    border: 5px solid #777;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    font-family: arial;
    font-size: 0.9em;
  }
  #meta h3 {
    color: #000;
    font-size: 1.1em;
    padding: 0px;
    margin: 0px;
    display: inline-block;
  }
  #loading {
    float: right;
  }
</style>
<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script>
<script>
  dojo.require("dijit.layout.BorderContainer");
  dojo.require("dijit.layout.ContentPane");
  dojo.require("esri.map");
  dojo.require("esri.layers.KMLLayer");
 
  var map;
  function init() {
    map = new esri.Map("map");
    var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
    map.addLayer(basemap);

    var kmlUrl = 'http://dl.dropbox.com/u/21472423/15.kml';
    var kml = new esri.layers.KMLLayer(kmlUrl);
    map.addLayer(kml);
    dojo.connect(kml, 'onLoad', function() {
      dojo.style(dojo.byId('loading'), 'display', 'none');
    });
   
    dojo.connect(map, 'onLoad', function() {
        //resize the map when the browser resizes
        dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
    });


try{
//SNIPPET FOR AUTO EXTENT
    var kmlExtent, layers = kml.getLayers();
    dojo.forEach(layers, function(lyr) {
   if ( lyr.graphics && lyr.graphics.length > 0 ) {
     var lyrExtent = esri.geometry.geographicToWebMercator(esri.graphicsExtent(lyr.graphics) );
     if ( globals.kmlExtent ) {
    kmlExtent = kmlExtent.union(lyrExtent);
     } else {
    kmlExtent = lyrExtent;
     }
   }
    });
    map.setExtent(kmlExtent);
   }catch(err)
   {
  alert(err);
   }
  }
  dojo.ready(init);
</script>
</head>

<body class="tundra">
<div data-dojo-type="dijit.layout.BorderContainer"
     data-dojo-props="design:'headline',gutters:false"
     style="width: 100%; height: 100%; margin: 0;">
  <div id="map"
       data-dojo-type="dijit.layout.ContentPane"
       data-dojo-props="region:'center'">
    <div id="meta">
      <span id="loading"><img src="images/loading_black.gif" /></span>
    <div>
  </div>
</div>
</body>
</html>
[/HTML]

Can anyone help me with this?  :S

Thank you.
0 Kudos
6 Replies
AndyGup
Esri Regular Contributor
@mjgarcia did you try running your snippet after the kml loads?

    dojo.connect(kml, 'onLoad', function() {
      dojo.style(dojo.byId('loading'), 'display', 'none');
     // Add your snippet here
    });


-Andy
0 Kudos
derekswingley1
Deactivated User
Wait for the kml layer to load before trying to access its features. In other words, put the code to build the extent inside the function that fires when the km layer loads.
0 Kudos
ManuelGarcia
Emerging Contributor
Thank you for answers!

I put the code to build the extent inside the function, and the snippet is properly working now.

My Solution:

dojo.connect(kml, 'onLoad', function () {
            dojo.style(dojo.byId('loading'), 'display', 'none');
      //AutoExtent
      var kmlExtent, layers = kml.getLayers();
        dojo.forEach(layers, function(lyr) {
       if ( lyr.graphics && lyr.graphics.length > 0 ) {
         var lyrExtent = esri.geometry.geographicToWebMercator(esri.graphicsExtent(lyr.graphics) );
         kmlExtent = lyrExtent;
       }
        });
        map.setExtent(kmlExtent);
        });
0 Kudos
ManuelGarcia
Emerging Contributor
Everything was working perfectly with a linestring or a placemark. However when the kml contains an Folder element with both, I am getting an exception: "TypeError: Cannot call method 'toJson' of undefined".

This is the html: http://dl.dropbox.com/u/21472423/esri/kml.html
And this is the kml with Folder element: http://dl.dropbox.com/u/21472423/esri/kml-folder.kml (The syntax is correct).

Does anyone know how to do this?

Thank you.
0 Kudos
derekswingley1
Deactivated User
I think the presence of a folder in the KML file is red herring. The problem appears to be that one of the KML layers has a single point which does not result in a valid extent. Try this:


<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title> </title>

<link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/esri/dijit/css/Popup.css"/>

<style>
  html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
  #map { margin: 0; padding: 0; }
  #meta {
    position: absolute;
    left: 20px;
    bottom: 20px;
    width: 300px;
    height: 100px;
    z-index: 40;
    background: #fff;
    color: #777;
    padding: 5px;
    border: 5px solid #777;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    font-family: arial;
    font-size: 0.9em;
  }
  #meta h3 {
    color: #000;
    font-size: 1.1em;
    padding: 0px;
    margin: 0px;
    display: inline-block;
  }
</style>

<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script>
<script>
  dojo.require("dijit.layout.BorderContainer");
  dojo.require("dijit.layout.ContentPane");
  dojo.require("esri.map");
  dojo.require("esri.layers.KMLLayer");

  dojo.require("esri.dijit.Popup");
 
  var map;

  function init() {
    var initExtent = new esri.geometry.Extent({"xmin":-13947963,"ymin":4434797,"xmax":-13170751,"ymax":4779680,"spatialReference":{"wkid":102100}});
    var popup= new esri.dijit.Popup(null,dojo.create("div")); 
    map = new esri.Map("map",{ infoWindow: popup, extent: initExtent });
    //map = new esri.Map("map",{ extent: initExtent });

    var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
    map.addLayer(basemap);

    var kmlUrl = "http://dl.dropbox.com/u/21472423/esri/kml-folder.kml";
    var kml = new esri.layers.KMLLayer(kmlUrl);
    map.addLayer(kml);
    dojo.connect(kml, 'onLoad', function() {
      var layers = kml.getLayers();
      var kmlLayerExtent;
      dojo.forEach(layers, function(l) {
        // get the extent for the layer
        var ext = esri.geometry.geographicToWebMercator(esri.graphicsExtent(l.graphics));
        // if the layer's extent is valid, union it with the rest of the layer
        // extents. layers with a single point do not result in a valid extent
        if ( ext ) {
          (kmlLayerExtent) ? kmlLayerExtent.union(ext): kmlLayerExtent = ext;
        }
      });
      map.setExtent(kmlLayerExtent);
    });
   
    dojo.connect(map, 'onLoad', function() {
      //resize the map when the browser resizes
      dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
    });
  }
  dojo.ready(init);
</script>
</head>

<body class="tundra">
<div data-dojo-type="dijit.layout.BorderContainer"
     data-dojo-props="design:'headline',gutters:false"
     style="width: 100%; height: 100%; margin: 0;">
  <div id="map"
       data-dojo-type="dijit.layout.ContentPane"
       data-dojo-props="region:'center'">
    <div id="meta">
      <h3>Display KML Using a <a href="http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi/kmllayer.htm">KMLLayer</a></h3>
      <br />
      The map displays a simple KML file that was created using Google Earth and
      is hosted on an Esri server. Symbology and attributes are honored.
    <div>
  </div>
</div>
</body>
</html>
0 Kudos
SrimathiSekar
Deactivated User
We have used similar code to display the kml layer.It works in a simple html.Our requirement is to show the KML map in microstrategy.According to me I should be modifying the esrimap.js of esrimapviewer.js or other esri related js files.

Please let me where should i integrate the code to get the kml layer displayed in micro strategy.
0 Kudos