Sorry about the lack-lustre title, but it's hard to describe...
Lets, just say I have two tables (cad and cad_polygon)...
cad and cad_polygon share the same column that relates to one-another (cad_pid)...
cad has these columns: cad_pid, jrsdctn_id
while, cad_polygon has these columns: cad_pid, ogc_fid, wkb_geometry
Now, the below query I have working (half the day trying) selects a parcel based on degree from a long,lat co-ord, from that significantly smaller subset of polygons, it finds their distance in metres from the given long,lat co-ord, then displays only polygons who's centroid is within 500m of the long,lat co-ord.
SELECT SUBQUERY.cad_pid, SUBQUERY.ogc_fid, SUBQUERY.dist_meters,
SUBQUERY.wkb_geometry FROM (
SELECT cad_pid, ogc_fid,
CAST(ST_Distance_Sphere(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914)
) AS numeric
) AS dist_meters, wkb_geometry
FROM cad_polygon
WHERE ST_DWithin(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914),
0.01)
ORDER BY dist_meters ASC
) AS SUBQUERY
WHERE SUBQUERY.dist_meters < 500;
I want to add to this and using the list that this query spits out, join my other table (cad) so I can give the additional column "jrsdctn_id" for each resulting row... ie:
Sample data would be: cad:
cad_pid | jrsdctn_id
0001 | abc123
0002 | def456
0003 | dhk778
0004 | dsk730
cad_polygon:
cad_pid | ogc_fid | wkb_geometry
0001 | ht0101 | 67686687601010000200063D7987FF15ASD1518541DAW
0002 | hz4561 | 435453457601010000200063D7987FF15ASDFW4GF8DE4
0003 | yv0301 | 2626WD687601010000200063D7987FF15ASD1WE851D4D
0004 | vt9701 | D484DW4D8441D8W1C684V63D7987FF15ASD1D7DW4848D
Expected results:
cad_pid | jtsdctn_id | ogc_fid | dist_meters | wkb_geometry
0002 | def456 | hz4561 | 192.769 | 43545...
0004 | dsk730 | vt9701 | 342.548 | D484D...
If some sql wizard out there can help would be great!
A bit late, and the accepted answer is absolutely correct about the JOIN
, of course, but this actually is significantly GIS related, and it's awareness ultimately makes things easier for you:
You seem to be either using a custom CRS or ogr2ogr (or any GDAL/OGR function) didn't find a matching SRID/projection in PostGIS' spatial_ref_sys table; any PostGIS function using LonLat's as input for spherical/shperoidal algebra, however, will always assume your coordinates are in EPSG:4326 (WGS84).
If your LonLat's do not exactly match with those of WGS84, the results will be off!
Now, PostGIS also has the geography type, which again assumes EPSG:4326 coordinates, that will, if used with those functions, implicitly use meter as units and will be calculated on the WGS84 spheroid if used with the default ST_Distance
parameters (more precise but slightly slower than with use_spheroid := false
, which will calculate distance based on a sphere instead).
With this in mind, your query can be expressed as:
WITH
pt AS (
SELECT ST_Transform(ST_SetSRID(ST_MakePoint(0, 0), 900914), 4326)::geography AS geog
),
ctr AS (
SELECT *,
ST_Transform(ST_Centroid(wkt_geometry), 4326)::geography AS geog
FROM cad_polygon
)
SELECT ctr.cad_pid,
cad.jtsdctn_id,
ctr.ogr_fid,
ST_Distance(ctr.geog, pt.geog) AS distance_meter,
ctr.wkt_geometry
FROM ctr
JOIN cad
ON ctr.cad_pid = cad.cad_pid
WHERE ST_DWithin(ctr.geog, pt.geog, 500)
ORDER BY distance_meter ASC;
Note the use of CTEs to avoid transformation/casting for each processed row, and to make things more structured.
I just couldn't let this go...
You could use a JOIN
SELECT SUBQUERY.cad_pid, SUBQUERY.ogc_fid, SUBQUERY.dist_meters,
SUBQUERY.wkb_geometry, SUBQUERY.jrsdctn_id FROM (
SELECT cad_pid, ogc_fid,
CAST(ST_Distance_Sphere(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914)
) AS numeric
) AS dist_meters, wkb_geometry, cad.jrsdctn_id
FROM cad_polygon
INNER JOIN cad on cad.cad_pid = cad_polygon.cad_pid
WHERE ST_DWithin(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914),
0.01)
ORDER BY dist_meters ASC
) AS SUBQUERY
WHERE SUBQUERY.dist_meters < 500;
or better add the join in the outer
SELECT SUBQUERY.cad_pid
, SUBQUERY.ogc_fid
, SUBQUERY.dist_meters,
SUBQUERY.wkb_geometry, cad.jrsdctn_id
FROM (
SELECT cad_polygon.cad_pid, ogc_fid,
CAST(ST_Distance_Sphere(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914)
) AS numeric
) AS dist_meters
, wkb_geometry
FROM cad_polygon
WHERE ST_DWithin(
ST_Centroid(wkb_geometry),
ST_GeomFromText(
'POINT(00.0000 -00.0000)',
900914),
0.01)
ORDER BY dist_meters ASC
) AS SUBQUERY
INNER JOIN cad on cad.cad_pid = SUBQUERY.cad_pid
WHERE SUBQUERY.dist_meters < 500;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.