Search code examples
javascriptkmlarcgisarcgis-js-api

Get extent from KML layer in ArcGIS Online


Is there any way to calculate the extent of a KML layer loaded from the web using the KMLLayer({ url: "my file" }) method in ArcGIS Online? The KMLs loaded from AGOL have a valid fullExtent property, but ones loaded from other sources seem to default to the entire world, which is not useful.

Here is an example:

app.kml=new KMLLayer({ url: "my file" });                                                                                    
app.map.add(app.kml);                                                                                                    
app.kml.load().then(function() { app.mapView.extent=app.kml.fullExtent; console.log(app.kml) });

It is live at:

http://viseyes.org/visualeyes/test.htm?kml=https://www.arcgis.com/sharing/rest/content/items/a8efe6f4c12b462ebedc550de8c73e22/data

The console prints out the KMLLayer object, and the fullExtent field seems to be not set right.


Solution

  • I agree, it does not seem like the fullExtent property is what you would expect. I think there are two workarounds:

    Write some code to query the layerView to get the extent:

    view.whenLayerView(kmlLayer).then(function(layerView) {
      watchUtils.whenFalseOnce(layerView, "updating", function() {
        var kmlFullExtent = queryExtent(layerView);
        view.goTo(kmlFullExtent);
      });
    });
    
    function queryExtent(layerView) {
      var polygons = layerView.allVisiblePolygons;
      var lines = layerView.allVisiblePolylines;
      var points = layerView.allVisiblePoints;
      var images = layerView.allVisibleMapImages;
    
      var kmlFullExtent = polygons
        .concat(lines)
        .concat(points)
        .concat(images)
        .map(
          graphic => (graphic.extent ? graphic.extent : graphic.geometry.extent)
        )
        .reduce((previous, current) => previous.union(current));
      return kmlFullExtent;
    }
    

    Example here.

    -- or --

    Call the utility service again and use the "lookAtExtent" property:

    view.whenLayerView(kmlLayer).then(function(layerView) {
      watchUtils.whenFalseOnce(layerView, "updating", function() {
        // Query the arcgis utility and use the "lookAtExtent" property -
        esriRequest('https://utility.arcgis.com/sharing/kml?url=' + kmlLayer.url).then((response) => {
          console.log('response', response.data.lookAtExtent);
          view.goTo(new Extent(response.data.lookAtExtent));
        });
    
      });
    });
    

    Example here.