Postgis and Postgres: How to perform a ST_Contains query with geometry array? - postgresql

I have a boundary which is stored in a geometry array. (like {...,...,...})
My goal is to perform a ST_Contains query. I want see whether a node is inside that boundary or not.
I tried something like
SELECT ST_Contains(ST_Polygonize((SELECT CAST(bt.geomarray AS geometry[]) FROM boundarytable AS bt)), nodetable.geom)
But I always get errors like "Invalid hex character (,) encountered".
Can anybody show me the right way to do this?

Now that I know how to do it, I'm answering this question by myself.
We do not have to use an array. We step through each node's geom and create the polygon. We store the polygon in polygontable. (Notice: don't forget you need the polygon to be closed, so you have to add the first node as last node again in boundarytable before you perform the query. Otherwise you will get an error):
SELECT ST_MakePolygon(ST_MakeLine(bt.geom)) AS geomboundary
INTO TABLE polygontable
FROM boundarytable AS bt
GROUP BY bt.dummy -- (just a constant value to round up all bt.geom)
Then we can perform the ST_Contains query like
SELECT *, ST_Contains((SELECT geomboundary FROM polygontable), anytable.geom)

Related

i'm working with postgreSQL with converting long/lat to point and also want to make line with that point

i'm working with postgreSQL with converting long/lat to point and also want to make line with that point
select bs1.rental_shop_name,
bs1.lon,
bs1.lat,
bs2.rental_shop_name,
bs2.lon,
bs2.lat,
count(*),
ST_MakeLine(ST_MakePoint(bs1.lon, bs1.lat), ST_MakePoint(bs2.lon, bs2.lat))
from bikeuser as bu
join bikestation as bs1 on bs1.rental_shop_code = bu.rental_shop_code
join bikestation as bs2 on bs2.rental_shop_code = bu.return_shop_code
group by bs1.rental_shop_name,
bs1.lon,
bs1.lat,
bs2.rental_shop_name,
bs2.lon,
bs2.lat,
ST_MakeLine(ST_MakePoint(bs1.lon, bs1.lat), ST_MakePoint(bs2.lon, bs2.lat))
order by count desc limit 40
but result is failed and msg is
SQL state: 42883 the st_makepoint does not exist and also have to use explicit converter
also i tested with simple form like this.
SELECT ST_MakePoint(-71.1043443253471, 42.3150676015829);
BUT ITS SAME RESULTS...
Just ST_MakePoint is not enough with lat long. You have to set SRID of the geometry as well. If the data comes from WGS84(which usually is the case with lat long), you need to apply ST_SetSRID on the geometry.
ST_MakeLine(ST_SetSRID(ST_MakePoint(bs1.lon, bs1.lat),4326), ST_SetSRID(ST_MakePoint(bs2.lon, bs2.lat),4326))
You should take into account your own data SRID.

Problems with spatial join

I am new to sql, and attempting to use it to speed up spatial analysis on a set of ~1.2 million trips from a csv that contains the lat and lon for pickup and dropoff points.
What I am trying to do in plain English is:
select all trips that start in the area of interest (loaded into my database as a shapefile) into one table
select all trips that end in the area of interest into another
-perform a spatial join between these points and a shapefile of census tracks (which contains neighborhood names)
count by neighborhood name to list the most frequent origins/destination of trips to/ from the area of interest.
The code I am working with is below (If its helpful, NTA or neighborhood tabulation area, is the neighborhood name which I want to display in my table at the end of this operation) :
--Select all trips that end in project area
SELECT *
INTO end_PA
FROM trips, projarea
WHERE ST_Intersects(trips.dropoff, projarea.geom);
--for trips that end in project area - index by NTA of pick up point
ALTER TABLE end_PA ADD COLUMN GID SERIAL;
CREATE TABLE points_ct_end AS
SELECT nyct2010.ntacode as ct_nta, end_PA.gid as point_id
from nyct2010, end_PA WHERE ST_Intersects(nyct2010.geom , end_PA.pickup);
--Count most common NTA
--return count for each NAT as a csv
copy(
select count(ct_nta) from points_ct_end
group by ct_nta
order by count desc)
to 'C://TaxiData//Analysis//Trips_Arriving_LM.csv' DELIMITER ',' CSV HEADER;
However, I am having problems from the very start - ST_Intersects does not return any points within the area of interest!
Troubleshooting solutions I have tried thus far:
My first thought is that the points weren't in the correct SRID. When I created the 'dropoff' point I set the SRID to 4326. I tried both using ST_SetSRID to change the projection of both data sets to 4326, and manually re projecting the shapefiles to 4326 in ArcMap - but neither worked.
I plotted a small sample of the points from the 'trips' data set in Arc Map to ensure they were correctly projected and overlapping with the ProjArea shapefile. They are.
I imported the multipoint shapefile this created into my geo database to test if that worked with ST_Intersects. Nope.
I tried using ST_Within. This threw the error message:
ERROR: function st_within(character varying, geometry) does not exist
....
HINT: No function matches the given name and argument types. You
might need to add explicit type casts.
I am using Big SQL and postgres
Thanks!!
My first thought is that the points weren't in the correct SRID. When I created the 'dropoff' point I set the SRID to 4326. I tried both using ST_SetSRID to change the projection of both data sets to 4326, and manually re projecting the shapefiles to 4326 in ArcMap - but neither worked.
ST_SetSRID doesn't change the projection (reproject). It just changes the internal representation. This can totally screw everything up if the previous SRID matched the input data. You likely wanted ST_Transform().
There isn't enough information here to trouble shoot this problem. However, we can answer this...
ERROR: function st_within(character varying, geometry) does not exist
This simply means the first argument is not a geometery. Of course, we can't do anything with that at all because we don't have your query that you tried with ST_Within().
Your syntax for ST_Intersects() looks to be right. But, there simply isn't enough information provided to help. Show some schema and sample data.

Orient SQL - Filter result set using WHERE?

I've got a bit of a semantic question about Orient SQL queries.
Take for example this very simple graph:
v(#12:1 User) --> e(#13:1 FriendOf) --> v(#12:2 User)
In other words, a given User with an rid of #12:1 is friends with another user with an rid of #12:2.
To get the friends of user #12:1, one might express this in Orient SQL like so:
SELECT EXPAND(both("FriendOf")) FROM #12:1
This query would return a result list comprised of the User with rid #12:2.
Now lets say I want to filter that result list by an additional criteria, like say a numeric value ("age"):
SELECT EXPAND(both("FriendOf")) FROM #12:1 WHERE age >= 10
The above query would filter the CURRENT vertex (#12:1), NOT the result set. Which makes sense, but is there a way to apply the filter to the EXPAND(both("FriendOf")) result rather than the current vertex? I know I can do this with gremlin like so:
SELECT EXPAND(gremlin('current.both("FriendOf").has("age",T.gte,10)')) FROM #12:1
But the above does not seem to make use of indexes (at least not when I ask it to explain). For very large data sets, this is problematic.
So is there a proper way to apply a WHERE statement to the resulting data set?
Thanks !
... is there a way to apply the filter to the EXPAND(both("FriendOf")) result rather than the current vertex?
The simple answer is to embed your basic "SELECT EXPAND ..." within another SELECT, i.e.
SELECT FROM (SELECT EXPAND(both("FriendOf")) FROM #12:1) WHERE age >= 10
By the way, on my Mac, the above took .005s compared to over 2s for the Gremlin version. There must be a moral there somewhere :-)

COUNT(field) returns correct amount of rows but full SELECT query returns zero rows

I have a UDF in my database which basically tries to get a station (e.g. bus/train) based on some input data (geographic/name/type). Inside this function i try to check if there are any rows matching the given values:
SELECT
COUNT(s.id)
INTO
firsttry
FROM
geographic.stations AS s
WHERE
ST_DWithin(s.the_geom,plocation,0.0017)
AND
s.name <-> pname < 0.8
AND
s.type ~ stype;
The firsttry variable now contains the value 1. If i use the following (slightly extended) SELECT statement i get no results:
RETURN query SELECT
s.id, s.name, s.type, s.the_geom,
similarity(
regexp_replace(s.name::text,'(Hauptbahnhof|Hbf)','Hbf'),
regexp_replace(pname::text,'(Hauptbahnhof|Hbf)','Hbf')
)::double precision AS sml,
st_distance(s.the_geom,plocation) As dist from geographic.stations AS s
WHERE ST_DWithin(s.the_geom,plocation,0.0017) and s.name <-> pname < 0.8
AND s.type ~ stype
ORDER BY dist asc,sml desc LIMIT 1;
the parameters are as follows:
stype = '^railway'
pname = 'Amsterdam Science Park'
plocation = ST_GeomFromEWKT('SRID=4326;POINT(4.9492530 52.3531670)')
the tuple i need to be returned is:
id name type geom (displayed as ST_AsText)
909658;"Amsterdam Sciencepark";"railway_station";"POINT(4.9482893 52.352904)"
The same UDF returns quite well for a lot of other stations, but this is one (of more) which just won't work. Any suggestions?
P.S. The use of the <-> operator is coming from the pg_trgm module.
Some ideas on how to troubleshoot this:
Break your troubleshooting into steps. Start with the simplest query possible. No aggregates, just joins and no filters. Then add filters. Then add order by, then add aggregates. Look at exactly where the change occurs.
Try reindexing the database.
One possibility that occurs to me based on this is that it could be a corrupted index used in the second query but not the first. I have seen corrupted indexes in the past and usually they throw errors but at least in theory they should be able to create a problem like this.
If this is correct, your query will suddenly return rows if you remove the ORDER BY clause.
If you have a corrupted index, then you need to pay close attention to hardware. Is the RAM ECC? Is the processor overheating? How are you disks doing?
A second possibility is that there is a typo on a join condition of filter statement. Normally this is something I would suspect first but it is easy enough to weed out index problems to start there. If removing the ORDER BY doesn't change things, then chances are it is a typo. If you can't find a typo, then try reindexing.

How to put together two queries?

In the title is what I need.
CREATE TABLE newTable1 AS SELECT t2.name,t2.the_geom2
FROM t1,t2
WHERE ST_Contains(ST_Expand(t2.the_geom2,0.05),t1.the_geom1)
and t1.gid=2;
CREATE TABLE newTable2 AS SELECT t1.the_geom,t1.label FROM t1 WHERE t1.gid=2;
First query result is all points within polygon and apart from it for 5min where this polygon has gid=2. But I also want to display this polygon. I tried to write in first query
... AS SELECT t2.name,t2.the_geom2,t1.the_geom1,t1.label ...but got only points without polygon...
This question is linked with already asked question "How to find all points away from some polygon?". But didn't get answere, so please...
And is ST_expand ok solution or it will be better to use ST_DWithin or ST_buffer ?
You can't combine two CREATE TABLE statements into one. Why are you creating tables if you are just querying data?
It sounds like what you are really trying to do is one query that will give you the points within the polygon and the polygon itself. Something like this?
SELECT
t1.the_geom AS polygon, t1.label AS polygon_label,
t2.the_geom2 AS point, t2.name AS point_name
FROM
t1, t2
WHERE
ST_Contains(ST_Expand(t2.the_geom2,0.05), t1.the_geom1)
AND t1.gid = 2;
If this is still not clear, post your complete table definitions and more details about what you are trying to do.