I have a lot of polylines (polyline) and a polygon. Polylines can intersect with the polygon in different ways:
no intersection (polyline out of polygon)
no intersetion (polyline in a polygon)
one intersection (polyline starts/ends in polygon)
multiple intersections (polyline can for example start in polygon, go out of it and then return back inside...)
I need to calculate the total length of all polylines within the polygon. I'm using MSSQL 2016 Express version. Can it be done with just TSQL?
The answer is Yes - TSQL is turing-complete, meaning that you can implement any algorithm you want with it. It is more convenient to use than a turing machine but (arguably) less so than, for example, C# with a fully fledged development environment.
Related
My question is probably a duplicate, but all the answers I have seen so far do not satisfy me or still leaves me in doubt.
I have a web application that uses Google Maps API to draw and save shapes (circles and polygons) in a SQL Server DB with the geometry data type (where I save lat/long coordinates) and an SRID = 4326.
My objective is to later on, determine if a point is contained in the area of those circles/polygons thanks to SQL function geometry::ST_Intersects().
I have been told so far that my method wouldn't work because I am using geometry instead of geography. But to my surprise... after checking with a few tests, it works perfectly well with geometry and I am not able to understand why or how?
Could somebody explain to me why the geometry type works well with operations on lat/long whereas geography would be more suited?
I post as an answer because as comment is too long
geometry works well to the extent that your intersections are approximable to flat intersections.
the difference between geometry and geography consists in the fact that the former works by hypothesizing to work on plane surfaces the second on spherical surfaces. in the case in which the polygons in question are related to small areas in the order of a few thousand meters geometry works very well. the difference between measured distance by imagining that the points lie on a plane or that the points lie on the earth's sphere is so small as to be negligible. Unlike the question if the points are a few hundred kilometers in this case the distance measured in the plane or on the sphere is very different and proportionally is also the result of the intersection between these areas
I would like to buffer the warning polygon by two miles can anyone help me with
this so if ema personal are with in to miles of the warning the are listed, I've been trying to use ST Buffer (to expand the polygon coverage for the search) but cant seem to get it right? Is it in Meters (3218.69)? I'm using the latest opengeo suite.
SELECT DISTINCT ON (ema.name)
ST_X(ema.geom),ST_Y(ema.geom),ema."name", torpoly.expire
FROM ema INNER JOIN torpoly ON ST_Within(ema.geom, ST_BUFFER(torpoly.geom)
ORDER BY ema."name"
Your options are either:
Use an appropriate projected coordinate system for the region that uses linear units in metres or feet (UTM, State plane, etc.). All distance calculations on geometry types use a Cartesian coordinate system, which is quick and simple.
Use the geography type, which does distance calculations on objects with EPSG:4326 (lat/lon) with distance units in metres. If you don't want to change the data types, you can use a geom::geography cast, and maybe make an index on that cast.
And never do ST_Within(.., ST_Buffer()) for this type of analysis. It is slower and imperfect. Instead, use ST_DWithin, which finds all geometry/geography objects within a distance threshold of each other, which is just like a buffer. This function may use a spatial GiST index, if present.
I'm trying to use path finding on a series of convex polygons, rather than waypoints. To even further complicate this, the polygons are made by the users, and may have inconsistent vertices. For example:
We know the object is X wide by Y deep, and that the polygons have vertices at certain locations. Is there a specific algorithm to find the fastest way to the goal while keeping the entire object in the polygons (If I understand correctly, A* only works on waypoints)? How do you handle the vertices not being the same object but being at the same location?
EDIT: The polygons are convex; It's 2 separate polygons with the edges on the line.
Also, how do you implement * pathfinding, as a node based system wouldn't work in a 'infinite' resolution polygon?
In general, all shortest-path segments will have, as end-points, either polygon vertices or the start and goal points. If you build a graph that includes all those segments (from the start to each "visible" polygon vertex, from the goal to each "visible" polygon vertex, and from each polygon vertex to each other polygon vertex) and run A* on that, you have your optimal path. The cost of building the graph for A* is:
For each vertex, a visibility-test to find visible vertices: the simple algorithm (for each pair of vertices, see if the segment from one to another lies inside the polygon) is O(n^3). Building convex polygons and processing them independently, or using a smarter "radial sweep" algorithm can greatly lower this, but I suspect it is still around O(n^2).
For each query (from a start-point to a goal-point), O(n) for the visibility-test to find all vertices that it can see.
If you are only going to apply A* once, then the price of building the fixed part of the A* graph for a single traversal may be somewhat steep. An alternative is to build the graph incrementally as you use it:
Java code implementing the above approach can be found here.
The polygons in your drawing are not convex. For convex polygons, you can place a way point in the middle of each each edge and then apply A*. And, of course, you need to fix inconsistent vertices.
I would like to be able to map geographic points from WGS84, I believe, formatted for ms sql server, to the set of cells it would touch if the same coordinate pair were to be tessallated into an sql server spatial index with 4 hiearchical grids of 256 cells each.
The sql server 2008 spatial index does not ideally suit our needs because it doesn't support the use of both geographic and non-geographic data within the same index.
If we knew how to perform the translation ourselves it would seem like that would allow us to bypass the above limitation.
this page shows visually how a geography point can be mapped to planar cells which can be individually encoded as a sequence of from 1 and up to 4 positive integers. For an example of numbered cells please refer to the section "Deepest-Cell Rule" within the linked page.
I'm basically looking for pseduo-code on how to do just that.
Any help will be appreciated and if you know the algorithmic details that would be very much appreciated.
Thank you in advance.
A simple solution is to interleave x-and y co-ordinate, like in a morton curve a.k.a z curve. You can verify it by calcuting the upper bound using the most significant bit. Bing maps uses a morton curve:http://msdn.microsoft.com/en-us/library/bb259689.aspx but a hilbert curve is much more complicated but also better in most cases. In hilbert curve it's using a gray code for the co-ordinate. Here is some code example:Mapping N-dimensional value to a point on Hilbert curve.
There are two polygons given. how can one determine whether one polygon is inside, outside or intersecting the other polygon?
Polygons can be Concave or convex.
You want to use the separating axis theorem for convex polygons.
Basically, for each face of each polygon you project each polygon onto the normal of that face and you see if those projections intersect.
You can perform various tricks to reduce the number of these computations that you have to perform- for example, you can draw a rectangle around the object and assume that if two objects' rectangles do not intersect, they themselves do not intersect. (This is easier because it's less computationally expensive to check the intersection of these boxes, and is generally quite intuitive.)
Concave polygons are more difficult. I think that you could decompose the polygon into a set of convex polygons and attempt to check each combination of intersection, but I wouldn't consider myself skilled enough in this area to try it.
Generally, problems like that are solved easily by a sweep-line algorithm. However, the primary purpose and benefit of using the sweep-line approach is that it can solve the problem efficiently when input consists of two relatively large sets of polygons. Once the sweep line solution is implemented, it can also be efficiently applied to a pair of polygons, if need arises. Maybe you should consider moving in that direction, in case you'll need to solve a massive problem in the future.
However, if you are sure that you need a solution for two and only two polygons , then it can be solved by a sequential point-vs-polygon and segment-vs-polygon tests.
There is an easyish method to check whether a point lies in a polygon. According to this Wikipedia article it is called the ray casting algorithm.
The basic idea of the algorithm is that you cast a ray in some arbitrary direction from the point you are testing and count with how many of the edges of the polygon it intersects. If this number is even then the point lies outside the polygon, otherwise if it is odd the point lies inside the polygon.
There are a number of issues with this algorithm that I won't delve into (they're discussed in the Wikipedia article I linked earlier), but they are the reason I call this algorithm easyish. But to give you an idea you have to handle corner cases involving the ray intersecting vertices, the ray running parallel and intersecting an edge and numeric stability issues with the point lying close to an edge.
You can then use this method in the way Thomas described in his answer to test whether two polygons intersect. This should give you an O(NM) algorithm where the two polygons have N and M vertices respectively.
Here is a simple algorithm to know if a given point is inside or outside a given polygon:
bool isInside(point a, polygon B)
{
double angle = 0;
for(int i = 0; i < B.nbVertices(); i++)
{
angle += angle(B[i],a,B[i+1]);
}
return (abs(angle) > pi);
}
If a line segment of A intersects a line segment of B then the two polygons intersect each other.
Else if all points of polygon A are inside polygon B, then A is inside B.
Else if all points of polygon B are inside polygon A, then B is inside A.
Else if all points of polygon A are outside polygon B, then A is outside B.
Else the two polygons intersect each other.