ThinkGeo.com    |     Documentation    |     Premium Support

Add Vertex to Existing Line Shape

I am experiencing a frustrating problem trying to add a vertex to an exiting line. My scenario is I am tracking a changing point coordinate and I want to create a bread crumb trail behind the moving point. I create a line with the first two points and then I attempt to simply append to that line. The approach I am using is lopping through this code as I add vertexes to a collection from coordinates obtained from my tracking point.:


Feature feat;

LineShape lineShape = null;

lineLayer.Open();

lineLayer.EditTools.BeginTransaction();


//get the feature and append vertex from last vertex collected in my vertex collection

feat = lineLayer.FeatureSource.GetFeatureById("mission",ReturningColumnsType.NoColumns);

lineShape = feat.GetShape() as LineShape;

lineShape.Vertices.Add(_vertexes.Last());


lineLayer.EditTools.CommitTransaction();

lineLayer.Close();


My initial  line shape is created from my first two vertexes. Then it loops this code to add additional vertexes. When I add the third vertex to lineShape, I can examine lineShape and see it has three vertexes. The problem is when it loops, derives a new lineSHape from the feature and trys to add the fourth vertex, lineShape only has two vertices again. What do I have to do to get lineShape to persist the added vertex in the feature? It has to be something simple I am missing. Any Help? Thanks.


Eric


 



Eric, 
  
 After the lineShape is updated, you also need to update it to the featureSource to commit the changes to lineLayer.  Another line of code is needed before committing transaction. 
  
 Here are some sample codes. You see there are 2 ways to implement it.  
 
            InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();

            inMemoryFeatureLayer.Open();
            inMemoryFeatureLayer.EditTools.BeginTransaction();
            inMemoryFeatureLayer.EditTools.Add(new Feature(1, 1, "id"));
            inMemoryFeatureLayer.EditTools.CommitTransaction();

            inMemoryFeatureLayer.EditTools.BeginTransaction();
            //get the feature and append vertex from last vertex collected in my vertex collection
            Feature feat = inMemoryFeatureLayer.FeatureSource.GetFeatureById("id", ReturningColumnsType.NoColumns);
            PointShape pointShape = feat.GetShape() as PointShape;
            pointShape.X = 2;
            Feature newFeature = new Feature(pointShape);
            inMemoryFeatureLayer.EditTools.Update(pointShape);

            inMemoryFeatureLayer.EditTools.CommitTransaction();
            inMemoryFeatureLayer.Close();
            // inMemoryFeatureLayer.InternalFeatures[0].GetWellKnownText() -> "POINT(2 1)"

           // ----------------------------------------------------
           // The other way, using InternalFeatures.
            InMemoryFeatureLayer inMemoryFeatureLayer2 = new InMemoryFeatureLayer();
            inMemoryFeatureLayer2.InternalFeatures.Add(new Feature(1, 1, "id"));
            //inMemoryFeatureLayer2.BuildIndex();

            //get the feature and append vertex from last vertex collected in my vertex collection
            Feature feat2 = inMemoryFeatureLayer.InternalFeatures["id"];
            PointShape pointShape2 = feat.GetShape() as PointShape;
            pointShape2.X = 2;
            Feature newFeature2 = new Feature(pointShape2);
            inMemoryFeatureLayer2.InternalFeatures["id"] = newFeature2;
            //inMemoryFeatureLayer2.BuildIndex();

            // inMemoryFeatureLayer2.InternalFeatures["id"].GetWellKnownText() -> "POINT(2 1)"
 
  
 For the 2nd way, you need to call inMemoryFeatureLayer2.BuildIndex() everytime a record is updated if the record count is large to get some performance benefit. 
  
 Thanks, 
  
 Ben 


Ben,


Thanks for  the info.  I believe there is a typo with the sample you provided.


Feature newFeature = new Feature(pointShape);

inMemoryFeatureLayer.EditTools.Update(pointShape);


should be


Feature newFeature = new Feature(pointShape);

inMemoryFeatureLayer.EditTools.Update(newFeature);


Creating a new feature and then updating the layer with this feature worked for me. I tried to simply update the shape but this did not work. Having to create a whole new feature seems a little much, but it works, which is the desired end result.


I did identify another problem I would classify as a Bug. The problem being adding a lineshape to a projected layer. In this case my output projection is GoggleMapParameterString. I have a list of vertexes that are tracked in decimal degrees. My layer.FeatureSource.Projection is set properly, But when I add the lineshape to the layer from the vertexes the lineshape is not projected. I have to actually project each vertex I add before creating or appending the lineShape.


Is this behavior intended. Why should I have to project my input coordinates if the layer has a defined projection. Shouldn't that happen on the fly? If not, what is the purpose of a layer having a projection if I have the overhead of managing it.


Any insight is appreciated.


Eric



Eric, 
  
 Update(poingShape) and Update(newFeature) are both fine and the results are both correct, but what I wanted to write is Update(newFeature), thanks for the reminder.  
  
 The projection property is for converting the row data from one projection to another, after setting this property, the row data would be transparent for us. For example, if the row data is WGS84 (4326) and we have a projection converting from 4326 to 9009123(Google Projection), that means the 4326 row data is transparent to us, we can just think the row data is in 900913 (although it is not) which means whatever data we get from the feature source, it is in 900913, whatever data we add to feature source, it should also be in 900913, although behind the scenes it will convert to 4326 and then write that projected data to the physical file, but from a user’s point, everything is in 900913. 
  
 Hope that makes sense and let me know if you have any issues. 
  
 Thanks, 
  
 Ben