ThinkGeo.com    |     Documentation    |     Premium Support

Not drawing a straight line across the Greenwich meridian

 Guys, I need to tackle this Greenwich meridian problem where a straight line is drawn across the map projected in EPSG 4326.  I need to figure out a methodical way to split such a feature taking into consideration the map projection.   


For example, if I have a line that goes around the world and my projection is, 4326 for example, i do not want a straight line across the map.  So, I may have to split the line into a multi line.... a solution of this nature.


Do you guys already have a way to handle this?  I looked at the Proj4Projection class but could determine if any of these methods will do the trick.


Thanks,


Klaus


 


 



I think that what you are describing is similar to the case handled in the Code Community project, Polygon across Meridiancode.thinkgeo.com/projects/show/polygonmeridian. Here we split a polygon into a multi polygon, but for a line this is basically the same operation. Let us know if this is not what you are looking for.



 Precisely what I am looking for, thank you.



You are welcome. Let us know if you have any doubts.

 Did something similar for Lines and this is the method.  The tricky part was to constrain the line within the map extent.  This is not yet production ready but I just wanted to find out if you guys had a better way to get a line within a given extent.



   public MultilineShape SplitLine180Meridian(LineShape line)
        {
            OffsetProjection offsetProjection = new OffsetProjection();
            offsetProjection.Open();
     

            var worldExtent = new RectangleShape(-180, 90, 180, -90);
            var westernLineVertices = new Collection<Vertex>();
            var easternLineVertices = new Collection<Vertex>();

            foreach (Vertex vertex in line.Vertices)
            {
                if (vertex.X > 0)
                {
                    westernLineVertices.Add(offsetProjection.ConvertToExternalProjection(vertex.X, vertex.Y));
                    easternLineVertices.Add(vertex);
                }
                else
                {
                    westernLineVertices.Add(vertex);
                    easternLineVertices.Add(offsetProjection.ConvertToInternalProjection(vertex.X, vertex.Y));
                }
            }
            offsetProjection.Close();

            var multiLineShape = new MultilineShape();
            var westernLine = new LineShape(westernLineVertices);
            var easternLine = new LineShape(easternLineVertices);       
            
     // suspect....start
            var crossingW = worldExtent.GetCrossing(westernLine).Points; 
            var crossingE = worldExtent.GetCrossing(easternLine).Points;
            
            var westLine = westernLine.GetLineOnALine(new PointShape( westernLine.Vertices.First()), crossingW.First());
            var eastLine = easternLine.GetLineOnALine(crossingE.First(), new PointShape( easternLine.Vertices.Last())); 
           
            var _wl = westLine as LineShape;
            var _el = eastLine as LineShape;
            // suspect...end
            
            multiLineShape.Lines.Add(_wl);
            multiLineShape.Lines.Add(_el);

            return multiLineShape;

 



After doing some investigation, it turns out that the task of splitting line on the 180 meridian is more complicated than with a polygon because the API GetIntersection lacks the support for line. I asked the develpment if there is another way to accomplish this or if we can relatively easily add the support for line in GetIntersection. In the meantime, I think that you are going to have to content yourself with using a MultilineShape that has the one LineShape for the east side and one LineShape for the west side. See the code below:



private MultilineShape SplitLineAt180Meridian(LineShape line)
{
    
    OffsetProjection offsetProjection = new OffsetProjection();
    offsetProjection.Open();

    LineShape westernLineShape = new LineShape();
    LineShape easternLineShape = new LineShape();

    foreach (Vertex vertex in line.Vertices)
    {
        if (vertex.X > 0)
        {
            westernLineShape.Vertices.Add(offsetProjection.ConvertToExternalProjection(vertex.X, vertex.Y));
            easternLineShape.Vertices.Add(vertex);
        }
        else
        {
            westernLineShape.Vertices.Add(vertex);
            easternLineShape.Vertices.Add(offsetProjection.ConvertToInternalProjection(vertex.X, vertex.Y));
        }
    }
    offsetProjection.Close();

    MultilineShape multilineShape = new MultilineShape();
    multilineShape.Lines.Add(easternLineShape);
    multilineShape.Lines.Add(westernLineShape);
    
    return multilineShape;
}
 

 


So, the result is going to look like the picture below. I hope this is of for you for now:



To accomplish the task completely in a way comparable to with a Polygon, we would need the GetIntersection function working as you can see in the picture below:



 



 Val, thanks for the response.


The section of code where I commented is suspect actually works to constraint the split lines within my map's extent.  Initially, I was simply adding the split lines to a MultiLineShape obejct just like you did.  But I needed the lines confined within my map extent.



Attached is the picture I get.  Red line is original.  Green line is actually a blue line but superimposed on original red line.  Green segments are my split lines.  


What is wrong with the proposed?


 



  var worldExtent = new RectangleShape(-180, 90, 180, -90);
            var crossingW = worldExtent.GetCrossing(westernLine).Points; 
            var crossingE = worldExtent.GetCrossing(easternLine).Points;
            
            var westLine = westernLine.GetLineOnALine(new PointShape( westernLine.Vertices.First()), crossingW.First());
            var eastLine = easternLine.GetLineOnALine(crossingE.First(), new PointShape( easternLine.Vertices.Last())); 
           
            var _wl = westLine as LineShape;
            var _el = eastLine as LineShape;
            
            multiLineShape.Lines.Add(_wl);
            multiLineShape.Lines.Add(_el);

 



We don’t see any picture attached. You must have forgotten. It is a little difficult to tell if what you proposed is right without knowing about the line you are doing the operation on. If this is working for you then it must be correct for your cases but keep in mind that this is not going to work with any line. The line has to be in a certain direction, cannot cross multiple time the 180 degrees meridian etc. To have that operation working in any cases, a GetIntersection function for line would be necessary. We are still looking for an answer from the Development Team to know if we can add this function into our map control. Thank you.

Has the GetIntersection gained functionality with lines as of now? It’s been three years so I would like to know if this has changed since Val’s reply. Thanks

Hi Todd, 
  
 Sorry, it looks we still haven’t the GetIntersection function. 
  
 So what’s your scenario now? I think maybe we can try finding some other APIs for your target. 
  
 Regards, 
  
 Don