Does GeoJSON spec imply that polygons should be simple? - geojson

If we read 3.1.6 of RFC7946 one may think GeoJSON implicitly requires polygons to be simple. For example:
A linear ring MUST follow the right-hand rule with respect to the
area it bounds, i.e., exterior rings are counterclockwise, and
holes are clockwise.
From this statement we may infer that we must not change the winding direction of a polygon thus may not anticipate twisted polygons (like the rightmost one here).
Also:
For Polygons with more than one of these rings, the first MUST be
the exterior ring, and any others MUST be interior rings. The
exterior ring bounds the surface, and the interior rings (if
present) bound holes within the surface.
It seems from this paragraph we can decide not to anticipate holes of a polygon to intersect with polygon itself.
Considering all this, can we assume that polygons stored in well-formed GeoJSON are simple or at least with simple exterior and interior contours?

Related

Ray tracer for complicated figures

I have implemented realtime ray tracer with MetalFramework for iOS and it is implemented for following optical prisms like dodecahedron, icosahedron, octahedron, cube, etc. All my figures are composed from triangles, for example cube - 12 triangles, octahedron - 4 triangles. I trace rays and search intersection with figure, then I search how ray moves in prism. Then ray leaves figure and I search intersection with skybox. The problem is in complicated figures. When I test cube fps is 60, but when I test dodecahedron fps is 6. In my algorithm intersection with figure is the same as intersection with any triangle. It means that when I check intersection with ray and figure I have to check intersection with all triangles. I need some idea how to do not check intersections for all triangles. Thanks.
let say you have world bounded by some bounding box
create grid (dividing this box to cubes or whatever)
each voxel/cell
Is a list of triangles that intersects or are in it so before rendering for each cell process all triangles and store index of all triangles inside or crossing
rewrite ray-tracer to trace through this voxel map
So just increment the ray through neighboring voxels it is the same as line rasterization on pixels. This way you have partially Z-sort done. So take first voxel hit by ray and test only triangles contained in it. If any hit on voxel was found then stop (no need to test other voxels because they are farer).
further optimizations
You can add flag if triangle has been tested so test only those which where not already tested because many triangles will be multiple times tested otherwise
[notes]
Number of voxels per axis greatly affect performance so you need to play with it a bit to achieve best performance. If you have dynamic objects then the voxel map lists computations must be done once in a while or even per each frame. For static scene there is sufficient to do this just once.
To trace efficiently you'll need to use an acceleration structure, for example a KD-tree or a bounding volume hierarchy(BVH). This is similar to using a binary search tree to find a matching element.
I would suggest using a BVH because it is easier to construct and traverse than a KD-tree. And I would suggest against using a uniform voxel grid structure. A voxel grid can easily have very poor performance when triangles are unevenly distributed through the scene or heavily concentrated in a few voxels.
The BVH is just a tree of bounding volumes, such as an axis aligned bounding box (AABB) which encompass the primitives within it. This way if your a ray misses the bounding volume you know that it does not hit any primitives contained with it.
To construct a BVH:
Put all the triangle in one bounding volume. This will be the root of the tree.
Divide the triangles into two sets where the bounding volume of each set of triangles is minimized. More properly you'd want to follow the surface area heuristic (SAH), where you want to create set of triangles where you minimize the sum of the (surface area of the BVH)/(# triangles) for both sets of triangles.
Repeat step 2 for each node recursively until you the number of triangles you have left hits some threshold (4 is a good number to try).
To traverse
Check if the ray hits the root bounding box, if it does then proceed to step 2 otherwise no hit.
Check if it hits the child bounding boxes. If it does then repeat this step for its children bounding boxes. Otherwise no hit.
When you get the a bounding box which only contains triangles you'll need to test each triangle to see if it is hit just like normal.
This is a basic idea of a BVH. There much more detail that I haven't gone into about the BVH that you'll have to search for, since there are so many variations in the details.
In Short Implement a bounding volume hierarchy to trace.

Detect if polygon has intersecting lines (bowtie)

I'm looking for a way to detect if a set of points/coordinates have any intersecting lines.
A little setup, I'm drawing a polygon using UIBezierPath on an overlay to a map. This all works. I'm able to reduce the map points down using a point reducing algorithm, and I'm left with a simple looking polygon that renders on my map just fine. FWIW, I'm using Google Maps SDK.
My problem is that it is possible for the user to draw a polygon with self intersecting lines (which is a problem for what I am doing). I need to be able to do one of 3 things.
Remove the intersecting points in the array. (Clip off the bow tie pieces)
Detect if my points have this bow tie (I'll just tell them to redraw a new polygon)
If possible (which I don't think it is), prevent the path from drawing the bow tie in the first place.
I mostly see the bow tie when the polygon self closes and the end point is slightly underlapping the start point. So when the polygon closes and renders into map coordinates on the map, I get a tiny bow tie that messes with an internal API.
Is there anything out there that will work using map coordinates? I've seen some fixes for regular CGPoints, but nothing that will take map coordinates. I would prefer to do this check on my polygon after it has gone through my reducer as it leaves many less points to check. Performance is an issue, and would prefer not to iterate over hundreds of points directly coming off the UIBezierPath. Any help would be appreciated.
I don't know about the Google Maps SDK or the UIBezierPath. I assume that you are given a polygon in the 2D plane and you would like to automatically detect where the polygon intersects itself (if it does).
Perhaps the easiest way to do this is checking all pairs of edges whether they intersect or not. You can check this in O(n2) time where n is the number of edges, as there are n*(n-1)/2 pairs of edges. For a given pair of edges, here are the details how to do it:
How to check if two given line segments intersect?
Nothing extraordinary but the details do require attention.
A more sophisticated algorithm is the plane sweep algorithm:
Line segment intersection, starting at slide 25
Line Segment Intersection Using a Sweep Line Algorithm

Algorithm for selecting outer points on a graph ("rich" convex hull)

I'm looking for an efficient way of selecting a relatively large portion of points (2D Euclidian graph) that are the furthest away from the center. This resembles the convex hull, but would include (many) more points. Further criteria:
The number of points in the selection / set ("K") must be within a specified range. Most likely it won't be very narrow, but it most work for different ranges (eg. 0.01*N < K < 0.05*N as well as 0.1*N < K < 0.2*N).
The algorithm must be able to balance distance from the center and "local density". If there are dense areas near the upper part of the graph range, but sparse areas near the lower part, then the algorithm must make sure to select some points from the lower part even if they are closer to the center than the points in the upper region. (See example below)
Bonus: rather than simple distance from center, taking into account distance to a specific point (or both a point and the center) would be perfect.
My attempts so far have focused on using "pigeon holing" (divide graph into CxR boxes, assign points to boxes based on coordinates) and selecting "outer" boxes until we have sufficient points in the set. However, I haven't been successful at balancing the selection (dense regions over-selected because of fixed box size) nor at using a selected point as reference instead of (only) the center.
I've (poorly) drawn an Example: The red dots are the points, the green shape is an example of what I want (outside the green = selected). For sparse regions, the bounding shape comes closer to the center to find suitable points (but doesn't necessarily find any, if they're too close to the center). The yellow box is an example of what my Pigeon Holing based algorithms does. Even when trying to adjust for sparser regions, it doesn't manage well.
Any and all ideas are welcome!
I don't think there are any standard algorithms that will give you what you want. You're going to have to get creative. Assuming your points are embedded in 2D Euclidean space here are some ideas:
Iteratively compute several convex hulls. For example, compute the convex hull, keep the points that are part of the convex hull, then compute another convex hull ignoring the points from the original convex hull. Continue to do this until you have a sufficient number of points, essentially plucking off points on the perimeter for each iteration. The only problem with this approach is that it will not work well for concavities in your data set (e.g., the one on the bottom of your sample you posted).
Fit a Gaussian to your data and keep everything > N standard
deviations away from the mean (where N is a value that you'd have to
choose). This should work pretty well if your data is Gaussian. If
it isn't, you could always model it with several Gaussians (instead
of one), and keep points with a joint probability less than some threshold. Using multiple Gaussians will probably handle concavities decently. References:
http://en.wikipedia.org/wiki/Gaussian_function
How to fit a gaussian to data in matlab/octave?\
Use Kernel Density Estimation - If you create a kernel density
surface, you could slice the surface at some height (e.g., turning
it into a plateau), giving you a perimeter shape (the shape of the
plateau) around the points. The trick would be to slice it at the
right location though, because you could end up getting no points
outside of the shape, but with the right selection you could easily
get the green shape you drew. This approach will work well and give you the green shape in your example if you choose the slice point wisely (which may be difficult to do). The big drawback of this approach is that it is very computationally expensive. More information:
http://en.wikipedia.org/wiki/Multivariate_kernel_density_estimation
Use alpha shapes to get a general shape the wraps tightly around
the outside perimeter of the point set. Then erode the shape a
little to force some points outside of the shape. I don't have a lot of experience with alpha shapes, but this approach will also be quite computationally expensive. More info:
http://doc.cgal.org/latest/Alpha_shapes_2/index.html

Best way to search a point across several polygons

I need to match a given point (lat, lon) against several polygons to decide if there is a match.
The easiest way would be to iterate over each polygon and apply the point-in-polygon check algorithm, but that is prohibitively expensive.
The next optimization that I did was to define a bounding rectangle for each polygon (upper bound, lower bound) and iteratively check the point against each bounding box (fewer comparisons as against checking all the points in the polygon).
Is there any other optimizations possible? Would a spatial index on the bound rectangle points or a geohash help?
Further optimizations:
The bounding box idea is good. Checking if a point is in a bounding box is extremely fast.
If you still need more speed, you can do more pre-calculation like this:
For each polgon create a bounding box.
Define equally sized "tiles" that cover your map.
For each tile, create a list of polygons that overlap. You can do that by first checking if the bounding box overlaps with the tile. If they do, you check if the polygon overlaps with the tile.
When searching, do this:
Determine the tile that you're in. That's a fast operation.
Now you have the list of potential polygons.
For each polygon, check if the point is in the bounding box.
if it is, check if the point is in the polygon using the more expensive algorithm that you've mentioned.
I've used this algorithm several times and it's very fast. By changing the tile size you can choose the right balance between memory footprint and performance:
Think of the extreme cases:
One huge tile that covers the entire map:
You'll get one list of all elements in your map, you'll have to check all of the bounding boxes.
Very tiny tiles (1x1 m for a map that only has a polygon per country):
You'll get a huge amount of tiles. All polygons will be split over many tiles, and each tile will only have one polygon. But, once you've figured out in which tile the point is (fast), it's almost 100% sure that there's just one polygon that needs to be checked.
You need to be somewhere in between. If you only need this once and a while, you might want to choose a low memory footprint over performance. The optimal tilesize can also depends on the homogeneity of the polygon sizes. So, there is no automatic way to calculate an optimal tile-size, and you'll just have to tweak a bit until you get it right.

Tools for 3D shape analysis

I have a 3D shape in a 3D binary image. Therefore, I have a list of all of the x,y,z points.
If I am to analyze a shape for various identification, such as "sphericity", "spiky"-ness, volume, surface area, etc., what are some of the choices do I have here?
Could you post a sample shape? Do you have a complete set of points on the surface and interior of the shape? Are the points evenly spaced? Is this synthetic data, or perhaps a point cloud from a 3D scan?
A few ideas:
Calculate the 3D convex hull of the points. This will give you the outer "envelope" of the points and is useful for comparison with other measurements. For example, you can compare the surface area of the convex hull to the surface area of the outer surface points.
Find the difference between "on" voxels in the convex hull and "on" voxels in the raw point set. You can then determine how many points are different, whether there is one big clump, etc. If the original shape is a doughnut, the convex hull will be a disk, and the difference will be the shape of the hole.
To calculate spikiness, you can think of comparing the Euclidean distance between two points (the "straight line" distance) and the shortest distance on the outer surface between those two points.
Compare the surface area of the raw data to the surface area after a 3D morphological "close" operation or some other smoothing operation.
To suggest a type of volume calculation, we'd need to know more about the point set.
Consider the Art Gallery Problem to 3D. Are there points on the surface not visible to certain points in the interior? Is the shape convex or star convex?
http://en.wikipedia.org/wiki/Art_gallery_problem
http://en.wikipedia.org/wiki/Star-convex_set
A good reference for geometric algorithms is Geometric Tools for Computer Graphics by Schneider and Eberly. It's pricey new, but you can probably find a cheap used copy in good condition at addall.com. I suspect you'll find all the answers you want and more in that book.
http://www.amazon.com/Geometric-Computer-Graphics-Morgan-Kaufmann/dp/1558605940
One of the authors maintains a site on the same subject:
http://www.geometrictools.com/
Another good textbook is Computational Geometry in C by Joseph O'Rourke.
http://www.amazon.com/Computational-Geometry-Cambridge-Theoretical-Computer/dp/0521649765/ref=sr_1_1?s=books&ie=UTF8&qid=1328939654&sr=1-1

Resources