ThinkGeo.com    |     Documentation    |     Premium Support

Updating feature in inmemory layer does not change the feature's position

I have a WMS layer and an in-memory layer. The inmemory layer has a feature that displays in the center of the map. The location of this feature is updated every second (via a timer). I have followed the sample code to effectuate this (as you can see in the code snippet below). However, the icon representing the feature does not move on the map, even though the coordinates change.


How can I change the code to ensure the feature's updated position is displayed?



 



Feature gpsFeature = _featureLayer.InternalFeatures[GPS_KEY];PointShape pointShape = (PointShape)gpsFeature.GetShape();this._featureLayer.Open();this._featureLayer.EditTools.BeginTransaction();this._featureLayer.EditTools.Update(pointShape);this._featureLayer.EditTools.CommitTransaction();this._featureLayer.Close();

wpfMap1.Refresh();



gpsFeature.ColumnValues[LABEL_KEY_NAME] = labelText;


 


pointShape.X = longitude;


pointShape.Y = latitude;


pointShape.Id = GPS_KEY;


 


 


 


 


 



Gregory, 
  
 In the current version (3.0.362), you need to Lock an overlay before doing any changes with it, your code will be like  
  
 
            PointShape newPointShape = new PointShape(10, 30);
            
            // the "layerOverlay" holds the InMemoryLayer
            winformsMap1.Overlays["layerOverlay"].Lock.EnterWriteLock();
            _featureLayer.InternalFeatures[GPS_KEY] = new Feature(newPointShape);
            winformsMap1.Overlays["layerOverlay"].Lock.ExitWriteLock();

            winformsMap1.Refresh();
 
  
 Also by the way, you do not need to do the Begin/Commit Transaction to an InMemoryFeatureLayer, instead you can directly get/set the features within it.  
  
 In the upcoming version which will be available next Monday, there is another way to refresh an overlay "map.Refresh(overlay)", you can try that method also.  
  
 Let me know if you have any issues. 
  
 Thanks, 
  
 Ben 


Thanks, Ben - it works perfectly! Here’s what I did: 
  
  
         public void UpdateGpsMarker(double latitude, double longitude) 
         { 
             string labelText = String.Format(Properties.Resources.GpsLocationShortFormat, latitude, longitude); 
             PointShape pointShape = new PointShape(longitude, latitude); 
             pointShape.Id = GPS_KEY; 
             Feature gpsFeature = new Feature(pointShape); 
             gpsFeature.ColumnValues.Add(LABEL_KEY_NAME, labelText); 
             wpfMap1.Overlays[POINTS_OVERLAY].Lock.EnterWriteLock(); 
             if (_featureLayer.InternalFeatures.Contains(GPS_KEY)) 
             { 
                 _featureLayer.InternalFeatures[GPS_KEY] = gpsFeature; 
             } 
             else 
             { 
                 _featureLayer.InternalFeatures.Add(GPS_KEY, gpsFeature); 
             } 
             wpfMap1.Overlays[POINTS_OVERLAY].Lock.ExitWriteLock(); 
             wpfMap1.Overlays[POINTS_OVERLAY].Lock.IsDirty = true; 
  
  
 
  
 Now both the position and label of the GPS marker updates every timer tick.

Greg, 
  
   I am answering this for Ben. :-)  If your map is in Single threaded mode as per the ThreadingMode property on the Map control then you only need the IsDirtly line of code.  You do not need the locking part so that might save you some lines of code.  If you are using multi threading then you do need the locking and I suggest that you enter the write lock and then put the rest in a Try/Finally block and then put the ExitWriteLock in the finally area.  If you do this there is no need for the IsDirty line as behind the scenes the ExitWriteLock sets the IsDirty flag itself. 
  
 Glad this all worked out and let us know anything else you run into. 
  
 David