Select to view content in your preferred language

Problem Saving new feature in Feature Layer created from DrawObject

1106
2
Jump to solution
05-23-2012 07:26 PM
CraigPatterson
Regular Contributor
I'm creating a tool that allows users to create new features based on the graphic returned by a DrawObject.  The graphic is added to a featurelayer.  Finally, I save the records via an Editor Widget linked to the featurelayer. 

Graphics returned by the DrawObject in Polygon mode save fine.  Graphics returned by buffering the graphic returned by the DrawObject in Line mode also work fine.  However, if the DrawObject is set to rectangle, I can not save the new feature created by graphic.  I've attached a screenshot of the error message.

[ATTACH=CONFIG]14587[/ATTACH]

This is the DrawComplete event handler for my DrawObject

                 /// <summary>         /// Rectangle_DrawObject DrawComplete event handler         /// Adds user drawn rectangle to Projects FeatureLayer         /// </summary>         /// <param name="sender"></param>         /// <param name="args">DrawEventArgs</param>          private void Rectangle_DrawObject_DrawComplete(object sender, DrawEventArgs args)         {             Rectangle_DrawObject.IsEnabled = false;              //Ready the graphic              Graphic graphic = new Graphic()             {                 Geometry = args.Geometry             };              // Input spatial reference for buffer operation defined by first feature of input geometry array             graphic.Geometry.SpatialReference = Map.SpatialReference;              AddProjectGraphic(graphic);          }


The AddProjectGraphic method adds the attributes and adds the graphic to the feature layer

        /// <summary>         /// AddProjectGraphic         /// Adds graphic to Projects_Edit featurelayer         /// </summary>         /// <param name="graphic">Graphic to be added</param>         private void AddProjectGraphic(Graphic graphic)         {              // Retrieve the Projects featurelayer from the application             FeatureLayer projects = Map.Layers["Projects_Edit"] as FeatureLayer;              // add attributes to the graphic             // loop through the field list             foreach (var field in projects.LayerInfo.Fields)             {                 // only add fields that are editable and set to null                 if (field.Editable) {                     graphic.Attributes[field.Name] = null;                 }             } // end loop              // Add the buffered line graphic to the featurelayer             if (projects != null)             {                 projects.Graphics.Add(graphic);                  // turn off datagrid/turn on dataform                 DocumentFeatureDataGrid.Visibility = Visibility.Collapsed;                 DocumentFeatureDataForm.Visibility = Visibility.Visible;                                  // set the data forms source to new graphic                 DocumentFeatureDataForm.GraphicSource = graphic;             }         }


I've used Fiddler to inspect what was being sent to the server when saving the new features.

Here is the message sent when trying to save a rectangle...
[{,"attributes":{"BARCODE":null,"BAR_IMAGE":null,"DELETE_POLY":null,"DOCHYPERLINK":null,"PROJECT_NAME":null,"PRINT_DATE":null,"FILENUMBER":null,"SHEET_NUMBER":null,"SHEET_TOTAL":null,"COMMUNITY":null,"AVAILABLE":null,"QC":null,"QCDATE":null,"QCUSER":null}}]

Here is the message sent when trying to save a  polygon...
[{"geometry":{"spatialReference":{"wkt":"PROJCS[\"NAD_1983_StatePlane_Michigan_South_FIPS_2113_IntlFeet\",GEOGCS[\"GCS_North_American_1983\",DATUM[\"D_North_American_1983\",SPHEROID[\"GRS_1980\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Lambert_Conformal_Conic\"],PARAMETER[\"False_Easting\",13123359.58005249],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",-84.36666666666666],PARAMETER[\"Standard_Parallel_1\",42.1],PARAMETER[\"Standard_Parallel_2\",43.66666666666666],PARAMETER[\"Latitude_Of_Origin\",41.5],UNIT[\"Foot\",0.3048]]"},"rings":[[[12761546.5763327,543598.139940832],[12761922.406962,541437.113822478],[12759573.465529,541437.113822478],[12759479.5078716,544161.885884751],[12760419.0844448,542752.521024954],[12761546.5763327,543598.139940832]]]},"attributes":{"BARCODE":"testpolygonforfiddler","BAR_IMAGE":null,"DELETE_POLY":null,"DOCHYPERLINK":null,"PROJECT_NAME":null,"PRINT_DATE":null,"FILENUMBER":null,"SHEET_NUMBER":null,"SHEET_TOTAL":null,"COMMUNITY":null,"AVAILABLE":null,"QC":null,"QCDATE":null,"QCUSER":null}}]


When I debug the program and step through each line of code, the geometry is present in the feature up until I save.

Perhaps I've found a bug, but there's no reason I can see that this should fail.

Anyone have any suggestions?

Craig
0 Kudos
1 Solution

Accepted Solutions
JenniferNery
Esri Regular Contributor
When using Draw, note that DrawMode=Rectangle results to e.Geometry of type Envelope. You would want to convert this to Polygon geometry first.

   var env = e.Geometry as Envelope;    Polygon p = new Polygon() { SpatialReference = env.SpatialReference };    PointCollection ring = new PointCollection();    ring.Add(new MapPoint(env.XMin, env.YMin));    ring.Add(new MapPoint(env.XMin, env.YMax));    ring.Add(new MapPoint(env.XMax, env.YMax));    ring.Add(new MapPoint(env.XMax, env.YMin));    ring.Add(new MapPoint(env.XMin, env.YMin));    p.Rings.Add(ring);    var graphic = new Graphic() { Geometry = p };


Also, you may want to call Simplify on the result geometry from Draw to ensure that the geometry is topologically correct before saving to your FeatureLayer. Editor.Add or TemplatePicker already does this for you if GeometryService has been provided (you can check this on Fiddler): http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#ToolkitTemplatePicker. To call Simplify, you can look at this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Simplify

View solution in original post

0 Kudos
2 Replies
JenniferNery
Esri Regular Contributor
When using Draw, note that DrawMode=Rectangle results to e.Geometry of type Envelope. You would want to convert this to Polygon geometry first.

   var env = e.Geometry as Envelope;    Polygon p = new Polygon() { SpatialReference = env.SpatialReference };    PointCollection ring = new PointCollection();    ring.Add(new MapPoint(env.XMin, env.YMin));    ring.Add(new MapPoint(env.XMin, env.YMax));    ring.Add(new MapPoint(env.XMax, env.YMax));    ring.Add(new MapPoint(env.XMax, env.YMin));    ring.Add(new MapPoint(env.XMin, env.YMin));    p.Rings.Add(ring);    var graphic = new Graphic() { Geometry = p };


Also, you may want to call Simplify on the result geometry from Draw to ensure that the geometry is topologically correct before saving to your FeatureLayer. Editor.Add or TemplatePicker already does this for you if GeometryService has been provided (you can check this on Fiddler): http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#ToolkitTemplatePicker. To call Simplify, you can look at this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Simplify
0 Kudos
CraigPatterson
Regular Contributor
You're the best.  Your code worked like a charm.  I adjust my draw complete method to incorporate your code...

            Graphic graphic;

            if (Rectangle_DrawObject.DrawMode == DrawMode.Rectangle)
            {

                var env = args.Geometry as Envelope;
                ESRI.ArcGIS.Client.Geometry.Polygon p = new ESRI.ArcGIS.Client.Geometry.Polygon() { SpatialReference = env.SpatialReference };
                ESRI.ArcGIS.Client.Geometry.PointCollection ring = new ESRI.ArcGIS.Client.Geometry.PointCollection();
                ring.Add(new MapPoint(env.XMin, env.YMin));
                ring.Add(new MapPoint(env.XMin, env.YMax));
                ring.Add(new MapPoint(env.XMax, env.YMax));
                ring.Add(new MapPoint(env.XMax, env.YMin));
                ring.Add(new MapPoint(env.XMin, env.YMin));
                p.Rings.Add(ring);
                graphic = new Graphic() { Geometry = p };

            }
            else
            {
                //Ready the graphic 
                graphic = new Graphic()
                {
                    Geometry = args.Geometry
                };            
            }



Thanks,

Craig
0 Kudos