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 |
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 |
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 |
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 |
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 |
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) 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 |
Free forum by Nabble | Edit this page |