How to add a feature to an exisiting feature set

Dec 10, 2011 at 2:14 AM

I struggled quite a bit to reliably add a feature to an exisiting feature set (read from a shape file). It was pretty straight forward adding/changing features to a feature set created from scratch using the example code provided in Tutorial 4, but that code doesn't work (at least not for me) when applied to a featureset that has been read from disk (e.g. as a shapefile). After going through all the posts on this topic the following code worked for me:

Note: I have only used this code for point features, I don't know if this will work for lines or polygons.



public void AddPointFeature(Coordinate coord, PointLayer layer)
    {
      layer.EditMode = true;
      var addedPoint = new Point(coord);
      var addedFeature = layer.DataSet.AddFeature(addedPoint);
      //Repeat this line for all attributes defined for this feature set
      addedFeature.DataRow["SOME_ATTRIBUTE"] = "Some value";
      layer.DataSet.InitializeVertices();
      layer.AssignFastDrawnStates();
      layer.EditMode = false;
      layer.DataSet.Save();
    }
After this you should call yourMap.ResetBuffer() to refresh the display

If you have labels defined for the layer you are editing then the labels should be defined as follows (and not using 'yourMap.AddLabels(...)), otherwise you will get a KeyNotFoundException (see http://dotspatial.codeplex.com/discussions/236609):

          labelLayer = new MaplabelLayer();
          layer.labelLayer = labelLayer;
          layer.ShowLabels = true;
          labelLayer.Symbolizer = new LabelSymbolizer {
            FontFamily = "Tahoma",
            FontColor = Color.Black,
            FontSize = 8,
            BackColor = Color.White,
            BackColorEnabled = true,
            BackColorOpacity = 0.5f
          };
          labelLayer.Symbology.Categories[0].Expression = "[SOME_ATTRIBUTE]";
          labelLayer.DynamicVisibilityWidth = 0.025;

Of course your symbolizer might be different and so for the expression on which the label is based as well as the dynamic visibility.

I hope this will be helpful to someone else, or some kind soul will explain what the incantations layer.EditMode = true; layer.DataSet.InitializeVertices(); layer.AssignFastDrawnStates(); actually do to make this work.

Also if there is something wrong with this method and it will fail horribly at some unspecified future point, I would be grateful if someone could point that out too.

Thank you.

Dec 27, 2011 at 8:19 PM
Edited Dec 27, 2011 at 8:34 PM

 I was copying the FeatureSet in memory  to solve this problem.  I think that your approach is much better..

 



 

 

Jan 17, 2012 at 1:39 PM

Thanks very much for your hint. I struggled with this simple concept (add new features to an existing shape file) all day, but still am not quite over the hump. Sometimes it feels like you are feeling around in the dark with this API.

When I reproduce your code, points are indeed added however none of the points are selectable. Putting the layer into editmode and back out screws it up somehow. If I remove and re-add the shape file, things apparently get reinitialized and selection works correctly then.

Thanks for your contribution.

Jan 17, 2012 at 2:58 PM

Loyd,

In the mean time I have changed my application to create this particular feature layer dynamically from a database and I no longer load it from a shape file and therefor no longer have the need to add features to an exisiting shape file. I do recall however having this problem of not being able to select a feature, in my case that turned out to be related to not having set a selection symbolyzer like so:

          category.SelectionSymbolizer = new PointSymbolizer(Color.Red, DotSpatial.Symbology.PointShape.Rectangle, 6);

for the particular layer symbology. In other words features were being selected, it is just that the display didn't change to show the selection because there was no selection symbolizer.

Regards

Kobus