I'm in a process of developing an application and I would appreciate some help regarding an idea how to store data in mysql table.
I have two points - point A and point B which are start and end point.
I've already wrote some php function that will create rectangles similar to:
http://googlegeodevelopers.blogspot.com/2010/05/search-along-route-made-easy-with.html
However depending on the route and radius it generates different amount of rectangles. What is the best way to save those rectangles into the database, so later I can query the DB and check if another two points (start/end) are in any of those rectangles.
Can you give me an example?
The easiest way to do it is to store your rectangles as polygons, per
http://dev.mysql.com/doc/refman/4.1/en/polygon-property-functions.html
You can then use MBRIntersects to figure out if they intersect (or use MBRWithin or MBRContains, if you'd prefer), per
http://dev.mysql.com/doc/refman/5.1/en/functions-for-testing-spatial-relations-between-geometric-objects.html#function_mbrintersects
For funky-shaped polygons, this isn't adequate, but the MBR (minimum bounding box) of a rectangular bounding box will be exactly the same as the rectangle itself.
Related
I have a set of of polygons. Sometimes they are completely disconnected (like separate patches). Other times, two sides of two polygons may touch each other (when the polygons are adjacent like on a chess board). The polygons never cross each other. In other words, their intersection is always empty.
I need to check if a point is contained in any one of those polygons. Is there a way I can build a single geometry using these polygons and check if the point is in it?
Currently I'm building a long WHERE close with OR conditions and do something like the below:
st_contains(st_GeomFromText('POLYGON(("+polygon+"))'), st_GeomFromText(CONCAT('POINT()')))
Thanks.
In a MySQL database, how do I find circular areas that fall entirely or partially within a certain distance from another point? There are plenty of examples to find points within a certain radius, but not circular areas that intersect that certain radius.
I have a list of contractors that service certain areas (point and radius). Customers need to be able to find these contractors based on a distance from them.
I think you are looking for ST_Buffer, which will buffer a geometry by a certain distance. In your case this will turn your point into a circle, and you can then use ST_Intersects to find intersecting circles representing contractor areas.
Something like:
Select id from contractor c where intersects(c.geom, st_buffer(point, radius));
where obviously you need to provide values for point and a radius.
I have a x,y,z 3D points stored in MySQL,
I would like to ask the regions, slices or point neighbours.
Are there way to index the points using Peano-Hilbert curves to accelerate the queries?
Or are there more efficient way to store the 3D data in the MySQL?
thanks Arman.
I've personally never went this far, but I used a Z-curve to store 2D points. This worked quite well, and didn't feel the need to try to implement the hilbert curve for better results.
This should allow you to quickly filter out points that certainly are not close by. In an absolute worst case scenario you still need to scan more than 25% of your table to find points within an area.
The way to go about it is to split the x y z in binary and stitch them together into a single value using the curve. I wish I had a SQL script ready, but I just have one for the 2d z-curve which is a much much easier to do.
Edit:
Sorry you might already know all this already and really just looking for SQL samples, but I have some additions:
I'm not sure the 25% worst case scan is true as well for 3D planes. It might be higher, don't have the brainpower right now to tell you ;).
This type of Curve will help you find ranges of where you need to search. If you have 2 coordinates, you can convert these to the hilbert-curve number to find out which section of your table you need to look for items that do exactly match your query.
You might be able to extend this concept to find neighbours, but in order to use the curve you are still 'stuck' to look in ranges.
You can probably take the algorithm to create a geohash, and extend it to 3 coordinates. Basically, you define would have a world cube of possible 3d points, and then as you add more bits, you narrow down the cube. You then consistently define it so that the lower left hand corner has the smallest value, and you can perform range checks like:
XXXXa < the_hash < XXXXz
I am involved in a GIS project. I have a base map file (shape file) that contains the road layer for a large portion of a town. The problem is that the shape file contains only two features each containing around 500000 points each. The features are multipolygons containing a large no of polygons inside. I wish to convert it to numerous features each containing not more than one polygon. Is it possible? If yes, how?
Seems like what you have here is a multi-part feature. If you are using ArcGIS, you need to add the advance editor toolbar in your arcmap. Start an editing session and use the explode multi-part feature tool and then you will have one geometry for each record.
If you have connectivity information (e.g. you have polygons and not just points) it's not too tough to do a decent job of polygon reduction.
What I've done in the past consisted of two steps.
Any vertex that is surrounded by polygons, all of which are coplanar, can be removed. I did this by "sliding" the vertex to a neighbor vertex, that neighbor getting all of the test vertex's neighbors and any triangles that become degenerate (e.g. any triangles shared between the two vertices) were removed.
Any vertex which has two edges leaving opposite one another, where the polygons on either side are either completely nonexistent or are coplanar can also be similarly collapsed into a neighbor vertex, but obviously only one that is along one of the parallel edges.
note-
Two polygons are coplanar if they share at least one point in common and if they have the same normal. Since the candidate polygons are always attached to the candidate vertex, you just need to compare polygon normals. The normal can be computed by taking the cross product of two of the edges of the polygon.
Does anyone know of a way to fetch all polygons in a MySQL db within a given distance from a point? The actual distance is not that important since it's calculated for each found polygon later, but it would be a huge optimization to just do that calculation for the polygons that are "close".
I've looked at the MBR and contains functions but the problem is that some of the polygons are not contained within a bounding box drawn around the point since they are very big, but some of their vertices are still close.
Any suggestions?
A slow version (without spatial indexes):
SELECT *
FROM mytable
WHERE MBRIntersects(mypolygon, LineString(Point(#X - #distance, #Y - #distance), Point(#X + #distance, #Y + #distance))
To make use of the spatial indexes, you need to denormalize your table so that each polygon vertex is stored in its own record.
Then create the SPATIAL INDEX on the field which contains the coordinates of the vertices and just issue this query:
SELECT DISTINCT polygon_id
FROM vertices
WHERE MBRContains(vertex, LineString(Point(#X - #distance, #Y - #distance), Point(#X + #distance, #Y + #distance))
The things will be much more easy if you store UTM coordinates in your database rather than latitude and longitude.
I don't think there's a single answer to this. It's generally a question of how to organize your data so that it makes use of the spacial locality inherent to your problem.
The first idea that pops into my head would be to use a grid, assign each point to a square, and check select the square the point is in, and those around it. If we're talking infinite grids, then use a hash-value of the square, this would give you more points than needed (where you have collisions), but will still reduce the amount by a bunch. Of course this isn't immediately applicable to polygons, it's just a brainstorm. A possible approach that might yield too many collisions would be to OR all hashed values together and select all entries where the hashes ANDed with that value is non-zero (not sure if this is possible in MySQL), you might want to use a large amount of bits though.
The problem with this approach is, assuming we're talking spherical coordinates (lat, long generally does) are the singularities, as the grid 'squares' grow narrower as you approach the poles. The easy approach to this is... don't put any points close to the poles... :)
Create a bounding box for all of the polygons and (optionally storing these results in the database will make this a lot faster for complex polygons). You can then compare the bounding box for each polygon with the one round the point at the desired size. Select all the polygons which have intersecting bounding boxes.