[prev in list] [next in list] [prev in thread] [next in thread] 

List:       postgis-users
Subject:    Re: [postgis-users] split line at polygon edge
From:       Rémi_Cura <remi.cura () gmail ! com>
Date:       2016-03-18 8:04:56
Message-ID: CAJvUf_tuzNHHGG2sn0LEcGbynxw5aJsNq1=rH7dTbh8rZp+qaA () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hey, in theory st_intersection already uses index and st_intersects under
the hood,
I personally prefer to explicitly add it, as I found it more easy to
understand.

What you didn't take into account is that you may get multiline,
for instance if your polygon is a U, and the line cross it left to right,
the intersection result would be two lines (each in a vertical part of the
U).
If you don't mind having multilinestring :

--------------------------------------
SELECT
ST_Multi(ST_CollectionExtract(ST_Intersection(t.geom,d.geom),2))::geometry(multilinestring,4326)
AS geom
    , t.trails_id, d.id AS trail_system
FROM temp_trails AS t, divisions AS d
WHERE ST_Intersects(t.geom,d.geom) = TRUE;
-------------------------------------
if you want only line, you have to break multilines into simple lines
-------------------------------------
SELECT  row_number() over() as qgis_id, dmp.path AS line_id
    , dmp.geom::geometry(linestring,4326) AS geom
    , t.trails_id, d.id AS trail_system
FROM temp_trails AS t, divisions AS d
    , ST_Dump(ST_CollectionExtract(ST_Intersection(t.geom,d.geom),2)) as dmp
WHERE ST_Intersects(t.geom,d.geom) = TRUE;
--------------------------------------

Cheers,
Rémi-C



2016-03-17 22:17 GMT+01:00 François Hugues <hugues.francois@irstea.fr>:

> Hi,
>
> Empty geometries are returned when there is no intersection and I think we
> forgot something obvious. When you want to intersect geometries you need to
> add WHERE ST_Intersects (a.geom,b.geom).
>
> Things should work better and faster.
>
> HugThanks Remi-C and Hugues for your suggestions, they got me what I
> needed!
>
> I first tried Remi-C's example, since I was curious about how it would turn
> out. It gave me an error mentioning that it could not convert
> GeometryCollection to LineString. This error brought me back to what Hugues
> mentioned. So I used ST_Summary() to verify the GeometryCollections, which
> appeared to be empty (0 elements), and mixed in I noticed the LineStrings,
> MultiLineStrings. Since the Collections seemed to be empty I opted to
> separate out the linestrings I using a function Hugues mentioned
> ST_GeometryType()
>
> Specifically I used:
> ST_GeometryType(geom) like '%Line%'
>
> to get both linestring and multilinestrings.
>
> In the end it took 2 statements, even though I knew someone much more
> proficient then myself could do it in one.
>
> My final statements where:
> #create table public.temp_trail_div1 as select st_intersection(t.geom,
> d.geom) as geom,t.trails_id,
> d.id as trail_system from public.temp_trails as t, public.divisions as d;
>
> #create table public.temp_trail_div_sep as select * from
> public.temp_trail_div1 where ST_GeometryType(geom) like '%Line%';
>
> This seems to have done the trick, for now. Could someone enlighten me on
> how that might be done in one statement?
>
> Thanks again,
> Garret
>
>
> On Thu, Mar 17, 2016 at 5:45 AM, Rémi Cura <remi.cura@gmail.com> wrote:
>
> > Hey,
> > two things :
> > recent version of QGIS are boringly strict about geometry type,
> > so if you want to be able to add the corresponding postgis layer to qgis,
> > you may have to explicitely cast the result.
> > QGIS also require a unique identifier per row,
> > which you can fabricate with row_number() for instance
> > ​​
> > ----------------------------------------------------------------
> > CREATE TABLE my_table AS
> > SELECT row_number() over() AS qgis_unique_id,
> >     st_intersection(t.geom, d.geom)::geometry(linestring,4326) AS geom
> >     ,t.trails_id, d.id
> > FROM public.temp_trails as t, public.polys as d;
> > ----------------------------------------------------------------
> >
> > Cheers,
> > Rémi-C
> >
> > 2016-03-17 8:15 GMT+01:00 François Hugues <hugues.francois@irstea.fr>:
> >
> >> Hello,
> >>
> >>
> >>
> >> Dis you take a look at the query result ? I think you should first try
> >> to see what is the type of geometry returned using ST_GeometryType().
> You
> >> may have some geometrycollections and I'm not sure QGis can handle  it.
> In
> >> this case you could extract lines using ST_CollectionExtract().
> >>
> >>
> >>
> >> To achieve what you want to do, you'll be able to compare your original
> >> lines table with the result of your query using ST_Difference().
> >>
> >>
> >>
> >> Regards,
> >>
> >>
> >>
> >> Hugues.
> >>
> >>
> >>
> >> *De :* postgis-users [mailto:postgis-users-bounces@lists.osgeo.org] *De
> >> la part de* Garret W
> >> *Envoyé :* jeudi 17 mars 2016 04:11
> >> *À :* postgis-users@lists.osgeo.org
> >> *Objet :* [postgis-users] split line at polygon edge
> >>
> >>
> >>
> >> Hi Ive been looking for a way to take several hundred lines and split
> >> them where they intersect a polygon while also giving them the ID of the
> >> polygon they fall in. Ive seen many posts on splitting polygons. But its
> >> been difficult for me to adapt those examples.
> >>
> >> Ive been able to get an output from this:
> >>
> >> select st_intersection(t.geom, d.geom),t.trails_id, d.id
> >>  from public.temp_trails as t, public.polys as d;
> >>
> >> Its giving me the line and IDs that I wanted but the geom is unreadable
> >> for some reason by QGIS.
> >>
> >> 99.9% of the lines fall within a polygon. Id like to still hang on to
> >> those few lines that arent contained in a polygon. They should just be
> >> split with no ID added
> >>
> >> Im using; postgis 2.2, postgresql 9.5
> >>
> >> Thank you
> >> Garret
> >>
> >> _______________________________________________
> >> postgis-users mailing list
> >> postgis-users@lists.osgeo.org
> >> http://lists.osgeo.org/mailman/listinfo/postgis-users
> >>
> >
> >
> > _______________________________________________
> > postgis-users mailing list
> > postgis-users@lists.osgeo.org
> > http://lists.osgeo.org/mailman/listinfo/postgis-users
> >
> _______________________________________________
> postgis-users mailing list
> postgis-users@lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/postgis-users
>

[Attachment #5 (text/html)]

<div dir="ltr"><div class="gmail_default" \
style="font-family:monospace,monospace"><div \
style="font-family:arial,sans-serif;font-size:12.8px">Hey, in theory st_intersection \
already uses index and st_intersects under the hood,  </div><div \
style="font-family:arial,sans-serif;font-size:12.8px">I personally prefer to \
explicitly add it, as I found it more easy to understand.</div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><br></div><div \
style="font-family:arial,sans-serif;font-size:12.8px">What you didn&#39;t take into \
account is that you may get multiline,</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">for instance if your polygon is \
a U, and the line cross it left to right,  </div><div \
style="font-family:arial,sans-serif;font-size:12.8px">the intersection result would \
be two lines (each in a vertical part of the U).</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">If you don&#39;t mind having \
multilinestring :</div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><br></div><div \
style="font-family:arial,sans-serif;font-size:12.8px">--------------------------------------</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">SELECT \
ST_Multi(ST_CollectionExtract(ST_Intersection(t.geom,d.geom),2))::geometry(multilinestring,4326) \
AS geom</div><div style="font-family:arial,sans-serif;font-size:12.8px">      , \
t.trails_id, <a href="http://d.id">d.id</a> AS trail_system</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">FROM temp_trails AS t, \
divisions AS d</div><div style="font-family:arial,sans-serif;font-size:12.8px">WHERE \
ST_Intersects(<span style="font-size:12.8px">t.geom,d.geom</span><span \
style="font-size:12.8px">) = TRUE;  </span></div><div \
style="font-family:arial,sans-serif;font-size:12.8px">-------------------------------------</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">if you want only line, you have \
to break multilines into simple lines</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">-------------------------------------</div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><div \
style="font-size:12.8px">SELECT   row_number() over() as qgis_id, dmp.path AS \
line_id</div><div style="font-size:12.8px">      , \
dmp.geom::geometry(linestring,4326) AS geom</div><div style="font-size:12.8px">      \
, t.trails_id, <a href="http://d.id">d.id</a> AS trail_system</div><div \
style="font-size:12.8px">FROM temp_trails AS t, divisions AS d</div><div \
style="font-size:12.8px">      ,  <span \
style="font-size:12.8px">ST_Dump(ST_CollectionExtract(ST_Intersection(t.geom,d.geom),2)) \
as dmp</span></div><div style="font-size:12.8px"><span style="font-size:12.8px">WHERE \
ST_Intersects(</span><span style="font-size:12.8px">t.geom,d.geom</span><span \
style="font-size:12.8px">) = TRUE</span><span style="font-size:12.8px">;  \
</span></div></div><div \
style="font-family:arial,sans-serif;font-size:12.8px">--------------------------------------</div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><br></div><div \
style="font-family:arial,sans-serif;font-size:12.8px">Cheers,</div><div \
style="font-family:arial,sans-serif;font-size:12.8px">Rémi-C</div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><br></div><div \
style="font-family:arial,sans-serif;font-size:12.8px"><br></div></div></div><div \
class="gmail_extra"><br><div class="gmail_quote">2016-03-17 22:17 GMT+01:00 François \
Hugues <span dir="ltr">&lt;<a href="mailto:hugues.francois@irstea.fr" \
target="_blank">hugues.francois@irstea.fr</a>&gt;</span>:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex">Hi,<br> <br>
Empty geometries are returned when there is no intersection and I think we forgot \
something obvious. When you want to intersect geometries you need to add WHERE \
ST_Intersects (a.geom,b.geom).<br> <br>
Things should work better and faster.<br>
<br>
HugThanks Remi-C and Hugues for your suggestions, they got me what I needed!<br>
<div><div class="h5"><br>
I first tried Remi-C&#39;s example, since I was curious about how it would turn<br>
out. It gave me an error mentioning that it could not convert<br>
GeometryCollection to LineString. This error brought me back to what Hugues<br>
mentioned. So I used ST_Summary() to verify the GeometryCollections, which<br>
appeared to be empty (0 elements), and mixed in I noticed the LineStrings,<br>
MultiLineStrings. Since the Collections seemed to be empty I opted to<br>
separate out the linestrings I using a function Hugues mentioned<br>
ST_GeometryType()<br>
<br>
Specifically I used:<br>
ST_GeometryType(geom) like &#39;%Line%&#39;<br>
<br>
to get both linestring and multilinestrings.<br>
<br>
In the end it took 2 statements, even though I knew someone much more<br>
proficient then myself could do it in one.<br>
<br>
My final statements where:<br>
#create table public.temp_trail_div1 as select st_intersection(t.geom,<br>
d.geom) as geom,t.trails_id,<br>
<a href="http://d.id" rel="noreferrer" target="_blank">d.id</a> as trail_system from \
public.temp_trails as t, public.divisions as d;<br> <br>
#create table public.temp_trail_div_sep as select * from<br>
public.temp_trail_div1 where ST_GeometryType(geom) like &#39;%Line%&#39;;<br>
<br>
This seems to have done the trick, for now. Could someone enlighten me on<br>
how that might be done in one statement?<br>
<br>
Thanks again,<br>
Garret<br>
<br>
<br>
On Thu, Mar 17, 2016 at 5:45 AM, Rémi Cura &lt;<a \
href="mailto:remi.cura@gmail.com">remi.cura@gmail.com</a>&gt; wrote:<br> <br>
&gt; Hey,<br>
&gt; two things :<br>
&gt; recent version of QGIS are boringly strict about geometry type,<br>
&gt; so if you want to be able to add the corresponding postgis layer to qgis,<br>
&gt; you may have to explicitely cast the result.<br>
&gt; QGIS also require a unique identifier per row,<br>
&gt; which you can fabricate with row_number() for instance<br>
&gt; ​​<br>
&gt; ----------------------------------------------------------------<br>
&gt; CREATE TABLE my_table AS<br>
&gt; SELECT row_number() over() AS qgis_unique_id,<br>
&gt;        st_intersection(t.geom, d.geom)::geometry(linestring,4326) AS geom<br>
&gt;        ,t.trails_id, <a href="http://d.id" rel="noreferrer" \
target="_blank">d.id</a><br> &gt; FROM public.temp_trails as t, public.polys as \
d;<br> &gt; ----------------------------------------------------------------<br>
&gt;<br>
&gt; Cheers,<br>
&gt; Rémi-C<br>
&gt;<br>
&gt; 2016-03-17 8:15 GMT+01:00 François Hugues &lt;<a \
href="mailto:hugues.francois@irstea.fr">hugues.francois@irstea.fr</a>&gt;:<br> \
&gt;<br> &gt;&gt; Hello,<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Dis you take a look at the query result ? I think you should first try<br>
&gt;&gt; to see what is the type of geometry returned using ST_GeometryType(). \
You<br> &gt;&gt; may have some geometrycollections and I'm not sure QGis can handle   \
it. In<br> &gt;&gt; this case you could extract lines using \
ST_CollectionExtract().<br> &gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; To achieve what you want to do, you'll be able to compare your original<br>
&gt;&gt; lines table with the result of your query using ST_Difference().<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Regards,<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Hugues.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
</div></div>&gt;&gt; *De :* postgis-users [mailto:<a \
href="mailto:postgis-users-bounces@lists.osgeo.org">postgis-users-bounces@lists.osgeo.org</a>] \
*De<br> &gt;&gt; la part de* Garret W<br>
&gt;&gt; *Envoyé :* jeudi 17 mars 2016 04:11<br>
&gt;&gt; *À :* <a href="mailto:postgis-users@lists.osgeo.org">postgis-users@lists.osgeo.org</a><br>
 &gt;&gt; *Objet :* [postgis-users] split line at polygon edge<br>
<div class="HOEnZb"><div class="h5">&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Hi Ive been looking for a way to take several hundred lines and split<br>
&gt;&gt; them where they intersect a polygon while also giving them the ID of the<br>
&gt;&gt; polygon they fall in. Ive seen many posts on splitting polygons. But its<br>
&gt;&gt; been difficult for me to adapt those examples.<br>
&gt;&gt;<br>
&gt;&gt; Ive been able to get an output from this:<br>
&gt;&gt;<br>
&gt;&gt; select st_intersection(t.geom, d.geom),t.trails_id, <a href="http://d.id" \
rel="noreferrer" target="_blank">d.id</a><br> &gt;&gt;   from public.temp_trails as \
t, public.polys as d;<br> &gt;&gt;<br>
&gt;&gt; Its giving me the line and IDs that I wanted but the geom is unreadable<br>
&gt;&gt; for some reason by QGIS.<br>
&gt;&gt;<br>
&gt;&gt; 99.9% of the lines fall within a polygon. Id like to still hang on to<br>
&gt;&gt; those few lines that arent contained in a polygon. They should just be<br>
&gt;&gt; split with no ID added<br>
&gt;&gt;<br>
&gt;&gt; Im using; postgis 2.2, postgresql 9.5<br>
&gt;&gt;<br>
&gt;&gt; Thank you<br>
&gt;&gt; Garret<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; postgis-users mailing list<br>
&gt;&gt; <a href="mailto:postgis-users@lists.osgeo.org">postgis-users@lists.osgeo.org</a><br>
 &gt;&gt; <a href="http://lists.osgeo.org/mailman/listinfo/postgis-users" \
rel="noreferrer" target="_blank">http://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
 &gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; postgis-users mailing list<br>
&gt; <a href="mailto:postgis-users@lists.osgeo.org">postgis-users@lists.osgeo.org</a><br>
 &gt; <a href="http://lists.osgeo.org/mailman/listinfo/postgis-users" \
rel="noreferrer" target="_blank">http://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
 &gt;<br>
_______________________________________________<br>
postgis-users mailing list<br>
<a href="mailto:postgis-users@lists.osgeo.org">postgis-users@lists.osgeo.org</a><br>
<a href="http://lists.osgeo.org/mailman/listinfo/postgis-users" rel="noreferrer" \
target="_blank">http://lists.osgeo.org/mailman/listinfo/postgis-users</a></div></div></blockquote></div><br></div>



[Attachment #6 (text/plain)]

_______________________________________________
postgis-users mailing list
postgis-users@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/postgis-users

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic