ThinkGeo.com    |     Documentation    |     Premium Support

How set initial map extent

How do I set an initial map extent? In the getting started sample the CurrentExtent is set to a RectangleShape. Is there a way to determine this from my shape layer?


I am trying to display a single line layer but nothing is being displayed. I have copied code from the getting started app and changed a few lines to suit my line style. I don't know the initial erxtent to set. I'm sure V2 used to automatically work out the best extent to set intially?


What am I doing wrong?


I can send the shape file if required. It worked fine under V2 and loads in map explorer. Here is my code.




            winformsMap1.MapUnit = GeographyUnit.Meter;

            ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"D:\KernMobileGisData\MoretonBay V3\Assets\MBRC_Roadcentreline.shp");

            worldLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway1;

            worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay layerOverlay = new LayerOverlay();

            layerOverlay.Layers.Add(worldLayer);

            winformsMap1.Overlays.Add(layerOverlay);

            winformsMap1.Refresh();


Thanks. Steve



Steve,


Thanks for your post and questions.
 
There is minor difference between V2 and V3, the V3 will not automatically adjust the map control extent.
 
First, are you sure your data is in meter instead of DeciamlDegree? If so, try to add following code before refresh to set your extent:

 

worldLayer.Open();
winformsMap1.CurrentExtent = worldLayer.GetBoundingBox();
worldLayer.Close();


Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Hi Yale 
  
 Definitely Meter. 
  
 I tried GetBoundingBox but had not Opened the layer first. 
  
 Works great thanks. 


Steve, 
  
 Glad to let me know your status. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Hi, 
  
 and is there a way to simulate the same behavior than with version 2.0 (show the whole map at the opening) ? 
  
 Thanks. 
 EG

You can use the function GetFullExtent I created. It will get the extent of all the layers you pass as you can see in the example below:


 



 winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
            winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            ShapeFileFeatureLayer streetLayer = new ShapeFileFeatureLayer(@"..\..\Data\streets.shp");
            streetLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.LocalRoad1;
            streetLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            ShapeFileFeatureLayer pointLayer = new ShapeFileFeatureLayer(@"..\..\Data\points.shp");
            pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City6;
            pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay overlay = new LayerOverlay();
            overlay.Layers.Add("Street", streetLayer);
            overlay.Layers.Add("Point", pointLayer);
            winformsMap1.Overlays.Add("Overlay", overlay);

            streetLayer.Open();
            winformsMap1.CurrentExtent = GetFullExtent(overlay.Layers); 
            streetLayer.Close();

            winformsMap1.Refresh();

  private RectangleShape GetFullExtent(GeoCollection<Layer> Layers)
         {

             Collection<BaseShape> rectangleShapes = new Collection<BaseShape>();
           
            foreach (Layer layer in Layers)
            {
                layer.Open();
                rectangleShapes.Add(layer.GetBoundingBox());
            }

            return ExtentHelper.GetBoundingBoxOfItems(rectangleShapes);
         }


Thank you Val for this function. 



First I tried with GetBoundingBox(); on a single layer, and the map is too zoom in (just a part is shown). 

I tried your function but the result is the same. 



If I compare the CurrentExtent of my layer with the release 2.0 : 

Release 2.0 : Height=4566... Width=5052... (default Extent, because I don't set CurrentExtent, and all the map is shown) 

Release 3.0 : Height=694... Width= 1196...  (returned by GetBoundingBox or your function --> too zoom in)



Is this the problem? 

 



Eric,


I think Val’ suggestion is correct, I doubt there are some problems in your shape file data recording its bounding boxes, while it is wield that in V2 it is correct.
 
How many layers are you trying to use? Could you debug out all their bounding boxes as well as the currentExtent for the MapControl to double check their ranges?


private RectangleShape GetFullExtent(GeoCollection<Layer> Layers)
        {
 
            Collection<BaseShape> rectangleShapes = new Collection<BaseShape>();
 
            foreach (Layer layer in Layers)
            {
                layer.Open();
                RectangleShape boundingBox = layer.GetBoundingBox();
                System.Diagnostics.Debug.WriteLine(boundingBox.ToString());
 
                rectangleShapes.Add(boundingBox);
            }
 
            return ExtentHelper.GetBoundingBoxOfItems(rectangleShapes);
        }

 
Besides, we have the Default Full extent in the Map Suite Explorer, could you have a try on that against your data?
 
Thanks.


Yale

Hi Yale,


Thank you for your help.


To isolate the problem, I tested a simple program with a single layer.


Here are the debug BoundingBoxes :


 



V3
Layer 'Sections' GetBoundingBox = 734038.15,200341.63,739113.83,195432.97
Layer 'Sections'                = 734038.15,200341.63,739113.83,195432.97
GetFullExtent return            = 734038.15,200341.63,739113.83,195432.97
winformsMap1.CurrentExtent      = 735977.630625,198234.64375,737174.349375,197539.95625


V2 (Map.CurrentExtent.ToString --> "MapSuite.Geometry.RectangleR")
?Map.CurrentExtent.UpperLeftPoint
{MapSuite.Geometry.PointR}
    X: 733860.18174334138
    Y: 200341.63
?Map.CurrentExtent.LowerRightPoint
{MapSuite.Geometry.PointR}
    X: 739291.7982566586
    Y: 195432.96999999997


MapSuiteExplorer works in V3 and V2 (see attachment MapSuiteExplorer)


This is the code I try in V3, maybe I miss something ?



  Dim layer As New ShapeFileFeatureLayer("P:\Maps\SECTION.shp")
        layer.Name = "Sections"
        layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1
        layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

        layer.Open()
        System.Diagnostics.Debug.WriteLine("Layer '" & layer.Name & "' GetBoundingBox = " & layer.GetBoundingBox.ToString())
        layer.Close()

        Dim overlay As LayerOverlay = New LayerOverlay()
        overlay.Layers.Add("SECTIONS", layer)

        winformsMap1.Overlays.Add("OVERLAY", overlay)

        Layer.Open()
        winformsMap1.CurrentExtent = GetFullExtent(overlay.Layers)
        System.Diagnostics.Debug.WriteLine("winformsMap1.CurrentExtent = " & winformsMap1.CurrentExtent.ToString())
        Layer.Close()

        winformsMap1.Refresh()

... and in attachment the map shown (layerV3_GetBoundingBox)


MapSuiteDesktop 3.0.0.0 (3.1.299)



 


Eric,
 
Thanks for your reply and clear explanations. I think the problem lies in the CurrentExtent Set to the winformsMap1 is not correct.
 
Try to set a definite value for the extent, it should works.

winformsMap1.CurrentExtent = new RectangleShape(734038.15, 200341.63, 739113.83, 195432.97);

 
So, one possible reason is that the Function ExtentHelper.GetBoundingBoxOfItems did not return back a correct Rectangle Shape? I tested the following code, and the returning rectangleShape is exactly the same with baseShape.


BaseShape baseShape = new RectangleShape(734038.15, 200341.63, 739113.83, 195432.97);
Collection<BaseShape> rectangleShapes = new Collection<BaseShape>();
rectangleShapes.Add(baseShape);

RectangleShape rectangleShape = ExtentHelper.GetBoundingBoxOfItems(rectangleShapes);

 
Then, I think the problem is in setting the CurrenExtent for winformsMap. What is the width and height for your MapControl? It is obvious not right there is huge difference between the extent you set with the final result extent of the MapControl.
 
Thanks.
 
Yale

Yale, I agree with you. I can't set the CurrenExtent for winformsMap:


- values from the layer itself : winformsMap1.CurrentExtent = layer.GetBoundingBox


- or specific values : winformsMap1.CurrentExtent = New RectangleShape(734038.15, 200341.63, 739113.83, 195432.97)


has the same effet, winformsMap1.CurrentExtent is always the same :


winformsMap1.CurrentExtent = 735977.630625,198234.64375,737174.349375,197539.95625

winformsMap1.Height = 494 winformsMap1.Width = 851 


I dispatched the shapes to test V2 and V3 in different folders (it seems there is index conflict), but this doesn't change the result. I tried with other shapes, same behaviour.


I notice that the ScaleLineAdornmentLayer (MapSuiteExplorer) is wrong ! maybe it is linked with the extent problem ?



Eric, 
  
 That is a wield problem. 
  
 I do not think this problem is related with the AdormentLayer. If possible, could you pack up your small sample application and send to recreate it? I do not think the data needed to be packed, as you say this problem will lies whatever the data is. 
  
 Thanks. 
  
 Yale 


Yale,


Thank you for wathching. Tell me if this is not enough (the bin folder is too big in the attachment).



Eric, 
  
 Thanks for your sample. 
  
 I think in my enviroment it is correct. When it is first start up, it is blank because you did not add any layers then, after click on the parcelles, the map will show all the maps with full extent. I use the following test data: 
 Dim shapeFile As String = "C:\Program Files\ThinkGeo\Map Suite Desktop Full Edition 3.0\Samples\SampleData\Data\Countries02.shp" 
  
 Could you have atry to remove the "SplitContainer1" in your sample and have a try? 
  
 Thanks. 
  
 Yale

Yale,


Thank you for the test.


I tried with Countries02.shp (see attachements).


In Map Suite Explorer it is OK.


In my application, without Splitter and Dock, I can see all the map, but this time, not large enough and the rectangle size change after setting map


 



Layer 'Sections' GetBoundingBox = -180,83.6235961914063,180,-90
GetFullExtent Layer 'Sections' = -180,83.6235961914063,180,-90
GetFullExtent Return = -180,83.6235961914063,180,-90
winformsMap1.CurrentExtent = -287.9296875,191.225860595703,287.9296875,-197.602264404297
winformsMap1.Height = 553 winformsMap1.Width = 819

Do you have the same behavior in your environment ? 


I work with VS2005 and Framework 2.0 (System.dll, System.data.dll, System;Windows.dll) but I thing it is the same  in Framework 3.0.


 



Eric, 
  
 That is it. 
  
 I thin the problem lies in the Splitter and dock in your environment. The two attachments in above post seem correct. 
  
 I am not quire sure why the splitter caused your problem. I am now using the Win7 32 bit operating system with VS2005/ VS2008/VS2010 installed. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Yale, 


Unfortunately, the splitter / dock is not the cause of the problem.

Display my card in a winformsMap without splitter or dock, is always wrong size.

So I'm really stuck !

Can you try to view the attached map and tell me the size of the rectangle

In my environment I found:



Layer 'Sections' GetBoundingBox = 582037.42693499,2087402.29851214,600093.945313442,2077856.53812679
GetFullExtent Layer 'Sections' = 582037.42693499,2087402.29851214,600093.945313442,2077856.53812679
GetFullExtent Return = 582037.42693499,2087402.29851214,600093.945313442,2077856.53812679
winformsMap1.CurrentExtent = 590546.076749216,2082958.48081947,591585.295499216,2082300.35581947
winformsMap1.Height = 468 winformsMap1.Width = 739

But the map does not appear (bad design, no doubt) in my program. The display is ok in MapSuiteExplorer (see attachment).


Is it possible to know the code used by MapSuiteExplorer to properly size the map when it opened?



Let me interject in this conversation. by looking at the project Zoom To Full Extent of the Code Community, code.thinkgeo.com/projects/show/zoomtofullextent, I used your attached shapefile in a sample app. I have it working just fine with the Dock property set to Fill for the map. The behavior of the map when resizing the form is as expected. See my code below. I hope this is going to help:


 



 private void TestForm_Load(object sender, EventArgs e)
        {
            winformsMap1.MapUnit = GeographyUnit.Meter;

            ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(@"..\..\Data\DEPT_region.shp");
            shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Red, GeoColor.StandardColors.Black, 2);
            shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay layerOverlay = new LayerOverlay();
            layerOverlay.Layers.Add(shapeFileFeatureLayer);
            winformsMap1.Overlays.Add(layerOverlay);

            winformsMap1.CurrentExtent = GetFullExtent(layerOverlay.Layers);

            winformsMap1.Refresh();
        }

        //Function for getting the extent based on a collection of layers.
        //It gets the overall extent of all the layers.
        private RectangleShape GetFullExtent(GeoCollection<Layer> Layers)
        {
            Collection<BaseShape> rectangleShapes = new Collection<BaseShape>();

            foreach (Layer layer in Layers)
            {
                layer.Open();
                if (layer.HasBoundingBox == true) rectangleShapes.Add(layer.GetBoundingBox());
            }
            return ExtentHelper.GetBoundingBoxOfItems(rectangleShapes);
        }


Thank you so much Val.


Your example helped me finally find the error ...

In fact, it is not really a problem of extents, but the MapUnit which was bad for the card used!




- GeographyUnit.DecimalDegree (which was translated from the MapLengthUnits.DecimalDegrees v2, and works fine in V2 ?)


-  instead of GeographyUnit.Meter ...



I am glad we finally have it solved for you. Any other questions or doubts, let us know.