# Polygon Self-Intersecting when there is minimal wrapping at -180/180 failing

**URL:** <https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065>\
**Category:** Elasticsearch\
**Created:** [May 23, 2023, 3:28am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065 "2023-05-23T03:28:35Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 23, 2023, 3:28am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/1 "2023-05-23T03:28:35Z")

</div>

I am receiving a polygon-self intersecting error when I have a polygon that barely wraps across 180 to -180:

I have a simple mapping for a index setup as:

```auto
    index_mapping = {
        "time": {
            "type": "date",
            "format": "strict_date_optional_time||epoch_second"
        },
        "polygon": {
            "type": "geo_shape",
        }
    }

```

For this example I have a simple routine that generates a circle in python:

```auto
def generate_circle(lon, lat, radius, num_points):
    circle_points = []
    for i in range(num_points):
        theta = 2 * math.pi * i / num_points
        circle_lon = lon + radius * math.cos(theta)
        circle_lat = lat + radius * math.sin(theta)
        # Normalize longitude to be between -180 and 180
        circle_lon = (circle_lon + 180) % 360 - 180
        circle_points.append([circle_lon, circle_lat])
    # Repeat the first point to close the polygon
    circle_points.append(circle_points[0])
    return circle_points

```

The center point for my circle is:

```auto
        130.42233939828182 (lon)
        19.811126221598894 (lat)

```

In python I would generate it like this:

`my_polygon = np.array( generate_circle( lon, lat, 50,360))`

```auto
{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse field [footprint] of type [geo_shape]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse field [footprint] of type [geo_shape]",
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "Polygon self-intersection at lat=26.53163948195544 lon=80.87758400007965"
    }
  },
  "status": 400
}

```

Here I made python picture of the circle properly rendered and added a dot at the self intersecting point, which is where ES "thinks" there is self intersecting that isn't actually happening based on the error:

 ![mycirc](https://us1.discourse-cdn.com/elastic/original/3X/a/8/a88f7bf79db778479410bc07b1a80585302d70c4.jpeg)

I am sure there are other boundary cases, as I was drawing a lot of circles in a similar manner and getting these sorts of errors whenever I wrap either longitude/latitude rollover points.

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 23, 2023, 9:38am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/2 "2023-05-23T09:38:27Z")

</div>

Unfortunately you are right, there are some cases where the logic to handle polygons across the dateline does not work. I am pretty sure that is the same issue as described here:

> <https://github.com/elastic/elasticsearch/issues/92949>
>
> The H3 cell with id :576531121047601151L is a cell that is close to the pole and… crosses the dateline. 
> 
> \`\`\`
> POLYGON ((145.55819761008024 87.36469531897455, -163.45686812885106 76.14556729327887, -131.70883909799159 69.3713413970545, -100.82187023945153 67.53592429216951, -66.90449930727482 72.20470504369587, -34.758418053388596 81.27137177623808, 145.55819761008024 87.36469531897455))
> \`\`\`
> 
> \<img width="339" alt="image" src="https://user-images.githubusercontent.com/29038686/212687130-93c7a107-48e2-45cd-8a56-214f5c23c8a5.png"\>
> 
> H3 boundary points are returned in CCW direction from the H3 library.  
> 
> Therefore the following command should break this polygon across the dateline which it does not (it does work for any other polygon on the H3 grid):
> 
> \`\`\`
> GeometryNormalizer.apply(Orientation.CCW, polygon)
> \`\`\`
> 
> But the following command does:
> 
> \`\`\`
> GeometryNormalizer.apply(Orientation.CW, polygon)
> \`\`\`
> 
> I guess the normalizer is detecting the polygon orientation wrong. In general the way this algorithm is trying to detect the orientation of the polygon seems wrong and needs to be revisit,

For the time being, your best option is to not normalize the longitude. In that case, it should be handled properly.

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 23, 2023, 2:48pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/3 "2023-05-23T14:48:21Z")

</div>

@Ignacio_Vera thank you for the suggestion, that got me passed that specific issue.

```auto
def generate_circle(lon, lat, radius, num_points):
    circle_points = []
    for i in range(num_points):
        theta = 2 * math.pi * i / num_points
        circle_lon = lon + radius * math.cos(theta)
        circle_lat = lat + radius * math.sin(theta)
        # Normalize longitude to be between -180 and 180
        # Disabled normalization based on Ignacio comment
        # circle_lon = (circle_lon + 180) % 360 - 180
        circle_points.append([circle_lon, circle_lat])
    # Repeat the first point to close the polygon
    circle_points.append(circle_points[0])
    return circle_points

```

In some cases that normalization caused the outer ring to be CW not CCW. Since I didn't want to generate all my polygons again, I ended up using osgeo to `MakeValid` every polygon I send in.

```auto
from osgeo import ogr
# Other code ...
geom = ogr.CreateGeometryFromJson(json.dumps(polygon))
geom = geom.MakeValid()
fixed_poly = json.loads( geom.ExportToJson())

```

This ensured that my polygon orientation was always correct.

Thank you for the work around!

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 23, 2023, 2:59pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/4 "2023-05-23T14:59:53Z")

</div>

I spoke too soon, it seems that it isn't rendering correctly, even though I no longer normalized it.

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/4/f/4fb3353bff2b59a49df60b1ac098604cdf01c805.jpeg)

I tried to manually force orientation with the geojson, but that did not work. I tried both `clockwise` and `counterclockwise` so it does seem like there is a real bug here. Not just a pure limitation.

This also breaks all the polygon intersection math.

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 23, 2023, 4:13pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/5 "2023-05-23T16:13:22Z")

</div>

Could you share how to generate that polygon again (center + radius + numPoints)? what are you using for rendering the polygon?

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 23, 2023, 6:01pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/6 "2023-05-23T18:01:38Z")

</div>

So the picture above is rendered using kibana 8.7.1 with ES 8.7.1  
However what I realized as I was getting you the data, my hack to make things load properly using OGR, was actually breaking up the polygon. This was allowing me to post it, but OGR made a multipolygon out of it, and broke it at the intersect points where the polygon wrapped at 0 to 360.0deg. So I think Kibana was doing it's best to render it.

At the end of the day, I think what has to happen is the user in this case has to know if they are generating a polygon that wraps either 0/360 or -180/180 and normalize that properly? Seems a bit tedious, and I imagine if we cross two rollovers with a big rectangle or something it would break no matter what we did with normalization? Is this by design, or should this be written up as a bug or documented in the API in some way so the user knows they have to make sure the data they send in has a continuous range (e.g. no wrap)?

Just for completeness sake, here is the the polygon:

```auto
{"type":"Polygon","coordinates":[[[302.92086341761876,27.490763815308622],[302.79356042427986,27.925698812340162],[302.67298741602195,28.3622272781889],[302.5592374826112,28.800257420853267],[302.4524061372526,29.239696542290655],[302.35259140143626,29.680450999661442],[302.25989388920914,30.122426164537107],[302.17441689065095,30.56552638003878],[302.09626645430683,31.00965491587421],[302.02555146830287,31.45471392124137],[301.96238373983556,31.90060437557009],[301.90687807269455,32.34722603707438],[301.85915234243924,32.794477389091654],[301.81932756880803,33.24225558418813],[301.78752798489637,33.690456386014176],[301.76388110258836,34.13897410889808],[301.7485177736771,34.587701555172934],[301.7415722460496,35.036529950237544],[301.7431822142521,35.48534887536081],[301.75348886368545,35.9340461982476],[301.7726369076083,36.38250800139475],[301.80077461605094,36.830618508277354],[301.8380538356604,37.2782600074195],[301.88462999941066,37.725312774417816],[301.9406621250199,38.17165499200414],[302.00631280081996,38.6171626682521],[302.0817481577166,39.0617095530538],[302.1671378257763,39.505167053017],[302.2626548738555,39.947404144958924],[302.36847573057537,40.38828728820249],[302.48478008481874,40.82768033591292],[302.6117507638026,41.265444445747995],[302.7495735866485,41.70143799013421],[302.8984371912448,42.13551646652399],[303.0585328320616,42.56753240803472],[303.23005414645337,42.997335294921264],[303.4131968868537,43.42477146738829],[303.6081586161499,43.8496840403067],[303.81513836341173,44.271912820462234],[304.0343362370464,44.69129422703151],[304.2659529923705,45.107661216052115],[304.51018955051904,45.520843209729854],[304.76724646557443,45.9306660315057],[305.03732333678244,46.3369518478887],[305.3206181627496,46.73951911814781],[305.6173266345781,47.13818255304519],[305.9276413650129,47.53275308388409],[306.2517510508455,47.9230378432378],[306.58983956605664,48.308840158816594],[306.94208498349303,48.68995956202052],[307.308658523265,49.06619181281323],[307.68972342654047,49.43732894263203],[308.0854337539961,49.80315931712498],[308.49593310888486,50.16346772056881],[308.9213532854911,50.5180354638728],[309.36181284468324,50.86664051810873],[309.8174156193421,51.20905767552237],[310.28824915363913,51.54505873997459],[310.7743830814735,51.874412748725035],[311.27586745083516,52.19688622740585],[311.7927310024446,52.51224347993162],[312.3249794127151,52.82024691495128],[312.872593512867,53.120657410264535],[313.4355274978844,53.41323471639454],[314.0137071409002,53.69773790022862],[314.60702803050225,53.973925829306786],[315.2153538503149,54.241557696950736],[315.83851472199177,54.50039358798709],[316.4763056343856,54.75019508432434],[317.1284849830909,54.99072590910016],[317.79477324570837,55.22175260752558],[318.4748518189969,55.44304526192359],[319.168362044482,55.654378237798696],[319.87490444901977,55.855530957093094],[320.59403822620385,56.046288694095324],[321.32528098330226,56.22644338878443],[322.06810877657654,56.39579447173336],[322.8219564553403,56.55414969407513],[323.58621833195804,56.70132595547692],[324.36024919117125,56.837150122585776],[325.14336564771673,56.96145983002634],[325.9348478562294,57.07410425576355],[326.73394157198715,57.174944862506926],[327.53986055527764,57.26385609684183],[328.3517893061744,57.34072603793612],[329.1688861104635,57.40545698799663],[329.99028637152304,57.4579659971355],[330.81510619730443,57.498185315953194],[331.6424462063684,57.526062769940275],[332.47139551235574,57.541562050732026],[333.301035842475,57.544662920298265],[334.13044574269674,57.535361325294794],[334.9587048204492,57.51366942001212],[335.78489797479085,57.47961549760768],[336.6081195643078,57.433243830562645],[337.42747746434884,57.37461442253961],[338.24209696761335,57.303802674996746],[339.05112448546794,57.22089897301347],[339.8537310115708,57.12600819577525],[340.6491153142868,57.019249158031734],[341.4365068298216,56.90075398956338],[342.2151682338233,56.77066746026012],[342.9843976752123,56.629146258820825],[343.74353066203935,56.47635823332638],[344.4919415950779,56.312481602024235],[345.2290449504739,56.137704142597116],[345.95429611799796,55.95222236798478],[346.66719190614714,55.75624069649973],[347.3672707294709,55.54997062354386],[348.0541124969828,55.33362990171023],[348.72733822334624,55.107441735462686],[349.38660938668426,54.87163399594348],[350.03162705837855,54.62643846078696],[350.6621308311208,54.372090083127645],[351.2778975718147,54.10882629330557],[351.8787400257511,53.83688633609773],[352.46450529786017,53.55651064565967],[353.0350732358525,53.26794025975016],[353.59035473875804,52.97141627424447],[354.1302900128368,52.667179338423594],[354.6548467951196,52.35546919105925],[355.164018563012,52.036524236901485],[355.65782274649985,51.71058116281697],[356.13629895759414,51.37787459251926],[356.5995072497668,51.03863677857817],[357.0475264183048,50.69309733018851],[357.4804523507679,50.34148297501677],[357.89839643509475,49.98401735332456],[358.30148403137895,49.620920842484374],[358.6898530119405,49.252410409953264],[359.06365237305255,48.87869949275005],[359.42304092055053,48.49999790148514],[359.76818603054846,48.116511747018265],[0.09926248561315647,47.728443387862875],[0.41645138599152015,47.335991396513684],[0.719939134845953,46.939350542942904],[1.0099164959172424,46.53871179358918],[1.2865777215949663,46.13426232424782],[1.5501197490239493,45.72618554535866],[1.8007414616018766,45.31466113828049],[2.0386430130197284,44.899865101231946],[2.2640252108538177,44.4819698036713],[2.477088956629158,44.06114404797761],[2.6780347392298793,43.63755313738426],[2.8670621785275983,43.21135894920032],[3.0443696161258655,42.78272001243814],[3.2101537501737996,42.351791589042286],[3.364609311277276,41.91872575798955],[3.5079287766303326,41.48367150159911],[3.6403021195955456,41.046774793456876],[3.761916592079153,40.608178687419375],[3.8729565371701637,40.168023407218946],[3.973603229640616,39.726446436244224],[4.0640347420347895,39.283582607118475],[4.1444258342053475,38.839564190742685],[4.214947864284701,38.394520984511075],[4.275768719207116,37.94858039944368],[4.327052763021472,37.501867546014665],[4.368960801355294,37.0545053184858],[4.4016500605061974,36.606614477581985],[4.4252741797483885,36.158313731371024],[4.439983215547266,35.7097198142324],[4.445923656476,35.26094756381977],[4.443238447722538,34.81210999594014],[4.432067024165404,34.36331837728839],[4.412545351080264,33.91468229599077],[4.38480597161846,33.46630972992261],[4.348978060271737,33.018307112777336],[4.305187481606448,32.57077939787321],[4.253556853613783,32.12383011969274],[4.194205615082006,31.677561453156965],[4.127250096451111,31.23207427064339],[4.052803593661174,30.787468196761363],[3.9709764445517175,30.343841660903422],[3.8818761074130093,29.901291947595247],[3.785607241328904,29.45991524466936],[3.682271787987265,29.01980668929115],[3.5719690546670186,28.581060411867163],[3.454795798140929,28.143769577867563],[3.330846309260756,27.70802642759587],[3.200212498016184,27.27392231393972],[3.062983978882273,26.841547738137383],[2.9192481562896524,26.410992383594383],[2.7690903100712596,25.982345147785335],[2.6125936807554497,25.555694172275267],[2.4498395545904934,25.131126870895205],[2.2809073481991002,24.708729956105316],[2.1058746927732166,24.28858946357928],[1.9248175177302433,23.87079077504248],[1.737810133761072,23.455418639395596],[1.5449253152087388,23.042557192155193],[1.3462343817235216,22.63228997324116],[1.141807279146723,22.224699943140845],[0.9317126595807608,21.819869497478273],[0.7160179606073692,21.41788048001634],[0.49478948362044567,21.01881419411911],[0.26809247124196917,20.622751412700314],[0.03599118379310667,20.22977238668354],[359.79854897479385,19.839956851999098],[359.55582836546637,19.453384035141593],[359.30789111821815,19.070132657311788],[359.05479830908104,18.69028093716604],[358.7966103990843,18.31390659219582],[358.53338730453623,17.941086838759812],[358.2651884661934,17.571898390790473],[357.9920729172901,17.206417457197134],[357.7140993504047,16.844719737987305],[357.4313261831358,16.486880419128198],[357.14381162255995,16.13297416617006],[356.85161372844226,15.78307511665386],[356.55479047516843,15.437256871325266],[356.25339981236675,15.095592484178137],[355.94749972418515,14.758154451350693],[355.63714828718753,14.425014698897991],[355.32240372683225,14.096244569465842],[355.0033244724935,13.771914807890965],[354.6799692109839,13.452095545754087],[354.3523969385373,13.13685628491285],[354.02066701120606,12.826265880043135],[353.6848391936289,12.520392520217882],[353.344973706122,12.219303709554469],[353.00113127004596,11.923066246962119],[352.6533731513992,11.631746205023092],[352.3017612025897,11.345408908042131],[351.9463579023345,11.064118909300493],[351.58722639363606,10.787939967552349],[351.22443051978706,10.516935022802942],[350.8580348583518,10.25116617140931],[350.4881047530761,9.990694640546455],[350.1147063436757,9.735580762083007],[349.7379065934572,9.485883945912343],[349.35777331472343,9.241662652786882],[348.97437519192056,9.002974366704597],[348.5877818024832,8.769875566898692],[348.19806363533826,8.54242169948284],[347.80529210703,8.320667148805837],[347.4095395754323,8.104665208571308],[347.01087935101657,7.8944680527788265],[346.6093857056499,7.69012670654505],[346.2051338788986,7.491691016863793],[345.7982000818198,7.299209623365701],[345.388661498227,7.11272992913865],[344.9765962834209,6.932298071671432],[344.5620835603814,6.757958893983309],[344.14520341342353,6.589755916003247],[343.7260368793251,6.427731306262502],[343.30466593593957,6.27192585396463],[342.8811734883152,6.122378941497266],[342.45564335234565,5.979128517449432],[342.02816023598723,5.842211070197983],[341.59880971808064,5.711661602126401],[341.1676782248254,5.587513604538191],[340.73485300395964,5.469799033326062],[340.30042209670563,5.358548285457233],[339.8644743075486,5.253790176333521],[339.4270991719223,5.155551918083335],[338.98838692188156,5.063859098840911],[338.54842844985023,4.978735663066017],[338.1073152705358,4.900203892955208],[337.66513948111253,4.828284390993152],[337.2219937197763,4.762996063689982],[336.77797112278427,4.704356106547752],[336.333165280094,4.652379990296203],[335.8876701897246,4.607081448434575],[335.4415802109643,4.5684724661132465],[334.99499001655613,4.536563270385175],[334.54799454399426,4.511362321853771],[334.1006889460676,4.492876307739934],[333.65316854079134,4.481110136387182],[333.2055287608682,4.476066933220119],[332.75786510282234,4.477748038167188],[332.310273075951,4.486153004554844],[331.8628481512406,4.501279599476258],[331.4156857103913,4.523123805633477],[330.96888099509664,4.5516798246479535],[330.5225290567216,4.586940081830398],[330.07672470652307,4.628895232396827],[329.63156246655217,4.67753416911369],[329.18713652137876,4.732844031351325],[328.74354067077087,4.79481021552098],[328.30086828346396,4.863416386867021],[327.8592122521448,4.938644492582571],[327.4186649497765,5.020474776213274],[326.9793181873813,5.108885793310499],[326.54126317339626,5.203854428292638],[326.104590474709,5.305355912469711],[325.6693899794772,5.413363843184098],[325.23575086182734,5.527850204017621],[324.8037615485236,5.648785386012698],[324.37350968768993,5.776138209853326],[323.9450821196639,5.90987594894968],[323.51856485005095,6.049964353368259],[323.09404302504487,6.196367674548185],[322.6716009090692,6.349048690742885],[322.2513218647914,6.5079687331253],[321.83328833555254,6.6730877124938806],[321.4175818302481,6.844364146516068],[321.00428291069096,7.021755187445442],[320.59347118148,7.205216650248362],[320.1852252823901,7.394703041076108],[319.7796228832956,7.590167586018441],[319.37674068163193,7.791562260074912],[318.97665440239456,7.99883781628056],[318.57943880066875,8.211943814923726],[318.18516766667943,8.430828652793684],[317.7939138333446,8.655439592397645],[317.4057491863113,8.885722791086838],[317.02074467644957,9.121623330033348],[316.638970334775,9.363085242999949],[316.26049528976785,9.610051544847018],[315.88538778705197,9.862464259721621],[315.5137152113967,10.120264448876002],[315.14554411099783,10.383392238063367],[314.7809402239971,10.651786844461224],[314.4199685071922,10.925386603073862],[314.0626931668923,11.204128992567073],[313.7091776918697,11.487950660490066],[313.35948488835913,11.776787447841368],[313.0136769170546,12.070574412936457],[312.6718153320538,12.36924585453745],[312.3339611216998,12.672735334205933],[312.00017475126964,12.980975697842082],[311.67051620746105,13.293899096374675],[311.3450450446274,13.611437005567698],[311.0238204327128,13.93352024491118],[310.7069012068407,14.260078995564902],[310.39434591850943,14.591042817324878],[310.08621288835025,14.926340664583812],[309.7825602604047,15.265900901257742],[309.48344605787923,15.609651314652394],[309.18892824033776,15.957519128242927],[308.89906476229294,16.30943101334277],[308.61391363315965,16.66531309963663],[308.3335329785366,17.025090984554748],[308.05798110278124,17.38868974146482],[307.78731655284827,17.756033926659214],[307.5215981833594,18.12704758511551],[307.2608852228783,18.50165425500751],[307.0052373413621,18.879776970946015],[306.75471471876324,19.26133826592659],[306.5093781147583,19.64626017196306],[306.2692889395783,20.034464219384308],[306.03450932591716,20.425871434772937],[305.8051022018964,20.820402337522104],[305.58113136506074,21.217976934988904],[305.3626615573831,21.618514716220258],[305.14975854125277,22.021934644227176],[304.94248917642255,22.428155146783748],[304.7409214978869,22.837094105724887],[304.5451247946613,23.24866884471756],[304.35516968943097,23.66279611547823],[304.17112821903277,24.07939208241005],[303.99307391573046,24.49837230563037],[303.82108188923763,24.919651722360758],[303.6552289094384,25.343144626648524],[303.49559348974765,25.768764647389897],[303.3422559710459,26.196424724622762],[303.1952986061143,26.626037084056914],[303.054805644486,27.057513209809112],[302.92086341761876,27.490763815308625],[302.92086341761876,27.490763815308622]]]}

```

Here is the message it complains about

```auto
{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse field [footprint] of type [geo_shape]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse field [footprint] of type [geo_shape]",
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "Polygon self-intersection at lat=19.897866172518697 lon=-53.64623045641713"
    }
  },
  "status": 400
}

```

Here is what it "should" look like

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/b/f/bfca0dc2fba1a74de56903f3e40aa2b445eb068c.jpeg)

Here is how I am plotting it in python: This requires you have installed plotly

```auto
import numpy as np
import plotly.graph_objects as go
import plotly.io as pio
import math
my_cir = # Copy what I had above (I have too many lines in this post) remove 1 set of [] from the json blob or fix my code below ;)
        
def generate_circle(lon, lat, radius, num_points):
    circle_points = []
    for i in range(num_points):
        theta = 2 * math.pi * i / num_points
        circle_lon = lon + radius * math.cos(theta)
        circle_lat = lat + radius * math.sin(theta)
        # Normalize longitude to be between -180 and 180
        circle_lon = (circle_lon + 180) % 360 - 180
        circle_points.append([circle_lat, circle_lon])
    # Repeat the first point to close the polygon
    circle_points.append(circle_points[0])
    return np.array(circle_points)

def add_trace( data, color, fig, fill=False):
    lat = data[:,1]
    lon = data[:,0]
    print(lat.shape)
    print(lon.shape)
    if not fill:
        fig.add_trace(go.Scattergeo(lat=lat,
            lon=lon,mode='lines', line=dict(color=color, width=1 ),
            showlegend=False))
    else:
        fig.add_trace(go.Scattergeo(lat=np.flip(lat),
            lon=np.flip(lon),mode='lines', line=dict(color=color, width=0.5 ),
            fill = 'toself',
            fillcolor=color,
            showlegend=False))

fig = go.Figure()

lat=19.897866172518697
lon=-53.64623045641713

fig.add_trace(go.Scattergeo(lat=[lat], lon=[lon], mode='markers',
    showlegend=False, marker=dict(color="red", size=3)))

add_trace(np.array(my_cir["coordinates"]), "green", fig)
fig.update_layout(
    showlegend=True,
    geo=dict(
        resolution=50,
        showland=True,
        landcolor='rgb(217, 217, 217)',
        countrycolor='rgb(204, 204, 204)',
        showcountries=True,
        showcoastlines=True,
        coastlinewidth=1,
        showocean=True,
        oceancolor='rgb(230, 230, 255)',
        projection_type='natural earth'
    )
)
fig.write_image( "mycirc.png", format="png", scale=4 )

```

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 23, 2023, 6:12pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/7 "2023-05-23T18:12:18Z")

</div>

I will have a closer look tomorrow but there is something very odd in the polygon you shared. The first point looks like `[302.92086341761876,27.490763815308622]` but further in the list I see the point `[0.09926248561315647,47.728443387862875]`. It seems it is considering the longitude ranges between 0 and 360. I would expect that to confuse Elasticsearch.

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 23, 2023, 7:14pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/8 "2023-05-23T19:14:01Z")

</div>

@Ignacio_Vera I will get you a better example later today, it turns out I did this in haste and had my normalization wrong, and I don't want you to waste your time with that one (looks like the conditioning that Scattergeo does on lat/lon values fix my oversight).

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 24, 2023, 1:59am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/9 "2023-05-24T01:59:08Z")

</div>

So I wanted to generate something more inline with what I am doing.  
So all of my circles I am sending to ES are generated in X,Y,Z using a unit sphere.

To demonstrate this I wrote a python script for you that you can use / modify with elasticsearch 8.7. It handles the mappings and such so other than telling Kibana the index exists and time is what you are using, it should just work for you.

It will dump out to stdout the 2 polygons, the first loads fine but plots are wrong:  
Here is the one that is considered valid, but plots wrong:

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/f/9/f9f6f98596f2b88c34d03bb030f338545b85f127.jpeg)

I normalize so that my coordinate system is 0-360deg for longitude (however the geo\_point I was getting errors when I had it from 0-360, so I left it at -180,180).

I noticed in some cases my winding could be wrong, so I enforce it using geojson\_rewind.

Here is the failing polygon:

```auto
{"time": "2023-05-23T00:05:00", "center_point": [1.25, 45.0], "poly": {"type": "Polygon", "coordinates": [[[0.866430833706147, 34.69353612407307], [0.5596083542616839, 34.69658776328635], [0.25284221113031435, 34.701383745964414], [359.9461574779588, 34.707924804887966], [359.6395792669232, 34.71621193919848], [359.33313274064017, 34.726246414299965], [359.026843124123, 34.73802976173303], [358.7207357167928, 34.75156377901997], [358.4148359045565, 34.76685052947927], [358.1091691719616, 34.783892342008244], [357.8037611144385, 34.80269181083146], [357.4986374506427, 34.82325179521299], [357.19382403490624, 34.84557541913001], [356.88934686981094, 34.86966607090475], [356.58523211889434, 34.895527402792204], [356.2815061195004, 34.92316333051972], [355.9781953957858, 34.95257803277539], [355.6753266718949, 34.98377595064078], [355.3729268853147, 35.01676178696428], [355.0710232004231, 35.051540505669934], [354.7696430222418, 35.08811733099728], [354.46881401040804, 35.12649774666669], [354.1685640933778, 35.16668749496457], [353.86892148287376, 35.20869257574249], [353.5699146885917, 35.25251924532366], [353.2715725331805, 35.29817401531018], [352.97392416750847, 35.34566365128352], [352.6769990862319, 35.39499517139072], [352.380827143681, 35.44617584480801], [352.0854385700784, 35.49921319007342], [351.7908639881056, 35.554114973278956], [351.4971344298352, 35.610889206112816], [351.20428135404427, 35.66954414374149], [350.9123366639272, 35.730088282520796], [350.62133272522436, 35.7925303575246], [350.33130238478714, 35.856879339879136], [350.04227898959516, 35.92314443389028], [349.75429640624776, 35.991335073950594], [349.46738904094735, 36.06146092121179], [349.18159185999696, 36.133531860008155], [348.8969404108311, 36.20755799401527], [348.6134708436035, 36.28354964212769], [348.3312199333522, 36.36151733403827], [348.05022510276626, 36.44147180550133], [347.7705244455767, 36.52342399326055], [347.4921567505969, 36.60738502962158], [347.2151615264363, 36.69336623664862], [346.939579026914, 36.781379119962956], [346.6654502771979, 36.871435362120344], [346.3928171006979, 36.963546815543204], [346.12172214673876, 37.057725494982265], [345.8522089190438, 37.153983569481014], [345.58432180505736, 37.252333353815324], [345.31810610613655, 37.352787299378925], [345.05360806864365, 37.455357984484415], [344.79087491597085, 37.5600581040477], [344.5299548815295, 37.666900458622564], [344.2708972427383, 37.775897942750404], [344.0137523560431, 37.88706353258851], [343.7585716930048, 38.00041027277884], [343.5054078774897, 38.115951262517285], [343.2543147239994, 38.23369964078163], [343.00534727717724, 38.35366857067507], [342.7585618525281, 38.475871222839466], [342.514016078391, 38.600320757891154], [342.27176893920216, 38.72703030783011], [342.0318808200881, 38.85601295637062], [341.79441355282836, 38.98728171814032], [341.55943046322733, 39.12084951669152], [341.32699641993474, 39.256729161266854], [341.0971778847556, 39.39493332225912], [340.87004296448794, 39.53547450530229], [340.64566146432867, 39.678365023928876], [340.4241049428856, 39.82361697072602], [340.20544676883395, 39.97124218692018], [339.9897621792542, 40.121252230318056], [339.77712833968627, 40.273658341528346], [339.5676244059345, 40.4284714083869], [339.3613315876552, 40.585701928504854], [339.158333213755, 40.74535996985683], [338.958714799628, 40.90745512932376], [338.762564116253, 41.071996489102226], [338.56997126117017, 41.238992570889906], [338.3810287313517, 41.408451287753714], [338.19583149797376, 41.58037989358539], [338.0144770830929, 41.75478493004663], [337.83706563822193, 41.93167217090373], [337.66370002479124, 42.11104656364932], [337.4944858964743, 42.29291216830745], [337.329531783343, 42.477272093315946], [337.16894917780894, 42.664128428378724], [337.0128526222914, 42.85348217417944], [336.86135979853907, 43.04533316884698], [336.7145916185146, 43.239680011062404], [336.57267231673285, 43.43651997969731], [336.4357295439221, 43.63584894987318], [336.30389446185393, 43.83766130533247], [336.17730183916154, 44.04194984701362], [336.0560901479361, 44.248705697723786], [335.94040166086006, 44.45791820280614], [335.8303825485979, 44.669574826702245], [335.7261829771278, 44.88366104531423], [335.62795720465147, 45.100160234077165], [335.53586367767286, 45.31905355165888], [335.45006512578124, 45.54031981921202], [335.37072865461784, 45.76393539511291], [335.2980258364384, 45.989874045132346], [335.23213279761575, 46.21810680799637], [335.17323030234763, 46.44860185630898], [335.1215038317524, 46.68132435282627], [335.07714365744175, 46.916236302089125], [335.0403449085608, 47.153296397443796], [335.01130763117845, 47.39245986350343], [334.99023683879017, 47.6336782941302], [334.97734255257296, 47.87689948604853], [334.97283982989194, 48.12206726823311], [334.9769487794127, 48.36912132725297], [334.9898945610161, 48.61799702879463], [335.011907368544, 48.86862523563314], [335.0432223932244, 49.12093212237054], [335.0840797654378, 49.374838987317716], [335.13472447228315, 49.63026206195575], [335.1954062481955, 49.88711231848178], [335.2663794356464, 50.14529527601582], [335.347902812733, 50.40471080612654], [335.4402393842288, 50.66525293841942], [335.543656132431, 50.92680966702595], [335.6584237239035, 51.18926275893233], [335.78481616797376, 51.45248756519687], [335.9231104226133, 51.71635283622071], [336.07358594311034, 51.980720542362285], [336.23652416873557, 52.24544570131778], [336.4122079424227, 52.51037621383077], [336.6009208583326, 52.775352709441144], [336.8029465320571, 53.04020840413812], [337.01856778815886, 53.30476897194236], [337.24806575974145, 53.568852432607066], [337.4917188948207, 53.83226905779681], [337.749801864431, 54.09482129827268], [338.0225843676725, 54.35630373478254], [338.3103298292931, 54.61650305552088], [338.6132939859373, 54.87519806318313], [338.93172335787904, 55.132159714788735], [339.26585360393307, 55.3871511975818], [339.6159077582998, 55.63992804443332], [339.9820943493884, 55.890238292257926], [340.3646054021727, 56.13782268701533], [340.76361432739986, 56.38241493888449], [341.17927370298463, 56.62374203116916], [341.6117129552027, 56.86152458640977], [342.0610359498299, 57.09547729302814], [342.52731850615976, 57.32530939561137], [343.01060584984344, 57.55072525163998], [343.51091002370674, 57.77142495707429], [344.0282072790595, 57.98710504272547], [344.562435473469, 58.19745924274699], [345.1134915044421, 58.402179335882956], [345.68122881186315, 58.600956059301375], [346.2654549852644, 58.793480093921126], [346.8659295149297, 58.979443119116006], [347.4823617283381, 59.15853893355518], [348.11440895538027, 59.330464637729094], [348.7616749669951, 59.49492187242768], [349.42370873222444, 59.65161810610933], [350.1000035380352, 59.80026796274674], [350.78999651448953, 59.940594580393835], [351.493068604853, 60.07233098942182], [352.2085450159587, 60.19522149815874], [352.93569617856235, 60.30902307258184], [353.67373924055573, 60.41350669579386], [354.42184010783205, 60.50845869230694], [355.1791160384488, 60.593682001701694], [355.9446387857097, 60.66899738605511], [356.7174382751335, 60.734244555672085], [357.4965067892865, 60.78928319812665], [358.28080362347566, 60.83399389643268], [359.0692601646763, 60.868278923316325], [359.8607853361847, 60.89206290003913], [0.6542713416947095, 60.90529330999572], [1.4485996351365316, 60.90794085934353], [2.2426470369687195, 60.89999967916492], [3.035291913909248, 60.88148736605587], [3.8254203374747817, 60.852444860516286], [4.611932137239023, 60.81293616501333], [5.393746767394305, 60.76304790603597], [6.169808909900837, 60.702888746783906], [6.93909374404501, 60.63258865928047], [7.700611820341976, 60.55229806660743], [8.453413486100885, 60.46218686759066], [9.196592820269075, 60.36244335758248], [9.929291046018818, 60.25327305997009], [10.65069940057208, 60.13489748368275], [11.360061452616947, 60.0075528222731], [12.056674868046798, 59.871488610130385], [12.73989263436357, 59.72696635106285], [13.409123762720299, 59.57425813390103], [14.063833494060873, 59.41364524895557], [14.70354304204676, 59.24541681815591], [15.327828910387893, 59.069868450541854], [15.936321825820698, 58.88730093351997], [16.528705330344224, 58.69801896897295], [17.10471407752226, 58.5023299619588], [17.664131877789714, 58.30054286839245], [18.20678953690225, 58.0929671067947], [18.73256253008043, 57.87991153794411], [19.24136855216244, 57.66168351509879], [19.733164981351706, 57.438588006379135], [20.20794629104779, 57.210926789929644], [20.665741440924194, 56.97899772161352], [21.106611274962347, 56.743094074240254], [21.53064595067883, 56.50350394668202], [21.937962420364443, 56.26050974069605], [22.328701981862935, 56.014387702831755], [22.70302791330039, 55.76540752845633], [23.06112320327503, 55.51383202467274], [23.403188385355747, 55.259916828720755], [23.729439483329543, 55.00391017833713], [24.040106071492232, 54.74605273049482], [24.335429452388382, 54.48657742493703], [24.61566095276919, 54.22570938896005], [24.88106033714189, 53.963665879972694], [25.131894337107553, 53.70065626246324], [25.36843529372146, 53.43688201613001], [25.59095990932815, 53.17253677207467], [25.7997481047164, 52.907806374112326], [25.995081976976792, 52.64286896241628], [26.177244853118395, 52.377895076883476], [26.346520434283946, 52.113047777777204], [26.503192025286353, 51.848482781372795], [26.64754184415318, 51.58434860849965], [26.779850406398623, 51.32078674403526], [26.900395978829124, 51.057931805564586], [27.009454097824687, 50.795911719569006], [27.10729714720202, 50.53484790365299], [27.19419399096455, 50.27485545345345], [27.270409656453978, 50.01604333300476], [27.336205063648322, 49.75851456745388], [27.39183679658379, 49.502366437132586], [27.4375569131181, 49.24769067209921], [27.47361278948864, 48.99457364635976], [27.500246996356736, 48.74309657106853], [27.517697203256375, 48.49333568609204], [27.526196108590966, 48.245362449396], [27.525971392533506, 47.99924372378587], [27.51724569039277, 47.75504196059538], [27.500236584200707, 47.5128153799761], [27.475156610461795, 47.272618147494555], [27.44221328217793, 47.03450054679121], [27.401609123425374, 46.79850914810017], [27.353541714912467, 46.56468697246725], [27.298203749088202, 46.33307365153996], [27.235783093504324, 46.10370558283471], [27.166462861254672, 45.876616080415204], [27.090421487429126, 45.65183552094125], [27.007832810623142, 45.42939148507016], [26.9188661586399, 45.20930889421239], [26.823686437609467, 44.991610142661486], [26.72245422383122, 44.776315225133004], [26.61532585771755, 44.5634418597617], [26.50245353928642, 44.35300560661655], [26.38398542471009, 44.145019981804936], [26.260065723483876, 43.93949656724441], [26.130834795829855, 43.73644511618897], [25.996429249996027, 43.535873654601936], [25.85698203915365, 43.3377885784733], [25.71262255763253, 43.14219474718276], [25.56347673626965, 42.9490955730132], [25.409667136675523, 42.75849310692198], [25.251313044251503, 42.5703881206783], [25.088530559816377, 42.38478018547676], [24.921432689721826, 42.201667747137314], [24.750129434357518, 42.02104819800206], [24.5747278749638, 41.84291794563849], [24.39533225868672, 41.667272478458734], [24.212044081823024, 41.494106428362464], [24.02496217121717, 41.32341363051041], [23.834182763782053, 41.155187180333144], [23.639799584126308, 40.98941948787874], [23.44190392027849, 40.826102329599905], [23.24058469750804, 40.66522689768007], [23.035928550247036, 40.50678384699479], [22.828019892125553, 40.35076333980291], [22.616940984135795, 40.197155088259265], [22.40277200094721, 40.04594839483836], [22.185591095395637, 39.89713219075565], [21.965474461175802, 39.75069507247072], [21.742496393766828, 39.606625336353964], [21.51672934962403, 39.46491101159567], [21.288244003671252, 39.325539891433955], [21.057109305130894, 39.18849956277555], [20.82339253172745, 39.05377743428037], [20.5871593423052, 38.92136076297917], [20.348473827896328, 38.791236679489984], [20.107398561281798, 38.663392211897786], [19.863994645082187, 38.5378143083586], [19.618321758419995, 38.41448985848717], [19.37043820219276, 38.293405713585344], [19.120400942996184, 38.17454870576548], [18.868265655736877, 38.057905666021774], [18.614086764974104, 37.94346344129962], [18.357917485027997, 37.83120891061141], [18.09980985889291, 37.72112900024533], [17.839814795993277, 37.61321069811131], [17.57798210881782, 37.50744106726701], [17.314360548469494, 37.40380725866434], [17.048997839164713, 37.30229652315579], [16.781940711718107, 37.202896222797875], [16.513234936045308, 37.10559384148726], [16.242925352717577, 37.01037699496405], [15.971055903599733, 36.91723344021456], [15.697669661603754, 36.82615108430514], [15.422808859587747, 36.73711799267645], [15.14651491843091, 36.650122396927145], [14.868828474312977, 36.565152702113615], [14.589789405226668, 36.48219749359218], [14.30943685675112, 36.40124554342813], [14.027809267111877, 36.32228581639537], [13.744944391555293, 36.24530747558918], [13.460879326060535, 36.170299887673345], [13.175650530415794, 36.09725262778226], [12.8892938506811, 36.02615548409733], [12.601844541062178, 35.95699846211633], [12.313337285216676, 35.889771788632935], [12.023806217015874, 35.82446591544391], [11.733284940782596, 35.76107152279909], [11.441806551025934, 35.69957952260989], [11.149403651693433, 35.63998106143039], [10.85610837495949, 35.58226752322499], [10.561952399570146, 35.52643053193531], [10.266966968761551, 35.47246195385881], [9.97118290777081, 35.4203538998509], [9.67463064095665, 35.370098727361494], [9.377340208546798, 35.32168904231643], [9.079341283028441, 35.27511770085406], [8.78066318519825, 35.230377810925944], [8.481334899888054, 35.18746273377091], [8.181385091380037, 35.14636608527069], [7.880842118528506, 35.10708173719517], [7.579734049600802, 35.06960381834463], [7.278088676853258, 35.03392671559611], [6.975933530854775, 35.00004507486043], [6.673295894572561, 34.96795380195624], [6.370202817233007, 34.93764806340674], [6.066681127970753, 34.909123287164725], [5.7627574492784674, 34.88237516327083], [5.458458210270408, 34.85739964444999], [5.153809659771468, 34.834192946650404], [4.8488378792444, 34.81275154952897], [4.543568795566443, 34.7930721968873], [4.23802819366756, 34.77515189706143], [3.9322417290413796, 34.75898792326871], [3.6262349401405913, 34.74457781391457], [3.3200332606678558, 34.73191937286184], [3.0136620317728102, 34.72101066966497], [2.707146514167448, 34.711850039771285], [2.400511900168965, 34.704436084690975], [2.0937833256823524, 34.698767672137286], [1.7869858821323987, 34.694843936138554], [1.4801446283568112, 34.69266427712282], [1.1732846024694936, 34.69222836197581], [0.866430833706147, 34.69353612407307]]]}}

```

```auto
import math
import json
import socket
import numpy as np
from datetime import datetime, timedelta
from elasticsearch import Elasticsearch, helpers
from elasticsearch.helpers import BulkIndexError
from geojson_rewind import rewind

def lla2ecef(lat, lon, alt):
    # WGS-84 ellipsoid parameters
    a = 6378137 # semi-major axis (equatorial radius) in meters
    f = 1 / 298.257223563 # flattening
    b = a * (1 - f) # semi-minor axis (polar radius) in meters

    # convert lat, lon to radians
    lat_rad = math.radians(lat)
    lon_rad = math.radians(lon)

    # Prime vertical radius of curvature at the specific latitude
    N = a / math.sqrt(1 - ((2*f - f**2) * math.sin(lat_rad)**2))

    # Calculate ECEF coordinates
    x = (N + alt) * math.cos(lat_rad) * math.cos(lon_rad)
    y = (N + alt) * math.cos(lat_rad) * math.sin(lon_rad)
    z = (b **2/a** 2 * N + alt) * math.sin(lat_rad)

    return x, y, z

def ecef2lla(x: float, y: float, z: float) -> tuple[float, float, float]:
    """
    Convert ECEF coordinates to LLA coordinates.

    Args:
        x: X coordinate in meters.
        y: Y coordinate in meters.
        z: Z coordinate in meters.

    Returns:
        Latitude in degrees.
        Longitude in degrees.
        Altitude in meters.
    """

    # Earth constants
    a = 6378137 # Semi-major axis of the Earth in meters.
    e = 8.181919084261345e-2 # Eccentricity of the Earth.

    # Calculate the radius vector.
    r = np.sqrt(x **2 + y** 2)

    # Calculate the eccentricity squared.
    e_sq = e ** 2

    # Calculate the flattening of the Earth.
    f = 1 / 298.257223563

    # Calculate the semi-minor axis of the Earth in meters.
    b = a * (1 - f)

    # Calculate the eccentricity squared of the prime vertical.
    ep_sq = (a **2 - b** 2) / b ** 2

    # Calculate the second eccentricity squared.
    ee = a **2 - b** 2

    # Calculate the auxiliary quantity f.
    f = 54 * b **2 * z** 2

    # Calculate the auxiliary quantity g.
    g = r **2 + (1 - e_sq) * z** 2 - e_sq * ee

    # Calculate the auxiliary quantity c.
    c = e_sq **2 * f * r** 2 / g ** 3

    # Calculate the auxiliary quantity s.
    s = (1 + c + np.sqrt(c **2 + 2 * c))** (1 / 3.)

    # Calculate the auxiliary quantity p.
    p = f / (3. * (g **2) * (s + (1. / s) + 1)** 2)

    # Calculate the auxiliary quantity q.
    q = np.sqrt(1 + 2 * p * e_sq ** 2)

    # Calculate the reduced semi-major axis.
    r_0 = -(p * e_sq * r) / (1 + q) + np.sqrt(0.5 * (a ** 2) * (1 + (1. / q))
                                              - p * (z **2) * (1 - e_sq) / (q * (1 + q)) - 0.5 * p * (r** 2))

    # Calculate the distance to the prime vertical.
    u = np.sqrt((r - e_sq * r_0) **2 + z** 2)

    # Calculate the distance to the ellipsoid.
    v = np.sqrt((r - e_sq * r_0) **2 + (1 - e_sq) * z** 2)

    # Calculate the height above the ellipsoid.
    z_0 = (b ** 2) * z / (a * v)

    # Calculate the altitude.
    h = u * (1 - b ** 2 / (a * v))

    # Calculate the latitude.
    phi = np.arctan((z + ep_sq * z_0) / r)

    # Calculate the longitude.
    lambd = np.arctan2(y, x)

    # Return the latitude, longitude, and altitude.
    return phi * 180 / np.pi, lambd * 180 / np.pi, h

def create_index_with_mapping(es_client, index_name):
    """
    Create Elasticsearch index with the given mapping.

    :param es: Elasticsearch instance
    :param index_name: Name of the index to create
    """

    index_mapping = {
        "time": {
            "type": "date",
            "format": "strict_date_optional_time||epoch_second"
        },
        "center_point": {
            "type": "geo_point"
        },
        "poly": {
            "type": "geo_shape",
        }
    }
    es_client.options(ignore_status=[400]).indices.create(index=index_name)
    es_client.indices.put_mapping(index=index_name, properties=index_mapping)

# Function to generate a circle's points in ECEF and convert to LLA
def generate_circle_ecef_to_lla(x_center, y_center, z_center, radius, num_points):
    circle_points = []
    for i in range(num_points):
        theta = 2 * math.pi * i / num_points
        x = x_center + radius * math.cos(theta)
        y = y_center + radius * math.sin(theta)
        z = z_center
        lat, lon, _ = ecef2lla(x, y, z)
        # Map between 0 and 360.0
        lon = np.mod( lon + 360.0, 360.0 )
        circle_points.append([lon, lat]) # Adjusted for [lon, lat] order
    # Repeat the first point to close the polygon
    circle_points.append(circle_points[0])
    return circle_points

def yield_circles(radius, lat, sides):
    #for ii in range(121, 124):
    for ii in range(2):
        circle_time = start_time + timedelta(minutes=5*ii)

        # 288 circles in 1 day
        lon = ii*1.25
        x, y, z = lla2ecef(lat, lon, 0.0)

        points = generate_circle_ecef_to_lla(x, y, z, radius, sides)

        circle = {}
        circle["time"] = circle_time.isoformat()
        # This has to be between (-180,180)
        circle["center_point"] = ((lon+180.0) % 360.0 - 180.0, lat)
        circle["poly"] = {
            'type': 'Polygon',
            'coordinates': [points]}
        inputval = {"geometry": circle["poly"], "type": "Feature"}
        poly_rw = rewind(inputval)
        circle["poly"] = poly_rw["geometry"]
        print(json.dumps(circle))
        yield circle

# Hard coded, but change as your heart desires
radius = 2000e3
sides = 360
lat = 45.0

index_name = "circles"
start_time = datetime.combine(datetime.today().date(), datetime.min.time())

es_host = f"{socket.gethostname()}"
es_port = 9200
es_client = Elasticsearch(f"http://{es_host}:{es_port}", request_timeout=30.0)

create_index_with_mapping(es_client, index_name)

data = ({
    "_index": index_name,
    "_source": es_record,
} for es_record in yield_circles(radius, lat, sides))

try:
    success, errors = helpers.bulk(es_client, data, raise_on_error=False)
    # success, errors = helpers.bulk(es_client, data, raise_on_error=False)
except BulkIndexError as e:
    print(f"{e}")
print(json.dumps(errors))

```

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 24, 2023, 12:16pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/10 "2023-05-24T12:16:25Z")

</div>

I am not sure if I follow what you are doing but the final polygon seems wrong. If you get the maximum longitude and the minimum longitude of the polygon, I would expect that maxLon - minLon \< 180 if it is not normalised.

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 24, 2023, 3:22pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/11 "2023-05-24T15:22:03Z")

</div>

maybe I don't understand what you mean by not normalized. I am sending in geodesic coordinates that are in the range of [0-360deg lat], originally the longitude was [-180,180].

Can you explain why you would expect valid polygons to be less than 180.0?

This is how I am thinking about it:  
If I have a polygon that spans -150 to 150 in longitude that would give me 150 - (-150) = 300 (say you were drawing a large box).

or if you drew a box from 10 to 200 in longitude, that would still be valid and would be 190.

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 24, 2023, 3:53pm UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/12 "2023-05-24T15:53:11Z")

</div>

Elasticsearch only considers polygons across the dateline if `maxLon - minLon` \> 180. In that case, depending on the orientation (which currently sometimes is computed wrongly) might decide to that the polygon crosses the dateline or not:

- if the polygon orientation is correct, then the polygon does _not_ cross the dateline and `maxLon - minLon` \> 180. For example it goes from -150 to 150

- if the polygon orientation is correct, then the polygon does cross the dateline. In your example, the longitudes will go from 150 to 210 (360 - 210) and `maxLon - minLon` \< 180

So your polygon example where min longitudes are around 0 and max longitudes are around 360, it makes no sense on what we are expecting,

---

<div class="post-metadata">

**Author:** ![Craig\_Roush](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/craig_roush/32/121297_2.png) [@Craig\_Roush](https://discuss.elastic.co/u/Craig_Roush)\
**Post date:** [May 25, 2023, 12:52am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/13 "2023-05-25T00:52:40Z")

</div>

So at the end of the day, I need either normalize between -180,180 or 0-360 depending on if my polygon wraps (e.g. maxLon - minLon \< 180.0).

When I modify my code I provided earlier, that resolves this issue.

Do you know if they are planning to fix the issue with not always computing the orientation correctly?

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [May 25, 2023, 10:05am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/14 "2023-05-25T10:05:31Z")

</div>

yes, we are planing to fix it.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 22, 2023, 10:06am UTC](https://discuss.elastic.co/t/polygon-self-intersecting-when-there-is-minimal-wrapping-at-180-180-failing/334065/15 "2023-06-22T10:06:26Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
