ThinkGeo.com    |     Documentation    |     Premium Support

Edit shape on Map Click event

Hi,


I am trying to edit shape on a map. The edit mode is trigger by single click on a shape. Then I display information about the shape and user can also moving the shape on the map.


Problem:


When user click on a shape, the shape is added to EditOverlay and related information is display on a datagrid. When user click on the shape again, it turns yellow (shape moving mode?), but it immediately turn back to blue. This is only the problem when I handle Map1_Click event. If I remove the Map1_Click event and just use the edit button like the one in the demo code, it works fine.


         protected void Map1_Click(object sender, MapClickedEventArgs e)

        {

            FeatureLayer featureLayer = (FeatureLayer)CrashOverlay.Layers[ddlFeatureLayer.SelectedItem.Text];

            if (!featureLayer.FeatureSource.IsOpen)

                featureLayer.FeatureSource.Open();

            Collection<feature></feature> selectedFeatures = featureLayer.QueryTools.GetFeaturesNearestTo(e.Position, GeographyUnit.Meter, 1,

                                                                  ReturningColumnsType.AllColumns);

            if (featureLayer.FeatureSource.IsOpen)

                featureLayer.FeatureSource.Close();

            

            foreach (Feature feature in selectedFeatures)

            {

                if(!(Map1.EditOverlay.Features.Count == 1 && Map1.EditOverlay.Features[0].Id == feature.Id))

                {

                    Map1.EditOverlay.Features.Clear();

                    Map1.EditOverlay.Features.Add(feature.Id, feature);

                    BindFeatureAttributes(feature);

                    Map1.EditOverlay.TrackMode = TrackMode.Edit;

                    break;

                }

            }

        }


any idea how to fix this?



Ching, 
  
 Thanks for your question.  
  
 So when the shape turns back to blue are you allowed to edit it? Is the only problem that it flashes yellow or does it now allow the user to edit the selected shape? 
  
 I’m sure we can come up with a solution but I want to make sure I understand what is happening and what you want it to do. 
  
 Thanks 
  


I am trying to drag that point to a different location on the map. It is only draggable when it is yellow (or may be it was orange).


I also want to mention that at one point out of like 20 tries, it stays yellow, and I was able to drag that point to different location and saved to the database.



Ching, 
  
 Can you provide a small self contained sample recreating the issue and list the steps to recreate it?  Once we have that we can easily debug it and provide a solution for the issue. 
  
 Thanks!

To reproduce this problem:


Open your C# VS2010 HowDoISamples solution.


Then Add following codes into DrawEditShapes.aspx.cs


        protected void Map1_Click(object sender, MapClickedEventArgs e)

        {

            if (Map1.EditOverlay.TrackMode != TrackMode.Edit)

            {

                var feature = GetSelectedFeature(e.Position);

                if (feature != new Feature())

                {

                    MakeFeatureEditable(feature);

                }

            }

        }


        private Feature GetSelectedFeature(PointShape ps)

        {

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

            InMemoryFeatureLayer featureLayer = (InMemoryFeatureLayer)dynamicOverlay.Layers["shapeLayer"];

            if (!featureLayer.FeatureSource.IsOpen)

                featureLayer.FeatureSource.Open();

            Collection<feature></feature> selectedFeatures = featureLayer.QueryTools.GetFeaturesNearestTo(ps, GeographyUnit.Meter,

                                                                                                1,

                                                                                                ReturningColumnsType.AllColumns);

            if (featureLayer.FeatureSource.IsOpen)

                featureLayer.FeatureSource.Close();

            return selectedFeatures.Count > 0 ? selectedFeatures[0] : new Feature();

        }


        private void MakeFeatureEditable(Feature feature)

        {

            if (!(Map1.EditOverlay.Features.Count == 1 && Map1.EditOverlay.Features[0].Id == feature.Id))

            {

                Map1.EditOverlay.Features.Clear();

                Map1.EditOverlay.Features.Add(feature.Id, feature);

                //BindFeatureAttributes(feature);

                Map1.EditOverlay.TrackMode = TrackMode.Edit;

                Map1.EditOverlay.EditSettings.IsDraggable = true;

            }

        }


Then wire up the Map1_Click event to the Map1 control.


Run the project, go to the DrawEditShapes page.


Put a few points on the map, click the "Save" button, then start clicking on a point.


It might work the first few times, but try to click away and click on the point again.


You will see the point just flash yellow instead of staying yellow.


 


Ching



Hi Ching, 
  
 Thanks for your post. 
  
 I have reproduce your problem follow your step. 
  
 I will try to make sure whether that’s a bug or code incorrect way, and find a solution for it. 
  
 Regards, 
  
 Don

Hi Ching,  
  
 I did some try but it looks your way cannot work well there. 
  
 There are two problems in your implement. 
  
 1. You need remove feature from InMemoryFeatureLayer when you move it to EditOverlay, and when save the change, move it back. 
  
 2. You add map click server side event for select one feature, but when you try to drag it, this event called again, and any change you did in client side covered by the status from server side. So you cannot make a server side event to select point and then drag it in client side. 
  
 So I think the solution should be try to implement that in client side, you can try to directly operate Openlayer’s feature in JS code. 
  
 Regards, 
  
 Don

Hi Don,


Thanks for the suggestion.


Your solution #1 doesn't work for us. We use SqlServer2008FeatureLayer, we cannot remove a feature then add it back. This will cause cascading deleting and the primary key will be different when add it back.


Your solution #2 doesn't work either. We need server side event click to get the attributes of that feature. We do not want to store the attributes on client side viewstate because the dataset will be huge.


Is there a way to do a single click to make the feature movable. Why do I have to click the feature and then click again to move the feature. I did tried to learn Openlayer JS code. I just thought this functionality is very common that someone might had already developed a solution.


Thanks,


Ching



Hi Ching, 
  
 Because your problem a little complex, so I talked with our developer and reply you the 2 items. They are not solution but just some description about how our EditOverlay works. 
  
 If you are using SqlServer2008FeatureLayer, then when you don’t change the mouse event etc., does the Edit things work well in your project?  Sorry I don’t have a Sqlserver here so I cannot have a quickly test. 
  
 I understand your requirement for the item 2. I did search but haven’t found related scenario before, our switch features to Edit mode directly call Openlayers related API, if you need change that to let customer can only select one feature and block server side update, I think the best solution is override related OpenLayers function and implement.  
  
 Sorry in post we mainly reply some common questions, your question should be hard and I think if you won’t find a solution from other topics you can try to contact your Rep for professional service. 
  
 Regards, 
  
 Don

hello, i’m a cameroonian student, I do my training at Orange Cameroon, my job is to create a map incorporating all subscribers. I try map suite and I get errors in my code: 
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
         WinformsMap1.MapUnit = GeographyUnit.DecimalDegree 
         ‘’ Set a proper extent for the Map.   
  
         WinformsMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.GeographicColors.Sand) 
  
         Dim worldMapKitDesktopOverlay As New WorldMapKitWmsDesktopOverlay() 
         WinformsMap1.Overlays.Add(worldMapKitDesktopOverlay) 
  
         Dim worldlayer As New ShapeFileFeatureLayer("…\Data_admin_SHP\cameroun\CAM.shp") 
         '// Set the worldLayer (carte du cameroun)with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.   
         worldlayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Orange, GeoColor.FromArgb(100, GeoColor.SimpleColors.Black)) 
  
         '// This setting will apply from ZoonLevel01 to ZoomLevel20, that means we can see the world the same style with ZoomLevel01 all the time no matter how far we zoom out/in.  
         worldlayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 
         worldlayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City4(“ADM2”) 
    Dim LayerOverlay As New LayerOverlay() 
  
         '// Add the shapefile layer to the layer overlay 
         LayerOverlay.Layers.Add(“wordlayer”, worldlayer) 
 '// We need to add the layer overlay to Map. 
         WinformsMap1.Overlays.Add(LayerOverlay) 
         worldlayer.Open() 
  
         AddHandler WinformsMap1.MapClick, AddressOf WinformsMap1_MapClick 
         WinformsMap1.CurrentExtent = New RectangleShape(-139.2, 92.4, 120.9, -93.2) 
         ''We now need to call the Refresh() method of the Map control so that the Map can redraw based on the data that has been provided. 
         WinformsMap1.Refresh() 
  Private Sub WinformsMap1_MapClick(ByVal sender As Object, ByVal e As MapClickWinformsMapEventArgs) 
         MsgBox(“on commence”) 
         Dim worldLayer As FeatureLayer = WinformsMap1.FindFeatureLayer(“worldlayer”) 
  
         Dim selectedFeatures As Collection(Of Feature) = worldLayer.QueryTools.GetFeaturesContaining(e.WorldLocation, New String(0) {“ADM2”}) 
         If selectedFeatures Is Nothing Then 
             MessageBox.Show(“aucune couche trouvée”) 
         End If 
         worldLayer.Close() 
         If selectedFeatures.Count > 0 Then 
             Dim text As String = "The country you selected is: " & selectedFeatures(0).ColumnValues(“ADM2”).Trim() 
             MessageBox.Show(text, “Note”, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, CType(0, MessageBoxOptions)) 
             System.Diagnostics.Debug.WriteLine(text) 
         End If 
         MessageBox.Show(“terminer”) 
     End Sub 
 this is the error “l’exception nullreference n’a pas été gérée” i don’t know why it is happening 
   

Hello Emmanuella,  
  
 Welcome to use map suite, sorry your exception message is French, so I guess the exception is “System.NullReferenceException was unhandled”? if not, could you please paste the English exception?  
  
 If so, this is an internal exception, it will caused by many reason, it’s hard to see which part was the root cause, is that possible you can provide a sample to us to recreate this problem?  
  
 Regards,  
  
 Gary