In PostGIS, how do I find all points within a polygon? - polygon

I am using PostgreSQL with the GIS extension to store map data, together with OpenLayers, GeoServer etc. Given a polygon, e.g. of a neighborhood, I need to find all LAT/LONG points stored in some table (e.g. traffic lights, restaurants) that are within the polygon. Alternatively given a set of polygons I would like to find the set of points within each polygon (like a GROUP BY query, rather then iterating over each polygon).
Are these functions something I need to program, or is the functionality available (as extended SQL)? Please elaborate.
Also for the simple 2D data I have do I actually need the GIS extension (GPL license is a limitation) or will PostgreSQL suffice?
Thanks!

In PostGIS you can use the bounding box operator to find candidates, which is very efficient as it uses GiST indexes. Then, if strict matches are required, use the contains operator.
Something like
SELECT
points,neighborhood_name from points_table,neighborhood
WHERE
neighborhood_poly && points /* Uses GiST index with the polygon's bounding box */
AND
ST_Contains(neighborhood_poly,points); /* Uses exact matching */
About if this is needed, depends on your requirements. For the above to work you certainly need PostGIS and GEOS installed. But, if bounding box match is enough, you can code it simply in SQL not needing PostGIS.
If exact matches are required, contains algorithms are publicly available, but to implement them efficiently requires some effort implementing it in a library which would then be called from SQL (just like GEOS).

I believe ST_Contains automatically rewrites the query to use the the GiST-indexed bounding box, as it notes:
"This function call will automatically
include a bounding box comparison that
will make use of any indexes that are
available on the geometries. To avoid
index use, use the function
_ST_Contains."
http://postgis.refractions.net/docs/ST_Contains.html

ST_Contains would solve your problem.
SELECT
polygon.gid, points.x, points.y
FROM
polygons LEFT JOIN points
ON st_contains(polygon.geom, points.geom)
WHERE
polygon.gid=your_id

Related

How to delete area of polygons that overlap?

I am trying to take a single layer of polygon buffers and delete the areas in which these circular buffers overlap (or intersect... I am not sure about the correct terminology here). I have so far tried the Intersection tool and Symmetrical difference tool, but these requires two layer inputs, and I am just working with a single layer. How can I accomplish this? I am working in QGIS.
Here is what I am working with:
I simply want to select and delete the areas where these circles overlap. I have searched this extensively online, but cannot find a solution that works for me, since I am only working with one layer.
you can try select by location analysis, if select "Where the feature" condition "Overlap", it select just overlap features.enter image description here
And delete after.
You can perform SQL Query with Execute SQL tool [
https://docs.qgis.org/3.16/en/docs/user_manual/processing_algs/qgis/vectorgeneral.html#id85]
Where Additional input datasources is your circle layer, that must have unique value, in my example attribute is called fid
Query is:
select c1.fid as fid1, c2.fid as fid2, intersection(c1.geometry,c2.geometry) as geometry
from input1 as c1, input1 as c2
where c1.fid > c2.fid and st_intersects(c1.geometry,c2.geometry)
query result is intersaction between geometries:
aftert that you can do symmetrical difference to optain
There is a new QGis plugin named "Buffer Without Overlaps" that works fine!

How does a non-tile based map works?

Ok, here is the thing. Recently i decided i wanted to understand how Random map generation works. I found some papers and some arguments. The most interesting one was "Diamond Square algorithm" and "Midpoint Displacement". I still have to try to apply those to a software, but other than that, i ran into this site: http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/
As you can see, the idea is to use polygons. But i have no idea how to apply that a Tile-Based map, not even how to create those polygons using the tools i have (c++ and sdl). I am assuming there is no way to do it ( please correct me if i am wrong.) But if i am not, how does a non-tile map works, and how are these polygons generated?
This answer will not give you directly the answers you're looking for, but hopefully will get you close enough!
The Problem
I think what blocks you is how to represent the data. You're probably used to a 2D grid that simply represent the type of each tile. As you know, this is fine to handle a tile-based map, but doesn't properly allow you to model worlds where tiles are of a different shape.
Graphs
What I suggest to you, is to see the problem a bit differently. A grid is nothing more than a graph (more info) with nodes that have 4 (or 8 if you allow diagonals) implicit neighbor nodes. So first, what I would do if I was you, would be to move from your strict standard 2D grid to a more "loose" graph, where each node has a position, a position, a list of neighbors (in most cases you'll have corners with 2 neighbors, borders with 3 and "middle" tiles with 4) and finally a rendering component which simply draws your tile on screen at the given position. Once this is done, you should be able to have the exact same results on screen that you currently have with your "2D Tile-Based" engine by simply calling the rendering component with each node who's bounding box (didn't touch it in what you should add to your node, but I'll get back to this later) intersects with the camera's frustum (in a 2D world, it would most likely if the position +/- the size intersects the RECT currently being drawn).
Search
The more generic approach will also help you doing stuff like pathfinding with generic algorithms that explore nodes until they find a valid path (see A* or Dijkstra). Even if you decided to stick to a good old 2D Tile Map game, these techniques would still be useful!
Yeah but I want Polygons
I hear you! So, if you want polygons, basically all you need to do, is add to your nodes a list of vertices and the appropriate data that you might need to render your polygons (either vertex color, textures and U/V maps, etc...) and update your rendering component to do the appropriate OpenGL (this for example should help) calls to draw your nodes. Once again, the first step to iteratively upgrade your 2D Tile Engine to a polygon map engine would be to, for each tile in your map, give each of your nodes two triangles, a texture resource (the tile), and U/V mappings (0,0 - 0,1 - 1,0 and 1,1). Once again, when this step is done, you should have a "generic" polygon based tile map engine. The creation of most of this data can be created procedurally by calculating coordinates based on tile position, tile size, etc...
Convex Polygons
If you decide that you ever might need NPCs to navigate on your map or want to allow your player to navigate by clicking the map, I would suggest that you always use convex polygons (the triangle being the simplest for of a convex polygon). This allows your code that assume that two different positions on the same polygon can be navigated to in straight line.
Complex Maps
Based on the link you provided, you want to have rather complex maps. In this case, the author used Voronoi Diagrams to generate the polygons of the map. There are already solutions to do triangulation like that, but you might also want to use other techniques that are easier to work with if you're just switching to 3D like this one for example. Once you have interesting results, you should consider implementing serialization to save/open your map data from the game. If you want to create an editor, be aware that it might be a lot of work but can be worth it if you want people to help you creating maps or to add elements to the maps (like geometry that's not part of the terrain).
I went all over the place with this answer, but hopefully it helps!
Just iterate over all the tiles, and do a hit-test from the centre of the tile to the polys. Turn the type of the tile into the type of the polygon. Did you need more than that?
EDIT: Sorry, I realize that probably isn't helpful. Playing with procedural algorithms can be fun and profitable. Start with a loop that iterates over all tiles and chooses randomly whether or not the tile is occupied. Then, iterate over them again and choose whether it is occupied or its neighbour is.
Also, check out the source code for this: http://dustinfreeman.org/toys/wall7-dustin.html

Fusion table layer filtering based on polygon

I've a fusion table map example with 5 layers given in this link : http://jsfiddle.net/ju2Re/
I want to filter the layers such that,
first I select a layer using dropdown : Office hierarchy > Zone > Bagalkot
Now I want to select the 220 KV stations only inside that polygon using the select box.
Please anyone help. Thank you in advance.
I don't believe you can do this natively with fusion tables (at least
not right now). The only query that can be used for "point in
polygon" analysis is:
ST_INTERSECTS(,
)
.
That takes a geometry as one argument, but the only values of are:
-
-
So if you have one point, you can use it to define a small circle and
use ST_INTERSECTS with a polygon, but that won't work for multiple
points.
With the current size of your tables you can use GViz to retrieve the
data from FusionTables and analyze it in the browser.
Proof of Concept (only works for "Geographical Heirarchy"/"District")
The code adds a "Contains" method to google.maps.Polygon, then iterates through the markers, displaying them if they are contained in the "activePolygon".
Proof of Concept should handle all the cases that have data

SQLite - Index for rectangle intersection without GIS extension

I have a quite large SQLite database to store some geo-data. I can't use the GIS extension and i'd also like everything to work with other databases as well.
My table structure is the following:
tbl(float fromLon, float fromLat, float toLon, float toLat, binary binaryData)
i store some binary-data within the database (the polygon of something) and store it's bounding-box in the form of fromLon,fromLat -> toLon,toLat.
Next i have some queries like "give me all binaryData (polygons) that are within this region (reqLlon1,reqLat1)-(reqLon2,reqLat2)".
a sample query would be:
SELECT binaryData
FROM tbl WHERE
(reqLon1 < toLon) AND
(reqLat1 < toLat) AND
(reqLon2 > fromLon) AND
(reqLat2 > fromLat)
The problem is, it seems that i can't figure the right index to speed things up.. a simple index like
idx1(fromLon,fromLat,toLon,toLat)
does not work out. I tried the same thing with MySQL (same layout, same index) and it states (explain select ..) that it only uses half of the index's length..
can someone give me a hint what the index should look like to work out? or could it be, that it's impossible?
You should consider using the R*Tree module.
An R-Tree is a special index that is designed for doing range queries.
R-Trees are most commonly used in geospatial systems where each entry
is a rectangle with minimum and maximum X and Y coordinates. Given a
query rectangle, an R-Tree is able to quickly find all entries that
are contained within the query rectangle or which overlap the query
rectangle. This idea is easily extended to three dimensions for use in
CAD systems. R-Trees also find use in time-domain range look-ups.

polygon to raster GIS

I have a shapefile of India with states (probably as polygons). I want to convert each polygon into equally divided cells ("raster" way), and populate (actually coloring) each cell by a value that would be calculated from an algorithm which is cell's location specific. This should be done for all the cells in the polygon (programmatically) so that at the end I have the shapefile, looking as a thematic (of what my algorithm calculates), raster image. I am not starting any image because the information is actually calculated value from algorithm and not coming from satellite imagery or anything like that.
In other words, it is not a vegetation or elevation thematic but something like population distribution, where each value (color) of cell represents a mean value of population there, showing wholly as a distribution at large scale.
Can any one please help how to do this using any open source application? (both as application and also programmatically using API like sharpmap) Please help
The GDAL utilities and scripting would be my choice.
http://www.gdal.org/index.html
I don't quite understand how you are going to decide cell values based on position, but have a look at the following utilites:
http://www.gdal.org/gdal_grid.html
http://www.gdal.org/gdal_rasterize.html
If you can't get the required output from the command line, then the GDAL functions can be scripted (C++ or Python have the most examples).
One easy way to do this would be to use Mapnik and its Python binding. See their site for a tutorial on thebasic usage and their XML configuration schema.
I've done this using MapScript (from UMN's Mapserver).
http://mapserver.org/mapscript/index.html#mapscript
It's fairly straight forward and has many bindings (PHP, Ruby, Python, .NET and so forth), but the API is the same across all bindings. Those bindings when I last used it were of varying quality and I'm not up to date on the current quality
I've done this using python and GDAL by following the instructions outlined here:
http://proj.lis.ic.unicamp.br/webmaps/docs/calc_ndvi/
I hope this helps.
ps. The site is in portugese, so if you don't speak the language you may find Google translate very useful. Good luck.
n

Resources