peterstace / simplefeatures

Simple Features is a pure Go Implementation of the OpenGIS Simple Feature Access Specification
MIT License
131 stars 19 forks source link

panic with Union #496

Closed akhenakh closed 11 months ago

akhenakh commented 1 year ago

Union of those 2 geometries panic.

panic: runtime error: slice bounds out of range [1:0]

Both geometries are reported valid by GEOS, not sure what happened

play https://go.dev/play/p/U4ZuTk678WI

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "strings"

    "github.com/peterstace/simplefeatures/geom"
)

func main() {
    a0 := `{"type":"Polygon","coordinates":[[[-83.5825305152402,32.7316823944815,0],[-83.58376293006216,32.73315376178507,0],[-83.58504085655653,32.734597137036324,0],[-83.58636334101533,32.73601156235818,0],[-83.58772946946186,32.73739605462324,0],[-83.58913829287843,32.738749652823024,0],[-83.59058883640313,32.740071417020225,0],[-83.59208009385833,32.74136043125909,0],[-83.59361103333862,32.74261579844315,0],[-83.59518059080796,32.743836647669376,0],[-83.59678768034422,32.745022130852156,0],[-83.59843118482598,32.746171426099316,0],[-83.60010996734121,32.74728373328835,0],[-83.60182286094272,32.74835828151699,0],[-83.60356867749573,32.74939432363171,0],[-83.6053462070958,32.75039113983657,0],[-83.60715421364506,32.75134803897381,0],[-83.60899144521312,32.75226435508957,0],[-83.61085662379259,32.75313945319649,0],[-83.61274845635847,32.75397272333648,0],[-83.61466562799973,32.7547635884388,0],[-83.61660680960262,32.75551149954699,0],[-83.61857065109865,32.756215934654755,0],[-83.62055578961366,32.75687640673859,0],[-83.62256084632457,32.75749245578336,0],[-83.62458442890414,32.75806365483586,0],[-83.62662513245226,32.75858960587211,0],[-83.62868153809899,32.759069943900975,0],[-83.63075221766115,32.759504334926895,0],[-83.6328357331767,32.759892478947584,0],[-83.6349306369047,32.76023410294001,0],[-83.63703547248946,32.76052897293848,0],[-83.63914877915153,32.76077688192745,0],[-83.64126908772954,32.760977657903275,0],[-83.64339492533685,32.76113116287015,0],[-83.64552481489585,32.76123728881648,0],[-83.64765727560365,32.761295961756694,0],[-83.64979082712301,32.761307141684846,0],[-83.65192398562425,32.76127082060284,0],[-83.65405527030447,32.761187023508135,0],[-83.65618319896379,32.76105580840831,0],[-83.65830629359328,32.76087726729329,0],[-83.66042307921083,32.7606515241745,0],[-83.66253208572374,32.760378736038,0],[-83.66463184629896,32.76005909090909,0],[-83.666720902951,32.75969281274174,0],[-83.66879780351513,32.75928015456466,0],[-83.67086110700251,32.758821403399814,0],[-83.67290937847787,32.75831687924383,0],[-83.67494119511315,32.75776693105163,0],[-83.67695514665314,32.75717194084009,0],[-83.67894983308719,32.756532323629834,0],[-83.68092387070277,32.75584852243937,0],[-83.68287588719608,32.755121013232745,0],[-83.68480452667785,32.75435029997188,0],[-83.6867084511868,32.75353691874934,0],[-83.68858633871054,32.752681435518205,0],[-83.69043688423329,32.75178444323992,0],[-83.69225880474181,32.75084656496929,0],[-83.69405083421947,32.74986845274852,0],[-83.69581173063119,32.74885078644311,0],[-83.69754027103403,32.74779427211197,0],[-83.69923525541884,32.746699642822385,0],[-83.70089550880579,32.74556766051264,0],[-83.70251987926525,32.74439911017125,0],[-83.70410724071183,32.74319480286376,0],[-83.70565649104168,32.74195557654766,0],[-83.70716655737118,32.740682290251605,0],[-83.70863639277735,32.73937582791714,0],[-83.71006497711272,32.738037097583764,0],[-83.71145132142914,32.73666702917708,0],[-83.71279446471812,32.735266572878935,0],[-83.71409347705406,32.73383670052444,0],[-83.71534745831372,32.73237840618403,0],[-83.71655554062085,32.73089270080836,0],[-83.71771688788061,32.729380616419256,0],[-83.7188306961288,32.72784320203518,0],[-83.71989619434675,32.7262815256503,0],[-83.72091264550903,32.72469667027635,0],[-83.72187934768948,32.72308973592171,0],[-83.72279563289698,32.721461838543654,0],[-83.72366086608594,32.71981410620665,0],[-83.72447445225765,32.718147683855385,0],[-83.72523582737989,32.71646372644627,0],[-83.72594446851502,32.71476340406971,0],[-83.72659988462323,32.713047893684596,0],[-83.7272016266906,32.71131838726742,0],[-83.72774927777567,32.70957608482731,0],[-83.72824246383601,32.70782219347475,0],[-83.72868084389114,32.70605793103041,0],[-83.72906411790967,32.70428451962234,0],[-83.7293920229094,32.7025031912739,0],[-83.72966433589676,32.700715179871075,0],[-83.7298808698651,32.69892172546988,0],[-83.7300414788296,32.69712407208444,0],[-83.73014605577549,32.69532346570795,0],[-83.73019452970033,32.693521154312656,0],[-83.73018687161033,32.691718388897606,0],[-83.73012309050767,32.689916417551466,0],[-83.7300032323846,32.68811649010913,0],[-83.7298273852511,32.68631985477568,0],[-83.72959567309675,32.684527756380156,0],[-83.72930826092573,32.68274143695762,0],[-83.72896535074773,32.680962133537285,0],[-83.72856718354245,32.6791910811693,0],[-83.72811403832833,32.67742950582342,0],[-83.72760623312291,32.67567862846354,0],[-83.72704412086836,32.67393966108957,0],[-83.72642809662005,32.672213810695574,0],[-83.72575858936847,32.670502271353506,0],[-83.72503606605545,32.66880622898625,0],[-83.72426102976982,32.66712685869006,0],[-83.7234340194563,32.66546532333759,0],[-83.72255561311698,32.66382277497487,0],[-83.7216264197786,32.66220034969901,0],[-83.72064708740885,32.66059917243128,0],[-83.7196182950583,32.659020351096295,0],[-83.71854075868117,32.65746497883392,0],[-83.71741522729366,32.655934134581365,0],[-83.71624248192614,32.65442887527333,0],[-83.71502333853363,32.65295024597017,0],[-83.71375864112719,32.65149926868198,0],[-83.71244926771118,32.650076949469984,0],[-83.7110961292355,32.64868427122874,0],[-83.70970016179575,32.64732219892485,0],[-83.70826233431666,32.64599167470751,0],[-83.70678364482677,32.6446936215174,0],[-83.70526511731526,32.64342893528683,0],[-83.70370780580646,32.642198493088834,0],[-83.70211278830624,32.64100314591942,0],[-83.70048117076016,32.639843721724354,0],[-83.5825305152402,32.7316823944815,0]]]}`
    a1 := `{"type":"Polygon","coordinates":[[[-83.7004774529266,32.6398466121988,0],[-83.70047002035855,32.63878317849731,0],[-83.70041586825457,32.63698593605796,0],[-83.70032015514218,32.635189934722355,0],[-83.7001829220105,32.633395861340894,0],[-83.70000422287623,32.63160440392813,0],[-83.69978412771954,32.62981624851955,0],[-83.69952272555449,32.62803208010292,0],[-83.69922011737137,32.62625258168692,0],[-83.69887642118621,32.62447843430119,0],[-83.69849177198259,32.62271031792762,0],[-83.69806631976164,32.62094891056905,0],[-83.69760022855255,32.61919488417471,0],[-83.69709368034157,32.617448911858,0],[-83.6965468711139,32.61571166254135,0],[-83.6959600118723,32.61398380014135,0],[-83.69533332962666,32.61226598682834,0],[-83.69466706733576,32.610558879417574,0],[-83.69396148204461,32.60886313204674,0],[-83.69321684575763,32.607179393731265,0],[-83.69243344543858,32.605508308364286,0],[-83.69161158312701,32.60385051506592,0],[-83.69075157582185,32.60220664969666,0],[-83.68985375449185,32.600577340317166,0],[-83.68891846413382,32.59896320998224,0],[-83.68794606575167,32.59736487767214,0],[-83.6869369323401,32.595782953403166,0],[-83.68589145196958,32.59421804311706,0],[-83.68481002662222,32.59267074483933,0],[-83.68369307318127,32.59114165158963,0],[-83.68254101772683,32.58963134730721,0],[-83.68135430531467,32.588140409994146,0],[-83.68013339089586,32.58666941066759,0],[-83.67887874246,32.58521891044939,0],[-83.6775908410352,32.58378946417498,0],[-83.67627018255072,32.58238161992768,0],[-83.67491727108492,32.58099591461497,0],[-83.67353262759636,32.57963287932353,0],[-83.672116782124,32.57829303408062,0],[-83.67067027669756,32.576976891812144,0],[-83.6691936661525,32.57568495659644,0],[-83.66768751766423,32.57441772040466,0],[-83.66615240620806,32.57317566915436,0],[-83.66458891968134,32.57195927688873,0],[-83.66299765913638,32.57076900868697,0],[-83.66137923156268,32.5696053204315,0],[-83.65973425803597,32.56846865624676,0],[-83.65806336847956,32.56735945001265,0],[-83.65636720096583,32.56627812687794,0],[-83.65464640637285,32.56522509872003,0],[-83.65290164081736,32.56420076950008,0],[-83.65113357426955,32.56320553037359,0],[-83.64934288275319,32.562239760214204,0],[-83.64753025020829,32.561303830095774,0],[-83.64569637058659,32.56039809694767,0],[-83.64384194505757,32.55952290582491,0],[-83.64196768247413,32.558678592702115,0],[-83.64007430088597,32.55786547859453,0],[-83.63816252230092,32.557083875495216,0],[-83.63623307966984,32.55633408241693,0],[-83.63428670803907,32.55561638434438,0],[-83.63232415432932,32.55493105625056,0],[-83.63034616674187,32.55427836018635,0],[-83.62835350104498,32.553658545105925,0],[-83.62634691952618,32.553071847041345,0],[-83.62432718982811,32.55251849201296,0],[-83.62229508215452,32.55199869096533,0],[-83.62025137346129,32.551512640931385,0],[-83.61819684489521,32.55106052890324,0],[-83.61613228225971,32.55064252688454,0],[-83.6140584727552,32.55025879587766,0],[-83.61197620917002,32.54990948087789,0],[-83.60988628662082,32.54959471587927,0],[-83.60778950394953,32.54931462087689,0],[-83.6056866623264,32.54906930390417,0],[-83.60357856571565,32.54885885793329,0],[-83.60146601715016,32.548683362970685,0],[-83.59934982455226,32.548542887017454,0],[-83.59723079793977,32.5484374830644,0],[-83.59510974337238,32.548367191122004,0],[-83.59298747366185,32.548332038187716,0],[-83.59086479905883,32.54833203826062,0],[-83.58874252934831,32.548367191340425,0],[-83.58662147571223,32.54843748342834,0],[-83.58450244816842,32.548542887526914,0],[-83.58238625650185,32.54868336362566,0],[-83.58027370793636,32.54885885873379,0],[-83.57816561039428,32.549069304850185,0],[-83.57606276877115,32.54931462196843,0],[-83.57396598609986,32.54959471711633,0],[-83.57187606448198,32.54990948226047,0],[-83.5697938008968,32.55025879740575,0],[-83.5677199913923,32.55064252855815,0],[-83.56565542782548,32.551060530722374,0],[-83.5636008992594,32.551512642896036,0],[-83.56155719173032,32.5519986930755,0],[-83.55952508405673,32.55251849423954,0],[-83.55750535342733,32.55307184944255,0],[-83.55549877190853,32.55365854762355,0],[-83.5535061073758,32.55427836282039,0],[-83.55152811978834,32.55493105905922,0],[-83.54956556514728,32.55561638726946,0],[-83.54761919456425,32.55633408551663,0],[-83.54568975100185,32.55708387876954,0],[-83.54377797346453,32.55786548198527,0],[-83.54188459094505,32.55867859620927,0],[-83.54001032940934,32.55952290944848,0],[-83.53815590388032,32.56039810068766,0],[-83.53632202437504,32.561303833952174,0],[-83.53450939194656,32.56223976424523,0],[-83.53271869949887,32.563205534521025,0],[-83.53095063306748,32.564200773763936,0],[-83.52920586855973,32.565225103100296,0],[-83.52748507315184,32.566278131374624,0],[-83.52578890668585,32.56735945462575,0],[-83.52411801619812,32.56846866097627,0],[-83.52247304278782,32.56960532527743,0],[-83.52085461637827,32.5707690135329,0],[-83.51926335501841,32.57195928185107,0],[-83.51769986965584,32.573175674116705,0],[-83.51616475831608,32.57441772548342,0],[-83.5146586088965,32.575684961791616,0],[-83.51318199858426,32.576976897123735,0],[-83.51173549420557,32.57829303950863,0],[-83.51031964780188,32.579632884867955,0],[-83.50893500442973,32.58099592015939,0],[-83.50758209412808,32.5823816254721,0],[-83.5062614348287,32.583789469835814,0],[-83.50497353456805,32.585218916226644,0],[-83.50371888531728,32.58666941656126,0],[-83.50249797101489,32.588140415887814,0],[-83.50131125871914,32.58963135320088,0],[-83.50015920442885,32.591141657599714,0],[-83.499042250173,32.59267075096583,0],[-83.49796082494206,32.594218049359974,0],[-83.49691534573569,32.595782959762495,0],[-83.49590621255695,32.597364884147886,0],[-83.49493381434942,32.5989632165744,0],[-83.49399852416602,32.600577346909326,0],[-83.49310070301064,32.60220665628882,0],[-83.49224069582189,32.60385052165808,0],[-83.49141883368495,32.60550831507286,0],[-83.49063543354052,32.60717940043984,0],[-83.48989079742816,32.60886313887173,0],[-83.48918521132211,32.610558886242565,0],[-83.48851894920583,32.61226599365333,0],[-83.48789226812434,32.613983807082754,0],[-83.48730540905737,32.61571166948276,0],[-83.48675859895658,32.61744891891582,0],[-83.48625205092023,32.61919489134895,0],[-83.48578595985666,32.620948917743284,0],[-83.48536050781033,32.622710325101856,0],[-83.48497585878133,32.624478441475425,0],[-83.48463216376032,32.626252588861156,0],[-83.48432955575183,32.628032087277155,0],[-83.48406815277187,32.62981625569379,0],[-83.48384805879388,32.631604411102366,0],[-83.48366935983424,32.63339586851513,0],[-83.48353212588765,32.63518994189659,0],[-83.48343641394669,32.63698594334861,0],[-83.48338226201733,32.638783185787965,0],[-83.48336969309977,32.640580979221035,0],[-83.48339871519394,32.642378636564594,0],[-83.48346931829994,32.644175467941444,0],[-83.48358148041709,32.64597078638477,0],[-83.48373515855175,32.64776390178455,0],[-83.4839302976977,32.6495541282217,0],[-83.48416682484796,32.65134078059206,0],[-83.48444465202166,32.653123171928804,0],[-83.48476367520172,32.654900621318724,0],[-83.48512377538256,32.656672445753124,0],[-83.48552481557246,32.658437967112754,0],[-83.48596664579938,32.660196507511195,0],[-83.48644909702827,32.661947394882795,0],[-83.48697198925194,32.663689955299255,0],[-83.48753512252708,32.6654235226321,0],[-83.48813828381364,32.66714743203344,0],[-83.48878124406448,32.66886102133291,0],[-83.4894637593313,32.67056363371527,0],[-83.49018556960047,32.672254617021885,0],[-83.490946399899,32.673933322353754,0],[-83.49174596221539,32.675599105701316,0],[-83.49258395055196,32.67725132806087,0],[-83.49346004587252,32.67888935636589,0],[-83.49437391423973,32.68051256174082,0],[-83.49532520757177,32.68212032101443,0],[-83.49631356294387,32.683712018349674,0],[-83.49733860136595,32.68528704163479,0],[-83.49839993377802,32.68684478888614,0],[-83.49949715412342,32.68838466021558,0],[-83.50062984249209,32.68990606656158,0],[-83.50179756593545,32.69140842188941,0],[-83.50299987939772,32.69289115215512,0],[-83.50423632187423,32.694353686457966,0],[-83.50550642130085,32.6957954636761,0],[-83.50680969176003,32.697215930953156,0],[-83.50814563324795,32.6986145432326,0],[-83.5095137357491,32.699990763490554,0],[-83.51091347620942,32.70134406378353,0],[-83.51234431667373,32.70267392408429,0],[-83.51380571115416,32.70397983332956,0],[-83.51529709864528,32.705261290584225,0],[-83.51681790812992,32.70651780480845,0],[-83.51836755660017,32.70774889299506,0],[-83.51994545115278,32.70895408121729,0],[-83.52155098572959,32.71013290847046,0],[-83.52318354623978,32.711284920618404,0],[-83.52484250578684,32.71240967679629,0],[-83.52652722932518,32.71350674393913,0],[-83.52823706888714,32.71457570108911,0],[-83.52997137045142,32.715616138231475,0],[-83.53172946800598,32.71662765443185,0],[-83.53351068657477,32.7176098626093,0],[-83.53531434419685,32.71856238377374,0],[-83.53713974773538,32.71948485389445,0],[-83.53898619637013,32.720376918021124,0],[-83.5408529819467,32.72123823313601,0],[-83.54273938757953,32.72206846925989,0],[-83.54464468916532,32.72286730636703,0],[-83.54656815573227,32.72363443747023,0],[-83.54850904932366,32.7243695685626,0],[-83.55046662301876,32.72507241762802,0],[-83.55244012558953,32.72574271370983,0],[-83.5544287991722,32.72638019877346,0],[-83.55643188078076,32.72698462986015,0],[-83.55844860044428,32.72755577390641,0],[-83.56047818400086,32.72809340995597,0],[-83.56251985053652,32.72859733399097,0],[-83.5645728170418,32.72906735002622,0],[-83.56663629375518,32.72950327904406,0],[-83.56870948928528,32.72990495206765,0],[-83.57079160595433,32.73027221708768,0],[-83.57288184468754,32.7306049300984,0],[-83.57497940128789,32.73090296609886,0],[-83.57708346992851,32.73116620809166,0],[-83.57919324245424,32.73139455706556,0],[-83.5813079090801,32.73158792303153,0],[-83.58253417348143,32.73167954800889,0],[-83.7004774529266,32.6398466121988,0]]]}`

    var g0, g1 geom.Geometry

    err := json.NewDecoder(strings.NewReader(a0)).Decode(&g0)
    if err != nil {
        log.Fatal(err)

    }

    err = json.NewDecoder(strings.NewReader(a1)).Decode(&g1)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(g0.Summary())
    fmt.Println(g1.Summary())

    u, err := geom.Union(g0, g1)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(u.AsText())
}

Could you give a look? Thanks!

peterstace commented 1 year ago

Thank you for the detailed bug report, I should get some time to take a look at this soon.

akhenakh commented 1 year ago

FYI the resulting polygon is probably invalid.

They visually look contiguous, but they are not, and they're actually only touching in 2 points.

akhenakh commented 1 year ago

I've tested your fix branch on the same dataset, with success. Thank you.

peterstace commented 1 year ago

Thanks for testing! FYI I've created a new tag v0.42.0 that contains the panic fix.

I haven't worked out a fix for the root cause of the issue -- that's something I still intend to look into.

In the meantime, you may wish to look into using the Union wrapper from the GEOS C library. It handles those geometry without giving an error.

wiki0831 commented 1 year ago

--alternative temp fix-- You can try reducing floating point precision to 6 decimal place (which is about 111mm), this will return a valid output and preserve the overall topology.

reference implementation:

func ReducePrecision(g geom.Geometry, decimalPlace int) geom.Geometry {
    processPoint := func(xy geom.XY) geom.XY {
        ratio := math.Pow(10, float64(decimalPlace))
        x := math.Round(xy.X*ratio) / ratio
        y := math.Round(xy.Y*ratio) / ratio
        return geom.XY{X: x, Y: y}
    }
    return g.TransformXY(processPoint)
}

https://go.dev/play/p/nckAWTeE8gR

peterstace commented 11 months ago

A fix for the root cause has been added in v0.46.0.

akhenakh commented 11 months ago

Thanks for the heads up, we switched to geos. Do you recommend moving back to the Go implementation?

peterstace commented 11 months ago

The main reasons you may wish to switch back to the Go implementation (and avoid the GEOS dependency) would be if you:

The main reason to stay with the geos package:

If the drawbacks of the geos package and the CGO/GEOS dependency are not too bad for you, I'd recommend staying with geos.

akhenakh commented 11 months ago

Having CGO is not too much of a problem, like on a CI it's okay, but the burden to maintain it for every developers environments, Mac windows ... is a bigger task, having the default build flag using the native not optimized Go would be the best option and a geos build tag for the CGO one.

But I remember you had a different API between geos and geom, which would make this difficult to implement it like that.

Thanks again for all the help, we are using your lib and it performs really well, most of the time using the native Go anyway.