ThinkGeo.com    |     Documentation    |     Premium Support

Drawing a dateline / meridian crossing polygon

Hi.


When I generate a polygon from a list of points which goes around the left or right end of the map, it fails to generate an appropriate polygon.


For example, for the point list


(179, 0), (-179, 0),(-179, 1),(179, 1),(179, 0)


it should make a polygon at the end of the map.


However it returns a polygon acrossing the middle of the map.


I think MapSuite does not understand that -180 longitude and 180 longitude is connected.


I've tried your Convex Hull example too, but it also failed to generate a correct convex hull.


 



Seungwoo,


We have a sample in Code Community, it shows how to display the Pacific Rim and Asia  if you pan to the west, so that the world "wraps around". You can download the source code from


code.thinkgeo.com/projects/show/pacificrim


It is just a reference sample, if you have any question please let me know.


Thanks


James



Hi James. 
  
 I’m sorry but it doesn’t appear to solve my problem. 
  
 Here’s my code. 
  
  
  
              InMemoryFeatureLayer layer = new InMemoryFeatureLayer(); 
              for (int i = 150; i < 179; i++) 
              { 
                  PointShape point = new PointShape(i, 28.0 + Math.Sin(i) * 10); 
                  layer.InternalFeatures.Add(new Feature(point)); 
              } 
  
              for (int i = -179; i < -170; i++) 
              { 
                  PointShape point = new PointShape(i, 28.0 + Math.Sin(i) * 10); 
                  layer.InternalFeatures.Add(new Feature(point)); 
              } 
              //Populate the MultipointShape of all the PointShapes from the oil rigs features. 
              MultipointShape multipointShape = new MultipointShape(); 
              foreach (Feature feature in layer.InternalFeatures) 
              { 
                  PointShape pointShape = (PointShape)feature.GetShape(); 
                  multipointShape.Points.Add(pointShape); 
              } 
  
              //Gets the Convex Hull from the MultipointShape. 
              RingShape ringShape = multipointShape.ConvexHull(); 
  
 
  


I see what you are trying to accomplish with your features crossing the 180 degree meridian. The proper solution for you will depend on how you have your map projected. If you have the map using regular decimal degrees unprojected, it is going to be a little tricky with the result being a MultipolygonShape with two outer rings one to the extreme west and the other one to the extreme east. If your area of interest is the Pacific, frankly this is going to be an awkward solution with the two parts of the polygon at two ends of the map. I would recommend applying the custom projection found in the project pointed by James. Let us know what way you want to use and we will show you the fitting solution. Thank you.

Hi Val. 
 I’m glad that you understood my situation. 
 Yes I’m using a regular decimal degrees map and the result may be multiple polygons like you’ve said. 
 I especially suffering this problem when I need to make polygon from a point list which crosses left end and right end several times. 
 I think I can define my problem clearer. 
  
 I want to draw a thin stripe wraps around the globe (which maybe cross the poles) 
 I know the points of the stripe border. 
 How can I get a polygon(or polygons) of the stripe from those points? 
  



I attach a screenshot of the 'stipe' i've meant above to help your understanding.


I had to use an ugly and messy way to draw it and it is not stable. :(



Using the code that you provided, you get the following result by creating the conevex hull. The resulting polygon goes all across the map which is not what is expected.



 I think the a reasonable aproach in this case is to treat as separate the points that have a positive longitude value (Eastern Hemisphere) and the points that have a negative longitude value (Western Hemisphere). That way you get a result that is more in line with is expected to show on the map:



Please, look at the code that I modified from yours:


 



  //------------process the East---------------------
            layer.Open();
            layer.EditTools.BeginTransaction();
            MultipointShape multipointShape1 = new MultipointShape();
            for (int i = 150; i < 179; i++)
            {
                PointShape point = new PointShape(i, 28.0 + Math.Sin(i) * 10);
                layer.EditTools.Add(new Feature(point));
                multipointShape1.Points.Add(point);
            }
            //Gets the Convex Hull from the MultipointShape1. 
            RingShape ringShape1 = multipointShape1.ConvexHull();
            PolygonShape polygonShape1 = new PolygonShape();
            polygonShape1.OuterRing = ringShape1;
            layer.EditTools.Add(new Feature(polygonShape1));

            layer.EditTools.CommitTransaction();
            layer.Close();


            //---------process the West------------------------------
            layer.Open();
            layer.EditTools.BeginTransaction();
            MultipointShape multipointShape2 = new MultipointShape();
            for (int i = -179; i < -170; i++)
            {
                PointShape point = new PointShape(i, 28.0 + Math.Sin(i) * 10);
                layer.EditTools.Add(new Feature(point));
                multipointShape2.Points.Add(point);
            }

            //Gets the Convex Hull from the MultipointShape2. 
            RingShape ringShape2 = multipointShape2.ConvexHull();
            PolygonShape polygonShape2 = new PolygonShape();
            polygonShape2.OuterRing = ringShape2;
            layer.EditTools.Add(new Feature(polygonShape2));
           
            layer.EditTools.CommitTransaction();
            layer.Close();


I let you know that we just published a project in the Code Community with a solution that might be a more exact fit to your case. I suggest you check it out. It is called Polygon across Meridian.


code.thinkgeo.com/projects/show/polygonmeridian



Hi Val. 
 Thanks for your help. 
  
 The polygon below doesn’t work in your code. 
  
             PolygonShape polygonShape = new PolygonShape(); 
             RingShape ringShape = new RingShape(); 
             ringShape.Vertices.Add(new Vertex(-100, 50)); 
             ringShape.Vertices.Add(new Vertex(10, 40)); 
             ringShape.Vertices.Add(new Vertex(100, 30)); 
             ringShape.Vertices.Add(new Vertex(170, 20)); 
             ringShape.Vertices.Add(new Vertex(-170, 10)); 
             ringShape.Vertices.Add(new Vertex(-100, 0)); 
  
             ringShape.Vertices.Add(new Vertex(-100, 10)); 
             ringShape.Vertices.Add(new Vertex(-170, 20)); 
             ringShape.Vertices.Add(new Vertex(170, 30)); 
             ringShape.Vertices.Add(new Vertex(100, 40)); 
             ringShape.Vertices.Add(new Vertex(10, 50)); 
             ringShape.Vertices.Add(new Vertex(-100, 60)); 
             ringShape.Vertices.Add(new Vertex(-100, 50)); 
             polygonShape.OuterRing = ringShape; 
  
 Thanks. 


That’s because your polygon also crosses the Meridian 0 (Greenwich) and this is a case i did not take into account. I will work tomorrow on the logic to handle that case too. In the meantime, you can notice, that if you shorten your polygon so it does not cross the Meridian 0, it will work: 
  
   PolygonShape polygonShape = new PolygonShape(); 
             RingShape ringShape = new RingShape(); 
             //ringShape.Vertices.Add(new Vertex(-100, 50)); 
             ringShape.Vertices.Add(new Vertex(10, 40)); 
             ringShape.Vertices.Add(new Vertex(100, 30)); 
             ringShape.Vertices.Add(new Vertex(170, 20)); 
             ringShape.Vertices.Add(new Vertex(-170, 10)); 
             ringShape.Vertices.Add(new Vertex(-100, 0)); 
  
             ringShape.Vertices.Add(new Vertex(-100, 10)); 
             ringShape.Vertices.Add(new Vertex(-170, 20)); 
             ringShape.Vertices.Add(new Vertex(170, 30)); 
             ringShape.Vertices.Add(new Vertex(100, 40)); 
             ringShape.Vertices.Add(new Vertex(10, 50)); 
             ringShape.Vertices.Add(new Vertex(10, 40)); 
             //ringShape.Vertices.Add(new Vertex(-100, 60)); 
             //ringShape.Vertices.Add(new Vertex(-100, 50)); 
              
             polygonShape.OuterRing = ringShape;