ThinkGeo.com    |     Documentation    |     Premium Support

Update mssql feature layer edit mode

Good day i am able to load a mssql feature layer with geometry from my database on the map control. My question is how can i allow the user to update this geometry and save it back to the database? 



By looking at the samples it seems i can find a feature by looking at where the user clicked with something like the following



            worldLayer.Open();
            Collection<Feature> features = worldLayer.QueryTools.GetFeaturesContaining(e.Position, new string[1] { "CNTRY_NAME" });
            worldLayer.Close();



My understanding is that i can then add this feature to the editoverlay with something like the following



Map1.EditOverlay.Features.Add(features[0]);



Can anyone provide me with a code sample of how this can work together and save the updated polygon/feature back to the db?



any help would be greatly appreciated.







Hi Wilhelm,



Warm welcome to Map Suite Forums!

I guess the below codes should be fit for you:


protected void buttonSubmit_Click(object sender, EventArgs e)
        {
            LayerOverlay dynamicOverlay = (LayerOverlay)Map1.CustomOverlays[“DynamicOverlay”];
            MsSql2008FeatureLayer shapeLayer = (MsSql2008FeatureLayer)dynamicOverlay.Layers[“shapeLayer”];
 
            shapeLayer.FeatureSource.BeginTransaction();
            foreach (var item in Map1.EditOverlay.Features)
            {
                shapeLayer.FeatureSource.UpdateFeature(item);
            }
            shapeLayer.FeatureSource.CommitTransaction(); // those codes are used to save back to DB.
 
            Map1.EditOverlay.Features.Clear();
            Map1.EditOverlay.TrackMode = TrackMode.None;
            dynamicOverlay.Redraw();
        }
 
        protected void Map_Click(object sender, MapClickedEventArgs e)
        {
            LayerOverlay dynamicOverlay = (LayerOverlay)Map1.CustomOverlays[“DynamicOverlay”];
            MsSql2008FeatureLayer shapeLayer = (MsSql2008FeatureLayer)dynamicOverlay.Layers[“shapeLayer”];
            shapeLayer.Open();
            Collection features = shapeLayer.QueryTools.GetFeaturesContaining(e.Position, new string[1] { “CNTRY_NAME” });
            shapeLayer.Close();
 
            foreach (Feature feature in features)
            {
                Map1.EditOverlay.Features.Add(feature.Id, feature);
            }
 
            Map1.EditOverlay.TrackMode = TrackMode.Edit;
            dynamicOverlay.Redraw();
        }

If you have anything confused, don’t hesitate to let us know.

Hope it helps.



Thanks,

Troy

Hi troy thank you so much for the swift response. I am still trying to get this to work let me share more of my source here is my page load event




protected void Page_Load(object sender, EventArgs e)
       {
           if (!Page.IsPostBack)
           {
               Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
               Map1.CurrentExtent = new RectangleShape(-13939426.6371, 6701997.4056, -7812401.86, 2626987.386962);
               Map1.MapUnit = GeographyUnit.Meter;
 
               Map1.MapTools.OverlaySwitcher.Enabled = true;
               Map1.MapTools.MouseCoordinate.Enabled = true;
 
               GoogleOverlay google = new GoogleOverlay("Google Map");
               google.JavaScriptLibraryUri = new Uri(ConfigurationManager.AppSettings["GoogleUriV3"]);
               google.GoogleMapType = GoogleMapType.Normal;
 
               string connectString = "Data Source=xxx;Initial Catalog=xxx;User Id=xx;Password=xxxx;";
 
               MsSql2008FeatureLayer sql2008Layer = new MsSql2008FeatureLayer(connectString, "test""id");
               sql2008Layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
               sql2008Layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
               sql2008Layer.Srid = 4326;
 
 
               Proj4Projection proj4 = new Proj4Projection();
               proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
               proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
               sql2008Layer.FeatureSource.Projection = proj4;
 
               LayerOverlay shapeOverlay = new LayerOverlay("shapeLayer"false, TileType.SingleTile);
               shapeOverlay.Layers.Add(sql2008Layer);
               shapeOverlay.TransitionEffect = TransitionEffect.None;
 
      
 
 
               Map1.CustomOverlays.Add(google);
               Map1.CustomOverlays.Add(shapeOverlay);
 
 
           
     
           }
       }

and here is my map click event


protected void Map1_Click(object sender, MapClickedEventArgs e)
      {
          LayerOverlay dynamicOverlay = (LayerOverlay)Map1.CustomOverlays["shapeLayer"];
          MsSql2008FeatureLayer shapeLayer = (MsSql2008FeatureLayer)dynamicOverlay.Layers["sql2008Layer"];
          shapeLayer.Open();
          Collection<Feature> features = shapeLayer.QueryTools.GetFeaturesContaining(e.Position, new string[1] { "id" });
          shapeLayer.Close();
 
          foreach (Feature feature in features)
          {
              Map1.EditOverlay.Features.Add(feature.Id, feature);
          }
 
          Map1.EditOverlay.TrackMode = TrackMode.Edit;
          dynamicOverlay.Redraw();
 
 
      }

Currently im getting this error when i click a feature on the map:



"The given key was not present in the dictionary". On the second line of my map click event. Im guessing it cannot find the right layer to search.



Please could you help me correct this code? 

Best regards








Hi Wilhelm,  
  
 I checked the codes and found the key is missing when you add the layer into the LayerOverlay, please modify the codes in page_load event like the below: 
  
  
LayerOverlay shapeOverlay = new LayerOverlay(“shapeLayer”, false, TileType.SingleTile);
shapeOverlay.Layers.Add(“sql2008Layer”, sql2008Layer);
 
  
 If the issue persists, don’t be hesitate to let us know. 
 Thanks, 
 Troy

Thanks troy the changes you suggested worked like a charm. 



However i am still experiencing some issues with the editing.

What happens is i am able to select a feature and it then turns blue. However when i click a second time the polygon points flash quickly and then turns blue again. Sometimes if i am very quick i can select one of these points and it stays orange so that i can drag the points to where i want them but this is far from ideal.



How do i keep it in the orange edit state?



here is my current map click method for reference


protected void Map1_Click1(object sender, MapClickedEventArgs e)
{
 
 
 
        LayerOverlay dynamicOverlay = (LayerOverlay)Map1.CustomOverlays["shapeLayer"];
        MsSql2008FeatureLayer shapeLayer = (MsSql2008FeatureLayer)dynamicOverlay.Layers["sql2008Layer"];
        shapeLayer.Open();
        Collection<Feature> features = shapeLayer.QueryTools.GetFeaturesContaining(e.Position, new string[1] { "id" });
        shapeLayer.Close();
 
        foreach (Feature feature in features)
        {
            if (Map1.EditOverlay.Features.Contains(feature.Id) == true)
            {
 
            }
            else
            {
 
                Map1.EditOverlay.Features.Add(feature.Id, feature);
            }
 
        }
 
        Map1.EditOverlay.TrackMode = TrackMode.Edit;
        dynamicOverlay.Redraw();
 
   
 
 
}







The database update also works perfectly thanks.



Best Regards



Wilhelm





 

Hi Wilehlm,



I can recreate your issue, and the reason is we register the map click event for the map. That results that the edit click on the modified feature will be treat as a map click and then fire a map click post back on the server. So, the solution is we don’t allow the post back if the map is under the modify mode. Please try the below steps:



1. register a click event for the map in Page_Load event: 


Map1.OnClientClick = “CheckMapEditMode”;

2. add the scripts in header:


function CheckMapEditMode() {
    if (Map1.GetMapParser().editOverlay) {
        var modifyControl = Map1.GetMapParser().paintControls[“Modify”];
        if (modifyControl.active) {
            return false;
        }
    }
}

Hope it helps.

Thanks,

Troy