UnaryUnionOp / Empty geometry

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

UnaryUnionOp / Empty geometry

michaelm-2
Hi Martin,

I'm on the way to use your new UnaryUnionOp to replace the old Union and
UnionByAttribute plugins of OpenJUMP (I already optimized these plugins,
but your new cascaded union operation makes it even 2x to 5x faster !).

Here is my question :
Is there any reason to return null if an empty geometry is passed to
UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
In my case, it breaks a union operation using a computed geometry as an
input.
Anyway, returning null should be at least documented.

Thanks for the excellent job

Michaël

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UnaryUnionOp / Empty geometry

Martin Davis
Good point, Michael - thanks.

You're right, there's no reason why an actual empty Geometry object
couldn't be returned.  And this is a much more friendly design to have
(in fact, it's the a pattern I've tried to follow everywhere in JTS -
the Union behaviour is a mistake).

I'll modify this to return an empty geometry if the input is empty.  I
think the best thing to do is to return an empty geometry which has the
dimension of the maximum dimension of the input geometries.  Do you agree?

This will appear in JTS 1.10.   In the meantime I'd suggest simply
wrapping the union() method in another function to provide this behaviour.

Great to hear that unary union is providing good performance!  It's nice
to have this capability exposed in a tool that everyone can use.  (And
of course I provide it in JEQL too....  8^)

Michael Michaud wrote:

> Hi Martin,
>
> I'm on the way to use your new UnaryUnionOp to replace the old Union
> and UnionByAttribute plugins of OpenJUMP (I already optimized these
> plugins, but your new cascaded union operation makes it even 2x to 5x
> faster !).
>
> Here is my question :
> Is there any reason to return null if an empty geometry is passed to
> UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
> In my case, it breaks a union operation using a computed geometry as
> an input.
> Anyway, returning null should be at least documented.
>
> Thanks for the excellent job
>
> Michaël
>
> _______________________________________________
> jts-devel mailing list
> [hidden email]
> http://lists.refractions.net/mailman/listinfo/jts-devel
>

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UnaryUnionOp / Empty geometry

Martin Davis
There is a further complication to this modification.  In order to
return an empty geometry when given an empty collection, it is necessary
to have a GeometryFactory provided to build the empty geometry.  I'll
add a constructor which takes a collection and a GeometryFactory, and
will return an appropriate empty geom if the collection is empty.  (It's
easy to do this externally to the UnaryUnionOp as well, but it is nice
to have this behaviour captured in the library as well).

I think I'll return an empty GEOMETRYCOLLECTION, for consistency with
the rest of JTS.  I realize that there is a current issue with
limitations on being able to cascade this geometry in further
operations, but I plan to address that as well, by allowing empty GCs as
input.



Martin Davis wrote:

> Good point, Michael - thanks.
>
> You're right, there's no reason why an actual empty Geometry object
> couldn't be returned.  And this is a much more friendly design to have
> (in fact, it's the a pattern I've tried to follow everywhere in JTS -
> the Union behaviour is a mistake).
>
> I'll modify this to return an empty geometry if the input is empty.  I
> think the best thing to do is to return an empty geometry which has
> the dimension of the maximum dimension of the input geometries.  Do
> you agree?
>
> This will appear in JTS 1.10.   In the meantime I'd suggest simply
> wrapping the union() method in another function to provide this
> behaviour.
>
> Great to hear that unary union is providing good performance!  It's
> nice to have this capability exposed in a tool that everyone can use.  
> (And of course I provide it in JEQL too....  8^)
>
> Michael Michaud wrote:
>> Hi Martin,
>>
>> I'm on the way to use your new UnaryUnionOp to replace the old Union
>> and UnionByAttribute plugins of OpenJUMP (I already optimized these
>> plugins, but your new cascaded union operation makes it even 2x to 5x
>> faster !).
>>
>> Here is my question :
>> Is there any reason to return null if an empty geometry is passed to
>> UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
>> In my case, it breaks a union operation using a computed geometry as
>> an input.
>> Anyway, returning null should be at least documented.
>>
>> Thanks for the excellent job
>>
>> Michaël
>>
>> _______________________________________________
>> jts-devel mailing list
>> [hidden email]
>> http://lists.refractions.net/mailman/listinfo/jts-devel
>>
>

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UnaryUnionOp

michaelm-2
In reply to this post by Martin Davis
Hi,

Two other points about UnaryUnionOp behaviour :

The doc says : Heterogeneous GeometryCollections are fully supported but

the UnaryUnionOp first union points, then linestrings then polygons,
producing eventually a multipoint, a multilinestring and a multipolygon.
Then it tries to union resulting geometries with Geometry.union() (in
the UnaryUnionOp.unionWithNull method) which do not accept
GeometryCollection.
=> unioning a heterogeneous layer with more than one point and/or one
linestring ends up with an exception

The other point is that documention says that "Unioning a set of
LineStrings has the effect of fully noding and dissolving the linework".
I'm not sure what dissolving means in this case, but if I union 2 simple
linestrings wich touch each other, the result is not a simple linestring
but a multilinestring containing the two original linestrings (I must
admit that differences between union, dissolve and merge are not always
clear in my mind)

Hope that helps

Michaël


Martin Davis a écrit :

> Good point, Michael - thanks.
>
> You're right, there's no reason why an actual empty Geometry object
> couldn't be returned.  And this is a much more friendly design to have
> (in fact, it's the a pattern I've tried to follow everywhere in JTS -
> the Union behaviour is a mistake).
>
> I'll modify this to return an empty geometry if the input is empty.  I
> think the best thing to do is to return an empty geometry which has
> the dimension of the maximum dimension of the input geometries.  Do
> you agree?
>
> This will appear in JTS 1.10.   In the meantime I'd suggest simply
> wrapping the union() method in another function to provide this
> behaviour.
>
> Great to hear that unary union is providing good performance!  It's
> nice to have this capability exposed in a tool that everyone can use.  
> (And of course I provide it in JEQL too....  8^)
>
> Michael Michaud wrote:
>> Hi Martin,
>>
>> I'm on the way to use your new UnaryUnionOp to replace the old Union
>> and UnionByAttribute plugins of OpenJUMP (I already optimized these
>> plugins, but your new cascaded union operation makes it even 2x to 5x
>> faster !).
>>
>> Here is my question :
>> Is there any reason to return null if an empty geometry is passed to
>> UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
>> In my case, it breaks a union operation using a computed geometry as
>> an input.
>> Anyway, returning null should be at least documented.
>>
>> Thanks for the excellent job
>>
>> Michaël
>>
>> _______________________________________________
>> jts-devel mailing list
>> [hidden email]
>> http://lists.refractions.net/mailman/listinfo/jts-devel
>>
>

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UnaryUnionOp

Martin Davis
Thanks for pointing these issues out, Michael.

Good point about hetergeneous union not working.  There should be a
fairly easy fix for this - I'll give it some thought.

I use "dissolve" to mean that coincident line segments (either partially
or fully) are reduced to a single line segment covering the coincident
part.  You can see this easily if you try unioning two overlapping
parallel lines.

"Noding" means that nodes are introduced whereever endpoints in either
geometry exist, and whereever line segments cross.

Both of these are consistent with the current behaviour of the union()
method on Geometry.

So what you're seeing in your test case is the expected behaviour.  Of
course, another possible result is to merge any connected linestrings
together into a "minimal coverage" of linear components.  This is
accomplished by the LineMerger class in JTS.  You have to choose one
behaviour or the other - I chose the "fully noded" behaviour as the
default, since it's simpler than doing the merge.  You can always use
LineMerger to join things together again.  (In OpenJUMP, you might use
this inside your union plugin - or even better, offer it as an option
for the user)



Michael Michaud wrote:

> Hi,
>
> Two other points about UnaryUnionOp behaviour :
>
> The doc says : Heterogeneous GeometryCollections are fully supported but
>
> the UnaryUnionOp first union points, then linestrings then polygons,
> producing eventually a multipoint, a multilinestring and a
> multipolygon. Then it tries to union resulting geometries with
> Geometry.union() (in the UnaryUnionOp.unionWithNull method) which do
> not accept GeometryCollection.
> => unioning a heterogeneous layer with more than one point and/or one
> linestring ends up with an exception
>
> The other point is that documention says that "Unioning a set of
> LineStrings has the effect of fully noding and dissolving the linework".
> I'm not sure what dissolving means in this case, but if I union 2
> simple linestrings wich touch each other, the result is not a simple
> linestring but a multilinestring containing the two original
> linestrings (I must admit that differences between union, dissolve and
> merge are not always clear in my mind)
>
> Hope that helps
>
> Michaël
>
>
> Martin Davis a écrit :
>> Good point, Michael - thanks.
>>
>> You're right, there's no reason why an actual empty Geometry object
>> couldn't be returned.  And this is a much more friendly design to
>> have (in fact, it's the a pattern I've tried to follow everywhere in
>> JTS - the Union behaviour is a mistake).
>>
>> I'll modify this to return an empty geometry if the input is empty.  
>> I think the best thing to do is to return an empty geometry which has
>> the dimension of the maximum dimension of the input geometries.  Do
>> you agree?
>>
>> This will appear in JTS 1.10.   In the meantime I'd suggest simply
>> wrapping the union() method in another function to provide this
>> behaviour.
>>
>> Great to hear that unary union is providing good performance!  It's
>> nice to have this capability exposed in a tool that everyone can
>> use.  (And of course I provide it in JEQL too....  8^)
>>
>> Michael Michaud wrote:
>>> Hi Martin,
>>>
>>> I'm on the way to use your new UnaryUnionOp to replace the old Union
>>> and UnionByAttribute plugins of OpenJUMP (I already optimized these
>>> plugins, but your new cascaded union operation makes it even 2x to
>>> 5x faster !).
>>>
>>> Here is my question :
>>> Is there any reason to return null if an empty geometry is passed to
>>> UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
>>> In my case, it breaks a union operation using a computed geometry as
>>> an input.
>>> Anyway, returning null should be at least documented.
>>>
>>> Thanks for the excellent job
>>>
>>> Michaël
>>>
>>> _______________________________________________
>>> jts-devel mailing list
>>> [hidden email]
>>> http://lists.refractions.net/mailman/listinfo/jts-devel
>>>
>>
>
> _______________________________________________
> jts-devel mailing list
> [hidden email]
> http://lists.refractions.net/mailman/listinfo/jts-devel
>

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UnaryUnionOp

michaelm-2
Martin Davis a écrit :
> Thanks for pointing these issues out, Michael.
>
> Good point about hetergeneous union not working.  There should be a
> fairly easy fix for this - I'll give it some thought.
>
> I use "dissolve" to mean that coincident line segments (either
> partially or fully) are reduced to a single line segment covering the
> coincident part.  You can see this easily if you try unioning two
> overlapping parallel lines.
OK, so dissolving is something different than merging. Thanks for
clarification.

>
> "Noding" means that nodes are introduced whereever endpoints in either
> geometry exist, and whereever line segments cross.
> Both of these are consistent with the current behaviour of the union()
> method on Geometry.
>
> So what you're seeing in your test case is the expected behaviour.  Of
> course, another possible result is to merge any connected linestrings
> together into a "minimal coverage" of linear components.  This is
> accomplished by the LineMerger class in JTS.  You have to choose one
> behaviour or the other - I chose the "fully noded" behaviour as the
> default, since it's simpler than doing the merge.  You can always use
> LineMerger to join things together again.  (In OpenJUMP, you might use
> this inside your union plugin - or even better, offer it as an option
> for the user)
Yes, I added a "merge" option in the "UnionByAttribute" plugin I wrote
last year, but after I read UnaryUnionOp javadoc, a few days ago, I
started to be confused. Thanks for clarification.
I think most users would wait for a merged linestring rather than a
multilinestring after an union, but I can understand the choice to do a
minimal union and to let the user do extra processing like merging if
needed not to penalize the one who does not need it.

Michaël

>
>
>
> Michael Michaud wrote:
>> Hi,
>>
>> Two other points about UnaryUnionOp behaviour :
>>
>> The doc says : Heterogeneous GeometryCollections are fully supported but
>>
>> the UnaryUnionOp first union points, then linestrings then polygons,
>> producing eventually a multipoint, a multilinestring and a
>> multipolygon. Then it tries to union resulting geometries with
>> Geometry.union() (in the UnaryUnionOp.unionWithNull method) which do
>> not accept GeometryCollection.
>> => unioning a heterogeneous layer with more than one point and/or one
>> linestring ends up with an exception
>>
>> The other point is that documention says that "Unioning a set of
>> LineStrings has the effect of fully noding and dissolving the linework".
>> I'm not sure what dissolving means in this case, but if I union 2
>> simple linestrings wich touch each other, the result is not a simple
>> linestring but a multilinestring containing the two original
>> linestrings (I must admit that differences between union, dissolve
>> and merge are not always clear in my mind)
>>
>> Hope that helps
>>
>> Michaël
>>
>>
>> Martin Davis a écrit :
>>> Good point, Michael - thanks.
>>>
>>> You're right, there's no reason why an actual empty Geometry object
>>> couldn't be returned.  And this is a much more friendly design to
>>> have (in fact, it's the a pattern I've tried to follow everywhere in
>>> JTS - the Union behaviour is a mistake).
>>>
>>> I'll modify this to return an empty geometry if the input is empty.  
>>> I think the best thing to do is to return an empty geometry which
>>> has the dimension of the maximum dimension of the input geometries.  
>>> Do you agree?
>>>
>>> This will appear in JTS 1.10.   In the meantime I'd suggest simply
>>> wrapping the union() method in another function to provide this
>>> behaviour.
>>>
>>> Great to hear that unary union is providing good performance!  It's
>>> nice to have this capability exposed in a tool that everyone can
>>> use.  (And of course I provide it in JEQL too....  8^)
>>>
>>> Michael Michaud wrote:
>>>> Hi Martin,
>>>>
>>>> I'm on the way to use your new UnaryUnionOp to replace the old
>>>> Union and UnionByAttribute plugins of OpenJUMP (I already optimized
>>>> these plugins, but your new cascaded union operation makes it even
>>>> 2x to 5x faster !).
>>>>
>>>> Here is my question :
>>>> Is there any reason to return null if an empty geometry is passed
>>>> to UnaryUnionOp(Geometry) or  UnaryUnionOp(Collection)?
>>>> In my case, it breaks a union operation using a computed geometry
>>>> as an input.
>>>> Anyway, returning null should be at least documented.
>>>>
>>>> Thanks for the excellent job
>>>>
>>>> Michaël
>>>>
>>>> _______________________________________________
>>>> jts-devel mailing list
>>>> [hidden email]
>>>> http://lists.refractions.net/mailman/listinfo/jts-devel
>>>>
>>>
>>
>> _______________________________________________
>> jts-devel mailing list
>> [hidden email]
>> http://lists.refractions.net/mailman/listinfo/jts-devel
>>
>

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Loading...