ewestern / geos

This is a Haskell binding to Geos, the open-source geometry library
MIT License
13 stars 9 forks source link

Cannot parse multi-polygon #4

Closed jamiecook closed 7 years ago

jamiecook commented 7 years ago

Hi,

I'm having real problems with MultiPolygons which I think I have reproduced in the tests (branch PR is here: https://github.com/ewestern/geos/pull/3)

image

Basically the following hex encodes a multi polygon

0106000020e6100000020000000103000000010000002e0000001826530523256340321ea5129e603bc0e7e26f7b8223634005a568e55e703bc0cade52ce97216340534145d5af703bc0d38558fd9121634051f4c0c760793bc04eb857e62d21634004711e4e60763bc09a42e735f620634071ab2006ba7a3bc09e616a4b1d206340906ad8ef89793bc0f3e84658d41f63402159c0046e7d3bc0d3d9c9e0a8206340709692e524803bc0226e4e25032063404f57772cb6813bc048c2be9d4420634023a46e675f853bc0994869360f1f6340c6f7c5a52a813bc0e605d847271f6340d28f8653e68a3bc08ac745b5081e634025b1a4dc7d863bc01ec539eae81c6340406ce9d1548b3bc0b84082e2c71c6340ed832c0b269a3bc022aaf067f81b63405c72dc291d943bc07a7077d66e1b63400d1afa27b8983bc035b22b2d231b6340882cd2c43b883bc0c828cfbc9c1a63401616dc0f78883bc03a5cab3dec1a6340ddcd531d728b3bc0378b170b431a634024d5777e518e3bc0cbf6216fb9176340de3d40f7e5903bc050508a56ee1763401cb5c2f4bd863bc0f4311f1068186340772b4b7496853bc09b560a815c17634064ac36ffaf7e3bc0e15e99b7ea17634077f35487dc703bc0fce4284094176340a9177c9a935f3bc0a530ef71a6166340bc9179e40f5a3bc03eca880bc0156340087250c24c5f3bc0f8e0b54b1b166340c4b0c398f4573bc05e2a36e6f5176340af08feb792513bc07a3881e9b41863400a2fc1a90f583bc0dc813ae55118634008e753c72a5d3bc04208c897d0186340ff3d78edd2663bc030849cf7ff196340ed647094bc663bc0d653abaf2e1b6340a69718cbf46b3bc0bb809719b61c63405f46b1dcd26a3bc03eeaaf57581d634000ac8e1ce9643bc0fa5e43705c1e634003eb387ea8683bc0e9edcf45431f6340b073d3669c663bc05f27f565e91f6340211ff46c564d3bc09f909db731226340e3a9471adc463bc0b212f3aca4226340d0b7054b75553bc0f14a92e7fa2463406571ff91e95c3bc01826530523256340321ea5129e603bc00103000000010000000b00000003b16ce610236340779fe3a3c5413bc01b2c9ca479226340dae731ca33433bc0221add416c22634083fa96395d3a3bc0ee5d83be74216340acaa97df693a3bc04b5af10d052163403140a20914353bc062dba2cc86216340dc2a8881ae313bc06953758fec22634078b988efc4343bc0569e40d8a9236340e2afc91af5303bc0478e7406c6236340807d74eaca3b3bc054e4107173236340d7868a71fe423bc003b16ce610236340779fe3a3c5413bc0

which looks like this when it's parsed

MULTIPOLYGON(((153.160525 -27.377412,153.109678 -27.438948,153.049781 -27.440183,153.049071 -27.474133,153.036853 -27.462407,153.030055 -27.479401,153.003576 -27.474761,152.994671 -27.48996,153.020615 -27.500563,153.000384 -27.506686,153.008376 -27.520987,152.970607 -27.504557,152.973545 -27.542577,152.938563 -27.525358,152.903432 -27.544263,152.8994 -27.602143,152.874073 -27.57857,152.85728 -27.59656,152.848044 -27.532162,152.831633 -27.533082,152.841338 -27.54471,152.820684 -27.555931,152.741386 -27.566009,152.747844 -27.526336,152.762703 -27.521827,152.730042 -27.494873,152.747402 -27.440865,152.736847 -27.373346,152.707818 -27.351805,152.679693 -27.372265,152.690832 -27.343576,152.748767 -27.318645,152.772084 -27.343989,152.759997 -27.363934,152.775463 -27.401656,152.812496 -27.401315,152.849449 -27.421704,152.897229 -27.41728,152.917034 -27.394182,152.948784 -27.408821,152.976962 -27.400824,152.997241 -27.3021,153.068569 -27.276796,153.082602 -27.333821,153.155628 -27.362939,153.160525 -27.377412)),((153.095813 -27.256922,153.077349 -27.262509,153.075715 -27.227985,153.045501 -27.228178,153.031867 -27.207337,153.047705 -27.194069,153.091377 -27.20613,153.114483 -27.19124,153.117923 -27.233565,153.107842 -27.261695,153.095813 -27.256922)))

But testing this seems to cause seg faults.

Happy to help with debugging this but don't really know where to start.

ewestern commented 7 years ago

Thanks for making the test! I think I know the issue. Will try to push something later today.

jamiecook commented 7 years ago

Ack! don't leave me hangin'!!!!

I've been doing some debugging of my own but don't have a solid idea yet - can you give a newbie a 2min version of your idea?

ewestern commented 7 years ago

Sure. The issue (I think!) has to do with the transfer of ownership of individual Geometry objects that belong to a MultiGeometry object. If you look in Raw.CoordSeq, you'll notice a CoordinateSequence class, that has instances for both CoordSeq and CoordSeqConst. The idea is that: sometimes you might want a coordinate sequence that lives completely separate from whatever geometry once owned it -- and sometimes you might want to just peek at the value, but let the parent geometry continue to own it.

The same thing needs to be done for Geometry.

What's happening in some cases is that the functions that convert between Haskell types and C types are unclear about whether the sub-geometries they want are ones that maintain parent ownership and ones that do not maintain parent ownership. So in a couple places we're adding a finalizer to an object whose parent (which retains ownership) already has a finalizer attached. The first one deallocates the child object through the parent, and the one attached to the child results in a "pointer being freed was not allocated" error.

The solution that I've started on is creating a Geometry class, which has instances for Geom (a type with a finalizer) and GeomConst (a type without a finalizer). Most functions will use the instance method for accessing these, but certain functions that expect the object to maintain parent ownership can specify that in their type.

Does that make sense?

jamiecook commented 7 years ago

Ah yes it does! And it's not something I would have been able to get to the bottom of easily.

Just to be clear, in general I should be able to (for Polygons say) use the returned objects without being in the Geos monad right? For example: image

I also emailed you separately to this - do you happen to have any good examples of using the library (esp to talk to PostGIS). I'm thinking that I might be able to help out with drafting some examples into the README, but I'm still a bit unsure whether I'm using the library right.

jamiecook commented 7 years ago

The reason I ask is that even when I use PostGIS to break the multipolygon up into simple polygons

SELECT encode((ST_DUMP(ST_Simplify(wkb_geometry::geometry, 0.01))).geom::geometry(Polygon,4326), 'hex') 
FROM my_table

I get a core dump on that show line ?

image

ewestern commented 7 years ago

Have you seen this issue after recent fixes?

jamiecook commented 7 years ago

No i'm pretty sure this was closed off in an earlier PR.