Determine outer boundries of polygon from lat/lng point array - geospatial

I have a large array of lat/lng points. Could be up to 20k points. I'm plotting them using KML. What I want to do is to take only the outter most points and use them to draw a polygon instead. I already know how to draw a polygon in kml, I just need to figure out how to select only the outer most points of the group.
Any ideas? I'd like to have at least 5 points to the polygon but no more than 25 points total.
So far i've come up with checking for top most and bottom most points (basically crearing a square) using < & > logic.
The points will be in america & canada only if that matters.
Thanks for any help.
EDIT: I've gotten the Convex Hull algorithm to work, but it isnt exactly what I need. I'm trying to map out zip codes. If a zip code has an L shape then the polygon is going to be a triangle shape and not an L shape. Any ideas?

You need to use a Convex Hull algorithm. It's not too hard to implement yourself if it's not available in whatever software package you're using.

Related

Polygon triangulation with collinear points?

I have a polygon with collinear points. I want to triangulate the polygon while retaining all the collinear points, since I require those vertices on the generated meshes. Currently I tried to use poly2tri, but it doesn't support collinear points. Is there a polygon triangulation algorithm which support collinear points?
Try moving the points slightly, so they are not colinear. Doing the meshing and then moving the points back.
I tried running the meshing algorithm, then perturbing all the points it missed, then running it again.
It can be quite slow but it does work.
A simple polygon with collinear vertices presents a serious problem for the "ear splitting" triangulation. The best example to see this problem - sketch yourself a 5-point star. Pick any of the points as the convex vertex for a candidate ear.
The diagonal for this ear lies completely within the polygon, and doesn't form "X" intersections with any of the other edges, so by the criteria for a "valid diagonal", it should work. But, notice that once you slice off the ear, the remaining polygon is no longer a simple polygon - because it contains two vertices where the edges meet at a straight (180 deg.) angle. That alone disqualifies the new sub-polygon as "simple", and it will crash any attempt to continue triangulation on it using ear-splitting. I will post a separate question on how best to triangulate these ill-conditioned polys.

Convex hull of parallel lines

I have arbitrary many lines in 3D space which are all parallel to each other. Now I want to find the convex hull of these lines. To illustrate this, I've drawn a picture:
I know the start- and endpoints of all lines (the blue dots). The lines are not equally long. If a viewer looks in the direction of the lines (marked as the viewer direction in the pic) he sees only the dots. Now I want to find the convex hull of these dots. Hopefully its clear what I mean.
My idea was to project the start or endpoints on a plane which is perpendicular to the line's direction. After that I can apply some kind of convex hull algorithm to these points. But I have no idea how.
Your idea is exactly correct. One way to accomplish this is to define a vector v along your viewing direction, and then rotate v to the z-axis. The same rotation will convert lines to vertical lines. Then drop the z-coordinate of the endpoints to get your projected points. Then compute the convex hull. There are hull algorithms all over the web, including my own here.
Here's a suggestion based on the calculus of variations.
Consider enclosing your collection of parallel line segments in a simple closed curve minimizing the area of the curve given the constraint that it has to enclose all your segments.
Your "curve" is going to be piecewise linear, so there you might be able to use a P.W basis function in the iterations, though it's possible that you could run into some singularities when the algorithm needs to drop a segment.

Polygon Decomposition - Removing Concave Points to Form Convex Polygons

I would like to deconstruct the following polygon shown in blue removing all of the points from the polygon that cause concavity.
Currently, what I have been attempting to do is:
Take each point out of the polygon
Test the point to see if it falls within the polygon created by the rest of the set
If true remove the point
If false keep the point
This works in most cases, but in the previous case the points at (2,3) and (2,4) will not both be removed. In both cases either one of the points will be removed, but the other will not depending on the order which the array is passed in.
What I am wondering is this:
Is there some way to test to see if the polygon I am dealing with happens to have one of these cases (IE: 3 points of failure in a row?)
or
Is there simply a more effective way of creating convex polygons?
Thank you.
I think perhaps you're looking for the convex hull?
The first algorithm that springs to mind is QuickHull. Initially, take the leftmost and the rightmost points, l and r. They must be on the hull.
Construct a first guess at the hull that's two outward faces, one from l to r and one from r to l. So you have a polygon with zero volume.
Divide all remaining points into those in front of lr and those in front of rl.
From then on, while any face has any points in front of it:
find the furthest point from the face
delete this edge and replace it with two edges, one from the original start point to the furthest point and one from the furthest point to the original end point
of all the points that were in front of the old face, put those in front of the first of the new faces you've added into its in front set, put those in front of the second into its in front set and don't retain any reference to those now inside
At the end you'll have the convex hull.
Why not simply compute the convex hull of the points?
This is a well studied problem with a number of algorithms in books and online. A method of "sweeping angles" is particularly common, eg.
http://courses.csail.mit.edu/6.854/06/scribe/s25-rasmu-sweepline.pdf
What you are looking for is known as "convex hull" finding. Look here at wikipedia for algorithms for this problem. The "gift wrapping" algorithm is easy to implement. When yout found the hull, just remove all points that are not part of the hull.
Be aware that the Convex Hull is already implemented in some languages/environments.
Example in Mathematica:
<< ComputationalGeometry`;
data2D = {{4.4, 14}, {6.7, 15.25}, {6.9,12.8}, {2.1, 11.1}, {9.5, 14.9},
{13.2, 11.9}, {10.3, 12.3}, {6.8, 9.5}, {3.3, 7.7}, {0.6, 5.1},
{5.3, 2.4}, {8.45, 4.7}, {11.5,9.6}, {13.8, 7.3}, {12.9, 3.1},
{11, 1.1}};
PlanarGraphPlot[data2D, ConvexHull[data2D]]
Output:

Creating closed spatial polygons

I need to create a (large) set of spatial polygons for test purposes. Is there an algorithm that will create a randomly shaped polygon staying within a bounding envelope? I'm using OGC Simple stuff so a routine to create the well known text is the most useful, Language of choice is C# but it's not that important.
Here you can find two examples of how to generate random convex polygons. They both are in Java, but should be easy to rewrite them to C#:
Generate Polygon example from Sun
from JTS mailing list, post Minimum Area bounding box by Michael Bedward
Another possible approach based on generating set of random points and employ Delaunay tessellation.
Generally, problem of generating proper random polygons is not trivial.
Do they really need to be random, or would some real WKT do? Because if it will, just go to http://koordinates.com/ and download a few layers.
What shape is your bounding envelope ? If it's a rectangle, then generate your random polygon as a list of points within [0,1]x[0,1] and scale to the size of your rectangle.
If the envelope is not a rectangle things get a little more tricky. In this case you might get best performance simply by generating points inside the unit square and rejecting any which lie in the part of the unit square which does not scale to the bounding envelope of your choice.
HTH
Mark
Supplement
If you wanted only convex polygons you'd use one of the convex hull algorithms. Since you don't seem to want only convex polygons your suggestion of a circular sweep would work.
But you might find it simpler to sweep along a line parallel to either the x- or y-axis. Assume the x-axis.
Sort the points into x-order.
Select the leftmost (ie first) point. At the y-coordinate of this point draw an imaginary horizontal line across the unit square. Prepare to create a list of points along the boundary of the polygon above the imaginary line, and another list along the boundary below it.
Select the next point. Add it to the upper or lower boundary list as determined by it's y-coordinate.
Continue until you're out of points.
This will generate convex and non-convex polygons, but the non-convexity will be of a fairly limited form. No inlets or twists and turns.
Another Thought
To avoid edge crossings and to avoid a circular sweep after generating your random points inside the unit square you could:
Generate random points inside the unit circle in polar coordinates, ie (r, theta).
Sort the points in theta order.
Transform to cartesian coordinates.
Scale the unit circle to a bounding ellipse of your choice.
Off the top of my head, that seems to work OK

Minimize Polygon Vertices

What is a good algorithm for reducing the number of vertices in a polygon without changing the way it looks very much?
Input: A polygon, represented as a list of points, with way too many verticies: raw input from the mouse, for example.
Output: A polygon with much fewer verticies that still looks a lot like the original: something usable for collision detection, for example (not necessarily convex).
Edit: The solution to this would be similar to finding a multi-segmented line of best fit on a graph. It's called Segmented Least Squares in my algorithms book.
Edit2: The Douglas Peucker Algorithm is what I really want.
Edit: Oh look, Simplifying Polygons
You mentioned collision detection. You could go really simple and calculate a bounding convex hull around it.
If you cared about the concave areas, you can calculate a concave hull by taking the centroid of your polygon, and choosing a point to start. From the starting point rotate around the centroid, finding each vertex you want to keep, and assigning that as the next vertex in the bounding hull. The complexity of the algorithm would come in how you determined which vertices to keep, but I'm sure you thought of that already. You can throw all your vertices into buckets based on their location relative to the centroid. When a bucket gets more than an arbitrary number of vertices full, you can split it. Then take the mean of the vertices in that bucket as the vertex to use in your bounding hull. Or, forget the buckets, and when you're moving around the centroid, only choose a point if its more than a given distance from the last point.
Actually, you could probably just use all the vertices in your polygon as "cloud of points" and calculate the concave hull around that. I'll look for an algorithm link. Worst case on this would be a completely convex polygon.
Another alternative is to start with a bounding rectangle. For each vertex on the rectangle, find the distance from the point to the polygon. For the farthest vertex, split it into two more vertices and move them in some. Repeat until some proportion of either vertices or area is met. I'd have to think about the details of this one a little more.
If you care about the polygon actually looking similar, even in the case of a self-intersecting polygon, then another approach would be required, but it doesn't sound like thats necessary since you asked about collision detection.
This post has some details about the convex hull part.
There's a lot of material out there. Just google for things like "mesh reduction", "mesh simplification", "mesh optimization", etc.

Resources