Line within range of another line?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Line within range of another line?

orkun
Hi,
How can I find Line within range of another line?
I mean I try to find line section within certain range of another line.
For example, road lines close to fault lines.

Ps : I know that using st_buffer causes performance issue.
Can you give any advice?

Regards



--
Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users
Reply | Threaded
Open this post in threaded view
|

Re: Line within range of another line?

Regina Obe

Use ST_DWithin  (works for both geography and geometry) and any kind of geometry, not just lines . 

My example is for geography since units are always in meters.  For geometry units you have to specify based on your spatial_ref_sys and geometries have to have same spatial ref sys

 

something like below will return all roads that are within 100 meters of a fault line

 

SELECT l.gid, l.geog

FROM roads As l

WHERE EXISTS (SELECT 1 FROM fault_lines As fl WHERE ST_DWithin(fl.geog, l.geog, 100) );

 

If you need to know the exact fault lines, do a JOIN instead – keep in mind if a road is close enough to more than one fault line, it will be duplicated

 

SELECT l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) );

 

 

 

If you want jus the closes fault line within 100 meters use DISTINCT ON

 

SELECT DISTINCT ON(l.gid)  l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) )

ORDER BY l.gid, dist;

 

 

 

Hope that helps,

Regina

http://www.postgis.us

http://www.paragoncorporation.com

 

http://postgis.net

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Sunday, October 30, 2016 2:59 AM
To: PostGIS Users Discussion <[hidden email]>; PostGIS Users Discussion <[hidden email]>
Subject: [postgis-users] Line within range of another line?

 

Hi,

How can I find Line within range of another line?

I mean I try to find line section within certain range of another line.

For example, road lines close to fault lines.

 

Ps : I know that using st_buffer causes performance issue.

Can you give any advice?

 

Regards

 



--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

 


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users
Reply | Threaded
Open this post in threaded view
|

Re: Line within range of another line?

orkun
Thank you,

It was great help.

Later, I had built this:
---
WITH faultbuffer as (
   SELECT gid,ST_Union(St_Buffer(the_geom,100)) as geom from fault4analyse group by gid
)
 
SELECT road.gid,ST_Intersection(road.the_geom,faultbuffer.geom ) as road_fayBuffer from road4analyse as road , faultbuffer 
  WHERE ST_Intersects(road.the_geom, faultbuffer.geom ) 
---

and it is reasonably fast.

Does it do same thing you have offered ?

kind regards


On Sun, Oct 30, 2016 at 10:55 AM, Regina Obe <[hidden email]> wrote:

Use ST_DWithin  (works for both geography and geometry) and any kind of geometry, not just lines . 

My example is for geography since units are always in meters.  For geometry units you have to specify based on your spatial_ref_sys and geometries have to have same spatial ref sys

 

something like below will return all roads that are within 100 meters of a fault line

 

SELECT l.gid, l.geog

FROM roads As l

WHERE EXISTS (SELECT 1 FROM fault_lines As fl WHERE ST_DWithin(fl.geog, l.geog, 100) );

 

If you need to know the exact fault lines, do a JOIN instead – keep in mind if a road is close enough to more than one fault line, it will be duplicated

 

SELECT l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) );

 

 

 

If you want jus the closes fault line within 100 meters use DISTINCT ON

 

SELECT DISTINCT ON(l.gid)  l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) )

ORDER BY l.gid, dist;

 

 

 

Hope that helps,

Regina

http://www.postgis.us

http://www.paragoncorporation.com

 

http://postgis.net

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Sunday, October 30, 2016 2:59 AM
To: PostGIS Users Discussion <[hidden email]>; PostGIS Users Discussion <[hidden email]>
Subject: [postgis-users] Line within range of another line?

 

Hi,

How can I find Line within range of another line?

I mean I try to find line section within certain range of another line.

For example, road lines close to fault lines.

 

Ps : I know that using st_buffer causes performance issue.

Can you give any advice?

 

Regards

 



--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

 


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users



--
Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users
Reply | Threaded
Open this post in threaded view
|

Re: Line within range of another line?

Regina Obe

Temiz,

 

Good question.  They will yield similar results, but not exactly the same

 

1)      When you do a buffer, it's an approximation since it uses by default 8 segments to approximate a quarter circle.  That said, it's possible you will get a different count of lines than you would with ST_DWithin and the ST_DWithin answer would be more correct.

2)      Unfortunately if you do need to return that portion of your line that intersects your buffer, you would need the ST_Buffer you have and deal with the less the accurateness of it if it's an issue.

3)      Have you compared the performance of both?  Your faultbuffer would not be able to utilize an index on the fault4analyse table, where as the ST_DWithin approach could.

4)      It would also be interesting to compare the performance differences.  In some cases using ST_Intersects with buffer is faster than using ST_Dwithin since GEOS has some special optimizations that I think ST_Dwithin lacks, but ST_DWithin would need to do less work up front than buffer (which could be huge for large geometries) and a buffered geom can't use index of underlying table.

I think when you buffer depending on the size of your buffer and the jagged edges you have in fault, you may end up with a simpler geometry that would require less work for ST_Intersects / ST_Dwihin.

 

It's also not clear to me why you are doing a ST_Union (do you have multiple fault lines with same gid?  ) if not then that union is not necessary.

 

And I would think you would want one record per road so the union should be done after, so the below would make more sense.

 

SELECT road.gid,  ST_Union(ST_Intersection(road.the_geom, ST_Buffer(fault.the_geom, 100)  ) ) as road_fayBuffer

FROM road4analyse as road

INNER JOIN fault4analyse AS fault

  ON ST_DWithin(road.the_geom, fault.geom, 100 ) 

GROUP BY road.gid

 

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Monday, October 31, 2016 3:59 AM
To: PostGIS Users Discussion <[hidden email]>
Subject: Re: [postgis-users] Line within range of another line?

 

Thank you,

 

It was great help.

 

Later, I had built this:

---

WITH faultbuffer as (

   SELECT gid,ST_Union(St_Buffer(the_geom,100)) as geom from fault4analyse group by gid

)

 

SELECT road.gid,ST_Intersection(road.the_geom,faultbuffer.geom ) as road_fayBuffer from road4analyse as road , faultbuffer 

  WHERE ST_Intersects(road.the_geom, faultbuffer.geom ) 

---

 

and it is reasonably fast.

 

Does it do same thing you have offered ?

 

kind regards

 

 

On Sun, Oct 30, 2016 at 10:55 AM, Regina Obe <[hidden email]> wrote:

Use ST_DWithin  (works for both geography and geometry) and any kind of geometry, not just lines . 

My example is for geography since units are always in meters.  For geometry units you have to specify based on your spatial_ref_sys and geometries have to have same spatial ref sys

 

something like below will return all roads that are within 100 meters of a fault line

 

SELECT l.gid, l.geog

FROM roads As l

WHERE EXISTS (SELECT 1 FROM fault_lines As fl WHERE ST_DWithin(fl.geog, l.geog, 100) );

 

If you need to know the exact fault lines, do a JOIN instead – keep in mind if a road is close enough to more than one fault line, it will be duplicated

 

SELECT l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) );

 

 

 

If you want jus the closes fault line within 100 meters use DISTINCT ON

 

SELECT DISTINCT ON(l.gid)  l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) )

ORDER BY l.gid, dist;

 

 

 

Hope that helps,

Regina

http://www.postgis.us

http://www.paragoncorporation.com

 

http://postgis.net

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Sunday, October 30, 2016 2:59 AM
To: PostGIS Users Discussion <[hidden email]>; PostGIS Users Discussion <[hidden email]>
Subject: [postgis-users] Line within range of another line?

 

Hi,

How can I find Line within range of another line?

I mean I try to find line section within certain range of another line.

For example, road lines close to fault lines.

 

Ps : I know that using st_buffer causes performance issue.

Can you give any advice?

 

Regards

 



--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

 


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users



 

--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users
Reply | Threaded
Open this post in threaded view
|

Re: Line within range of another line?

orkun
Thank you, 
it was great help.

particularly your  section worked well and helpful ( since I am going to create geojson outcome from this sql for web app):
---

And I would think you would want one record per road so the union should be done after, so the below would make more sense.

 

SELECT road.gid,  ST_Union(ST_Intersection(road.the_geom, ST_Buffer(fault.the_geom, 100)  ) ) as road_fayBuffer

FROM road4analyse as road

INNER JOIN fault4analyse AS fault

  ON ST_DWithin(road.the_geom, fault.geom, 100 ) 

GROUP BY road.gid



---
  I used ST_Union because  fault lines are so scattered (roads are as well) and buffers look weird. I preferred more conservative approach by creating complete buffer zone. I thought at least one of the geometry should be simple.

on the subject of correctness of distance calculation, how about using epsg:3857. You see
I directly use geometries in 3857. Do you recommend me transform to geography for correct distance calculation?

thank you again

regards

thanks again. 

On Mon, Oct 31, 2016 at 11:39 PM, Regina Obe <[hidden email]> wrote:

Temiz,

 

Good question.  They will yield similar results, but not exactly the same

 

1)      When you do a buffer, it's an approximation since it uses by default 8 segments to approximate a quarter circle.  That said, it's possible you will get a different count of lines than you would with ST_DWithin and the ST_DWithin answer would be more correct.

2)      Unfortunately if you do need to return that portion of your line that intersects your buffer, you would need the ST_Buffer you have and deal with the less the accurateness of it if it's an issue.

3)      Have you compared the performance of both?  Your faultbuffer would not be able to utilize an index on the fault4analyse table, where as the ST_DWithin approach could.

4)      It would also be interesting to compare the performance differences.  In some cases using ST_Intersects with buffer is faster than using ST_Dwithin since GEOS has some special optimizations that I think ST_Dwithin lacks, but ST_DWithin would need to do less work up front than buffer (which could be huge for large geometries) and a buffered geom can't use index of underlying table.

I think when you buffer depending on the size of your buffer and the jagged edges you have in fault, you may end up with a simpler geometry that would require less work for ST_Intersects / ST_Dwihin.

 

It's also not clear to me why you are doing a ST_Union (do you have multiple fault lines with same gid?  ) if not then that union is not necessary.

 

And I would think you would want one record per road so the union should be done after, so the below would make more sense.

 

SELECT road.gid,  ST_Union(ST_Intersection(road.the_geom, ST_Buffer(fault.the_geom, 100)  ) ) as road_fayBuffer

FROM road4analyse as road

INNER JOIN fault4analyse AS fault

  ON ST_DWithin(road.the_geom, fault.geom, 100 ) 

GROUP BY road.gid

 

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Monday, October 31, 2016 3:59 AM
To: PostGIS Users Discussion <[hidden email]>
Subject: Re: [postgis-users] Line within range of another line?

 

Thank you,

 

It was great help.

 

Later, I had built this:

---

WITH faultbuffer as (

   SELECT gid,ST_Union(St_Buffer(the_geom,100)) as geom from fault4analyse group by gid

)

 

SELECT road.gid,ST_Intersection(road.the_geom,faultbuffer.geom ) as road_fayBuffer from road4analyse as road , faultbuffer 

  WHERE ST_Intersects(road.the_geom, faultbuffer.geom ) 

---

 

and it is reasonably fast.

 

Does it do same thing you have offered ?

 

kind regards

 

 

On Sun, Oct 30, 2016 at 10:55 AM, Regina Obe <[hidden email]> wrote:

Use ST_DWithin  (works for both geography and geometry) and any kind of geometry, not just lines . 

My example is for geography since units are always in meters.  For geometry units you have to specify based on your spatial_ref_sys and geometries have to have same spatial ref sys

 

something like below will return all roads that are within 100 meters of a fault line

 

SELECT l.gid, l.geog

FROM roads As l

WHERE EXISTS (SELECT 1 FROM fault_lines As fl WHERE ST_DWithin(fl.geog, l.geog, 100) );

 

If you need to know the exact fault lines, do a JOIN instead – keep in mind if a road is close enough to more than one fault line, it will be duplicated

 

SELECT l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) );

 

 

 

If you want jus the closes fault line within 100 meters use DISTINCT ON

 

SELECT DISTINCT ON(l.gid)  l.gid, l.geog, fl.name, ST_Distance(l.geog, fl.geog) AS dist

FROM roads AS l INNER JOIN fault_lines AS fl ON (ST_DWithin(fl.geog, l.geog, 100) )

ORDER BY l.gid, dist;

 

 

 

Hope that helps,

Regina

http://www.postgis.us

http://www.paragoncorporation.com

 

http://postgis.net

 

 

From: postgis-users [mailto:[hidden email]] On Behalf Of Ahmet Temiz
Sent: Sunday, October 30, 2016 2:59 AM
To: PostGIS Users Discussion <[hidden email]>; PostGIS Users Discussion <[hidden email]>
Subject: [postgis-users] Line within range of another line?

 

Hi,

How can I find Line within range of another line?

I mean I try to find line section within certain range of another line.

For example, road lines close to fault lines.

 

Ps : I know that using st_buffer causes performance issue.

Can you give any advice?

 

Regards

 



--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

 


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users



 

--

Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency


_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users



--
Ahmet Temiz
Jeoloji Müh.
Afet ve Acil Durum Yönetimi Başkanlığı
Bilgi İşlem  Dairesi Başkanlığı-CBS Grubu


________________________

Ahmet Temiz
Geological Eng.
Information Systems - GIS Group
Disaster and Emergency Management
of Presidency

_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users
Reply | Threaded
Open this post in threaded view
|

Re: Line within range of another line?

Paul Ferro-2
In reply to this post by orkun
Greetings,

I have a similar issue where I want join attributes by location from line A to line B. Line B contains the attributes I'm interested to join to line A. Line A is a continuous road network, while line B is erratic gps line output. It some cases line A and line B intersect, but that is not always the case. I used the join attributes by location tool in qgis and got mixed results since the tool performs an intersect first, where I need a function to handle both an ST_overlap and ST_buffer. I think the lines are too close together to use ST_DWithin.

Perhaps something like this:

SELECT ST_Overlaps(a,b) As a_overlap_b, ST_Crosses(a,b) As a_crosses_b, ST_Intersects(a, b) As a_intersects_b,
ST_Contains(b,a) As b_contains_a,
ST_Dimension(a) As dim_a, ST_Dimension(b) as dim_b, ST_Dimension(ST_Intersection(a,b)) As dima_intersection_b
FROM (SELECT ST_Buffer(ST_GeomFromText('POINT(1 0.5)'), 3)  As a,
ST_Buffer(ST_GeomFromText('LINESTRING(1 0, 1 1, 3 5)'),0.5)  As b)
As foo;

Will the attributes carry over to the output?

Paul 

_______________________________________________
postgis-users mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/postgis-users