How to find all points away from some polygon? - postgresql

What I need is to find all points away from rectangle for 10km. Points geometry is the_geom1, rectangles (polygon) geometry is the_geom2. SRID of them is 4258.
I tried:
SELECT *
FROM table1,table2
WHERE ST_DWithin(table1.the_geom1,table2.the_geom2,10000)
and table1.gid=2;
But the result is not Ok. I get way too many results (everything is returned).
What am I doing wrong?

Your query should work. The big issue may be as described in https://gis.stackexchange.com/questions/32711/how-do-i-use-st-dwithin-with-meters which discusses unit conversion issues.
You may have an issue with unit selection or configuration.
If you are telling it, for example, that the geometries must be within 10000 miles, you would get just about everywhere. Even 10000km would likely return everything on the same continent.

Related

Why ST_Intersection from Postgis returns multilinestring for self-intersecting linestrings?

I am trying on PostgreSQL with the extension Postgis to get the geometry of a gps_trace that intersects a box, then i want to get one linestring for each distinct part of the trace in the box. In the following example with 1 trace and 1 box , that would mean ST_intersection returns me a multilinestring with 2 linestrings inside, so that i can extract each of them with ST_Dump()
The geometries are in epsg 4326, I use the request SELECT ST_Intersection(gps_traces.geom, grid.box)
FROM gps_traces, grid
But as a result, i get a multilestring with 34 geometries inside. After zooming a little, i discovered that when the line self-intersects, it seems to consider and register each part as a separate linestring although at the beginning, the trace was a linestring in one go.
I am extremely surprised of this behavior, and didn't find any documentation on the subject nor topics that talked about it, so i'm asking here how is build the geometry resulting from an intersection and why I get this behavior ?
This is the first time i get to use stackoverflow, so I apologize if some elements are missing

Can't extract geo keys when inserting large polygon

I have been battling this for the past 2 days and can't seem to get it working.
I have the polygon in this gist, which I'm trying to insert into collection with '2dsphere' index on the polygon field. I've gone through quite a few itterations, removing some points from the polygon, trying to sort it so that it's 100% counter-clockwise (which resulted in malformed polygon) and mongo still won't let me insert it. The error I'm seeing is just Can't extract geo keys: without any extra information at the end.
I went for help to geo json validator, which told me, that I need to have the first point at the end of the polygon, but that results in a Edges 0 and 395 cross.. I'm kinda getting hopeless, as I have about 1000 of these polygons from external API and can't go through them 1 by 1. Also the wierd thing is, if I swap latitude with longitude, mongo is able to insert them, but that's not a solution, even the documentation says longitude first. And as can be observed in the gist, pretty much every map I tried can display the polygon and I wasn't able to observe any kind of "disruption" or wierd edges.
I would love if someone could point out what's wrong with the polygon or gime me a nudge in the right direction.
Also this probably shouldn't change anything, but I'm using mongoose and I did try to insert this polygon manualy via the mongo shell.

Buffering multiple linestrings

I'm pretty new to postgresql, so there might be a pretty simple answer to my question, at least I hope so.
I have imported a table with thousands of single linestrings that represent the main roads of a country.
I'd like to buffer every single one of them and intersect the results with another polygon (Basically just a circle, but the thing is, that the position of the circle is dynamic, depending on the preferences of the user).
However, I don't know how to buffer all linestrings at once. It works just fine when I buffer and intersect just one linestring, but it's kinda crucial that I buffer all of them.
And importing the roads as a multilinestring with SPIT doesn't work at all.
So ... how do I make that happen? Any hints?
I'd really appreciate any help.
The best approach would be to simply add another column that represents the buffers of the roads and add a spatial index, ie,
alter table roads add column road_buffer geometry(POLYGON, SRID);
update table roads set road_buffer = st_buffer(roads, distance);
create index ix_spatial_road_buffer on roads using gist(road_buffer);
where POLYGON and SRID indicate the type and spatial reference ID of the column. You can omit this, although it is good practice to use a specific type and SRID. YOU could also use AddGeometryColumn for the same end.
You can now run a query against the buffered roads, which will be fast, as it is indexed, but return the actual roads, eg,
Select road_id, road from roads where st_intersects(road_buffer, circle);
Now, if you wanted to do it the other way, without actually having a pre-buffered linestring, you could do somthing like,
select road_id, road, road_buffer from
(select st_buffer(road, dist) as road_buffer, road, road_id
from roads where
st_intersects(st_expand(st_envelope(road), dist), circle)
) road_buff
where st_intersects(road_buffer, circle);
The trick here is that you compute the buffer in a subquery, but only for those linestrings/roads whose envelope (ie, minimum bounding rectangle) intersects with your circle -- a much faster calculation than buffering all linestrings. Note, also, the use of st_expand, by the same amount as the buffer distance, which basically expands the mbr and ensures you don't miss any potential candidates. I did a quick test on half a million random lines, and this approach was much faster (10x) than simply checking for circle intersections against the buffer of all points.
Actually I came up with a solution that works just fine.
I just buffered my linestrings externally (used qgis) and reuploaded the entire thing as one big polygon.
However, I'd still like to know how it is done while maintaining the linestring structure.
Both approaches that John Barça suggested would work for me.

How do I optimize point-to-circle matching?

I have a table that contains a bunch of Earth coordinates (latitude/longitude) and associated radii. I also have a table containing a bunch of points that I want to match with those circles, and vice versa. Both are dynamic; that is, a new circle or a new point can be added or deleted at any time. When either is added, I want to be able to match the new circle or point with all applicable points or circles, respectively.
I currently have a PostgreSQL module containing a C function to find the distance between two points on earth given their coordinates, and it seems to work. The problem is scalability. In order for it to do its thing, the function currently has to scan the whole table and do some trigonometric calculations against each row. Both tables are indexed by latitude and longitude, but the function can't use them. It has to do its thing before we know whether the two things match. New information may be posted as often as several times a second, and checking every point every time is starting to become quite unwieldy.
I've looked at PostgreSQL's geometric types, but they seem more suited to rectangular coordinates than to points on a sphere.
How can I arrange/optimize/filter/precalculate this data to make the matching faster and lighten the load?
You haven't mentioned PostGIS - why have you ruled that out as a possibility?
http://postgis.refractions.net/documentation/manual-2.0/PostGIS_Special_Functions_Index.html#PostGIS_GeographyFunctions
Thinking out loud a bit here... you have a point (lat/long) and a radius, and you want to find all extisting point-radii combinations that may overlap? (or some thing like that...)
Seems you might be able to store a few more bits of information Along with those numbers that could help you rule out others that are nowhere close during your query... This might avoid a lot of trig operations.
Example, with point x,y and radius r, you could easily calculate a range a feasible lat/long (squarish area) that could be used to help rule it out if needless calculations against another point.
You could then store the max and min lat and long along with that point in the database. Then, before running your trig on every row, you could Filter your results to eliminate points obviously out of bounds.
If I undestand you correctly then my first idea would be to cache some data and eliminate most of the checking.
Like imagine your circle is actually a box and it has 4 sides
you could store the base coordinates of those lines much like you have lines (a mesh) on a real map. So you store east, west, north, south edge of each circle
If you get your coordinate and its outside of that box you can be sure it won't be inside the circle either since the box is bigger than the circle.
If it isn't then you have to check like you do now. But I guess you can eliminate most of the steps already.

OpenStreetMap Api call returns empty set

I am trying to call OpenStreetMap API:
http://api.openstreetmap.org/api/0.6/map?bbox=43.65,-79.38,43.66,-79.37
It returns no error, but map is empty:
Do you have any ideas why?
thanks
I think for the given request, the empty dataset delivered is actually the correct response.
The API documentation says api/0.6/map returns
All nodes that are inside a given bounding box and any relations that reference them.
All ways that reference at least one node that is inside a given bounding box, any relations that reference them [the ways], and any
nodes outside the bounding box that the ways may reference.
All relations that reference one of the nodes, ways or relations included due to the above rules. (Does not apply recursively, see
explanation below.)
As far as I can see, your bounding box selects a bit of Antarctica. What data did you expect?
I guess, in OSM, Antarctica is just a way, describing its outline (and maybe some research stations somewhere). If you now ask for an area in the middle of nowhere there, there are no data to get. This is because within your bbox there are no nodes. The way for the outline/area of Antarctica is only fetched if at least one of its nodes lies within your bounding box.
PS: If you want a piece of Toronto (with lots of data), swap longitude and latitude values :)
https://wiki.openstreetmap.org/wiki/Download#Construct_a_URL_for_the_HTTP_API
it says the bounding box can only be 0.5 by 0.5 degrees. it also says you might want to try XAPI for such a large area