Register  |  Login
ThinkGeo - GPS Tracking and Mapping Solutions  |  Home  |  Cygnus Track  |   Code Community

Discussion Forums

The online community for users of Map Suite GIS components

RSS Feed Available AddThis - Bookmarking and Sharing Button Printer Friendly

PrevPrev NextNext

How to Display the Pacific Rim with a World ShapeFile in Map Suite 3.x

Posted by ThinkGeo on 04-17-2009 02:10 AM

Many of our Map Suite sample applications include an example of the world being displayed using a world ShapeFile. We are often asked by Map Suite developers how to display the Pacific Rim and Asia if you pan to the west, so that the world "wraps around," as it does with Google Maps. This article will provide some simple code that will make this possible in your Map Suite 3.x projects, as well as a sample application that will let you take this concept even further.

Introduction

Many of our Map Suite sample applications include an example of the world being displayed using a world ShapeFile. The ShapeFile is in Decimal Degrees and it displays the world according to longitude and latitude value ranges. These ranges are from -180 to 180 for longitude and 90 to -90 for latitude. In our various examples that use this ShapeFile, you see the Western Hemisphere on the left and the Eastern Hemisphere on the right.

Now, a common request that we receive is to display the Pacific Rim and Asia if you pan to the west, so that the world "wraps around," as it does with Google Maps.

This can be accomplished in Map Suite 3.x by using a custom projection that offsets all of the points by 360 for the x (longitude) values. (180 + 180 = 360). When you apply this projection, you will have the following result:

Screenshot

Notice that the green curve represents the Great Circle, or the shortest path between two points on the globe. Google Maps offers the Great Circle feature too, but it will not display correctly over the Pacific Rim. In the image below, you can see what happens when you try to draw the shortest path over the Pacific Rim with Google Maps:

Screenshot

In Map Suite 3.x, the following code will create the projection class and apply it to the world layer:


//This class, inheriting from Projection, applies the very simple projection of offsetting all the points
//360 degrees to the left.
    public class OffsetProjection : Projection, IDisposable
    {
        protected override Vertex[] ConvertToExternalProjectionCore(double[] x, double[] y)
        {

            Vertex[] vertices = new Vertex[x.Length];

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = new Vertex(x[i] - 360, y[i]);
            }
            return vertices;
        }

        protected override Vertex[] ConvertToInternalProjectionCore(double[] x, double[] y)
        {
            Vertex[] vertices = new Vertex[x.Length];

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = new Vertex(x[i] + 360, y[i]);
            }
            return vertices;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            Close();
        }
    }


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

            //We are loading the same ShapeFile twice: Once unprojected and a second time projecting
            //all the features 360 degrees to the left.
            ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"..\..\Data\cntry02.shp");
            worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
            worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            winformsMap1.StaticOverlay.Layers.Add("WorldLayer", worldLayer);
          
            OffsetProjection offsetProj = new OffsetProjection();

            //Run this code only once to build the spatial index for the projected layer.
            //worldLayer.Open();
            //Collection<Feature> features = worldLayer.QueryTools.GetAllFeatures(ReturningColumnsType.NoColumns);
            //worldLayer.Close();
            //ShapeFileFeatureLayer.BuildIndexFile(features, @"..\..\Data\cntry02_offset.idx", BuildIndexMode.DoNotRebuild);
            
            //Loads the country layer with the Projection offsetting all the features 360 degrees to the left.
            ShapeFileFeatureLayer worldLayerOffset = new ShapeFileFeatureLayer(@"..\..\Data\cntry02.shp", @"..\..\Data\cntry02_offset.idx");
            worldLayerOffset.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.GetSimpleAreaStyle(GeoColor.SimpleColors.LightGreen);
            worldLayerOffset.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            worldLayerOffset.FeatureSource.Projection = offsetProj;
            winformsMap1.StaticOverlay.Layers.Add("World Offset", worldLayerOffset);


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

            //Notice that the current extent has to be expressed in the projected values to have the map
            //centered on the Pacific.
            //80 - 360 = -280
            winformsMap1.CurrentExtent = new RectangleShape(-280, 58, -70, -20);
            winformsMap1.Refresh();

        }

The result from this code is as shown below:

Screenshot

In the above figure, you can see in green the layer that has been projected 360 degrees to the left, in comparison to the non-projected layer, which is in white.

There are a few more tricks to get different aspects of this technique working, such as when you want to display InMemoryFeatureLayers or Great Circle distances. For more example code on that, see the attached sample application. Please note that before you can use it, you will need to set the references for Map Suite's DLLs according to your installation of Map Suite.

Downloads

Have Questions?

Do you have any questions or comments about this article? If so, feel free to post them below!

About the Author

Val Guillou is a GIS analyst and developer at ThinkGeo, a software company specializing in geospatial software with an emphasis on software development tools and GPS tracking solutions.

0 Comments

You are not authorized to post a reply.
Active Forums 4.2