Decode a JSON geometry

4454
4
09-08-2011 07:12 AM
EstherColero
New Contributor III
Hi,

I'm looking for a way to store the Graphics of the DrawWidget in a database and load them in a next session.

I thing that I need to save the geometry and the symbol for each Graphic, and probably the best way is use JSON.encode and JSON.decode
http://help.arcgis.com/en/webapi/flex/apiref/com/esri/ags/utils/JSON.html

I can transform a geometry to JSON and the JSON string to a Object type but, How can I create a Geometry type from JSON string? I'm sure that there is something in the API (probably geometryService wrapper use that) but I can't find it.

And if you know how to create a Symbol (SimpleMarkerSymbol, SimpleLineSymbol....) or a Graphic from JSON using API or if you have a code snippet it could be very useful for me 🙂 Any help is welcome.

Thank you in advance.

Regards
Esther
Tags (2)
0 Kudos
4 Replies
IvanBespalov
Occasional Contributor III
Hi, FeatureSet is Array of Graphics.
FeatureSet () Constructor
public function FeatureSet(features:Array = null)

where
features property 
features:Array

Array of graphic features.

...

See also
com.esri.ags.Graphic


Each feature in features array is Graphic. Each Graphic (in JSON) consists of "geometry" (in JSON) and "attributes" (in JSON) smthing like:
"features" : [
    {
      "geometry" : {
        "x" : -178.24479999999991,
        "y" : 50.012500000000045
      },
      "attributes" : {
        "objectid" : 3745682,
        "datetime" : 1272210710000,
        "depth" : 31.100000000000001,
        "eqid" : "2010vma5",
        "latitude" : 50.012500000000003,
        "longitude" : -178.2448,
        "magnitude" : 4.7999999999999998,
        "numstations" : 112,
        "region" : "Andreanof Islands, Aleutian Islands, Alaska",
        "source" : "us",
        "version" : "Q"
      }
    },
    {
      "geometry" : {
        "x" : -72.865099999999927,
        "y" : -37.486599999999953
      },
      "attributes" : {
        "objectid" : 3745685,
        "datetime" : 1272210142999,
        "depth" : 40.600000000000001,
        "eqid" : "2010vma4",
        "latitude" : -37.486600000000003,
        "longitude" : -72.865099999999998,
        "magnitude" : 4.9000000000000004,
        "numstations" : 58,
        "region" : "Bio-Bio, Chile",
        "source" : "us",
        "version" : "7"
      }
    }
  ]


com.esri.ags.FeatureSet has public methods:
fromJSON () method 
public static function fromJSON(json:String):FeatureSet


toJSON () method 
public function toJSON():String


Good luck.
0 Kudos
EstherColero
New Contributor III
Thank you Ivan,

I have try this previuosly, but when I rebuild the FeatureSet there are all Graphics but there is not any geometry or symbol (all them are null)

var pFeatureSet:FeatureSet = null;
var pFeatureSet2:FeatureSet = null;
var arrGraphics:Array = new Array();
var pGraphic:Graphic;

//Store all Graphics in an Array
for (var i:int = 0; i < graphicsLayer.numGraphics; i++)
{
    pGraphic = Graphic(graphicsLayer.getChildAt(i));
    arrGraphics.push(pGraphic);
}

//Create FeatureSet
pFeatureSet = new FeatureSet(arrGraphics);

//to JSON
var strJSON:String = pFeatureSet.toJSON();

//toFeatureSet
pFeatureSet2 = FeatureSet.fromJSON(strJSON); //All graphics, but no geometries or symbols

//Now with your example
strJSON = '{"features" : [{"geometry" : {"x" : -178.24479999999991,"y" : 50.012500000000045},"attributes" : {"objectid" : 3745682,"datetime" : 1272210710000,"depth" : 31.100000000000001,"eqid" : "2010vma5","latitude" : 50.012500000000003,"longitude" : -178.2448,"magnitude" : 4.7999999999999998,"numstations" : 112,"region" : "Andreanof Islands, Aleutian Islands, Alaska","source" : "us","version" : "Q"}},{"geometry" : {"x" : -72.865099999999927,"y" : -37.486599999999953},"attributes" : {"objectid" : 3745685,"datetime" : 1272210142999,"depth" : 40.600000000000001,"eqid" : "2010vma4","latitude" : -37.486600000000003,"longitude" : -72.865099999999998,"magnitude" : 4.9000000000000004,"numstations" : 58,"region" : "Bio-Bio, Chile","source" : "us","version" : "7"}}] }';
pFeatureSet2 = FeatureSet.fromJSON(strJSON); //All graphics, but no geometries or symbols


I am using Flex viewer 2.4. does it work for you?

Regards
Esther
0 Kudos
IvanBespalov
Occasional Contributor III
Hi.
Reading reference:
fromJSON () method
public static function fromJSON(json:String):FeatureSet

Convert from JSON to FeatureSet.

Parameters
json:String â?? ArcGIS JSON String

Returns
FeatureSet â?? a new FeatureSet

See also

Input JSON should match this REST response syntax

Try this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:esri="http://www.esri.com/2008/ags"
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
 <s:layout>
  <s:VerticalLayout paddingBottom="6"/>
 </s:layout>
 
 <fx:Script>
  <![CDATA[
   import com.esri.ags.FeatureSet;
   import com.esri.ags.Graphic;
   import com.esri.ags.events.MapMouseEvent;
   import com.esri.ags.geometry.Geometry;
   import com.esri.ags.geometry.MapPoint;
   
   import mx.collections.ArrayCollection;
   import mx.utils.StringUtil;
   
   private var jsonFeatureSet:String = "";
   
   /**
    * Listen map mouse down handler
    */
   protected function myMap_mapMouseDownHandler(event:MapMouseEvent):void
   {    
    //var grGeometry:MapPoint = myMap.extent.center;
    var grGeometry:MapPoint = event.mapPoint;
    var grAttributes:Object = new Object();
    var dateAttr:Date = new Date();
    grAttributes.creationDate = dateAttr;
    var numberAttr:Number = 777;
    grAttributes.n = numberAttr;
    var boolAttr:Boolean = true;
    grAttributes.b = boolAttr;
    var stringAttr:String = "Text";
    grAttributes.s = stringAttr;
    
    var gr:Graphic = new Graphic(grGeometry, sms, grAttributes);
    gr.toolTip = mx.utils.StringUtil.substitute("{0}\n{1}\n{2}\n{3}", 
     gr.attributes.creationDate, 
     gr.attributes.n, 
     gr.attributes.b, 
     gr.attributes.s);
    
    var grId:String = myGraphicsLayer.add(gr);
    
    trace(StringUtil.substitute("Graphic with id: {0} added.", grId));
   }
   
   /**
    * Listen export button click handler
    */
   protected function btnExportClick(event:MouseEvent):void
   {
    var arrGraphics:ArrayCollection = myGraphicsLayer.graphicProvider as ArrayCollection;
    if (arrGraphics != null && arrGraphics.length > 0) {
     var fsToExport:FeatureSet = new FeatureSet(arrGraphics.toArray());
     fsToExport.geometryType = Geometry.MAPPOINT;
     if (fsToExport != null) {
      jsonFeatureSet = fsToExport.toJSON();
      trace(jsonFeatureSet);
     }
    }
   }
   
   /**
    * Listen import button click handler
    */
   protected function btnImportClick(event:MouseEvent):void
   {
    if (jsonFeatureSet != null && jsonFeatureSet.length > 0) {
     var fsImported:FeatureSet = FeatureSet.fromJSON(jsonFeatureSet);
     if (fsImported != null) {
      var arrImported:Array = fsImported.features as Array;
      myGraphicsLayer.graphicProvider = arrImported;
     }
    }
   }
   
   /**
    * Listen clear all button click handler
    */
   protected function btnClearClick(event:MouseEvent):void
   {
    myGraphicsLayer.clear();
   }
   
  ]]>
 </fx:Script>
 <fx:Declarations>
  <!-- Symbol for all point shapes -->
  <esri:SimpleMarkerSymbol id="sms"
         color="0x00FF00"
         size="12"
         style="{SimpleMarkerSymbol.STYLE_DIAMOND}"/>
 </fx:Declarations>
 
 <esri:Map id="myMap"
     mapMouseDown="myMap_mapMouseDownHandler(event)"
     level="3"
     wrapAround180="true">
  <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"/>
  <esri:GraphicsLayer id="myGraphicsLayer" symbol="{sms}"/>
 </esri:Map>
 
 <s:Button id="btnExport" label="Export to JSON string" click="btnExportClick(event)"/>
 <s:Button id="btnClearAll" label="Clear all graphics" click="btnClearClick(event)"/>
 <s:Button id="btnImport" label="Import from JSON string" click="btnImportClick(event)"/>
</s:Application>

In this sample:
1 - Add graphics clicking on Map
2 - Click export to JSON button
3 - Click clear graphics button
4 - Click import fromJSON button

Symbols 😞
The 1 of the ways, to hold information about symbols = save it in one of the attributes in your graphic object. Parse this attribute when "FeatureSet.fromJSON" complete (create own classes, methods). Create symbol based on parsed data on fly.

Good luck.
0 Kudos
PaulHastings1
Occasional Contributor
if fidelity is important maybe ByteArray?

in the app init, register the ESRI classes you're using, eg:

registerClassAlias("com.esri.ags.Graphic", Graphic);
registerClassAlias("com.esri.ags.SpatialReference", SpatialReference);
registerClassAlias("com.esri.ags.geometry.MapPoint", MapPoint);
registerClassAlias("com.esri.ags.geometry.Extent", Extent);
registerClassAlias("com.esri.ags.symbols.SimpleFillSymbol",SimpleFillSymbol);

then to serialize, for example:
protected function addBM(event:MouseEvent):void {   
var thisBookmark:Object={};   
var bookmark:ByteArray = new ByteArray();
thisBookmark.extent=theMap.extent;
        // gets array of redline graphics in current map extent
thisBookmark.redlines=redlineInExtent();
bookmark.writeObject(thisBookmark);
        // send back to coldfusion for storage
psService.addBM(userID,bookmarksWindow.bmName.text,
          bookmarksWindow.shareBM.selected,new Date().getTime(),bookmarkl);
}

ByteArray readObject() will deserialize this back to the original data, symbolization & all.
0 Kudos