Select to view content in your preferred language

2.4 Flex Viewer with KML's served locally

3671
14
08-06-2011 03:52 PM
NeoGeo
by
Frequent Contributor
Some KML's and KMZ's work as layers in the new 2.4 Flex Viewer if served from a remote server, but when I try to acess KML's served locally on the GIS server through IIS, the viewer returns "Layer failed to load.  Fault code 400.  Fault info:  File not found. Wrong URL. Fault details:"

No details were given.  The KML virtual directory has MIME types for both kml and kmz.  If I access the url for one of the kml files from a browser, it gives me the option to open or download the file.  I do have a crossdomain file which allows everything in the web root folder.  I thought perhaps it just could not handle that particular kml so I created a super simple kml using the sample from Google's web site with a single point, but it still gives me that error.  Thinking that maybe it was something I had wrong with my IIS configuration, I pointed it to a feed on the other ArcGIS Server which I know works because I am using them with kml tools in the Flex 1.x Viewer on that server, but it gives me the same error. Any ideas?

Thanks!
Tags (2)
0 Kudos
14 Replies
EjayLai
Deactivated User
It's glad to see kml is finally being supported though it has to be
publicly accessible
. Thank you!
0 Kudos
DavidLewis
New Contributor
Will it be possible to get a copy of the utility service to run it on our side for people serving data on corporate intranets and for military usage on the military network?


If this utility service could be incorporated into ArcGIS Server, this would solve my problems! I am developing for the ArcGIS Viewer for Flex on a closed (intranet) network. The alternate solution of KML -> Shape file -> ArcSDE -> ArcIMS -> Viewer has not been working satisfactorily for us. Have the KML -> Layer as a local service would be indispensable!
0 Kudos
NeoGeo
by
Frequent Contributor
We have been working with ESRI (ie paying them lots of money LOL) for a local solution for the 2.x Viewer and what they came up with could be set up by any reasonably good programmer.  Basically they came up with a Geoprocessing Service which uses the import kml tool from ArcToolbox to import the kml feeds on a scheduled basis.  A good portion of this could be built in modelbuilder and converted to Python so you can add the code to handle the downloads and whatnot.  There is a Map Service using this Geoprocessing service as a "capability".  The map document is just an msd which points at the downloaded data, which means you can change the symbology and scale dependencies to whatever you want.  I would just keep it simple and create my own symbology but they wrote scripts to import some of the kml symbology and generate an mxd.  Either way it is great because most have probably noticed that the symbology on many kml's is not so good.  Also the load time is instant vs up to 5 minutes on some worldwide kml datasets with the out of the box kml support.  They got quite a bit fancier than I would have if I was writing it, but to be perfectly honest, it just never occurred to me to create a geoprocessing service using the import kml tool or I would have done it a long time ago.  It is still being tested at the moment.  Just thought I would put this idea out there for people who don't want to write their own parser.
0 Kudos
NolanAlbarelli
Occasional Contributor
Hey NeoGeo, thanks for sharing the solution with us.  I think we are working very similar projects if you are developing a flex viewer on a military network.  I'd love to discuss the kml issue with you further.  any chance you're still serving the client behind this effort?  feel free to send me a message privately if you would prefer.  thanks again!

We have been working with ESRI (ie paying them lots of money LOL) for a local solution for the 2.x Viewer and what they came up with could be set up by any reasonably good programmer.  Basically they came up with a Geoprocessing Service which uses the import kml tool from ArcToolbox to import the kml feeds on a scheduled basis.  A good portion of this could be built in modelbuilder and converted to Python so you can add the code to handle the downloads and whatnot.  There is a Map Service using this Geoprocessing service as a "capability".  The map document is just an msd which points at the downloaded data, which means you can change the symbology and scale dependencies to whatever you want.  I would just keep it simple and create my own symbology but they wrote scripts to import some of the kml symbology and generate an mxd.  Either way it is great because most have probably noticed that the symbology on many kml's is not so good.  Also the load time is instant vs up to 5 minutes on some worldwide kml datasets with the out of the box kml support.  They got quite a bit fancier than I would have if I was writing it, but to be perfectly honest, it just never occurred to me to create a geoprocessing service using the import kml tool or I would have done it a long time ago.  It is still being tested at the moment.  Just thought I would put this idea out there for people who don't want to write their own parser.
0 Kudos
SangeetaBomma
New Contributor
Hi, I am working Adobe FlASH pLAYER SDK 4.6 and Viewer API VERSION 3.0.
We have a GIS Viewer Application and would like to add a widget to add a KML file locally to the map. And then be able to edit/delete the added layer.


Any suggestions are greatly appreciated. I am new to working with KML layers. And have a deadline to meet on this implementation.
Also I have tried the implementation suggested, but when I do a network trace, the utility service
on arcgis.com to convert the KML for us is giving a 304 error and I dont see any KML Layer added to map.

Here is the code:
<viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"
       xmlns:s="library://ns.adobe.com/flex/spark"
       xmlns:mx="library://ns.adobe.com/flex/mx"
       xmlns:viewer="com.esri.viewer.*"
       widgetConfigLoaded="init()">
<viewer:states>
  <s:State name="KMLInput"/>
  <s:State name="removeKML"/>
</viewer:states>
<viewer:transitions>
  <s:Transition autoReverse="true" toState="*">
   <s:Fade targets="{[KMLInput,removeKML]}"/>
  </s:Transition>
</viewer:transitions>
<fx:Script>
  <![CDATA[
   import com.esri.ags.layers.KMLLayer;
   import com.esri.ags.layers.Layer;
   import com.esri.ags.layers.supportClasses.KMLFeatureInfo;
   import com.esri.ags.layers.supportClasses.KMLFolder;
   import com.esri.ags.layers.supportClasses.LayerInfoWindowRenderer;
   import com.esri.viewer.AppEvent;
   import com.esri.viewer.components.toc.TOC;
   import com.esri.viewer.components.toc.tocClasses.TocKmlFolderItem;
   import com.esri.viewer.components.toc.tocClasses.TocKmlNetworkLinkItem;
   import com.esri.viewer.components.toc.tocClasses.TocMapLayerItem;
  
   import flash.display.Sprite;
   import flash.net.FileFilter;
   import flash.net.FileReference;
   import flash.utils.ByteArray;
  
   import flashx.textLayout.events.SelectionEvent;
  
   import mx.collections.ArrayCollection;
   import mx.collections.ArrayList;
   import mx.controls.Alert;
   import mx.events.ValidationResultEvent;
   import mx.messaging.Consumer;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.http.Operation;
   import mx.utils.object_proxy;
   import mx.validators.ValidationResult;
   import mx.validators.Validator;
  
   import widgets.InfoTemplates.SimpleInfoWinWidget;
   import widgets.LayerList.LayerListWidget;

   private const ICON_URL:String = "assets/images/";
   private var KMLLocation:String;
   public var kmlLayer:KMLLayer= new KMLLayer();
   private var fr:FileReference;
   private static const FILE_TYPES:Array = [new FileFilter("KML/KMZ","*.kml;*.kmz")];
   //this function called when the widget's configuration is loaded
  
   private function init():void
   {
    if (configXML) // checking for valid content in the configuration file
    {
     lbl.text = configXML.content || getDefaultString("KMLLayerWidgetContent");
    }
    KMLLayerWgt.addTitlebarButton(ICON_URL + "Google-Earth-Add.png","Load KML",showstateLoadKML);
    KMLLayerWgt.addTitlebarButton(ICON_URL + "Google-Earth-Remove.png","Remove KML",showstateDelete);
   }
  
   private function showstateLoadKML():void
   {
    this.currentState="KMLInput";
    KMLLayerWgt.selectedTitlebarButtonIndex = 1;
   }
   private function showstateDelete():void
   {
    this.currentState="removeKML";
    KMLLayerWgt.selectedTitlebarButtonIndex = 0;
   }
//todo figure out an array to add a new kml, or add a field to ask if you want new?
   public function LoadKML():void
   {
   /* kmlLayer.url = KMLAddress.text;
    kmlLayer.name = kmlname.text;*/
    kmlLayer.url ="http://localhost/3.0.0/Simple.kml"
    kmlLayer.name = "Simple.kml";
    map.addLayer(kmlLayer);
    this.ClearForm();   
   }
  
   public function ClearForm():void
   {
    KMLAddress.text="Paste http:// URL here";
    kmlname.text="Enter a Name for your file";
   }

   private function removeLayer():void
   {
    map.getLayer(kmlLayer.name);
    map.removeLayer(kmlLayer);
   }

  


  
  ]]>
</fx:Script>
<viewer:WidgetTemplate id="KMLLayerWgt"
         width="300" height="200">
  <s:Group id="KMLInput"
     width="100%"
     visible="false"
     visible.KMLInput="true">
   <s:Label id="lbl"
      fontSize="12"
      fontStyle="italic"
      fontWeight="bold"
      width="100%"
      paddingTop="8"/>
   <s:Form id="KMLEntryFrm"
      width="100%" height="25%">
    <s:FormItem id="kmlnm"
       width="100%"
       required="false">
        <s:TextInput id="kmlname"
         width="100%"
         text="Enter a Name for your file">
        </s:TextInput>
    </s:FormItem>
    <s:FormItem id="KMLAddentry"
        width="100%"
        required="true">
     <s:TextInput id = "KMLAddress"
         width="100%"
         text="Paste http:// URL here">
     </s:TextInput>
     <s:HGroup width="100%"
         horizontalAlign="center"
         paddingTop="5">
      <s:Button click="LoadKML()" label="Load KML"/>
      <s:Button click="ClearForm()" label="Clear"/>
     
     </s:HGroup>
    
    </s:FormItem>   
   </s:Form>
  </s:Group>
  <s:Group id="removeKML"
     width="100%" height="100%"
     visible="false"
     visible.removeKML="true">
   <s:HGroup width="100%"
       horizontalAlign="center">
    <s:Form>
     <s:Button click="removeLayer()" label="Remove KML"/>
        <s:Button click="ClearForm()" label="  Clear  "/>
   </s:Form>
   </s:HGroup>
  </s:Group>
</viewer:WidgetTemplate>
</viewer:BaseWidget>
0 Kudos