ThinkGeo.com    |     Documentation    |     Premium Support

Moving icons on the layer

I have the following code and have not been able to find a way to move a Feature based on lat/long. The only method I can find is iconLayer.EditTools.TranslateByOffset but I want have to do this by lat/long.


The only way I could find to do it was to delete the feature and recreate it as follows.


Is there a better way to achieve this ?


 


Regards


 


 


Ewan


 


    Private Sub New_Raster_Position(ByVal Unit_Name As String, ByVal Unit_Operator As String, ByVal Lat As Double, ByVal Lon As Double, ByVal Speed As Double, ByVal Direction As Integer, ByVal Status As String)



        Dim IconPath As String = Get_GIS_Icon(Unit_Name)



        If System.IO.File.Exists(IconPath) = False Then

            IconPath = AppPath & "\icons\gis\base.png"

        End If



        gisMAP.Overlays("iconOverlay").Lock.EnterWriteLock()



        Try



            Dim myFeature As New Feature(Lon, Lat, Unit_Name)

            myFeature.ColumnValues.Add("Unit_Name", Unit_Name)



            Dim iconLayer As InMemoryFeatureLayer = DirectCast(gisMAP.FindFeatureLayer("iconLayer"), InMemoryFeatureLayer)

            iconLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.Image = New GeoImage(IconPath)



            iconLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City1("Unit_Name")

            iconLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20



            If Not iconLayer.InternalFeatures.Contains(Unit_Name) Then

                iconLayer.InternalFeatures.Add(Unit_Name, myFeature)

            Else

                iconLayer.Open()

                iconLayer.EditTools.BeginTransaction()

                iconLayer.EditTools.Delete(Unit_Name)

                iconLayer.EditTools.CommitTransaction()

                iconLayer.Close()

                iconLayer.InternalFeatures.Add(Unit_Name, myFeature)

            End If



        Finally

            gisMAP.Overlays("iconOverlay").Lock.ExitWriteLock()

        End Try

        gisMAP.Refresh()



    End Sub


 


 


 



Ewan,


You are basically right!
 
While a better way for this is using update the feature instead of Delete & Add new feature again and again.
 
Following is the code you can take a reference:

Private Sub New_Raster_Position(ByVal Unit_Name As String, ByVal Unit_Operator As String, ByVal Lat As Double, ByVal Lon As Double, ByVal Speed As Double, ByVal Direction As Integer, ByVal Status As String)

            Dim IconPath As String = "..\..\SampleData\Data\United States.png"

            winformsMap1.Overlays("iconOverlay").Lock.EnterWriteLock()
            Try

                Dim myFeature As New Feature(Lon, Lat, Unit_Name)
                myFeature.ColumnValues.Add("Unit_Name", Unit_Name)

                Dim iconLayer As InMemoryFeatureLayer = DirectCast(winformsMap1.FindFeatureLayer("iconLayer"), InMemoryFeatureLayer)
                iconLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.Image = New GeoImage(IconPath)

                iconLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City1("Unit_Name")
                iconLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

                If Not iconLayer.InternalFeatures.Contains(Unit_Name) Then
                    iconLayer.InternalFeatures.Add(Unit_Name, myFeature)
                Else
                    iconLayer.Open()
                    iconLayer.EditTools.BeginTransaction()
                    'iconLayer.EditTools.Delete(Unit_Name)
                    iconLayer.EditTools.Update(myFeature)
                    iconLayer.EditTools.CommitTransaction()
                    iconLayer.Close()
                    'iconLayer.InternalFeatures.Add(Unit_Name, myFeature)
                End If

            Finally
                winformsMap1.Overlays("iconOverlay").Lock.ExitWriteLock()
            End Try
            winformsMap1.Refresh()

        End Sub

 

Any more questions just let me know.
 
Thanks.
 
Yale


Thanks - but I found a problem after the post that when I add a second icon the code changes all of the icon images in the layer.

Ewan, 
  
 I am not very clear with your later problem. 
  
 All the features in the layer should share the same icon, we cannot support each feature using each different Icon, if you want to do this, you probably need to try some other kinds of styles like IconValueStyle  ,ClassBreakStyle, ValueStyle etc. 
  
 Let me know if you still have problems. 
  
 Thanks. 
  
 Yale 


I am essentially trying to do the same thing. I want to move some icons on the map. This approach worked for me with the default threading on the map, but when using multithreaded mapping, the icons flash on the screen. I need to have the icons update without flashing. Right now, I am only displaying 2 icons (2 layers).


 


Any suggestions to fix my problem? Am I supposed to put moving icons in a custom layer or trackshapelayer? I see examples in custom layers.


 


Some observations:


Icons flash in a custom layer when in multithreaded map. I created a separate layer for each icon type.


Icons do not flash when placed in the TrackShapeLayer.  This won't do becuase I need multiple icons of different types.


When in the default threading map. I had to thread out the icon updating because of performance issues. In the multithreading map, I was able to update the icons in the main thread.



Greg, 
  
 The default threading is the single threading mode, it probably behave some differently with multi-threading mode. 
  
 Can you show me the code to redraw your to icon layers? And when do you refresh them? It would be nice if you could send me a small sample application to recreate this problem?  
  
 Thanks. 
  
 Yale 


Yale,


Here is a sample project. I have two icons loaded with their respective routes displayed. I have the map set to multithread, with all settings optimized for speed. I have a form timer set at 500 ms updating the icons to move up their paths.


The icons flash pretty bad on the updates. 


 


Thanks for looking into this!!



1724-MovingIcons.zip (35.1 KB)

I have made some progress on this. I had assumed that executing the Map.Refresh(iconOverlay) command for the overlays would have been for better performance. I am now instead executing a single Map.Refresh() on the whole map in the form timer1_Tick function.


 


I'd still like to know what the preferred method is for doing this. I'm a little worried about performance when I put more icons on the map. 


 


I am also seeing some issues when I display imagery with the icons. The imagery and the icons will go away when I pan and zoom.



Greg,


 
I read the code carefully, and found that the performance issue would be very serious when you add more icons to it, because for each icon, you create an overlay for it, then you have to call refresh multiple times for multiple icons.
 
My suggestion is for all icons we should keep it in the same overlay. If do not want to use MapShape(code.thinkgeo.com/projects/show/mapshapes), we could create an inmemoryFeatureLayer for each icon. In this way, we only need to refresh one overlay per timer tick.
 
I have re-write the sample, please take a look at the attachment and have a try, hope this performance can satisfy your requirement. I have change the reference and path file names.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

1731-Update_MovingIcons_20100204.zip (25.7 KB)

Yale, 
 Thanks for the update. Loading multiple layers into the overlays is something I didn’t consider before. 
  
 However, you did change the threading from multi to single. I need to have the multithreading available. Is the multithreading just not ready for use yet? 
  
  I also noticed that you were calling the deprecated functions and calling new Feature instead of the UpdateFeature function. I also noticed that you were cashing the tiles. 
  
 Thanks, 
 Greg

Greg,  
  
 Yes, I did those changes. Those changes are the suggested way when you want to update one of the Overlays in the MapControl. 
  
 About the deprecated functions, we have removed the deprecated obsolete information because of so many complain about it. 
  
 About the Multi-threaded mode, I think when you updating one overlay , it will cause the flashing problem, and if you call Refresh instead, I doubt it will cause some performance problem. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Is there any way to update an icon in multitread mode without the flashing?

 


Greg,
 
Let me jump in and see if I can help. I think Yale will give you more exact answer for your questions.
 
As my testing, if you remove the static overlay, just keep dynamic overlay and track overlay, it won’t flashing.
 
Or keep all overlays, remove the tile cache for static overlay, call winformsMap1.Refresh(); instead of winformsMap1.Refresh(winformsMap1.Overlays["DynamicOverlay"]); when the timertick, it won’t flashing.
 
I can not found any other way to avoid flashing when Multithreaded mode.
 
James

James, Thanks for your help. Greg, In multi-threaded mode, I do not think there is a ideal way when you only update one of the overlays in map control.  
  
 Thanks. 
  
 Yale