ThinkGeo.com    |     Documentation    |     Premium Support

Slow perfomance dragging vertices

Hi,


I am evaluating Map Suite Desktop as a potential replacement for MapObjects.  I was pleasantly surprised to see how easy it was to add a shape to the EditOverlay and enable the editing of vertices by clicking and dragging them to a new position.  This was something I had to code manually in our current application.


However, I have noticed that even when I add only one polygon shape to the EditOverlay, clicking and dragging the vertices is very sluggish.  I am practicing on a shapefile of the United States.  When just one state (Alabama) is added to the EditOverlay vertex dragging is somewhat sluggish and jerky.  If even one additional state is added to the EditOverlay performance degrades to the point of being unusable.


I know there must be a way to optimize this functionality to make it usable, but I haven't seen anything yet in the forums.  Any suggestions?


Thanks,


Steve


 



 It should not be sluggish and jerky by clicking and dragging vertices of a polygon in the EditOverlay. I think you have something in your code causing some ineficiency. I recommend that you send us as an attachment a self contained sample app that shows the problem and we should be able to correct that.


Also, did you check the projects in the Code Community? We have several projects on that theme, EditOverlay, Dragging vertices etc.


For example, I think those projects below are pretty close to the tasks you are tring to implement:


Editing Rectanglescode.thinkgeo.com/projects/show/editingrectangles


Snapping to Vertexcode.thinkgeo.com/projects/show/snappingtovertex


Vertex Tolerancecode.thinkgeo.com/projects/show/vertextolerance



Steven, 
  
   Which shapefile are you using, I mean is it one that we ship with?  I would like to try that out and see if we can re-create it.  As an aside what resolution are you running at? 
  
 David

Hi David, Val


The states shapefile I am experimenting is the one that comes with the Map Suite sample data.  Here is how I am adding a shape to the EditOverlay for editing:



Private Sub AddShapeForEditing(ByVal oPoint As PointShape)
      Dim oFeatureLayer As FeatureLayer
      Dim oFeatures As Collection(Of Feature)

      oFeatureLayer = WinformsMap1.FindFeatureLayer("StatesShp")
      oFeatures = oFeatureLayer.QueryTools.GetFeaturesContaining(oPoint, ReturningColumnsType.AllColumns)

      With WinformsMap1.EditOverlay
         .EditShapesLayer.Open()
         .EditShapesLayer.EditTools.BeginTransaction()
         .EditShapesLayer.InternalFeatures.Clear()
         If oFeatures.Count > 0 Then
            .EditShapesLayer.EditTools.Add(oFeatures(0))
         End If
         .EditShapesLayer.EditTools.CommitTransaction()
         .EditShapesLayer.Close()
         .CalculateAllControlPoints()
      End With
      WinformsMap1.Refresh(WinformsMap1.EditOverlay)

   End Sub

And here is the code that I use to set up the EditOverlay:



         With WinformsMap1.EditOverlay
            .EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.SimpleColors.Blue, 1)
            .EditShapesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
            .CanAddVertex = True
            .CanDrag = False
            .CanRotate = False
            .CanRemoveVertex = True
            .CanReshape = True
            .CanResize = False
         End With


 I'm not sure what you mean by 'resolution'.  Are you talking about my screen resolution or some setting on the WinFormsMap?


Thanks!


Steve



Steven,


Thanks for your post and code sample.


Yes, as you already have noticed, it becomes very slow when we try to edit a very large feature. Following 2 ways will give some enhancement, and we are still doing more performance profiling now, hope we can make it as fast as we need.


1.Solution1, Build Index for the InmemoryFeatureLayer.

2.Change the style after removing the customized style.



With winformsMap1.EditOverlay
    .EditShapesLayer.Open()
    .EditShapesLayer.EditTools.BeginTransaction()
    .EditShapesLayer.InternalFeatures.Clear()
    .EditShapesLayer.EditTools.Add(feature)
    Dim result As TransactionResult = .EditShapesLayer.EditTools.CommitTransaction()
    .EditShapesLayer.BuildIndex()
    .EditShapesLayer.Close()
    .CalculateAllControlPoints()
    'Add Index build here.
    .ExistingControlPointsLayer.BuildIndex()
    '.ExistingControlPointsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear()
    '.ExistingControlPointsLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.SimpleColors.Black, 2)
End With

Any more questions just feel free to let me know.


Thanks.


Yale

 



Yale,


Thanks for the suggestions.  I tried rebuilding the index on the ExistingControlPointsLayer.  Motion when dragging a vertex the is smoother with the index.  However, every time I release the vertex from dragging an error is generated. Here is the stack trace:


System.Collections.Generic.KeyNotFoundException was unhandled

  Message=The given key was not present in the dictionary.

  Source=mscorlib

  StackTrace:

       at System.ThrowHelper.ThrowKeyNotFoundException()

       at System.Collections.Generic.Dictionary`2.get_Item(TKey key)

       at ThinkGeo.MapSuite.Core.GeoCollection`1.get_Item(String key)

       at ThinkGeo.MapSuite.Core.InMemoryFeatureSource.GetFeaturesBasedOnCachedBoundingBoxes(RectangleShape extent, IEnumerable`1 returningColumnNames)

       at ThinkGeo.MapSuite.Core.InMemoryFeatureSource.GetFeaturesInsideBoundingBoxCore(RectangleShape boundingBox, IEnumerable`1 returningColumnNames)

       at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawingCore(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

       at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesForDrawing(RectangleShape boundingBox, Double screenWidth, Double screenHeight, IEnumerable`1 returningColumnNames)

       at ThinkGeo.MapSuite.Core.FeatureLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

       at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

       at ThinkGeo.MapSuite.DesktopEdition.EditInteractiveOverlay.DrawCore(GeoCanvas canvas)

       at ThinkGeo.MapSuite.DesktopEdition.Overlay.MainDraw(GeoCanvas canvas)

       at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x742ba885258f6c2c(RectangleShape xb35a33b423b17f65, Overlay x99251f66cdabc2ad, Int32 xa209325f5c895f7e, Int32 x7454a0d1965919b1, GeographyUnit xbb704b4400ce6f76)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x88c2a2d6d754e692(IEnumerable`1 xa6f0db4f183189f1)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xe3cee4adb9c72451()

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x9ac8c50f434f4b39(Int32 xb565f4681f05557a)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x4eb49068e137ed8f(InteractionArguments x195facd4ef5d753d)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xfeca3317d3c75bbb(Object xd9272088e65bd176, x6a8380ab1a7ebb4c xc2fd4c0ed406cdb7)

       at ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.OnMouseEvent(x6a8380ab1a7ebb4c e)

       at ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.AnalyseMouseUp(Double screenX, Double screenY, Double worldX, Double worldY, MapMouseButton mouseButton)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xd1e58e0ca2447b93(Object xd9272088e65bd176, MouseEventArgs xc2fd4c0ed406cdb7)

       at System.Windows.Forms.MouseEventHandler.Invoke(Object sender, MouseEventArgs e)

       at System.Windows.Forms.Control.OnMouseUp(MouseEventArgs e)

       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

       at System.Windows.Forms.Control.WndProc(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.Run(ApplicationContext context)

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)

       at MapTutorial.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81

       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)

       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       at System.Threading.ThreadHelper.ThreadStart()

  InnerException:


Maybe you can shed some light on what's going on there.


As for the 2nd tip:

2.Change the style after removing the customized style.


Are you saying to clear whatever the existing style is and set a new one?  Is this instead of or in addition to building the index?  And why does clearing and re-defining the style cause a performance boost?


Thanks!


Steve


 




 


 



Steven,


Thanks for your feedback and reporting. I have fixed this issue and make the ExistingControlPointsLayer indexed automatically when the control points was generated. So please ignore this statement anymore and it will be available in next version (4.0.64.0), please get it and have a try.
 
Also, I attached a sample for easy to test, you may need to change the data location according to your package installation path and reference the DLLs needed to run it.
 
You may found that the performance will be enhanced by change the style for the control point layer that is because we use a simple PointStyle instead of ValueStyle which is more time consuming.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Post7760.zip (15.1 KB)

Yale,


Thanks very much for your response.  With the new build the performance when dragging vertices is much imporoved.  It's still not as smooth and responsive as I would like, but for now it seems usable.  Also, I see what you mean by using the simpler symbols for control points.  Using simpler symbols results in a small performance gain.


However, once I hit the button and the control points become visible I want to zoom in on a particular state.  So I hold down the shift key to create a track rectangle but once I drag with the mouse it takes a very very long time for the rectangle to draw.  In fact, it takes too long to be usable.  Is there a way to speed that up?


Thanks again!


Steve


 


 



Steven, 
  
   We are working on the performance issues around editing.  The fundamental issue is that as you click and then drag we need to find out if you are clicking on a control point.  If not then we hand the event over to the track rectangle, but we always have to do the check.  When you are editing features with thousands or tens of thousands of vertices then that process takes some time.  Actually we have some good ideas on how to cut that time we are just trying them out out now.  You will see some good progress on this over the next few days. 
  
   An unrelated thing regarding the styles is that we should consider limited the scales at which people can edit depending on their feature.  I mean if you want to edit the US and you are at a scale where it displays all 10,000 points of the US then editing is not really very useful except for maybe rotating, scaling etc but not point manipulations as the points are too close together.  We need to figure out some way to limit this and try to avoid the absurd situations where editing is not feasible.  Maybe we start showing the control points once the density of the control points is below a certain number on the screen, say 1,000.  In any event this is just a side issue. 
  
   One other think I was just thinking about would be if a rectangular control point would draw faster than a circle.  From many of our performance tests much of the time is spent in drawing of the ellipse and I think filling a rectangle is going to be faster.  Anyway just something we will check out as well. 
  
 David

Yes. Filling a rectangle is faster.


Edit... but the circles are aesthetically more pleasant for the end user, if you don't have to draw thousands of them.



David, 



I had to manually implement the clicking and dragging of vertices in our current application so believe me, I feel your pain.  However, in our application we know BEFORE the mouse down event whether we are tracking a rectangle or searching for a node (control point).  In addition we only try to draw control points within the current extent of the map, so even if the user is trying to display control points on 1000 features the only ones that draw are the ones in the visible extent.  I'm sure you're way ahead of me. 



Cheers, 



Steve



Steve, 
  
    We should have some more performance enhancements out very soon.  We are making very good progress, I think you will be very pleased. :-) 
  
 David

Ted, 
  
   Thanks for the confirmation, I was pretty sure of that.  I am also certain if we change the circles to rectangles there will be a public outcry…  :-)  I think we may try it anyway for the development release and see if we can get the time down.  Actually though wit the latest round of enhancements the editing is lightning fast so I think the rectangle stuff may be a moot point. 
  
 David

Steven & Ted, thanks for your sharing and feedback. 
  
 We are definitely making progress, please get the latest version(4.0.66.0) to see its enhancement. We will continue paly more around with it. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


David, Yale, 
  
 I just tried the 4.0.66.0 version and can see that it is even smoother and more responsive that the previous one I was using.  Also, the track rectangle is much smoother and more responsive when control points are visible.  Keep up the good work! 
  
 Steve 
  


Ditto.   Thank you very much for the improvements in this area.    They really make a difference in the user’s perception of our entire application.

Steven & Ted,


Thanks for your enouncement and contributions, I appreciate it very much.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale