ThinkGeo.com    |     Documentation    |     Premium Support

PolygonShape - defined using Trackshape clockwise

Good Morning,


I mentioned that I'm new to using TrackShapes, right?


I'm using TrackShapes to allow a user to define polygons. Before using TrackShapes, I allowed the user to define a polygon by clicking a series of points on the map. When they were done, I would verify that the polygon had been defined by clicking the points counter-clockwise and if they hadn't, I would reverse the order of the vertices before creating my polygon. I need them to be defined counter-clockwise for querying SQL Server.


I'm now using TrackShapes, so I'm not working with the individual vertices, but rather I get a PolygonShape when they are through. I know that I could parse the well defined text for the vertices and then run my own check and finally reverse the order of the vertices if needed. However, I imagine that the PolygonShape class contains a hidden list of vertices. Maybe I'm wrong on that. I'm wondering if the PolygonShape class could offer a method to determine if the polygon is defined clockwise or counter-clockwise and a method for getting the well defined text showing the vertices in the opposite direction if needed.


Of course, maybe there's a way the library handles this already, but I'm not aware of it.


Thank you!


Kimberly



Kimberly,


A PolygonShape contains one or more RingShapes and each RingShape has a list of vertices. For example, the following picture is a Polygon which has one outer ring, and 2 InnerRings, you can get their vertices from the codes below.


polygonShape.OuterRing.Vertices
polygonShape.InnerRings[0].Vertices
polygonShape.InnerRings[1].Vertices

 
So you see we can get the vertices’ sequence from a RingShape, not a Polygon.
 
We don’t have that API in the current version (in fact we have a private method doing that but we didn’t review and polish it to make it ready to be public) and we’ll see if we will add one. Here I created an extend method (support in .NET 3 and above) IsCounterClockwise for you and you can use directly.  
 

int featureCount = winformsMap1.EditOverlay.EditLayer.InternalFeatures.Count;
PolygonShape polygon = (PolygonShape)winformsMap1.EditOverlay.EditLayer.InternalFeatures[featureCount - 1].GetShape();
bool isCounterClockwise = polygon.OuterRing.IsCounterClockwise();

// Extend Method
        static class ClockWiseExtender
        {
            public static bool IsCounterClockwise(this RingShape ringShape)
            {
                Collection<Vertex> vertices = ringShape.Vertices;

                Vertex hightestPoint = new Vertex(double.MinValue, double.MinValue);
                int hightestPointNumber = 0;
                int count = vertices.Count;
                for (int i = 0; i < count; i++)
                {
                    if (vertices<i>.Y > hightestPoint.Y)
                    {
                        hightestPoint = vertices<i>;
                        hightestPointNumber = i;
                    }
                }

                int previousPointNumber = hightestPointNumber - 1;
                if (previousPointNumber < 0)
                {
                    previousPointNumber = count - 2;
                }
                Vertex previousPoint = vertices[previousPointNumber];

                int nextPointNumber = hightestPointNumber + 1;
                if (nextPointNumber >= count)
                {
                    nextPointNumber = 1;
                }
                Vertex nextPoint = vertices[nextPointNumber];

                double prev2x = previousPoint.X - hightestPoint.X;
                double prev2y = previousPoint.Y - hightestPoint.Y;
                double next2x = nextPoint.X - hightestPoint.X;
                double next2y = nextPoint.Y - hightestPoint.Y;

                double disc = next2x * prev2y - next2y * prev2x;

                bool isCounterClockwise = false;

                if (disc == 0.0)
                {
                    isCounterClockwise = previousPoint.X > nextPoint.X;
                }
                else
                {
                    isCounterClockwise = disc > 0.0;
                }

                return isCounterClockwise;
            }

 
You can create a similar function to reverse the vertices if needed. You can directly called the method RingShape.Vertices.Reverse() I think.
 
Let me know if you have any issues.
 
Thanks,
 
Ben