ThinkGeo.com    |     Documentation    |     Premium Support

Edit existing layer

Hi,


I was wondering if someone can help me regarding the editing of existing layers.  Here is my scenario: The user log into the system and use the map shapes to draw different shapes.  He saves this and log out.  Next time he logs in he wants to continue adding shapes and also remove or edit the existing shapes.  Do I edit a normal layer or do I still use the memorylayer? This is what I have tried to do:


I used the example that I received on creating shapes and saving to a shape file.  I've created a new shapefile and added a memory layer that allows the user to add shapes.  At the moment I have 3 shape files, Polygon, Point and Line and one memory layer.  On the save of the memory layer I check the type of the shape/feature and save to the relevant shapefile.


If  the user log in the next time I try and load the existing shapes into the memory layer and when he save again I recreate the shape file.  It does not work that well because I notice that the user has to be in editmode before he can add shapes to the existing memory layer.  If he is not in editmode then it seems that duplicated shapes are created or I loose some of the shapes when I save.


Any advise on how to edit existing layers? Do I have to use the InMemoryFeatureLayer or can I edit a normal ShapeFileFeatureLayer?


Thanks very much!


Sonja


 

 

 



Sonja, 
  
 You can save the features in Map.EditOverlay.Features to WKT first and save them to a file (or database whatever), when user login again you just retrieve those features from the WKT one by one. 
  
 Here is how to get a WKT from a feature 
 
Feature feature = new Feature();
Feature.GetWellKnownText();
 
 Here is how to create a feature from a WKT 
 <code lang="csharp"> 
 Feature feature = new Feature(“WKT”); 
 </code> 
 You can also save it to WKB (by calling GetWellKnownBinary()), that’s more efficient just need more work when save it to a file / retrieve it from a file because WKB itself is just a byte array. 
  
 You might also think about using Serialization. That works now but may bring some compatibility issue when we have new version. WCF will solve that versioning issue and we will implement this new way in the future versions. 
  
 Let me know for any queries. 
  
 Ben 


Thank you for your reply.  Is it possible that you can post more examples on your website? The API documention does not help.   
  
 Thanks

Sonja, 
  
 Here is the sample code for your scenario.  The save button simulates the process when a user logs out and the load button simulates the user logs in again.  
  
 
protected void buttonSave_Click(object sender, ImageClickEventArgs e)
        {
            StreamWriter sw = new StreamWriter(@"C:\wktforuser1.txt");

            foreach (Feature feature in Map1.EditOverlay.Features)
            {
                sw.WriteLine(feature.GetWellKnownText());
            }
           sw.Close();
            Map1.EditOverlay.Features.Clear();
            Map1.EditOverlay.TrackMode = TrackMode.None;
        }

        protected void buttonLoad_Click(object sender, ImageClickEventArgs e)
        {
            StreamReader sr = new StreamReader(@"C:\wktforuser1.txt");

            while (!sr.EndOfStream)
            {
                Map1.EditOverlay.Features.Add(new Feature(sr.ReadLine()));
            }
            sr.Close();
            Map1.EditOverlay.TrackMode = TrackMode.Edit;
        }
 
 Our online samples and API documentations might not provide you enough information; we will continually update and enrich them, they will be more helpful in the future. 
  
 Thanks, 
  
 Ben 


Thank you for your reply.  This is what I have done so far.  I've loaded my features into the EditOverlay and onSave I add features.  I will have to UpdateFeature and DeleteFeature when the user delete from the the layer or edit existing shapes.  I tried that but I can't seem to find a way to see if a feature exist.  I tried the GetByFeatureID but it does not seem to find the feature.  Am I on the right track or should I change my method completely.  This is my code:


In Page_Load I'm doing the following:



Map1.DynamicOverlay.Layers.Clear(); 
string strPolygonFile = MapPath("~/shapeFiles/polygon.shp"); 
InMemoryFeatureLayer memoryLayer = new InMemoryFeatureLayer(); memoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.FillSolidBrush.Color = GeoColor.FromArgb(100, GeoColor.StandardColors.Yellow); memoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color = GeoColor.StandardColors.Red; 
memoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; Map1.DynamicOverlay.Layers.Add("memoryLayer", memoryLayer); 

System.Collections.ObjectModel.Collection<dbfcolumn> dbfColumns = new System.Collections.ObjectModel.Collection<dbfcolumn>(); 
dbfColumns.Add(new DbfColumn("id", DbfColumnType.String, 256, 0)); dbfColumns.Add(new DbfColumn("feature", DbfColumnType.String, 10000, 0)); 
if (!File.Exists(strPolygonFile.ToString())) 
ShapeFileFeatureSource.CreateShapeFile(ShapeFileType.Polygon, strPolygonFile.ToString(), dbfColumns); 

ShapeFileFeatureLayer polygonLayer = new ShapeFileFeatureLayer(strPolygonFile.ToString()); polygonLayer.Open(); 

System.Collections.ObjectModel.Collection<feature> allPolygon = polygonLayer.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns); 
polygonLayer.Close();
foreach (Feature featurePolygon in allPolygon) 
{ Map1.EditOverlay.Features.Add(featurePolygon); } 


   



protected void btnSave_Click(object sender, EventArgs e) { 

string strFile = MapPath("~/shapeFiles/polygon.shp"); 
InMemoryFeatureLayer shapeLayer = (InMemoryFeatureLayer)Map1.DynamicOverlay.Layers["memoryLayer"]; 

foreach (Feature feature in Map1.EditOverlay.Features) 
{

shapeLayer.InternalFeatures.Add(feature.Id, feature); 
ShapeFileFeatureSource featureSource = new ShapeFileFeatureSource(strFile.ToString(), ShapeFileReadWriteMode.ReadWrite); 
featureSource.Open(); 
featureSource.BeginTransaction(); 
featureSource.AddFeature(feature); 
featureSource.CommitTransaction(); 
featureSource.Close(); 

}


   


The InMemoryFeatureLayer is most probably not necessary.  Thanks for any advice.


Sonja



Sonja, 
  
 I see, you are using shape files for storing the uncommented features. That’s fine. If the user cannot add any tabular data, I prefer converting it to WKT and save it to file. One reason is that is just one file, while shape file at least have 3 files (.shp, .shx and .dbf). The other reason is that’s pure data and very straightforward, the code will also be simpler, that is easy to debug. It’s just personal preference and sure using shape files provides you the possibilities for some advanced features, so I think both ways are fine. 
  
 About your code, yes, the InMemoryFeatureLayer in your codes seems unnecessary unless it is used in some place else. 
  
 Thanks, 
  
 Ben 


Hi, 
  
 Do you have any examples of the FeatureSource UpdateFeature and DeleteFeature functionality?  
  
 Thanks, 
 Sonja

Sonja, 


Here is a simple sample for you, please have a look.
 
Thanks,
 
Ben

410-5220.zip (7.67 KB)

Thanks for this, it does not really help me.   
  
 What is the limit on the number of shapes I can load into the editOverlay? I’m loading a couple of shapes and my system hangs.  I also get at times an “Unspecified error” when I try to edit my shapes.  I draw a simple line and get the error that it is not a valid shape.  I’m a bit frustrated at the moment, if I do it the one way I get an error, If I try a different approach I’m getting another error. 
  
  
 Thanks 


Sonja,


Just wonder are you using IE8? IE8 has some bugs which might cause those issues. See more info here:
connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=333905
 
If you are using IE8, remove the DocType (as following) on your aspx page may help you with these issues. If not, please send us a sample and we will find out what the problem is.
 DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
Thanks,
 
Ben

Hi, 
  
 No, I’m using IE7.  Another thing that is also slowing down my map is the Map1_ExtentChanged.  I’m displaying the current extent in a label so on the change of the extent I call e.CurrentScale.ToString() in the Map1_ExtentChanged procedure.  This slows down my map to a point where it seems that the map hangs when I zoom or pan and currently I only have 4 layers in my map.  If I take out the Map1_ExtentChanged procedure the map is much faster again and on zoom I can see something is happening.  I do need the extentChanged because I want to enable and disable layers that is not drawn.  I do use Ajax so I don’t know if this might cause a problem. 
  
 This is what I’m currently doing: 
  
 On the load of the page I load all my layers on my map.  This I read from an SQL server database that contains the layer names and the paths to the shapefiles. 
 I load the fillcolor, linecolor and default label for each layer from settings also found in the database. 
 I load the layer names in a checkboxlist.  Here the user can show or hide layers. 
 I also enable or disable the checkboxes of the layers that is not drawn on the map.  On the extent change I do this again.  This is where my map gets really slow.   
 I also allow the user to edit and add custom layers.  Here they can edit or delete existing shapes or add new shapes.  This is then saved to shapefiles and added as a layer on the map.  Here I sometimes get the “Unspecified error”. 
  
 Thanks, 
 Sonja    
  


Sonja,


ExtentChanged is a server-side event, whenever it is raised, it’ll do a postback which will sure slow down your application. Please try the client event instead which will greatly improve the performance.
 

// Server Side Code. Paste it to the PageLoad method of the aspx.cs file.
Map1.OnClientExtentChanged = "clientExtentChanged";



// Client Code, please paste it into the header tag block.
function clientExtentChanged() {
    var currentExtent = Map1.GetCurrentExtent();
    alert(currentExtent.toString());
}

 
GetCurrentExtent is one of our client APIs; please have a look at the following link for more Client APIs:
gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/20/aft/4902/afv/topic/Default.aspx
 
I see what your app does, the requirements are not odd and the implementation should be normal. I’m not sure where the “Unspecified error” comes from and I guess maybe it related with editing/saving the shape file.  Can you create a simple sample recreating this problem and send to us so we can have a further look here?  We have a couple posts in forum showing how to edit shape file, here is one for example, hope it helps. If your data is sensitive, you can send it to support@thinkgeo.com and ask to forward to Ben.
 
Thanks,
 
Ben