ThinkGeo.com    |     Documentation    |     Premium Support

Editing Shapes and identifying them based on their feature column values

Hello,



I create shapes on a map and assign data to the features based on database values.  I can access these feature on mapclick (getting the closest shape to the click).



However, when I edit the shapes boundaries, I am not able to access these column values when I loop through all the features.



I am using the example in DrawEditShapes.aspx.   



On Save:





 



            LayerOverlay dynamicOverlay = (LayerOverlay)Map1.CustomOverlays["DynamicOverlay"];
            InMemoryFeatureLayer shapeLayer = (InMemoryFeatureLayer)dynamicOverlay.Layers["shapeLayer"];

            foreach (Feature feature in Map1.EditOverlay.Features)
            {
                if (!shapeLayer.InternalFeatures.Contains(feature.Id))
                {
                    shapeLayer.InternalFeatures.Add(feature.Id, feature);
                }
            }

            Map1.EditOverlay.Features.Clear();
            Map1.EditOverlay.TrackMode = TrackMode.None;
            dynamicOverlay.Redraw();

feature.columns.count is 0.  Therefore for some reason I can't access the feature column values that I set.  I need to be able to update the boundaries (wkt, wkb) of the shapes in the database.     Any ideas?



Hi Chad,


You just set the column values to the features, but didn't set the layer's, please add the following code to see it works or not:



Feature feature = shapeLayer.InternalFeatures[0];
shapeLayer.Open();
foreach(var column in feature.ColumnValues)
{
    shapeLayer.Columns.Add(new FeatureSourceColumn(column.Key));
}


Hope it helps,


Edgar



Edgar,


Sorry I just saw that you replied.  I wish it would automatically follow posts that we create.



Where do I put that code?  This is some of what I have for when I create the layer.



 



propertyLayer.EditTools.BeginTransaction();
                ////if the user has properties
                if (p.GetProperties())
                {
                    //create the properties layer
                    foreach (DataRow dr in p.dtProperties.Rows)
                    {
                        //Create Feature based upon Well Known Text you have stored in your database table
                        Feature propPolygon = new Feature(dr["property_wkt"].ToString());
                        //Set the field information for each plot polygon based upon what is stored in the database.
                        propPolygon.ColumnValues.Add("id", dr["property_id"].ToString());
                        propPolygon.ColumnValues.Add("name", dr["property_name"].ToString());
                        propPolygon.ColumnValues.Add("zip", dr["zip"].ToString());
                        propPolygon.ColumnValues.Add("acres", dr["property_acres"].ToString());
                        propPolygon.ColumnValues.Add("link", dr["property_link"].ToString());
                        propPolygon.ColumnValues.Add("info", dr["property_info"].ToString());
                        propPolygon.ColumnValues.Add("featureId", dr["feature_id"].ToString());

                        propertyLayer.EditTools.Add(propPolygon);
                    }
                }
                propertyLayer.EditTools.CommitTransaction();
                propertyLayer.Close();




Where do I put the code you posted?

Chad, 
  
 You can add it after  propertyLayer.Close(); method. 
  
 The Layer.Columns represents the features’ column name and add them once is enough. 
  
 Regards, 
  
 Edgar

 Edgar,



It still is not seeing the columns for some reason.  Here is part of my save method.  feature.columnvalues.count = 0

 



                foreach (Feature feature in Map1.EditOverlay.Features)
                {
                    if (!propertyLayer.InternalFeatures.Contains(feature.Id))
                    {
                        //propertyLayer.InternalFeatures.Add(feature.Id, feature);

                        //get area
                        AreaBaseShape abs = (AreaBaseShape)feature.GetShape();

                        if (!propertyLayer.InternalFeatures.Contains(feature.Id))
                        {
                            //propertyLayer.InternalFeatures.Add(feature.Id, feature);

                            //p.AddProperty(null, null, feature.GetWellKnownText(), 
                            //    feature.WellKnownBinary, GetBoundingBox(abs), feature.Id, loginId,
                            //    txtPropertyAcres.Text.Trim(), rePropertyInfo.Content, txtPropertyLink.Text.Trim(), txtZip.Text.Trim());

                        }

                        //    p.AddProperty(hdnPropertyId.Value, txtPropertyName.Text.Trim(), null, null, null, null, loginId,
                        //txtPropertyAcres.Text.Trim(), rePropertyInfo.Content, txtPropertyLink.Text.Trim(), txtZip.Text.Trim());
                    }
                }


Any ideas?

Could you please send the sample to me then I can find out the error through the whole code? Maybe in somewhere the columnvalue is not assigned incorrectly. 
  
 Thanks, 
  
 Edgar

Edgar, I will need to try and isolate the issue.  I have a very large project.

Thanks Chad, we’ll wait for the sample.

Edgar, 
  
 I have removed everything but the mapping.  Where can I send you the code?

Hi Chad,


Before we dig into your sample I want to be sure that we have addressed what I think is the main issue.


We seem to be ignoring that you need to create and populate your EditLayer with the columns names before you will have access to this information. In the code above I only see that you are populating the Features with column values that specify a column name, but have you created this column in your EditLayer?


Edgar's code shows the creation of these columns:




Feature feature = shapeLayer.InternalFeatures[0];
shapeLayer.Open();
foreach(var column in feature.ColumnValues)
{
    shapeLayer.Columns.Add(new FeatureSourceColumn(column.Key));
}
 
 



Ryan, 
  
 I have sent the code to your the forumsupport email.   Here is the snippet that shows where Edgar’s code is implemented. 
  
  
        private void CreatePropertyLayer()
        {

            try
            {
                //Define your InMemoryFeatureLayer and setup the columns you want at the Layer Level.

                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromArgb(180, 102, 255, 102), 10, GeoColor.StandardColors.Orange, 1);
                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Orange, 10, true);
                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Transparent, GeoColor.StandardColors.Orange, 10, LineDashStyle.Dash);

                propertyLayer.DrawingQuality = DrawingQuality.HighSpeed;

                propertyLayer.Open();
                propertyLayer.Name = “PROPERTY”;
                propertyLayer.Columns.Add(new FeatureSourceColumn(“id”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“name”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“zip”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“acres”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“link”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“info”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“featureId”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“weather_station”));
                propertyLayer.Columns.Add(new FeatureSourceColumn(“perm”));

                //Set the Style on how you wnat your Plots to be displayed and for only Zoomlevel 10 to 20
                //propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultAreaStyle = AreaStyles.Crop1;
                propertyLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

                //Loop throuh your dataset returned from your database and add it to the Plots InMeoryFeaturelayer
                propertyLayer.EditTools.BeginTransaction();
                ////if the user has properties
                if (p.GetProperties())
                {
                    //create the properties layer
                    foreach (DataRow dr in p.dtProperties.Rows)
                    {
                        //Create Feature based upon Well Known Text you have stored in your database table
                        Feature propPolygon = new Feature(dr[“property_wkt”].ToString());
                        //Set the field information for each plot polygon based upon what is stored in the database.
                        propPolygon.ColumnValues.Add(“id”, dr[“property_id”].ToString());
                        propPolygon.ColumnValues.Add(“name”, dr[“property_name”].ToString());
                        propPolygon.ColumnValues.Add(“zip”, dr[“zip”].ToString());
                        propPolygon.ColumnValues.Add(“acres”, dr[“property_acres”].ToString());
                        propPolygon.ColumnValues.Add(“link”, dr[“property_link”].ToString());
                        propPolygon.ColumnValues.Add(“info”, dr[“property_info”].ToString());
                        propPolygon.ColumnValues.Add(“featureId”, dr[“feature_id”].ToString());
                        propPolygon.ColumnValues.Add(“weather_station”, dr[“weather_station”].ToString());

                        propertyLayer.EditTools.Add(propPolygon);
                    }
                }
                propertyLayer.EditTools.CommitTransaction();
                propertyLayer.Close();

                //Edgar’s code
                Feature feature = propertyLayer.InternalFeatures[0];
                propertyLayer.Open();
                propertyLayer.EditTools.BeginTransaction();
                foreach (var column in feature.ColumnValues)
                {
                    propertyLayer.Columns.Add(new FeatureSourceColumn(column.Key));
                }
                propertyLayer.EditTools.CommitTransaction();
                propertyLayer.Close();

                //Add the property Layer to the LayerOverlay
                dynamicOverlay.Layers.Add(“propertyLayer”, propertyLayer);
            }
            catch (Exception ex)
            {
                Logging.WriteLogToFile(loginId, ex);
            }
        }



Hi Chad,


I am afraid I was not as clear as I could have been with my previous reply. We need to add these columns both to your propertyLayer and to the Map1.EditOverlay. Below is your code with my addition:


private void CreatePropertyLayer()
        {

            try
            {
                //Define your InMemoryFeatureLayer and setup the columns you want at the Layer Level.

                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromArgb(180, 102, 255, 102), 10, GeoColor.StandardColors.Orange, 1);
                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Orange, 10, true);
                propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Transparent, GeoColor.StandardColors.Orange, 10, LineDashStyle.Dash);

                propertyLayer.DrawingQuality = DrawingQuality.HighSpeed;

                propertyLayer.Open();
                propertyLayer.Name = "PROPERTY";
                propertyLayer.Columns.Add(new FeatureSourceColumn("id"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("name"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("zip"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("acres"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("link"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("info"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("featureId"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("weather_station"));
                propertyLayer.Columns.Add(new FeatureSourceColumn("perm"));

                //Set the Style on how you wnat your Plots to be displayed and for only Zoomlevel 10 to 20
                //propertyLayer.ZoomLevelSet.ZoomLevel10.DefaultAreaStyle = AreaStyles.Crop1;
                propertyLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

                //Loop throuh your dataset returned from your database and add it to the Plots InMeoryFeaturelayer
                propertyLayer.EditTools.BeginTransaction();
                ////if the user has properties
                if (p.GetProperties())
                {
                    //create the properties layer
                    foreach (DataRow dr in p.dtProperties.Rows)
                    {
                        //Create Feature based upon Well Known Text you have stored in your database table
                        Feature propPolygon = new Feature(dr["property_wkt"].ToString());
                        //Set the field information for each plot polygon based upon what is stored in the database.
                        propPolygon.ColumnValues.Add("id", dr["property_id"].ToString());
                        propPolygon.ColumnValues.Add("name", dr["property_name"].ToString());
                        propPolygon.ColumnValues.Add("zip", dr["zip"].ToString());
                        propPolygon.ColumnValues.Add("acres", dr["property_acres"].ToString());
                        propPolygon.ColumnValues.Add("link", dr["property_link"].ToString());
                        propPolygon.ColumnValues.Add("info", dr["property_info"].ToString());
                        propPolygon.ColumnValues.Add("featureId", dr["feature_id"].ToString());
                        propPolygon.ColumnValues.Add("weather_station", dr["weather_station"].ToString());

                        propertyLayer.EditTools.Add(propPolygon);
                    }
                }
                propertyLayer.EditTools.CommitTransaction();
                propertyLayer.Close();

                //ThinkGeo's code
                //Loop through all the columns in your feature and add these
                //columns to the EditOverlay
                Feature feature = propertyLayer.InternalFeatures[0];
                Map1.EditOverlay.FeatureSource.Open();
                foreach (var column in feature.ColumnValues)
                {
                    Map1.EditOverlay.Columns.Add(new FeatureSourceColumn(column.Key));
                }
                

                //Add the property Layer to the LayerOverlay
                dynamicOverlay.Layers.Add("propertyLayer", propertyLayer);
            }
            catch (Exception ex)
            {
                Logging.WriteLogToFile(loginId, ex);
            }
        }
 
 



Hello everyone, 
  
 I want to add 2 extra columns in a InMemoryFeatureLayer in a controller and  also add values in all rows of those additional columns. 
 FeatureLayer shapeFileLayer = (FeatureLayer)((LayerOverlay)map.CustomOverlays[“StaticOverlay”]).Layers[“DivisionLayer”]; 
             InMemoryFeatureLayer mapShapeLayer = (InMemoryFeatureLayer)((LayerOverlay)map.CustomOverlays[“HightLightDynamicOverlay”]).Layers[“HighLightLayer2”]; 
             mapShapeLayer.IsVisible = true; 
             shapeFileLayer.Open(); 
             Collection features = shapeFileLayer.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns); 
             shapeFileLayer.Close(); 
             mapShapeLayer.InternalFeatures.Clear(); 
 //here i want to add all columns in shapeFileLayer to mapShapeLayer 
             foreach (Feature feature in features) 
             { 
                 mapShapeLayer.InternalFeatures.Add(feature.Id, feature); 
             } 
 //Now i want to add 2 extra columns and give them values from a database table. 
 //Don’t worry about data and its type I Just want to know how it can be possible. 
 If there is some way to add a temporary columns in shape file please give me its sample or code. 
 Thanks.

Hi Shehraz, 
  
 I have replied you in your another topic. 
  
 thinkgeo.com/forums/MapSuite/tabid/143/aft/13064/Default.aspx 
  
 Regards, 
  
 Don