How to find all points within polygon in postgis? - postgresql

I have locations stored in location_table (point_location geometry), now i draw a polygon on google map and pass that polygon (geometry) to backend, I want to find all the locations that are within that polygon.
SELECT POINT_LOCATION
FROM LOCATIONS_TABLW
WHERE ST_Contains(GeomFromEWKT(?), POINT_LOCATION);
This is giving me random results when I pass the polygon from google maps to backend. Its not giving me all points that are exactly within the polygon. It gives me points that are even outside the polygon.
What is the correct way to find all points within polygon in postgis with accuracy (including border cases also)
Update :
we tried with st_intersects() it did not work as well.
UPDATE
Please find below queries
SRID=4326;POLYGON((-103.30549637500008 20.852735681153252,-103.08103481249998 20.612974162085475,-101.6261045 20.537532106266806,-99.83567868749998 20.395877027062447,-99.80306537500002 22.0572706994358,-99.64994812500004 28.918636198451633,-121.1212769375 8.69559423007209,-103.30549637500008 20.852735681153252))
SRID=4326;POINT(-103.496956 20.722446)
SRID=4326;POINT(-103.4955 20.723544)
select ST_Intersects(GeomFromEWKT('SRID=4326;POINT(-103.496956 20.722446)'), GeomFromEWKT('SRID=4326;POLYGON((-103.30549637500008 20.852735681153252,-10
3.08103481249998 20.612974162085475,-101.6261045 20.537532106266806,-99.83567868749998 20.395877027062447,-99.80306537500002 22.0572706994358,-99.64994812500004 28.918
636198451633,-121.1212769375 8.69559423007209,-103.30549637500008 20.852735681153252))'));
This Should Return False, but it's returning true.

You can use
SELECT POINT_LOCATION
FROM LOCATIONS_TABLE
WHERE ST_Contains(ST_GEOMFROMTEXT('POLYGON((P1.X P1.Y, P2.X P2.Y, ...))'), LOCATIONS_TABLE.POINT_LOCATION);
Note: Polygon must be closed (that means the last coordinate == first coordinate). Second parameter POINT_LOCATION must be the geometry column in your point table.
UPDATE:
I have tried to replay your steps in my pg database. I created 2 tables, LOCATIONS_TABLE (id, geom) and POLYGON (id, geom). After that i filled the LOCATIONS_TABLE with the 2 points
SRID=4326;POINT(-103.4955 20.723544)
SRID=4326;POINT(-103.496956 20.722446)
After that i inserted the polygon in the POLYGON table
SRID=4326;POLYGON((-103.305496375 20.8527356811533,-103.0810348125 20.6129741620855,-101.6261045 20.5375321062668,-99.8356786875 20.3958770270624,-99.803065375 22.0572706994358,-99.649948125 28.9186361984516,-121.1212769375 8.69559423007209,-103.305496375 (...)
I visualized the situation in qgis, see picture below:
As you can see, the 2 points are inside the polygon. So i manually created a point outside the polygon. After that, you can use the following sql query, to see if the points are inside the polygon:
SELECT ST_Contains(polygon.geom, point.geom)
FROM public."LOCATIONS_TABLE" point, public."POLYGON" polygon
It returns t for the 2 points inside and false for the third point.

Related

How can I put the values in the table into the polygon function in the postgresql platform?

How can I put the values in the table into the polygon function?
Note : ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)') --coordinates are representations. What I want is to put the values in the table into the function.
you could use the geometry directly (if they were suitable, which they are not, see below).
SELECT ST_MakePolygon(wkb_geometry) FROM madened50 WHERE ...
BUT, a polygon is made of at least 4 points, with the 1st and last point being the same. In your table, the lines have 2 points only, so how exactly do you want to make a polygon from a line?
Don't forget that you can't just add one of point multiple times (the polygon will be invalid where the vertex is repeated, and a lot of function won't work properly with invalid geometries)
If it was only for the last point, which must be the same as the 1st one, you could add it though
SELECT ST_MakePolygon(ST_AddPoint(wkb_geometry, ST_StartPoint(wkb_geometry)))
FROM madened50 WHERE ...

How to fill in gaps between polygons using postgis functions

I have a similar case as shown in the below question.
https://gis.stackexchange.com/questions/293695/filling-gaps-between-polygons-using-qgis
That solution uses qgis, but I want to use a postgis function on a table on the geometry column. The solution talks about convex hull but not sure how to use the convex_hull postgis function here. I want to fill the gap by moving/merging the gap to the neighboring polygon.
As long as you have a column to group them by (e.g., "postal_code"), you can do:
SELECT
st_convexhull(st_collect(geom_column))
FROM
my_geom_table
GROUP BY
grouping_column -- e.g., "postal_code"

How to merge disjoint polygons into a single polygon in Postgis using Postgresql

I have a table with polygon geometries. The polygons are separate to each other like the picture below:
I want to get a single polygon formed after merging these polygons using Postgresql. Below is the expected polygon:
Please ignore the buffer in boundaries of red polygon, it is just to make the picture clearer.
My polygon table has two columns, id and geom. I have tried using ST_Collect, ST_MakePolygon, and ST_ExteriorRing but using these I only get MULTIPOLYGON having these polygons as it is. I need a single polygon. Any help would be appreciated.
You can use similar SQL to this
SELECT
ST_ConcaveHull(
ST_Collect( ARRAY(
select
"Poly"
from table_name
where "OBJECTID" in (5,15,2)
)
),0.99
)
and add some pic to better illustrate

Put points on the map, longitude/latitude not where they should be although SRID the same

Thank you for looking at this - I'm sure it's a simple question but this is all very new to me and after a lot of internet searching my points are still in the sea!
I have a set of UK postcode data that I have converted into latitude and longitude. I also have a UK counties shape file.
The code that I have used to convert the latitude/longitude to a geometry point column is as follows:
ALTER TABLE colic ADD COLUMN longlat geometry(POINT,27700);
update colic set longlat = st_setsrid(st_point( longitude, latitude), 27700);
And this produces a column that has values as follows (I've only included a couple!):
"0101000020346C000048BF7D1D3867E83FC05B2041F1334A40"
"0101000020346C0000F085C954C1A8F7BFA1F831E6AE954A40"
"0101000020346C000020D26F5F07CEF4BFE3361AC05B504A40"
"0101000020346C00007D3F355EBA49F73FB6847CD0B3614A40"
The .prj from my shape file is:
PROJCS["British_National_Grid", GEOGCS["GCS_OSGB_1936",
DATUM["D_OSGB_1936", SPHEROID["Airy_1830",6377563.396,299.3249646]],
PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],
PROJECTION["Transverse_Mercator"],
PARAMETER["False_Easting",400000.0],
PARAMETER["False_Northing",-100000.0],
PARAMETER["Central_Meridian",-2.0],
PARAMETER["Scale_Factor",0.9996012717],
PARAMETER["Latitude_Of_Origin",49.0], UNIT["Meter",1.0]]
And I set its SRID to 27700 when I upload it using the PostGIS shapefile uploader.
In PG Admin, when I ask:
select st_srid(geom) from counties limit 1;
select st_srid(longlat) from colic limit 1;
I get 27700 for both.
But...when I try any spatial query I get no response, and when I load the layers into quantum, the point data are off the tip of Cornwall in the north Atlantic, and only represented as one dot on the scale of the counties map.If I zoom in on them, they are 'there', but just not in east anglia where they should be!
This is my first attempt at both SQL and mapping - I'm sure there is something really simple that I have missed.
You are mixing up spatial references (SRS). The SRS in the .prj file (aka SRID=27700) is projected eastings and northings, which have units of metres. This is not latitude and longitude! Furthermore, it is a deception to call a column longlat when it isn't for longitude/latitude coordinates.
If you try to insert latitude/longitude in a column with SRID=27700, the points will not behave as expected, e.g., they will be in the far bottom left corner of a map.
If you have lat/long data from WGS84 (SRID=4326), you can transform this to eastings and northings:
UPDATE colic SET
geom = ST_Transform(ST_SetSRID(ST_Point(longitude, latitude), 4326), 27700);

Why can't I add a single value to an entire column in PostgreSQL PostGIS?

I'm new to PostgreSQL, so bear with me.
I have two tables, one called "polys" with several polygons and another called "box" that contains only one polygon (my bounding box). My query selects all the polygons in "polys" that fall within the bounding box "box" - a clip if you will. Both tables have two columns, one containing their ID's and another containing their GeoJSON called "the_geom".
What I want is one column containing IDs of polygons that fall within the bounding box, another column with these polygons' GeoJSONs called "the_geom_webmercator", another called "polygonarea" with each polygon's area, and then another column called "totalarea" which contains the SAME EXACT VALUE for each polygon (the value being the sum of all the polygons). However, simply asking for the SUM won't work since this returns only 1 value. Instead, I want this value to fill the entire column. Below is what I've tried; the `SUM...AS' is the portion in question.
SELECT polys.id, ST_Transform(ST_Intersection(polys.the_geom, box.the_geom),3857)
AS the_geom_webmercator,
ST_Area(ST_Transform(ST_Intersection(polys.the_geom,box.the_geom),3857))
AS polygonarea,
SUM(ST_Area(ST_Transform(ST_Intersection(polys.the_geom,box.the_geom),3857)))
AS totalarea FROM polys,box
If you use the SUM() aggregate-function you also need a GROUP BY statement.
I guess what you want is a WINDOW Function
http://www.postgresql.org/docs/9.1/static/tutorial-window.html
With window function you can calculate aggregates for single rows without GROUP BY.
SELECT
polys.id,
ST_Transform(ST_Intersection(polys.the_geom, box.the_geom),3857) AS the_geom_webmercator,
ST_Area(ST_Transform(ST_Intersection(polys.the_geom,box.the_geom),3857)) AS polygonarea,
SUM(ST_Area(ST_Transform(ST_Intersection(polys.the_geom,box.the_geom),3857))) OVER () AS totalarea
FROM polys,box