PostGIS find linestrings that are connected - sql

Hi i am trying to get all linestrings that are close to the nodes of other linestring
I tried:
SELECT *
FROM lines p
JOIN lines ps ON( ST_Buffer(p.geom, 0.01) && ps.geom
AND ST_Intersects(st_buffet(p.geom, 0.01), ps.geom))
But I also get lines that intersects.
There is function ST_Touches() however i can't figure out how can I add some tolerance. Maybe there is a way to make buffer over linestring nodes?

You would need to extract the nodes using st_dumpPoints, then you can join the line to these points. It is better to use st_dwithin rather than an inexact buffer.
The query would be similar to
SELECT *
FROM lines p
JOIN
(SELECT *, (ST_DumpPoints(geom)).geom
FROM lines ps) as pts
ON st_dwithin(p.geom, ps.geom, 0.1);
You might want to select something else than *, as you would get 3 geometries per row (1st line, 2 line, node of contact)
PS: regarding st_touch, the two lines can still touch each others between 2 vertices.

Related

How to get polygons contained within another polygon, including those that touch the border in BigQuery Standard SQL?

I'm trying to get blockgroups contains within a designated market area polygon in BigQuery. I've tried using st_contains and st_covers but I still only get the completely contained ones (and not the bordering ones:
SELECT a.blockgroup_geom as the_geom,
a.geo_id,
c.total_pop
FROM `bigquery-public-data.geo_census_blockgroups.us_blockgroups_national` a
join `bigquery-public-data.census_bureau_acs.blockgroup_2018_5yr` c
on a.geo_id = c.geo_id
join `bigquery-public-data.geo_us_boundaries.designated_market_area` b
on st_covers(b.dma_geom,a.blockgroup_geom)
where b.dma_name = 'Milwaukee, WI'
What do I need to do to get all of the blockgroups within the dma polygon?
looks like the two datasets are not exactly aligned, so any slight discrepancies between the two polygons, or errors due to planar to spherical conversion prevent perfect nesting of the polygons.
This post has deeper discussion and an idea how to handle this: https://mentin.medium.com/creating-spatial-hierarchy-2ba5488eac0a
Here I would try ST_Intersects condition and check area of intersection to see if the larger part of the blockgroup belongs to DMA:
SELECT a.blockgroup_geom as the_geom,
a.geo_id,
c.total_pop,
(st_area(st_intersection(b.dma_geom,a.blockgroup_geom))
> 0.75 * st_area(a.blockgroup_geom)) as mostly
FROM `bigquery-public-data.geo_census_blockgroups.us_blockgroups_national` a
join `bigquery-public-data.census_bureau_acs.blockgroup_2018_5yr` c
on a.geo_id = c.geo_id
join `bigquery-public-data.geo_us_boundaries.designated_market_area` b
on st_intersects(b.dma_geom,a.blockgroup_geom)
where b.dma_name = 'Milwaukee, WI'
Does this result make sense? I've colored green polygons with mostly = true, and blue those with mostly = false:

Joining point value to polygon with With statements

I have loaded a function hex_grid, it works fine see here but now I have a hexagonal grid I would like to add up all the values from the overlapping centroid points from a polygon layer. I've used with statements to keep things a little tidy, both select statements work as expected, my problem occurs when joining, clearly I've done something wrong but I just can't see it, any help would be appreciated. Here's the code. The hex and points are both in the same crs.
with hex AS(
SELECT hex_grid(
1,
(ST_XMIN(sa.geom)),
(ST_YMIN(sa.geom)),
(ST_XMAX(sa.geom)),
(ST_YMAX(sa.geom)),
32635, 32635, 32635) as geom_h
FROM geodata.study_area sa),
points AS(
SELECT count(*) as count, ST_Centroid(su.geom) AS geom_p
FROM clas.survey_unit su
group by su.geom
)
SELECT hex.geom_h, points.count
FROM hex
JOIN points
ON ST_Contains(points.geom_p, hex.geom_h)
group by hex.geom_h, points.count;
ST_Contains should have the polygon first, which contains the points
ON ST_Contains(hex.geom_h,points.geom_p)

find number of polygons a line intersects

I am working with SQL Server and spatial types. Have found the very interesting. I have reached a situation and I am not sure how I might work it out. Let me outline
I have 2 points (coordinates) eg. 3,9 and 50, 20 - this is a straight line, joining such.
I have multiple polygons (50 +).
I want to be able to calculate how many polygons that the above line passes through. What I mean by pass through, when I join the 2 coordinates, how many polygons the line intersects? I want to work this out with a SQL query.
Please let me know if not clear - it is difficult to explain!
Based on your coordinates, I'm assuming geometry (as opposed to geography), but the approach should hold regardless. If you have a table dbo.Shapes that has a Shape column of type geometry and each row contains one polygon, this should do:
declare #line geometry = geometry::STLineFromText('LINESTRING(3 9, 50 20)', 0);
select count(*)
from dbo.Shapes as s
where s.shape.STIntersects(#line) = 1;
If you want to know which polygons intersect, just change the count(*) to something more appropriate.

How to find the points that did not intersect with STIntersect using SQL Server

I performed STInteract using two tables and the intersections of points onto a given polygon. I have converted all the tables to have geometries for all. I am having a problem writing the query for this. I am trying to look for the points that did not intersect.
These are my two table
PO_Database = contains the points
POLY_Database = Polygon of interest
This is my script:
SELECT GEOM
FROM [dbo].[PO_Database] as PO
JOIN [dbo].[POLY_Database] as p ON hwy.GEOM.STIntersects(p.NEATCELL) = 1
I tried changing the value from 1 to 0 but I get repeating values of the geometry for when the query is run with 0. How do I write the query to give me the names of the points that did not intersect with the polygon. Also is there a way to do checks if the intersects where done right.
If you get repeating values, you probably have multiple rows in the POLY_Database table. If you want to find the points that do not intersect any of those polygons, try this query:
SELECT GEOM
FROM [dbo].[PO_Database] as PO
WHERE NOT EXISTS (
SELECT * FROM [dbo].[POLY_Database] as p
WHERE hwy.GEOM.STIntersects(p.NEATCELL) = 1
)

spatial data query

I have the following query which does a self join with a table and outputs all the points of intersections between lines.
insert into road_intersection
select nextval('road_intersection_id_seq'), a.road_id, b.road_id, st_intersection(a.road, b.road), st_centroid(st_intersection(a.road, b.road))
from polygon_road a, polygon_road b
where st_intersects(a.road, b.road) AND a.road_id!=b.road_id
BUT it outputs duplicate values for each point of intersection since it computes the point of intersection for each road. EG:
70;71;POINT_OF_INTERSECTION
71;70;POINT_OF_INTERSECTION
70 AND 71 are both id values of two distinct roads. As you can see the point of intersection has been computed twice for the same two roads.
Any suggestions how i can solve this issue and only one point of intersection would be computed?
Try something like:
select nextval('road_intersection_id_seq'),
a.road_id,
b.road_id,
st_intersection(a.road, b.road),
st_centroid(st_intersection(a.road, b.road))
from polygon_road a, polygon_road b
where st_intersects(a.road, b.road)
--AND a.road_id!=b.road_id --not needed any more
AND a.road_id < b.road_id
It will leave only one of the intersections (the one, where the first road has smaller id)