ThinkGeo.com    |     Documentation    |     Premium Support

Center a point in winformsMap

Hi


I have a point which represents a vehicle which i want to display in the center of the winformsMap. When I use winformsMap1.CenterAt(feature), it only "Moves the Center of MapControl CurrentExtent to the worldPoint."  I rotate the map in the direction in which the vehicle moves and the point(vehicle) gets re-displayed every time it changes position.  After a few displays, the layers and point does not display in the window anymore.


How do I center a point in the  winformsMap1? Or how do I get the currentExtent to display in the middle of the winformsMap? 


 Regards


Alta


 



I've just been working with the Map Suite Desktop Edition for a week, but I accomplished something like this with the following code: 



wpfMap1.MapUnit = GeographyUnit.DecimalDegree; 



// Map Layer representing the US 

ShapeFileFeatureLayer usLayer = new ShapeFileFeatureLayer(@"C:\Program Files\ThinkGeo\Map Suite Desktop Evaluation Edition 3.0 (BETA)\Samples\SampleData\Data\USStates.shp"); 

usLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1; 

usLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05; 



// Map Layer representing major US Cities 

ShapeFileFeatureLayer citiesLayer = new ShapeFileFeatureLayer(@"C:\Program Files\ThinkGeo\Map Suite Desktop Evaluation Edition 3.0 (BETA)\Samples\SampleData\Data\MajorCities.shp"); 

// Point & Text Style for Cities within Zoom Levels 1-5 

citiesLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.Capital3; 

citiesLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.Capital3("AREANAME"); 

citiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05; 



wpfMap1.StaticOverlay.Layers.Add("USLayer", usLayer); 

wpfMap1.StaticOverlay.Layers.Add("USCitiesLayer", citiesLayer); 

wpfMap1.CurrentExtent = new RectangleShape(-160, 45, 30, 26); 



// Change color of ocean. 

wpfMap1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean); 



// Center the display of the State on Morrow County. 

citiesLayer.FeatureSource.Open(); 

Collection<feature></feature> cityFeature = citiesLayer.FeatureSource.GetFeaturesByColumnValue("AREANAME", "Kansas City"); 

wpfMap1.ZoomIntoCenter(65, cityFeature[0]); 

citiesLayer.FeatureSource.Close(); 




wpfMap1.Refresh(); 



The "tricks" here are creating the RectangleShape with the "right" values and the Zoom Level, which is set to 65 here. I had to try a few different values before I got it to look right.  Try adjusting these two things and you might get what you want. This map displays the US map, overlayed with cities, and center's the display of the US on Kansas City. 



Nick



Nick, Thanks for sharing.  
  
 Alta, If you still have problem, can you let us know how you rotate the map? Maybe something we can improve there. 
  
 Thanks, 
  
 Ben

Thanks for the help Nick. It works, but my code is in a loop, so I cannot zoom in every time and I rotate the map every time depending on which direction the train is heading. It seems that the CurrentExtent gets most of the time centered at the point but it does not get centered in the middle of the winformsMap. The point to which i want to center spirals around on the map until it does not display on the map anymore. The point represents a train and each time i get new coordinates, i remove and re-display the train layer.


See the attachment for some screen shots

Here is some of my code: 


layerZone = New MapSuite.Core.ShapeFileFeatureLayer(fileName, ShapeFileReadWriteMode.ReadOnly) layerZone.Name = ZONE_LAYER TextStyle.TextColumnName = "ZONE_ID" TextStyle.Font = New GeoFont("Arial", 9) TextStyle.TextSolidBrush = New GeoSolidBrush(GeoColor.SimpleColors.Black) TextStyle.LabelAllPolygonParts = True layerZone.ZoomLevelSet.ZoomLevel04.DefaultTextStyle = TextStyle layerZone.ZoomLevelSet.ZoomLevel04.DefaultAreaStyle = New MapSuite.Core.AreaStyle(New MapSuite.Core.GeoPen(GeoColor.SimpleColors.Black, 2)) Dim transColor As New GeoSolidBrush(GeoColor.FromArgb(80, GeoColor.SimpleColors.PastelGreen)) 'make transparent layerZone.ZoomLevelSet.ZoomLevel04.DefaultAreaStyle.FillSolidBrush = transColor layerZone.ZoomLevelSet.ZoomLevel04.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 layerZone.FeatureSource.Projection = rotationProjection winformsMap1.StaticOverlay.Layers.Add(ZONE_LAYER, layerZone) 'get the area around the layer Dim tempLayer As ShapeFileFeatureLayer = DirectCast(winformsMap1.StaticOverlay.Layers(ZONE_LAYER), ShapeFileFeatureLayer) tempLayer.Open() extentLayer = tempLayer.GetBoundingBox If extentLayer.GetArea(GeographyUnit.DecimalDegree, AreaUnit.SquareKilometers) > extent.GetArea(GeographyUnit.DecimalDegree, AreaUnit.SquareKilometers) Then extent = extentLayer End If tempLayer.Close() winformsMap1.CurrentExtent = extent 'do this code repeatedly: 'setup the train layer as a point trainPoint = New MapSuite.Core.PointShape(vertexCollectionTrain.Item(0).X, vertexCollectionTrain.Item(0).Y) Feature = New MapSuite.Core.Feature(trainPoint, trainDictionary) trainLayer.InternalFeatures.Clear() trainLayer.Name = TRAIN_LAYER trainLayer.ZoomLevelSet.ZoomLevel04.DefaultPointStyle.PointType = PointType.Symbol trainLayer.ZoomLevelSet.ZoomLevel04.DefaultPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.StandardColors.Red), 8) trainLayer.ZoomLevelSet.ZoomLevel04.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 trainLayer.InternalFeatures.Add(TRAIN_LAYER, Feature) trainLayer.FeatureSource.Projection = rotationProjection winformsMap1.StaticOverlay.Layers.Add(TRAIN_LAYER, trainLayer) 'center the train on the map winformsMap1.CenterAt(Feature) 'winformsMap1.ZoomIntoCenter(10, feature) 'winformsMap1.ZoomOutToCenter(10, feature) 'rotate the map back to North rotationProjection.Angle = -lastAngle winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent) lastAngle = 0 'rotation of the map - heading of the train rotationProjection.Angle = angle winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent) lastAngle = angle 



518-Rotate_and_center2.docx (149 KB)

I will defer to the Pro, Ben. :) 
  
 Regards, 
 Nick




 


Alta,


I recreated your problem and I think that's a bug of rotation.  In fact that happened in one of your previous posts, please have a look.


gis.thinkgeo.com/Support/Dis...fault.aspx


We will solve it in the next version, sorry for the inconvenience.


Thanks,


Ben.




Thanks Ben! I’ll wait for the next version

Hope we can release it soon, we have already added many fancy stuff and I’m sure that will be a great version. :-)

Hi Ben, 
 Just to follow up, is the rotation now fixed and released? In which version is it, is it in SilverLight?  I really need this feaure now. 
 regards 
 Alta

Alta, 
  
 We want to get the next beta / release candidate out around the end of the month or early next month. We can send a temporary version to you so you can continue with your app. We will send it to you maybe tomorrow by email and please remember that’s just a temporary version and not well tested so may have some problems.  
  
 Thanks, 
  
 Ben

Hi Ben 
 I have just upgraded from the “special version” (DesktopEditionFull3.0.199 Beta 2 Fix) you gave me on 14 April,  to DesktopEditionFull3.0.362. 
  
 Then I had to use a LayerOverlay and I used winformsMap1.Overlays.Add to add that to the WinFormsMap. 
  
 The problem I had with CenterAt and rotation is back.  
  
 Could you please investigate? 


Alta,


In version 3.0.362, we introduce the lock system when you want to redraw some special overlay; I think you probably missed this point  :)
 
Try following code to see if it works:

private void btnRotate_Click(object sender, EventArgs e)
        {
            string version = WinformsMap.GetVersion();
            double degree = double.Parse(txtDegrees.Text);
            
            rotationProjection.Angle += degree;
            winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent);
            ((NorthArrowAdornmentLayer)(winformsMap1.AdornmentOverlay.Layers["northArrowAdornmentLayer"])).RotateAngle += (float)degree;

            winformsMap1.Overlays["layerOverlay"].Lock.EnterWriteLock();
            winformsMap1.Overlays["layerOverlay"].Lock.ExitWriteLock();

            winformsMap1.AdornmentOverlay.Lock.EnterWriteLock();
            winformsMap1.AdornmentOverlay.Lock.ExitWriteLock();
         
            winformsMap1.Refresh();
        }

 

Besides, just want to let you know we are now on the way of next public release in 2 weeks or so, and we will do some minor chages on its usage.
 
Any more questions please feel free to let me know.
 
Thanks.
 
Yale


No,sorry Yale, that did not help. There was a bug when you rotate the map in the previous version.  The point I want to center the map to, gets centered in the CurrentExtent but does not center in the WinFormsMap. The point then spirals away from the middle of the WinFormsMap each time I re-display it until it is "off the map"



Alta,


Could you try the sample attachment is what we are trying to accomplish?
 
Let me know if any more problems!
 
Thanks.
 
Yale

1133-NorthArrowDemo.zip (102 KB)

Yale, thanks for the example. The rotate works perfectly on its own. 
  
 Now, try to add a winformsMap1.CenterAt(x, y)  at the end of btnRotate_Click, with x and y any point on the map of USA, eg -122.416656 and 47.45087. 
 After a CenterAt, the USA is not visible on the map anymore. 
  
 Maybe the winformsMap1.CurrentExtent is not set correctly. 
 Please help me.

Alta,


I think we are making the same mistakesJ
 
There are two APIs:

public void CenterAt(PointShape worldPoint)
public void CenterAt(float screenX, float screenY)

 

so we should use the first API instead of the second one which takes the screen coordainte.

winformsMap1.CenterAt(new PointShape(-122.416656494141, .450870513916));

 
Any more questions please feel free to let me know.

Thanks.
 
Yale

Thanks Yale, but when I add a LineShape repeatedly, the rotate does not work anymore. 


I get a few GPS coordinates which I use to draw a line. That represents a train. Each 5 seconds I get the next set of coordinates and I must remove the lineShape and display the new one again and I must rotate the map according to the direction the train is heading and the loco must be in the center of the map.


I used the code you gave me (North Arrow Demo) and added the lineShape, rotate and CenterAt.


If I run the code without the line: c = c + 1, it works.


When I step through the code (debug), it works even if have the c=c+1 line in.


Please have a look at the code.



1137-Form1.cs (5.86 KB)

Alta,


I made some minor changed based on your sample, and hope it works.
 
Besides, the attachment contains a small test application to show the problem.
 
Any more questions please feel free to let me know.
 
Thanks.
 
Yale

1139-Post_5435_Demo.zip (23.4 KB)

Thanks Yale! 
 I will look at your code. 
  
 I have Desktop Edition 3.0.362 RC and it does not have MapFocusMode

The CurrentExtent does not change in version "DesktopEditionFull3.0.199 Beta 2 Fix" after a rotate and CenterAt. 
  
 Is Ben still there? Maybe he can remember the fix for this bug.