diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8a5b136..96e6c1a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,10 +38,16 @@ jobs: sudo apt-get update -y sudo apt-get install libgdal-dev gdal-bin - uses: Swatinem/rust-cache@v2 + - name: Install cargo-nextest + uses: taiki-e/install-action@nextest - name: Build run: cargo build --verbose --all - name: Run tests - run: cargo test + run: cargo nextest run + - name: Install wasm-pack + uses: taiki-e/install-action@wasm-pack + - name: Build WASM + run: wasm-pack build --target web crates/viewshed-reconstructor e2e: name: End to end tests diff --git a/Cargo.lock b/Cargo.lock index d0dc4a3..ba0dacd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,6 +261,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "console_log" version = "1.0.0" @@ -414,6 +424,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + [[package]] name = "gdal" version = "0.19.0" @@ -755,11 +789,12 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -1239,6 +1274,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "smallvec" version = "1.15.1" @@ -1364,6 +1405,7 @@ dependencies = [ "tracing", "tracing-subscriber", "tvs-lib", + "viewshed-reconstructor", ] [[package]] @@ -1484,6 +1526,19 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "viewshed-reconstructor" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "geo", + "js-sys", + "tracing", + "tracing-subscriber", + "tvs-lib", + "wasm-bindgen", +] + [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -1495,9 +1550,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -1508,9 +1563,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1518,9 +1573,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -1531,18 +1586,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 553e4cd..1465e06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "crates/total-viewsheds", "crates/tvs-lib", + "crates/viewshed-reconstructor", ] [workspace.dependencies] @@ -10,6 +11,8 @@ color-eyre = "0.6.5" geo = "0.31.0" serde = "1.0.219" serde_json = "1.0.143" +tracing = { version = "0.1.41" } +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } # Canonical lints for whole crate # @@ -24,6 +27,7 @@ serde_json = "1.0.143" [workspace.lints.rust] # It's always good to write as much documentation as possible missing_docs = "warn" +unreachable_pub = "warn" [workspace.lints.clippy] # `clippy::all` is already on by default. It implies the following: @@ -93,3 +97,8 @@ multiple_unsafe_ops_per_block = "allow" # i dont write docs with punctuation but you can still tell what im saying doc_paragraphs_missing_punctuation = "allow" + +# Along with `unreachable_pub = "warn"` this enforces the practice of explicitly defining visibility. +# Therefore, if a symbol isn't truly public to the outside world then it should be qualified with +# `pub(crate)`, `pub(super)`, etc. +redundant_pub_crate = "allow" diff --git a/benchmarks/cardiff-viewshed.json b/benchmarks/cardiff-viewshed.json index e4e80c9..f17c133 100644 --- a/benchmarks/cardiff-viewshed.json +++ b/benchmarks/cardiff-viewshed.json @@ -1 +1 @@ -{"type":"MultiPolygon","coordinates":[[[[-3.30941915032233,51.53780568725623],[-3.3080861950590075,51.537463838363806],[-3.3067278272108385,51.539473525977904],[-3.308051058272776,51.53982984855978],[-3.30941915032233,51.53780568725623]]],[[[-3.3067532597671656,51.5371219743089],[-3.3054203448869783,51.536780095091295],[-3.3040817012645824,51.53876043015245],[-3.3027585322282165,51.53840406658359],[-3.301374398918109,51.5403555525948],[-3.3026874384036735,51.54072628157445],[-3.3040816466043905,51.538760511153754],[-3.3040814266495504,51.53876083653242],[-3.3054046163768,51.53911718872721],[-3.3067532597671656,51.5371219743089]]],[[[-3.3027545746036,51.53609629117226],[-3.301421719201108,51.53575436647166],[-3.3001122499934668,51.53769129298221],[-3.296142986492751,51.53662202133366],[-3.294809777950515,51.53850132698179],[-3.293496868713629,51.53813051354931],[-3.292121712748439,51.53998073199242],[-3.290819361871763,51.539595656504524],[-3.289403348187319,51.5414166182719],[-3.287936674563477,51.54322162260439],[-3.2853765744131938,51.542395148543044],[-3.2838825360674653,51.54415660436839],[-3.283882539590554,51.544156605460735],[-3.282339851677814,51.54590090254047],[-3.280747972216977,51.547628648631274],[-3.2832353898725475,51.54853764159162],[-3.2848520415687505,51.54678290474435],[-3.287364563965132,51.54766460720725],[-3.288955930635636,51.545865045530405],[-3.2902243346867017,51.546292120102045],[-3.2917766921578884,51.544461605653204],[-3.29305685232551,51.54487478505397],[-3.2945689619709984,51.543013606564706],[-3.2958604757036007,51.5434127616585],[-3.297331055619441,51.54152128453389],[-3.298633524792323,51.54190629336489],[-3.300061375045217,51.53998480726149],[-3.3000613807697987,51.53998480889862],[-3.3000615246978775,51.53998460597773],[-3.300061648970519,51.53998443874478],[-3.3000616445665876,51.53998443737995],[-3.301435099949513,51.538048084585505],[-3.301435109195865,51.53804808704012],[-3.3014353309148015,51.53804775892073],[-3.301435381657783,51.53804768752695],[-3.3014353798962595,51.53804768698104],[-3.3027545746036,51.53609629117226]]],[[[-3.301531391252313,51.51846922562661],[-3.2987401157240672,51.51802335260609],[-3.297927299941622,51.5199341653201],[-3.3007057835951823,51.52041038807222],[-3.301531391252313,51.51846922562661]]],[[[-3.3012087224089393,51.52259467503561],[-3.299826275627792,51.52234149135655],[-3.2988924294167306,51.524263480149536],[-3.3002676332855185,51.52453169053441],[-3.3012087224089393,51.52259467503561]]],[[[-3.300429465690905,51.47112200993378],[-3.299876677384325,51.46919135361843],[-3.298462296804608,51.46935727724887],[-3.2990106053799004,51.471272494806364],[-3.300429465690905,51.47112200993378]]],[[[-3.297860841192189,51.467449081881476],[-3.2972059502024367,51.46554697406899],[-3.295801802604193,51.465743593966806],[-3.2964512325001927,51.467630008244946],[-3.2922227195104194,51.468173779262465],[-3.292804785299015,51.47002118087175],[-3.294219203863351,51.46985532906567],[-3.2947539688799137,51.47172384694748],[-3.296172857193062,51.47157341331309],[-3.295633616122381,51.46968945991539],[-3.297048021634878,51.46952357314731],[-3.296451270244276,51.46763011763405],[-3.2964513572776566,51.46763036985957],[-3.297860841192189,51.467449081881476]]],[[[-3.294397783154588,51.46594058277716],[-3.293701427004324,51.46407644155374],[-3.2909045914693213,51.464500134586196],[-3.291589425815944,51.46633373216876],[-3.294397783154588,51.46594058277716]]],[[[-3.2913903525279617,51.47018701616773],[-3.2908133024628934,51.468355353958344],[-3.2908133094856336,51.46835535285111],[-3.2908132233683562,51.468355102814556],[-3.2908131918187795,51.46835500246662],[-3.290813188746585,51.46835500301961],[-3.2901850928517304,51.466529905627844],[-3.28737666141,51.466922960950534],[-3.2867093778349465,51.46513591486066],[-3.2881078442371896,51.46492412961458],[-3.287384307827808,51.46312868548479],[-3.2845997285824597,51.46358265342938],[-3.2838395520568273,51.46182597848132],[-3.281068123361402,51.462310149944656],[-3.281815095839357,51.464036554937685],[-3.2804227609439742,51.46426348046688],[-3.281115393741344,51.46598288760219],[-3.2825139079749284,51.4657711696531],[-3.2831640642458155,51.467512776910425],[-3.2845683147463984,51.46731631224839],[-3.2851750825828887,51.46908006495374],[-3.2894037627043318,51.46853655720011],[-3.2899759095007517,51.47035283412477],[-3.2913903525279617,51.47018701616773]]],[[[-3.2906417248926534,51.52265350386927],[-3.289266632409053,51.52238518359176],[-3.2883329348950836,51.5241917206214],[-3.284230761283584,51.52334184161874],[-3.2851414514993915,51.521580126533976],[-3.2837664232317345,51.521311742016195],[-3.282863217818765,51.52305887611482],[-3.282863219579477,51.52305887666101],[-3.2819115821661913,51.52479521054463],[-3.2791931033238804,51.52419880520862],[-3.2782097777800017,51.52589531071599],[-3.276859074196047,51.52558232141124],[-3.2758372643858324,51.52725321036156],[-3.2744954971652676,51.52692553654849],[-3.2734363639174626,51.52857044469723],[-3.270771561313455,51.52788591573269],[-3.2696859693221283,51.52949010491763],[-3.2683633368450637,51.52913335243129],[-3.2672428645061706,51.530711435984315],[-3.269867850300298,51.531453642850764],[-3.2686824380520023,51.533047463787646],[-3.26998441259134,51.53343278812903],[-3.268743721640165,51.53502735718362],[-3.267458175855293,51.53660857592244],[-3.268737889279079,51.53702201923803],[-3.270034618188922,51.53542699034204],[-3.2700346239127467,51.535426992254926],[-3.2700347881659746,51.535426781390804],[-3.2700348683346,51.535426682544276],[-3.2700348656921614,51.535426681450396],[-3.271286413516726,51.53381809908892],[-3.2712864187996993,51.53381810072802],[-3.271286558487273,51.53381791293386],[-3.271286671046952,51.533817768238286],[-3.2712866670842793,51.53381776687182],[-3.272492926305972,51.532195792258065],[-3.273805495882116,51.532566844901964],[-3.2725884421503317,51.53420339748793],[-3.2738904874861694,51.53458868004804],[-3.275118322354458,51.53293756599679],[-3.273805729253845,51.53256653080873],[-3.2738056281107784,51.53256666671467],[-3.2749764726972637,51.530917304320404],[-3.2749764801807446,51.53091730650507],[-3.2749766648579732,51.530917033616724],[-3.2749767125696945,51.530916966352656],[-3.27497671080877,51.530916965806355],[-3.276101033440626,51.52925525949321],[-3.2800985143979005,51.530281860862694],[-3.278944747153586,51.531987304504966],[-3.281590354348,51.53270055973792],[-3.280368670486106,51.534421888589364],[-3.2829940875127943,51.53516380238974],[-3.284236051273269,51.533413757138355],[-3.2842360596371996,51.533413759321235],[-3.2842362608952707,51.53341346198334],[-3.284236305969749,51.533413398285006],[-3.284236304208622,51.53341339773884],[-3.285428769149896,51.53165045089856],[-3.286761382671355,51.53199256024578],[-3.2855589393280504,51.533770335890594],[-3.2868818401288373,51.53412689724795],[-3.2880942650780542,51.53233428598314],[-3.28676162940033,51.53199219481487],[-3.2867613909800344,51.531992547068036],[-3.2879140418532877,51.53020158683473],[-3.285230178217522,51.529546499592115],[-3.2863141942815433,51.527773291013844],[-3.2863141995633827,51.52777329237797],[-3.2863143101357752,51.52777310131465],[-3.2863144176849115,51.52777292561604],[-3.2863144128428217,51.5277729242513],[-3.287348566844673,51.52598817930163],[-3.2887079090007147,51.52628629951607],[-3.2897003720644458,51.52447498408043],[-3.2897003597424823,51.52447498135498],[-3.2906417248926534,51.52265350386927]],[[-3.282763833423946,51.530965827371],[-3.2814312780949053,51.53062367530658],[-3.282546179936144,51.52889168252083],[-3.2838880614237755,51.529219267168735],[-3.282763833423946,51.530965827371]],[[-3.2761012552447606,51.52925491523785],[-3.2747688086147706,51.528912690137794],[-3.274768582808892,51.52891302369831],[-3.275837239456579,51.527253250989716],[-3.275837068891129,51.52725352989573],[-3.277178846591703,51.52758118973062],[-3.2761012552447606,51.52925491523785]],[[-3.273653994316927,51.530560273052465],[-3.2723312984976376,51.53020356509095],[-3.273436146034442,51.52857078290808],[-3.2747685797470205,51.528913028639586],[-3.273653994316927,51.530560273052465]]],[[[-3.2873849446386623,51.520062103649884],[-3.2860026512133262,51.519808756977255],[-3.285141275595982,51.52158048994427],[-3.2865163182911865,51.521848861629785],[-3.2873849446386623,51.520062103649884]]],[[[-3.2823914115680166,51.52104334109557],[-3.2810164160711,51.52077492432165],[-3.2801285573884784,51.5224921723278],[-3.2814958791173097,51.522775532058866],[-3.2823914115680166,51.52104334109557]]],[[[-3.268039683192168,51.51311436482603],[-3.2652490560598153,51.51266769380919],[-3.2658645786573453,51.51111438568215],[-3.2644632983855955,51.510906261427095],[-3.2638537658218207,51.512444333802335],[-3.261063233325376,51.51199756506631],[-3.260423443347005,51.51349871485506],[-3.261812280510714,51.513737277826415],[-3.261123879626418,51.51524596029626],[-3.260393272749355,51.5167470439246],[-3.2658923758927343,51.5178215944073],[-3.266652007854612,51.51626049107757],[-3.266652009174374,51.516260491350245],[-3.266652034061804,51.51626043673494],[-3.266652153748408,51.51626019081952],[-3.266652147149595,51.516260189456126],[-3.2673677975562048,51.514691368999706],[-3.267367804593564,51.51469137008822],[-3.267367911505936,51.514691118701805],[-3.2673679442519066,51.51469104734464],[-3.267367942491704,51.5146910467982],[-3.268039683192168,51.51311436482603]]],[[[-3.265047331087454,51.50454806461478],[-3.263626403999646,51.50440143074483],[-3.2631989785720523,51.50593135810492],[-3.2617823346626027,51.50576924842497],[-3.261316766885152,51.50727918616017],[-3.2641406601677376,51.507634215233324],[-3.2646155394578877,51.50609376814499],[-3.2646155456139425,51.50609376896045],[-3.264615605605854,51.50609355466276],[-3.2646156373714326,51.50609345121478],[-3.264615634732522,51.50609345066938],[-3.265047331087454,51.50454806461478]]],[[[-3.2642427150162314,51.520917443892465],[-3.261524693533529,51.52032062797213],[-3.2606518416311285,51.52182553464567],[-3.263352827634462,51.52245187919639],[-3.2642427150162314,51.520917443892465]]],[[[-3.259773974730324,51.49046503033577],[-3.259769514361089,51.488974463086464],[-3.255450552128475,51.489002955685756],[-3.2554547340236413,51.49044617526324],[-3.249695758463139,51.490421169375885],[-3.2496609834575465,51.491801736921175],[-3.251100372499068,51.49182370374083],[-3.2510262280903235,51.49321907702875],[-3.2553420533944557,51.493331908712236],[-3.255418561096607,51.49188949737716],[-3.2568579644513176,51.49191139352996],[-3.256894479167028,51.490452662746584],[-3.259773974730324,51.49046503033577]]],[[[-3.2591229176143126,51.48153662350705],[-3.258868979749208,51.48005450883897],[-3.254579265257543,51.48036465218259],[-3.2548250005702957,51.48179967735671],[-3.2519597345964986,51.4819751615609],[-3.252160820762031,51.483381689633404],[-3.253595733065252,51.48330958175982],[-3.2537592937143955,51.4847334605837],[-3.2580695469444176,51.48456396617894],[-3.2579004559898275,51.48309315251181],[-3.257900460821481,51.483093152231966],[-3.2579004361509165,51.483092980001715],[-3.2579004235255633,51.483092870023086],[-3.25790042045117,51.48309287030092],[-3.257690298149075,51.48162442399021],[-3.2591229176143126,51.48153662350705]]],[[[-3.2370575251006684,51.446068427634955],[-3.2358170306906313,51.44483215442271],[-3.234605120934215,51.445316253789066],[-3.233344581618449,51.44410729685881],[-3.2333445842494526,51.444107295759125],[-3.233344478228016,51.44410719765995],[-3.233344337881274,51.444107063111346],[-3.233344334373717,51.44410706476045],[-3.232050260027249,51.44291199739693],[-3.2320502934570974,51.442912027264406],[-3.2332343960625627,51.44240182200474],[-3.2318922694040824,51.441207767421986],[-3.2307226134117264,51.44173079878541],[-3.232050020302428,51.442911784215426],[-3.230865900090519,51.44342197746064],[-3.232146266024495,51.44460441358133],[-3.2333932537399863,51.445800403612715],[-3.2346069668939,51.44701005082634],[-3.2370575251006684,51.446068427634955]]],[[[-3.2365515225484964,51.54213850645648],[-3.235391517956827,51.541604992737504],[-3.2339256280280284,51.54282186082797],[-3.23507053382027,51.543367934201655],[-3.2365515225484964,51.54213850645648]]],[[[-3.2321591841725437,51.47338250996534],[-3.231682270771058,51.472195465008454],[-3.2302894369610162,51.472421795160926],[-3.2307602027258646,51.473593627303956],[-3.2321591841725437,51.47338250996534]]],[[[-3.231672449727352,51.43949327825778],[-3.2302495197065118,51.4383167436149],[-3.230249753190856,51.43831692965032],[-3.2313894120078803,51.43776871352048],[-3.2299183517277945,51.436595467587296],[-3.22879418888284,51.43715602012401],[-3.230249449352495,51.43831668717366],[-3.2291097676455762,51.43886489408659],[-3.230517616286519,51.440028982812294],[-3.231672449727352,51.43949327825778]]],[[[-3.228896683874253,51.4726483311319],[-3.228399838272377,51.47149694997292],[-3.2270135450739357,51.47173838810745],[-3.227503821606495,51.472874625440156],[-3.228896683874253,51.4726483311319]]],[[[-3.2247676444344577,51.53845264061804],[-3.222478346507599,51.537360286466566],[-3.2211330568259835,51.53843708352752],[-3.2233914500159546,51.5395542183442],[-3.2247676444344577,51.53845264061804]]],[[[-3.222854675668012,51.4724628275924],[-3.2223537146617454,51.47137731614356],[-3.2209743482270055,51.47163375649805],[-3.220450768411644,51.470569284721535],[-3.2218227352530406,51.470297857282326],[-3.221261585414106,51.46922414022785],[-3.2212615871696477,51.4692241396778],[-3.2212615527797066,51.46922407744105],[-3.2212614703150595,51.46922392033761],[-3.2212614659250036,51.469223921164186],[-3.220670425395957,51.46815648095729],[-3.2193145210500083,51.46845763656992],[-3.2187025383502146,51.46741172823063],[-3.2200497962170513,51.46709584876431],[-3.219399395520678,51.46604171897702],[-3.218061194672796,51.466372232298],[-3.2173910738130673,51.46534009497484],[-3.2173912063968686,51.465340289345235],[-3.220048654041101,51.46465019635361],[-3.2193300905907605,51.46359666664936],[-3.219330091468444,51.463596666374336],[-3.2193300685662116,51.4635966343003],[-3.2193299434669305,51.463596450623506],[-3.219329938200293,51.46359645199932],[-3.2185822275693172,51.46255111337289],[-3.221199325699823,51.461803482317194],[-3.220401074545397,51.46073784958381],[-3.2204010767391513,51.46073784875909],[-3.2204010106936485,51.46073776405587],[-3.220400910293205,51.46073763000756],[-3.2204009063436496,51.460737631108024],[-3.2195732015570657,51.459681059820134],[-3.2208599895232664,51.45927894145063],[-3.21999131532131,51.45821738931913],[-3.219991315759801,51.458217389044464],[-3.2199912928708647,51.45821736218219],[-3.2199911365929577,51.45821717085138],[-3.21999113132812,51.45821717277582],[-3.2190931463025225,51.457165447522016],[-3.2190931484961234,51.457165446697324],[-3.219093080720388,51.45716537077227],[-3.219092974203711,51.457165245779635],[-3.21909297069407,51.45716524715399],[-3.2181655922240306,51.456123251075624],[-3.2169143217374314,51.456566862097375],[-3.217829478612018,51.45759515720181],[-3.216565962791385,51.45802505360324],[-3.2156632135807706,51.45701066887471],[-3.215663214019273,51.45701066860006],[-3.215663199058857,51.45701065270259],[-3.2156630274320355,51.45701045945804],[-3.2156630221671456,51.4570104613823],[-3.214732127267953,51.456006081244965],[-3.2147321316551998,51.456006079595745],[-3.214731972825872,51.45600591486679],[-3.2147319345450454,51.45600587347772],[-3.2147319336680353,51.456005874027],[-3.213773150834466,51.455011774383145],[-3.2137731539050565,51.45501177300929],[-3.2137730373267583,51.455011656522785],[-3.213772966495159,51.45501158334],[-3.213772964740608,51.45501158416425],[-3.212786395905433,51.45402787836511],[-3.211573999595481,51.45451173859854],[-3.2105740652816595,51.453552263697986],[-3.2105740674752443,51.45355226287346],[-3.210573986990227,51.453552188598735],[-3.2105738717524313,51.453552078142614],[-3.2105738686813106,51.453552079242094],[-3.2095473296504293,51.45260364650714],[-3.2095473300889243,51.45260364623253],[-3.2095473050226317,51.45260362403287],[-3.2095471181112907,51.45260345136291],[-3.2095471132856828,51.45260345328656],[-3.208494293681064,51.45166636049798],[-3.2084942954355786,51.451666359673816],[-3.2084942061723813,51.45166628293536],[-3.208494076887212,51.451666167824335],[-3.2084940733776732,51.45166616919838],[-3.2074152651285104,51.450740674380874],[-3.2085706425799843,51.450205197035345],[-3.2074506081755727,51.44927872601996],[-3.205170122260398,51.45037468550091],[-3.2040558523984024,51.449485597320425],[-3.2040558541524344,51.449485596222026],[-3.2040557666734113,51.4494855288051],[-3.204055641383712,51.44948542904709],[-3.2040556387521835,51.4494854304204],[-3.202916510424299,51.44860843380451],[-3.2018075418484044,51.44918090731573],[-3.200660320628346,51.44832846613263],[-3.197381743049494,51.450081809175295],[-3.198480700453048,51.45089843202408],[-3.199589750933273,51.45032599508592],[-3.200681287825405,51.451166398898444],[-3.2017492440268387,51.452018583371526],[-3.2027933684580145,51.452882352095145],[-3.2038132736570346,51.453757390525226],[-3.204808627003041,51.4546434145252],[-3.2057788895086836,51.455539937942525],[-3.2045800821565873,51.45603687084229],[-3.205511829669965,51.456931030639076],[-3.2067243519709954,51.456447237954464],[-3.2076440674658038,51.45736440626712],[-3.208538278301319,51.45829168441286],[-3.2110158895841843,51.45737748344871],[-3.2119089928285165,51.458341173690144],[-3.2106576063193057,51.45878471585095],[-3.21151175937576,51.45974461375326],[-3.212338945555813,51.46071360703338],[-3.213138855535764,51.46169132701568],[-3.213911517083318,51.46267781235948],[-3.2152094708420713,51.462289849028274],[-3.215964912651447,51.463298486611755],[-3.2146562927156173,51.463672253272456],[-3.215373345206578,51.46467485039051],[-3.212735517755461,51.46539370727178],[-3.212735633583696,51.46539387697344],[-3.212038992214005,51.46441974133589],[-3.210730312087895,51.464793462737525],[-3.2100175145273084,51.46384161874507],[-3.2100175167213942,51.46384161792054],[-3.210017454212545,51.463841537871964],[-3.210017367923885,51.46384142273092],[-3.2100173644124017,51.46384142355642],[-3.209278110462111,51.462897488583586],[-3.2092781130947685,51.46289748748447],[-3.209278032989516,51.46289738934477],[-3.209277968723671,51.462897307651296],[-3.2092779665290974,51.46289730820151],[-3.2085124823689264,51.46196157069717],[-3.208512483246648,51.461961570422226],[-3.208512461243349,51.46196154492858],[-3.208512324806844,51.461961378254955],[-3.2085123204182837,51.46196137962964],[-3.207720689557966,51.46103394682295],[-3.206456983826482,51.46146373403676],[-3.2072367811756775,51.46237733312877],[-3.20596122269176,51.46279327134895],[-3.2067040388073464,51.463701361324965],[-3.2074213486184777,51.464617342397716],[-3.208113016702784,51.46554104177332],[-3.2094217369640714,51.4651673534708],[-3.2100977126815007,51.466112667855334],[-3.210747237446329,51.46706525839076],[-3.212076066225651,51.46672029605743],[-3.2127083397025107,51.46769431470418],[-3.214046613948207,51.4673638663868],[-3.214660538082218,51.4683590661014],[-3.213313213273907,51.46867488549624],[-3.213890847177831,51.46966228961013],[-3.215246819428655,51.46936120088817],[-3.21580492539461,51.47036937654603],[-3.2171691151354986,51.47008309122312],[-3.2177067095367247,51.4711119145486],[-3.2182155901241263,51.4721466279813],[-3.2186955487578994,51.47318683378094],[-3.219146356845205,51.47423204313956],[-3.220539302233143,51.47400584814757],[-3.220081954033288,51.472945550247545],[-3.222854675668012,51.4724628275924]],[[-3.2160623115624496,51.46568510555795],[-3.215373471155693,51.464675026390495],[-3.2153734922941455,51.46467505599799],[-3.216692378677418,51.464315607737475],[-3.2173910628010676,51.46534007880013],[-3.2160623115624496,51.46568510555795]],[[-3.212254471766347,51.45692016085463],[-3.2113216348973928,51.455952909112014],[-3.2125474056883663,51.455482348173206],[-3.2134932148707964,51.456463023864835],[-3.212254471766347,51.45692016085463]],[[-3.212075936284157,51.46672009591881],[-3.2120759446532703,51.46672010880444],[-3.211416705294197,51.465753312193684],[-3.2127356551636868,51.46539390850116],[-3.2134047476449483,51.46637511411822],[-3.212075936284157,51.46672009591881]],[[-3.207936660806959,51.45596324246485],[-3.206977861696402,51.455043168432766],[-3.2081766222570764,51.45454621257667],[-3.209149132704333,51.455479420236934],[-3.207936660806959,51.45596324246485]]],[[[-3.2082898248788383,51.554267999527774],[-3.2073714472424952,51.553575123700426],[-3.205573932415067,51.55448465673884],[-3.2037509085137734,51.55537458793507],[-3.201903824168089,51.556244216238554],[-3.201903821524654,51.55624421432027],[-3.200032258816615,51.55709374076065],[-3.199193731670927,51.556362560430905],[-3.1973188294315147,51.55718271088737],[-3.198136740330274,51.557922919722735],[-3.2000320477654633,51.5570938369018],[-3.200031873647451,51.557093915738236],[-3.2008704263686054,51.55782509437696],[-3.202762372427609,51.55696630840521],[-3.2027623794785796,51.556966314434874],[-3.2046298935050874,51.556087059914354],[-3.204629903616674,51.55608705497005],[-3.2046302799554067,51.55608687778911],[-3.2046302751078546,51.55608687367809],[-3.2064724398109674,51.55518759045623],[-3.206472444217077,51.555187593744606],[-3.2064727466638665,51.55518744074811],[-3.2064728152440716,51.55518740723554],[-3.2064728143625523,51.55518740641329],[-3.2082898248788383,51.554267999527774]]],[[[-3.183467080204134,51.489454550344554],[-3.1834477899848483,51.488795807153394],[-3.1834477917419663,51.488795806878194],[-3.1834477885963715,51.48879575394058],[-3.1834477862903423,51.48879567137849],[-3.1834477840934925,51.48879567137962],[-3.183410082415561,51.48813723849907],[-3.1819717961203358,51.4881771779033],[-3.1820085843851196,51.48882000997718],[-3.182027396075139,51.48946312586259],[-3.183467080204134,51.489454550344554]]],[[[-3.1709129060117642,51.44279030937524],[-3.1695922581644043,51.44227533550471],[-3.1688415361782964,51.44304200412531],[-3.170140896799733,51.44354868041476],[-3.1709129060117642,51.44279030937524]]],[[[-3.1664341632505586,51.50390229413877],[-3.1651563023317495,51.503487736107076],[-3.165156273355379,51.503487770130164],[-3.1655324463838785,51.503026352348606],[-3.164243219945809,51.50262576573476],[-3.163878464162948,51.50307316385138],[-3.1626006505029225,51.50265857819444],[-3.1622352120954194,51.50308807389354],[-3.160969203850639,51.502659616774416],[-3.1606039644640105,51.50307134392267],[-3.1593501445358885,51.502629144049],[-3.159350122579705,51.50262916791955],[-3.1597031433818903,51.50223122717576],[-3.1609691274474656,51.50265970155658],[-3.1613228591534104,51.50224397831457],[-3.160045090554203,51.501829364486376],[-3.1603756121711424,51.50142399890947],[-3.1603756134900634,51.50142399945765],[-3.1603756551982443,51.50142394623094],[-3.1603756758334796,51.501423920714856],[-3.1603756749542797,51.50142392044083],[-3.160694846760993,51.5010149626273],[-3.160694806372701,51.50101501667659],[-3.161994960515245,51.50140154212586],[-3.1623133275873005,51.500974831849746],[-3.1610025702046833,51.500602533391415],[-3.1610025517666696,51.500602557809735],[-3.161298690122333,51.50018683914384],[-3.15997775255393,51.49982886366033],[-3.1599777450914934,51.49982887436023],[-3.1602523962232887,51.49942445836967],[-3.158921679868632,51.49908091382791],[-3.1586568356823386,51.499470873005386],[-3.157335939508274,51.49911286772798],[-3.1575909839628524,51.498737354443726],[-3.157590981325637,51.498737353895905],[-3.157835480334244,51.49835912296968],[-3.157835438198367,51.49835919183052],[-3.1591755267677293,51.498688204033144],[-3.1594184468415962,51.49829263120868],[-3.158069370469004,51.49797827268388],[-3.1580693489624827,51.49797830780021],[-3.158292565489367,51.497594941646994],[-3.156934933167962,51.4972953135677],[-3.1567203122180136,51.497663898352016],[-3.1553712738475053,51.497349509035864],[-3.15515531851262,51.497701121714876],[-3.1564953671682505,51.4980301640257],[-3.156260305429215,51.49839377912125],[-3.1549296513008707,51.49805018977894],[-3.1546941995944313,51.49839682620205],[-3.1544490940349976,51.49874083614043],[-3.154194418305586,51.49908210266166],[-3.1528943948320736,51.49869549361971],[-3.152641184828436,51.499019863324335],[-3.152378915888105,51.499341454468045],[-3.1536565413959847,51.49975615444783],[-3.1533735739424245,51.50008864684858],[-3.1533735748215697,51.500088647122645],[-3.1530813878571977,51.50041796154637],[-3.1527799491844077,51.50074413359133],[-3.154021091428691,51.50119999467964],[-3.1536976890727373,51.50153623794036],[-3.1549259277563966,51.502005539584914],[-3.154579875066384,51.50235150585691],[-3.1542242065210098,51.502693637618215],[-3.153859020380733,51.50303184204421],[-3.1526718026058824,51.50252305736218],[-3.1523115549214804,51.502844426031956],[-3.1519423855346465,51.50316180751632],[-3.151564452057467,51.50347506865984],[-3.1511776898352433,51.50378426123591],[-3.1534326576526217,51.504902748332675],[-3.153850270342549,51.504568879708785],[-3.1561362775908712,51.505662584269295],[-3.156574721512309,51.50529913760219],[-3.157732880477776,51.505833435791764],[-3.158175931647355,51.50545249542994],[-3.1570030084480636,51.504930899172024],[-3.1574207524221256,51.50455820466614],[-3.1574207528618516,51.5045582049403],[-3.1574207660382094,51.50455819259312],[-3.1574208393891596,51.504558127289215],[-3.157420837630449,51.50455812646683],[-3.157828093684232,51.50418093291591],[-3.157828095003207,51.50418093346411],[-3.1578281376051027,51.50418089230709],[-3.157828172741883,51.504180859929754],[-3.1578281718624264,51.504180859381414],[-3.1582248136465427,51.503799285153306],[-3.1594398506553296,51.50428184696629],[-3.1598391589596004,51.50388259604333],[-3.159839137441489,51.50388261854234],[-3.1610675027223327,51.50435185596292],[-3.1614685615928098,51.50393480288769],[-3.1602272663630333,51.5034790230128],[-3.1606039486564055,51.503071361756966],[-3.1606038946471045,51.50307142266795],[-3.1618577370909513,51.50351361185031],[-3.1622351370161637,51.5030881630648],[-3.1635011690103743,51.5035166103295],[-3.1638784452847424,51.50307318689882],[-3.1638783895283957,51.50307325521792],[-3.1651562228662202,51.503487829396214],[-3.1647672251888648,51.5039450441725],[-3.1660333051119607,51.504373464319194],[-3.1664341632505586,51.50390229413877]],[[-3.160694869589013,51.501014931898816],[-3.1593947361292565,51.500628395031676],[-3.1593947159337485,51.50062842109606],[-3.1596918117928285,51.5002302507165],[-3.1596917788690413,51.50023029708283],[-3.1610025113795652,51.50060261240773],[-3.160694869589013,51.501014931898816]],[[-3.159839212096719,51.50388254116747],[-3.1586108694142525,51.503413293590846],[-3.158985995020029,51.50302322969318],[-3.1577447493220796,51.502567423477316],[-3.158096281250363,51.50218700317457],[-3.159350075154159,51.50262921922758],[-3.1589859203679955,51.50302331118194],[-3.1602271855606525,51.50347910615008],[-3.159839212096719,51.50388254116747]],[[-3.1596918337421727,51.50023021998848],[-3.158381119519075,51.49985789246383],[-3.1586568312925363,51.499470879315524],[-3.158656781249995,51.499470952842074],[-3.159977693730706,51.49982894596769],[-3.1596918337421727,51.50023021998848]],[[-3.159086539383553,51.50102327704264],[-3.157797425541026,51.50062261944979],[-3.158094562759993,51.500241922195876],[-3.159394672468743,51.500628476243044],[-3.159086539383553,51.50102327704264]],[[-3.1578354829680877,51.49835911912876],[-3.156495411942199,51.498030094616],[-3.156720291589711,51.497663933742146],[-3.156720267889077,51.49766397434479],[-3.1580693221887812,51.497978351147],[-3.1578354829680877,51.49835911912876]],[[-3.1546572437156266,51.503887672430196],[-3.1534844017413235,51.50336604112452],[-3.153858954056649,51.503031903503924],[-3.1538589443936074,51.503031912558235],[-3.155046187734093,51.503540688746625],[-3.1546572437156266,51.503887672430196]]],[[[-3.1641382723425333,51.50949010211992],[-3.162995061062682,51.50894333664965],[-3.162453632665514,51.50937626048859],[-3.1635813788293063,51.509935400691575],[-3.1641382723425333,51.50949010211992]]],[[[-3.162633792059036,51.50616368135733],[-3.1602309302579217,51.505172295473976],[-3.1597954290306878,51.50557566794736],[-3.1593487880729407,51.50597416085919],[-3.160521760885836,51.50649573603765],[-3.1609827988746324,51.50608438876526],[-3.1621702004329846,51.506593092580836],[-3.162633792059036,51.50616368135733]]],[[[-3.161851877150382,51.50839655998736],[-3.160708720604972,51.50784977213351],[-3.1601982231639445,51.508257947946866],[-3.1613259141107095,51.50881710966496],[-3.161851877150382,51.50839655998736]]],[[[-3.1595655918656242,51.50730297336278],[-3.1584224900521405,51.506756163127314],[-3.1579429240915657,51.50713959155492],[-3.1590705598243143,51.5076987750605],[-3.1595655918656242,51.50730297336278]]],[[[-3.1388075208718114,51.48919486740104],[-3.138788180364379,51.48902273111564],[-3.13878818080375,51.48902273111558],[-3.1387881781617373,51.48902271438386],[-3.1387881763986583,51.4890226982006],[-3.1387881759592866,51.48902269820066],[-3.1387640311718803,51.48885083410638],[-3.1387640316112493,51.48885083410632],[-3.1387640294103294,51.48885082231187],[-3.138764026326599,51.488850798722794],[-3.1387640254478564,51.4888507987229],[-3.1387350746713873,51.48867919118215],[-3.1373046366252053,51.48878112466292],[-3.1373309546015684,51.48893715200981],[-3.1373529023864895,51.489093412759246],[-3.1373704825764794,51.48924992199966],[-3.1388075208718114,51.48919486740104]]],[[[-3.136505999660156,51.415676193711256],[-3.1344351159271846,51.41554031448968],[-3.1344351163650295,51.41554031119806],[-3.1344348022747752,51.41554029394782],[-3.134434690412711,51.415540286552634],[-3.1344346899743862,51.41554028792418],[-3.1323603401400955,51.41542699195771],[-3.1323603392639963,51.415426997992384],[-3.130283579668248,51.41533633880241],[-3.130283579667681,51.41533633523652],[-3.1302832774255362,51.41533632538051],[-3.1302831528436443,51.415336319902245],[-3.1302831524051964,51.41533632127377],[-3.1282041848411457,51.41526830283078],[-3.1282041852791873,51.415268297344774],[-3.126123155818234,51.41522292941023],[-3.12612315581814,51.41522292803873],[-3.1261230417653003,51.41522292694455],[-3.1261227847075213,51.415222921191116],[-3.126122784707708,51.415222923934124],[-3.124041236999142,51.41520024176287],[-3.1240412369991044,51.41520024011707],[-3.1240411102251318,51.415200240118196],[-3.124040808862707,51.41520023682928],[-3.124040808862782,51.41520024012088],[-3.121959002573211,51.41520024012087],[-3.1219590021346213,51.41520023682926],[-3.1219587007721965,51.41520024011818],[-3.121958573998224,51.41520024011705],[-3.1219585739981865,51.41520024176285],[-3.119877083316021,51.41522292366129],[-3.1198770833161515,51.41522292174118],[-3.1198769087274263,51.415222925576735],[-3.1198766547405046,51.41522292831297],[-3.119876655178982,51.415222931055965],[-3.11779605385603,51.415268289134694],[-3.1177960534173965,51.415268288860375],[-3.117796028852068,51.41526828968218],[-3.1177956827446085,51.415268297072906],[-3.1177956831828375,51.415268300913134],[-3.1157166585920826,51.41533632154795],[-3.115716658153678,51.41533631990211],[-3.115716521727728,51.41533632592824],[-3.1157162308909316,51.41533633551065],[-3.1157162313290745,51.41533633880228],[-3.113639472171988,51.41542699799226],[-3.1136394712958326,51.41542699223188],[-3.1115651210229274,51.415540287923974],[-3.1115651210232698,51.41554028655248],[-3.1115649964396423,51.415540294769315],[-3.1115646946322837,51.41554031119786],[-3.1115646955087968,51.41554031448955],[-3.1094942381701562,51.41567616578163],[-3.1094942372937897,51.41567616248994],[-3.1094939284639893,51.41567618604412],[-3.109493811337154,51.41567619371103],[-3.1094938117754167,51.41567619508257],[-3.1074273917434563,51.41583458848424],[-3.1074273913050665,51.41583458766129],[-3.1074273206770906,51.41583459368649],[-3.107427022812105,51.41583461668809],[-3.10742702368833,51.41583461997981],[-3.105364898529631,51.416015541205404],[-3.1053648998438534,51.4160155458687],[-3.103308599353434,51.41621885990315],[-3.1033085989157017,51.41621885770866],[-3.103308405889945,51.4162188790716],[-3.103308176014983,51.41621890179986],[-3.103308176891271,51.41621890426871],[-3.1012578450921304,51.41644459113825],[-3.1012578433401616,51.416444585377626],[-3.0992132605943463,51.41669267936988],[-3.099213262346352,51.41669268458193],[-3.0971766728238244,51.41696291328807],[-3.0971766723859204,51.416962911916485],[-3.097176535506278,51.41696293163589],[-3.09717630956865,51.41696296148478],[-3.0971763104446235,51.41696296395368],[-3.095147551200911,51.41725534145842],[-3.09514754901066,51.41725533624621],[-3.093126454044182,51.41756989418823],[-3.093126456234397,51.417569899126185],[-3.091115248482241,51.41790629096689],[-3.0911152462920373,51.41790628630319],[-3.0891132886686976,51.4182646144044],[-3.089113286916357,51.41826461111229],[-3.0891130004088847,51.41826466588938],[-3.089112878435846,51.41826468779809],[-3.0891128788735265,51.41826468916972],[-3.087121551240673,51.418644706451474],[-3.087121550802409,51.41864470590275],[-3.0871214889362193,51.41864471850159],[-3.0871211949652757,51.418644774368715],[-3.087121196717491,51.418644777660866],[-3.0851407452949937,51.41904643427169],[-3.085140744418727,51.41904643289991],[-3.0851406176116876,51.41904646001462],[-3.085140339428533,51.41904651643047],[-3.0851403411806158,51.41904651972263],[-3.083171418548912,51.419469681476606],[-3.0831714181111614,51.41946968037926],[-3.0831713163115486,51.419469703385836],[-3.0831710139872293,51.419469768292096],[-3.0831710161778925,51.419469771584446],[-3.0812141701308176,51.41991432075753],[-3.0812141688164467,51.419914318836966],[-3.0812139941718457,51.41991436074253],[-3.081213766434662,51.41991441222966],[-3.081213768187003,51.419914414973285],[-3.079269588286961,51.42038021715758],[-3.07926958653473,51.42038021441393],[-3.079269354399095,51.420380273027426],[-3.079269190282438,51.42038031246533],[-3.07926919159674,51.420380314385916],[-3.0773382174679047,51.4208672412237],[-3.077338215277871,51.42086723765694],[-3.077337903266482,51.42086732037385],[-3.077337870793116,51.420867328590184],[-3.077337871231556,51.42086732886465],[-3.075420742202217,51.42137522107463],[-3.075420741325915,51.42137521997707],[-3.0754206500449692,51.42137524544989],[-3.075420348559157,51.421375325148674],[-3.0754203511880727,51.42137532844132],[-3.0735177001068545,51.42190401662579],[-3.0735176979161807,51.421904013881864],[-3.0735174547839255,51.4219040848228],[-3.073517306010272,51.42190412617923],[-3.0735173073246824,51.421904127825584],[-3.0716296569893884,51.42245346589046],[-3.0716296552372215,51.422453463421],[-3.0716294252623624,51.42245353326658],[-3.0716292712164197,51.42245357818418],[-3.0716292725307746,51.42245357983056],[-3.0697571976235647,51.42302340143533],[-3.0697571958711536,51.42302339924012],[-3.0697570040713984,51.42302346004748],[-3.0697568105186024,51.42302351920824],[-3.0697568122710135,51.42302352140344],[-3.0679008327182937,51.42361366816681],[-3.067900830089787,51.42361366487397],[-3.0679005206513543,51.4236137673165],[-3.06790050177808,51.423613773342225],[-3.0679005022164967,51.42361377361673],[-3.0660612284651307,51.42422405403837],[-3.0660612267128564,51.424224051843126],[-3.066061045869548,51.424224114569846],[-3.0660608505450777,51.42422417920962],[-3.0660608527361033,51.42422418140509],[-3.064238896231541,51.42485439084842],[-3.064238895793136,51.42485439057389],[-3.064238875600828,51.42485439796986],[-3.064238520489115,51.42485452067799],[-3.0642385239938887,51.42485452479423],[-3.0624343896353565,51.425504488223154],[-3.0624343865683614,51.425504484929974],[-3.062434091573239,51.425504595594504],[-3.0624340165088952,51.42550462271136],[-3.0624340173853297,51.42550462353471],[-3.0606481943789747,51.426174165653364],[-3.0606481939405756,51.42617416537883],[-3.060648161015719,51.42617417797909],[-3.0606478818154836,51.42617428288723],[-3.0606478848827594,51.42617428590616],[-3.0588809722989407,51.42686318432151],[-3.058880970984158,51.426863183223595],[-3.058880863862187,51.426863226504295],[-3.058880607037801,51.42686332675736],[-3.0588806101054007,51.42686332950205],[-3.0571332018792594,51.4275713511458],[-3.057133196620964,51.42757134620547],[-3.0554054065012166,51.42829845059665],[-3.05540540562444,51.42829845004754],[-3.055405366107879,51.4282984673056],[-3.055405050421865,51.42829860015871],[-3.0554050543657065,51.42829860372689],[-3.0536981219450383,51.42904426881831],[-3.053698119753961,51.42904426689692],[-3.0536979643128466,51.429044337574226],[-3.05369777067569,51.42904442194393],[-3.053697773305145,51.42904442413989],[-3.0520118143332957,51.4298085949507],[-3.0520118108275454,51.42980859193129],[-3.052011541205042,51.42980871876855],[-3.0520115144192923,51.429808730821485],[-3.0520115148572478,51.42980873137035],[-3.0503470939329818,51.43059115432692],[-3.0503470934946018,51.430591154052344],[-3.0503470741720986,51.43059116336654],[-3.0503467492087966,51.43059131622409],[-3.0503467535912505,51.43059131979269],[-3.048704416134104,51.43139173803659],[-3.0487044117517037,51.43139173446792],[-3.048704111792142,51.431391885965255],[-3.048704081489599,51.43139190075821],[-3.04870408192753,51.43139190130708],[-3.0470842812744796,51.43221009277516],[-3.047084280836104,51.43221009250058],[-3.0470842689773168,51.43221009880177],[-3.047083948804179,51.43221026043092],[-3.047083953625362,51.432210263999934],[-3.045487190235196,51.43304597677372],[-3.045487187167538,51.43304597430299],[-3.0454869829217057,51.43304608498478],[-3.0454868594994995,51.43304614963777],[-3.0454868616913546,51.433046151010714],[-3.0439135751074415,51.43389915673403],[-3.0439135689712185,51.433899152341105],[-3.042363683155852,51.434769505667944],[-3.0423636914838865,51.434769511433956],[-3.0408389131421,51.43565625333889],[-3.0408389065670693,51.435656248945484],[-3.0393387531382374,51.43655965490515],[-3.03933875226151,51.43655965435593],[-3.03933872458121,51.43655967161701],[-3.039338442956204,51.43655984120711],[-3.0393384477777436,51.43655984450215],[-3.0378639898135016,51.43747926970662],[-3.0378639884983962,51.43747926888277],[-3.037863926542221,51.43747930888542],[-3.0378636888336237,51.43747945710853],[-3.03786369321729,51.43747945985471],[-3.036415031788487,51.43841483731602],[-3.036415025212459,51.43841483347098],[-3.0349923954822375,51.43936602003799],[-3.0349923928514904,51.439366018664515],[-3.0349922750709073,51.43936610004287],[-3.034992102801905,51.43936621539336],[-3.034992106309388,51.43936621731609],[-3.0335964849392805,51.44033255882279],[-3.0335964818706955,51.44033255690035],[-3.033596328477629,51.44033266705152],[-3.033596195309511,51.44033275911437],[-3.0335961979397243,51.44033276076217],[-3.032227717561338,51.44131415924758],[-3.032227715369496,51.44131415787439],[-3.0322276116329325,51.44131423487203],[-3.0322274340587225,51.441314362283485],[-3.0322274380051395,51.44131436420663],[-3.0308865104375333,51.44231052606716],[-3.030886505175975,51.44231052332003],[-3.030886268228536,51.442310705816844],[-3.0308862352601365,51.44231073020353],[-3.03088623613688,51.442310730752816],[-3.029573234658686,51.443321381005994],[-3.029573233343,51.44332138045635],[-3.0295731898180605,51.443321414983295],[-3.029573002097939,51.44332155966343],[-3.0295730064827993,51.44332156186132],[-3.0282883708971786,51.44434636523007],[-3.0282883682663666,51.444346363856454],[-3.028288260540282,51.4443464531908],[-3.0282881084150968,51.44434657430792],[-3.0282881119232297,51.44434657595656],[-3.0270322733982282,51.44538518892582],[-3.0270322716441296,51.44538518810148],[-3.027032211838973,51.44538523934637],[-3.027032013087121,51.44538540376288],[-3.0270320179110057,51.445385405961225],[-3.0258053220268466,51.446437541722645],[-3.0258053189570155,51.446437540348605],[-3.025805194934666,51.446437650788134],[-3.025805069601849,51.44643775820929],[-3.02580507267167,51.446437759583326],[-3.0246078919637265,51.447503101994165],[-3.0246078867007653,51.44750309979537],[-3.0246076931680186,51.447503278475615],[-3.0246076452279254,51.44750332122596],[-3.024607646543669,51.44750332177566],[-3.0234401064944714,51.44858176733212],[-3.0234401121959045,51.448581769805664],[-3.0223030219740603,51.44967257728345],[-3.0223030167109664,51.44967257508454],[-3.0223028372078504,51.44967275377299],[-3.0223027866160947,51.449672802554666],[-3.022302788370865,51.449672803104775],[-3.0211963129040886,51.45077580483035],[-3.021196311149898,51.45077580400593],[-3.0211962574668396,51.45077585991619],[-3.0211960867547076,51.450776029833],[-3.0211960915794824,51.45077603175728],[-3.0201205406376475,51.45189092082538],[-3.020120533180552,51.45189091807585],[-3.019075806499053,51.45301781867799],[-3.0190758130788393,51.45301782115252],[-3.018063063034488,51.45415549585722],[-3.018063059086302,51.454155494482194],[-3.018062949471055,51.45415562303],[-3.018062854394344,51.45415572964695],[-3.018062857465091,51.45415573074688],[-3.0170820175353,51.45530423544808],[-3.017082011393073,51.45530423352244],[-3.017081838797953,51.455304444301895],[-3.01708181546491,51.455304471710654],[-3.0170818163423716,51.455304471985734],[-3.01613315987592,51.45646348899208],[-3.0161331585600184,51.45646348844228],[-3.0161331259729027,51.456463529831616],[-3.0161329648165975,51.45646372690515],[-3.016132970519886,51.456463728830435],[-3.015216788611989,51.45763290451648],[-3.015216784662951,51.45763290341566],[-3.0152166868823835,51.457633033617405],[-3.0152165996834484,51.45763314517661],[-3.0152166031934335,51.457633146277026],[-3.0143331522785735,51.45881215851177],[-3.014333146574413,51.45881215686069],[-3.014333006922301,51.45881235175723],[-3.014332994588272,51.458812368477986],[-3.0143329954657885,51.45881236875311],[-3.0134823972896374,51.46000107135984],[-3.0134824047489643,51.46000107356119],[-3.0126652935882343,51.46119858268642],[-3.012665285689645,51.461198580484606],[-3.011881551328395,51.46240506019892],[-3.011881548695699,51.46240505937352],[-3.011881496235008,51.462405144081885],[-3.0118813904506982,51.46240530718895],[-3.011881395277651,51.46240530856501],[-3.011131601894855,51.46361989273817],[-3.0111315983838463,51.463619891911925],[-3.011131528711207,51.46362001061647],[-3.0111314471485717,51.46362014302454],[-3.0111314510980383,51.463620144125514],[-3.010415649083173,51.46484274430395],[-3.010415648205567,51.46484274402881],[-3.010415634090987,51.46484276925066],[-3.0104155207548415,51.46484296307044],[-3.0104155264602803,51.46484296444742],[-3.0097339562999914,51.46607317935915],[-3.0097339505944256,51.46607317798215],[-3.0097338486668646,51.46607337318374],[-3.0097338164655025,51.466073431029486],[-3.0097338182207483,51.46607343157977],[-3.00908670733114,51.467310851138265],[-3.009086705575856,51.467310850587964],[-3.0090866786509602,51.46731090514706],[-3.0090865736293906,51.46731110610531],[-3.0090865793350954,51.46731110748234],[-3.0084741098159253,51.468555386814764],[-3.0084741067430723,51.468555386263176],[-3.008474059495149,51.46855548853007],[-3.008473983129111,51.468555643708],[-3.0084739875187996,51.46855564453517],[-3.0078963468845914,51.46980640912325],[-3.0078963411779216,51.46980640802045],[-3.007896259451981,51.469806597205626],[-3.0078962280984958,51.46980666520066],[-3.007896230293052,51.46980666575142],[-3.007353581461437,51.471063569278186],[-3.0073535739985156,51.471063567899336],[-3.0068459089355155,51.472326675571615],[-3.006845916837839,51.472326676950935],[-3.0063737943209543,51.47359460045614],[-3.0063737916870132,51.47359459990493],[-3.006373762037989,51.47359468655345],[-3.00637369702724,51.473594860942],[-3.006373702295823,51.47359486177013],[-3.005937058453029,51.47486773751969],[-3.0059370505495893,51.47486773641461],[-3.0055359412416798,51.47614543785618],[-3.0055359359728206,51.47614543702801],[-3.005535884112956,51.47614561910954],[-3.005535858426601,51.476145700824425],[-3.005535861061388,51.47614570110137],[-3.005170564182327,51.4774273492017],[-3.0051705633045103,51.47742734892651],[-3.0051705553165413,51.477427380462686],[-3.005170499022287,51.47742757762591],[-3.005170504730554,51.47742757845454],[-3.0048410644694514,51.47871301120413],[-3.0048410635916127,51.478713010928935],[-3.0048410564838646,51.478713041643076],[-3.00484099657673,51.47871327583259],[-3.0048410031636976,51.47871327666213],[-3.0045475307533427,51.48000206766431],[-3.004547524604772,51.48000206710951],[-3.0045474818770104,51.480002281841074],[-3.0045474703248507,51.48000233230009],[-3.004547472081281,51.48000233257616],[-3.0042900500604923,51.48129412477085],[-3.0042900483040147,51.481294124494774],[-3.0042900398277492,51.481294174408276],[-3.0042899966539953,51.48129439078503],[-3.004290002802736,51.48129439133985],[-3.0040687125204832,51.482588790877706],[-3.004068708128096,51.48258879059895],[-3.0040686857551813,51.48258894719991],[-3.0040686670187586,51.48258905689974],[-3.004068670093216,51.482589057177165],[-3.003883577456901,51.48388570664224],[-3.0038835699898483,51.483885706086056],[-3.003734684029282,51.4851846728579],[-3.0037346932538838,51.48518467341587],[-3.0036221793675892,51.486484529258405],[-3.003622170142009,51.48648452897471],[-3.003545988185247,51.48778568018228],[-3.003545983792364,51.48778567990351],[-3.003545979465409,51.48778582253347],[-3.003545972108808,51.487785947605346],[-3.003545975622971,51.48778594788322],[-3.0035061824746667,51.489087485287314],[-3.0035061811572663,51.48908748501167],[-3.0035061810497123,51.48908752615609],[-3.0035061748036846,51.489087730500835],[-3.0035061805148104,51.48908773078095],[-3.003502777463188,51.490389510137085],[-3.003502772189851,51.490389510406004],[-3.0035027769698392,51.49038969885275],[-3.003502776781965,51.490389770718295],[-3.0035027789788895,51.49038977072053],[-3.0035357697866774,51.49169137400493],[-3.0035357662714968,51.49169137400135],[-3.003535772975664,51.49169149881316],[-3.003535776576089,51.49169163431939],[-3.0035357805306666,51.49169163432341],[-3.0036051721400736,51.49299293999664],[-3.003605180489581,51.49299293973084],[-3.003710927429282,51.49429303043217],[-3.0037109173211327,51.49429303097049],[-3.0038530324679837,51.49559203086931],[-3.003853029391223,51.495592031140475],[-3.00385304405599,51.49559213703382],[-3.0038530607927885,51.49559229093114],[-3.0038530651878537,51.49559229066131],[-3.0040314516239475,51.49688928529533],[-3.004031448107654,51.49688928556606],[-3.0040314688769567,51.4968894101177],[-3.004031487424029,51.496889544267454],[-3.0040314913797683,51.49688954399718],[-3.004246168989723,51.49818465637899],[-3.004246176461967,51.498184655837946],[-3.004496997293959,51.49947697303398],[-3.0044969946564124,51.49947697330561],[-3.004497016810585,51.49947707317183],[-3.004497047602699,51.499477231471914],[-3.004497051998133,51.499477231202064],[-3.0047839855848797,51.500766617995325],[-3.0047839772325404,51.5007666188098],[-3.0051070684500787,51.502053197042024],[-3.005107077682353,51.5020531959541],[-3.0054659723426864,51.5033355446659],[-3.0054659679461735,51.5033355452101],[-3.0054660167648266,51.503335703253576],[-3.0054660442020342,51.50333580120477],[-3.005466046839796,51.50333580093312],[-3.005860768202287,51.50461404380121],[-3.0058607594090354,51.50461404488962],[-3.006291275992253,51.50588804656829],[-3.0062912755520212,51.50588804684214],[-3.0062912790437717,51.50588805644597],[-3.006291361929535,51.505888301474734],[-3.006291368964181,51.505888300658846],[-3.0067573804464747,51.50715716350894],[-3.006757376048921,51.50715716432747],[-3.006757432390268,51.50715730591998],[-3.0067574734242637,51.507157417324784],[-3.0067574765024823,51.507157416779236],[-3.007258929755589,51.508421008664584],[-3.007258927556405,51.508421009211006],[-3.0072589559602245,51.50842107534433],[-3.0072590297737514,51.50842126166403],[-3.0072590350505326,51.508421260846355],[-3.0077957799642174,51.509679196329415],[-3.007795775566439,51.50967919714799],[-3.0077958450735522,51.5096793497247],[-3.007795887024685,51.50967944796379],[-3.007795890103064,51.50967944741822],[-3.008367880054581,51.51093159348589],[-3.085721608509103,51.49668609583448],[-3.0855349048089367,51.49627889330892],[-3.099412069106691,51.493880514166044],[-3.0993016149595984,51.49362286184591],[-3.099198411641373,51.49336411918239],[-3.1033989443967678,51.49273541999037],[-3.1033198947399545,51.492521416377336],[-3.1061314677049023,51.492132773526464],[-3.1060688393513565,51.49194863318684],[-3.107479822405184,51.491769632190866],[-3.1074271333646184,51.491600228534026],[-3.107379194322577,51.491430294992014],[-3.1102194068014843,51.49113394148261],[-3.110258632625791,51.49127295670288],[-3.1102586317469276,51.49127295697708],[-3.110258637454001,51.491272975081266],[-3.1102586400876904,51.49127298468193],[-3.110258640527158,51.49127298440767],[-3.1103017553563057,51.49141157898761],[-3.113123644532048,51.49105345787002],[-3.1131601933205877,51.491160871029074],[-3.1131601941994296,51.491160870754854],[-3.1131997328901964,51.4912678477448],[-3.113199732450747,51.49126784801906],[-3.113199735963953,51.491267857071136],[-3.113199740355306,51.49126786914054],[-3.113199740794703,51.49126786914057],[-3.1132422645765914,51.49137439898616],[-3.1132422641371917,51.491374398986125],[-3.1132422645764164,51.49137439980905],[-3.113242272920531,51.49137442038197],[-3.113242273359926,51.49137442038201],[-3.1132877690775618,51.49148047071193],[-3.1132877686381635,51.49148047071189],[-3.1132877743476306,51.491480483330015],[-3.1132877778609904,51.49148049183347],[-3.113287778300386,51.49148049183352],[-3.1133362319191646,51.49158603027622],[-3.1119556452727277,51.491841183984164],[-3.1119002618932794,51.491720544029654],[-3.110512741013016,51.491960600375215],[-3.110454246317554,51.491824229608504],[-3.1103995665602313,51.491687225594646],[-3.1089994654454003,51.49189688930221],[-3.108942983195729,51.49174403253301],[-3.1075372250632545,51.49193839294124],[-3.1075993628993595,51.492106570029144],[-3.1089994764210735,51.491896919750424],[-3.108999472908898,51.49189690987533],[-3.1090602117807173,51.49204910743645],[-3.109060211341311,51.4920491074364],[-3.1090602157321467,51.4920491178602],[-3.1090602240745873,51.49204913815912],[-3.1090602245140726,51.49204913788487],[-3.1091252182919344,51.492200671019525],[-3.1105127528693397,51.49196062780611],[-3.1105127471606546,51.49196061491357],[-3.110575055508766,51.49209634886145],[-3.1119556562518165,51.49184120839758],[-3.1120143927061235,51.49196120266955],[-3.112014392266726,51.4919612026695],[-3.1120143953411494,51.49196120843002],[-3.1120144041248095,51.491961226534414],[-3.1120144050036087,51.49196122653449],[-3.112076499387374,51.49208058663981],[-3.1120765007056463,51.49208058636564],[-3.1121419100010477,51.49219922808605],[-3.112141909561576,51.49219922836032],[-3.1121419179067806,51.4921992428988],[-3.112141923177396,51.492199252225355],[-3.1121419236168655,51.4921992519511],[-3.11221064037975,51.492317162937084],[-3.1122106399403435,51.49231716293704],[-3.1122106447719053,51.492317170892086],[-3.112210653995765,51.49231718625353],[-3.112210654435166,51.49231718625357],[-3.1122826580442013,51.49243433056464],[-3.1109429151297663,51.49276361560005],[-3.110861898618032,51.49263180181793],[-3.1108618981788503,51.492631800995],[-3.1107845795261557,51.49249912350557],[-3.109427232558057,51.49279900320228],[-3.109345462038649,51.49265066988583],[-3.109267851287709,51.492501467750486],[-3.107894556670061,51.492771576017084],[-3.1079799237456083,51.49293569929982],[-3.1066143688607606,51.493220713076234],[-3.1067125036321928,51.49339875136088],[-3.1094272492467123,51.49279903310252],[-3.109427243976579,51.49279902377582],[-3.109513138287765,51.492946423800966],[-3.1095131378483503,51.49294642380092],[-3.109513143997104,51.49294643395059],[-3.109513154976766,51.49294645287829],[-3.1095131558555855,51.49294645287841],[-3.109603170479386,51.493092914665496],[-3.110942930941457,51.492763642208416],[-3.111027604052169,51.49289452753746],[-3.111027603612699,51.4928945278117],[-3.11102761195824,51.4928945401559],[-3.111027620742841,51.49289455387161],[-3.111027621182254,51.49289455387166],[-3.1111159588244894,51.493024522809584],[-3.112436481084116,51.49266624617092],[-3.1125182083130887,51.492780877553955],[-3.112518207873617,51.49278087782821],[-3.1125182179769393,51.49278089126963],[-3.1125182245659277,51.492780900596294],[-3.1125182250053993,51.49278090032203],[-3.112603144722741,51.49289462373372],[-3.112603144283266,51.49289462400797],[-3.112603159658186,51.492894643484384],[-3.112603161854539,51.492894646501824],[-3.1126912486010583,51.49300742709737],[-3.1126912481615903,51.49300742737163],[-3.1126912587045963,51.493007439990194],[-3.1126912661723516,51.49300744986551],[-3.11269126661183,51.493007449591246],[-3.1127825116198546,51.493119275842375],[-3.1140597678442137,51.49270435224532],[-3.1141423168649203,51.49280129510783],[-3.114142315986054,51.49280129538206],[-3.114227580201735,51.492897343359026],[-3.1142275802016792,51.492897343633324],[-3.114227585473544,51.49289734911965],[-3.114227597335028,51.49289736256105],[-3.114227597774439,51.49289736256109],[-3.114315517010981,51.49299244761666],[-3.1143155165715126,51.49299244789092],[-3.114315529311815,51.492992461606676],[-3.1143155345837514,51.49299246681871],[-3.1144061171991835,51.49308659854793],[-3.115633877420612,51.49261705137067],[-3.1157137493285605,51.492696860959676],[-3.1157137524039302,51.49269686397712],[-3.115713765144701,51.49269687686984],[-3.11571376558416,51.49269687659557],[-3.1157958569232407,51.49277580357979],[-3.115795856044382,51.49277580385404],[-3.1158801589131495,51.492853840273796],[-3.1158801584737432,51.49285384027377],[-3.11588016726069,51.4928538482289],[-3.115880175608315,51.4928538556354],[-3.1159666302620117,51.492930946074516],[-3.1159666337768233,51.492930949091985],[-3.115966647396637,51.49293096143614],[-3.115966647836054,51.49293096143616],[-3.1160552446143606,51.49300709793473],[-3.116055244174955,51.493007097934694],[-3.1160552525227194,51.4930071047926],[-3.116055262188458,51.493007113296365],[-3.116055262627915,51.493007113022095],[-3.1161459751746885,51.49308227308146],[-3.1161459742958257,51.49308227335571],[-3.1162388118423863,51.49315646300609],[-3.11736573004531,51.492596996163066],[-3.1172883802025644,51.49253518440388],[-3.1172127689632725,51.492472537995006],[-3.117138910823304,51.49240906873527],[-3.117066863774262,51.49234482627854],[-3.1182535250688,51.491835785145604],[-3.1183111628570717,51.49188717743876],[-3.11831116285704,51.49188717771307],[-3.1183111698868253,51.49188718374786],[-3.1183111742804037,51.491887187862474],[-3.1183702403142335,51.49193794408994],[-3.118370239874819,51.49193794436422],[-3.118370249101453,51.491937952044886],[-3.118370252177002,51.491937954513666],[-3.1184307284447654,51.49198805986059],[-3.11843072800534,51.49198806013488],[-3.118430737232021,51.49198806754122],[-3.1184307403076046,51.491988069735726],[-3.118492607918611,51.492037508564316],[-3.1173657146675997,51.49259698381899],[-3.1174447807089787,51.4926579430948],[-3.1174447802695675,51.49265794309478],[-3.117444792132466,51.49265795214712],[-3.1174447965261396,51.49265795543889],[-3.117444796526169,51.49265795516459],[-3.117525538786201,51.49271803177907],[-3.1175255383467575,51.49271803205334],[-3.117607964735967,51.49277723203795],[-3.117607971765915,51.49277723697562],[-3.117607980992683,51.49277724383345],[-3.1176079814321223,51.49277724355918],[-3.11769205065144,51.49283553646163],[-3.1198152778190766,51.49162115055499],[-3.1198666796849874,51.4916555635184],[-3.1198666792455905,51.491655563518385],[-3.1198666875937713,51.49165556900453],[-3.11986668979066,51.49165557037609],[-3.1198666897906855,51.491655570101784],[-3.119919056250432,51.49168942460036],[-3.1199190566898225,51.49168942460037],[-3.1199723508357553,51.49172269649379],[-3.118963108599961,51.49236374471788],[-3.1190354119143064,51.492407335891706],[-3.119035411474874,51.49240733616599],[-3.1190354228988344,51.49240734274949],[-3.1190354259745092,51.492407344669665],[-3.1190354264139373,51.49240734439538],[-3.119108922920176,51.492450132972785],[-3.1191089334653976,51.492450139007644],[-3.1191089374198606,51.492450141202156],[-3.119183634147674,51.49249213074697],[-3.11918363458711,51.49249213047268],[-3.1192594783701737,51.49253329080836],[-3.119259477930728,51.492533291356935],[-3.1193364766769593,51.49257362741882],[-3.119336476237559,51.49257362741881],[-3.119336492055521,51.492573635648206],[-3.1193364924949667,51.49257363537391],[-3.1194145917190417,51.492613118631276],[-3.1194145912796305,51.492613118631276],[-3.1194145952341406,51.49261312055146],[-3.1194146070976556,51.49261312658635],[-3.1194146070976774,51.49261312631205],[-3.1194937988890445,51.492651752922335],[-3.119493798449611,51.49265175319662],[-3.119574073579368,51.492689518220025],[-3.11957407357935,51.492689518494316],[-3.1195740858823524,51.4926895239806],[-3.1195740898368816,51.49268952590081],[-3.119574090276288,51.492689525900815],[-3.119655392939693,51.49272640327537],[-3.118819197102104,51.49345811427541],[-3.1189221414482162,51.49350311538473],[-3.118922141887663,51.49350311511046],[-3.119026286581012,51.49354697043413],[-3.1190262861415663,51.49354697070841],[-3.119026307672206,51.49354697921234],[-3.1191316632540986,51.49358969313622],[-3.1191316628146875,51.493589693136215],[-3.1191316751179463,51.493589697799656],[-3.1191316839059486,51.49358970164009],[-3.1191316843453873,51.49358970136582],[-3.119238218295548,51.49363126099373],[-3.1192382178561036,51.493631261268014],[-3.1192382292806005,51.49363126538283],[-3.1192382393868536,51.4936312694976],[-3.119238239826289,51.49363126922331],[-3.1193459196239806,51.49367166193344],[-3.119345919184543,51.49367166220772],[-3.1193459367607206,51.493671668517074],[-3.1193459407153727,51.49367166988868],[-3.119345941154784,51.49367166988869],[-3.119454734278907,51.49371088305926],[-3.119454733839486,51.49371088305926],[-3.1194547355971225,51.49371088360789],[-3.11945475580974,51.49371089101451],[-3.1194547558097674,51.4937108907402],[-3.1195646284204717,51.493748912298116],[-3.119564627981036,51.49374891257241],[-3.1195646385268003,51.49374891613857],[-3.119564650830192,51.493748920253374],[-3.119564650830208,51.49374891997907],[-3.1196755699660454,51.49378573894853],[-3.119675569526603,51.49378573922282],[-3.1196755866635337,51.49378574443494],[-3.119675591936411,51.49378574635516],[-3.119675591936429,51.49378574608087],[-3.119787524196136,51.49382135121187],[-3.119787528590226,51.49382135258348],[-3.1197875461665627,51.493821358344185],[-3.1197875466059966,51.4938213580699],[-3.1199004572696993,51.49385573811251],[-3.119900457269681,51.493855738386806],[-3.1199004700125887,51.49385574195299],[-3.119900479679598,51.4938557449705],[-3.1200143349057994,51.49388888977209],[-3.1200143454516636,51.49388889278961],[-3.120014357315768,51.49388889608147],[-3.1201291447938093,51.49392080152455],[-3.120703338790713,51.493096546933366],[-3.120611499145728,51.49307101990662],[-3.1205204013831116,51.493044500419444],[-3.120430048583345,51.49301698902223],[-3.120340501388543,51.49298850464448],[-3.1210053876450523,51.4921912590557],[-3.121072545082886,51.49221262128188],[-3.121072545082876,51.49221262155618],[-3.121072556067812,51.49221262484792],[-3.121072558264793,51.492212625670845],[-3.121072558704212,51.49221262539654],[-3.121140303277544,51.49223325275355],[-3.1211403032775378,51.49223325302784],[-3.1211403107473026,51.492233255222345],[-3.12114031645948,51.492233256868204],[-3.121140316898879,51.49223325686822],[-3.121208627953539,51.4922531427716],[-3.121208627514122,51.4922531430459],[-3.1212086314687197,51.49225314414314],[-3.1212086415748903,51.492253146886256],[-3.1212774975777293,51.49227228530022],[-3.1207033198962937,51.49309654144707],[-3.120795848250795,51.493121060924366],[-3.120795847811356,51.493121061472955],[-3.120889066188593,51.4931445736735],[-3.120889066188607,51.493144573399206],[-3.120982890656667,51.49316705747341],[-3.1209828902172414,51.49316705774769],[-3.121077366469103,51.49318852494101],[-3.121077366908526,51.49318852466673],[-3.121172391238382,51.49320895083789],[-3.1211723907989546,51.49320895111217],[-3.1211724092541373,51.493208954952614],[-3.121172410132962,51.49320895495262],[-3.121267990444408,51.49322834256909],[-3.1212679900049887,51.49322834284337],[-3.121267993080855,51.49322834339202],[-3.121268009778416,51.49322834668383],[-3.121268010217843,51.49322834640954],[-3.1213641179434135,51.49324668998362],[-3.1213641179434046,51.49324669025792],[-3.1213641249739723,51.4932466913552],[-3.121364136838043,51.493246693824034],[-3.1213641372774594,51.49324669354974],[-3.1214607438495454,51.49326398731959],[-3.121460746486007,51.4932639878682],[-3.12146076318361,51.49326399088569],[-3.121460763183617,51.493263990611396],[-3.1215578391556007,51.49328022908946],[-3.1215578387161864,51.49328022908945],[-3.1215578457467656,51.49328023018672],[-3.121557858050272,51.493280232381245],[-3.121557858489692,51.49328023210695],[-3.121655373096548,51.493295410354385],[-3.121655373096541,51.49329541062868],[-3.1216553924306454,51.49329541364618],[-3.1216553928700685,51.49329541337188],[-3.1217533171042624,51.4933095269986],[-3.1217533171042566,51.4933095272729],[-3.1217533355595597,51.49330952974176],[-3.1217533368778008,51.49330952974178],[-3.1218516404134427,51.49332257408338],[-3.1218516404134364,51.49332257435767],[-3.121851647004622,51.49332257518061],[-3.1218516606264077,51.49332257682654],[-3.1218516606264153,51.49332257655224],[-3.121950314016274,51.49333454804168],[-3.1219503140162694,51.49333454831598],[-3.1219503175315726,51.49333454859031],[-3.12195033335043,51.493334550510525],[-3.121950333789848,51.493334550236234],[-3.1220493075865927,51.493345445306545],[-3.1220493071471718,51.493345445580836],[-3.122148590358715,51.4933552620368],[-3.122148590358707,51.49335526231109],[-3.1221485934346003,51.4933552625854],[-3.1221486101323057,51.4933552642313],[-3.122148610132311,51.49335526395701],[-3.122248132885075,51.493363995762834],[-3.1222481407945213,51.49336399631147],[-3.1222481526586856,51.493363997408736],[-3.1223479043997977,51.49337164346658],[-3.122184887761563,51.49426467901207],[-3.1223098520202917,51.494272878254826],[-3.1223098520202828,51.494272878803415],[-3.122435027703144,51.4942797154845],[-3.1224350272637222,51.4942797154845],[-3.1224350382492894,51.49427971603315],[-3.1224350523108146,51.494279716856106],[-3.122435052310818,51.4942797165818],[-3.1225603998586657,51.49428518850601],[-3.1225603998586715,51.494285187957416],[-3.122685856422848,51.49428929265539],[-3.122685856422846,51.494289292929686],[-3.1226858805911117,51.49428929347833],[-3.122685881469958,51.49428929347834],[-3.1228114334171266,51.494292030675375],[-3.122811445720972,51.494292030949694],[-3.1228114584642404,51.49429203122403],[-3.1228114584642417,51.49429203094972],[-3.1229370679927606,51.49429339982261],[-3.1229370802966074,51.49429339982262],[-3.122937093039877,51.49429340009694],[-3.1229370930398774,51.49429339982263],[-3.1230627205903874,51.494293399822624],[-3.123062720590388,51.49429340009693],[-3.1230627460769274,51.494293399822624],[-3.1230627465163505,51.49429339982261],[-3.123188355166024,51.49429203122402],[-3.123188368348716,51.494292030949694],[-3.123188380213139,51.49429203094967],[-3.123313932160308,51.49428929375263],[-3.123313957207419,51.49428929320397],[-3.1233139572074173,51.49428929292968],[-3.123439413771596,51.494285188231714],[-3.123439413771599,51.49428518850601],[-3.1235647613194497,51.4942797168561],[-3.1235647617588724,51.49427971685609],[-3.123564786366545,51.49427971575879],[-3.123564786366543,51.4942797154845],[-3.1236899365628963,51.494272880175046],[-3.1236899506244167,51.49427287935207],[-3.1236899616099807,51.49427287880341],[-3.1238149267475483,51.49426467901206],[-3.1238149267475417,51.49426467873777],[-3.123939618051977,51.49425512104895],[-3.1239396426596056,51.49425511885439],[-3.124064048255561,51.494244203817665],[-3.1240640482555646,51.49424420409195],[-3.124188179117702,51.49423193061094],[-3.124188179117686,51.49423193006235],[-3.1243118985751894,51.494218311579935],[-3.1243119139549242,51.494218309933984],[-3.1243119231827636,51.49421830883671],[-3.1244352422105686,51.494203343982576],[-3.12443524221058,51.49420334425688],[-3.124435262423925,51.494203341787966],[-3.1244352676969624,51.49420334096501],[-3.1245581493732995,51.49418703522682],[-3.1245581542069156,51.494187034403865],[-3.1245581739808257,51.49418703193494],[-3.124558173980816,51.49418703166064],[-3.1246805818234744,51.49416938942901],[-3.1246805980819934,51.49416938696011],[-3.1246806059915526,51.49416938586281],[-3.1248025017608683,51.49415041262574],[-3.1248025087915705,51.494150411528445],[-3.1248025259289123,51.494150408785224],[-3.124923872703711,51.494130110305115],[-3.1249238907198595,51.49413010701327],[-3.124923896871712,51.49413010591597],[-3.125044681459607,51.494108484114825],[-3.1250446814595976,51.49410848384052],[-3.1251648181645324,51.49408555408224],[-3.125164818603962,51.49408555435652],[-3.125164838817144,51.494085550241714],[-3.125164843211316,51.494085549418756],[-3.125284320159695,51.49406131417419],[-3.1252843205991225,51.49406131444847],[-3.1252843421305134,51.49406130978502],[-3.1252843443275995,51.49406130951066],[-3.1254031500854,51.494035770976446],[-3.1249224656162977,51.493188520826266],[-3.1250169040790645,51.49316706213676],[-3.1250169045184917,51.493167062411054],[-3.125016923413015,51.49316705774769],[-3.1251107474416586,51.4931445736735],[-3.1251107513963237,51.49314457285053],[-3.125110765896763,51.493144569284425],[-3.1252039473638193,51.493121066136325],[-3.125203958788388,51.49312106311885],[-3.1252039658188946,51.49312106147294],[-3.125296474839534,51.49309654693335],[-3.1252964801124046,51.49309654556178],[-3.125296493733985,51.493096541995655],[-3.1253883043782165,51.49307102292408],[-3.1259854567539147,51.49388889608145],[-3.1260993339506604,51.49385574497049],[-3.1260993396629915,51.49385574332456],[-3.126099357239397,51.49385573811247],[-3.1260993567999793,51.49385573811248],[-3.126212266145455,51.49382135861849],[-3.1262122665848753,51.49382135861848],[-3.126212284600628,51.493821352857765],[-3.1262122894341386,51.493821351486154],[-3.12632424322484,51.49378573949713],[-3.126324243224818,51.49378573922282],[-3.12643516280007,51.49374892025336],[-3.1264351693911694,51.49374891805879],[-3.126435185649223,51.493748912572386],[-3.126435185209803,51.49374891257241],[-3.126545058259889,51.493710890465884],[-3.1265450586993246,51.49371089074016],[-3.1266538948851035,51.493671661933384],[-3.126653894885083,51.493671661659086],[-3.12676157468281,51.49363126922327],[-3.126761588743691,51.493631263736894],[-3.1267615953347456,51.493631261268014],[-3.1268681297242726,51.49358970136578],[-3.126868129724306,51.49358970164008],[-3.1269735059580706,51.4935469794866],[-3.1269735235340668,51.49354697208002],[-3.12697352748868,51.493546970708394],[-3.1270776726214593,51.49350311538472],[-3.12789330491083,51.49424382103231],[-3.1280168132154134,51.49418982992075],[-3.128016819806408,51.494189826903195],[-3.1280168387006673,51.49418981867351],[-3.1280168382612046,51.49418981839923],[-3.128138794966576,51.49413450072832],[-3.1281387954060293,51.49413450100259],[-3.1282592343407507,51.494077840043545],[-3.1282592339012707,51.49407783949497],[-3.1283780210446026,51.494019898895324],[-3.1283780214840595,51.4940198991696],[-3.128495195938463,51.493960660280344],[-3.128495206483879,51.493960654793916],[-3.128495218347492,51.49396064875885],[-3.1286107181547873,51.493900142034605],[-3.1286107177153286,51.49390014176032],[-3.128724484873305,51.49383839875293],[-3.128724485312761,51.49383839902721],[-3.128836553212551,51.49377540081356],[-3.1288365523336483,51.493775400265015],[-3.1289467961876247,51.493711217076104],[-3.1289467966270723,51.49371121735037],[-3.128946815520532,51.49371120582898],[-3.1289468190356295,51.49371120390873],[-3.1290552735541133,51.49364581572424],[-3.129055273114663,51.493645815449966],[-3.129161862284112,51.4935792689092],[-3.1291618745866976,51.49357926095396],[-3.1291618842530395,51.493579254918934],[-3.1292665962101096,51.49351155661065],[-3.1292666010432226,51.49351155331885],[-3.1292666159820346,51.49351154371767],[-3.1292666155425803,51.4935115434434],[-3.12936941909222,51.49344271476941],[-3.129369425243457,51.49344271065463],[-3.1293694401821517,51.49344270050486],[-3.1293694397426934,51.49344270023058],[-3.129470302372235,51.493372762318465],[-3.1294703028116775,51.49337276259274],[-3.129569233749326,51.493301707766676],[-3.1295692333098706,51.49330170749239],[-3.129666121836984,51.49322961558372],[-3.129666123594429,51.49322961421214],[-3.1296661420477685,51.49322960049627],[-3.129666141608322,51.493229600221994],[-3.1297610013483665,51.493156462457485],[-3.130887947579347,51.493715918419404],[-3.130996234366042,51.49362938075574],[-3.130996234805503,51.49362938103001],[-3.131102087489884,51.493541675205286],[-3.1311020989129523,51.493541665329836],[-3.1311021072606358,51.49354165847185],[-3.131205469611728,51.493452830852604],[-3.131205477519911,51.49345282372035],[-3.1312054907003444,51.49345281247327],[-3.131205490260874,51.49345281219901],[-3.131306372390705,51.49336285511075],[-3.1313063719512346,51.49336285483649],[-3.1314047035722283,51.493271829733004],[-3.1314047040116857,51.49327183000727],[-3.1314047171917214,51.4932718171144],[-3.131404722463823,51.493271812450985],[-3.1315004943584754,51.49317972948825],[-3.131500496115763,51.49317972756805],[-3.131500513689152,51.493179710834696],[-3.1315005132496814,51.49317971056043],[-3.131593714004126,51.49308658044305],[-3.1303659515864024,51.49261703600908],[-3.130443579467478,51.49253636850802],[-3.1304435803463275,51.49253636878226],[-3.1305189571788485,51.49245485078004],[-3.1305189668440017,51.49245484008187],[-3.130518971237245,51.492454835144265],[-3.1305920566106766,51.49237250834083],[-3.1305920557318214,51.492372508066595],[-3.1306628276889956,51.4922893990744],[-3.130662827249544,51.49228939880014],[-3.1307312515327386,51.49220554739855],[-3.130731262076138,51.49220553395734],[-3.1307312642726917,51.49220553121423],[-3.1307973334232444,51.4921209470082],[-3.1307973448450386,51.492120931372554],[-3.1307973466023182,51.49212092945236],[-3.1308610408615034,51.49203563823104],[-3.130861050086764,51.49203562561277],[-3.1308610527225085,51.492035621772445],[-3.1309223523321044,51.49194964932483],[-3.1309223567249687,51.49194964274142],[-3.1309223646322852,51.49194963176903],[-3.1309812502743077,51.49186300580411],[-3.132311543730522,51.49220687045132],[-3.132242839775174,51.492307944768115],[-3.1321713104306887,51.49240826851472],[-3.1321713042806723,51.4924082767441],[-3.1320969815995157,51.49250780437972],[-3.1333966517758967,51.492894647324675],[-3.133481589503662,51.49278090032191],[-3.133481592139237,51.49278089648154],[-3.1334816057567476,51.492780878376756],[-3.133481605317271,51.49278087810249],[-3.133563332546255,51.49266624671945],[-3.1348838548059073,51.493024523358116],[-3.1349722100176947,51.49289452836024],[-3.134972209138806,51.49289452808603],[-3.1350568822493203,51.49276364193411],[-3.1350568831281995,51.49276364220832],[-3.1351378996400263,51.49263182842621],[-3.1351379075457126,51.49263181471059],[-3.135137915890873,51.492631801269205],[-3.1352152336649732,51.49249912460273],[-3.1338579036294525,51.4921992291832],[-3.133923313364192,51.49208058718843],[-3.1339233181954462,51.49208057813622],[-3.1339233265404123,51.49208056277484],[-3.133985407748085,51.4919612276317],[-3.1339854086269563,51.49196122790592],[-3.134044168357838,51.491841185355604],[-3.134099540758054,51.49172056899161],[-3.134099547784564,51.49172055308175],[-3.1340995517369525,51.491720544029604],[-3.134151542980056,51.49159934288426],[-3.1341515434193203,51.49159934233562],[-3.134151553080436,51.491599319293805],[-3.134200147382088,51.49147757012879],[-3.1342001482608834,51.49147757012871],[-3.1342453412554825,51.49135528474338],[-3.1342453456462636,51.49135527185103],[-3.1342453495981863,51.491355261153096],[-3.1342871079391634,51.49123252732941],[-3.135698057834607,51.4914115792619],[-3.1357411731034484,51.4912729857791],[-3.1357411783710587,51.49127296740066],[-3.135741181443986,51.49127295725137],[-3.135780407707607,51.491133941756736],[-3.1357804120967785,51.49113392474989],[-3.135780414730449,51.49113391514922],[-3.1358157480731146,51.49099449328197],[-3.1358157502673807,51.490994483681355],[-3.135815755095302,51.49099446448007],[-3.1358471845789744,51.490854679035124],[-3.1358471867725313,51.490854666965845],[-3.135847190283488,51.490854652153445],[-3.135874706727977,51.49071454537658],[-3.135874707606751,51.49071454537649],[-3.135898307976346,51.49057413345427],[-3.135898307976192,51.490574132905664],[-3.135898312801481,51.4905741046526],[-3.135898311922706,51.4905741046527],[-3.1359179791441574,51.49043348386739],[-3.135917980462315,51.49043348386724],[-3.1359337193935755,51.49029261417301],[-3.134496614648247,51.490237894126295],[-3.134507101521279,51.49011259310383],[-3.1345071024000446,51.49011259310376],[-3.1345140873133808,51.48998717310252],[-3.134514087747719,51.48998715307884],[-3.1345140881856497,51.48998714731857],[-3.134517563720224,51.48986169419472],[-3.1345175645989847,51.489861694194644],[-3.134517532978096,51.489736198073594],[-3.1345175334174753,51.48973619807355],[-3.1345175329741566,51.48973618243869],[-3.1345175329715995,51.489736172289724],[-3.1345139933676984,51.48961072176932],[-3.1345139938070763,51.48961072176929],[-3.134513992924935,51.48961070832884],[-3.134513992482447,51.48961069598555],[-3.134513992043069,51.48961069598558],[-3.1345069449208904,51.489485277076355],[-3.1345069444815135,51.4894852770764],[-3.1344963920825855,51.48935995259138],[-3.133059343409227,51.48941495765938],[-3.133068575135944,51.48952463788535],[-3.133074737420193,51.489634364179764],[-3.1330778311216694,51.48974415025781],[-3.133077855335161,51.48985397637049],[-3.13307481002083,51.48996376214893],[-3.1330686951553592,51.49007350210695],[-3.133059512031005,51.49018317896331],[-3.1330472689537143,51.490292700278665],[-3.131611917857042,51.4902222958501],[-3.1315987922066824,51.49031607986782],[-3.1315830516827976,51.490409677826634],[-3.1315646931969963,51.490503106732135],[-3.1315437268299586,51.49059631638609],[-3.1315437263908277,51.490596317757614],[-3.1315201595903748,51.490689275242545],[-3.1314939984884003,51.49078195861273],[-3.131465244386696,51.49087436210613],[-3.131433917030876,51.49096642180834],[-3.1314339161525964,51.490966424551374],[-3.131400017284376,51.491058134974324],[-3.1313635525980477,51.49114947910901],[-3.1313245528229374,51.49124038151937],[-3.131283006086561,51.49133087073052],[-3.131238944437628,51.49142087377473],[-3.1311923590783626,51.491510410673406],[-3.131143297434188,51.49159939117677],[-3.1297860212754314,51.49129944859065],[-3.1297860203968466,51.49129944996218],[-3.1298269164916346,51.491225283326585],[-3.129826915612803,51.491225283052344],[-3.129865723517352,51.49115070041615],[-3.1299024476329027,51.49107568971208],[-3.129902448950626,51.49107568669475],[-3.1299024546609804,51.49107567517396],[-3.1299370686415604,51.491000290990534],[-3.1299695764501574,51.490924525923354],[-3.129969577767865,51.49092452290601],[-3.1299695825994065,51.49092451138528],[-3.129999960966176,51.49084841892526],[-3.1299999622838905,51.49084841590793],[-3.1299999671152476,51.49084840329001],[-3.1300282134151196,51.490771991667856],[-3.1300282147327425,51.490771988101926],[-3.130028218685557,51.49077197712983],[-3.1300543245837638,51.490695269114184],[-3.1300543250228974,51.490695267468375],[-3.1300543298540147,51.49069525347897],[-3.130078286576924,51.49061827403274],[-3.1300782878944537,51.49061826991822],[-3.130078291407728,51.490618258123256],[-3.130100092817649,51.49054102836896],[-3.130100095013351,51.490541020414234],[-3.130100096769832,51.490541013556715],[-3.1301197358509514,51.49046355790835],[-3.130119736289912,51.49046355516535],[-3.1301197398029514,51.490463541998906],[-3.130137209978872,51.49038588404744],[-3.1301372117350006,51.490385874995546],[-3.1301372130522593,51.490385869235254],[-3.1301525103830774,51.490308032845675],[-3.1301656339998414,51.49023001088719],[-3.130165633121072,51.49023001088724],[-3.130176569866646,51.49015188866756],[-3.1301765711828136,51.49015187604984],[-3.13017657162181,51.49015187358115],[-3.1301853219456306,51.490073644243445],[-3.130185321945331,51.490073642323374],[-3.1301853237006174,51.49007362805984],[-3.1301918854206985,51.489995315468526],[-3.130191886297305,51.48999530175366],[-3.1301918862970894,51.48999530038217],[-3.1301962581101734,51.48991692785292],[-3.1301962589864307,51.48991691194365],[-3.1301984391500466,51.48983850361487],[-3.1301984272375165,51.489760068538466],[-3.1301984267956313,51.4897600526293],[-3.130196222387541,51.48968164593893],[-3.1301962219469965,51.48968163853296],[-3.1301962215062358,51.48968162975549],[-3.130191825054279,51.48960325803412],[-3.1301918250540637,51.489603256662626],[-3.1301918241731497,51.48960324294786],[-3.130191823733772,51.489603242947894],[-3.130185237449985,51.48952493088181],[-3.13018523788936,51.48952493088178],[-3.1301764617862124,51.48944668642522],[-3.1301764600270285,51.48944667572776],[-3.1301764595869623,51.489446671339046],[-3.1301654993963273,51.489368550447665],[-3.1301654980772975,51.48936854468752],[-3.1301654967575785,51.48936853453862],[-3.1301523516107004,51.48929053008015],[-3.130152351171327,51.48929053008017],[-3.1301370303144886,51.48921269554114],[-3.130137029434972,51.48921269060384],[-3.1301370272365148,51.48921268045502],[-3.130119532878957,51.48913502488621],[-3.1301195333183296,51.489135024886195],[-3.1301195298012927,51.48913501172016],[-3.1301195293614934,51.48913500897723],[-3.130099862833521,51.48905754088082],[-3.130099862394147,51.48905754088083],[-3.1300780333785623,51.488980297833756],[-3.1300780329391893,51.488980297833784],[-3.130054053315873,51.48890332015572],[-3.1300540506785017,51.488903312749876],[-3.1300540484804995,51.488903305344],[-3.130027920018579,51.48882660071385],[-3.1300279156231006,51.48882658919365],[-3.130027914304354,51.48882658507929],[-3.1299996462446416,51.48875017763315],[-3.1299996440470346,51.488750172695944],[-3.12999964009107,51.48875016199862],[-3.129969239476992,51.48867407367826],[-3.1299692399163175,51.48867407340394],[-3.129936711152892,51.48859831298496],[-3.129936704559993,51.48859829735045],[-3.129902068754708,51.488522917494784],[-3.1299020691940354,51.48852291722046],[-3.129902062601454,51.488522903506016],[-3.129902062162,51.48852290295745],[-3.1298653254767976,51.488447911891775],[-3.1298653259161284,51.488447911617456],[-3.1298653193237267,51.4884478990002],[-3.129865318005217,51.48844789625731],[-3.1298264909978535,51.48837331784284],[-3.12982648836104,51.48837331372855],[-3.1298264826475988,51.48837330248273],[-3.12978557631449,51.488299157563326],[-3.129785571480203,51.4882991490604],[-3.1297855679644284,51.48829914330038],[-3.1297425862700097,51.48822544010256],[-3.128394087703745,51.48854028298485],[-3.1284284761160954,51.48859925432988],[-3.128461207799888,51.48865858534415],[-3.128461208239325,51.48865858589273],[-3.128492269125961,51.48871825079438],[-3.128521664483246,51.48877825973346],[-3.12854937672606,51.48883857650491],[-3.128575398816722,51.48889918766971],[-3.128599721079747,51.48896006799416],[-3.1286223373558286,51.489021203490466],[-3.1286432419246917,51.48908257825071],[-3.1272324251823336,51.4892618339076],[-3.1272167506367574,51.489215810810876],[-3.127199788772866,51.489169956450155],[-3.1271997878939213,51.489169954255814],[-3.1271997852570195,51.489169947124196],[-3.127181547944522,51.48912429359118],[-3.127181544428832,51.489124285911004],[-3.1271815439893564,51.48912428481384],[-3.1271620329897525,51.48907883677092],[-3.127162032989699,51.489078836222326],[-3.12716202903454,51.48907882744497],[-3.127141250503843,51.48903359888043],[-3.127141247427613,51.48903359202313],[-3.1271412465486947,51.489033590103084],[-3.12711920708221,51.488988595005125],[-3.127095908441221,51.488943838036036],[-3.1270959036073234,51.488943828984425],[-3.1270713620546964,51.488899341412704],[-3.1270713594180553,51.488899336749746],[-3.127071357220857,51.488899332909675],[-3.12704557012318,51.48885511034588],[-3.1256970344074917,51.489169922185226],[-3.1256790262719365,51.489140638154524],[-3.125679024953702,51.48914063623448],[-3.1256790227566134,51.489140632394374],[-3.125660198300239,51.48911154916432],[-3.1256601987395998,51.489111548890016],[-3.125640556645429,51.489082663442986],[-3.1256405562060783,51.48908266371729],[-3.1256201180064886,51.48905400787079],[-3.1255988731569864,51.48902556818411],[-3.1255768453865844,51.488997375377515],[-3.1255768431895414,51.488997372086004],[-3.1255768409925597,51.48899736989169],[-3.125554023711321,51.488969415735966],[-3.1255304331781795,51.48894171997971],[-3.125530429223568,51.48894171504245],[-3.125530428784177,51.48894171476817],[-3.1255060623637485,51.48891427439365],[-3.1255060623637556,51.48891427466794],[-3.125480938511713,51.48888710997226],[-3.1254809367541276,51.48888710805222],[-3.125480933238964,51.48888710448645],[-3.1254550537137926,51.48886021738915],[-3.1254550528350027,51.48886021656629],[-3.1254550484410695,51.48886021217762],[-3.1254284211527517,51.488833611181256],[-3.127856832423291,51.487867672623814],[-3.1278020859875317,51.48781504943602],[-3.1278020842299172,51.48781504779032],[-3.1278020750024482,51.48781503928749],[-3.1277458771101228,51.487763031379615],[-3.1277458749130993,51.48776302918533],[-3.127745865685643,51.487763020682515],[-3.1277458652462857,51.48776302068253],[-3.1276882229304284,51.48771163381245],[-3.127688222930399,51.48771163353815],[-3.1276882163394415,51.48771162805248],[-3.127688211066613,51.487711623115345],[-3.1276291401480707,51.487660870995164],[-3.1276291401480534,51.487660870720866],[-3.1275686485383054,51.48761076075411],[-3.127568648538273,51.487610760479825],[-3.127568637992805,51.48761075197704],[-3.127568635795819,51.487610750057044],[-3.127506763921304,51.48756131597849],[-3.127506764360665,51.48756131597846],[-3.1275067538152816,51.48756130802427],[-3.127506752497067,51.487561306652836],[-3.1274435082685192,51.48751255422023],[-3.127443508268492,51.487512553945926],[-3.1274434964049758,51.48751254516888],[-3.1274434950867995,51.487512544071755],[-3.1273788855360247,51.48746447876856],[-3.1262841826853824,51.48804824917819],[-3.1262347351312085,51.48801274012005],[-3.12623472502537,51.488012732988615],[-3.1261842824296493,51.48797776128339],[-3.126184281990278,51.4879777612834],[-3.1261328799434915,51.487943351066974],[-3.126080513612734,51.48790949959525],[-3.1271073257921094,51.487279481578575],[-3.127036238078481,51.48723510532633],[-3.125018129493359,51.48851731967881],[-3.124981984853325,51.488495530452745],[-3.1249819795807676,51.488495527161284],[-3.1249819773838805,51.48849552606414],[-3.124945229983457,51.488474134018226],[-3.124945225589688,51.488474131549616],[-3.1249452225140306,51.488474129629616],[-3.1249078820194587,51.488453141071965],[-3.1249078771863057,51.48845313832908],[-3.1249078749894212,51.48845313695762],[-3.124869945794269,51.48843255408199],[-3.1248699457942823,51.48843255435628],[-3.1248314551396676,51.48841239197367],[-3.124831453382164,51.48841239115081],[-3.1248314472309078,51.48841238785934],[-3.1247923990708846,51.48839264816352],[-3.1247923916015248,51.48839264459778],[-3.124792391162138,51.488392644049185],[-3.124752797359482,51.488373333073945],[-3.124752797359467,51.488373332799654],[-3.1247126535200094,51.48835444835013],[-3.1247126530806315,51.488354448350144],[-3.124672003141252,51.488336010997415],[-3.1246719969900405,51.488336008528826],[-3.124671995671924,51.48833600770596],[-3.1246308308446022,51.48831801388375],[-3.1246308361170603,51.48831801607804],[-3.126261660150284,51.48683650980517],[-3.126178334273517,51.48680142406999],[-3.1261783347128502,51.48680142379569],[-3.126178323289417,51.48680141940725],[-3.1261783171383084,51.48680141666445],[-3.1260940235615746,51.486767244028805],[-3.1260940235615835,51.48676724430311],[-3.1260088049000885,51.48673400177026],[-3.1260088053394437,51.48673400177025],[-3.126008790401151,51.4867339962847],[-3.1260087873256133,51.4867339949133],[-3.125922651045324,51.486701685498296],[-3.1259226448942874,51.48670168330408],[-3.1259226352283567,51.486701679738474],[-3.125835608566256,51.48667031331333],[-3.125835601097157,51.48667031084485],[-3.1258355905525224,51.48667030700496],[-3.1257477025027915,51.486639894538904],[-3.1257476981092154,51.48663989316752],[-3.1257476844891015,51.486639888504804],[-3.1256589600913345,51.486610438224254],[-3.125658960091321,51.486610437949956],[-3.125658943835097,51.486610432738686],[-3.1256589416383167,51.48661043219013],[-3.1255693892363365,51.48658194711028],[-3.1255693887970026,51.486581947384586],[-3.125479070335898,51.48655444725159],[-3.125479065502993,51.4865544458802],[-3.1254790514436106,51.48655444176605],[-3.1253879800996063,51.48652793069234],[-3.125387973509283,51.486527928772404],[-3.1253879616466853,51.4865279252068],[-3.1252961628977647,51.48650241059612],[-3.1252961628977576,51.48650241032182],[-3.1252961444448966,51.48650240565914],[-3.1252961440055316,51.486502405384854],[-3.1252036464048767,51.48647789464101],[-3.1252036464048616,51.48647789436671],[-3.125110456098437,51.48645438940804],[-3.1251104394030347,51.48645438529389],[-3.125016625803489,51.48643190422109],[-3.12501661701645,51.48643190230117],[-3.1250166064719873,51.48643189955839],[-3.1249221809970664,51.4864104448385],[-3.125402705120669,51.485563175856555],[-3.125283919269114,51.48553764203257],[-3.125283905649471,51.48553763928985],[-3.12528389510523,51.48553763709569],[-3.1251644381385746,51.48551340662143],[-3.1251644337451476,51.48551340579862],[-3.125164413535371,51.485513401684535],[-3.1251644135353858,51.48551340195883],[-3.1250442946706314,51.48549047592932],[-3.1250442951099617,51.485490475655006],[-3.124923507308377,51.48546885379405],[-3.124538816277276,51.48633498573066],[-3.1246354349262413,51.48635228129473],[-3.1247315616195745,51.486370628165396],[-3.1248271313394116,51.48639001345299],[-3.124827132218109,51.48639001345296],[-3.1249221616656,51.48641044045008],[-3.124441624563087,51.48725770816285],[-3.1243703654788995,51.48724239064956],[-3.124370350980082,51.48724238763247],[-3.1242986596402047,51.48722784579139],[-3.1242265861281298,51.48721408977019],[-3.1242265738261272,51.48721408757594],[-3.1242265729474177,51.487214087575964],[-3.12415412560757,51.48720111874533],[-3.1240813141023547,51.48718893902461],[-3.1240813114662194,51.48718893875034],[-3.124081299164236,51.48718893655607],[-3.1240081726981024,51.48717755444733],[-3.1240081612748445,51.48717755280165],[-3.1240081577599934,51.4871775522531],[-3.123934709739002,51.48716696638431],[-3.123860976626065,51.48715718251485],[-3.1237869948839765,51.487148205032696],[-3.1237869874149347,51.48714820420985],[-3.123786979506541,51.487148203387015],[-3.123712744737983,51.487140031743124],[-3.1237127447379884,51.487140032017415],[-3.123638307904341,51.48713267197127],[-3.1238510917158155,51.48624372821176],[-3.1237515652661965,51.486234996109665],[-3.1237515652661916,51.486234995835375],[-3.12365180689562,51.486227349316195],[-3.1238147662176403,51.485334310775734],[-3.123689809867364,51.48532611202657],[-3.123689826122843,51.48532611284935],[-3.123827793782886,51.484431434551276],[-3.1236775855536876,51.484423230477425],[-3.1235646501657874,51.48531927585117],[-3.1236898002019404,51.48532611120374],[-3.1235518324135545,51.4862207894765],[-3.1236517893217774,51.48622734794482],[-3.123488828026295,51.48712038639634],[-3.1235636514275487,51.48712612160246],[-3.1236382925269237,51.48713267059986],[-3.1234255057120985,51.48802161411205],[-3.1234751515645147,51.488026522732596],[-3.1235246322333206,51.488031969502686],[-3.1235739644160057,51.48803795579397],[-3.123286941145941,51.48891872796341],[-3.12326227964929,51.488915735446184],[-3.123237533797961,51.488913011460234],[-3.1232375329192195,51.488913011460234],[-3.123237528525501,51.48891301091165],[-3.123212715454565,51.48891055737696],[-3.123187832527362,51.488908374293494],[-3.1231878294517603,51.4889083740192],[-3.123187827254904,51.4889083737449],[-3.123162891606485,51.488906462484096],[-3.123137901478932,51.48890482277157],[-3.123112869613573,51.488903455430226],[-3.1231128643411155,51.48890345515593],[-3.1230878030399047,51.488902361282875],[-3.1230627101055357,51.48890154005523],[-3.1230375969612156,51.488900992570144],[-3.123012468000207,51.4889007188276],[-3.122987340357538,51.4889007188276],[-3.1229622219414397,51.48890099257014],[-3.1229371087971196,51.48890154005523],[-3.122937105282149,51.488901540329536],[-3.122937104403406,51.48890154032952],[-3.1229120158627515,51.48890236100859],[-3.1228869492890827,51.48890345515593],[-3.122861912151267,51.488904822771566],[-3.1228369272961722,51.4889064622098],[-3.122811986375298,51.488908373744906],[-3.122787098175635,51.488910557376954],[-3.1227622851046974,51.48891301091165],[-3.1227622807109805,51.48891301146024],[-3.122762279832238,51.488913011460234],[-3.122737539253369,51.4889157348976],[-3.122712868090543,51.48891872851199],[-3.1226882940237584,51.48892198956056],[-3.122663805189562,51.4889255188662],[-3.1226394239955177,51.488929313960384],[-3.1226151574711793,51.48893337319741],[-3.122591003419307,51.488937696851664],[-3.122566972823808,51.48894228327744],[-3.122566970626945,51.488942283826034],[-3.1225669688694584,51.48894228410032],[-3.1225430700780348,51.48894713192626],[-3.1225193162715197,51.48895223786096],[-3.122519311438412,51.48895223895811],[-3.122495704373926,51.488957603001644],[-3.119470877934815,51.483906176615776],[-3.119636129508067,51.483868628600746],[-3.119802427589516,51.483832881962286],[-3.119969709372331,51.483798950957734],[-3.1201378830548534,51.48376685340999],[-3.1203069332790268,51.48373659205785],[-3.1204768503982683,51.48370816936601],[-3.120647465730734,51.48368161303135],[-3.12064746748803,51.483681612757074],[-3.120818862328346,51.48365691043469],[-3.1209909031417666,51.483634081593976],[-3.1211635104310655,51.48361313637985],[-3.121336731224288,51.48359406875598],[-3.121510452636328,51.48357689161018],[-3.1216846087899732,51.483561611796894],[-3.121859162364232,51.48354823178256],[-3.122034085263985,51.48353675458239],[-3.122209261090978,51.48352718705141],[-3.1223847236946356,51.48351952726859],[-3.1225603729318836,51.48351378044391],[-3.122736128868547,51.483509948770745],[-3.122911963410241,51.483508032797175],[-3.12308786120288,51.48350803279717],[-3.123263694426617,51.483509949045015],[-3.1234394411375686,51.48351378016962],[-3.1234394406982515,51.48351378044391],[-3.123615089935499,51.483519527268584],[-3.123790552539152,51.48352718677711],[-3.123790552978472,51.483527186777096],[-3.1239657560433214,51.48353675595363],[-3.1241037129045393,51.48264207733074],[-3.124303605548892,51.48265519324964],[-3.136505999660156,51.415676193711256]],[[-3.130203952752984,51.49277580769445],[-3.130119654717096,51.49285384027377],[-3.128932964354688,51.49234481366014],[-3.1290032029530668,51.49227979718667],[-3.129003214815485,51.49227978593991],[-3.1290032161335106,51.49227978456836],[-3.129071626954106,51.49221401273454],[-3.1302860476068113,51.49269687741845],[-3.130203952752984,51.49277580769445]],[[-3.1297430510375497,51.491373169050036],[-3.129698042669619,51.49144638462949],[-3.1296980391553086,51.49144639038993],[-3.1296509759555664,51.49151912577472],[-3.1296509763949913,51.49151912604899],[-3.129601902285207,51.491591314580205],[-3.1295508080324006,51.491662971342144],[-3.128240585146455,51.491290306251685],[-3.1282814540515664,51.49123299237885],[-3.128281455369521,51.49123299045871],[-3.1282814623986734,51.49123298058372],[-3.1283207220928877,51.49117523091209],[-3.1283207278039473,51.491175221860054],[-3.128320730000554,51.49117521884269],[-3.128358369505896,51.49111704928356],[-3.1283583699453312,51.49111704955784],[-3.1283943919027726,51.49105845544961],[-3.128428756340616,51.490999501529544],[-3.1297860133684527,51.49129946285451],[-3.1297430510375497,51.491373169050036]],[[-3.127579247494871,51.49326715021018],[-3.127481616031034,51.49331650839057],[-3.12738259966048,51.49336480528863],[-3.127282265173565,51.49341200743424],[-3.1271806020279906,51.49345812031042],[-3.1270776923943706,51.49350310660654],[-3.1262620825866807,51.49276239656504],[-3.1263444211299642,51.49272640327535],[-3.126344420690535,51.492726403001065],[-3.1264257237933393,51.492689525626474],[-3.126425724232768,51.492689525900765],[-3.1265059989231467,51.49265176087738],[-3.126506004635237,51.49265175813426],[-3.1265060156200155,51.492651752922285],[-3.126585205653794,51.49261312686066],[-3.126585206093227,51.49261312713494],[-3.1266633215747173,51.49257363564818],[-3.126663328604931,51.492573632082106],[-3.126663336513925,51.49257362796741],[-3.1267403198815584,51.492533299586306],[-3.127675493170836,51.4932167307509],[-3.127579247494871,51.49326715021018]],[[-3.12731340462681,51.49218170577075],[-3.1273134041873734,51.492181705496456],[-3.127246149571722,51.49222833888051],[-3.1261845467956157,51.49162114369728],[-3.126133126475859,51.491655569004514],[-3.12613312427897,51.49165557037606],[-3.126080757379829,51.49168942487464],[-3.1271077637448337,51.492319381672765],[-3.1270367045909193,51.492363745266466],[-3.1269644021553966,51.492407336440266],[-3.1269644017159552,51.49240733616599],[-3.1268908762104077,51.49245014147643],[-3.1268161948610826,51.492492122517554],[-3.12681619442166,51.49249212224328],[-3.1267403352600858,51.49253329108263],[-3.1258051864220358,51.491849854576586],[-3.1257474260857787,51.49188011248],[-3.1256888400024216,51.491909730440284],[-3.125629434763677,51.491938705438834],[-3.125569240688331,51.49196702321031],[-3.125508251186671,51.49199468677094],[-3.1254464992141573,51.49202168103248],[-3.1246309418360183,51.4912809597349],[-3.124672110651466,51.49126296339095],[-3.124712760933244,51.49124452514855],[-3.1247127613726535,51.49124452542285],[-3.1247529067412025,51.49122563952212],[-3.124792509408824,51.49120632324481],[-3.1248315588298508,51.49118658207758],[-3.1248315623449145,51.491186580157446],[-3.1248315662993775,51.491186578237304],[-3.1248700655491186,51.491166410534866],[-3.124907987385478,51.491145830561585],[-3.124907988703614,51.49114582973868],[-3.1249079944156053,51.49114582672133],[-3.124945342792775,51.49112483255767],[-3.124982090029459,51.491103439016605],[-3.1249820904688534,51.49110343929089],[-3.1250182493070264,51.49108164006396],[-3.125053778884163,51.49105945874193],[-3.125088696775503,51.491036885176065],[-3.125088696336098,51.491036884901774],[-3.125122971785142,51.49101393856822],[-3.125156592928826,51.49099062714807],[-3.1251565968832127,51.49099062440503],[-3.1251565995194692,51.490990622484915],[-3.125189570751749,51.49096694323566],[-3.12522186746782,51.490942913987595],[-3.125253494940499,51.490918530626715],[-3.125284435155806,51.490893807143024],[-3.1253146802054625,51.490868749846044],[-3.1253442195450347,51.4908433672397],[-3.125373044387645,51.490817666730706],[-3.125373050538815,51.490817661244655],[-3.12540115253708,51.49079165051401],[-3.125428523343665,51.49076533724268],[-3.125455154171978,51.490738729934584],[-3.125481032281244,51.49071184175668],[-3.1255061598691185,51.490684670240775],[-3.1255305233162183,51.49065722965105],[-3.1255541160331055,51.49062952739412],[-3.1255541177905375,51.49062952547401],[-3.125554120866038,51.49062952163379],[-3.1255769309910337,51.49060157224808],[-3.1255769327484564,51.490601569779386],[-3.1255769353846032,51.49060156676207],[-3.125598965554946,51.49057336723072],[-3.125620199076147,51.490544937578186],[-3.125620202151615,51.49054493346368],[-3.1256202030303166,51.49054493209219],[-3.1256406390249687,51.490516275610474],[-3.125640642100401,51.49051627094735],[-3.1256406429791066,51.490516269850154],[-3.125660278372858,51.49048738955701],[-3.125679099547143,51.49045830520247],[-3.1256971082606615,51.49042901459254],[-3.125714295727882,51.49039953199119],[-3.1257306557993485,51.4903698669993],[-3.127096056505354,51.49065502671313],[-3.1270715193235197,51.49069952064332],[-3.127045742553273,51.49074373976579],[-3.127018725752017,51.49078768325685],[-3.1269904882471407,51.49083132066805],[-3.1269610423369913,51.4908746325231],[-3.1269303774747286,51.49091763473064],[-3.1268985208964417,51.490960288064414],[-3.1268654800684454,51.49100258374571],[-3.1268312606996815,51.49104451436739],[-3.1267958689385518,51.49108607169929],[-3.1267593298257905,51.49112722776134],[-3.126721632375313,51.4911679929761],[-3.1267216319359403,51.49116799325042],[-3.126682813490828,51.49120832784263],[-3.1266428617472455,51.491248245252066],[-3.1266018140488723,51.491287707623556],[-3.126559652819634,51.49132673223714],[-3.1265164246304087,51.49136527547712],[-3.126472114541522,51.49140335188048],[-3.1264267480348225,51.491440937855764],[-3.126380330381621,51.49147802956144],[-3.12633288926123,51.4915146050518],[-3.1262844338996314,51.49155065719361],[-3.1273793324808774,51.49213435593519],[-3.12731340462681,51.49218170577075]],[[-3.123815380506196,51.489058758786676],[-3.1237945527656477,51.489049988847334],[-3.123794548371877,51.4890499869273],[-3.1237734745944814,51.48904144328049],[-3.1237521692794648,51.489033132234816],[-3.1237306262753664,51.48902505132152],[-3.123708868868879,51.48901720959209],[-3.123708867550753,51.48901720904351],[-3.1237088640357547,51.48901720794635],[-3.1236868913478784,51.48900960430351],[-3.1236647051358837,51.48900223984432],[-3.1236647033783873,51.48900223929574],[-3.1236647003027675,51.489002238472885],[-3.123642315505127,51.48899511813446],[-3.123642311550758,51.48899511676299],[-3.123619730803459,51.488988241368126],[-3.1236197281672218,51.488988240819545],[-3.123619725970349,51.48898823999668],[-3.123596952788099,51.4889816106424],[-3.1235740021093226,51.48897523144298],[-3.123550871736844,51.48896910212404],[-3.1235508682218605,51.48896910130116],[-3.1235508669037415,51.48896910102687],[-3.123527573094064,51.488963225702655],[-3.123504114528748,51.4889576040988],[-3.1234805021917866,51.48895223895811],[-3.123480497358682,51.48895223786096],[-3.1234567435521603,51.48894713165196],[-3.1239135628134775,51.48809476237694],[-3.123961079753454,51.48810497625226],[-3.124008303231091,51.48811570633693],[-3.1240552161124966,51.488126948517014],[-3.1241018096116857,51.48813870059863],[-3.1241480670340196,51.48815095819354],[-3.1241939857445966,51.48816372130217],[-3.124193986183962,51.48816372130217],[-3.1242395275196375,51.48817697867917],[-3.124284701147669,51.48819073306783],[-3.124329470601614,51.48820497349713],[-3.1243738451092695,51.48821970298469],[-3.1244178000669813,51.48823491302804],[-3.1244613284458262,51.48825060170766],[-3.1245043977332987,51.48826675695541],[-3.1245044008089033,51.48826675832685],[-3.1245470224294927,51.48828338453183],[-3.124589170021745,51.48830047154586],[-3.1246308277689874,51.488318012512295],[-3.123815380506196,51.489058758786676]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1231464567122256,51.48980029768287],[-3.122999906539917,51.48979949951172]],[[-3.1229999305416225,51.489799503960434],[-3.1229999270265814,51.48979950341185],[-3.1229999388898397,51.489799505606214],[-3.123011993717521,51.489801878818696],[-3.122999906539917,51.48979949951172],[-3.1229999169208416,51.48979950149177],[-3.122999906539917,51.48979949951172],[-3.1229999208752637,51.48979950231466],[-3.12299992570844,51.489799503137554],[-3.122999924390299,51.48979950286326],[-3.1229999199964986,51.48979950204036],[-3.1230850147300266,51.48981423419881],[-3.1229999305416225,51.489799503960434]],[[-3.122999920435883,51.48979950286326],[-3.122999906539917,51.48979949951172],[-3.123075026306517,51.48981610627907],[-3.122999920435883,51.48979950286326]],[[-3.1229999191177393,51.48979950615481],[-3.122999906539917,51.48979949951172],[-3.123063133628365,51.48983203742523],[-3.1229999191177393,51.48979950615481]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230603334095375,51.48979520133038],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229999147239456,51.48979949490866],[-3.1229999173602216,51.48979949353717],[-3.122999906539917,51.48979949951172],[-3.122999913845187,51.489799495731546],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999917799598,51.489799493811475],[-3.1230596413531124,51.48976983686138],[-3.122999906539917,51.48979949951172]],[[-3.1229999186783646,51.48979949737732],[-3.122999906539917,51.48979949951172],[-3.1230555586620694,51.489789864346236],[-3.1229999186783646,51.48979949737732]],[[-3.122999917360222,51.489799493811475],[-3.123004784371165,51.489796989210255],[-3.122999917799598,51.489799493811475],[-3.1229999151633288,51.48979949490866],[-3.122999914723944,51.48979949518295],[-3.122999906539917,51.48979949951172],[-3.122999919117746,51.48979949271428],[-3.1230399110185996,51.489778169722406],[-3.122999917360222,51.489799493811475]],[[-3.122999919557122,51.489799499023114],[-3.122999906539917,51.48979949951172],[-3.1230332201591526,51.489798227379914],[-3.122999919557122,51.489799499023114]],[[-3.1229999191177393,51.48979950258895],[-3.122999920435883,51.48979950286326],[-3.12302874683752,51.48980623107792],[-3.1229999191177393,51.48979950258895]],[[-3.122999912966419,51.48979949381147],[-3.1229999125270416,51.489799494085766],[-3.122999906539917,51.48979949951172],[-3.122999914723948,51.48979949161709],[-3.123025929954184,51.489773998774126],[-3.122999912966419,51.48979949381147]],[[-3.122999925269059,51.489799489148446],[-3.1229999147239456,51.48979949490866],[-3.1230189420661705,51.4897886105487],[-3.122999925269059,51.489799489148446]],[[-3.122999919117746,51.48979949271428],[-3.1229999173602216,51.48979949353717],[-3.122999925269059,51.489799489148446],[-3.1230188080555146,51.48978905984636],[-3.122999919117746,51.48979949271428]],[[-3.122999934496037,51.489799480370955],[-3.1229999287841097,51.48979948421108],[-3.1230172820887616,51.489787239066594],[-3.122999934496037,51.489799480370955]],[[-3.1229999322991424,51.48979948201672],[-3.122999934496037,51.489799480370955],[-3.123015093978063,51.4897891525591],[-3.1229999322991424,51.48979948201672]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230147284123317,51.48978379116025],[-3.122999906539917,51.48979949951172]],[[-3.122999912527045,51.48979948750264],[-3.1230111949183534,51.489775709289304],[-3.1229999107695283,51.4897994913428],[-3.122999910330144,51.489799492165695],[-3.1230142020302316,51.489767319931254],[-3.122999912527045,51.48979948750264]],[[-3.122999914723948,51.48979949161709],[-3.122999906539917,51.48979949951172],[-3.1230141914906273,51.489784947319954],[-3.122999914723948,51.48979949161709]],[[-3.122999906539917,51.48979949951172],[-3.12299991736022,51.4897994913428],[-3.123013656327324,51.48978908672812],[-3.122999906539917,51.48979949951172]],[[-3.122999915163316,51.489799501766065],[-3.122999906539917,51.48979949951172],[-3.122999916481459,51.48979950204036],[-3.1229999191177393,51.48979950258895],[-3.123013353598675,51.48980280648923],[-3.122999915163316,51.489799501766065]],[[-3.122999916042079,51.48979949353718],[-3.122999906539917,51.48979949951172],[-3.1230112089826116,51.489792319586634],[-3.122999916042079,51.48979949353718]],[[-3.122999919117742,51.48979949765162],[-3.1229999169208424,51.489799497925915],[-3.123011113638571,51.4897979481503],[-3.122999919117742,51.48979949765162]],[[-3.12299991736022,51.4897994913428],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230100428683536,51.48979154442491],[-3.12299991736022,51.4897994913428]],[[-3.1229999147239456,51.48979949463437],[-3.1229999164814606,51.48979949353718],[-3.123009739257355,51.489793674337065],[-3.1229999147239456,51.48979949463437]],[[-3.122999909451387,51.489799493811475],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.123009342493486,51.489774964300246],[-3.122999909451387,51.489799493811475]],[[-3.1229999388898397,51.489799505606214],[-3.1229999305416225,51.489799503960434],[-3.1230089518901454,51.489801172231246],[-3.1229999388898397,51.489799505606214]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230082168055695,51.48979033011456],[-3.122999906539917,51.48979949951172]],[[-3.1229999191177433,51.48979949106851],[-3.1229999160420836,51.48979949298858],[-3.122999906539917,51.48979949951172],[-3.122999913845183,51.48979949463437],[-3.1229999160420836,51.48979949298858],[-3.122999915602706,51.48979949353717],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.123007379348247,51.48979403750576],[-3.1229999191177433,51.48979949106851]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230057523243318,51.48979149176027],[-3.122999906539917,51.48979949951172]],[[-3.1229999090120057,51.48979949216569],[-3.123002218831768,51.48979171202047],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999908133246,51.48979949381147],[-3.1229999081332434,51.48979949298858],[-3.1230003114839806,51.48979758086785],[-3.122999908572625,51.48979949216568],[-3.1230049891200995,51.48977827012162],[-3.1229999090120057,51.48979949216569]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.123003926261847,51.48979241339651],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1230027522390125,51.48979386579637],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999907254485,51.48979949353718],[-3.1230006032321023,51.48978954644983],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.123000507886813,51.489799582683524],[-3.122999906539917,51.48979949951172]],[[-3.1229999257084455,51.48979948640547],[-3.1229999287841097,51.48979948421108],[-3.1229999322991424,51.48979948201672],[-3.1229999257084455,51.48979948640547]],[[-3.1229999235115447,51.48979948805124],[-3.1229999226327743,51.48979948859984],[-3.122999924390304,51.48979948722835],[-3.1229999235115447,51.48979948805124]],[[-3.1229999208752695,51.489799489971325],[-3.122999915602706,51.48979949353717],[-3.1229999191177433,51.48979949106851],[-3.1229999217540234,51.489799489148425],[-3.1229999226327743,51.48979948859984],[-3.1229999208752695,51.489799489971325]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229999169208424,51.489799497925915],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.1229999098907673,51.48979949326287],[-3.1229999098907624,51.48979949298858],[-3.122999910330144,51.489799492165695],[-3.1229999098907673,51.48979949326287]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.1229999098907624,51.48979949298858],[-3.122999909451387,51.489799493811475],[-3.1229999098907637,51.48979949271428],[-3.1229999098907624,51.48979949298858]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.12295844910747,51.48981796053995],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229918622075026,51.4898047915733],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999905057586,51.48979950780058],[-3.1229949725762536,51.48982289788369],[-3.122999906539917,51.48979949951172],[-3.122999905057586,51.48979950780058]],[[-3.122992426804906,51.48984048330472],[-3.122999905057586,51.48979950780058],[-3.122999906539917,51.48979949951172],[-3.122992426804906,51.48984048330472]],[[-3.1229602132032297,51.489835554190634],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229602132032297,51.489835554190634]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229998958306058,51.48979949682873],[-3.1229998927549514,51.489799496005844],[-3.1229998905580514,51.489799495457255],[-3.1229998874823868,51.48979949463437],[-3.1229998852854894,51.489799494085766],[-3.1229998822098275,51.48979949326288],[-3.1229998734222297,51.48979949106851],[-3.122999874740373,51.4897994913428],[-3.1229998694678134,51.489799489971325],[-3.122999862877108,51.48979948832553],[-3.122928545397545,51.489780129007244],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.1229965600584517,51.48979845779364],[-3.122999896269991,51.489799496280135],[-3.1229577219631346,51.48978579022631],[-3.122999906539917,51.48979949951172],[-3.1229965600584517,51.48979845779364]],[[-3.122999906539917,51.48979949951172],[-3.1229867724272853,51.48981460123763],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.1229869174239875,51.48981006739124],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122924419134795,51.48980908703206],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122962453614494,51.489821687407485],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122960609101872,51.48981573709347],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.1229986585367784,51.489800444797346],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.1229599482803065,51.4898088259193],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229599482803065,51.4898088259193]],[[-3.122999906539917,51.48979949951172],[-3.122816220712529,51.48975432883289],[-3.122999868149681,51.489799489697035],[-3.122999878694792,51.48979949243998],[-3.1229998800129355,51.48979949271428],[-3.122999883967356,51.489799493811475],[-3.1229998870430027,51.48979949463437],[-3.1229998892399093,51.48979949518296],[-3.1229998923155637,51.489799496005844],[-3.122999894512467,51.48979949655443],[-3.122999897588123,51.48979949737732],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.122999906539917,51.48979949951172],[-3.1229946922546548,51.48979726213524],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172]],[[-3.1229598230826365,51.48977959496686],[-3.1229998971487465,51.48979949463437],[-3.122999897588128,51.48979949490867],[-3.122999906539917,51.48979949951172],[-3.1229598230826365,51.48977959496686]],[[-3.122999894512468,51.489799499845994],[-3.1229370293515255,51.489801213359215],[-3.122999906539917,51.48979949951172],[-3.122999894512468,51.489799499845994]],[[-3.122999897588128,51.48979949490867],[-3.122999898466888,51.48979949518296],[-3.122999898906269,51.489799495457255],[-3.122999897588128,51.48979949490867]],[[-3.1229998949518483,51.48979949518296],[-3.122999895830607,51.489799495457255],[-3.122999906539917,51.48979949951172],[-3.1229998949518483,51.48979949518296]],[[-3.1229998971487465,51.48979949463437],[-3.122999896269986,51.489799494085766],[-3.122999898466888,51.48979949518296],[-3.1229998971487465,51.48979949463437]],[[-3.1229998923155713,51.48979949353718],[-3.1229946175600687,51.48979731397728],[-3.1229998984668796,51.489799496005844],[-3.1229998923155713,51.48979949353718]],[[-3.122999895830607,51.489799495457255],[-3.122999892754947,51.489799494360064],[-3.1229998883611505,51.489799492714276],[-3.1229911565649506,51.489796152057195],[-3.1229998918761854,51.48979949381147],[-3.12292401628936,51.489769317060215],[-3.1229998923155713,51.48979949353718],[-3.122999898466892,51.489799496280135],[-3.122999895830607,51.489799495457255]],[[-3.122999894512467,51.48979949655443],[-3.1229998936337084,51.489799496280135],[-3.1229998958306058,51.48979949682873],[-3.1229998967093673,51.48979949710302],[-3.122999894512467,51.48979949655443]],[[-3.122999889679291,51.48979949079421],[-3.122957393315392,51.48977683197761],[-3.122999896269986,51.489799494085766],[-3.122999889679291,51.48979949079421]],[[-3.1229998949518483,51.489799500120284],[-3.122986492107007,51.489800305728274],[-3.122999891436809,51.48979950012029],[-3.122969523693721,51.489800992014885],[-3.122999894512468,51.489799499845994],[-3.122999896269987,51.489799499845994],[-3.1229998949518483,51.489799500120284]],[[-3.1229427180373666,51.489774033598735],[-3.1229998826492067,51.489799488599836],[-3.1229998953912244,51.489799494360064],[-3.1229427180373666,51.489774033598735]],[[-3.1229998826492067,51.489799488599836],[-3.1229805648761126,51.48979056491103],[-3.12299988660363,51.48979949024562],[-3.1229998826492067,51.489799488599836]],[[-3.122999883967356,51.489799493811475],[-3.1229998830885903,51.48979949353718],[-3.1229998852854894,51.489799494085766],[-3.122999883967356,51.489799493811475]],[[-3.1229745440531396,51.489792941140244],[-3.122999862877108,51.48979948832553],[-3.122999868149681,51.489799489697035],[-3.1229745440531396,51.489792941140244]],[[-3.121452686373269,51.49131559243724],[-3.121410545521726,51.49129850787088],[-3.121368877066869,51.491280961655065],[-3.1213277034181552,51.491262963390966],[-3.1212870443486365,51.49124452158259],[-3.1212469152373408,51.491225643362405],[-3.121207304221415,51.49120632297052],[-3.1211682486490004,51.49118657878595],[-3.121168247330861,51.49118657796302],[-3.121129751596187,51.491166411906406],[-3.1210918227297033,51.491145828367166],[-3.121054478746342,51.49112483667224],[-3.1210544765494324,51.49112483557501],[-3.1210177156918992,51.491103434627725],[-3.120981571792691,51.49108164417854],[-3.121990753457291,51.49044057597751],[-3.1220088291244155,51.490451473380766],[-3.1220272066627555,51.49046217219308],[-3.1220458772846733,51.49047266692833],[-3.1220458794815755,51.49047266802554],[-3.122045880799718,51.49047266884844],[-3.122064841429472,51.49048295868357],[-3.1220840911882575,51.49049304224697],[-3.122084090748872,51.49049304224695],[-3.122103619530827,51.49050291460103],[-3.1221234211845093,51.49051257272836],[-3.122123420745122,51.490512572728356],[-3.122143493073502,51.4905220155316],[-3.1221638185011527,51.49053123450732],[-3.12216381937992,51.49053123478161],[-3.122163822455605,51.49053123615311],[-3.1221844066943514,51.49054023404416],[-3.1222052391988413,51.49054900646156],[-3.122226309423702,51.490557548467834],[-3.121452686373269,51.49131559243724]],[[-3.1219730101640106,51.48916950845512],[-3.1219555544619317,51.48918079258485],[-3.121938419929355,51.48919226323649],[-3.1219216061269153,51.48920392068448],[-3.1219216048087763,51.48920392150736],[-3.1219216026118612,51.48920392315311],[-3.121905120084774,51.489215759717375],[-3.121888967954327,51.489227776495234],[-3.1218731510537894,51.489239969921],[-3.121857683443522,51.4892523290231],[-3.121857683004135,51.48925232929739],[-3.121857680367835,51.48925233149174],[-3.121842557654108,51.48926485956182],[-3.1218277908216407,51.48927754782263],[-3.1218133776736705,51.48929039764578],[-3.1218133745979673,51.48929040038872],[-3.1217993256798695,51.48930340299694],[-3.1217993230435583,51.48930340546558],[-3.1217856396736496,51.48931655921324],[-3.1145005760571114,51.486418652253626],[-3.114596385658473,51.48632656543335],[-3.1146947393688773,51.48623555148772],[-3.1147956486051895,51.48614559834212],[-3.114899048325804,51.48605676605653],[-3.1150049086441967,51.48596907903473],[-3.1151132168114173,51.48588254796685],[-3.1152238998811392,51.48579723126648],[-3.1153369802582844,51.48571311109917],[-3.115452381483746,51.485630245604],[-3.1155700684034913,51.48554865808716],[-3.1156900339847753,51.48546835457588],[-3.1158122356054063,51.4853893641361],[-3.115936600766586,51.48531173311263],[-3.1219907782479623,51.489158416333005],[-3.1219730101640106,51.48916950845512]],[[-3.1197153700644016,51.49155064978736],[-3.119666923929624,51.4915146047775],[-3.1196194744612016,51.491478022703795],[-3.119619474021803,51.49147802270378],[-3.119573073064684,51.49144094389052],[-3.119527699528096,51.49140335188051],[-3.1194833938328297,51.49136527986603],[-3.119440160371244,51.49132673168855],[-3.120626769242604,51.490817666182124],[-3.120655588812775,51.490843362027974],[-3.120655588373388,51.490843362027974],[-3.1206555892521415,51.49084336257658],[-3.120655594085193,51.49084336723972],[-3.1206555945245937,51.49084336696543],[-3.120685127712951,51.490868744634305],[-3.1206851277129313,51.49086874490861],[-3.1207153723232053,51.49089380193129],[-3.1207153723232057,51.49089380220558],[-3.1207153762775652,51.49089380522292],[-3.1207153780350483,51.49089380686873],[-3.120715378474435,51.49089380686875],[-3.1207463186897066,51.49091853090102],[-3.12074631912912,51.490918530626736],[-3.1207779400111932,51.49094290850156],[-3.1207779395717856,51.49094290877584],[-3.120777943965552,51.4909429117932],[-3.1207779461624288,51.490942913439014],[-3.120810243757253,51.49096694323569],[-3.1197153700644016,51.49155064978736]],[[-3.118142571125239,51.491731124190444],[-3.1180893116411696,51.491677909296946],[-3.1180893107624583,51.491677908474024],[-3.1180375546424175,51.49162412856891],[-3.11798730100422,51.4915697836541],[-3.1179385762050194,51.491514901985205],[-3.117891387270695,51.4914594895989],[-3.117845763632683,51.491403582979785],[-3.117801710558746,51.491347188164404],[-3.117759236831034,51.49129031694963],[-3.119069436594917,51.49091763445639],[-3.1191012861436906,51.490960279012434],[-3.1191012857042977,51.49096027901242],[-3.1191012887796794,51.49096028312696],[-3.1191012922944092,51.490960287790124],[-3.119101292733831,51.49096028751583],[-3.1191343361978507,51.49100258703738],[-3.1191343366372486,51.4910025870374],[-3.119168557763373,51.49104452012779],[-3.119168558202784,51.4910445198535],[-3.1192039394194913,51.49108606539032],[-3.119203938980099,51.4910860653903],[-3.1192039420555497,51.491086068956264],[-3.1192039464490597,51.49108607389373],[-3.119203946449078,51.49108607361944],[-3.119240484243863,51.49112722721279],[-3.1192404838044583,51.49112722748707],[-3.119240485561882,51.491127229132914],[-3.1192404912734744,51.491127235441894],[-3.119278174225299,51.491167984747015],[-3.1192781737858946,51.49116798474701],[-3.1192781816943067,51.49116799297614],[-3.1192781816943334,51.49116799270185],[-3.119316997942642,51.4912083253739],[-3.119316997503242,51.49120832537388],[-3.1193170040936087,51.49120833195722],[-3.119317005411685,51.49120833332873],[-3.11931700585108,51.49120833332874],[-3.119356943535171,51.49124823674863],[-3.118142571125239,51.491731124190444]],[[-3.1150185519347433,51.49186298742551],[-3.114962096941936,51.4917757323604],[-3.114908069951257,51.4916878429868],[-3.1148565232242027,51.49159940352063],[-3.114807444448996,51.49151039256918],[-3.1147608731456264,51.491420882278234],[-3.114716809300704,51.49133087374795],[-3.114675268713137,51.49124039934923],[-3.116062744988755,51.49100029044197],[-3.1160973589694128,51.491075674076804],[-3.1160973585300145,51.49107567407678],[-3.1161340822061954,51.49115068450653],[-3.1161340844024177,51.491150689443984],[-3.116134089673609,51.49115069959326],[-3.1161340901130457,51.49115069931899],[-3.1161729050454667,51.49122529813909],[-3.116172905484858,51.49122529813911],[-3.116213792354967,51.49129944749348],[-3.1162137919155257,51.491299447767766],[-3.116213798065538,51.49129945791709],[-3.1162138007012152,51.49129946258027],[-3.116256754685591,51.4913731553348],[-3.1162567542461566,51.49137315560907],[-3.1162567603962747,51.4913731652098],[-3.1162567630319202,51.49137317014729],[-3.1162567634713523,51.49137316987301],[-3.1163017714001255,51.491446383806654],[-3.1163017705213347,51.49144638380661],[-3.1163488275708,51.491519110413584],[-3.1150185519347433,51.49186298742551]]],[[[-3.135996080090974,51.49366826085528],[-3.1346963637190908,51.4932814495082],[-3.134597229114068,51.49340837982029],[-3.1358859338184195,51.49380929558869],[-3.135996080090974,51.49366826085528]]],[[[-3.135933440380829,51.48930495899101],[-3.1359176252552445,51.48916411990224],[-3.1359176239344086,51.48916411030202],[-3.1359176221719522,51.48916409274723],[-3.135917621732579,51.48916409274728],[-3.135897875262651,51.48902347626555],[-3.135897875702024,51.4890234762655],[-3.1358978739412042,51.48902346447095],[-3.135897871300173,51.48902344746486],[-3.1358978708608,51.48902344746491],[-3.1358741922000712,51.4888830404221],[-3.1344437418365634,51.488984939008105],[-3.134464788750039,51.48910976627815],[-3.134482339281743,51.48923477409691],[-3.134496395164699,51.48935997837495],[-3.135933440380829,51.48930495899101]]],[[[-3.132499719300091,51.487698910843086],[-3.132439528115322,51.4875957077756],[-3.1310910667002667,51.48791058169932],[-3.1311426564971323,51.48799904206189],[-3.132499719300091,51.487698910843086]]],[[[-3.130555431559462,51.481110426945264],[-3.130311410540802,51.48102943184502],[-3.1303114105407146,51.481029431296434],[-3.1303113679268946,51.481029417858544],[-3.130311360019134,51.48102941511606],[-3.130065113053107,51.48095109101842],[-3.1300651126138903,51.480951091567036],[-3.129816707762464,51.480875460397975],[-3.1291971085436914,51.481686753571395],[-3.1289694492320907,51.48162048291661],[-3.128969446156877,51.48162048209388],[-3.1289694026643957,51.481620469478436],[-3.128969402225132,51.48162046975275],[-3.1287399256208337,51.48155668935967],[-3.1287399260601,51.481556689085345],[-3.1287398970652887,51.48155668140645],[-3.128739878614044,51.48155667647002],[-3.1285086549775336,51.48149540607413],[-3.12850865541677,51.481495405525514],[-3.1282757005322255,51.481436650053276],[-3.128275700971493,51.481436649778956],[-3.128275679445249,51.48143664484259],[-3.128275659676165,51.48143663963184],[-3.128275659236899,51.48143663990616],[-3.128041146600562,51.481380442953],[-3.1280411470398337,51.48138044267868],[-3.1280411158488146,51.4813804355483],[-3.1280410982764066,51.48138043143461],[-3.1280410982764346,51.4813804317089],[-3.1278050581669987,51.481326800121714],[-3.128285475006454,51.4804795185912],[-3.1280241723494777,51.480423351052046],[-3.1280241723494164,51.48042335050345],[-3.1280241345696482,51.48042334282476],[-3.128024118754856,51.480423339533864],[-3.1277612861143007,51.480370027453475],[-3.1273285144427954,51.48122726070847],[-3.127567474734965,51.4812757308748],[-3.1278050089644474,51.481326789426156],[-3.1273245791520514,51.48217406941379],[-3.127537084025414,51.482222353536486],[-3.127748171062363,51.48227293703575],[-3.1272206631522446,51.483109231672906],[-3.1274070306362622,51.48315623709263],[-3.127592060548807,51.48320526740133],[-3.1277757041445646,51.483256309166784],[-3.1279578621544375,51.483309335244236],[-3.1281385420655403,51.48336434728606],[-3.12813854206552,51.48336434701175],[-3.1283176147318583,51.4834213058061],[-3.1284951043337674,51.48348021903945],[-3.1286709019320766,51.48354105024274],[-3.1288449974374055,51.48360379640677],[-3.1290172797111198,51.48366841749743],[-3.1291877470093232,51.48373491242553],[-3.12935632861034,51.483803253773125],[-3.129522990257044,51.48387342810961],[-3.130338256952738,51.483132643144266],[-3.130150782828679,51.48305370607438],[-3.1301507678910343,51.483053700040756],[-3.1301507441664227,51.48305368989323],[-3.130150744166476,51.48305369016752],[-3.1299611311051168,51.48297682331606],[-3.129961128469061,51.48297682221902],[-3.129961092443078,51.48297680768342],[-3.129961092003842,51.48297680823206],[-3.1297693606390484,51.482902018993514],[-3.130521396584345,51.48213560733866],[-3.130305985666253,51.482054810365064],[-3.1303059852269937,51.48205481063938],[-3.1300884329516965,51.48197640307257],[-3.1300884333909558,51.48197640279826],[-3.1300884065919288,51.48197639347378],[-3.130088388579415,51.48197638689175],[-3.130088388140148,51.48197638716607],[-3.1298686843799044,51.48190036350881],[-3.130555431559462,51.481110426945264]]],[[[-3.124566884181321,51.377450850228385],[-3.121432925064509,51.37745085022832],[-3.1214454305165575,51.378349648049436],[-3.1214456181140076,51.37834964805194],[-3.1183382312304793,51.37838350929214],[-3.118338231230758,51.37838350654913],[-3.1183379669279643,51.378383512298946],[-3.118337591732371,51.37838351639852],[-3.118337591731953,51.37838352051305],[-3.115231163186857,51.378451242507005],[-3.115293663437633,51.37934922288266],[-3.1183751008681875,51.379282045759616],[-3.1184501222325474,51.381079091686445],[-3.121483133913565,51.38104604094955],[-3.1245168598720787,51.381046040947204],[-3.1245418727872476,51.37924844573061],[-3.121458570708031,51.37924844573892],[-3.1214460700134707,51.37834964805792],[-3.1245543787291967,51.3783496480495],[-3.124566884181321,51.377450850228385]]],[[[-3.1229999090120057,51.48979949216569],[-3.1229999085726248,51.48979949326288],[-3.1229999085726248,51.48979949353718],[-3.1229999090120057,51.48979949216569]]],[[[-3.1229999085726248,51.48979949353718],[-3.122999906539917,51.48979949951172],[-3.122999906539917,51.48979949951172],[-3.1229999085726248,51.48979949353718]]],[[[-3.116839290983609,51.34244236994229],[-3.116764405790065,51.34064530667811],[-3.1126090974183955,51.34073589527748],[-3.112609096980628,51.34073589445452],[-3.1126090098273513,51.34073589746412],[-3.1126083568365934,51.34073591166991],[-3.112608357710885,51.34073591880188],[-3.108457037685233,51.34087174077069],[-3.1084570372481473,51.34087173802759],[-3.1084567775377603,51.34087174951605],[-3.108456183665931,51.34087176891777],[-3.108456184539753,51.340871775501164],[-3.1043085117042395,51.341052839707835],[-3.104532988331071,51.34284500835394],[-3.1086314266530644,51.342666093346736],[-3.112733806772836,51.34253187246631],[-3.116839290983609,51.34244236994229]]],[[[-3.1166303945380345,51.49344271476944],[-3.1165294941225734,51.49337275024851],[-3.1164305807597583,51.49330170776674],[-3.115335595206418,51.493885373199774],[-3.1154509914507447,51.49396825519001],[-3.1154509910113237,51.49396825518998],[-3.115450994526281,51.49396825765887],[-3.115451013858447,51.49396827164923],[-3.1154510142979155,51.49396827137496],[-3.115568710656234,51.49404988340444],[-3.1166303945380345,51.49344271476944]]],[[[-3.1053551045490937,51.49369858663],[-3.1052487965060394,51.49350571066602],[-3.105147918302578,51.49331174454928],[-3.10377457455407,51.49358180453987],[-3.1038832286352624,51.493790734314004],[-3.1038832299536305,51.49379073403992],[-3.1039976872169173,51.49399840644899],[-3.1053551045490937,51.49369858663]]],[[[-3.105118491674686,51.49560852278276],[-3.104958820414999,51.49541279648961],[-3.104804678802269,51.495215401189114],[-3.1048046792417034,51.49521540118918],[-3.1046560505317524,51.49501631468237],[-3.104513013723915,51.49481564123504],[-3.1043756328781997,51.494613472766915],[-3.1042439355993174,51.49440985181807],[-3.1041179099676053,51.49420475865622],[-3.1027690567992057,51.49451930382468],[-3.102904051398208,51.494739003768935],[-3.1029040500796845,51.4947390043173],[-3.1030451678863242,51.49495719980179],[-3.103045167446786,51.494957200076016],[-3.103045181499427,51.494957220924924],[-3.103045196429974,51.49495724396833],[-3.1030451968695174,51.49495724369412],[-3.1031923659383964,51.49517382551483],[-3.1018716978917698,51.49553199490301],[-3.1020351425058488,51.49576131775506],[-3.102035141626853,51.4957613180292],[-3.1020351622679483,51.495761345188214],[-3.102035175003199,51.495761363568334],[-3.1020351758822,51.495761363294186],[-3.102204974641157,51.49598882483896],[-3.1022049733227117,51.49598882511303],[-3.102381155725856,51.496214463181275],[-3.1023811425497856,51.496214447269764],[-3.099803390064194,51.4970160604949],[-3.100008680949127,51.497267742109315],[-3.102563632692078,51.496438160330115],[-3.1023811794425815,51.49621449226083],[-3.103670019358573,51.49581366134566],[-3.103841073558715,51.49602334852719],[-3.105118491674686,51.49560852278276]]],[[[-3.1018717290703486,51.49553204099038],[-3.101714703520345,51.495300943821185],[-3.1015641716073774,51.49506818209251],[-3.100224274273443,51.49539734454334],[-3.100384195868432,51.4956446365172],[-3.1003841949894224,51.495644636791326],[-3.1003842121150744,51.49564466175559],[-3.1003842279225653,51.495644686445296],[-3.1003842288015653,51.49564468617116],[-3.100551008705418,51.49589014939899],[-3.0992302992586573,51.496248288728246],[-3.09941418064866,51.496506306884385],[-3.0994141617657123,51.49650628137105],[-3.098103639352412,51.49687874118067],[-3.0983053375098093,51.4971489655201],[-3.0983052962300563,51.497148912572264],[-3.097005359869073,51.49753557962024],[-3.097225548025879,51.49781761668412],[-3.0972255471468038,51.49781761695823],[-3.097225565591479,51.497817639180255],[-3.097225591939711,51.497817673198774],[-3.097225593258235,51.49781767292476],[-3.0974536364459055,51.49809726811669],[-3.098731170072801,51.49768251208467],[-3.0985144968173572,51.49741686639775],[-3.098305338388112,51.49714896661748],[-3.0996052505561806,51.49676228239375],[-3.0994141999710467,51.49650633239781],[-3.1007246975090967,51.496133855452705],[-3.100551043397343,51.49589019768177],[-3.1018717290703486,51.49553204099038]]],[[[-3.0992303339475904,51.496248340577246],[-3.099053679181225,51.49598833248055],[-3.097723142921537,51.49633201278251],[-3.097909605555997,51.496606468031565],[-3.0992303339475904,51.496248340577246]]],[[[-2.998405762765002,51.35730142591618],[-2.9962263216373186,51.354975691600806],[-2.9924854473504925,51.35637747054931],[-2.992485446476628,51.35637746972543],[-2.992485380688125,51.35637749543655],[-2.9924847925656923,51.35637771586889],[-2.992484799119267,51.356377722185165],[-2.9887841013262832,51.357819750570414],[-2.988014974494483,51.357060791788754],[-2.98433315974879,51.35855167581666],[-2.9835430462736587,51.357801199123145],[-2.979882335344959,51.35934069710121],[-2.979882334033142,51.359340696276696],[-2.979882256378175,51.359340730195306],[-2.9798815812091686,51.35934101409612],[-2.9798815895105335,51.359341021512456],[-2.976264845830476,51.36091984626152],[-2.9762648418968256,51.36091984323925],[-2.9762645580051785,51.360919971805686],[-2.9762641012574886,51.36092017119986],[-2.976264106936698,51.36092017641873],[-2.97269093871103,51.36253850128812],[-2.973542611401222,51.3632621264409],[-2.9770955047048404,51.361652971160126],[-2.9787583741638395,51.363118537997146],[-2.9823142886827188,51.36156623158994],[-2.983125232642125,51.36230794926993],[-2.9867028682743717,51.36080334508645],[-2.987493080248173,51.361553790202734],[-2.9910914198877556,51.36009666874917],[-2.994729198231848,51.35867913104544],[-2.998405762765002,51.35730142591618]]],[[[-2.9802135271109926,51.38873555324984],[-2.9783139617715815,51.387386848767946],[-2.975476758407945,51.38897882847854],[-2.974508365622331,51.38831491917324],[-2.9716974369079288,51.389948221426906],[-2.9697239789689367,51.388641665330084],[-2.966922698003074,51.39032704526571],[-2.9669226830648703,51.390327054572055],[-2.9669221198477573,51.390327393406714],[-2.9669221294716372,51.39032739972848],[-2.964168643279438,51.39204269445261],[-2.963146123089714,51.39141130129567],[-2.960422124385307,51.39316829183022],[-2.962502116481393,51.39440858838457],[-2.9651906392759906,51.39267443035267],[-2.966213209215873,51.39330579729623],[-2.968931721857032,51.391612242981836],[-2.9699365510777302,51.39225464553304],[-2.972683623841987,51.390601815726626],[-2.973670423084305,51.39125506802562],[-2.976444620025213,51.38964306996296],[-2.9774130627572735,51.39030695460576],[-2.9802135271109926,51.38873555324984]]],[[[-2.967465428384443,51.367299668218855],[-2.9656825044864217,51.36589041164084],[-2.9622480433266047,51.36762363888164],[-2.964069958836051,51.36901325138252],[-2.967465428384443,51.367299668218855]]],[[[-2.966803722646043,51.3710972712724],[-2.9658926725466834,51.370402488055305],[-2.962583688018022,51.37213273967278],[-2.9635139614137733,51.372817489095745],[-2.9635142516314605,51.37281733725329],[-2.960273094335082,51.374572928963175],[-2.9621716056775536,51.37592192494399],[-2.965375259306948,51.37418660930063],[-2.963514642831559,51.372817132882346],[-2.966803722646043,51.3710972712724]]],[[[-2.9621236327986042,51.390779899974525],[-2.9611011710916304,51.390148489939236],[-2.9583427338906736,51.391927642791146],[-2.956262960218215,51.39068726036491],[-2.953519957056345,51.39251911841239],[-2.9535201377210423,51.39251899331804],[-2.9524631514142343,51.391910215412764],[-2.94975480407597,51.39378316191036],[-2.949754797511534,51.393783158609025],[-2.9497544734889662,51.39378339073738],[-2.9497542422546883,51.39378355058739],[-2.9497542470673643,51.39378355333752],[-2.9470988894770027,51.39568532962768],[-2.947098885537042,51.395685327975954],[-2.947098714482491,51.39568545472061],[-2.9470983389892096,51.395685723794955],[-2.947098346866001,51.395685727921304],[-2.9444962224928863,51.39761615115744],[-2.944496212426727,51.39761614620466],[-2.9444957475429328,51.39761650373373],[-2.944495688614825,51.39761654725783],[-2.9444956899271024,51.397616548082745],[-2.941947072343388,51.399575435138864],[-2.943069423105674,51.400136699435805],[-2.9456021956159195,51.3981899554861],[-2.946708726347308,51.398763351285154],[-2.949279027039614,51.39685646919574],[-2.9503694016555437,51.397441820403685],[-2.9529760109801075,51.39557486363031],[-2.955633647680802,51.393736897818386],[-2.9566907146754535,51.394345640348995],[-2.9593821670194025,51.39254812727497],[-2.9593821705191465,51.39254812947427],[-2.9621236327986042,51.390779899974525]],[[-2.9519024644020457,51.394977489621965],[-2.9519024578372894,51.39497748632075],[-2.951902148765031,51.394977707779084],[-2.951901909179794,51.39497787338143],[-2.9519019139927285,51.39497787613148],[-2.9492793836591473,51.396856204200986],[-2.9492795591093746,51.396856074168085],[-2.948189212347269,51.3962707078249],[-2.950828290772898,51.394380558450656],[-2.953519584738422,51.39251937599132],[-2.9545766021807567,51.3931281418406],[-2.9519024644020457,51.394977489621965]]],[[[-2.9433897383646865,51.39704272611517],[-2.942283291532038,51.39646929552284],[-2.9397024523562947,51.39845287468824],[-2.940824748613966,51.39901416031405],[-2.9433897383646865,51.39704272611517]]],[[[-2.930725549792471,51.39396183110638],[-2.928481485335142,51.39283905003917],[-2.925801337111175,51.39497334505306],[-2.925801571649367,51.39497315151672],[-2.923526594964637,51.39387494717171],[-2.9208755026353224,51.39606332664732],[-2.9231808235862693,51.39713657196473],[-2.9258010365654705,51.39497359361288],[-2.928076121799425,51.396071744820944],[-2.930725549792471,51.39396183110638]]]]} \ No newline at end of file +{"type":"MultiPolygon","coordinates":[[[[-3.1074798166986866,51.4917696154967],[-3.1074271305111805,51.49160022109984],[-3.1060113627696273,51.49176382050571],[-3.1060688331116597,51.491948615080155],[-3.1060688323780985,51.4919486151657],[-3.1061314608186006,51.492132755442455],[-3.107537230396692,51.491938410145],[-3.1074798160262596,51.49176961557513],[-3.1074798166986866,51.4917696154967]]],[[[-3.1089994702314514,51.491896904829],[-3.1089429884158366,51.49174404794686],[-3.10753723083233,51.491938410094555],[-3.107599355943079,51.49210655340204],[-3.1089994702314514,51.491896904829]]],[[[-3.1104542479217945,51.49182423529681],[-3.1103995716300576,51.491687239550195],[-3.108999470181035,51.491896904845476],[-3.109060217252437,51.4920491230595],[-3.1090602174612885,51.49204912299249],[-3.1091252113218504,51.49220065616192],[-3.110512746436559,51.49196061440089],[-3.1104542481097557,51.491824235236486],[-3.1104542479217945,51.49182423529681]]],[[[-3.107979931664541,51.492935716022984],[-3.1078945644727445,51.49277159287955],[-3.106521254158103,51.49304168664287],[-3.106614377204615,51.49322073115065],[-3.107979931664541,51.492935716022984]]],[[[-3.109427240344145,51.49279901868077],[-3.1093454697534986,51.492650685043515],[-3.10797993239081,51.4929357160891],[-3.1080698757556426,51.493098884125786],[-3.108069875470959,51.49309888379163],[-3.108164367643033,51.49326104701962],[-3.1081643680195854,51.493261047213345],[-3.1082633802722928,51.49342215621811],[-3.1096031610017447,51.493092900394565],[-3.10951314618913,51.492946438686374],[-3.109513145846811,51.492946438510266],[-3.1094272400853287,51.492799018377],[-3.109427240344145,51.49279901868077]]],[[[-3.097544439558189,51.496055651164674],[-3.0973734742494186,51.49577735642157],[-3.0960245289831967,51.496091825190874],[-3.0962044851149932,51.49638476907181],[-3.097544439558189,51.496055651164674]]],[[[-3.097453612760197,51.49809724046619],[-3.0972255694204542,51.49781764520754],[-3.095936615176876,51.498218403513285],[-3.096176054575588,51.49851198113336],[-3.097453612760197,51.49809724046619]]],[[[-3.09905369610311,51.49598835909296],[-3.0988843736642386,51.49572651818876],[-3.0975444384633684,51.49605565143578],[-3.097723160944509,51.49633204107506],[-3.096392605694636,51.49667570760986],[-3.0965888359949854,51.49696455222908],[-3.097909587347105,51.49660644108334],[-3.0981036588300075,51.496878768405956],[-3.098103658888377,51.496878768570596],[-3.098305317536937,51.49714893993851],[-3.0983053164717296,51.497148939885406],[-3.0985145009577693,51.49741687297538],[-3.0998034100839793,51.49701608602257],[-3.1000086595594754,51.497267717300595],[-3.100008660437226,51.49726771765254],[-3.1002209167113195,51.497517074335114],[-3.1027522954756344,51.4966597850023],[-3.1025636143789543,51.496438138675906],[-3.1025636135987273,51.49643813836308],[-3.102381160315484,51.49621447007589],[-3.103670001441368,51.495813641027155],[-3.103504837521388,51.49560212213521],[-3.1035048383623187,51.49560212217709],[-3.1033456150891054,51.49538883602164],[-3.103345615043008,51.49538883589167],[-3.103192380856811,51.495173847456186],[-3.1031923799379584,51.4951738474347],[-3.1030451814444637,51.49495722222063],[-3.1030451815040014,51.49495722247112],[-3.1029040634631744,51.494739026497825],[-3.101564186164534,51.49506820571939],[-3.1017147063831896,51.495300949790575],[-3.1017147063196835,51.49530094952339],[-3.1018717125495083,51.49553201817859],[-3.1018717135296345,51.49553201820153],[-3.1020351580333836,51.49576134101791],[-3.100724679713444,51.496133831626636],[-3.1009051219468566,51.49637555991978],[-3.0996052307411284,51.49676225714486],[-3.0994141799819848,51.49650630743145],[-3.1007246796612096,51.49613383147933],[-3.1005510255021007,51.49589017405478],[-3.09923031567186,51.49624831498969],[-3.0990536960316843,51.49598835879237],[-3.09905369610311,51.49598835909296]]],[[[-3.106332466627341,51.49837405570434],[-3.1060952841185188,51.49819115481347],[-3.104968088557466,51.49875051143494],[-3.1052210815851335,51.498945608113516],[-3.106332466627341,51.49837405570434]]],[[[-3.1181425759948733,51.49173112974229],[-3.118089315718107,51.491677913960636],[-3.116861604949692,51.49214748535352],[-3.11692817921221,51.492214005768204],[-3.116928179289846,51.49221400582961],[-3.116996603354091,51.49227979076988],[-3.1169966029912555,51.49227979066343],[-3.117066856014544,51.492344820092164],[-3.117066856167307,51.49234482018728],[-3.1171389167597816,51.49240907428702],[-3.117138916793093,51.49240907418597],[-3.1172127630027417,51.49247253338232],[-3.1172127628318957,51.49247253324781],[-3.117288372167042,51.492535178209394],[-3.11728837223905,51.49253517849683],[-3.1173657216832793,51.492596990135375],[-3.117365722126372,51.49259698998085],[-3.117444788108588,51.49265794946048],[-3.1174447878661935,51.492657949345435],[-3.1175255463055467,51.492718038101394],[-3.11752554611766,51.49271803824319],[-3.1176079724235795,51.4927772379678],[-3.1165295016075802,51.493372755834095],[-3.116630384174691,51.49344270792971],[-3.116630384053118,51.4934427079037],[-3.1167332073016514,51.493511550207835],[-3.1188222201455877,51.49227423744116],[-3.1187536710368344,51.49222834379295],[-3.118753671117883,51.49222834381029],[-3.11868641565928,51.492181710297345],[-3.118686415450071,51.492181710228294],[-3.118620474129955,51.49213435105474],[-3.1186204742802635,51.492134350941306],[-3.118555867185251,51.49208628053931],[-3.118555867379165,51.492086280631355],[-3.118492614182152,51.492037513646345],[-3.118492613827682,51.49203751376996],[-3.1184307337938275,51.491988065053],[-3.1184307337362136,51.49198806482307],[-3.1183702457229865,51.49193794944214],[-3.118370245859665,51.49193794954974],[-3.118311168280854,51.49188718277476],[-3.118311168254209,51.49188718285561],[-3.118253519103912,51.491835780150964],[-3.118253518981696,51.49183578007485],[-3.1181973158223464,51.49178375709935],[-3.1181973161126098,51.491783757184514],[-3.118142576056986,51.49173112979142],[-3.1181425759948733,51.49173112974229]]],[[[-3.1158801666154567,51.492853848059084],[-3.115795864098734,51.492775811893395],[-3.114595099144387,51.4932718207888],[-3.114693450783988,51.49336286397518],[-3.114693450997864,51.49336286410838],[-3.1147943334597636,51.493452821860984],[-3.1147943335064046,51.49345282171952],[-3.1148977160606717,51.49354166663175],[-3.114897715821481,51.49354166644345],[-3.115003566982361,51.49362937144891],[-3.1150035670831624,51.493629371851306],[-3.115111854630006,51.49371591022389],[-3.1151118552503605,51.49371591000757],[-3.1152225461856884,51.493801255374514],[-3.1141113831440275,51.49437289227437],[-3.1142405945849667,51.49446903790063],[-3.1142405942843197,51.494469038127484],[-3.1143724747206454,51.4945637613237],[-3.114372475139079,51.49456376146181],[-3.1145069844002737,51.49465703335763],[-3.114506984238173,51.49465703332296],[-3.114644081349563,51.494748825504274],[-3.1156886584646104,51.494130192540055],[-3.1155686982500073,51.49404987544999],[-3.115568698391837,51.494049875480336],[-3.115451002425857,51.49396826363681],[-3.1165295012937526,51.49337275573051],[-3.1164305901398226,51.49330171515177],[-3.116430590365304,51.49330171498163],[-3.1163336807534687,51.493229607570306],[-3.116333681044343,51.49322960770836],[-3.1162388024826755,51.49315645543476],[-3.1162388019509537,51.49315645562019],[-3.1161459833357066,51.493082280763076],[-3.116145983249301,51.49308228041818],[-3.1160552528649217,51.49300710558174],[-3.1160552530699364,51.49300710574314],[-3.115966638535108,51.49293095383438],[-3.115966638495139,51.492930953955636],[-3.1158801667987817,51.49285384817325],[-3.1158801666154567,51.492853848059084]]],[[[-3.163433421122041,51.560961948827895],[-3.1614348960734957,51.5613916205167],[-3.1618931822489422,51.562243826466535],[-3.163915532451357,51.56180903160241],[-3.163433421122041,51.560961948827895]]],[[[-3.1644080544675472,51.55882715712456],[-3.1624692551910463,51.559267773861826],[-3.163433424182477,51.56096194564523],[-3.165419575002485,51.56051056557703],[-3.165419577314679,51.56051056828086],[-3.1673927466212675,51.560037617973805],[-3.167922058209482,51.560873678189],[-3.169905001130044,51.56037340788444],[-3.169905002505838,51.56037340811477],[-3.171873591310767,51.55985161000513],[-3.171873580484352,51.55985161129316],[-3.1738272132818155,51.55930844518636],[-3.173827229004745,51.55930844046279],[-3.175765308341872,51.55874407227836],[-3.174521937192113,51.55712212925272],[-3.1726295125353747,51.557673198664894],[-3.1732283444941927,51.55849082581701],[-3.1712977234386623,51.5590275921508],[-3.170721897777361,51.558203568808906],[-3.1687996858085237,51.55871307098308],[-3.168799684465154,51.55871307075816],[-3.1668634581642183,51.55920155229187],[-3.1668634563262876,51.55920155375411],[-3.164913807683304,51.559668865172966],[-3.1644080544675472,51.55882715712456]]],[[[-3.1776872306425124,51.55815867800066],[-3.175765297008212,51.55874407527785],[-3.176387015620622,51.559555041716685],[-3.1783315864398873,51.55896274700958],[-3.1776872306425124,51.55815867800066]]],[[[-3.2000320725823137,51.55709382724969],[-3.198136930631612,51.55792283776885],[-3.1989548702871153,51.55866303985847],[-3.2008706272790906,51.55782500494681],[-3.2008706163489915,51.55782500950612],[-3.2027625471188435,51.556966230503505],[-3.2036215064741214,51.557688151267165],[-3.2055091269796714,51.55679942230632],[-3.205509111491231,51.55679942655129],[-3.207371488217715,51.55589026782799],[-3.207371483424782,51.555890272615116],[-3.209208048136593,51.55496096215377],[-3.208289656798926,51.55426808542017],[-3.210080583652866,51.55332901900716],[-3.210080571904217,51.5533290211972],[-3.2118448623555844,51.55237058610739],[-3.211844880907391,51.55237058305678],[-3.2135819968563166,51.55139307211077],[-3.212606695334128,51.5507311513552],[-3.2108882626960025,51.55169813740343],[-3.2099316545399166,51.55102568685924],[-3.208205318140036,51.55196348280748],[-3.2063301879074824,51.55059791203773],[-3.2046163203676192,51.551496534736614],[-3.204616308502422,51.55149654158696],[-3.20287747872931,51.552376353885776],[-3.2019787653766665,51.55167354475407],[-3.2002353264674896,51.55252459349175],[-3.2002353409664077,51.55252458951838],[-3.1984682784315814,51.55335651324434],[-3.1976094835270037,51.55263455403849],[-3.1958396922148014,51.55343785178594],[-3.199193534081846,51.556362647930364],[-3.2010447504844333,51.555522363848155],[-3.201903635204229,51.55624430036359],[-3.200032061769829,51.55709383175989],[-3.2000320725823137,51.55709382724969]]],[[[-3.2162851058055364,51.55104797129179],[-3.214557309881515,51.55205498588715],[-3.2155326678432785,51.55271689029286],[-3.217278847728127,51.55169914824838],[-3.2162851058055364,51.55104797129179]]],[[[-3.2242358357785084,51.556257149251586],[-3.22236096634793,51.55734999201216],[-3.2233365508298166,51.55801183094975],[-3.225229804740711,51.55690825829071],[-3.2242358357785084,51.556257149251586]]],[[[-3.1579429671798778,51.50713955752087],[-3.1574528410750666,51.507517626914556],[-3.1641242375557415,51.51094576644429],[-3.164709203826071,51.51049448909462],[-3.1635814349479996,51.509935356377376],[-3.164138217042385,51.50949014687166],[-3.1641382144470818,51.50949015057204],[-3.1646824493169543,51.50903894272327],[-3.1623658315591108,51.507970475106866],[-3.1618518226505055,51.50839660584992],[-3.162995007388291,51.50894338020941],[-3.1624536872548985,51.50937621758705],[-3.1613259671705047,51.508817067901745],[-3.1618518251017482,51.50839660235516],[-3.1607086701821383,51.507849813309406],[-3.1601982746941486,51.50825790732196],[-3.1590706098251107,51.50769873584815],[-3.159565542628834,51.50730301307263],[-3.1595655403216774,51.50730301636176],[-3.1600493221711825,51.50690196154755],[-3.15773292114859,51.50583340204918],[-3.1572793674555144,51.50620938211142],[-3.158422442441195,51.506756201645295],[-3.157942972562721,51.50713955348082],[-3.1579429671798778,51.50713955752087]]],[[[-3.2222623617024455,51.538995559796255],[-3.2208715570586417,51.54006954010166],[-3.2242118900396948,51.54178184359421],[-3.2256500799585397,51.54067120943819],[-3.2245208285150713,51.540112658740725],[-3.225912196725894,51.538998913182446],[-3.2259121902459498,51.53899892243674],[-3.2272721092957934,51.53787018782606],[-3.226112322998077,51.537336580733715],[-3.2247675018763498,51.53845276075415],[-3.2224782136060037,51.537360394789765],[-3.221133192676807,51.53843697672792],[-3.2222623617024455,51.538995559796255]]],[[[-3.235391372895592,51.54160511508746],[-3.23392577613357,51.54282174007046],[-3.2362156187526856,51.54391387269061],[-3.2377114066426778,51.542672133523844],[-3.235391372895592,51.54160511508746]]],[[[-3.1602308871064495,51.50517233600477],[-3.1597954677589173,51.505575632747615],[-3.1621702474286235,51.506593049873096],[-3.1626337460860237,51.506163724622844],[-3.1626337493042804,51.50616372175765],[-3.1630851620607427,51.50572941200305],[-3.161870046716434,51.50524688932846],[-3.161432306681141,51.50566803370902],[-3.1602308871064495,51.50517233600477]]],[[[-3.1602272275387517,51.50347906333856],[-3.159839176712434,51.50388257838651],[-3.1610675434426367,51.50435181446096],[-3.161468522085111,51.50393484472445],[-3.1602272275387517,51.50347906333856]]],[[[-3.160969167894193,51.502659658026644],[-3.160603931587152,51.5030713816113],[-3.161857775256123,51.50351356949982],[-3.1622351779694577,51.50308811777484],[-3.160969167894193,51.502659658026644]]],[[[-3.1626006142846927,51.502658621397266],[-3.1622351733718803,51.50308812011762],[-3.163501207043306,51.50351656624603],[-3.163878427509444,51.50307320867114],[-3.1626006142846927,51.502658621397266]]],[[[-3.1651562639240014,51.503487781995645],[-3.164767264459215,51.50394499867857],[-3.166033345619664,51.50437341741478],[-3.1664341235283735,51.50390234137034],[-3.1651562639240014,51.503487781995645]]],[[[-3.1642431839693224,51.50262581070815],[-3.1638784262893456,51.50307321060264],[-3.1651562626658287,51.50348778398752],[-3.1655324094163575,51.50302639876393],[-3.1642431839693224,51.50262581070815]]],[[[-3.160694839083666,51.50101497319185],[-3.160375645885254,51.501423958645226],[-3.16166480360146,51.501824589196026],[-3.1619949943172365,51.50140149718117],[-3.160694839083666,51.50101497319185]]],[[[-3.1632951715475635,51.50178800673379],[-3.1629539839247207,51.50222520555103],[-3.16424318685497,51.50262580770977],[-3.1645953707744883,51.50217450184926],[-3.1632951715475635,51.50178800673379]]],[[[-3.1623132960872633,51.50097487464951],[-3.161994992626022,51.50140149967593],[-3.163295169800029,51.50178800931173],[-3.163624073511288,51.50134715982034],[-3.1623132960872633,51.50097487464951]]],[[[-3.1599777244071006,51.4998289039286],[-3.159691807805289,51.50023025706542],[-3.1610025425985286,51.500602571462146],[-3.1612986609027027,51.50018688098989],[-3.1599777244071006,51.4998289039286]]],[[[-3.3027583965096503,51.53840426256749],[-3.3013745399229766,51.5403553582081],[-3.30268758036507,51.54072608570904],[-3.3040815666823473,51.538760628261834],[-3.3027583965096503,51.53840426256749]]],[[[-3.158921653923412,51.49908095309156],[-3.1586568079570414,51.49947091411423],[-3.159977723731473,51.499828906152075],[-3.160252369181798,51.49942449904946],[-3.158921653923412,51.49908095309156]]],[[[-3.2687436844045465,51.53502740619075],[-3.26745830644661,51.536608418463196],[-3.26873802114608,51.53702186043527],[-3.2700347407411856,51.53542684282408],[-3.2700347510038976,51.535426832133105],[-3.27128654796439,51.533817929766954],[-3.27389061230031,51.534588515541195],[-3.2751182019026257,51.53293773168437],[-3.273805619863184,51.532566681834176],[-3.27497659748533,51.5309171319013],[-3.2749765947315597,51.53091714103612],[-3.276101154207301,51.52925508467467],[-3.274768699423533,51.52891285542557],[-3.2736538793300562,51.53056044662301],[-3.2723311846020953,51.530203737276594],[-3.2734362646198134,51.52857061102427],[-3.2707714549538993,51.52788607676672],[-3.269685857167902,51.52949027378549],[-3.268363227097439,51.52913351090415],[-3.2672429784144525,51.53071127894285],[-3.268555454184679,51.53108240174832],[-3.2673806003226837,51.532661966269075],[-3.2686825650455855,51.53304729575056],[-3.2674526607512404,51.53462794482122],[-3.2687436844045465,51.53502740619075]]],[[[-3.286761511718752,51.53199237313936],[-3.285559062157717,51.53377015869122],[-3.2868819636085886,51.53412671868557],[-3.2880941463077504,51.53233446600028],[-3.286761511718752,51.53199237313936]]],[[[-3.282339769851544,51.54590099451363],[-3.2807481338155227,51.547628476819185],[-3.2832355539894578,51.54853746697633],[-3.2848521906956183,51.54678274608946],[-3.287364725697227,51.547664428210744],[-3.288956103292128,51.54586485369198],[-3.2902244922394654,51.546291937864446],[-3.2917768559564324,51.544461415781065],[-3.293057006217807,51.54487459989944],[-3.2945691050706922,51.54301343398335],[-3.2958606254524834,51.5434125732925],[-3.297331213521907,51.5415210851405],[-3.2986336700307493,51.54190610210752],[-3.3000615088652516,51.53998463157946],[-3.3000615208180744,51.53998461599066],[-3.3014352470043695,51.53804788193058],[-3.301435243777387,51.538047892654774],[-3.3027544451713697,51.53609648706523],[-3.3014215908578386,51.53575456094602],[-3.3001121149634187,51.53769149699625],[-3.297465922495812,51.53697865036868],[-3.2961225915287082,51.53887230104344],[-3.293496733847252,51.53813069918134],[-3.292121569663448,51.53998092821119],[-3.2908192227833903,51.53959583925269],[-3.2894033093718695,51.54141667195474],[-3.2894032977624104,51.541416684054305],[-3.287936524240404,51.54322181134924],[-3.2853764272064745,51.54239532544009],[-3.2838826878996628,51.544156429195105],[-3.2838827067262075,51.54415641957781],[-3.2823397863644983,51.54590097946175],[-3.282339769851544,51.54590099451363]]],[[[-3.3054202137168445,51.53678029382088],[-3.3040815634081446,51.53876063914497],[-3.305404754224371,51.539116989975795],[-3.306753127948101,51.53712217445649],[-3.3054202137168445,51.53678029382088]]],[[[-3.308086062151248,51.53746403993008],[-3.306727965707469,51.53947332586323],[-3.3080511978571447,51.539829646806815],[-3.309419016325949,51.537805890241245],[-3.308086062151248,51.53746403993008]]],[[[-3.2744953937011005,51.5269257017438],[-3.2734362543216085,51.52857061892512],[-3.274768689034347,51.52891286339646],[-3.2758371605508048,51.52725337735963],[-3.2744953937011005,51.5269257017438]]],[[[-3.155416628486768,51.50476479661559],[-3.154993304046964,51.50511570310275],[-3.15613632206936,51.50566254820164],[-3.156574761272865,51.50529910507404],[-3.157732925248159,51.50583339803345],[-3.158175887678878,51.50545253368156],[-3.157002964424766,51.50493093869297],[-3.1574207979972657,51.50455816484097],[-3.1586081175895906,51.50506690609026],[-3.159029496723894,51.50467662317555],[-3.1590294996496944,51.50467662057093],[-3.15943989303071,51.50428180609995],[-3.159439890900021,51.504281807325285],[-3.1598391737910094,51.50388258173263],[-3.158610835214177,51.50341332941146],[-3.1589859577584645,51.50302326878198],[-3.160227226746991,51.503479066599915],[-3.160603927680639,51.50307138516284],[-3.1593501121881995,51.50262918028719],[-3.159703181563312,51.50223118458352],[-3.160969163444904,51.5026596602938],[-3.161322824249777,51.50224402017449],[-3.1600450562988858,51.50182940675366],[-3.1603756432699788,51.50142396136242],[-3.1590865082510438,51.50102331652254],[-3.158767312681765,51.50141477757407],[-3.1574895922545183,51.50100013444694],[-3.157797395839332,51.50062265748773],[-3.1577973982743446,51.50062265495798],[-3.1580945946073458,51.500241881904834],[-3.1593947042684083,51.50062843709465],[-3.159691805318418,51.5002302602957],[-3.158381094372129,51.49985792799869],[-3.1586568086085984,51.499470911970164],[-3.157335912879987,51.499112907179665],[-3.1575909586743056,51.4987373920171],[-3.157590956301749,51.498737393832656],[-3.1578354591986932,51.49835915712683],[-3.1605156606748745,51.4990171598204],[-3.1607675168860516,51.498607015449075],[-3.158069346385353,51.49797831328281],[-3.1582925438301332,51.49759498005404],[-3.1569349121104673,51.49729535045286],[-3.156720289708442,51.49766393763989],[-3.1567202910151617,51.49766393538941],[-3.156495391821024,51.49803012805037],[-3.1564953889909524,51.498030131086765],[-3.156260281153461,51.4983938175722],[-3.1549296282052337,51.49805022452014],[-3.154694184819083,51.49839684862207],[-3.153373352390994,51.498038795173485],[-3.153138454244315,51.49836846504042],[-3.1531384522012225,51.49836846769376],[-3.152894368325094,51.498695528022225],[-3.152894369621999,51.49869552610967],[-3.15264117434072,51.49901987725355],[-3.153930194248324,51.49942059521838],[-3.153656570112191,51.499756121384905],[-3.156211896008705,51.50058547580345],[-3.1559053611803622,51.5009456840538],[-3.1559053650364817,51.500945682089096],[-3.155588799610212,51.50130249570601],[-3.154335074034434,51.50086024360366],[-3.1540211256341824,51.501199961575864],[-3.1540211262943156,51.5011999588581],[-3.1536977215357433,51.50153620451466],[-3.1536977191009776,51.50153620730296],[-3.1533649562096504,51.501868878109306],[-3.154579893662038,51.50235148813904],[-3.1542241984355126,51.50269364614494],[-3.1542241958996904,51.50269364840218],[-3.153858981338637,51.50303187884142],[-3.1526717669440645,51.5025230896963],[-3.152311548632829,51.50284443208696],[-3.152311550592343,51.502844430230255],[-3.1519423960769966,51.50316179899892],[-3.1519423926604646,51.50316180234519],[-3.151564414156095,51.503475100676305],[-3.151564415958862,51.50347509810679],[-3.151177728688971,51.503784230539374],[-3.1511777243478085,51.50378423379724],[-3.1507824458697677,51.50408910601467],[-3.1518941088778565,51.50466055264433],[-3.152305195811301,51.50434348164609],[-3.1534326995656787,51.5049027150857],[-3.1538503153346187,51.50456884404013],[-3.153850313387715,51.504568846815246],[-3.1542585227897093,51.50423047667431],[-3.155416628486768,51.50476479661559]]],[[[-3.2620024210568817,51.52213855399508],[-3.261078796358144,51.523648088164215],[-3.26242037067523,51.52397591727075],[-3.2633529242062793,51.52245171682724],[-3.2633529187892503,51.52245172619413],[-3.264242628199245,51.52091759777856],[-3.261524608347312,51.520320778811424],[-3.26065193112046,51.52182538478699],[-3.2620024210568817,51.52213855399508]]],[[[-3.2815904847046893,51.53270037955508],[-3.280368794854748,51.53442171703847],[-3.282994214237358,51.53516362815575],[-3.2842361842974785,51.53341357406869],[-3.284236181377879,51.53341358375975],[-3.285428897106764,51.53165026512254],[-3.28676150051088,51.53199238174066],[-3.287913928955226,51.530201766500134],[-3.2852300814872537,51.52954666176106],[-3.286314311825166,51.52777310353489],[-3.2863143055274207,51.52777311443412],[-3.2873486652327406,51.52598801374647],[-3.2887080109189024,51.526286119059456],[-3.289700275297806,51.52447516562285],[-3.2897002624831555,51.524475174712286],[-3.2906416332592063,51.5226536864853],[-3.2892665413867324,51.52238536486472],[-3.2883328381359846,51.52419191205087],[-3.2842306669091115,51.523342028360744],[-3.2851413627486368,51.52158030322861],[-3.282391324478929,51.5210435148293],[-3.281495970942445,51.52277535948264],[-3.2828633227306594,51.523058693180396],[-3.281911495865955,51.52479537243493],[-3.2791930073216915,51.524198975305275],[-3.2782096754670547,51.52589549110277],[-3.2782096814541166,51.52589548074442],[-3.277178959652655,51.527581023631264],[-3.277178946662848,51.52758103761204],[-3.2761011437271463,51.52925509271561],[-3.280098638435566,51.530281681504725],[-3.2789448649745263,51.53198713467135],[-3.2815904847046893,51.53270037955508]],[[-3.2838881661440684,51.529219108408704],[-3.282763716880123,51.53096601201408],[-3.28143116229213,51.53062385846206],[-3.2825462837263584,51.5288915249794],[-3.2838881661440684,51.529219108408704]]],[[[-3.2860025675394513,51.51980893448608],[-3.285141364043359,51.521580313408556],[-3.2865164074368343,51.52184868350224],[-3.287384860282032,51.520062282785354],[-3.2860025675394513,51.51980893448608]]],[[[-3.2998261851262782,51.52234168403544],[-3.2988925252857344,51.52426328851697],[-3.300267730291655,51.524531497309184],[-3.3012086312255535,51.522594869341305],[-3.2998261851262782,51.52234168403544]]],[[[-3.298740037225192,51.51802354418087],[-3.297927383786031,51.51993397472206],[-3.300705868931443,51.52041019445185],[-3.301531311585604,51.51846942021452],[-3.298740037225192,51.51802354418087]]],[[[-3.2611239218646495,51.5152458785346],[-3.2603933477278124,51.516746894120075],[-3.265892454111175,51.517821438784615],[-3.266652080087366,51.51626034720215],[-3.2666520829707575,51.51626033483755],[-3.2673678749495156,51.51469120476749],[-3.2673678737638094,51.51469121272886],[-3.2680396184406004,51.51311452298476],[-3.265249000674729,51.51266783815766],[-3.2658645191907816,51.51111454134679],[-3.2644632394560227,51.51090641554287],[-3.2638537112229593,51.5124444767583],[-3.2610631712837987,51.511997715420016],[-3.2604235094366545,51.51349856518573],[-3.2618123544272772,51.51373711994428],[-3.2611239246385173,51.51524586664569],[-3.2611239218646495,51.5152458785346]]],[[[-3.261782290136395,51.50576939968263],[-3.2613168154294665,51.50727903550136],[-3.264140709762045,51.507634061499814],[-3.2646155920945708,51.50609360544951],[-3.264615591071622,51.50609361476963],[-3.265047290251938,51.50454821928379],[-3.2636263633367606,51.50440158393494],[-3.2631989350757475,51.505931520349414],[-3.261782290136395,51.50576939968263]]],[[[-3.2511003822346183,51.49182355613856],[-3.2510262375164367,51.49321893745602],[-3.255342063134557,51.4933317646337],[-3.2554185710231347,51.49188934522664],[-3.256857970259989,51.49191124775148],[-3.256894484230039,51.49045252855515],[-3.25977397578457,51.490464881435955],[-3.259769516537936,51.48897461229418],[-3.255450553977867,51.489003100009754],[-3.255454736042246,51.49044630820914],[-3.249695757095923,51.490421307459],[-3.249660988936803,51.49180159883287],[-3.2511003822346183,51.49182355613856]]],[[[-3.2177067429274313,51.47111198012924],[-3.218215618534832,51.47214668406733],[-3.2195950156524917,51.471890277630294],[-3.219078736447359,51.4708405839976],[-3.2204507189268816,51.47056917795735],[-3.2198973885305064,51.469510362154736],[-3.2198973898134504,51.469510367466064],[-3.2193145829976872,51.46845774116718],[-3.2193145786499393,51.4684577338515],[-3.218702474376431,51.46741161732292],[-3.2187024779968447,51.46741162371029],[-3.218061264835978,51.46637233506837],[-3.2167230408170906,51.46670282211523],[-3.2160623785190308,51.46568520738048],[-3.2134048130146726,51.4663752130467],[-3.2140465511006617,51.46736376756705],[-3.2127082849433073,51.46769422548623],[-3.213313275381166,51.46867499017191],[-3.216007910378739,51.46804333172603],[-3.216602720232288,51.46905999379921],[-3.2166027244571946,51.46906000090892],[-3.217169060629998,51.47008298880829],[-3.2171690593834894,51.47008298364654],[-3.2177067480200696,51.471111986111154],[-3.2177067429274313,51.47111198012924]]],[[[-3.2166923059579635,51.46431550023382],[-3.217391137591496,51.46534018688284],[-3.2187198703305877,51.464995146427626],[-3.2180111713925696,51.463956035515864],[-3.2166923059579635,51.46431550023382]]],[[[-3.127220681712565,51.48310923625088],[-3.12740704690764,51.483156241332196],[-3.1285086318928195,51.48149539973283],[-3.1282756825053553,51.48143664550625],[-3.1282756771361355,51.48143664425897],[-3.128041121543797,51.481380437068886],[-3.1280411230002665,51.481380437372096],[-3.127805032661336,51.4813267942562],[-3.12732460018854,51.48217407419381],[-3.1275370848989104,51.48222235388296],[-3.1270330270700417,51.48306426786339],[-3.1272206774170526,51.48310923525304],[-3.127220681712565,51.48310923625088]]],[[[-3.1266541022088044,51.482980500919965],[-3.1268441509917104,51.48302135259427],[-3.1273246014053404,51.48217407481715],[-3.1271108000276113,51.48212811753109],[-3.1271108010926416,51.48212811764857],[-3.126895748130232,51.48208449675921],[-3.126462941769926,51.48294172618128],[-3.126654103155512,51.4829805010244],[-3.1266541022088044,51.482980500919965]]],[[[-3.126679510306219,51.48204322597594],[-3.1268957493672707,51.482084497189845],[-3.1273285396367143,51.48122726609247],[-3.1270882781079767,51.48118141004342],[-3.126679510306219,51.48204322597594]]],[[[-3.1240552161529616,51.488126948656664],[-3.124101811716042,51.48813870120224],[-3.1252036368293226,51.48647789206826],[-3.125110448546195,51.486454387827344],[-3.125110446398304,51.48645438732839],[-3.125016615351122,51.48643190199579],[-3.125016615933767,51.4864319021171],[-3.124922170716582,51.48641044251091],[-3.124922171257417,51.48641044278797],[-3.124827140637814,51.48639001544393],[-3.124827141111199,51.48639001549616],[-3.124731554024293,51.486370626635946],[-3.1247315545741277,51.48637062682735],[-3.124635440134551,51.48635228235482],[-3.12463543817174,51.48635228185335],[-3.1245388256317574,51.48633498738258],[-3.124538826128118,51.48633498740228],[-3.124441744925504,51.48631874817343],[-3.124441745486299,51.48631874833462],[-3.1243442251904723,51.486303569292446],[-3.1243442256947542,51.486303569309705],[-3.124246296000777,51.48628945507746],[-3.1239347165791984,51.4871669676258],[-3.124008165181713,51.487177553501176],[-3.1240081648034934,51.487177553488245],[-3.124081306333914,51.48718893798533],[-3.12408130591331,51.48718893786443],[-3.124154118098747,51.48720111751556],[-3.1241541177264707,51.48720111750077],[-3.1242265783882943,51.48721408859708],[-3.123817704170635,51.48807589403885],[-3.123865763028679,51.48808506661732],[-3.12386576275375,51.48808506652162],[-3.1239135578959045,51.488094761311444],[-3.123913557659204,51.488094761285325],[-3.1239610745262043,51.48810497533411],[-3.1239610742557775,51.488104975195576],[-3.124008298378167,51.48811570539204],[-3.1240082980868373,51.48811570533139],[-3.1240552150789793,51.48812694840718],[-3.1240552161529616,51.488126948656664]]],[[[-3.124147987362437,51.486276410078254],[-3.1242462966278497,51.4862894552036],[-3.124557864245129,51.485411941727044],[-3.1244349799197435,51.48539563563148],[-3.124434977181173,51.485395635289514],[-3.124311655835703,51.485380670557355],[-3.1240493262631155,51.48626443778971],[-3.1241479851715392,51.486276409804674],[-3.124147987362437,51.486276410078254]]],[[[-3.124187935788763,51.48536705172767],[-3.12431165658949,51.4853806705773],[-3.1245739761709466,51.484496902628266],[-3.1244255139950856,51.48448056032261],[-3.1244255148572724,51.48448056072178],[-3.124276618590134,51.484465838421904],[-3.124063853935745,51.485354783240716],[-3.124187936507263,51.4853670520603],[-3.124187935788763,51.48536705172767]]],[[[-3.12412733439418,51.48445274051045],[-3.1242766194270284,51.48446583832129],[-3.1244893759473116,51.48357689296424],[-3.1243152133992385,51.483561612480074],[-3.12412733439418,51.48445274051045]]],[[[-3.12144574114814,51.378349646508156],[-3.1245540676843024,51.37834964648502],[-3.1245665705444527,51.37745084860092],[-3.1214332382538204,51.37745084862426],[-3.12144574114814,51.378349646508156]]],[[[-3.121483252769591,51.38104603931995],[-3.1245165561653674,51.38104603929737],[-3.124541564334428,51.37924844422913],[-3.1214582445321852,51.37924844425207],[-3.12144575867378,51.378349644911665],[-3.118337902059592,51.37838351125475],[-3.118337920103634,51.37838351168502],[-3.115231473260233,51.3784512341009],[-3.115293971060167,51.37934921454815],[-3.118375426182295,51.379282036975624],[-3.1184504251372274,51.381079086685304],[-3.1214832698722277,51.38104603776208],[-3.121483252769591,51.38104603931995]]],[[[-3.1126711671806686,51.341633887919116],[-3.1168014341199717,51.341543845125585],[-3.1167639896314077,51.34064531351081],[-3.1126087719488087,51.34073590026034],[-3.112608681379624,51.3407359058947],[-3.1084565983548913,51.34087175308765],[-3.108456621805666,51.340871753931424],[-3.1043089258317167,51.34105281934212],[-3.104308949515919,51.34105281107548],[-3.1001668915635703,51.34127904007811],[-3.100303997666704,51.342173766264814],[-3.1044211831288044,51.34194889573757],[-3.1045333977190444,51.342844988321374],[-3.108631280692616,51.34266609749127],[-3.108631257523472,51.34266609665768],[-3.1127334753695917,51.34253188097279],[-3.1126711671806686,51.341633887919116]]],[[[-2.9932330810803878,51.35714478941464],[-2.9969524032471195,51.35575107825373],[-2.995499511881111,51.35420057643561],[-2.99173727296878,51.35561035285374],[-2.9924850740109914,51.35637761202057],[-2.9887837042043075,51.357819902361165],[-2.988014603974228,51.35706093898196],[-2.984332761267639,51.358551834111886],[-2.983542677771282,51.35780135099105],[-2.979881944956437,51.35934085811814],[-2.979881969878124,51.35934085224165],[-2.9762644607485997,51.360920011422685],[-2.976264481911527,51.36092000316339],[-2.972691293501515,51.36253833744891],[-2.9726912105851535,51.36253837130305],[-2.9691634281321537,51.36419539294728],[-2.9700351195738652,51.36490962960729],[-2.9735428818602103,51.363261997242105],[-2.97439466195351,51.36398558342994],[-2.977927299448752,51.36238558891622],[-2.978758727217343,51.363118380923645],[-2.98231466240526,51.3615660649882],[-2.9831255879489214,51.36230779690034],[-2.986703250076753,51.36080318148286],[-2.9874934373440905,51.361553642505875],[-2.991091261407319,51.360096729888255],[-2.9910912358574437,51.36009673768238],[-2.9947289001781923,51.35867924426098],[-2.9932330810803878,51.35714478941464]]],[[[-2.9640702956832086,51.36901307833985],[-2.9674650863378633,51.36729983760488],[-2.9665736087631736,51.36659521371145],[-2.9631593260783484,51.368318274579465],[-2.9640702956832086,51.36901307833985]]],[[[-2.962584016048248,51.37213256499907],[-2.9658923389338163,51.37040265926756],[-2.9649813143038686,51.36970786980878],[-2.961653772134447,51.37144780716936],[-2.962584016048248,51.37213256499907]]],[[[-2.9621719230741066,51.37592174962655],[-2.9653749360096198,51.374186781020164],[-2.963514309667972,51.37281730254093],[-2.9602734154314527,51.374572751696874],[-2.9621719230741066,51.37592174962655]]],[[[-2.961921399629071,51.379683487424586],[-2.9650198181756475,51.37794522033386],[-2.964070466246121,51.377270748751215],[-2.960953391495627,51.37901946200673],[-2.961921399629071,51.379683487424586]]],[[[-2.9746575209019532,51.39190814880265],[-2.9774133668159863,51.390306794010854],[-2.9745080819998395,51.38831508109612],[-2.971697135912124,51.389948393132016],[-2.9707104067581476,51.389295109525506],[-2.967927177670554,51.39096965043063],[-2.966922419709172,51.39032721519156],[-2.9641683539345673,51.39204287148552],[-2.963145847829086,51.39141147533395],[-2.960422393861821,51.39316811470588],[-2.962502382543585,51.39440841358897],[-2.965190915882577,51.39267424824834],[-2.967236082955731,51.39393699030029],[-2.969936845286839,51.39225447066495],[-2.970941688116028,51.39289687968951],[-2.9736707072479787,51.391254890632865],[-2.9746575209019532,51.39190814880265]]],[[[-2.9593824417023376,51.39254795132276],[-2.962123356024353,51.39078007539227],[-2.961100892366286,51.390148666461535],[-2.958342517662501,51.39192777864586],[-2.9562626828730916,51.39068744201291],[-2.9535198488422885,51.39251918731065],[-2.952462877596716,51.391910401347104],[-2.9497545100513345,51.39378336178626],[-2.9497545292767984,51.3937833473431],[-2.9470986020316405,51.395685532077906],[-2.9470986223848676,51.39568551964992],[-2.9444959460445777,51.397616352821835],[-2.942283030827053,51.39646949238513],[-2.9397027076546807,51.398452674921096],[-2.9430696734236426,51.40013650326433],[-2.945602458173801,51.39818974926378],[-2.94670898072334,51.398763159083735],[-2.9492792993500294,51.39685626356746],[-2.950369659607535,51.39744163241914],[-2.952976066299395,51.395574820420975],[-2.952976047432437,51.39557483459553],[-2.955633925337934,51.393736702051726],[-2.956690981065145,51.39434545904678],[-2.959382371969605,51.392547987238764],[-2.9593824417023376,51.39254795132276]]],[[[-2.9292139691585874,51.39662059443401],[-2.9318473569908985,51.39452341349778],[-2.93072528194345,51.39396204048137],[-2.9280763837328907,51.396071532411824],[-2.9292139691585874,51.39662059443401]]],[[[-2.9269388255437794,51.39552245929639],[-2.9296032343614926,51.39340065666823],[-2.9284812142443197,51.392839262058864],[-2.9258012945905985,51.394973375088234],[-2.9269388255437794,51.39552245929639]]],[[[-2.9231810825429063,51.39713635411543],[-2.9258013066967132,51.394973366436524],[-2.9235263266357134,51.393875164644065],[-2.920875764443249,51.39606310651341],[-2.9231810825429063,51.39713635411543]]],[[[-3.125254498581327,51.479105965771474],[-3.1255530344654354,51.47913215835774],[-3.140634707144864,51.41601552197319],[-3.138572626728376,51.415834604576794],[-3.1385726382770236,51.41583460434409],[-3.136505837197938,51.415676181314154],[-3.136505792349639,51.41567617908522],[-3.1344348971220772,51.415540299062165],[-3.1344349087905523,51.41554029883922],[-3.1323605472627487,51.41542700239891],[-3.1323605591232186,51.415427006504025],[-3.1302833602350826,51.4153363279887],[-3.130283371535149,51.415336327536046],[-3.1282039648265423,51.415268294439564],[-3.128203976800281,51.41526829189678],[-3.126122992539249,51.4152229248357],[-3.1261229475175045,51.41522292482951],[-3.1240410165807764,51.41520023817769],[-3.1240410283645694,51.415200239215054],[-3.121958781869967,51.41520023923056],[-3.12195879361026,51.4152002381619],[-3.119876862673529,51.4152229248452],[-3.119876874761115,51.41522292513303],[-3.1177958905001892,51.4152682916033],[-3.1177958451422767,51.41526829442246],[-3.115716438433659,51.41533632755282],[-3.115716450178164,51.41533632797399],[-3.113639251290017,51.415427006518364],[-3.113639263150494,51.41542700238415],[-3.111564901622675,51.415540298853514],[-3.111564913291158,51.415540299047336],[-3.1094940180635806,51.415676179099464],[-3.1094940301662612,51.41567617716982],[-3.1074272289636378,51.415834599608914],[-3.1074271845737136,51.41583460456686],[-3.105365104157215,51.41601552198263],[-3.105365115716465,51.41601552335671],[-3.1033083811457534,51.41621888029336],[-3.1033083929931182,51.41621887920043],[-3.1012576277532373,51.41644461400617],[-3.101257638409715,51.41644460920115],[-3.0992134641677795,51.416692653456366],[-3.099213475726119,51.41669265496109],[-3.0971765124593613,51.41696293345853],[-3.0971764685583665,51.41696293999578],[-3.095147334061782,51.41725537139855],[-3.0951473462285115,51.41725536656761],[-3.09312665550131,51.41756986160696],[-3.0931266652796574,51.41756986268177],[-3.091115031270625,51.41790632603569],[-3.0911150450517013,51.417906321164615],[-3.0891130776724505,51.418264650778966],[-3.08911308697269,51.418264648120136],[-3.0871213934729576,51.4186447354018],[-3.0871213517080593,51.41864474500889],[-3.085140536554773,51.41904647527057],[-3.0851405463640305,51.419046474151216],[-3.083171210132124,51.419469725021834],[-3.0831712212768916,51.419469723684166],[-3.0812139613937477,51.41991436681301],[-3.081213973344145,51.41991436426118],[-3.079269383598115,51.42038026481328],[-3.0792693924965606,51.42038026208393],[-3.077338062916258,51.42086727881666],[-3.0773380224537092,51.42086728756543],[-3.0754205394341643,51.421375273331236],[-3.0754205498524945,51.42137527196569],[-3.073517495045983,51.421904072161006],[-3.0735175081862667,51.42190406791827],[-3.0716294591217865,51.42245352214877],[-3.071629466730401,51.422453519402715],[-3.069756996569429,51.423023461094814],[-3.069757009279303,51.42302345717429],[-3.067900686447137,51.42361371341892],[-3.06790064484572,51.42361372491618],[-3.0660610334041394,51.424224117281646],[-3.0660610433730238,51.42422411393067],[-3.0642387015395993,51.424854456717156],[-3.064238714280074,51.42485445461979],[-3.0624341955420533,51.42550455660241],[-3.0624342066116594,51.42550455096456],[-3.060648058985591,51.42617421496565],[-3.0606480157676903,51.426174233331075],[-3.0588807825437945,51.42686325680069],[-3.058880794957667,51.426863253010424],[-3.057133012475169,51.4275714263189],[-3.0571330223640367,51.427571418079154],[-3.0554052216195404,51.428298526415524],[-3.0554052333855015,51.42829852363668],[-3.053697939664548,51.42904434638723],[-3.053697949653051,51.429044342485675],[-3.0520116819114853,51.42980865338735],[-3.0520116427791026,51.429808669378964],[-3.050346914262815,51.43059123706104],[-3.0503469277897004,51.430591233253125],[-3.048704244181021,51.43139181968462],[-3.0487042482921782,51.431391815385645],[-3.047084109193165,51.43221017773507],[-3.047084119490002,51.43221017526854],[-3.0454870178060482,51.43304606512715],[-3.0454870284643505,51.43304605889611],[-3.0439134500320995,51.433899222586405],[-3.0439134122056344,51.43389923864923],[-3.042363836535915,51.4347694177666],[-3.0423638512168827,51.43476941664929],[-3.040838749516608,51.43565634650927],[-3.0408387547027114,51.435656338447245],[-3.039338591108986,51.436559749945076],[-3.0393386031985026,51.43655974559252],[-3.03786383465766,51.43747936442673],[-3.0378638420753385,51.437479361637884],[-3.0364149178456876,51.438414908696146],[-3.0364148809756273,51.438414927707676],[-3.0349922431221192,51.43936611945337],[-3.034992251739705,51.43936611453737],[-3.0335963331542515,51.44033266168897],[-3.033596343061954,51.44033265423608],[-3.0322275691937666,51.441314263317444],[-3.032227579684973,51.44131425690289],[-3.0308863679214393,51.44231062985382],[-3.0308863723881836,51.44231062365645],[-3.0295731318055714,51.4433214579863],[-3.0295731031875968,51.443321482115664],[-3.0282882352934366,51.44434647121263],[-3.0282882410985428,51.444346467056775],[-3.0270321372292743,51.445385299254184],[-3.0270321472543156,51.445385292622234],[-3.0258051908026244,51.44643765236188],[-3.0258051975653206,51.44643764636004],[-3.0246077632351382,51.44750321403525],[-3.0246077682052017,51.44750320691961],[-3.0234402217623355,51.44858165887378],[-3.0234401993853686,51.448581683844374],[-3.0223028985229075,51.44967269275806],[-3.022302904244584,51.44967268485062],[-3.021196195730647,51.45077591896249],[-3.0211962019539875,51.45077591488364],[-3.0201204243555675,51.45189103899957],[-3.020120426819502,51.45189103005688],[-3.0190759091361627,51.45301770539241],[-3.019075891188453,51.45301773080048],[-3.0180629540903943,51.454155615213395],[-3.0180629591034247,51.45415560891052],[-3.017081911891035,51.45530435635415],[-3.0170819149184678,51.455304349047296],[-3.016133058122472,51.45646361042465],[-3.01613306494808,51.45646360486599],[-3.0152166894594186,51.45763302779519],[-3.015216694404381,51.4576330209767],[-3.014333081222332,51.45881225002235],[-3.0143330595855646,51.45881227513816],[-3.0134824807446403,51.46000095212131],[-3.013482489698333,51.460000945500404],[-3.012665205475953,51.46119870871937],[-3.012665205794152,51.46119870066399],[-3.011881467247098,51.46240518605901],[-3.011881472194137,51.462405180579346],[-3.0111315203508715,51.46362002126555],[-3.0111315250201267,51.46362001387722],[-3.010415590565719,51.464842840453535],[-3.0104155785044178,51.464842866822906],[-3.0097338828317057,51.466073307604944],[-3.0097338842714687,51.466073301396044],[-3.0090866365614155,51.4673109820245],[-3.0090866426277314,51.467310974829815],[-3.008474042513092,51.46855551881518],[-3.0084740473843605,51.46855551093809],[-3.0078962840144596,51.46980653973653],[-3.0078962853063205,51.46980653346273],[-3.00735353734302,51.471063666552844],[-3.007353521411277,51.471063693770986],[-3.006845957800468,51.472326548886606],[-3.006845965187137,51.4723265412106],[-3.006373742300394,51.47359473387181],[-3.006373746183654,51.4735947268637],[-3.005937010666882,51.47486787123229],[-3.005937008869724,51.47486786408041],[-3.005535896584233,51.47614557280319],[-3.0055358977872415,51.47614556506968],[-3.0051705337746655,51.47742744927776],[-3.0051705284593058,51.4774274773975],[-3.0048410279299205,51.47871314701716],[-3.0048410324988777,51.47871313975475],[-3.0045474977842517,51.48000220334877],[-3.004547497090924,51.48000219612674],[-3.004290020588123,51.48129426136236],[-3.004290024306097,51.48129425387635],[-3.0040686874492555,51.482588927368695],[-3.004068687765353,51.48258892015034],[-3.003883561019792,51.48388580777256],[-3.003883553435013,51.48388583592059],[-3.0037346972402053,51.48518454288193],[-3.0037347033193993,51.485184535505454],[-3.0036221651026596,51.486484666192965],[-3.0036221607115783,51.48648465897904],[-3.0035459778476437,51.48778581758106],[-3.003545978010562,51.48778581016181],[-3.003506176801297,51.48908760035641],[-3.0035061787624397,51.48908761544424],[-3.003502775067912,51.4903896407102],[-3.0035027732791586,51.49038964064854],[-3.0035357708225803,51.49169150441871],[-3.0035357709996906,51.491691504363885],[-3.0036051628391456,51.49299281002678],[-3.00360516736158,51.49299281032529],[-3.0037109354730274,51.49429316137981],[-3.0037109293236615,51.494293160938454],[-3.0038530445638196,51.49559216130446],[-3.003853045164186,51.49559216107593],[-3.004031467333393,51.49688941486157],[-3.0040314675320503,51.496889415346764],[-3.004246145367859,51.49818452723674],[-3.0042461490708487,51.49818452749319],[-3.004497020220342,51.49947710274897],[-3.0044970210026154,51.4994771027539],[-3.0047840120634914,51.50076674744688],[-3.0047840073699024,51.500766747956405],[-3.0051070339323958,51.50205306904591],[-3.005107039335554,51.502053068274506],[-3.005466005931943,51.50333567353044],[-3.0054660051987483,51.50333567357628],[-3.0058608054366367,51.50461417204554],[-3.0058608003601344,51.50461417263287],[-3.006291316887575,51.50588817456206],[-3.0062913201765196,51.50588817418422],[-3.0067574246779047,51.507157291020185],[-3.0067574242589723,51.50715729115655],[-3.0072589775733705,51.50842113593517],[-3.007258979308682,51.5084211353804],[-3.0077958313951174,51.50967932264959],[-3.081371449534458,51.496998041875486],[-3.0811767248711446,51.496543396530974],[-3.0811767242444095,51.49654339673188],[-3.0809947449550465,51.49608669905875],[-3.096397979335051,51.493783140011864],[-3.0962907398566815,51.493492700480715],[-3.101914080362989,51.492715690203255],[-3.101835815131602,51.49248551206047],[-3.1018358160485717,51.492485511953575],[-3.1017639987429204,51.49225451616002],[-3.1031797970081945,51.49209096802818],[-3.103118799411914,51.491874675220465],[-3.1031187985010185,51.49187467535135],[-3.103063857703113,51.49165775089169],[-3.1059119645798092,51.49139249383731],[-3.105870066885221,51.491206074841145],[-3.105870066772141,51.49120607484052],[-3.105833387473899,51.49101922774856],[-3.108694537592324,51.49081611420643],[-3.10872511326398,51.490971819377584],[-3.108725113358213,51.490971819378096],[-3.108760037604456,51.49112716769955],[-3.111608077108298,51.49086177244276],[-3.1116394944102934,51.490985727010774],[-3.111639494930782,51.490985726935946],[-3.1116743729914553,51.49110932031752],[-3.111674372920815,51.491109320322],[-3.111712701145277,51.49123251487277],[-3.111712700656247,51.49123251492982],[-3.111754467397699,51.49135527312477],[-3.1117544677145186,51.49135527308806],[-3.111799660274211,51.491477557521414],[-3.111799660233878,51.49147755753461],[-3.1118482648730543,51.4915993309573],[-3.1118482650401282,51.49159933090368],[-3.1119002669769795,51.49172055621594],[-3.110512746341928,51.49196061443526],[-3.11057504891895,51.49209633547246],[-3.1105750484162376,51.49209633533256],[-3.110641136291766,51.49223135689909],[-3.1106411364078665,51.492231357078396],[-3.1107109894902054,51.492365638032304],[-3.11071099008442,51.49236563808638],[-3.1107845871216306,51.492499137512475],[-3.110784586888694,51.49249913723908],[-3.1108619054820434,51.492631814474215],[-3.110861905790134,51.49263181463271],[-3.1109429224277108,51.49276362924896],[-3.1096031604256,51.49309290053731],[-3.109697256902608,51.49323835920736],[-3.109697256862891,51.49323835904037],[-3.10979540636556,51.4933827703486],[-3.1097954069781046,51.49338277036292],[-3.1098975796455006,51.49352609030313],[-3.1112079085031072,51.49315349727495],[-3.1113034596305646,51.49328146264061],[-3.11130345912602,51.493281462615506],[-3.111402573917977,51.49340836744138],[-3.111402573964561,51.49340836731591],[-3.1115052222494803,51.49353417293064],[-3.1115052226883684,51.49353417310656],[-3.111611373228463,51.49365884117511],[-3.1128768602848953,51.49323007999755],[-3.112974302799587,51.49333985011411],[-3.112974303155302,51.49333985020749],[-3.1130748002781,51.493448541940346],[-3.113074800066306,51.493448541927854],[-3.113178321196297,51.49355612216688],[-3.1131783212893143,51.49355612219807],[-3.1132848349077746,51.49366255816207],[-3.1132848350319966,51.49366255826035],[-3.113394308708371,51.49376781751948],[-3.1145950996523477,51.493271820937856],[-3.1144993087776727,51.493179720064546],[-3.114499308668979,51.49317971997857],[-3.1144061077355496,51.49308658947271],[-3.1168616048915623,51.49214748533402],[-3.1167969007038367,51.49208024971103],[-3.11679690083621,51.492080249718846],[-3.1167340864267246,51.49201231937334],[-3.116734086204407,51.49201231931499],[-3.116673180703253,51.4919437149384],[-3.116673181019585,51.491943715045835],[-3.116614202968545,51.491874457544526],[-3.1166142027247172,51.49187445744679],[-3.1165571700884738,51.49180456791406],[-3.116557170062607,51.49180456798377],[-3.1165021002025757,51.491734067713864],[-3.1152024732699193,51.49212093809565],[-3.115138766798828,51.49203562996132],[-3.1151387667803787,51.49203562990934],[-3.1150774552414426,51.491949640673624],[-3.1150774548739224,51.49194964066506],[-3.1150185569311946,51.49186299652107],[-3.115018556955029,51.49186299662126],[-3.114962090535108,51.491775723969475],[-3.1149620908807822,51.491775723883805],[-3.1149080731773053,51.49168784931534],[-3.113559369045039,51.492002519823544],[-3.113499227060375,51.491899327794904],[-3.1134992272415585,51.49189932800754],[-3.1134419796486874,51.49179549643892],[-3.113441979186519,51.491795496396854],[-3.1133876434133168,51.49169105691352],[-3.113387643323004,51.491691056774066],[-3.1133362359055834,51.49158604119741],[-3.113336236296582,51.49158604130621],[-3.113287772868802,51.49148048163407],[-3.1132877729424053,51.49148048160734],[-3.113242268251645,51.491374409994364],[-3.1132422681054606,51.491374410041296],[-3.1131997359916816,51.491267858798956],[-3.113199736026978,51.49126785878744],[-3.1131601894279872,51.49116086037748],[-3.1131601891507685,51.491160860409586],[-3.1131236400917794,51.491053447424335],[-3.114534568471928,51.490874362940716],[-3.114565898945464,51.490966430840615],[-3.1145658991830802,51.490966430813074],[-3.114599798932913,51.49105814333368],[-3.1145997989026633,51.491058143343565],[-3.114636257618237,51.49114947254907],[-3.1146362577435363,51.491149472508845],[-3.1146752643321047,51.491240390575435],[-3.1146752642690227,51.491240390598335],[-3.1147168068646294,51.491330869831025],[-3.114716806529482,51.49133086973777],[-3.114760872488459,51.49142088257601],[-3.1147608725658738,51.491420882695536],[-3.114807448484763,51.49151040171324],[-3.1175383362426947,51.490940164640065],[-3.1175710538262016,51.490999495834856],[-3.117571053722662,51.49099949571335],[-3.1176054251141325,51.491058461406894],[-3.117605425251064,51.49105846147733],[-3.1176414399915435,51.491117043704044],[-3.11764143976111,51.49111704376117],[-3.1176790868851403,51.49117522467885],[-3.1176790868692463,51.49117522461204],[-3.1177183549109473,51.491232986494325],[-3.1177183551559566,51.491232986500016],[-3.117759232160906,51.49129031174761],[-3.11775923217322,51.491290311782265],[-3.1178017056954928,51.49134718293423],[-3.1178017054712623,51.49134718292308],[-3.117845762576413,51.49140358265676],[-3.1178457625971046,51.49140358260099],[-3.1178913898681357,51.49145949373206],[-3.1178913900632073,51.49145949381023],[-3.1179385736095715,51.49151489930393],[-3.11920394226674,51.49108606981462],[-3.119240487138896,51.49112723166205],[-3.1192404872722816,51.491127231697064],[-3.119278177400735,51.491167989109314],[-3.11927817732131,51.49116798910463],[-3.1193170012262046,51.49120832966784],[-3.119317001261085,51.49120832967954],[-3.1193569471186553,51.49124824110321],[-3.119356947165248,51.491248241140056],[-3.1193980028100667,51.491287711265535],[-3.119398002592372,51.49128771120166],[-3.1194401555173656,51.49132672800767],[-3.1194401556090248,51.491326728064756],[-3.1194833929789296,51.491365279661885],[-3.1194833929989114,51.49136527960126],[-3.1195277016412715,51.49140335424592],[-3.1195277015387624,51.491403354165215],[-3.119573067957451,51.49144094025965],[-3.1195730680006672,51.4914409404321],[-3.1196194783848563,51.491478026524405],[-3.119619478650703,51.49147802643169],[-3.119666918856844,51.49151460122142],[-3.1196669187114066,51.491514601152396],[-3.1197153742902466,51.49155065350182],[-3.1197153741775185,51.49155065358689],[-3.1197648303740837,51.49158617251248],[-3.1197648305309906,51.49158617256426],[-3.119815272280064,51.49162114724241],[-3.119815272219276,51.49162114722941],[-3.1198666841544114,51.49165556700763],[-3.118822220206451,51.49227423749967],[-3.118892042087261,51.492319377299715],[-3.118892042084869,51.4923193771557],[-3.1189631154638815,51.492363749356045],[-3.1189631152331856,51.49236374935454],[-3.1190354184647964,51.49240734043922],[-3.1190354185585263,51.49240734047723],[-3.119108929619339,51.49245013716223],[-3.1191089299318473,51.49245013732781],[-3.1191836264326875,51.49249212657219],[-3.119183626200038,51.49249212627608],[-3.119259485373953,51.49253329529325],[-3.1192594852153874,51.49253329541183],[-3.1193364839655917,51.49257363165831],[-3.1193364838181816,51.49257363153351],[-3.1194145986820923,51.49261312272016],[-3.1194145988303035,51.49261312272527],[-3.119493806015502,51.49265175681731],[-3.1194938060435526,51.4926517570657],[-3.119574081427811,51.492689522293894],[-3.118717557241875,51.49341201201886],[-3.1188192069041807,51.49345811882246],[-3.1188192071713994,51.49345811884092],[-3.1189221306215957,51.4935031111242],[-3.11892213077774,51.49350311095173],[-3.1190262966550613,51.49354697500758],[-3.119026296488298,51.493546975048936],[-3.119131673064573,51.49358969751622],[-3.119131673162933,51.493589697564694],[-3.1192382283350644,51.49363126542365],[-3.1192382283662727,51.49363126545995],[-3.1193459296712,51.49367166604616],[-3.1193459298694917,51.49367166623256],[-3.119454744499219,51.4937108872347],[-3.119454744588944,51.493710887107966],[-3.1195646393830496,51.49374891657706],[-3.1195646387818687,51.49374891637956],[-3.1196755802574407,51.4937857427361],[-3.1196755804139746,51.49378574288598],[-3.1197875347806443,51.493821354901144],[-3.119787534883517,51.49382135491611],[-3.119900468028448,51.49385574173984],[-3.1199004682169633,51.49385574183391],[-3.120014345734844,51.493888892987954],[-3.120014345796753,51.493888892999905],[-3.120129132989802,51.4939207983848],[-3.1201291323575564,51.4939207980391],[-3.120244794243005,51.49395144794118],[-3.120244794327538,51.4939514481931],[-3.120361295682617,51.49398083326578],[-3.120361295797023,51.493980833083626],[-3.120478601114001,51.494008944373164],[-3.120478601255019,51.494008944477706],[-3.1205966748011584,51.4940357734185],[-3.121077356936687,51.493188522758075],[-3.1211724000151406,51.493208953114774],[-3.1211724000535948,51.493208953281524],[-3.1212679999374733,51.49322834501227],[-3.1212679993815695,51.49322834482833],[-3.1213641269346377,51.49324669203142],[-3.1213641271813346,51.49324669210249],[-3.121460753123396,51.493263989179184],[-3.121460753147872,51.493263989151046],[-3.1215578480367956,51.493280230833726],[-3.1215578481654704,51.49328023088495],[-3.1216553824211433,51.49329541222397],[-3.121655382517525,51.49329541221185],[-3.121753326421889,51.49330952858214],[-3.1214416516531287,51.494187033575315],[-3.1215645585541503,51.49420334276166],[-3.121564557860385,51.494203342570266],[-3.121687902103442,51.49421831018477],[-3.1216879022152155,51.49421831015312],[-3.1218116462225405,51.49423193162646],[-3.1218116463621195,51.494231931827194],[-3.121935752435945,51.49424420300862],[-3.121935752592857,51.49424420283161],[-3.1220601829079224,51.49425511998192],[-3.122060183069238,51.49425512001222],[-3.1221848997177637,51.49426467980495],[-3.1221848999030617,51.494264679946845],[-3.1223098648872596,51.49427287946887],[-3.1223098641294875,51.4942728794755],[-3.122435039369074,51.49427971623868],[-3.1224350395615157,51.49427971625714],[-3.1225603869161995,51.494285188167986],[-3.1225603870351266,51.49428518793466],[-3.122685868304622,51.494289293326695],[-3.1226858684402625,51.49428929349621],[-3.122811445401756,51.49429203111837],[-3.1228114455573626,51.494292031125894],[-3.1229370799430587,51.49429340014378],[-3.122937080091056,51.49429340007911],[-3.1230627336181556,51.49429340007568],[-3.123075299665205,51.495192179849106],[-3.1232260638914804,51.49519053699857],[-3.1232260640621203,51.49519053698647],[-3.1233767593739343,51.49518725177897],[-3.1233767595367055,51.49518725157242],[-3.123527340009098,51.495182325009125],[-3.123527340183998,51.49518232528613],[-3.123677759946,51.495175758868136],[-3.123677760112566,51.49517575884282],[-3.1238279733202545,51.49516755457104],[-3.123827973505155,51.49516755456552],[-3.1239779343866214,51.495157714939744],[-3.123977933514739,51.495157714771935],[-3.1241275963701107,51.49514624280201],[-3.1241275966280595,51.495146242762495],[-3.1242769158564836,51.49513314193181],[-3.1242769159160457,51.49513314214072],[-3.1244258460247103,51.49511841644344],[-3.124425846320939,51.495118416199055],[-3.1245743419161007,51.49510207011978],[-3.1245743420502308,51.495102070154935],[-3.124722357891162,51.495084108676345],[-3.124722357058632,51.4950841089032],[-3.124869848048671,51.4950645375089],[-3.1248698482619965,51.495064537354956],[-3.12501676944855,51.49504336199724],[-3.125016769593128,51.49504336201261],[-3.125163076212647,51.49502058914466],[-3.125163076405666,51.495020589065035],[-3.1253087238746753,51.49499622562553],[-3.1253087239113895,51.49499622566492],[-3.125453667853477,51.49497027907945],[-3.125453668223535,51.49497027897005],[-3.1255978644693543,51.494942757141246],[-3.1255978636354786,51.494942757414336],[-3.1257412682587535,51.49491366874151],[-3.1257412683119643,51.494913668810035],[-3.1258838376114952,51.49488302214711],[-3.125883837829968,51.49488302191983],[-3.1260255283566494,51.49485082660341],[-3.1260255285214047,51.4948508267966],[-3.1261662971141715,51.49481709263751],[-3.126166297246938,51.494817092531854],[-3.1263061010058304,51.49478182980955],[-3.1263061011027946,51.49478182982584],[-3.1264448974339194,51.49474504928561],[-3.1264448966706975,51.49474504937623],[-3.1265826432862336,51.49470676223474],[-3.1265826443948597,51.49470676190175],[-3.1267192993130783,51.49466697980503],[-3.126719298513948,51.49466698001642],[-3.1268548201131607,51.49462571510715],[-3.126854819459748,51.494625715403615],[-3.1269891664513594,51.494582980253774],[-3.1269891674070767,51.494582979745445],[-3.127122298835586,51.49453878735913],[-3.1271222981141578,51.494538787593335],[-3.1272541734380805,51.494493151454485],[-3.1272541745800817,51.494493151287905],[-3.1273847536090287,51.494446085281695],[-3.1273847525641747,51.49444608538089],[-3.1275139955218165,51.49439760387228],[-3.1275139965935863,51.49439760350725],[-3.127641864090634,51.49434772124559],[-3.1276418636982717,51.49434772151167],[-3.127768316795467,51.49429645371208],[-3.127768316075969,51.49429645398111],[-3.1278933162481177,51.494243816268316],[-3.127893316950373,51.49424381582961],[-3.1280168260953487,51.494189824226815],[-3.1280168253906937,51.494189824520525],[-3.1281388059013264,51.494134495494144],[-3.128138807192056,51.494134495303456],[-3.1282592218932486,51.49407784569029],[-3.128259220905525,51.4940778459606],[-3.1283780331261593,51.494019893046314],[-3.1283780328201214,51.49401989335168],[-3.1284952063660953,51.49396065478666],[-3.1284952071657632,51.49396065432536],[-3.128610706319991,51.493900148147176],[-3.1286107055627475,51.49390014828794],[-3.1287244951570745,51.493838392949314],[-3.128724496352791,51.49383839275335],[-3.1288365417140613,51.49377540704926],[-3.128836540642593,51.49377540712521],[-3.1289468076465905,51.49371121027145],[-3.1289468072633557,51.493711210848915],[-3.129055262334803,51.493645822397895],[-3.1290552630095196,51.49364582175164],[-3.1291618730771362,51.493579261614826],[-3.1291618725541883,51.4935792621495],[-3.129266605176505,51.49351155061986],[-3.129266606297555,51.493511549889185],[-3.1293694295370957,51.49344270757945],[-3.1293694289051435,51.49344270792971],[-3.129470311472254,51.493372755834095],[-3.1294703123054437,51.49337275541186],[-3.129569223450388,51.49330171482751],[-3.1295692227100878,51.49330171530306],[-3.1296661323309056,51.49322960789173],[-3.1307772662830464,51.49380125612128],[-3.1308879572393438,51.49371591076088],[-3.1308879584550082,51.493715909848895],[-3.130996245991365,51.49362937147631],[-3.1309962454863745,51.493629372195684],[-3.13110209666823,51.493541667196766],[-3.131102097625082,51.49354166625998],[-3.1312054801688616,51.4934528213412],[-3.131205479620071,51.493452821860984],[-3.1313063620819706,51.49336286410838],[-3.1313063610840217,51.493362864718726],[-3.1314047127445996,51.49327182154543],[-3.1314047134274867,51.493271820937856],[-3.1315005043021618,51.493179720064546],[-3.1302860557901324,51.49269686949911],[-3.1303659436138744,51.492617044181955],[-3.1303659441984473,51.49261704351289],[-3.1304435878222656,51.49253635995472],[-3.1304435876635246,51.49253636060695],[-3.130518963480923,51.492454843397326],[-3.13051896426252,51.49245484268721],[-3.1305920492832526,51.49237251665118],[-3.130592048393291,51.492372517104386],[-3.1306628203961147,51.49228940734175],[-3.1319400536039654,51.49270434362392],[-3.1320198952428404,51.49260649655179],[-3.132019895874395,51.49260649589606],[-3.132096989412792,51.492507793830356],[-3.1320969890178683,51.49250779441237],[-3.1321713110205427,51.49240826743529],[-3.1321713116426433,51.49240826662786],[-3.1322428394457518,51.4923079450505],[-3.132242839276533,51.492307945606335],[-3.132311551144845,51.49220686000134],[-3.1336418661546817,51.49255070821254],[-3.133563341052145,51.49266623549858],[-3.13356334124552,51.49266623486334],[-3.133481597830911,51.492780889004095],[-3.1347919053833837,51.493153496718946],[-3.1348838637477865,51.493024509787446],[-3.134883863530262,51.493024510502096],[-3.1349722011801,51.492894541314975],[-3.13497220035863,51.492894541943286],[-3.1350568904085847,51.49276363010494],[-3.135056891427805,51.49276362901202],[-3.1351379080586237,51.49263181438735],[-3.1351379075878807,51.492631815197434],[-3.135215226201446,51.49249913796229],[-3.1338578976846527,51.49219924019637],[-3.1339233203772734,51.49208057478569],[-3.1339233195355316,51.4920805753806],[-3.1339854143692376,51.49196121525934],[-3.133985414454673,51.49196121594963],[-3.134044162540925,51.49184119747102],[-3.134044162765368,51.491841196520134],[-3.1340995461869694,51.49172055624648],[-3.1340995460940184,51.491720556858795],[-3.1341515480488495,51.49159933154654],[-3.1341515482111935,51.49159933063588],[-3.1342001528413856,51.49147755721316],[-3.134200152799735,51.49147755794998],[-3.1342453453714127,51.49135527351664],[-3.1342453456909634,51.49135527248191],[-3.1342871124144396,51.49123251428697],[-3.1356980623618007,51.49141156551331],[-3.135741177493853,51.49127297112829],[-3.135741177399452,51.491272971967],[-3.1357804110652903,51.491133928942254],[-3.1357804116403933,51.49113392782105],[-3.1358157518685643,51.490994478507005],[-3.1358157513550378,51.49099447929506],[-3.1358471874687246,51.490854666184745],[-3.1358471875523706,51.490854665039194],[-3.135874709956992,51.49071453071773],[-3.1358747103629523,51.49071453147378],[-3.1358983107634977,51.490574118626675],[-3.1358983099937037,51.49057411947398],[-3.1359179812396425,51.490433470887325],[-3.1359179820606724,51.490433469762785],[-3.1359337181408367,51.490292628264136],[-3.1344966135856267,51.49023790729938],[-3.134507103037013,51.490112581657044],[-3.1345071034682146,51.490112580664395],[-3.134514087616378,51.48998715981824],[-3.1345140876328625,51.48998716051997],[-3.13451756442649,51.48986168267958],[-3.1345175642573606,51.48986168168179],[-3.134517532618775,51.4897361850713],[-3.1330778311076846,51.48974416122844],[-3.133077855332899,51.489853970763],[-3.13307785548086,51.48985397163607],[-3.1330748098299335,51.489963764709415],[-3.133074809815529,51.4899637640954],[-3.1330686952356412,51.49007350726145],[-3.1330686948583124,51.490073508130024],[-3.1330595131485657,51.490183167955486],[-3.1330595136749677,51.490183167356236],[-3.133047267651212,51.490292710446745],[-3.131611916530196,51.490222305189114],[-3.1315987936071643,51.49031607043624],[-3.1315987941204106,51.49031606987139],[-3.1315830518200567,51.490409677864434],[-3.1315830515494656,51.490409677360404],[-3.1315646946494082,51.49050309957601],[-3.1315646945935733,51.4905031003397],[-3.1315437286343406,51.49059630832165],[-3.131543728976736,51.490596307796295],[-3.131520160365129,51.49068927315546],[-3.1315201599816618,51.49068927390291],[-3.1314939958458696,51.49078196831163],[-3.1314939959088592,51.4907819677525],[-3.131465244240033,51.490874362978275],[-3.1314652446010762,51.49087436245858],[-3.1314339141410192,51.49096643035846],[-3.1314339139013088,51.49096643113451],[-3.1314000141424874,51.49105814365511],[-3.1314000141737592,51.49105814310249],[-3.131363555464926,51.491149472307995],[-3.1313635553431247,51.49114947299099],[-3.131324548741079,51.49124039105758],[-3.1313245488108117,51.491240390598335],[-3.131283006215205,51.491330869831025],[-3.131283006046837,51.49133087054418],[-3.13123894006539,51.491420883376804],[-3.1312389400013414,51.4914208828591],[-3.131192364077954,51.49151040187118],[-3.131192364709275,51.49151040142502],[-3.1311432930161827,51.49159939935298],[-3.1297860171035676,51.49129945586387],[-3.1297430547458567,51.49137316347247],[-3.1297430550074266,51.49137316302244],[-3.1296980384218838,51.491446391322356],[-3.129698037855602,51.49144639192949],[-3.129650980716819,51.49151911860329],[-3.129650981173223,51.49151911825425],[-3.129601897833889,51.49159132115735],[-3.1296018979547817,51.491591320760335],[-3.129550803359555,51.491662977892965],[-3.1295508029151797,51.4916629784697],[-3.1294977125932544,51.491734067995644],[-3.1281981073813707,51.491347183148505],[-3.128240580909636,51.49129031199655],[-3.128240581265155,51.49129031153518],[-3.128281458264121,51.49123298628385],[-3.1282814581673986,51.49123298660146],[-3.1283207262121016,51.49117522471919],[-3.1283207258469736,51.491175224998415],[-3.128358372979995,51.49111704408448],[-3.1283583734330414,51.49111704359877],[-3.12839438817052,51.49105846136829],[-3.1283943879612517,51.49105846172833],[-3.128428759361703,51.49099949603478],[-3.1297860174012495,51.491299455348404],[-3.1298269124260325,51.491225290879335],[-3.1298269118999236,51.49122529125113],[-3.1298657271684953,51.491150692523945],[-3.129865727221853,51.49115069295537],[-3.129902450921579,51.49107568268919],[-3.1299024510619082,51.4910756820949],[-3.1299370719870403,51.491000283139606],[-3.1299370719289157,51.4910002835223],[-3.1299695795704747,51.490924518849184],[-3.1299695796719935,51.49092451828002],[-3.129999964110984,51.4908484109678],[-3.1299999640849108,51.4908484114283],[-3.1300282161046864,51.49077198466303],[-3.1300282163044644,51.49077198401633],[-3.1300543272783523,51.49069526107742],[-3.130054326977472,51.490695261510496],[-3.130078288992329,51.49061826577544],[-3.130078288939822,51.49061826624139],[-3.13010009470803,51.490541021162265],[-3.1301000950276054,51.4905410205394],[-3.1301197378870373,51.490463549643],[-3.1301197376016945,51.4904635500808],[-3.1301372116093296,51.4903858769732],[-3.1301372116558794,51.490385876336774],[-3.1301525114698237,51.490308024675336],[-3.1301525116953,51.49030802509537],[-3.130165632695526,51.49023001859337],[-3.130165632267805,51.490230019064086],[-3.1301765704700175,51.490151881490796],[-3.1301765709262206,51.49015188086608],[-3.130185322979023,51.49007363601394],[-3.130185322602996,51.49007363644198],[-3.1301918858810254,51.489995308154725],[-3.1301918861505844,51.489995307534315],[-3.1301962586365333,51.489916919664864],[-3.130196258646795,51.48991692010345],[-3.130198439049585,51.48983849653259],[-3.130198438943938,51.48983849590897],[-3.1301984265809963,51.489760060526706],[-3.1244396115632647,51.48979164714818],[-3.12443917252162,51.489775962465956],[-3.124439172517993,51.48977596255368],[-3.124438295065118,51.48976028504374],[-3.124438295009592,51.489760284919655],[-3.1244369794073057,51.489744619358085],[-3.1244369794808886,51.48974461944704],[-3.1244352261363377,51.4897289706043],[-3.1244352261292017,51.489728970479824],[-3.1244330355709433,51.48971334312357],[-3.124433035569101,51.489713343211484],[-3.124430408470781,51.489697742101875],[-3.1244304084241104,51.489697742192575],[-3.1244273455865,51.48968217208231],[-3.1244273455755724,51.48968217194833],[-3.1244238479258053,51.48966663757979],[-3.124423847981204,51.48966663768074],[-3.12441991659169,51.489651143785075],[-3.1244199165258815,51.48965114366051],[-3.1244155525882937,51.48963569495861],[-3.1244155525971236,51.4896356950384],[-3.124410757446895,51.48962029623522],[-3.124410757422768,51.48962029610708],[-3.124405532515161,51.48960495189358],[-3.124405532562313,51.48960495199145],[-3.124399879495614,51.48958966704078],[-3.1243998794991574,51.4895896671195],[-3.124393799995213,51.489574446088],[-3.124393799973386,51.489574445974156],[-3.124387295879076,51.4895592934985],[-3.12438729588922,51.48955929357505],[-3.1243803691914827,51.48954421427043],[-3.1243803691618965,51.489544214151586],[-3.124373021965582,51.48952921261166],[-3.1243730220392476,51.48952921269841],[-3.1243652565885087,51.48951429349162],[-3.124365256606431,51.48951429356644],[-3.1243570752667114,51.489499461237784],[-3.124357075205663,51.4894994611347],[-3.1243484804644748,51.48948472020306],[-3.124348480515306,51.48948472029307],[-3.1243394749964275,51.489470075247354],[-3.1243394748816535,51.489470075125915],[-3.1243300613226945,51.48945553042887],[-3.1243300614124894,51.48945553049867],[-3.1243202426865775,51.48944109057842],[-3.1243202427092673,51.489441090657806],[-3.1243100218078457,51.48942675991351],[-3.124310021803276,51.48942675979863],[-3.1242994018346084,51.48941254259576],[-3.1242994018895476,51.48941254267984],[-3.1242883860944133,51.48939844334835],[-3.1242883860030517,51.489398443228836],[-3.1242769777315744,51.48938446606499],[-3.124276977768623,51.48938446615306],[-3.1242651805019372,51.48937061541296],[-3.125530430505242,51.4889417174087],[-3.125506064634325,51.48891427747656],[-3.1255060647185324,51.488914277666574],[-3.1254809354972255,51.48888710738352],[-3.125480935718057,51.4888871075483],[-3.1254550508011247,51.48886021518863],[-3.1254550506032315,51.488860214967495],[-3.1254284178655145,51.48883360872698],[-3.1254284180045855,51.48883360881049],[-3.125401045567996,51.488807296789474],[-3.1254010453698684,51.488807296617765],[-3.125372941565922,51.48878128683433],[-3.1253729416764466,51.48878128700964],[-3.1253441150762167,51.488755587382734],[-3.125344115230031,51.48875558753122],[-3.1253145746142312,51.48873020588816],[-3.1253145743378177,51.488730205620534],[-3.125284328693722,51.488705149696976],[-3.125284329006665,51.488705149903424],[-3.125253387561146,51.4886804273247],[-3.125253387210792,51.488680427066036],[-3.125221759376367,51.488656045369574],[-3.125221759646447,51.48865604552367],[-3.1251894550691706,51.488632012129074],[-3.1251894548025536,51.488632011965215],[-3.125156483314143,51.4886083341986],[-3.125156483382656,51.48860833427029],[-3.1251228550334047,51.488585019339936],[-3.125122855242561,51.48858501956383],[-3.1250885802803863,51.48856207456956],[-3.1250885800753316,51.48856207432696],[-3.1250536689278223,51.488539506261986],[-3.1250536690991515,51.48853950644209],[-3.1250181324124564,51.48851732217622],[-3.1250181321845494,51.48851732196269],[-3.124981980772492,51.48849552825728],[-3.1249819808987533,51.48849552834449],[-3.124945225781759,51.48847413183371],[-3.124945225965769,51.48847413196709],[-3.1249078783409336,51.48845313916729],[-3.124907878112511,51.48845313899578],[-3.124869949347572,51.48843255630552],[-3.124869949088089,51.48843255613721],[-3.12483145073642,51.48841238982602],[-3.124831450814625,51.48841238999183],[-3.124792394612257,51.488392646198314],[-3.124792394882902,51.48839264630104],[-3.124752792724534,51.48837333103668],[-3.1247527930507464,51.488373331128635],[-3.124712656998766,51.48835445027587],[-3.124712657077449,51.48835445043128],[-3.124671999358888,51.48833600974352],[-3.124671998562511,51.48833600930758],[-3.124630831545125,51.48831801441108],[-3.124630831828921,51.4883180144782],[-3.1245891680661027,51.488300470842155],[-3.12458916830592,51.48830047093369],[-3.1245470204887913,51.48828338390197],[-3.1245470206195693,51.48828338399254],[-3.1245044015859444,51.488266758770685],[-3.1245044019122172,51.4882667588689],[-3.1244613246436073,51.48825060051846],[-3.124461323703188,51.48825060023246],[-3.1244178013098574,51.48823491368874],[-3.124417801531413,51.48823491373896],[-3.124373847279317,51.48821970376716],[-3.124373847519768,51.48821970384708],[-3.1243294747975976,51.48820497507959],[-3.124329475076731,51.48820497512957],[-3.124284697398918,51.488190732052],[-3.1242846964138558,51.48819073183126],[-3.124239527411601,51.48817697879553],[-3.124239527680935,51.488176978861325],[-3.12419398112015,51.48816372004267],[-3.1241939813513246,51.48816372014457],[-3.124148071105708,51.48815095958171],[-3.1241480713570873,51.488150959613776],[-3.1241018114081096,51.48813870119308],[-3.1235508691364635,51.48896910171013],[-3.123527570999531,51.488963225331055],[-3.1235275704625316,51.488963225206305],[-3.1235041115993027,51.488957603566035],[-3.12350411174497,51.48895760359636],[-3.1234804993053054,51.48895223839978],[-3.123480499440527,51.48895223846904],[-3.1234567406177036,51.48894713135045],[-3.1234567407360534,51.488947131363524],[-3.123432842765284,51.48894228387867],[-3.1234328429027505,51.48894228392651],[-3.123408813064142,51.48893769755173],[-3.123408812573412,51.48893769742636],[-3.1233846581815317,51.48893337356544],[-3.1233846583056275,51.488933373570376],[-3.12336038672145,51.48892931353366],[-3.1233603868616564,51.488929313573955],[-3.1233360054790955,51.48892551859794],[-3.1233360056051733,51.48892551860225],[-3.123311521849593,51.48892198984298],[-3.123311522006368,51.48892198987452],[-3.12328694333607,51.488918728406496],[-3.1232869427883165,51.48891872833809],[-3.1232622766870572,51.48891573516241],[-3.1232622768378233,51.48891573516641],[-3.1232375308207985,51.48891301118717],[-3.123237530964507,51.4889130112537],[-3.123212712570872,51.48891055730067],[-3.12321271271037,51.4889105572839],[-3.123187829497243,51.48890837410459],[-3.123187829636609,51.48890837410181],[-3.12316288918358,51.48890646236118],[-3.1231628886423812,51.488906462334256],[-3.1231378985455005,51.48890482262204],[-3.1231378986863114,51.48890482261937],[-3.1231128665581007,51.48890345542756],[-3.123112866701217,51.488903455477036],[-3.1230878001676747,51.48890236122206],[-3.1230878003040394,51.488902361216624],[-3.12306270699865,51.48890154023184],[-3.123062707143147,51.488901540201226],[-3.123037594708379,51.488900992736625],[-3.123037594165074,51.48890099273654],[-3.123012470250881,51.48890071896638],[-3.123012470393083,51.488900718978876],[-3.1229873426524155,51.48890071897907],[-3.1229873427940924,51.488900718966185],[-3.1229622188798998,51.48890099273674],[-3.122962219025768,51.4889009927402],[-3.1229371065909985,51.48890154019765],[-3.122937106043642,51.48890154023165],[-3.1229120127382517,51.488902361216816],[-3.1229120128799805,51.48890236122189],[-3.1228869463464375,51.488903455477214],[-3.1228869464895554,51.4889034554274],[-3.1228619143613434,51.488904822619546],[-3.122861914502153,51.488904822621855],[-3.122836924405274,51.488906462334434],[-3.1228369245513155,51.48890646231117],[-3.1228119840967885,51.48890837404467],[-3.1228119835611365,51.48890837410447],[-3.1227871003480128,51.48891055728402],[-3.122787100487509,51.488910557300564],[-3.1227622820938747,51.48891301125382],[-3.1227622822368337,51.488913011240626],[-3.1227375362213055,51.4889157352201],[-3.1227375363498737,51.48891573516218],[-3.1227128702486096,51.48891872833832],[-3.122712870388098,51.488918728356424],[-3.122688291716301,51.488921989817435],[-3.1226882911865865,51.48892198989632],[-3.122663807432506,51.48892551865606],[-3.1226638075792863,51.48892551859782],[-3.1226394261967267,51.48892931357407],[-3.122639426314731,51.488929313587],[-3.1226151547320495,51.48893337362418],[-3.1226151548983028,51.48893337356544],[-3.1225910005064224,51.48893769742636],[-3.1225910006186224,51.48893769739429],[-3.122566970775521,51.48894228376254],[-3.122566970271648,51.48894228387845],[-3.12254307230087,51.488947131363744],[-3.1225430724192216,51.488947131350216],[-3.122519313596409,51.48895223846928],[-3.122519313730869,51.488952238453116],[-3.1224957012927024,51.48895760365016],[-3.1224957014368746,51.48895760361936],[-3.122472242575141,51.4889632252601],[-3.1224722426824836,51.48896322522718],[-3.122448944542552,51.48896910159971],[-3.1224489440544274,51.4889691017053],[-3.1224258137367444,51.488975231026195],[-3.1224258138624332,51.48897523100968],[-3.122402858409035,51.488981611405286],[-3.1224028585675305,51.488981611354106],[-3.122380084969561,51.488988240880644],[-3.1223800850613252,51.48898824084751],[-3.122357500256015,51.48899511748641],[-3.1223575004093154,51.48899511743911],[-3.1223351112755107,51.48900223909514],[-3.12233511077374,51.4890022392339],[-3.122312924136371,51.48900960374495],[-3.1223129242565935,51.48900960370452],[-3.12229094686873,51.48901720882065],[-3.122290947022416,51.48901720879531],[-3.1222691855787126,51.489025052199665],[-3.1222691857121783,51.489025052131666],[-3.122247646839933,51.48903313143545],[-3.1222476463188173,51.48903313165698],[-3.1222263365869103,51.48904144440637],[-3.1222263367366097,51.48904144436061],[-3.122205262628585,51.48904998801624],[-3.1222052627477423,51.4890499879169],[-3.122184430681242,51.489058759876805],[-3.122184430823138,51.48905875984323],[-3.1221638471454587,51.489067757435265],[-3.122163847265887,51.48906775738819],[-3.122143518246431,51.489076977871974],[-3.122143517774642,51.48907697806493],[-3.122123449612447,51.48908641863839],[-3.1221234497755566,51.48908641859241],[-3.1221036485768354,51.48909607637305],[-3.122103648626345,51.48909607632122],[-3.1220841204224237,51.48910594836858],[-3.1220841205465897,51.489105948338775],[-3.1220648712864394,51.489116031645054],[-3.122064871414881,51.4891160315699],[-3.122045906960638,51.48912632306374],[-3.1220459065046793,51.489126323257565],[-3.122027232640593,51.48913681981058],[-3.1220272328176635,51.48913681979699],[-3.122008855226179,51.48914751820502],[-3.122008855288558,51.48914751810784],[-3.1219907795652677,51.489158415113465],[-3.1219907797110027,51.48915841506093],[-3.1219730113631385,51.48916950734406],[-3.1219730114525452,51.489169507310386],[-3.1219555558930097,51.48918079149298],[-3.1219555554487277,51.489180791722355],[-3.121938418002092,51.48919226437307],[-3.1219384181059193,51.48919226431376],[-3.1219216039844078,51.48920392193204],[-3.1219216041037243,51.48920392184215],[-3.121905118428255,51.48921576087698],[-3.1219051185546345,51.48921576079961],[-3.121888966347265,51.48922777764477],[-3.1218889664009946,51.48922777757007],[-3.121873152581974,51.4892399685661],[-3.121873152237423,51.489239968857085],[-3.121857681634165,51.48925233029492],[-3.1218576817040673,51.48925233024479],[-3.1218425590196723,51.489264858354574],[-3.114899042399683,51.48605677058288],[-3.1150049069068424,51.4859690799918],[-3.1150049064174685,51.48596908034264],[-3.1151132056571416,51.48588255651336],[-3.1151132080691384,51.4858825544766],[-3.115223909113405,51.48579722379034],[-3.1152239087373,51.48579722431327],[-3.1153369777891164,51.48571311272574],[-3.1153369769044397,51.485713113267344],[-3.1154523795177087,51.48563024638728],[-3.1154523786824257,51.48563024701642],[-3.115570079699158,51.48554865007947],[-3.1155700789723673,51.485548650494565],[-3.1156900425435845,51.48546834835015],[-3.115690045653527,51.48546834674469],[-3.1158122352917577,51.48538936388878],[-3.1158122346659223,51.485389364124394],[-3.115936613098408,51.4853117245686],[-3.1159366120783356,51.485311724936345],[-3.116063141414769,51.48523545231917],[-3.116063140978034,51.485235452999376],[-3.1161917826686194,51.48516057055358],[-3.116191781429252,51.48516057064859],[-3.1163224963066476,51.48508710116837],[-3.116322499498258,51.485087099811714],[-3.1164552477880236,51.485015065718244],[-3.1164552468889246,51.485015066244294],[-3.1165899881047787,51.48494448942864],[-3.116589987235687,51.48494448963717],[-3.1167266803471296,51.484875391591174],[-3.1167266800005384,51.48487539195394],[-3.1168652833700126,51.484807793724464],[-3.116865282228303,51.48480779404626],[-3.117005753642602,51.48474171620896],[-3.117005756944968,51.484741714858444],[-3.117148053667636,51.48467717758325],[-3.117148052824668,51.484677177912744],[-3.1172921314702635,51.48461420080681],[-3.117292130477054,51.484614201041694],[-3.117437947168326,51.484552803280316],[-3.1174379463342023,51.48455280397567],[-3.117585456649667,51.48449300425642],[-3.117585455601803,51.484493004576585],[-3.1177346146281644,51.48443482110633],[-3.1177346182757577,51.48443481955567],[-3.1178853806393034,51.48437827010282],[-3.1178853797050965,51.48437827057874],[-3.1180376994355057,51.484323372313035],[-3.1180376983598133,51.48432337249039],[-3.1181915290787177,51.48427014212675],[-3.11819152823719,51.48427014240975],[-3.118346823095329,51.484218596159366],[-3.118346826607462,51.48421859518821],[-3.1185035383475244,51.484168748794445],[-3.1185035372745262,51.484168749125516],[-3.1186616181368407,51.48412061771664],[-3.1186616174945225,51.484120617948484],[-3.1188210193427826,51.484074216185014],[-3.118821018233411,51.484074216543256],[-3.1189816925232083,51.484029558549175],[-3.118981691643459,51.484029558664666],[-3.1191435894537407,51.48398665804059],[-3.1191435928702815,51.48398665730153],[-3.119306664924268,51.48394552715738],[-3.1193066641729534,51.48394552738782],[-3.119470860785721,51.48390618020213],[-3.1194708597766274,51.48390618041769],[-3.1196361309494245,51.48386862816857],[-3.1196361300082724,51.48386862828167],[-3.1198024254179884,51.48383288240416],[-3.1198024245896043,51.48383288249881],[-3.1199696935992725,51.483798953878456],[-3.1199696971260473,51.483798953067236],[-3.120137888826695,51.48376685208254],[-3.120137888041364,51.48376685230698],[-3.1203069511891406,51.48373658868549],[-3.1203069500254714,51.483736589096594],[-3.120476833135944,51.483708172049056],[-3.120476832310014,51.483708171958604],[-3.120647483668609,51.483681610141346],[-3.120647482641239,51.483681610549],[-3.1208188502717844,51.48365691204752],[-3.120818853979392,51.48365691149545],[-3.1209908857279394,51.483634083881796],[-3.1209908847516514,51.48363408375507],[-3.121163528223562,51.48361313392904],[-3.1211635273236804,51.483613134334426],[-3.121336729935994,51.483594068675735],[-3.1213367289353835,51.48359406876808],[-3.1215104379587273,51.4835768930808],[-3.121510436982372,51.48357689296506],[-3.121684599530442,51.48356161247924],[-3.121684603279583,51.48356161206066],[-3.121859166330076,51.48354823148058],[-3.121859165307898,51.483548231643425],[-3.1220340756920075,51.483536754991306],[-3.1220340747064514,51.483536754975056],[-3.1222092791717224,51.483527185745764],[-3.122209278170016,51.483527186094506],[-3.122384723359348,51.48351952720151],[-3.1223847223673653,51.483519527166045],[-3.122560354871392,51.483513780941415],[-3.122560358702441,51.4835137807035],[-3.1227361250490158,51.48350994894947],[-3.1227361240280573,51.483509948925224],[-3.1229119706927086,51.483508032755665],[-3.1229119697010863,51.4835080328458],[-3.123087843138425,51.483508032844504],[-3.1230878421431285,51.483508032757],[-3.1232636888077794,51.48350994892389],[-3.1232636926104633,51.48350994892451],[-3.123439458957039,51.48351378072844],[-3.1234394579456763,51.48351378094284],[-3.1236150904497015,51.48351952716461],[-3.1236150894952583,51.48351952720273],[-3.1237905346845896,51.48352718609327],[-3.123790533682885,51.483527185746986],[-3.1239657381481547,51.48353675497382],[-3.123965737162599,51.48353675499254],[-3.1241406475467084,51.483548231642196],[-3.1241406513346575,51.48354823183058],[-3.124315214374671,51.48356161246057],[-3.1246909494391693,51.48177935510791],[-3.124914864169476,51.481799000685804],[-3.1251275958725198,51.48091005376449],[-3.1248788064750714,51.48088822576617],[-3.124878807868464,51.48088822573829],[-3.124629446473458,51.48086911166267],[-3.1246294410624156,51.48086911139358],[-3.124379583577844,51.48085271713379],[-3.1246554541975105,51.47906335706372],[-3.124955271586159,51.47908302941233],[-3.124955278079158,51.479083029735236],[-3.1252545002533303,51.479105965738015],[-3.125254498581327,51.479105965771474]],[[-3.11603023341062,51.490924518480924],[-3.1159998489660112,51.49084841116869],[-3.115999848991216,51.49084841116045],[-3.11597159697893,51.49077198439516],[-3.1159715967809234,51.49077198441811],[-3.1159454857958044,51.4906952614792],[-3.115945486101434,51.49069526144354],[-3.1159215240884524,51.49061826570848],[-3.115921524132602,51.49061826570568],[-3.1158997183793784,51.49054102062656],[-3.11589971805408,51.49054102067334],[-3.1158800751909057,51.49046354977693],[-3.1158800754735125,51.490463549745975],[-3.1158626014752366,51.49038587663837],[-3.115862601428121,51.49038587663812],[-3.1158473016057537,51.49030802497668],[-3.115847301382682,51.49030802496144],[-3.1158341803862024,51.49023001845946],[-3.115834180374166,51.49023001843024],[-3.11582324218974,51.49015188085226],[-3.115823242153614,51.49015188086608],[-3.1158144901008114,51.49007363601394],[-3.1158144904712857,51.49007363604018],[-3.1158079272044894,51.48999530775293],[-3.1158079269320273,51.489995307735214],[-3.1158035544404608,51.48991691986576],[-3.1158013740335626,51.489838496298226],[-3.1172410815163127,51.48983073228516],[-3.117242827808433,51.4898934711206],[-3.1172463277817557,51.48995618137096],[-3.117246327999725,51.48995618138512],[-3.117251580578711,51.49001884395108],[-3.117251580282332,51.49001884393008],[-3.1172585838817364,51.490081439726744],[-3.1172585839106377,51.4900814397157],[-3.1172673364045687,51.49014394967192],[-3.1172673364141996,51.490143949695295],[-3.1172778351446326,51.49020635476976],[-3.11727783532309,51.49020635478194],[-3.117290077098736,51.49026863596315],[-3.1172900771364276,51.490268635963346],[-3.1173040582349643,51.49033077428085],[-3.1173040580088793,51.490330774305626],[-3.117319774179185,51.49039275083372],[-3.1173197744394208,51.4903927507963],[-3.1173372208993286,51.49045454665038],[-3.117337220864006,51.49045454665262],[-3.1173563923070198,51.490516143011504],[-3.1173563920625176,51.49051614304003],[-3.1173772826562978,51.49057752114234],[-3.1173772828147,51.49057752112397],[-3.117399886201081,51.49063866226802],[-3.117399886180915,51.490638662274606],[-3.1174241954818522,51.490699547837146],[-3.11603023341062,51.490924518480924]],[[-3.1213468992265154,51.49229067669012],[-3.121277504154758,51.49227228740939],[-3.1212775045340964,51.492272287616814],[-3.121208634202072,51.49225314506824],[-3.1212086341649323,51.49225314506108],[-3.121140309559887,51.49223325507205],[-3.121140309446783,51.492233255015606],[-3.1210725513850677,51.49221262364493],[-3.121072551323344,51.49221262363596],[-3.121005380445919,51.4921912571697],[-3.121005380351999,51.49219125707979],[-3.120938817124445,51.49216916202709],[-3.120938817485146,51.49216916214559],[-3.120872882179661,51.49214634524281],[-3.1208728821258305,51.49214634531886],[-3.120807594830251,51.49212281351275],[-3.1208075947112763,51.49212281340092],[-3.1207429753200504,51.49209857385991],[-3.1207429753013223,51.49209857383814],[-3.120679043497546,51.49207363394804],[-3.1206790434385288,51.49207363391894],[-3.120615818698462,51.49204800127738],[-3.120615818798514,51.49204800125258],[-3.1205533203825335,51.4920216836704],[-3.1205533202888556,51.49202168377389],[-3.1204915672325337,51.49199468926672],[-3.1204915670722033,51.491994689255655],[-3.12043057819074,51.49196702604674],[-3.121287048135197,51.49124452358949],[-3.1212469109877268,51.49122564156378],[-3.1212469109737055,51.491225641439584],[-3.121207307859113,51.49120632498748],[-3.121207307785014,51.49120632498492],[-3.1211682507638447,51.49118657999031],[-3.1211682508375502,51.49118658005273],[-3.1211297518055017,51.49116641253228],[-3.1211297518847836,51.491166412472985],[-3.1210918225727364,51.49114582857053],[-3.1210918226890687,51.49114582871859],[-3.121054474645074,51.49112483470513],[-3.1210544744888247,51.491124834622354],[-3.1210177190961184,51.49110343689045],[-3.121017719049255,51.49110343687145],[-3.12098156750225,51.491081641940816],[-3.1209815676175894,51.49108164194156],[-3.1209460309279033,51.49105945645348],[-3.120946030929099,51.4910594565255],[-3.1209111199195307,51.49103688723718],[-3.1209111198891057,51.49103688720791],[-3.120876845196664,51.49101394099439],[-3.120876845237184,51.49101394100306],[-3.120843217301094,51.49099062485531],[-3.1208432171964877,51.49099062482079],[-3.1208102462611644,51.490966945840114],[-3.120810246336311,51.490966945783406],[-3.120777942445398,51.49094291118517],[-3.1207779425423574,51.49094291123119],[-3.120746315532713,51.49091852833738],[-3.1207463153554893,51.4909185283992],[-3.120715374860212,51.490893804634595],[-3.1207153748313936,51.49089380451962],[-3.120685130279793,51.490868747417515],[-3.120685130348136,51.49086874747131],[-3.120655590947763,51.49084336466592],[-3.1206555909344385,51.49084336470635],[-3.1206267656831015,51.49081766392916],[-3.1206267656219864,51.49081766389111],[-3.1205986633017173,51.490791652970834],[-3.120598663446852,51.49079165301341],[-3.1205712926149376,51.490765339876],[-3.1205712925838767,51.49076533985144],[-3.1205446615788777,51.49073873251071],[-3.1205446615556296,51.490738732502905],[-3.1205187784883432,51.4907118390643],[-3.1205187785412876,51.49071183906742],[-3.120493651294799,51.49068466772427],[-3.120493651205875,51.490684667700926],[-3.1204692874340236,51.49065722672882],[-3.120469287560553,51.4906572267718],[-3.120445694681971,51.49062952453235],[-3.120445694584439,51.49062952449325],[-3.120422879787012,51.49060156942286],[-3.1204228797766604,51.49060156945074],[-3.1204008500070888,51.490573370066166],[-3.1204008501192093,51.49057337007174],[-3.1203796120874627,51.49054493496459],[-3.120379612081309,51.49054493494725],[-3.1203591722561628,51.49051627277826],[-3.1203591721336577,51.490516272775416],[-3.1203395367397024,51.49048739227452],[-3.1203395367476534,51.490487392307905],[-3.1203207117637506,51.490458302274185],[-3.1203207118789655,51.490458302245635],[-3.120302703039805,51.49042901154176],[-3.1203027029713355,51.49042901150654],[-3.120285515761425,51.49039952905314],[-3.1202855158131957,51.490399529113894],[-3.120269155463867,51.49036986389325],[-3.120269155331822,51.49036986388124],[-3.120253626827214,51.490340024928024],[-3.1202536268013996,51.490340024888184],[-3.1202389348709856,51.49031002129311],[-3.1202389349826998,51.4903100213242],[-3.120225084098288,51.49027986222847],[-3.1202250841193138,51.49027986222083],[-3.1202120784995513,51.490249556810504],[-3.1202120784577825,51.49024955682392],[-3.120199922062161,51.49021911432992],[-3.120188618602584,51.49018854402283],[-3.1201886185233847,51.490188544032016],[-3.120178171420885,51.49015785522975],[-3.1201781715431354,51.49015785521547],[-3.120168583989079,51.49012705726523],[-3.120168584006736,51.490127057264104],[-3.120159858919527,51.490096159546326],[-3.1201598587894095,51.49009615956505],[-3.1201519988245496,51.49006517149004],[-3.1201519989375917,51.49006517147765],[-3.1201450064884613,51.49003410248753],[-3.1201450064696132,51.49003410248743],[-3.1201388836640893,51.49000296204481],[-3.1201388835748602,51.49000296203871],[-3.1201336322764344,51.48997175962865],[-3.1201336322716196,51.489971759616964],[-3.1201292540782952,51.48994050474506],[-3.120129254063847,51.48994050475058],[-3.1201257503070075,51.48990920693735],[-3.1201257504551982,51.489909206947836],[-3.120123122200176,51.48987787572875],[-3.120123122091192,51.48987787572166],[-3.1201213701372676,51.48984652063777],[-3.1201204950118195,51.48981515124264],[-3.1215602010223513,51.48980733421323],[-3.1215606390767223,51.489823018906115],[-3.1215615155486947,51.48983869643675],[-3.121561515603186,51.48983869644028],[-3.121562830222075,51.489854362033846],[-3.1215628301479796,51.4898543620286],[-3.1215645825156755,51.48987001091393],[-3.1215667721061418,51.48988563832057],[-3.1215693982410566,51.489901239499645],[-3.121569398285668,51.489901239502686],[-3.121572460167846,51.48991680968699],[-3.121575956876788,51.48993234413994],[-3.121575956820267,51.48993234414613],[-3.121579887272608,51.48994783813637],[-3.121579887337667,51.489947838126994],[-3.12158425034557,51.489963286933566],[-3.1215890445718872,51.48997868585193],[-3.121589044510764,51.489978685859064],[-3.1215942685134,51.489994030197984],[-3.1215942685529976,51.48999403019339],[-3.1215999207319176,51.49000931527822],[-3.1216059993609577,51.49002453645504],[-3.121605999381838,51.49002453644833],[-3.121612502619629,51.490039689077],[-3.12161942847035,51.49005476854761],[-3.1216194284144945,51.49005476853206],[-3.121626774789338,51.49006977024404],[-3.121626774802244,51.490069770263965],[-3.1216345394542895,51.490084689650644],[-3.1216345395203158,51.49008468965665],[-3.121642720084347,51.49009952217276],[-3.1216427200584596,51.490099522142394],[-3.121651314041934,51.49011426327075],[-3.1216513140761615,51.490114263288355],[-3.121660318862948,51.490128908537905],[-3.121660318805344,51.49012890855219],[-3.121669731652724,51.49014345346277],[-3.1216697316487556,51.490143453446066],[-3.1216795496889755,51.490157893586456],[-3.1216795497502328,51.490157893587885],[-3.1216897699934347,51.49017222455867],[-3.1217003893300093,51.490186442003704],[-3.1217003892739474,51.49018644200092],[-3.1217114044629533,51.49020054157264],[-3.121711404468126,51.49020054155868],[-3.121722812157284,51.4902145189701],[-3.1217228122060496,51.49021451898964],[-3.1217346089216598,51.49022836998253],[-3.121734608858393,51.49022836996103],[-3.121746791006176,51.49024209031733],[-3.1217467910506382,51.490242090329],[-3.1217593549209544,51.49025567586807],[-3.1217593548944853,51.4902556758665],[-3.121772296660111,51.490269122450705],[-3.121785612390865,51.49028242598745],[-3.1217856124063887,51.49028242599973],[-3.1217992980233378,51.49029558242865],[-3.1217992979507754,51.49029558240736],[-3.1218133492960285,51.49030858772562],[-3.121813349326579,51.490308587744664],[-3.1218277621212653,51.490321437989465],[-3.121827762127934,51.49032143796925],[-3.121842531980825,51.49033412922642],[-3.121842531946653,51.49033412919952],[-3.1218576543586725,51.49034665760349],[-3.1218576543730814,51.490346657660965],[-3.121873124740277,51.4903590193948],[-3.1218731248288862,51.4903590193639],[-3.1218889384364656,51.49037121066113],[-3.1218889383879858,51.49037121063812],[-3.121905090419266,51.49038322778654],[-3.121905090381692,51.490383227814895],[-3.121921575918143,51.49039506715371],[-3.121921575970449,51.49039506717097],[-3.121938389990167,51.490406725092676],[-3.121938389969902,51.49040672508834],[-3.1219555273506154,51.49041819804245],[-3.121955527365826,51.490418198057085],[-3.121972982887882,51.49042948254832],[-3.121972982887285,51.49042948251232],[-3.1219907512321527,51.49044057510334],[-3.1219907511744776,51.490440575102966],[-3.1220088269307547,51.490451472415366],[-3.1220088269541906,51.49045147242486],[-3.122027204616099,51.49046217113816],[-3.1220272046942195,51.49046217117956],[-3.1220458786645944,51.4904726680341],[-3.1220458786064302,51.49047266796008],[-3.122064843193707,51.490482959759774],[-3.122064843154066,51.49048295978943],[-3.122084092584309,51.49049304339895],[-3.1220840925474582,51.490493043367756],[-3.1221036209553326,51.490502915715375],[-3.1221036209923816,51.490502915716654],[-3.122123422430163,51.49051257379423],[-3.1221234224371757,51.490512573856336],[-3.122143490874729,51.490522014722096],[-3.121287048049032,51.49124452354496],[-3.12132770699801,51.49126296539316],[-3.1213277071048986,51.49126296540053],[-3.1213688754711626,51.491280961451054],[-3.121368875533624,51.49128096138206],[-3.12141054077412,51.491298506153086],[-3.1214105407074277,51.49129850616962],[-3.121452690132227,51.49131559431775],[-3.121452690171563,51.49131559433714],[-3.121495310940912,51.491332220655465],[-3.1214953109534016,51.49133222066998],[-3.121538390083642,51.491348380093754],[-3.1215383901629568,51.491348380168304],[-3.1215819145325985,51.49136406777399],[-3.1215819145684844,51.491364067723296],[-3.1216258709151474,51.49137927873227],[-3.121625870674689,51.49137927865327],[-3.121670245607132,51.491394008434675],[-3.121670245669754,51.491394008494616],[-3.1217150256738493,51.49140825255785],[-3.121715025715002,51.49140825256383],[-3.121760197147747,51.49142200656977],[-3.1217601972231437,51.491422006607394],[-3.1218057463246343,51.491435266365635],[-3.121805746349399,51.4914352663704],[-3.1218516592428283,51.49144802784201],[-3.1218516589899434,51.49144802770374],[-3.1218979216846394,51.49146028700407],[-3.1213468992265154,51.49229067669012]],[[-3.1270715194339,51.490699520484654],[-3.1270457397479006,51.4907437444598],[-3.1270457399048537,51.49074374418977],[-3.1270187277500283,51.49078768055551],[-3.1270187274102397,51.490787680919794],[-3.1269904909940287,51.49083131628641],[-3.1269904912678768,51.490831316077],[-3.1269610392044913,51.490874637158534],[-3.126961039277041,51.49087463692034],[-3.126930380535774,51.49091763051773],[-3.126930380269136,51.49091763086375],[-3.1268985241699476,51.490960283876106],[-3.1268985243392198,51.49096028362668],[-3.1268654805998297,51.49100258306524],[-3.126865480329137,51.49100258334626],[-3.1268312589976555,51.491044516320414],[-3.126831259112155,51.491044516139354],[-3.1267958706232903,51.49108606987908],[-3.1267958710682766,51.491086069652496],[-3.1267593262006255,51.49112723150273],[-3.1267593258098074,51.49112723185777],[-3.1267216356768697,51.49116798927003],[-3.1267216357562595,51.49116798894393],[-3.1266828118558605,51.49120832950714],[-3.126682811563559,51.49120832984166],[-3.126642865701497,51.49124824126254],[-3.1266428659145866,51.491248241140056],[-3.1266018102697677,51.491287711265535],[-3.1266018099770903,51.491287711525906],[-3.126559657043111,51.491326728326314],[-3.1265596574708097,51.491326728064756],[-3.126516420100905,51.491365279661885],[-3.1265164203361158,51.49136527943914],[-3.1264721116982446,51.4914033540866],[-3.127629567019617,51.49193794987259],[-3.1275690789944,51.49198806524978],[-3.127569079282983,51.491988064838715],[-3.1275071992551244,51.492037513555665],[-3.1275071985604477,51.49203751407679],[-3.127443945351447,51.492086281058064],[-3.1274439458975967,51.49208628075359],[-3.127379338796598,51.49213435115558],[-3.1273793392901337,51.49213435083857],[-3.1273133979760166,51.49218171001588],[-3.1273133974205543,51.492181710297345],[-3.1272461419619515,51.49222834381029],[-3.127246142383247,51.492228343576784],[-3.1271775932804973,51.49227423722874],[-3.1271775925331267,51.49227423771584],[-3.1271077706463286,51.49231937751215],[-3.1271077709949653,51.4923193771557],[-3.127036697615953,51.492363749356045],[-3.1260274573846396,51.491722700025946],[-3.126080762419065,51.491689421334755],[-3.126080762157584,51.49168942160209],[-3.1261331286245833,51.49165556721364],[-3.126133129185106,51.491655566848316],[-3.1261845411157427,51.49162114706729],[-3.1261845407997706,51.49162114724241],[-3.126234982548844,51.49158617256426],[-3.1262349829654354,51.49158617235315],[-3.126284439157503,51.49155065342476],[-3.126284438787349,51.49155065366252],[-3.126332894370691,51.491514601313106],[-3.12633289396108,51.49151460154146],[-3.1263803341762086,51.49147802675453],[-3.1263803346972145,51.49147802636369],[-3.126426745076906,51.49144094027139],[-3.1264267448604612,51.491440940579686],[-3.1264721112881437,51.49140335448805],[-3.1253146829048255,51.490868747365106],[-3.125344222302195,51.49084336455785],[-3.125344222145396,51.49084336470635],[-3.125373047396733,51.49081766392916],[-3.1253730471116006,51.49081766410353],[-3.1254011494378604,51.490791653187],[-3.125401149632982,51.49079165301341],[-3.125428520464897,51.490765339876],[-3.1254285203228345,51.49076533995765],[-3.125455151330829,51.49073873261878],[-3.1254551515257023,51.49073873239576],[-3.1254810345899844,51.490711838957154],[-3.1254810345370605,51.49071183917456],[-3.125506161786538,51.49068466783141],[-3.1255061620470865,51.49068466759472],[-3.1255305258159414,51.49065722662074],[-3.1255305255192813,51.4906572267718],[-3.1255541183978632,51.49062952453235],[-3.125554118321533,51.49062952465304],[-3.125576933123452,51.490601569584506],[-3.125576933303917,51.49060156939717],[-3.125598963071997,51.49057337001259],[-3.1255989629591348,51.49057337017888],[-3.1256202009938754,51.490544935071725],[-3.125620201171645,51.49054493484104],[-3.1256406409937982,51.49051627267019],[-3.12564064094543,51.49051627282899],[-3.125660276340881,51.490487392328085],[-3.125660276158316,51.49048739246769],[-3.125679101146711,51.49045830243585],[-3.125679101373237,51.49045830219299],[-3.125697110210906,51.490429011487244],[-3.1256971101062656,51.49042901166726],[-3.1257142973206644,51.490399529213846],[-3.1270715194339,51.490699520484654]]]]} \ No newline at end of file diff --git a/benchmarks/run.sh b/benchmarks/run.sh index 3102024..0f0412e 100755 --- a/benchmarks/run.sh +++ b/benchmarks/run.sh @@ -3,7 +3,7 @@ set -e export RUST_BACKTRACE=1 -export RUST_LOG=trace +export RUST_LOG=debug PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" diff --git a/crates/total-viewsheds/Cargo.toml b/crates/total-viewsheds/Cargo.toml index a3b8c35..28bd1f8 100644 --- a/crates/total-viewsheds/Cargo.toml +++ b/crates/total-viewsheds/Cargo.toml @@ -18,9 +18,10 @@ memchr = "2.8.0" serde_json.workspace = true rusqlite = { version = "0.38.0", features = ["bundled"] } rayon = "1.12.0" -tracing = { version = "0.1.41" } -tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } +tracing.workspace = true +tracing-subscriber.workspace = true tvs-lib = { path = "../tvs-lib", version = "0.1.0" } +viewshed-reconstructor = { path = "../viewshed-reconstructor", version = "0.1.0" } [dev-dependencies] tempfile = "3.20.0" diff --git a/crates/total-viewsheds/src/compute/area_of_interest.rs b/crates/total-viewsheds/src/compute/area_of_interest.rs index 9bbcdf4..b0b9a20 100644 --- a/crates/total-viewsheds/src/compute/area_of_interest.rs +++ b/crates/total-viewsheds/src/compute/area_of_interest.rs @@ -5,7 +5,7 @@ use color_eyre::Result; use geo::Contains as _; /// `Pruner` -pub struct Pruner { +pub(crate) struct Pruner { /// Width of the DEM in points width: u32, /// The DEM coordinates for the Area of Interest. @@ -14,12 +14,12 @@ pub struct Pruner { impl Pruner { /// Instantiate. - pub const fn new(width: u32, polygon: geo::Polygon) -> Self { + pub(crate) const fn new(width: u32, polygon: geo::Polygon) -> Self { Self { width, polygon } } /// Convert user-provided lon/lat coordinates to a polygon. - pub fn lonlat_coords_to_polygon( + pub(crate) fn lonlat_coords_to_polygon( points: Vec<(f32, f32)>, metadata: &tvs_lib::metadata::MetaData, ) -> Result { @@ -41,7 +41,7 @@ impl Pruner { } /// Can the given DEM ID be ignored in computations. - pub fn is_prunable(&self, dem_id: i64) -> bool { + pub(crate) fn is_prunable(&self, dem_id: i64) -> bool { let dem_coord = self.convert_dem_id_to_coord(dem_id); !self.polygon.contains(&dem_coord.0) } @@ -52,7 +52,7 @@ impl Pruner { reason = "We're only dealing with a max of the DEM's width" )] /// Convert a DEM 1D index to a 2D coordinate. - pub fn convert_dem_id_to_coord(&self, dem_id: i64) -> tvs_lib::dem::Coordinate { + pub(crate) fn convert_dem_id_to_coord(&self, dem_id: i64) -> tvs_lib::dem::Coordinate { let x = dem_id.rem_euclid(self.width.into()) as f64; let y = dem_id.div_euclid(self.width.into()) as f64; tvs_lib::dem::Coordinate(geo::coord! {x: x, y: y}) diff --git a/crates/total-viewsheds/src/compute/kernel.rs b/crates/total-viewsheds/src/compute/kernel.rs index 3522e43..26ce83b 100644 --- a/crates/total-viewsheds/src/compute/kernel.rs +++ b/crates/total-viewsheds/src/compute/kernel.rs @@ -7,7 +7,7 @@ use geo::HasDimensions as _; use itertools::izip; /// The data output by a single angle. -pub struct OutputData { +pub(crate) struct OutputData { /// The visibile surface area. pub surfaces: Vec, /// The longest lines of sight. @@ -57,7 +57,7 @@ const DEFAULT_UNROLL: usize = const { /// `kernel` will calculate the longest line of sight heatmap for a given angle and elevation map /// assuming that the maximum line of sight is `max_los` -pub fn kernel( +pub(crate) fn kernel( db_worker: &crate::storage::worker::Worker, elevation_map: &[i16], output: &mut OutputData, diff --git a/crates/total-viewsheds/src/compute/los.rs b/crates/total-viewsheds/src/compute/los.rs index fbda642..404fe68 100644 --- a/crates/total-viewsheds/src/compute/los.rs +++ b/crates/total-viewsheds/src/compute/los.rs @@ -1,6 +1,7 @@ /// `LineOfSight` abstracts the implementation of line of sight calculations to /// any "carry through" that can be materialized into a (f32, f32). -pub trait LineOfSight, LOS: Angle + PrefixMax + Accumulate> { +pub(crate) trait LineOfSight, LOS: Angle + PrefixMax + Accumulate> +{ /// `line_of_sight` calculates a line of sight for the given `pov_height` /// and outputs a triple of the surface area, longest line of sight in meters /// and a vector of bools of which @@ -9,7 +10,7 @@ pub trait LineOfSight, LOS: Angle + PrefixMax + Accumul /// `Angle` abstracts the angle calculation between a pov and all the elevation data within /// its band of sight -pub trait Angle { +pub(crate) trait Angle { /// `calculate_angles` calculates the angle from the `pov_height` to a given elevation fn calculate_angles( pov_height: f32, @@ -23,7 +24,7 @@ pub trait Angle { /// `Accumulate` accumulates the surface area visible and longest line of sight /// in a pair of (f32, f32). `Accumulate` doesn't care about the implementation details /// of accumulation so long as the `Output` type can be materialized to (f32, f32) -pub trait Accumulate> { +pub(crate) trait Accumulate> { /// `accumulate` accumulates the surface area using the distances by comparing /// whether a point at a distance is visible (angle > prefix) /// If `output_sector` is true, it should output a bitmap of which distances are visible @@ -38,7 +39,7 @@ pub trait Accumulate> { } /// `PrefixMax` calculates the prefix maximum of the given angles -pub trait PrefixMax { +pub(crate) trait PrefixMax { /// `prefix_max` calculates the prefix max of the fn prefix_max(highest: f32, angles_in: &[f32], angles_out: &mut [f32]); } diff --git a/crates/total-viewsheds/src/compute/rotation.rs b/crates/total-viewsheds/src/compute/rotation.rs index b291b85..dcb17ed 100644 --- a/crates/total-viewsheds/src/compute/rotation.rs +++ b/crates/total-viewsheds/src/compute/rotation.rs @@ -14,7 +14,7 @@ use std::rc::Rc; reason = "rotation should not be out of bounds" )] #[expect(clippy::expect_used, reason = "invriants broken if options not none")] -pub fn lines( +pub(crate) fn lines( elevs: &[i16], max_los: usize, angle: f64, diff --git a/crates/total-viewsheds/src/compute/rotator.rs b/crates/total-viewsheds/src/compute/rotator.rs index b3b9190..cb42478 100644 --- a/crates/total-viewsheds/src/compute/rotator.rs +++ b/crates/total-viewsheds/src/compute/rotator.rs @@ -10,7 +10,7 @@ /// * 180°: (`width_index` - x, `width_index` - y) // * 270°: (y, `width_index` - x) #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Quadrant { +pub(crate) enum Quadrant { /// Top-right quadrant: 0° to 90° TopRight, /// Top-left quadrant: 90° to 180° @@ -55,7 +55,7 @@ impl From for Quadrant { } /// Rotator struct. -pub struct Rotator { +pub(crate) struct Rotator { /// The centre of the DEM in relative coordinates. centre: (f64, f64), /// The index of the last point in a row/column of the DEM. @@ -72,7 +72,7 @@ pub struct Rotator { impl Rotator { /// Instantiate. - pub fn new(angle: f64, width: isize) -> Self { + pub(crate) fn new(angle: f64, width: isize) -> Self { assert!( (0.0f64..360.0f64).contains(&angle), "Angle {angle} must be in range 0..360" @@ -109,7 +109,7 @@ impl Rotator { /// we'd just make the angle negative here. But seeing as the rest of the maths involved in /// skew rotation is based in positive angles it's better to achieve the same rotation /// through a positive but inverted angle. - pub fn invert_angle(angle: f64) -> f64 { + pub(crate) fn invert_angle(angle: f64) -> f64 { if angle > 0.0f64 { 360.0f64 - angle } else { @@ -122,7 +122,7 @@ impl Rotator { /// /// Note that each shear step _must_ be rounded. This is essential to achieving a bijective /// mapping. - pub fn rotate(&self, x: isize, y: isize) -> (isize, isize) { + pub(crate) fn rotate(&self, x: isize, y: isize) -> (isize, isize) { let (x_centre, y_centre) = self.centre; let (quadrant_x, quadrant_y) = self.rotate_to_quadrant(x, y); diff --git a/crates/total-viewsheds/src/compute/unrolled_los.rs b/crates/total-viewsheds/src/compute/unrolled_los.rs index b77ddc7..de4ab7c 100644 --- a/crates/total-viewsheds/src/compute/unrolled_los.rs +++ b/crates/total-viewsheds/src/compute/unrolled_los.rs @@ -27,7 +27,7 @@ fn generate_distances(max_los: usize, refraction: f32, scale: f32) -> (Vec, /// Unroll holds an unrolled heatmap and unrolled longest line of sight calculation /// Since in Line of Sight-land max/addition are commutative, then Unroll will be materialized /// into (f32, f32) -pub struct UnrollVector +pub(crate) struct UnrollVector where [(); UNROLL * VECTOR_WIDTH]:, { @@ -40,7 +40,7 @@ where } /// `UnrolledLOS` implements an Unrolled `LineOfSight` calculation -pub struct UnrolledVectorLos { +pub(crate) struct UnrolledVectorLos { /// `angles` holds a buffer for line of sight angles to be put into /// which is exactly `max_los+1` long angles: Vec, @@ -81,7 +81,7 @@ where impl UnrolledVectorLos { /// `new` initializes a new `UnrolledLOS`, and precalculates all the distances /// and earth curvature adjustments - pub fn new(max_los: usize, refraction: f32, scale: f32) -> Self { + pub(crate) fn new(max_los: usize, refraction: f32, scale: f32) -> Self { assert_eq!( max_los % VECTOR_WIDTH, 0, diff --git a/crates/total-viewsheds/src/compute/vector_intrinsics.rs b/crates/total-viewsheds/src/compute/vector_intrinsics.rs index b7e4183..a854ee1 100644 --- a/crates/total-viewsheds/src/compute/vector_intrinsics.rs +++ b/crates/total-viewsheds/src/compute/vector_intrinsics.rs @@ -7,7 +7,7 @@ use std::simd::{Mask, Simd, f32x4}; /// `VectorMax` performs an element-wise SIMD max of floats, allowing for architecture /// specific implementations -pub trait VectorMax { +pub(crate) trait VectorMax { /// `max` computes an element-wise maximum from lhs and rhs, assuming neither contain NaNs /// or -0.0 fn max(lhs: Simd, rhs: Simd) -> Simd; @@ -15,7 +15,7 @@ pub trait VectorMax { /// `VectorGreater` performs a SIMD greater than of floats, allowing for architecture /// specific implementations -pub trait VectorGreater { +pub(crate) trait VectorGreater { /// gt computes an element-wise maximum from lhs and rhs, assuming neither contain NaNs /// or -0.0 fn gt(lhs: Simd, rhs: Simd) -> Mask; @@ -23,7 +23,7 @@ pub trait VectorGreater { /// `VectorLos` is an implementation of the internals of `PrefixMax`, `Angle`, and `Accumulate` /// for Portable SIMD -pub struct VectorLos; +pub(crate) struct VectorLos; impl VectorMax for VectorLos { #[inline] @@ -333,7 +333,7 @@ impl Angle for VectorLos { /// `DEFAULT_VECTOR_LENGTH` determines the CPU Kernel's default vector length based off /// the architecture that the binary is built for -pub const DEFAULT_VECTOR_LENGTH: usize = const { +pub(crate) const DEFAULT_VECTOR_LENGTH: usize = const { if cfg!(target_feature = "avx512f") { 16 } else if cfg!(any(test, feature = "ring_data")) { diff --git a/crates/total-viewsheds/src/config.rs b/crates/total-viewsheds/src/config.rs index a249c07..b7fd5a5 100644 --- a/crates/total-viewsheds/src/config.rs +++ b/crates/total-viewsheds/src/config.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; #[command( about = "Generate _all_ the viewsheds for a given Digital Elevation Model, therefore the total viewsheds." )] -pub struct Config { +pub(crate) struct Config { #[command(subcommand)] /// The subcommand. pub command: Commands, @@ -18,7 +18,7 @@ pub struct Config { /// CLI subcommand. #[derive(clap::Subcommand, Debug)] -pub enum Commands { +pub(crate) enum Commands { /// Run main computations. Compute(Compute), /// Reconstruct a viewshed. @@ -35,7 +35,7 @@ pub enum Commands { /// Arguments to the `compute` subcommand. #[derive(clap::Parser, Debug, Default)] -pub struct Compute { +pub(crate) struct Compute { // TODO: make this "reserved rings" and add support to the kernel so that the user can get // feedback of the actual number needed. // @@ -154,7 +154,7 @@ pub struct Compute { /// Arguments to the `viewshed` subcommand. #[derive(clap::Parser, Debug)] -pub struct Viewshed { +pub(crate) struct Viewshed { /// Path or directory where viewshed DB was saved. #[arg(value_name = "Path to existing database")] pub db_path: std::path::PathBuf, @@ -170,7 +170,7 @@ pub struct Viewshed { /// Arguments to the `post-process` subcommand. #[derive(clap::Parser, Debug)] -pub struct PostProcess { +pub(crate) struct PostProcess { /// Directory where viewshed DBs were saved. #[arg(value_name = "Path to existing databases")] pub db_dir: std::path::PathBuf, @@ -211,7 +211,7 @@ fn is_perfect_square(argument: &str) -> Result { /// Where to run the computations. #[derive(clap::ValueEnum, Clone, Debug, Default)] -pub enum Backend { +pub(crate) enum Backend { /// Optimised cache-efficient CPU kernel #[default] CPU, @@ -221,7 +221,7 @@ pub enum Backend { /// Which calculations to process. #[derive(clap::ValueEnum, Clone, Debug, PartialEq, Eq)] -pub enum Process { +pub(crate) enum Process { /// Calculate everything. All, /// Compute all the polar segments saving them to disk so that they can be used to later @@ -231,7 +231,7 @@ pub enum Process { /// Where to run the computations. #[derive(clap::ValueEnum, Clone, Debug, Copy, Default)] -pub enum HeatmapNormalisation { +pub(crate) enum HeatmapNormalisation { /// Just scale between 0 and 1 UnitScale, /// Scale between 0 and 1 with an exponential factor. diff --git a/crates/total-viewsheds/src/dump_usage.rs b/crates/total-viewsheds/src/dump_usage.rs index 55bc641..1527ac3 100644 --- a/crates/total-viewsheds/src/dump_usage.rs +++ b/crates/total-viewsheds/src/dump_usage.rs @@ -5,7 +5,7 @@ use color_eyre::Result; /// main dump usage function #[expect(clippy::print_stdout, reason = "We need to output the usage.")] -pub fn dump_full_usage_for_readme() -> Result<()> { +pub(crate) fn dump_full_usage_for_readme() -> Result<()> { use clap::CommandFactory as _; let mut command = crate::config::Config::command(); diff --git a/crates/total-viewsheds/src/los_pack.rs b/crates/total-viewsheds/src/los_pack.rs index 3916bab..287e810 100644 --- a/crates/total-viewsheds/src/los_pack.rs +++ b/crates/total-viewsheds/src/los_pack.rs @@ -10,7 +10,7 @@ const U10_MAX: u32 = (1 << 10) - 1; #[derive(Default, Debug, Clone, Copy)] /// Line of sight data that can be packed within 32 bits. -pub struct LineOfSightPacked(f32); +pub(crate) struct LineOfSightPacked(f32); #[expect( clippy::big_endian_bytes, @@ -21,7 +21,7 @@ impl LineOfSightPacked { /// /// f32 is better than u32 because I imagine that floats are just more widely recognised in general. /// At the end of the day, they're just bits that are neither valid f32 nor u32. - pub fn new(distance: u32, angle: u16) -> Result { + pub(crate) fn new(distance: u32, angle: u16) -> Result { if distance > U22_MAX { color_eyre::eyre::bail!("{} is greater than u22 max {U22_MAX}", distance); } @@ -37,7 +37,7 @@ impl LineOfSightPacked { /// create a packed line of sight without checking if the values fit within /// the packed bit widths - pub unsafe fn new_unchecked(distance: u32, angle: u16) -> Self { + pub(crate) unsafe fn new_unchecked(distance: u32, angle: u16) -> Self { let angle_u32 = u32::from(angle); let distance_bits = (distance & U22_MAX) << 10u32; @@ -54,25 +54,25 @@ impl LineOfSightPacked { } /// Distance in meters from the point of view to the visible point. - pub const fn distance(self) -> u32 { + pub(crate) const fn distance(self) -> u32 { (self.to_u32() >> 10u32) & U22_MAX } /// The angle of the line of sight from the point of view. #[expect(clippy::as_conversions, reason = "(self & 2^10) < 2^16")] - pub const fn angle(self) -> u16 { + pub(crate) const fn angle(self) -> u16 { (self.to_u32() & U10_MAX) as u16 } /// Get the raw f32 value. It doesn't represent any useful data, it's just the f32 view of the /// packed data. - pub const fn as_f32(self) -> f32 { + pub(crate) const fn as_f32(self) -> f32 { self.0 } /// calculate the longer packed line of sight, and when distances are equal /// choose the smaller angle - pub const fn max(self, rhs: Self) -> Self { + pub(crate) const fn max(self, rhs: Self) -> Self { if rhs.distance() > self.distance() { return rhs; } diff --git a/crates/total-viewsheds/src/main.rs b/crates/total-viewsheds/src/main.rs index e39f937..8f281b4 100644 --- a/crates/total-viewsheds/src/main.rs +++ b/crates/total-viewsheds/src/main.rs @@ -2,12 +2,11 @@ #![feature(portable_simd)] #![feature(specialization)] #![feature(mpmc_channel)] +#![feature(generic_const_exprs)] #![expect( incomplete_features, reason = "our usage isn't crazy and unlikely to break" )] -#![feature(generic_const_exprs)] -#![expect(clippy::pub_use, reason = "I admit I don't understand the other way.")] #![cfg_attr( test, expect( @@ -40,7 +39,7 @@ mod workers; /// cpu implements a CPU kernel for the longest line of sight mod compute { - pub mod area_of_interest; + pub(crate) mod area_of_interest; /// los contains all the traits necessary for implementing a line of sight algorithm mod los; @@ -49,7 +48,7 @@ mod compute { mod rotator; /// kernel is the exported kernel module - pub mod kernel; + pub(crate) mod kernel; /// `unrolled_los` holds a fully implemented los trait for unrolled vectorization mod unrolled_los; @@ -57,30 +56,23 @@ mod compute { /// `vector_intrinsics` holds all the vector-related LOS intrinsics mod vector_intrinsics; - pub use kernel::kernel; + pub(crate) use kernel::kernel; } /// Database for viewsheds mod storage { - pub mod db; - pub mod engine; - pub mod segments; - pub mod worker; + pub(crate) mod db; + pub(crate) mod engine; + pub(crate) mod segments; + pub(crate) mod worker; } /// Various ways to output data. mod output { - pub mod ascii; - pub mod bresenham; - pub mod png; - pub mod tiff; - - /// Load, parse and reconstruct euclidean polygon viewsheds from their raw polar segments. - pub mod viewsheds { - pub mod join; - pub mod viewshed; - pub mod visible_polygon; - } + mod ascii; + pub(crate) mod png; + pub(crate) mod tiff; + pub(crate) mod viewshed; } fn main() -> Result<()> { @@ -97,11 +89,11 @@ fn main() -> Result<()> { geo::coord! {x: f64::from(coordinate.0), y: f64::from(coordinate.1)}, ); - let (_, viewshed) = crate::output::viewsheds::viewshed::Viewshed::reconstruct( + let (_, viewshed) = crate::output::viewshed::Viewshed::reconstruct( viewshed_config.db_path.clone(), geo_coord, )?; - crate::output::viewsheds::viewshed::Viewshed::save( + crate::output::viewshed::Viewshed::save( viewshed, &viewshed_config.output_dir, geo_coord, @@ -207,5 +199,5 @@ fn compute(config: &config::Compute) -> Result<()> { #[cfg(test)] mod tests { - pub mod fixtures; + pub(crate) mod fixtures; } diff --git a/crates/total-viewsheds/src/output/ascii.rs b/crates/total-viewsheds/src/output/ascii.rs index dc2d92d..4f5075b 100644 --- a/crates/total-viewsheds/src/output/ascii.rs +++ b/crates/total-viewsheds/src/output/ascii.rs @@ -1,11 +1,7 @@ -//! Output viewsheds as ASCII. Most likely useful for tests. +//! Convert a viewshed to pure text. For testing. -#![cfg(test)] -#![expect(clippy::indexing_slicing, reason = "This code is mostly for tests")] - -use crate::output::viewsheds::viewshed::Viewshed; - -pub fn make_viewshed( +#[cfg(test)] +pub(crate) fn make_viewshed( elevations: &[i16], viewshed_pov: geo::Coord, config: crate::run::Config, @@ -22,97 +18,35 @@ pub fn make_viewshed( crate::run::test::compute(&mut dem, config.clone()); let (pov_coord, mut viewshed) = - Viewshed::reconstruct(config.viewsheds_db_path, coord_lonlat).unwrap(); - let viewsheder = crate::output::viewsheds::viewshed::Viewshed { + super::viewshed::Viewshed::reconstruct(config.viewsheds_db_path, coord_lonlat).unwrap(); + let viewsheder = crate::output::viewshed::Viewshed { dem: &dem, pov_coord, }; - let scale = 2; - let scale_f64 = f64::from(scale); - let raster_width = usize::try_from(dem.width * scale).unwrap(); - - let mut raster: Vec> = Vec::new(); - for _ in 0..dem.width * scale { - let raster_line = vec![false; raster_width]; - raster.push(raster_line); - } - - for point in viewshed.iter_mut() { - point.exterior_mut(|line| { - let mut maybe_from = None; + for polygons in viewshed.iter_mut() { + polygons.exterior_mut(|line| { for coordinate in line.coords_mut() { - let projected = viewsheder - .convert_viewshed_coord_to_dem_coord( - crate::output::viewsheds::viewshed::Coordinate(*coordinate), - ) + *coordinate = viewsheder + .convert_viewshed_coord_to_dem_coord(crate::output::viewshed::Coordinate( + *coordinate, + )) .unwrap(); - if maybe_from.is_none() { - maybe_from = Some(projected); - continue; - } + } + }); - let from = maybe_from.unwrap(); - #[expect( - clippy::as_conversions, - clippy::cast_possible_truncation, - reason = "Gotta rasterise" - )] - let rasteriser = crate::output::bresenham::Bresenham::new( - super::bresenham::RasterCoord { - x: (from.x * scale_f64).round() as i32, - y: (from.y * scale_f64).round() as i32, - }, - super::bresenham::RasterCoord { - x: (projected.x * scale_f64).round() as i32, - y: (projected.y * scale_f64).round() as i32, - }, - ); - for coord in rasteriser { - if coord.x >= 0i32 && coord.y >= 0i32 { - let x = usize::try_from(coord.x).unwrap(); - let y = usize::try_from(coord.y).unwrap(); - raster[y][x] = true; - } + polygons.interiors_mut(|interior| { + for interiror_line in interior { + for coordinate in interiror_line.coords_mut() { + *coordinate = viewsheder + .convert_viewshed_coord_to_dem_coord(crate::output::viewshed::Coordinate( + *coordinate, + )) + .unwrap(); } - maybe_from = Some(projected); } }); } - let mut ascii = Vec::new(); - let row_count = raster_width.div_euclid(2); - #[expect(clippy::needless_range_loop, reason = "clippy is wrong")] - for row in 0..row_count { - let mut viewshed_line = String::new(); - for x in 0..raster_width { - let y = row * 2; - let upper = raster[y][x]; - let lower = raster[y + 1][x]; - let character = match (upper, lower) { - (true, true) => ' ', - (false, true) => '▀', - (true, false) => '▄', - (false, false) => '█', - }; - viewshed_line.push(character); - } - ascii.push(viewshed_line); - } - - ascii -} - -#[expect(clippy::print_stderr, reason = "This is for tests")] -pub fn assert_viewshed(actual: &[String], expected: &[&str]) { - if actual != expected { - eprintln!("Actual:"); - eprint!("{}", actual.join("\n")); - eprintln!(); - eprintln!(); - eprintln!("Expected:"); - eprint!("{}", expected.join("\n")); - eprintln!(); - panic!("Viewsheds do not match"); - } + tvs_lib::ascii::rasterise_multi_polygon_geo(&viewshed, dem.width) } diff --git a/crates/total-viewsheds/src/output/png.rs b/crates/total-viewsheds/src/output/png.rs index 238189e..4215268 100644 --- a/crates/total-viewsheds/src/output/png.rs +++ b/crates/total-viewsheds/src/output/png.rs @@ -2,7 +2,7 @@ use color_eyre::{Result, eyre::ContextCompat as _}; /// Convert an array of floats to a grayscale heatmap. -pub fn save( +pub(crate) fn save( data: &[f32], width: u32, height: u32, diff --git a/crates/total-viewsheds/src/output/tiff.rs b/crates/total-viewsheds/src/output/tiff.rs index 1de965d..9213b15 100644 --- a/crates/total-viewsheds/src/output/tiff.rs +++ b/crates/total-viewsheds/src/output/tiff.rs @@ -3,7 +3,7 @@ use color_eyre::Result; /// Save an array of `f32`s (total surfaces, longest lines of sight) to a `.tiff` file. -pub fn save(dem: &tvs_lib::dem::DEM, data: &[f32], path: &std::path::PathBuf) -> Result<()> { +pub(crate) fn save(dem: &tvs_lib::dem::DEM, data: &[f32], path: &std::path::PathBuf) -> Result<()> { let driver = gdal::DriverManager::get_driver_by_name("GTiff")?; let mut dataset = driver.create_with_band_type::( diff --git a/crates/total-viewsheds/src/output/viewsheds/viewshed.rs b/crates/total-viewsheds/src/output/viewshed.rs similarity index 85% rename from crates/total-viewsheds/src/output/viewsheds/viewshed.rs rename to crates/total-viewsheds/src/output/viewshed.rs index a085a82..0a40077 100644 --- a/crates/total-viewsheds/src/output/viewsheds/viewshed.rs +++ b/crates/total-viewsheds/src/output/viewshed.rs @@ -6,11 +6,12 @@ use color_eyre::eyre::Result; /// point of view. The other option would be a metric projection with an anchor in the DEM centre, /// but metric projections are not globally correct. So reprojecting to the _viewshed's_ centre /// just gives us that little bit more accuracy, especially for larger DEMs. +#[cfg(test)] #[derive(Debug, Clone, Copy, PartialEq)] -pub struct Coordinate(pub geo::Coord); +pub(crate) struct Coordinate(pub geo::Coord); /// `Viewshed` -pub struct Viewshed<'viewshed> { +pub(crate) struct Viewshed<'viewshed> { /// The DEM used to compute the final data. pub dem: &'viewshed tvs_lib::dem::DEM, /// Coordinate of the observer for the viewshed we want to reconstruct. @@ -19,7 +20,7 @@ pub struct Viewshed<'viewshed> { impl Viewshed<'_> { /// Reconstruct a viewshed. - pub fn reconstruct( + pub(crate) fn reconstruct( db_path: std::path::PathBuf, requested_lonlat: tvs_lib::projector::LonLatCoord, ) -> Result<(tvs_lib::dem::Coordinate, geo::MultiPolygon)> { @@ -85,16 +86,59 @@ impl Viewshed<'_> { color_eyre::eyre::bail!("Point of view ({:?}) is not calculable", viewshed.pov_coord); } - let multi_polygon = super::visible_polygon::VisiblePolygon::parse_polar_segments( - &segments, - viewshed.dem.scale, - ); - - tracing::debug!("Viewshed reconstructed in {:?}.", start.elapsed()); + let multi_polygon = Self::build_viewshed_polygon(&segments, viewshed.dem.scale); + tracing::info!("Viewshed reconstructed in {:?}.", start.elapsed()); Ok((pov_dem_coord, multi_polygon)) } + /// Build a viewshed of euclidean polygons from polar segments. + pub(crate) fn build_viewshed_polygon( + data: &[Vec], + dem_scale: f32, + ) -> geo::MultiPolygon { + let raw_polygons = viewshed_reconstructor::joiner::Joiner::join(data, dem_scale); + let mut geo_polygons = Vec::new(); + for raw_polygon in raw_polygons { + let geo_polygon = Self::to_geo_polygon(&raw_polygon.to_polygon()); + tracing::trace!("Final viewshed, adding polygon: {geo_polygon:?}"); + geo_polygons.push(geo_polygon); + } + + geo::MultiPolygon::new(geo_polygons) + } + + /// Convert the polygon to the `geo` crate's representation. Ready for exporting to `GeoJSON`. + pub(crate) fn to_geo_polygon( + polygon: &viewshed_reconstructor::polygon::Polygon, + ) -> geo::Polygon { + let holes: Vec = polygon + .interior + .iter() + .map(|hole| { + geo::LineString( + hole.iter() + .map(|coordinate| geo::Coord { + x: coordinate.x, + y: coordinate.y, + }) + .collect::>(), + ) + }) + .collect(); + + let vertices: Vec = polygon + .exterior + .iter() + .map(|coordinate| geo::Coord { + x: coordinate.x, + y: coordinate.y, + }) + .collect(); + + geo::Polygon::new(geo::LineString(vertices), holes) + } + #[expect( clippy::panic, reason = "The closures expect () so I don't think there's any other way?" @@ -146,7 +190,7 @@ impl Viewshed<'_> { } /// Save the viewshed to disk. - pub fn save( + pub(crate) fn save( viewshed: geo::MultiPolygon, output_directory: &std::path::Path, viewshed_latlon: tvs_lib::projector::LonLatCoord, @@ -167,7 +211,7 @@ impl Viewshed<'_> { #[cfg(test)] impl Viewshed<'_> { /// Convert from the viewshed projection to DEM coordinates. - pub fn convert_viewshed_coord_to_dem_coord( + pub(crate) fn convert_viewshed_coord_to_dem_coord( &self, viewshed_coord: Coordinate, ) -> Result { @@ -190,7 +234,7 @@ impl Viewshed<'_> { #[cfg(test)] mod test { - use crate::output::ascii::assert_viewshed; + use tvs_lib::ascii::assert_rasterised; const SUMMIT_VIEWSHED: [&str; 12] = [ "████████████████████████", @@ -215,8 +259,8 @@ mod test { "██▀ █████████████ ▀█████", "██ ███████████████ █████", "██ ████████▀ ▄▄▄▄▄▄█████", - "██ ▀██████ ▄████████████", - "███ ▀█████ █████████████", + "██ ▀█▀▄ ██ ▄████████████", + "███ ▀▄▄███ █████████████", "████▄ ▀▀██ █████████████", "███████▄▄▄▄█████████████", "████████████████████████", @@ -248,7 +292,7 @@ mod test { "████████████████████████", "████████████████████████", ]; - assert_viewshed(&viewshed, expected); + assert_rasterised(&viewshed, expected); } #[test] @@ -262,11 +306,12 @@ mod test { ..crate::run::test::default_config(&temp_db) }, ); - assert_viewshed(&viewshed, &SUMMIT_VIEWSHED); + assert_rasterised(&viewshed, &SUMMIT_VIEWSHED); } #[test] fn viewshed_on_summit_with_high_angle_count() { + crate::setup_logging().unwrap(); let temp_db = tempfile::NamedTempFile::new().unwrap(); let viewshed = crate::output::ascii::make_viewshed( &crate::tests::fixtures::bigger_dem(), @@ -277,7 +322,7 @@ mod test { ..crate::run::test::default_config(&temp_db) }, ); - assert_viewshed(&viewshed, &PACMAN_VIEWSHED); + assert_rasterised(&viewshed, &PACMAN_VIEWSHED); } #[test] @@ -310,7 +355,7 @@ mod test { ..crate::run::test::default_config(&temp_db_for_viewsheds) }; - assert_viewshed( + assert_rasterised( &crate::output::ascii::make_viewshed( &elevations, geo::Coord { x: 5.0, y: 5.0 }, @@ -319,7 +364,7 @@ mod test { &SUMMIT_VIEWSHED, ); - assert_viewshed( + assert_rasterised( &crate::output::ascii::make_viewshed( &elevations, geo::Coord { x: 6.0, y: 6.0 }, @@ -328,7 +373,7 @@ mod test { &SUMMIT_VIEWSHED, ); - assert_viewshed( + assert_rasterised( &crate::output::ascii::make_viewshed( &elevations, geo::Coord { x: 7.0, y: 7.0 }, @@ -340,6 +385,7 @@ mod test { #[test] fn viewshed_near_summit() { + crate::setup_logging().unwrap(); let temp_db = tempfile::NamedTempFile::new().unwrap(); let viewshed = crate::output::ascii::make_viewshed( &crate::tests::fixtures::bigger_dem(), @@ -350,7 +396,7 @@ mod test { }, ); - assert_viewshed(&viewshed, &PACMAN_VIEWSHED); + assert_rasterised(&viewshed, &PACMAN_VIEWSHED); } #[test] @@ -380,6 +426,6 @@ mod test { "████████████████████████", "████████████████████████", ]; - assert_viewshed(&viewshed, expected); + assert_rasterised(&viewshed, expected); } } diff --git a/crates/total-viewsheds/src/output/viewsheds/join.rs b/crates/total-viewsheds/src/output/viewsheds/join.rs deleted file mode 100644 index be47313..0000000 --- a/crates/total-viewsheds/src/output/viewsheds/join.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Join the visible segments from each computed angle into the viewshed. - -impl super::visible_polygon::VisiblePolygon { - /// Convert polar segments to euclidean polygons. - pub fn parse_polar_segments( - data: &[Vec], - scale: f32, - ) -> geo::MultiPolygon { - let angle_count = data.len(); - let mut polygons = Vec::new(); - for (anglish, segments) in data.iter().enumerate() { - #[expect( - clippy::as_conversions, - clippy::cast_precision_loss, - reason = "The angle count should never strain the f32 mantissa" - )] - let (anglish_f32, angle_count_f32) = { (anglish as f32, angle_count as f32) }; - let polygoner = Self { - scale, - current_angle: (anglish_f32 / angle_count_f32) * 360.0, - }; - for segment in segments { - let opening = u32::from(segment.start()); - let closing = u32::from(segment.start() + segment.distance()); - let polygon = polygoner.make_visible_polygon(opening, closing); - polygons.push(polygon); - } - } - - geo::unary_union(polygons.iter()) - } -} diff --git a/crates/total-viewsheds/src/output/viewsheds/visible_polygon.rs b/crates/total-viewsheds/src/output/viewsheds/visible_polygon.rs deleted file mode 100644 index 3887360..0000000 --- a/crates/total-viewsheds/src/output/viewsheds/visible_polygon.rs +++ /dev/null @@ -1,203 +0,0 @@ -//! Create euclidean polygons from polar segments. - -/// `VisiblePolygon` -pub struct VisiblePolygon { - /// Scale of DEM data. - pub scale: f32, - /// The current sector angle. - pub current_angle: f32, -} - -impl VisiblePolygon { - /// Convert an index along a line of sight into a coordinate. - fn index_to_coordinate(&self, index: u32) -> super::viewshed::Coordinate { - let radians = self.current_angle.to_radians(); - let distance = f64::from(index); - - super::viewshed::Coordinate(geo::coord! { - x: distance * f64::from(radians.cos()), - y: distance * f64::from(radians.sin()) - }) - } - - /// Rotate a point about the centre of the viewshed. - #[expect( - clippy::suboptimal_flops, - reason = "I think readability is more important?" - )] - fn rotate_by(point: super::viewshed::Coordinate, angle: f64) -> geo::Coord { - let dx = point.0.x; - let dy = point.0.y; - let cos = angle.to_radians().cos(); - let sin = angle.to_radians().sin(); - geo::coord! { - x: dx * cos - dy * sin, - y: dx * sin + dy * cos - } - } - - /// Make a single polygon representing a visible region of the planet. - pub fn make_visible_polygon(&self, opening_index: u32, closing_index: u32) -> geo::Polygon { - let opening_coord = self.index_to_coordinate(opening_index); - let closing_coord = self.index_to_coordinate(closing_index); - - let spread = 0.5001f64; - let bottom_left = Self::rotate_by(opening_coord, spread); - let bottom_right = Self::rotate_by(opening_coord, -spread); - let top_left = Self::rotate_by(closing_coord, spread); - let top_right = Self::rotate_by(closing_coord, -spread); - - let scale = f64::from(self.scale); - - geo::Polygon::new( - geo::LineString(vec![ - bottom_left * scale, - bottom_right * scale, - top_right * scale, - top_left * scale, - bottom_left * scale, - ]), - vec![], - ) - } -} - -#[cfg(test)] -mod test { - fn builder( - viewshed: &crate::output::viewsheds::viewshed::Viewshed, - angle: f32, - ) -> crate::output::viewsheds::visible_polygon::VisiblePolygon { - crate::output::viewsheds::visible_polygon::VisiblePolygon { - scale: viewshed.dem.scale, - current_angle: angle, - } - } - - #[derive(Debug)] - struct VisiblePolygonFor { - pov: geo::Coord, - angle: f32, - opening_index: u32, - closing_index: u32, - } - - fn make_visible_polygon_for(setup: &VisiblePolygonFor) -> Vec { - let dem = crate::run::test::make_dem(&crate::tests::fixtures::single_peak_dem()); - let viewshed = crate::output::viewsheds::viewshed::Viewshed { - dem: &dem, - pov_coord: tvs_lib::dem::Coordinate(setup.pov), - }; - let viewsheder = builder(&viewshed, setup.angle); - let polygon = viewsheder.make_visible_polygon(setup.opening_index, setup.closing_index); - - let mut polygon_as_dem_coords = Vec::new(); - for coord in &polygon.exterior().0 { - let converted_coord = viewshed - .convert_viewshed_coord_to_dem_coord( - crate::output::viewsheds::viewshed::Coordinate(*coord), - ) - .unwrap(); - polygon_as_dem_coords.push(round_coordinate(converted_coord)); - } - polygon_as_dem_coords - } - - fn round(float: f64) -> f64 { - let factor = 10f64.powi(7); - (float * factor).round() / factor - } - - fn round_coordinate(coordinate: geo::Coord) -> geo::Coord { - geo::coord! { - x: round(coordinate.x), - y: round(coordinate.y), - } - } - - // Guide for the following tests: - // - // 0 1 2 3 4 5 6 7 8 - // 0 . . . . . . . . . - // 1 . . . . . .d . . . - // 2 . . . . .a . ) . . - // 3 . . . . . ( . c. . - // 4 . . . . o . b. . . - // 5 . . . . . . . . . - // 6 . . . . . . . . . - // 7 . . . . . . . . . - // 8 . . . . . . . . . - // - mod from_centre_to_top_right { - use super::*; - - const POV: geo::Coord = geo::coord! {x: 4.0, y: 4.0}; - const ANGLE: f32 = 45.0; - - // The polygon we're making is `abcd` from the above guide. - #[test] - fn making_a_visible_polygon() { - assert_eq!( - make_visible_polygon_for(&VisiblePolygonFor { - pov: POV, - angle: ANGLE, - opening_index: 1, - closing_index: 2, - }), - vec![ - (4.7009067, 3.2867503), - (4.7132503, 3.2990939), - (5.4265022, 2.5981862), - (5.401815, 2.5734989), - (4.7009067, 3.2867503) - ] - .into_iter() - .map(Into::into) - .collect::>() - ); - } - } - - // Guide for the following tests: - // - // 0 1 2 3 4 5 6 7 8 - // 0 . . . . . . . . . - // 1 . . . . . . . . . - // 2 . . . . . . . . . - // 3 . . . . . . . . . - // 4 . . . . . . . . . - // 5 . . . o .a . . . . - // 6 . . . . ( .d . . . - // 7 . . . . b. ) . . . - // 8 . . . . . c. . . . - // - mod from_bottom_left_to_bottom_right { - use super::*; - - const POV: geo::Coord = geo::coord! {x: 3.0, y: 5.0}; - const ANGLE: f32 = 135.0 + 180.0; - - // The polygon we're making is `abcd` from the above guide. - #[test] - fn making_a_visible_polygon() { - assert_eq!( - make_visible_polygon_for(&VisiblePolygonFor { - pov: POV, - angle: ANGLE, - opening_index: 1, - closing_index: 2, - }), - vec![ - (3.7132498, 5.7009093), - (3.7009061, 5.7132529), - (4.4018138, 6.4265049), - (4.4265011, 6.4018176), - (3.7132498, 5.7009093) - ] - .into_iter() - .map(Into::into) - .collect::>() - ); - } - } -} diff --git a/crates/total-viewsheds/src/post_process.rs b/crates/total-viewsheds/src/post_process.rs index 88fa74f..b59e1b4 100644 --- a/crates/total-viewsheds/src/post_process.rs +++ b/crates/total-viewsheds/src/post_process.rs @@ -4,7 +4,7 @@ use color_eyre::Result; use rayon::iter::{IntoParallelRefIterator as _, ParallelIterator as _}; /// Run post-processing tasks. -pub fn run(config: &crate::config::PostProcess) -> Result<()> { +pub(crate) fn run(config: &crate::config::PostProcess) -> Result<()> { #[expect( clippy::redundant_closure_for_method_calls, reason = "It's too verbose" diff --git a/crates/total-viewsheds/src/pre_process.rs b/crates/total-viewsheds/src/pre_process.rs index 8ecb543..43401de 100644 --- a/crates/total-viewsheds/src/pre_process.rs +++ b/crates/total-viewsheds/src/pre_process.rs @@ -5,7 +5,9 @@ use std::collections::HashMap; use color_eyre::eyre::{ContextCompat as _, Result}; /// Create a fast lookup for deciding which points should have their viewsheds saved. -pub fn create_biggest_tvs_subgrid(config: &crate::config::Compute) -> Result> { +pub(crate) fn create_biggest_tvs_subgrid( + config: &crate::config::Compute, +) -> Result> { let neighbourhood_size = config .only_save_biggest_viewsheds .context("Must specify --only-save-biggest-viewsheds")?; @@ -20,7 +22,7 @@ pub fn create_biggest_tvs_subgrid(config: &crate::config::Compute) -> Result Result> { @@ -51,7 +53,11 @@ pub fn find_biggest_total_surfaces( } /// Find which neighbourhood a given index is in. -pub const fn get_neighbourhood_id(index: i64, global_width: i64, neighbourhood_size: i64) -> i64 { +pub(crate) const fn get_neighbourhood_id( + index: i64, + global_width: i64, + neighbourhood_size: i64, +) -> i64 { let global_x = index.rem_euclid(global_width); let global_y = index.div_euclid(global_width); diff --git a/crates/total-viewsheds/src/run.rs b/crates/total-viewsheds/src/run.rs index 3b3919d..8a497d6 100644 --- a/crates/total-viewsheds/src/run.rs +++ b/crates/total-viewsheds/src/run.rs @@ -4,7 +4,7 @@ use color_eyre::Result; use std::path::PathBuf; /// Handles all the computations. -pub struct Compute<'compute> +pub(crate) struct Compute<'compute> where 'static: 'compute, { @@ -20,7 +20,7 @@ where #[derive(Clone)] /// Configuration for computing. -pub struct Config { +pub(crate) struct Config { /// The height of the observer that views viewsheds. pub observer_height: f32, /// What to compute. @@ -51,7 +51,7 @@ pub struct Config { impl<'compute> Compute<'compute> { /// Instantiate. - pub fn new(config: Config, dem: &'compute mut tvs_lib::dem::DEM) -> Result { + pub(crate) fn new(config: Config, dem: &'compute mut tvs_lib::dem::DEM) -> Result { if Self::is_process_viewsheds(&config.process) && !cfg!(any(test, feature = "ring_data")) { color_eyre::eyre::bail!( "Viewshed storage is only supported with the ring_data feature, \ @@ -73,13 +73,13 @@ impl<'compute> Compute<'compute> { } /// Are we computing viewsheds? - pub fn is_process_viewsheds(process: &[crate::config::Process]) -> bool { + pub(crate) fn is_process_viewsheds(process: &[crate::config::Process]) -> bool { Self::is_process_everything(process) || process.contains(&crate::config::Process::Viewsheds) } /// Render a heatmap and `.tiff` file of the total surface areas for each point within the computable area of the /// DEM. - pub fn render_total_surfaces(&self) -> Result<()> { + pub(crate) fn render_total_surfaces(&self) -> Result<()> { let Some(output_dir) = &self.config.output_directory else { return Ok(()); }; @@ -107,7 +107,7 @@ impl<'compute> Compute<'compute> { /// Render a heatmap and `.tiff` of the longest lines of sight for each point within the computable area of the /// DEM. - pub fn render_longest_lines(&self) -> Result<()> { + pub(crate) fn render_longest_lines(&self) -> Result<()> { let Some(output_dir) = &self.config.output_directory else { return Ok(()); }; @@ -156,11 +156,11 @@ impl<'compute> Compute<'compute> { } #[cfg(test)] -pub mod test { +pub(crate) mod test { use super::*; use googletest::prelude::*; - pub fn make_dem(elevations: &[i16]) -> tvs_lib::dem::DEM { + pub(crate) fn make_dem(elevations: &[i16]) -> tvs_lib::dem::DEM { let width = elevations.len().isqrt() as u32; let mut dem = tvs_lib::dem::DEM::new( tvs_lib::projector::LonLatCoord((33.33, 33.33).into()), @@ -173,14 +173,14 @@ pub mod test { dem } - pub fn default_metadata() -> tvs_lib::metadata::MetaData { + pub(crate) fn default_metadata() -> tvs_lib::metadata::MetaData { tvs_lib::metadata::MetaData { scale: 1.0, ..Default::default() } } - pub fn big_dem_metadata() -> tvs_lib::metadata::MetaData { + pub(crate) fn big_dem_metadata() -> tvs_lib::metadata::MetaData { tvs_lib::metadata::MetaData { width: 12, max_line_of_sight: 4, @@ -189,7 +189,7 @@ pub mod test { } } - pub fn default_config(temp_db: &tempfile::NamedTempFile) -> Config { + pub(crate) fn default_config(temp_db: &tempfile::NamedTempFile) -> Config { Config { observer_height: 0.8, process: vec![crate::config::Process::Viewsheds], @@ -207,7 +207,7 @@ pub mod test { } } - pub fn compute(dem: &mut tvs_lib::dem::DEM, config: Config) -> Compute<'_> { + pub(crate) fn compute(dem: &mut tvs_lib::dem::DEM, config: Config) -> Compute<'_> { let mut compute = Compute::new(config, dem).unwrap(); compute.run().unwrap(); compute diff --git a/crates/total-viewsheds/src/storage/db.rs b/crates/total-viewsheds/src/storage/db.rs index b440e67..8d52563 100644 --- a/crates/total-viewsheds/src/storage/db.rs +++ b/crates/total-viewsheds/src/storage/db.rs @@ -5,7 +5,7 @@ use std::path::Path; /// How we look up polar segments in the database. #[derive(Debug)] -pub enum ID { +pub(crate) enum ID { /// The precise DEM ID of the polar segment. DEM(i64), /// The neighbourhood ID within which a single DEM ID has been isolated. @@ -13,20 +13,20 @@ pub enum ID { } /// Sqlite DB connection details. -pub struct DB { +pub(crate) struct DB { /// A connection to Sqlite connection: rusqlite::Connection, } impl DB { /// Instantitate. - pub fn new>(db_path: P) -> Result { + pub(crate) fn new>(db_path: P) -> Result { let connection = rusqlite::Connection::open(db_path)?; Ok(Self { connection }) } /// Save the metadata. - pub fn save_metadata(&self, metadata: &tvs_lib::metadata::MetaData) -> Result<()> { + pub(crate) fn save_metadata(&self, metadata: &tvs_lib::metadata::MetaData) -> Result<()> { tracing::debug!("Saving metadata to {:?}...", self.connection.path()); self.connection.execute( @@ -49,7 +49,7 @@ impl DB { } /// Load the metadata. - pub fn load_metadata(&self) -> Result { + pub(crate) fn load_metadata(&self) -> Result { tracing::debug!("Loading metadata from {:?}...", self.connection.path()); let metadata_string: String = @@ -62,7 +62,10 @@ impl DB { } /// Load all the polar segments for a given ID. - pub fn load_segments(&self, id: &ID) -> Result<(Vec>, i64)> { + pub(crate) fn load_segments( + &self, + id: &ID, + ) -> Result<(Vec>, i64)> { tracing::debug!( "Loading polar segments for {id:?} from {:?}...", self.connection.path() @@ -115,12 +118,14 @@ impl DB { } /// Convert blob to `Segment`s. - fn bytes_to_segments(bytes: &[u8]) -> Result> { + fn bytes_to_segments(bytes: &[u8]) -> Result> { let mut out = Vec::with_capacity(bytes.len().div_euclid(4)); for chunk in bytes.chunks(4) { let array: [u8; 4] = chunk.try_into()?; #[expect(clippy::big_endian_bytes, reason = "That's how we save them in the DB")] - out.push(super::segments::Segment(u32::from_be_bytes(array))); + out.push(viewshed_reconstructor::segment::Segment( + u32::from_be_bytes(array), + )); } Ok(out) } diff --git a/crates/total-viewsheds/src/storage/engine.rs b/crates/total-viewsheds/src/storage/engine.rs index 7f35921..5f86335 100644 --- a/crates/total-viewsheds/src/storage/engine.rs +++ b/crates/total-viewsheds/src/storage/engine.rs @@ -6,7 +6,7 @@ use std::sync::mpsc; use std::thread; /// `Engine` is a thread-safe trait to store `PolarSegments` for a given `tvs_id` -pub trait Engine +pub(crate) trait Engine where Self: Send + Sync, { @@ -20,7 +20,7 @@ where } /// `NoopEngine` stores no `PolarSegments`, it exists for testing purposes -pub struct Noop; +pub(crate) struct Noop; impl Engine for Noop { fn store_segments( &self, @@ -48,7 +48,7 @@ impl Engine for Noop { /// /// Because of the large amount of data and need to optimize for quick writes t is not crash safe, /// meaning if your program crashes the underlying sql database will likely be corrupted -pub struct Sqlite { +pub(crate) struct Sqlite { /// `worker_handle` holds the `JoinHandle` for a worker thread which is reading /// from the Receiver end of `sender`'s channel. /// It uses an `Option` so that it can `take` the inner `JoinHandle` inside drop, @@ -60,7 +60,7 @@ pub struct Sqlite { impl Sqlite { /// Create a new `SqliteEngine` storing the database at `path` - pub fn new>(path: P) -> Self { + pub(crate) fn new>(path: P) -> Self { let (tx, rx) = mpsc::sync_channel(1024); // make an owned copy of Path so that it can be moved into the worker diff --git a/crates/total-viewsheds/src/storage/segments.rs b/crates/total-viewsheds/src/storage/segments.rs index a7f36d7..e795cfd 100644 --- a/crates/total-viewsheds/src/storage/segments.rs +++ b/crates/total-viewsheds/src/storage/segments.rs @@ -1,44 +1,6 @@ //! A "segment" is a single area of visibility for a given angle on a viewshed. There may be many //! segments per angle. -/// `Segment` is the rho portion of a line segment in polar coordinates -/// as (`rho`: u16, `delta_rho`: u16) which are packed into a single u32 for storage -#[derive(Clone, Default)] -pub struct Segment(pub u32); - -impl Segment { - /// `new` creates a `Segment` the segment's start point and the distance - fn new(start: u16, distance: u16) -> Self { - // pack start/distsance into a u32 in the format of (start|distance) - let wide_start: u32 = start.into(); - let wide_distance: u32 = distance.into(); - Self((wide_start << 16) | wide_distance) - } - - /// `start` returns the starting point of the `Segment` - #[expect( - clippy::as_conversions, - reason = "the top 16 bits are guaranteed to be 0" - )] - pub const fn start(&self) -> u16 { - (self.0 >> 16) as u16 - } - - /// `distance` returns the distance the `Segment` takes - #[expect( - clippy::as_conversions, - clippy::cast_possible_truncation, - reason = "the top 16 bits are guaranteed to be 0" - )] - pub const fn distance(&self) -> u16 { - self.0 as u16 - } -} - -#[expect( - clippy::module_name_repetitions, - reason = "That's the name we use in the DB" -)] /// `PolarSegments` holds the degree of a line of sight and the list /// of visible `Segments` which is constucted through a Run Length /// Encoding algorithm. @@ -47,12 +9,12 @@ impl Segment { /// 1. The kernel is run with higher angular resolutions. /// 2. The rotation maths causes some `dem_id`/angles to have multiple pairs. #[derive(Clone)] -pub struct PolarSegments { +pub(crate) struct PolarSegments { /// `degree` is a whole degree in the range [0, 359] pub degree: u16, /// `visible_segments` is a list of segments visible for a given /// angle and tvs id - pub visible_segments: Vec, + pub visible_segments: Vec, } impl PolarSegments { @@ -66,8 +28,9 @@ impl PolarSegments { clippy::indexing_slicing, reason = "we want to panic if out of indexes are oob" )] - pub fn from_bools(degree: u16, bitmap: &[bool]) -> Self { - let mut visible_segments: Vec = Vec::with_capacity(1); + pub(crate) fn from_bools(degree: u16, bitmap: &[bool]) -> Self { + let mut visible_segments: Vec = + Vec::with_capacity(1); let char_slice: &[u8] = bytemuck::cast_slice(bitmap); @@ -76,7 +39,7 @@ impl PolarSegments { let first_zero_index = memchr::memchr(0, &char_slice[cur_index..]).unwrap_or(char_slice.len() - cur_index); - visible_segments.push(Segment::new( + visible_segments.push(viewshed_reconstructor::segment::Segment::new( u16::try_from(cur_index).expect("cur_index overflowed"), u16::try_from(first_zero_index).expect("first_zero_index overflowed"), )); diff --git a/crates/total-viewsheds/src/storage/worker.rs b/crates/total-viewsheds/src/storage/worker.rs index f529214..05e3b68 100644 --- a/crates/total-viewsheds/src/storage/worker.rs +++ b/crates/total-viewsheds/src/storage/worker.rs @@ -4,7 +4,7 @@ /// A wrapper for a storage `Engine`. It converts bitmaps from the kernel into a `PolarSegments` /// to communicate. Keeping it a concrete struct lets us hide the underlying engine from the user /// but gives us flexibility to NOOP storage for testing purposes -pub struct Worker { +pub(crate) struct Worker { /// `engine` is the underlying storage engine for our `Storage` struct. /// We keep it `Box` so that Storage doesn't have a generic type parameter /// because: @@ -15,7 +15,7 @@ pub struct Worker { impl Worker { /// `new_noop` initializes a Worker with a dummy engine for testing - pub fn new_noop() -> Self { + pub(crate) fn new_noop() -> Self { Self { engine: Box::new(super::engine::Noop), } @@ -23,7 +23,7 @@ impl Worker { /// `new` creates a new Worker with Sqlite as its backing when /// the `test` or `ring_data` feature is enabled, otherwise returning a noop - pub fn new>(path: P) -> Self { + pub(crate) fn new>(path: P) -> Self { if !cfg!(any(test, feature = "ring_data")) { return Self { engine: Box::new(crate::storage::engine::Noop), @@ -36,7 +36,7 @@ impl Worker { } /// `store_bitmap` converts a bitmap into `PolarSegments` and uses its `Engine` to store it - pub fn store_bitmap( + pub(crate) fn store_bitmap( &self, dem_id: u64, neighbourhood_id: Option, @@ -57,7 +57,7 @@ impl Worker { /// /// All segments sent to `recv` will be run in the same transaction to save on transaction /// overhead. This means that any panic or error will end in a corrupted database -pub fn writer>( +pub(crate) fn writer>( path: P, recv: std::sync::mpsc::Receiver<(u64, Option, super::segments::PolarSegments)>, ) -> Result<(), rusqlite::Error> { diff --git a/crates/total-viewsheds/src/tests/fixtures.rs b/crates/total-viewsheds/src/tests/fixtures.rs index 598c13b..022898e 100644 --- a/crates/total-viewsheds/src/tests/fixtures.rs +++ b/crates/total-viewsheds/src/tests/fixtures.rs @@ -3,37 +3,7 @@ use color_eyre::eyre::Result; /// The nodata value from NASA's SRTM data. -pub const NODATA: f32 = -32768.0; - -// This is a little map to help orient yourself when looking at the results: -// -// 0 1 2 3 4 5 6 7 8 -// 9 10 11 12 13 14 15 16 17 -// 18 19 20 21 22 23 24 25 26 -// 27 28 29 30 31 32 33 34 35 -// 36 37 38 39 40 41 42 43 44 -// 45 46 47 48 49 50 51 52 53 -// 54 55 56 57 58 59 60 61 62 -// 63 64 65 66 67 68 69 70 71 -// 72 73 74 75 76 77 78 79 80 - -#[rustfmt::skip] -#[inline] -#[must_use] -/// A DEM tile with a symmetrical single peak. -pub fn single_peak_dem() -> Vec { - vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 3, 3, 3, 3, 3, 1, 0, - 0, 1, 3, 6, 6, 6, 3, 1, 0, - 0, 1, 3, 6, 9, 6, 3, 1, 0, - 0, 1, 3, 6, 6, 6, 3, 1, 0, - 0, 1, 3, 3, 3, 3, 3, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 - ] -} +pub(crate) const NODATA: f32 = -32768.0; // This is a little map to help orient yourself when looking at the results: // @@ -55,7 +25,7 @@ pub fn single_peak_dem() -> Vec { #[must_use] #[rustfmt::skip] /// A bigger DEM for making viewsheds. -pub fn bigger_dem() -> Vec { +pub(crate) fn bigger_dem() -> Vec { let x = 15; #[expect( clippy::as_conversions, @@ -82,7 +52,7 @@ pub fn bigger_dem() -> Vec { } /// Create the TVS heatmap that a compute run outputs. -pub fn create_tvs_tiff(data: Vec) -> Result { +pub(crate) fn create_tvs_tiff(data: Vec) -> Result { let width = data.len().isqrt(); let driver = gdal::DriverManager::get_driver_by_name("MEM")?; let dataset = driver.create_with_band_type::("", width, width, 1)?; diff --git a/crates/total-viewsheds/src/tile.rs b/crates/total-viewsheds/src/tile.rs index e38ab3d..5826770 100644 --- a/crates/total-viewsheds/src/tile.rs +++ b/crates/total-viewsheds/src/tile.rs @@ -7,7 +7,7 @@ use color_eyre::eyre::{ContextCompat as _, Result}; /// The basic raw data needed to compute total viewsheds. -pub struct Tile { +pub(crate) struct Tile { /// The width of the tile. pub width: u32, /// The size of single elevation sample in metres. @@ -20,7 +20,7 @@ pub struct Tile { impl Tile { /// Load a tile. - pub fn load(config: &crate::config::Compute) -> Result { + pub(crate) fn load(config: &crate::config::Compute) -> Result { if !config.input.exists() { color_eyre::eyre::bail!("Input file not found: {}", config.input.display()); } diff --git a/crates/total-viewsheds/src/workers.rs b/crates/total-viewsheds/src/workers.rs index 7f84de9..8eb452c 100644 --- a/crates/total-viewsheds/src/workers.rs +++ b/crates/total-viewsheds/src/workers.rs @@ -75,7 +75,7 @@ fn compilation_worker( /// create a db at path P only if `is_db_worker`, otherwise return /// a noop worker -pub fn init_worker>( +pub(crate) fn init_worker>( path: P, meta_data: &tvs_lib::metadata::MetaData, is_db_worker: bool, @@ -93,7 +93,7 @@ pub fn init_worker>( impl super::run::Compute<'_> { /// `run_parallel` runs the CPU kernel in parallel #[expect(clippy::expect_used, reason = "We need to panic on failure")] - pub fn run(&mut self) -> Result<()> { + pub(crate) fn run(&mut self) -> Result<()> { let max_los = usize::try_from(self.dem.max_los_as_points)?; let elevations = &self.dem.elevations; diff --git a/crates/tvs-lib/src/ascii.rs b/crates/tvs-lib/src/ascii.rs new file mode 100644 index 0000000..db7f945 --- /dev/null +++ b/crates/tvs-lib/src/ascii.rs @@ -0,0 +1,137 @@ +//! Output viewsheds as ASCII. Most likely useful for tests. + +#![expect( + clippy::indexing_slicing, + clippy::expect_used, + clippy::unwrap_used, + clippy::panic, + reason = "This code is mostly for tests" +)] + +use geo::CoordsIter as _; + +/// # Panics +#[inline] +#[must_use] +pub fn rasterise_multi_polygon_geo(multi_polygon: &geo::MultiPolygon, width: u32) -> Vec { + let scale = std::env::var("ASCII_TEST_SIZE") + .unwrap_or_else(|_| "2".to_owned()) + .parse::() + .expect("ASCII_TEST_SIZE env not a valid integer"); + let scale_f64 = f64::from(scale); + let raster_width = usize::try_from(width * scale).unwrap(); + + let mut raster: Vec> = Vec::new(); + for _ in 0..width * scale { + let raster_line = vec![false; raster_width]; + raster.push(raster_line); + } + + for polygon in multi_polygon.iter() { + let mut maybe_exterior_start = None; + for coordinate in polygon.exterior_coords_iter() { + if maybe_exterior_start.is_none() { + maybe_exterior_start = Some(coordinate); + continue; + } + + let from = maybe_exterior_start.unwrap(); + #[expect( + clippy::as_conversions, + clippy::cast_possible_truncation, + reason = "Gotta rasterise" + )] + let rasteriser = crate::bresenham::Bresenham::new( + super::bresenham::RasterCoord { + x: (from.x * scale_f64).round() as i32, + y: (from.y * scale_f64).round() as i32, + }, + super::bresenham::RasterCoord { + x: (coordinate.x * scale_f64).round() as i32, + y: (coordinate.y * scale_f64).round() as i32, + }, + ); + for coord in rasteriser { + if coord.x >= 0i32 && coord.y >= 0i32 { + let x = usize::try_from(coord.x).unwrap(); + let y = usize::try_from(coord.y).unwrap(); + raster[y][x] = true; + } + } + maybe_exterior_start = Some(coordinate); + } + + for interiors in polygon.interiors() { + let mut maybe_interior_start = None; + for coordinate in interiors { + if maybe_interior_start.is_none() { + maybe_interior_start = Some(*coordinate); + continue; + } + + let from = maybe_interior_start.unwrap(); + #[expect( + clippy::as_conversions, + clippy::cast_possible_truncation, + reason = "Gotta rasterise" + )] + let rasteriser = crate::bresenham::Bresenham::new( + super::bresenham::RasterCoord { + x: (from.x * scale_f64).round() as i32, + y: (from.y * scale_f64).round() as i32, + }, + super::bresenham::RasterCoord { + x: (coordinate.x * scale_f64).round() as i32, + y: (coordinate.y * scale_f64).round() as i32, + }, + ); + for coord in rasteriser { + if coord.x >= 0i32 && coord.y >= 0i32 { + let x = usize::try_from(coord.x).unwrap(); + let y = usize::try_from(coord.y).unwrap(); + raster[y][x] = true; + } + } + maybe_interior_start = Some(*coordinate); + } + } + } + + let mut ascii = Vec::new(); + let row_count = raster_width.div_euclid(2); + #[expect(clippy::needless_range_loop, reason = "clippy is wrong")] + for row in 0..row_count { + let mut viewshed_line = String::new(); + for x in 0..raster_width { + let y = row * 2; + let upper = raster[y][x]; + let lower = raster[y + 1][x]; + let character = match (upper, lower) { + (true, true) => ' ', + (false, true) => '▀', + (true, false) => '▄', + (false, false) => '█', + }; + viewshed_line.push(character); + } + ascii.push(viewshed_line); + } + + ascii +} + +/// # Panics +#[inline] +#[expect(clippy::print_stderr, reason = "This is for tests")] +pub fn assert_rasterised(actual: &[String], expected: &[&str]) { + if actual != expected { + eprintln!("Actual:"); + eprint!("{}", actual.join("\n")); + eprintln!(); + eprintln!(); + eprintln!("Expected:"); + eprint!("{}", expected.join("\n")); + eprintln!(); + panic!("Viewsheds do not match"); + } +} diff --git a/crates/total-viewsheds/src/output/bresenham.rs b/crates/tvs-lib/src/bresenham.rs similarity index 93% rename from crates/total-viewsheds/src/output/bresenham.rs rename to crates/tvs-lib/src/bresenham.rs index a31fed7..5d15478 100644 --- a/crates/total-viewsheds/src/output/bresenham.rs +++ b/crates/tvs-lib/src/bresenham.rs @@ -1,8 +1,8 @@ -#![cfg(test)] +//! Rasterise lines using the Bresenham algorithm. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] /// A raster coodinate. -pub struct RasterCoord { +pub(crate) struct RasterCoord { /// The x coordinate. pub x: i32, /// The y coordinate. @@ -20,7 +20,7 @@ impl From<(i32, i32)> for RasterCoord { /// Iterator that yields (x, y) pixels on a line using Bresenham's algorithm. /// -pub struct Bresenham { +pub(crate) struct Bresenham { /// The current start of the line. Updates as we move through the rasterisation. from: RasterCoord, /// Where the line ends. @@ -38,7 +38,7 @@ pub struct Bresenham { impl Bresenham { /// Instantiate. - pub fn new(from: RasterCoord, to: RasterCoord) -> Self { + pub(crate) const fn new(from: RasterCoord, to: RasterCoord) -> Self { let delta = RasterCoord { x: (to.x - from.x).abs(), y: (to.y - from.y).abs(), diff --git a/crates/tvs-lib/src/lib.rs b/crates/tvs-lib/src/lib.rs index cde6056..45498b0 100644 --- a/crates/tvs-lib/src/lib.rs +++ b/crates/tvs-lib/src/lib.rs @@ -1,5 +1,7 @@ //! Code we want to share amongst projects. +pub mod ascii; +mod bresenham; pub mod dem; pub mod metadata; pub mod projector; diff --git a/crates/viewshed-reconstructor/Cargo.toml b/crates/viewshed-reconstructor/Cargo.toml new file mode 100644 index 0000000..68c8f39 --- /dev/null +++ b/crates/viewshed-reconstructor/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "viewshed-reconstructor" +version = "0.1.0" +edition = "2024" + +[lib] +crate-type = ["cdylib", "rlib"] + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tracing.workspace = true +tracing-subscriber.workspace = true + +[target.'cfg(target_arch = "wasm32")'.dependencies] +console_error_panic_hook = "0.1.7" +js-sys = "0.3.103" +wasm-bindgen = "0.2" + +[dev-dependencies] +geo.workspace = true +tvs-lib = { path = "../tvs-lib", version = "0.1.0" } + +[lints] +workspace = true + diff --git a/crates/viewshed-reconstructor/README.md b/crates/viewshed-reconstructor/README.md new file mode 100644 index 0000000..34a8772 --- /dev/null +++ b/crates/viewshed-reconstructor/README.md @@ -0,0 +1,18 @@ +# Viewshed Reconstruction + +This crate is for reconstucting viewsheds from their raw "polar segments". + +It is used for both in the Rust backend for outputting final viewsheds. And it is used in browser +frontends for rendering viewsheds in maps. + +How to compile for WASM: +``` +rustup target add wasm32-unknown-unknown +cargo install wasm-pack + +wasm-pack build \ + --target web \ + --out-dir /publicish/Workspace/viewview/website/src/lib/viewshed-reconstructor \ + crates/viewshed-reconstructor +``` + diff --git a/crates/viewshed-reconstructor/src/growable_polygon.rs b/crates/viewshed-reconstructor/src/growable_polygon.rs new file mode 100644 index 0000000..9fb7562 --- /dev/null +++ b/crates/viewshed-reconstructor/src/growable_polygon.rs @@ -0,0 +1,392 @@ +//! Growable polygons are polygons constructed one angle at a time from polar segments. + +use crate::vertices::Opening; + +/// A polygon that grows, but only from its anti-clockwise facing side. +#[derive(Debug, Clone)] +pub struct GrowablePolygon { + /// The main exterior vertices. + pub vertices: Vec, + /// Interiore holes within the polygon. + pub holes: Vec>, + /// The distance of the opening furthest from the centre of the viewshed. Used for ordering + /// active polygons. Polygons must be joined to new segments (and other polygons) in increasing + /// order to prevent overlaps. + pub furthest_opening: u32, + /// Has the polygon been touched by anything in the current angle? If not, then it is marked as + /// an isolated polygon that doesn't need to be checked for touches on subsequent angles. + pub is_touched: bool, + /// Was the polygon created at 0 degrees? This is needed because the polygon may need to be + /// completed by joining another polygon that wraps into it at 360 degrees. + pub is_created_at_angle_0: bool, +} + +impl GrowablePolygon { + /// Create a new growable polygon. It always begins with a single polar segment converted to + /// its euclidean coordinates. + pub(crate) fn new(segment_vertices: &super::segment_polygon::Vertices, angle: f32) -> Self { + let mut vertices = Vec::new(); + for (segment_index, segment_vertex) in segment_vertices.vertices.iter().enumerate() { + let opening = match segment_index { + 1 => { + if angle == 0.0 { + Opening::GenesisStart(segment_vertices.distances.start) + } else { + Opening::Null + } + } + 2 => { + if angle == 0.0 { + Opening::GenesisEnd(segment_vertices.distances.end) + } else { + Opening::Null + } + } + 3 => Opening::NewEnd(segment_vertices.distances.end), + 4 => Opening::NewStart(segment_vertices.distances.start), + _ => Opening::Null, + }; + vertices.push(super::vertices::Vertex { + coordinate: *segment_vertex, + opening: opening.clone(), + }); + } + + Self { + vertices, + holes: Vec::new(), + furthest_opening: segment_vertices.distances.start, + is_touched: false, + is_created_at_angle_0: false, + } + } + + /// Create a new polygon ready to be inserted into an existing polygon. + /// + /// Note that we wind our polygons anti-clockwise. The normal new polygon is on the left with + /// indices (abcde). And the inserted polygon is on the right with vertices (cdeb). Note how the + /// inserted polygon can't wind in the same way. It's been opened up into a straight line. The + /// break happens between "c" and "b" such that they then become the ends of the line. + /// + /// z┌──┐y z┌──┐y + /// d┌──┐c │ │ d┌─┘c │ + /// │ │ + │ │ = │ │ + /// a/e└──┘b │ │ e└─┐b │ + /// w└──┘x w└──┘x + /// + /// (abcde) + (wxyz) = (wxyzcdeb) + fn new_for_insertion(segment_vertices: &super::segment_polygon::Vertices, angle: f32) -> Self { + let mut polygon = Self::new(segment_vertices, angle); + + #[expect( + clippy::indexing_slicing, + reason = "An new polygon MUST have 5 vertices by definition" + )] + let second = { polygon.vertices[1].clone() }; + + // Removing the first vertex doesn't destroy any data, because the first and last vertices + // are duplicates. + polygon.vertices.remove(0); + // Removing the second vertex also doesn't destroy any data because we copied it earlier. + polygon.vertices.remove(0); + + polygon.vertices.push(second); + polygon + } + + /// Once all the segments for an angle have been checked we convert the openings in the new + /// polygon as follows: + /// * `Opening::NewStart/NewEnd` become `Opening::Start/End`. + /// * `Opening::Start/End` become `Opening::Null`. + pub(crate) fn downgrade_openings(&mut self) { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Downgrading openings"); + let mut iterator = self.vertices.iter_mut().rev(); + while let Some(vertex) = iterator.next() { + match vertex.opening { + Opening::Null | Opening::GenesisStart(_) | Opening::GenesisEnd(_) => {} + Opening::End(_) => { + panic!("Dangling `Opening`"); + } + Opening::Start(_) => { + let Some(next) = iterator.next() else { + panic!("`Opening::Start` without adjacent end"); + }; + + vertex.opening = Opening::Null; + next.opening = Opening::Null; + } + Opening::NewStart(at) => { + vertex.opening = Opening::Start(at); + } + Opening::NewEnd(at) => { + vertex.opening = Opening::End(at); + } + } + } + } + + /// Insert new vertices into the polygon. Can be either a segment or an entire other growable + /// polygon that has _just_ been joined to the segment. Note that even though we could be + /// joinging a whole new polygon, it will still only ever be limited to the known case of the + /// freshly joined _segment_ touching this polygon. Therefore, we can assume things like, no + /// holes will ever be created on the _incoming_ polygon because only the segment section of it + /// is touching this currently instantiated polygon. + fn join( + &mut self, + base_vertices_range: std::ops::Range, + joining_vertices: Vec, + ) { + let old_start = self.extract_old_start(base_vertices_range.end); + + let removed_vertices: Vec = self + .vertices + .splice(base_vertices_range.clone(), joining_vertices) + .collect(); + + self.vertices + .get_mut(base_vertices_range.start) + .expect("Couldn't get new opening start index") + .opening = old_start; + + self.dedup_vertices_but_keep_openings(); + self.create_holes(&removed_vertices); + } + + /// Insert a segment into the polygon. + pub(crate) fn join_segment( + &mut self, + segment_vertices: &super::segment_polygon::Vertices, + vertices_range: std::ops::Range, + angle: f32, + ) { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Splicing new segment ({:?}) at: {vertices_range:?}", + segment_vertices.distances + ); + + let segment = Self::new_for_insertion(segment_vertices, angle); + self.join(vertices_range, segment.vertices); + + if segment.furthest_opening < self.furthest_opening { + self.furthest_opening = segment.furthest_opening; + } + } + + /// Insert another polygon into the `self` polygon, where `self` isn't the final polygon. + /// + /// Consider this situation. "A" and "B" are _existing_ active polygons. "s" is an incoming + /// segment. "s" joins to polygon "A" creating a new polygon "A+s". This new polygon then has to + /// also connect to polygon "B". + /// + /// `NewEnd`┌─┐x┌───────┐ + /// │ │ │ B │ Base polygon + /// │ │ └───────┘ + /// │s│ + /// │ │────────┐ + /// │ │ A │ Joining polygon + /// `NewStart`└─┘────────┘ + /// + /// We know that a segment always has `NewEnd` and `NewStart` openings. Therefore we can + /// calculate the index "x" at which the new polygon should be inserted by finding `NewEnd` and + /// substracting 1. + pub(crate) fn join_non_starting_polygon( + &mut self, + base_vertices_range: std::ops::Range, + joining_polygon: &mut Self, + ) { + let mut maybe_joining_new_end_index = None; + for (index, vertex) in joining_polygon.vertices.iter_mut().enumerate().rev() { + // Find where in the joining polygon we are opening up to be joined by the base polygon. + if matches!(vertex.opening, Opening::NewEnd(_)) { + maybe_joining_new_end_index = Some(index); + } + + // Nullify all openings so we don't try to join them in the future. + // TODO: why can't this be done via the `downgrade_openings()` method? + let is_start = matches!(vertex.opening, Opening::Start(_)); + let is_end = matches!(vertex.opening, Opening::End(_)); + if is_start || is_end { + vertex.opening = Opening::Null; + } + } + let Some(joining_new_end_index) = maybe_joining_new_end_index else { + panic!("Couldn't find `Opening::NewEnd` for joining polygon"); + }; + + // We can assume that the vertex at which we join the incoming polygon is always 1 before + // the base polygon's `NewEnd` opening. + let joining_vertices_entry = joining_new_end_index - 1; + + // Rotating achieves the effect of unlooping the polygon at the point at which the polygon + // is joined. + joining_polygon.vertices.rotate_left(joining_vertices_entry); + + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Splicing existing polygon at {base_vertices_range:?}, \ + joining polygon: {joining_polygon:#?}, rotated at {joining_vertices_entry}", + ); + + self.join(base_vertices_range, joining_polygon.vertices.clone()); + + self.holes.extend(joining_polygon.holes.clone()); + + if joining_polygon.furthest_opening < self.furthest_opening { + self.furthest_opening = joining_polygon.furthest_opening; + } + + if joining_polygon.is_created_at_angle_0 { + self.is_created_at_angle_0 = true; + } + } + + /// Insert a starting polygon (from angle 0) into a final polygon (from angle ~360). + pub(crate) fn join_starting_polygon( + &mut self, + base_vertices_range: std::ops::Range, + joining_vertices_range: std::ops::Range, + joining_polygon: &mut Self, + ) { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Splicing final polygon at {base_vertices_range:?}, \ + with: {:#?} at {joining_vertices_range:?}", + joining_polygon.vertices + ); + + // Nullify the Genesis markers + joining_polygon + .vertices + .get_mut(joining_vertices_range.start) + .expect("Bad joining vertex index") + .opening = Opening::Null; + joining_polygon + .vertices + .get_mut(joining_vertices_range.end) + .expect("Bad joining vertex index") + .opening = Opening::Null; + + // Rotating achieves the effect of unlooping the polygon at the point at which the polygon + // is joined. + joining_polygon + .vertices + .rotate_left(joining_vertices_range.start); + + self.join(base_vertices_range, joining_polygon.vertices.clone()); + + self.holes.extend(joining_polygon.holes.clone()); + } + + /// Join a polygon into itself. + pub(crate) fn join_self( + &mut self, + left_range: std::ops::Range, + right_range: std::ops::Range, + ) { + let range = if right_range.start > left_range.start { + left_range.start..right_range.start + } else { + right_range.start..left_range.start + }; + + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Splicing polygon into itself at: {range:?} ({left_range:?}/{right_range:?})" + ); + + let removed_vertices: Vec = + self.vertices.splice(range, vec![]).collect(); + self.create_holes(&removed_vertices); + } + + /// Extract the starting vertex of an opening that has just been joined to. + pub(crate) fn extract_old_start(&mut self, index: usize) -> Opening { + let vertex = self + .vertices + .get_mut(index) + .expect("Bad index for old opening start"); + + let old_start = vertex.opening.clone(); + vertex.opening = Opening::Null; + + old_start + } + + /// Create interior holes from the vertices that were removed for the join. + fn create_holes(&mut self, vertices: &[super::vertices::Vertex]) { + let holes = vertices.split_inclusive(|vertex| matches!(vertex.opening, Opening::End(_))); + + for hole in holes { + if hole.iter().any(|vertex| !vertex.is_centre()) { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Hole: {hole:?}"); + self.holes.push(hole.to_vec()); + } + } + } + + /// Is a segment and a polygon, or 2 polygons, touching? We decide by whether their openings are + /// overlapping. + pub(crate) const fn is_touching( + left: &std::ops::Range, + right: &std::ops::Range, + ) -> bool { + left.start < right.end && right.start < left.end + } + + /// Convert the polygon to the `geo` crate's representation. Ready for exporting to `GeoJSON`. + pub fn to_polygon(&self) -> crate::polygon::Polygon { + let holes: Vec> = self + .holes + .iter() + .map(|hole| { + hole.iter() + .map(|vertex| vertex.coordinate) + .collect::>() + }) + .collect(); + + let vertices: Vec = self + .vertices + .iter() + .map(|vertex| vertex.coordinate) + .collect(); + + crate::polygon::Polygon { + exterior: vertices, + interior: holes, + } + } + + /// Remove adjacent vertices that are either identical or extremely similar. This reduces the + /// byte size of the final polygon and speeds up the algorithm by about 10%. + // + // TODO: Could the algorithm be improved so that this wasn't needed? + fn dedup_vertices_but_keep_openings(&mut self) { + self.vertices.dedup_by(|left, right| { + if !matches!(left.opening, Opening::Null) || !matches!(right.opening, Opening::Null) { + return false; + } + Self::are_coordinates_within_tolerance(&left.coordinate, &right.coordinate) + }); + } + + /// Dedupe vertices, but allow destroying opening metadata. This is useful right at the very end + /// of the reconstruction. + pub(crate) fn dedup_vertices_ignore_openings(&mut self) { + self.vertices.dedup_by(|left, right| { + Self::are_coordinates_within_tolerance(&left.coordinate, &right.coordinate) + }); + } + + /// Are the two coordinates identical or as good as identical. + fn are_coordinates_within_tolerance( + left: &crate::polygon::Coordinate, + right: &crate::polygon::Coordinate, + ) -> bool { + let tolerance = 1e-6f64; + (left.x - right.x).abs() < tolerance && (left.y - right.y).abs() < tolerance + } +} diff --git a/crates/viewshed-reconstructor/src/joiner.rs b/crates/viewshed-reconstructor/src/joiner.rs new file mode 100644 index 0000000..fd02d57 --- /dev/null +++ b/crates/viewshed-reconstructor/src/joiner.rs @@ -0,0 +1,99 @@ +//! Join segments and polygons to existing growable polygons. + +mod last; +mod normal; + +/// Keeps track of active and completed polygons within a viewshed. +#[derive(Default)] +pub struct Joiner { + /// Polygons that don't intersect with the current angle. They don't need to be checked against + /// new segments. + completed: Vec, + /// Polygons that intersect with the current angle. They must be checked to see if any of their + /// openings touch any of the segments of the current angle. + active: Vec, +} + +impl Joiner { + /// Join segments into a collection of polygons. + /// + /// # Errors + /// If joining segments fails. + #[inline] + #[must_use] + pub fn join( + data: &[Vec], + dem_scale: f32, + ) -> Vec { + #[expect( + clippy::as_conversions, + clippy::cast_precision_loss, + reason = "The angle count should never strain the f32 mantissa" + )] + let angle_count = data.len() as f32; + let angle_scale = angle_count / 360.0; + + let mut joiner = Self { + completed: Vec::new(), + active: Vec::new(), + }; + + for (anglish, segments) in data.iter().enumerate() { + #[expect( + clippy::as_conversions, + clippy::cast_precision_loss, + reason = "The angle count should never strain the f32 mantissa" + )] + let angle = anglish as f32 / angle_scale; + + joiner.build_angle(angle, angle_scale, segments, dem_scale); + } + + joiner.build_final_angle(); + joiner.move_all_active_polygons_to_completed(); + for polygon in &mut joiner.completed { + polygon.dedup_vertices_ignore_openings(); + } + + joiner.completed + } +} + +#[cfg(test)] +fn rasterise_multi_polygon( + multi_polygon: Vec, +) -> Vec { + let width = 12u32; + let centre = f64::from(width.div_euclid(2)); + + let mut multi_polygons_geo = Vec::new(); + + for polygon in multi_polygon { + let mut line_exterior = Vec::new(); + for coordinate in polygon.to_polygon().exterior { + let foo = geo::Coord { + x: coordinate.x + centre, + y: coordinate.y + centre, + }; + line_exterior.push(foo); + } + + let mut holes = Vec::new(); + for hole in polygon.to_polygon().interior { + let mut line = Vec::new(); + for coordinate in hole { + let foo = geo::Coord { + x: coordinate.x + centre, + y: coordinate.y + centre, + }; + line.push(foo); + } + holes.push(geo::LineString::from(line)); + } + + let exterior = geo::LineString::from(line_exterior); + multi_polygons_geo.push(geo::Polygon::new(exterior, holes)); + } + + tvs_lib::ascii::rasterise_multi_polygon_geo(&geo::MultiPolygon::new(multi_polygons_geo), width) +} diff --git a/crates/viewshed-reconstructor/src/joiner/last.rs b/crates/viewshed-reconstructor/src/joiner/last.rs new file mode 100644 index 0000000..a5f2f3f --- /dev/null +++ b/crates/viewshed-reconstructor/src/joiner/last.rs @@ -0,0 +1,407 @@ +//! This is for joining polygons that wrap over the 360°-0° boundary. These joins are a bit more +//! complicated, but it's okay if the code is less efficient as it only happens once per viewshed +//! reconstruction. + +use crate::vertices::Opening; + +impl super::Joiner { + /// The final angle faces the challenge of joining polygons together from the first angle. + pub(crate) fn build_final_angle(&mut self) { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Building viewshed for final angle"); + + self.active.sort_by_key(|polygon| polygon.furthest_opening); + self.completed + .sort_by_key(|polygon| polygon.furthest_opening); + + let starting_polygon_indexes: Vec = self + .completed + .iter() + .enumerate() + .filter(|item| item.1.is_created_at_angle_0) + .map(|item| item.0) + .collect(); + + #[cfg(not(target_arch = "wasm32"))] + { + tracing::debug!(""); + let total_polygons = starting_polygon_indexes.len() + self.active.len(); + tracing::debug!("Final angle, polygons to check: {}", total_polygons); + tracing::trace!( + "Final angle, completed polygon (started at angle 0) indices: {:?}. Active polygons: {:?}", + starting_polygon_indexes, + self.active.len() + ); + }; + + let mut touching_starting_polygons = Vec::new(); + for starting_polygon_index in starting_polygon_indexes { + for final_polygon_index in 0..self.active.len() { + if self.handle_touching_polygons(final_polygon_index, Some(starting_polygon_index)) + { + touching_starting_polygons.push(starting_polygon_index); + } + } + } + + let polygons_to_remove = touching_starting_polygons.iter().rev(); + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!( + "Removing final joined polygons: {:?}", + polygons_to_remove.clone().collect::>() + ); + for touching_starting_polygon in polygons_to_remove { + self.completed.remove(*touching_starting_polygon); + } + + let self_joining_polygon_indexes: Vec = self + .active + .iter() + .enumerate() + .filter(|item| item.1.is_created_at_angle_0) + .map(|item| item.0) + .collect(); + + for self_joining_polygon_index in self_joining_polygon_indexes { + self.handle_touching_polygons(self_joining_polygon_index, None); + } + } + + /// Check whether a final and a starting polygon are touching. + fn handle_touching_polygons( + &mut self, + final_polygon_index: usize, + maybe_starting_polygon_index: Option, + ) -> bool { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!( + "Checking final polygon {final_polygon_index} \ + against starting polygon {maybe_starting_polygon_index:?}" + ); + + let vertices_clone = if let Some(starting_polygon_index) = maybe_starting_polygon_index { + self.completed + .get_mut(starting_polygon_index) + .expect("Bad polygon index") + .vertices + .clone() + } else { + self.active + .get_mut(final_polygon_index) + .expect("Bad polygon index") + .vertices + .clone() + }; + + let mut iterator = vertices_clone.iter().enumerate().rev(); + while let Some((index, vertex)) = iterator.next() { + match vertex.opening { + Opening::Null + | Opening::NewStart(_) + | Opening::NewEnd(_) + | Opening::Start(_) + | Opening::End(_) => (), + Opening::GenesisStart(_) => { + panic!("Dangling `Opening::GenesisStart`"); + } + Opening::GenesisEnd(start) => { + let Some(next) = iterator.next() else { + panic!("`Opening::GenesisEnd` without a following vertex"); + }; + let Opening::GenesisStart(end) = next.1.opening else { + #[cfg(not(target_arch = "wasm32"))] + tracing::error!( + "Bad opening ({:?}) in polygon: {vertices_clone:#?}", + next.1.opening + ); + panic!("`Opening::GenesisEnd` not followed by `Opening::GenesisStart`"); + }; + + let next_index = next.0; + + let joining_distances_range = end..start; + let joining_vertices_range = index..next_index; + + let is_touching = self.join_final_polygon( + final_polygon_index, + joining_distances_range, + maybe_starting_polygon_index, + joining_vertices_range, + ); + + if is_touching && maybe_starting_polygon_index.is_some() { + self.handle_touching_polygons(final_polygon_index, None); + return true; + } + } + } + } + + false + } + + /// Join a final polygon to either itself or a starting polygon. + fn join_final_polygon( + &mut self, + base_polygon_index: usize, + joining_opening_range: std::ops::Range, + maybe_joining_polygon_index: Option, + joining_vertices_range: std::ops::Range, + ) -> bool { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!( + "Checking base polygon {base_polygon_index} \ + opening indices: {joining_vertices_range:?}" + ); + + let base_polygon = self + .active + .get_mut(base_polygon_index) + .expect("Bad polygon index"); + + #[expect( + clippy::indexing_slicing, + reason = "A bad index would only be from bad code" + )] + let maybe_joining_polygon = + maybe_joining_polygon_index.map(|index| &mut self.completed[index]); + + let Some(base_vertices_range) = + super::super::vertices::find_contact(&base_polygon.vertices, &joining_opening_range) + else { + return false; + }; + + match maybe_joining_polygon { + Some(joining_polygon) => { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Final angle, polygon BEFORE: {:#?}", base_polygon); + base_polygon.join_starting_polygon( + base_vertices_range, + joining_vertices_range, + joining_polygon, + ); + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Final angle, polygon AFTER joined polygon: {:#?}", + base_polygon + ); + } + None => { + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Final angle, self-polygon BEFORE: {:#?}", base_polygon); + base_polygon.join_self(joining_vertices_range, base_vertices_range); + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!("Final angle, self-polygon AFTER: {:#?}", base_polygon); + } + } + + true + } +} + +#[cfg(test)] +mod test { + use tvs_lib::ascii::assert_rasterised; + + use crate::joiner::{Joiner, rasterise_multi_polygon}; + + #[test] + fn final_segment_joins_starting_segment_simple() { + crate::setup_logging(); + let part = vec![crate::segment::Segment::new(2, 2)]; + let joined = Joiner::join(&[part.clone(), vec![], vec![], vec![], vec![], part], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "████████████ ▀▀█████████", + "████████████ ██▄▄▀▀█████", + "████████████▄▀▀████ ████", + "███████████████ ███ ████", + "███████████████ ███ ████", + "███████████████▄▀▀█ ████", + "██████████████████▄▄████", + "████████████████████████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn inherit_holes_final() { + crate::setup_logging(); + let joined = Joiner::join( + &[ + vec![crate::segment::Segment::new(0, 3)], + vec![ + crate::segment::Segment::new(0, 1), + crate::segment::Segment::new(2, 1), + ], + vec![crate::segment::Segment::new(0, 3)], + vec![], + vec![], + vec![crate::segment::Segment::new(0, 5)], + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████ ▀▀█████████", + "████████████ ██▄▄▀▀█████", + "████████████ ██████▄ ▀██", + "████████████ ████▀▄▄████", + "████████████ ████ ██████", + "██████████▀▀▄▀▀██ ██████", + "███████▀▄▄██ ▀▀▄█ ██████", + "████████▄▄▀▀▄▀▀▄▄███████", + "████████████▄███████████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn final_segment_joins_2_starting_segments() { + crate::setup_logging(); + let long = vec![crate::segment::Segment::new(0, 4)]; + let starting = vec![ + crate::segment::Segment::new(0, 1), + crate::segment::Segment::new(2, 1), + ]; + let joined = Joiner::join(&[starting, vec![], vec![], vec![], vec![], long], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "████████████ ▀▀█████████", + "████████████ ██▄▄▀▀█████", + "████████████ ████▀▄▄████", + "████████████ █▀ █ ██████", + "████████████▄▀ █ ██████", + "███████████████▄▀ ██████", + "████████████████████████", + "████████████████████████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn final_segment_joins_starting_segment_with_2_openings() { + crate::setup_logging(); + let long = vec![crate::segment::Segment::new(0, 5)]; + let starting = vec![ + crate::segment::Segment::new(2, 1), + crate::segment::Segment::new(4, 1), + ]; + let joined = Joiner::join(&[starting, long.clone(), vec![], vec![], vec![], long], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████ ▀▀█████████", + "████████████ ██▄▄▀▀█████", + "████████████ ██████▄▄▀██", + "████████████ ████▀▄ █ ██", + "████████████ ▀▀ █ █ █ ██", + "████████████ ▀▀ █ █ █ ██", + "████████████ ██▄█ ▀ █ ██", + "████████████ ██████▄█ ██", + "████████████ ████▀▀▄▄███", + "████████████ ▀▀▄▄███████", + "████████████▄███████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn final_segment_joins_starting_segment_complex() { + crate::setup_logging(); + let long = vec![crate::segment::Segment::new(0, 4)]; + let short = vec![crate::segment::Segment::new(2, 2)]; + let joined = Joiner::join( + &[ + short.clone(), + long.clone(), + vec![], + vec![], + vec![], + vec![], + long, + short, + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▀▀▀▀▀▀████████", + "█████████▄▀█████▄▀██████", + "██████████▄▀██ ▀██▄▀████", + "███████████▄▀ ██ ██ ████", + "████████████ ▄▀▀ ██ ████", + "█████████████ ██▄██ ████", + "██████████████ ██▀▄█████", + "███████████████ ▄███████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn a_ring() { + crate::setup_logging(); + let part = vec![crate::segment::Segment::new(2, 2)]; + let ring = vec![part; 10]; + let joined = Joiner::join(&ring, 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▀▄▄▄▀▀████████", + "██████▀▄▄███████▄▄▀█████", + "█████ ████▀▄▄▀▀███▄▀████", + "████ ███▀▄█████▄▀███ ███", + "████ ███ ███████ ███ ███", + "████▄▀███▄▀▀██▀▄███▀▄███", + "██████ █████▄▄████▀▄████", + "███████▄▄▀▀███▀▀▄▄██████", + "███████████▄▄▄██████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn rings() { + crate::setup_logging(); + let part = vec![ + crate::segment::Segment::new(1, 1), + crate::segment::Segment::new(3, 1), + ]; + let ring = vec![part; 10]; + let joined = Joiner::join(&ring, 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▀▄▄▄▀▀████████", + "██████▀▄ ▀▄▄▄▄▀▀ ▄▀█████", + "█████ █ ██▀▀▄▄▀██ ▄▀████", + "████ █ █▀▄▀▄▄▄▀▄▀█ █ ███", + "████ █ █ █ ███ █ █ █ ███", + "████▄▀▄▀█▄▀▄▄ ▀▄█▀▄▀▄███", + "██████ ▄▀▀▀▄▄██▀▀▄▀▄████", + "███████▄▄▀▀▄▄▄ ▀▄▄██████", + "███████████▄▄▄██████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } +} diff --git a/crates/viewshed-reconstructor/src/joiner/normal.rs b/crates/viewshed-reconstructor/src/joiner/normal.rs new file mode 100644 index 0000000..0c54bea --- /dev/null +++ b/crates/viewshed-reconstructor/src/joiner/normal.rs @@ -0,0 +1,639 @@ +//! Join the visible segments from each computed angle into the viewshed. These "normal" joinings +//! are the ones that occur for every angle other than the final one. Therefore these should be +//! simpler and faster. + +impl super::Joiner { + /// Build the viewshed for a single angle. + pub(crate) fn build_angle( + &mut self, + angle: f32, + angle_scale: f32, + segments: &[crate::segment::Segment], + dem_scale: f32, + ) { + #[cfg(not(target_arch = "wasm32"))] + { + tracing::debug!(""); + tracing::debug!("Building viewshed for angle: {angle}"); + tracing::debug!( + "Polygon counts, completed: {}, active: {}. Segments: {}", + self.completed.len(), + self.active.len(), + segments.len() + ); + }; + + self.prepare_active_polygons(); + + let mut new_polygons = Vec::new(); + + let segment = crate::segment_polygon::SegmentPolygon { + dem_scale, + angle, + angle_scale, + }; + + for (segment_index, polar_segment) in segments.iter().enumerate() { + let start = u32::from(polar_segment.start()); + let end = u32::from(polar_segment.start() + polar_segment.distance()); + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!("Segment {segment_index}, distances range: {:?}", start..end); + let polygon_segment = crate::segment_polygon::Vertices::new(&segment, start, end); + let mut is_segment_touching_anything = false; + let mut maybe_joining_polygon_index = None; + let mut joined_polygons_to_remove = Vec::new(); + + for active_polygon_index in 0..self.active.len() { + let is_segment_touching_this_polygon = self.join_segment( + active_polygon_index, + &polygon_segment, + maybe_joining_polygon_index, + angle, + ); + + #[expect( + clippy::indexing_slicing, + reason = "We're getting the indexes from `.len()`" + )] + let active_polygon = &mut self.active[active_polygon_index]; + + if is_segment_touching_this_polygon { + active_polygon.is_touched = true; + is_segment_touching_anything = true; + if let Some(joining_polygon_index) = maybe_joining_polygon_index { + joined_polygons_to_remove.push(joining_polygon_index); + } else { + maybe_joining_polygon_index = Some(active_polygon_index); + } + } else { + maybe_joining_polygon_index = None; + } + } + + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!("Removing joined polygons: {joined_polygons_to_remove:?}"); + for joined_polygon_index in joined_polygons_to_remove.iter().rev() { + self.active.remove(*joined_polygon_index); + } + + if !is_segment_touching_anything { + new_polygons.push(Self::create_new_polygon_from_untouched_segment( + &polygon_segment, + angle, + )); + } + } + + for polygon in &mut self.active { + polygon.downgrade_openings(); + } + + self.move_untouched_active_polygons_to_completed(); + self.active.extend(new_polygons); + } + + /// When a segment doesn't touch anything it becomes its own independent polygon. + fn create_new_polygon_from_untouched_segment( + polygon_segment: &crate::segment_polygon::Vertices, + angle: f32, + ) -> crate::growable_polygon::GrowablePolygon { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!( + "Segment not touching anything at angle {angle}, \ + so making it its own polygon: {polygon_segment:?}" + ); + let mut polygon = crate::growable_polygon::GrowablePolygon::new(polygon_segment, angle); + if angle == 0.0 { + polygon.is_created_at_angle_0 = true; + } + polygon.downgrade_openings(); + + polygon + } + + /// Set all active polygons to untouched and order them based on their openings' distance from + /// the centre. + pub(crate) fn prepare_active_polygons(&mut self) { + self.active.sort_by_key(|polygon| polygon.furthest_opening); + self.active.iter_mut().for_each(|active| { + active.is_touched = false; + }); + } + + /// If a polygon wasn't touched by a segment from the current angle then it is moved to `self.completed`. + fn move_untouched_active_polygons_to_completed(&mut self) { + let completed = self.active.extract_if(.., |polygon| !polygon.is_touched); + self.completed.extend(completed); + } + + /// Once all angles have been checked, we can move all active polygons to "completed". + pub(crate) fn move_all_active_polygons_to_completed(&mut self) { + let active = self.active.drain(..); + self.completed.extend(active); + } + + /// This is the essential case for joining a new segment (B) to a single existing viewshed + /// polygon (A): + /// + /// ┌───────┐ + /// ┌───┐c │ + /// │ │───┐ │ + /// │ B │ h │ │ + /// │ │───┘ │ + /// └───┘b A │ + /// └───┐ │ + /// │ │ + /// ┌───┘ │ + /// │a │ + /// └───────┘ + /// + /// * Polygon A is an existing "active", complex [`GrowablePolygon`]. + /// * Polygon B is a new simple segment, represented by 5 vertices ([`SegmentPolygonVertices`]). + /// * Polygon A has 1 or more "openings" (represented here as "a", "b" and "c"). If it has + /// more than 1 opening there will be holes, that need to be created separately. A hole-to-be + /// is represented here by "h". + /// * Polygon B's vertices replace polygon A's vertices starting at the end of the first + /// touching opening and ending at the start of the last touching opening. + /// * The replaced vertices are used to make holes. + /// + /// This is the result of the join: + /// + /// ┌───────┐ + /// ┌───┘ │ + /// │ ┌───┐ │ + /// │b │ h │ │ + /// │ └───┘ │ + /// └───┐ │ + /// └───┐ │ + /// │ │ + /// ┌───┘ │ + /// │a │ + /// └───────┘ + /// + /// * Only 1 polygon remains, therefore polygon A has grown. + /// * A hole or holes ("h") have been created. + /// * There is one less opening (just "a" and "b"). + fn join_segment( + &mut self, + growable_polygon_index: usize, + segment: &crate::segment_polygon::Vertices, + maybe_joining_polygon_index: Option, + angle: f32, + ) -> bool { + let (base_polygon, maybe_joining_polygon) = + self.get_involved_polygons(growable_polygon_index, maybe_joining_polygon_index); + + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Polygon {growable_polygon_index} BEFORE: {:#?}", + base_polygon + ); + + let Some(base_vertices_range) = + super::super::vertices::find_contact(&base_polygon.vertices, &segment.distances) + else { + return false; + }; + + match maybe_joining_polygon { + Some(joining_polygon) => { + base_polygon.join_non_starting_polygon(base_vertices_range, joining_polygon); + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Polygon {growable_polygon_index} AFTER joined polygon: {:#?}", + base_polygon + ); + } + None => { + base_polygon.join_segment(segment, base_vertices_range, angle); + #[cfg(not(target_arch = "wasm32"))] + tracing::trace!( + "Polygon {growable_polygon_index} AFTER joined segment: {:#?}", + base_polygon + ); + } + } + + true + } + + /// Get the polygons involved in a touch check. + /// + /// It's in a function purely to hide the ugliness. + fn get_involved_polygons( + &mut self, + growable_polygon_index: usize, + maybe_joining_polygon_index: Option, + ) -> ( + &mut crate::growable_polygon::GrowablePolygon, + Option<&mut crate::growable_polygon::GrowablePolygon>, + ) { + if let Some(joining_polygon_index) = maybe_joining_polygon_index { + #[expect( + clippy::expect_used, + reason = "An error here is a broken invariant. Better to panic." + )] + // This `disjoint` shenanigans is to get 2 mutable references at once, otherwise + // the borrow checker complains. + let [growable_polygon, joining_polygon] = self + .active + .get_disjoint_mut([growable_polygon_index, joining_polygon_index]) + .expect("Polygon indexes not found"); + (growable_polygon, Some(joining_polygon)) + } else { + #[expect( + clippy::indexing_slicing, + reason = "We're getting the indexes from `.len()`" + )] + (&mut self.active[growable_polygon_index], None) + } + } +} + +#[cfg(test)] +mod test { + use tvs_lib::ascii::assert_rasterised; + + use crate::joiner::{Joiner, rasterise_multi_polygon}; + + #[test] + fn multiple_angles() { + crate::setup_logging(); + let segment = vec![crate::segment::Segment::new(0, 5)]; + let joined = Joiner::join(&[segment.clone(), segment.clone(), segment], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "█████████████████▀██████", + "█████████████▀▀▄▄ ██████", + "██████████▀▀▄████ ██████", + "███████▀▄▄███████ ██████", + "███▀▀▄▄██████████ ██████", + "██▄▀▀████████████ ██████", + "█████▄▄▀█████████ ██████", + "████████▄▄▀▀█████ ██████", + "████████████▄▀▀██ ██████", + "███████████████▄▄ ██████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn multiple_segments() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 5)]; + let multiple = vec![ + crate::segment::Segment::new(0, 2), + crate::segment::Segment::new(3, 1), + ]; + let joined = Joiner::join( + &[ + main.clone(), + main.clone(), + main.clone(), + main.clone(), + multiple, + main, + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████ ▀▀█████████", + "██████████▀▀▄██▄▄▀▀█████", + "███▀▀█▀▀▄▄▀▀ ██████▄▄▀██", + "███ █▄█▀ ▄▀▀▄████████ ██", + "███ █████▄███████████ ██", + "███ █████████████████ ██", + "███ █████████████████ ██", + "███ █████████████████ ██", + "████▄▄▀▀█████████▀▀▄▄███", + "████████▄▄▀▀█▀▀▄▄███████", + "████████████▄███████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn multiple_polygons() { + crate::setup_logging(); + let segment = vec![crate::segment::Segment::new(0, 5)]; + let joined = Joiner::join( + &[ + segment.clone(), + vec![], + vec![], + vec![], + vec![], + segment, + vec![], + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "█████████▀▀▀▀▄ █████████", + "██████▄ ▄████▀▄█████████", + "████████ ████ ██████████", + "█████████▄▀██ ████▀▀▄ ██", + "███████████ █▀▀▄▄███ ██", + "████████████▄▄▀▀█████ ██", + "████████████████▄▄▀▀█ ██", + "████████████████████▄▄██", + "████████████████████████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn multiple_polygons_not_touching() { + crate::setup_logging(); + let segment = vec![crate::segment::Segment::new(2, 2)]; + let joined = Joiner::join( + &[ + segment.clone(), + vec![], + vec![], + vec![], + vec![], + segment, + vec![], + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▀▀▀▄ █████████", + "███████▄ ████▀▄█████████", + "█████████▄▀▀▄▄████▀▀████", + "████████████████ ▄█ ████", + "████████████████ ██ ████", + "████████████████▄▄▀ ████", + "████████████████████████", + "████████████████████████", + "████████████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn varying_sized_segments() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 4)]; + let variance = vec![crate::segment::Segment::new(0, 2)]; + let joined = Joiner::join( + &[main.clone(), main.clone(), main.clone(), main, variance], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀ █████████████", + "████████ █▄▀██████▀█████", + "██████▀▄███▄▄▀▀█▀▄ █████", + "█████ █████████▄██ █████", + "████▄▀████████████ █████", + "██████ ███████████ █████", + "███████▄▀████████▀ █████", + "█████████ ██▀▀▄▄▄███████", + "██████████▄▄████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn untouched_openings_get_closed() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 4)]; + let pair = vec![ + crate::segment::Segment::new(0, 2), + crate::segment::Segment::new(3, 1), + ]; + let bottom = vec![crate::segment::Segment::new(0, 2)]; + let joined = Joiner::join(&[main.clone(), pair, bottom, main.clone(), main], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▄▄▀▀▀█████████", + "████████ ██████▄▄▀▀█████", + "██████▀▄██████████ █████", + "█████ ████████████ █████", + "████▄▄▄▄▄▀████████ █████", + "██████████ █▀▀▄▄▀█ █████", + "███████████▄▀▀▀▀▄ █████", + "██████████ ▄▀▀▄▄▄███████", + "██████████▄▄████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn centre_is_touched_after_more_than_one_angle() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 4)]; + let top = vec![crate::segment::Segment::new(2, 2)]; + let joined = Joiner::join( + &[ + main.clone(), + top.clone(), + top.clone(), + top.clone(), + top, + main, + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "██████████▀▀▄▀▀█████████", + "██████▀▀▄▄█████▄▄▀▀█████", + "█████ ████▀▀ ██████ ████", + "█████ ███ ██ ██████ ████", + "█████ ███ ██▄▀▀████ ████", + "█████ ███▄▀▀█▀▀▄███ ████", + "█████▄▀▀████▄████▀▀▄████", + "████████▄▄▀▀█▀▀▄▄███████", + "████████████▄███████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn a_hole() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 4)]; + let lid = vec![crate::segment::Segment::new(2, 1)]; + let joined = Joiner::join(&[main.clone(), main.clone(), lid, main.clone(), main], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████████▀▄▄▀▀▀█████████", + "████████ ██████▄▄▀▀█████", + "██████▀▄██████████ █████", + "█████ ████████████ █████", + "████▄▄▄▀▄ ▄▄ █████ █████", + "███████▄▀▄▀ ██████ █████", + "█████████ █▄█████▀ █████", + "██████████ █▀▀▄▄▄███████", + "██████████▄▄████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn multiple_holes() { + crate::setup_logging(); + let main = vec![crate::segment::Segment::new(0, 6)]; + let struts = vec![ + crate::segment::Segment::new(0, 1), + crate::segment::Segment::new(2, 1), + crate::segment::Segment::new(4, 1), + ]; + let joined = Joiner::join( + &[main.clone(), main.clone(), main.clone(), struts, main], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████▀▀██████████████", + "████████▀▄▄▄▄▄▀▀▀███████", + "███████▀▄▀ ██████▄▄▄▄▀▀█", + "█████▀▄█▀ ▄███████████ █", + "████▀▄▀▄▀▄▀ ██████████ █", + "███ █▀▄ █▀ ▄██████████ █", + "▄ ▄█▄▄▄█▄▄▄███████████ █", + "█▄▀███████████████████ █", + "███▄▀█████████████████ █", + "████▄▀███████████████▀ █", + "██████▄▀██████▀▀▀▄▄▄▄███", + "███████▄▀▀▄▄▄▄██████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn segment_joins_to_multiple_polygons() { + crate::setup_logging(); + let polygons = vec![ + crate::segment::Segment::new(2, 1), + crate::segment::Segment::new(4, 1), + ]; + let long = vec![crate::segment::Segment::new(0, 5)]; + let joined = Joiner::join( + &[ + polygons.clone(), + polygons.clone(), + polygons.clone(), + long, + polygons, + vec![], + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "██████████▀▀ ███████████", + "██████▀▀▄▄▀▀▄███████████", + "███▀▄▄▀▀▄▄▀▀ ████████▀██", + "███ █▄▄▀▄▄▀▀▄████▀█ ▄ ██", + "███ █████▄▀▀███ ▄ █ █ ██", + "███ ██████▀▀▄██ █ █ █ ██", + "███ ██▀▀█▄▀▀█▀▀▄█ █ █ ██", + "███ █▄▀▀▄▄▀▀▄▀▀▄▄▀▀▄█ ██", + "████▄▄▀▀▄▄▀▀▄▀▀▄▄▀▀▄▄███", + "████████▄▄▀▀▄▀▀▄▄███████", + "████████████▄███████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn join_in_distance_order() { + crate::setup_logging(); + + // Even though this polygon is made first and so naturally appears first in the `self.active` + // list of polygons, it is in fact _nearer_ the centre and so must be joined before newer but + // higher polygons. + let higher_but_made_first = crate::segment::Segment::new(2, 2); + + let lower = crate::segment::Segment::new(0, 1); + let first = vec![higher_but_made_first.clone()]; + let second = vec![lower, higher_but_made_first]; + let long = vec![crate::segment::Segment::new(0, 5)]; + let joined = Joiner::join(&[vec![], first, second, long, vec![]], 1.0); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████▀ ██████████████", + "███████▀▄█ █████████████", + "█████▀▄███ █████████████", + "████▀▄█████ ████████████", + "███ ███████▄▀███████████", + "██▄▄▄▀██▄ ▄▀ ███████████", + "██████ ██▄▀▄█▀▀▄▀███████", + "███████▄▀██▄▄████ ▀█████", + "█████████ ██▀▀▄▄▄███████", + "██████████▄▄████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } + + #[test] + fn inherit_holes_common() { + crate::setup_logging(); + + let joined = Joiner::join( + &[ + vec![], + vec![crate::segment::Segment::new(0, 3)], + vec![ + crate::segment::Segment::new(0, 1), + crate::segment::Segment::new(2, 1), + ], + vec![ + crate::segment::Segment::new(0, 3), + crate::segment::Segment::new(4, 1), + ], + vec![crate::segment::Segment::new(0, 5)], + vec![], + vec![], + ], + 1.0, + ); + let actual = rasterise_multi_polygon(joined); + let expected = [ + "████████████████████████", + "████████████████████████", + "█████▀▄▀████████████████", + "████▀▄█▄▀███████████████", + "███▀▄████▄▀█████████████", + "██▀▄██████▄▀████████████", + "██▄▀ ▄ █████▄▀▀█████████", + "███▄▀ █ ██▀ ▄▀█▄▄▀██████", + "████▄▀ █ ▀▀█▄▄▀▄▄███████", + "█████▄▀ ███▄▄▄██████████", + "██████▄█████████████████", + "████████████████████████", + ]; + assert_rasterised(&actual, &expected); + } +} diff --git a/crates/viewshed-reconstructor/src/lib.rs b/crates/viewshed-reconstructor/src/lib.rs new file mode 100644 index 0000000..66b6473 --- /dev/null +++ b/crates/viewshed-reconstructor/src/lib.rs @@ -0,0 +1,35 @@ +//! Reconstruct viewsheds from polar segments. +//! +//! You could just use + +#![expect( + clippy::expect_used, + clippy::panic, + reason = "We're not using errors to keep the WASM bundle size small" +)] + +#[cfg(test)] +use tracing_subscriber::{Layer as _, layer::SubscriberExt as _, util::SubscriberInitExt as _}; + +mod growable_polygon; +pub mod joiner; +pub mod polygon; +pub mod segment; +mod segment_polygon; +mod vertices; +mod wasm; + +/// Setup logging. +#[cfg(test)] +pub(crate) fn setup_logging() { + let filters = tracing_subscriber::EnvFilter::builder() + .with_default_directive( + "total_viewsheds=debug" + .parse() + .expect("Couldn't parse log ENV filter"), + ) + .from_env_lossy(); + let filter_layer = tracing_subscriber::fmt::layer().with_filter(filters); + let tracing_setup = tracing_subscriber::registry().with(filter_layer); + tracing_setup.init(); +} diff --git a/crates/viewshed-reconstructor/src/polygon.rs b/crates/viewshed-reconstructor/src/polygon.rs new file mode 100644 index 0000000..3c0a30b --- /dev/null +++ b/crates/viewshed-reconstructor/src/polygon.rs @@ -0,0 +1,39 @@ +//! A polygon represented by simple types. Avoids having to compile the `geo` crate. + +/// A viewshed-based coordinate. +#[expect(clippy::exhaustive_structs, reason = "It will never change")] +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct Coordinate { + /// The x coordinate. + pub x: f64, + /// The y coordinate. + pub y: f64, +} + +impl Coordinate { + /// Just a shortcut for a coordinate at 0,0. + #[inline] + #[must_use] + pub const fn zero() -> Self { + Self { x: 0.0, y: 0.0 } + } + + /// Scale the x and y compenents by a factor. + #[inline] + #[must_use] + pub fn scale(&self, factor: f64) -> Self { + Self { + x: self.x * factor, + y: self.y * factor, + } + } +} + +/// A polygon with a single exterior and multiple interior "holes". +#[expect(clippy::exhaustive_structs, reason = "It will never change")] +pub struct Polygon { + /// Coordinates representing the polygon's exterior boundary. + pub exterior: Vec, + /// Coordinates representing the polygon's interior boundaries. + pub interior: Vec>, +} diff --git a/crates/viewshed-reconstructor/src/segment.rs b/crates/viewshed-reconstructor/src/segment.rs new file mode 100644 index 0000000..0cc0e42 --- /dev/null +++ b/crates/viewshed-reconstructor/src/segment.rs @@ -0,0 +1,43 @@ +//! A "segment" is a single area of visibility for a given angle on a viewshed. There may be many +//! segments per angle. + +/// `Segment` is the rho portion of a line segment in polar coordinates +/// as (`rho`: u16, `delta_rho`: u16) which are packed into a single u32 for storage. +#[expect(clippy::exhaustive_structs, reason = "This will never change.")] +#[derive(Clone, Default)] +pub struct Segment(pub u32); + +impl Segment { + /// `new` creates a `Segment` the segment's start point and the distance + #[inline] + #[must_use] + pub fn new(start: u16, distance: u16) -> Self { + // pack start/distsance into a u32 in the format of (start|distance) + let wide_start: u32 = start.into(); + let wide_distance: u32 = distance.into(); + Self((wide_start << 16) | wide_distance) + } + + /// `start` returns the starting point of the `Segment` + #[expect( + clippy::as_conversions, + reason = "the top 16 bits are guaranteed to be 0" + )] + #[inline] + #[must_use] + pub const fn start(&self) -> u16 { + (self.0 >> 16) as u16 + } + + /// `distance` returns the distance the `Segment` takes + #[expect( + clippy::as_conversions, + clippy::cast_possible_truncation, + reason = "the top 16 bits are guaranteed to be 0" + )] + #[inline] + #[must_use] + pub const fn distance(&self) -> u16 { + self.0 as u16 + } +} diff --git a/crates/viewshed-reconstructor/src/segment_polygon.rs b/crates/viewshed-reconstructor/src/segment_polygon.rs new file mode 100644 index 0000000..75399ee --- /dev/null +++ b/crates/viewshed-reconstructor/src/segment_polygon.rs @@ -0,0 +1,213 @@ +//! Create euclidean polygons from polar segments. + +/// The 5 vertices of a segment and their distances from the centre. +#[derive(Debug)] +pub(crate) struct Vertices { + /// The 5 vertices of a segment. The 4 corners plus a copy of the first vertex to close the + /// polygon. + pub vertices: [crate::polygon::Coordinate; 5], + /// The distances of the top and bottom of the segment from the centre. + pub distances: std::ops::Range, +} + +impl Vertices { + /// Make a single polygon representing a visible region of the planet. + pub(crate) fn new(segment: &SegmentPolygon, opening_index: u32, closing_index: u32) -> Self { + let opening_coord = segment.index_to_coordinate(opening_index); + let closing_coord = segment.index_to_coordinate(closing_index); + + let spread = 1.0f64 / f64::from(segment.angle_scale) / 2.0f64; + let bottom_left = SegmentPolygon::rotate_by(opening_coord, spread); + let bottom_right = SegmentPolygon::rotate_by(opening_coord, -spread); + let top_left = SegmentPolygon::rotate_by(closing_coord, spread); + let top_right = SegmentPolygon::rotate_by(closing_coord, -spread); + + let scale = f64::from(segment.dem_scale); + + let vertices = [ + bottom_left.scale(scale), + bottom_right.scale(scale), + top_right.scale(scale), + top_left.scale(scale), + bottom_left.scale(scale), + ]; + + Self { + vertices, + distances: opening_index..closing_index, + } + } +} + +/// `SegmentPolygon` +pub(crate) struct SegmentPolygon { + /// Scale of DEM data. + pub dem_scale: f32, + /// The current sector angle. + pub angle: f32, + /// The number of angles per degree. + pub angle_scale: f32, +} + +impl SegmentPolygon { + /// Convert an index along a line of sight into a coordinate. + fn index_to_coordinate(&self, index: u32) -> crate::polygon::Coordinate { + let radians = self.angle.to_radians(); + let distance = f64::from(index); + + crate::polygon::Coordinate { + x: distance * f64::from(radians.cos()), + y: distance * f64::from(radians.sin()), + } + } + + /// Rotate a point about the centre of the viewshed. + #[expect( + clippy::suboptimal_flops, + reason = "I think readability is more important?" + )] + fn rotate_by(point: crate::polygon::Coordinate, angle: f64) -> crate::polygon::Coordinate { + let dx = point.x; + let dy = point.y; + let cos = angle.to_radians().cos(); + let sin = angle.to_radians().sin(); + crate::polygon::Coordinate { + x: dx * cos - dy * sin, + y: dx * sin + dy * cos, + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn builder(angle: f32) -> SegmentPolygon { + SegmentPolygon { + dem_scale: 1.0, + angle, + angle_scale: 1.0, + } + } + + #[derive(Debug)] + struct VisiblePolygonFor { + angle: f32, + opening_index: u32, + closing_index: u32, + } + + fn make_visible_polygon_for(setup: &VisiblePolygonFor) -> Vec { + let segment = builder(setup.angle); + let vertices = + super::Vertices::new(&segment, setup.opening_index, setup.closing_index).vertices; + + let mut polygon_as_dem_coords = Vec::new(); + for vertex in &vertices { + let dem_coord = crate::polygon::Coordinate { + x: vertex.x + 4.0, + y: -vertex.y + 4.0, + }; + polygon_as_dem_coords.push(round_coordinate(dem_coord)); + } + polygon_as_dem_coords + } + + pub(crate) fn coord(x: f64, y: f64) -> crate::polygon::Coordinate { + crate::polygon::Coordinate { x, y } + } + + fn round(float: f64) -> f64 { + let factor = 10f64.powi(7); + (float * factor).round() / factor + } + + fn round_coordinate(coordinate: crate::polygon::Coordinate) -> crate::polygon::Coordinate { + crate::polygon::Coordinate { + x: round(coordinate.x), + y: round(coordinate.y), + } + } + + // Guide for the following tests: + // + // 0 1 2 3 4 5 6 7 8 + // 0 . . . . . . . . . + // 1 . . . . . .d . . . + // 2 . . . . .a . ) . . + // 3 . . . . . ( . c. . + // 4 . . . . o . b. . . + // 5 . . . . . . . . . + // 6 . . . . . . . . . + // 7 . . . . . . . . . + // 8 . . . . . . . . . + // + mod from_centre_to_top_right { + use super::*; + + const ANGLE: f32 = 45.0; + + // The polygon we're making is `abcd` from the above guide. + #[expect(clippy::unreadable_literal, reason = "It's just a test")] + #[test] + fn making_a_visible_polygon() { + assert_eq!( + make_visible_polygon_for(&VisiblePolygonFor { + angle: ANGLE, + opening_index: 1, + closing_index: 2, + }), + vec![ + coord(4.7009093, 3.2867496), + coord(4.7132504, 3.2990907), + coord(5.4265009, 2.5981815), + coord(5.4018185, 2.5734991), + coord(4.7009093, 3.2867496), + ] + .into_iter() + .collect::>() + ); + } + } + + // Guide for the following tests: + // + // 0 1 2 3 4 5 6 7 8 + // 0 . . . . . . . . . + // 1 . . . . . . . . . + // 2 . . . . . . . . . + // 3 . . . . . . . . . + // 5 . . . . o .a . . . + // 6 . . . . . ( .d . . + // 7 . . . . . b. ) . . + // 8 . . . . . . c. . . + // 4 . . . . . . . . . + // + mod from_bottom_left_to_bottom_right { + use super::*; + + const ANGLE: f32 = 135.0 + 180.0; + + // The polygon we're making is `abcd` from the above guide. + #[expect(clippy::unreadable_literal, reason = "It's just a test")] + #[test] + fn making_a_visible_polygon() { + assert_eq!( + make_visible_polygon_for(&VisiblePolygonFor { + angle: ANGLE, + opening_index: 1, + closing_index: 2, + }), + vec![ + coord(4.7132503, 4.7009094), + coord(4.7009091, 4.7132506), + coord(5.4018183, 5.4265011), + coord(5.4265006, 5.4018187), + coord(4.7132503, 4.7009094), + ] + .into_iter() + .collect::>() + ); + } + } +} diff --git a/crates/viewshed-reconstructor/src/vertices.rs b/crates/viewshed-reconstructor/src/vertices.rs new file mode 100644 index 0000000..0dd2a4b --- /dev/null +++ b/crates/viewshed-reconstructor/src/vertices.rs @@ -0,0 +1,226 @@ +//! The vertices of a viewshed polygon. They have both real-world coordinates and "openings", which +//! are vertices that can join with other "openings". + +/// A vertex is a single point in a polygon. +#[derive(Debug, Clone)] +pub struct Vertex { + /// The coordinate of the vertex in euclidian space. + pub coordinate: crate::polygon::Coordinate, + /// The kind of opening that this vertex represents. + pub opening: Opening, +} + +impl Vertex { + /// Is the vertex at the centre of the viewshed? The centre is a special place, it is a + /// zero-length opening that isn't nulled if no segments/polygons touch it for a given angle. + pub(crate) fn is_centre(&self) -> bool { + self.coordinate.x.abs() == 0.0 && self.coordinate.y.abs() == 0.0 + } +} + +/// An opening is where one polygon can join a segment, or even another polygon. +/// The `u32` values in the variants are for storing the polar distance from the centre. This saves +/// having to do trigonometry to figure out if two openings are touching. +#[derive(Eq, PartialEq, Debug, Clone)] +pub enum Opening { + /// No opening. We could also just use `Option::None`, but unwrapping it isn't so ergonomic. + Null, + /// This i for polygons that start at 0 degrees. It's possible that another polygon (or even + /// itself), could connect to it at 360 degrees. + GenesisStart(u32), + /// The closing of the genesis opening at 0 degrees. + GenesisEnd(u32), + /// An active opening's start. + Start(u32), + /// An active opening's end. + End(u32), + /// When a segment or polygon is successfully attached to an existing polygon, but we still want + /// to carry on looking for other attachments in the given angle, we don't want to mistakenly + /// attach new segments/polygons to something that's just been attached. Once the whole angle is + /// completed, then these get downgraded to the common `Start/End` opendings. + NewStart(u32), + /// A `New` openings end. + NewEnd(u32), +} + +/// Iterator for finding start/open vertex pairs for openings. +pub(crate) struct OpeningsIterator<'vertices> { + /// The vertices to scan. + vertices: &'vertices [Vertex], + /// The current index of the iterator. + index: usize, + /// Keep track of the previously scanned opening. + previous_opening: Opening, +} + +impl<'vertices> OpeningsIterator<'vertices> { + /// Instantiate. + pub(crate) const fn new(vertices: &'vertices [Vertex]) -> Self { + Self { + vertices, + index: vertices.len() - 1, + previous_opening: Opening::Null, + } + } +} + +impl Iterator for OpeningsIterator<'_> { + type Item = (usize, std::ops::Range); + + #[expect( + clippy::panic, + reason = "Opening ordering is a requirement of the algorithm" + )] + fn next(&mut self) -> Option { + loop { + if self.index == 0 { + #[expect( + clippy::indexing_slicing, + reason = "There always has to be a first element" + )] + if matches!(self.vertices[0].opening, Opening::Start(_)) { + panic!("Dangling Opening::Start"); + }; + return None; + } + + #[expect(clippy::indexing_slicing, reason = "Bounds are enforced elsewhere")] + let (left, right) = { (&self.vertices[self.index], &self.vertices[self.index - 1]) }; + + let is_currently_end = matches!(left.opening, Opening::End(_)); + let is_previously_start = matches!(self.previous_opening, Opening::Start(_)); + let is_end_without_a_start = is_currently_end && !is_previously_start; + assert!(!is_end_without_a_start, "Dangling Opening::End"); + + if let Opening::Start(start) = left.opening { + let Opening::End(end) = right.opening else { + panic!("Opening::Start not followed by Opening::End"); + }; + + self.previous_opening = right.opening.clone(); + let opening_range = start..end; + let opening_index = self.index; + self.index = self.index.saturating_sub(2); + return Some((opening_index, opening_range)); + } + + self.previous_opening = left.opening.clone(); + self.index -= 1; + } + } +} + +/// Check if 2 openings touch. +pub(crate) fn find_contact( + vertices: &[Vertex], + joining_opening_range: &std::ops::Range, +) -> Option> { + OpeningsIterator::new(vertices) + .filter(|(base_opening_index, base_opening_range)| { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!( + "Checking if openings touch: \ + index: {base_opening_index:?}, \ + base distances: {base_opening_range:?}, \ + joining distances: {joining_opening_range:?}", + ); + + let is_touching = crate::growable_polygon::GrowablePolygon::is_touching( + base_opening_range, + joining_opening_range, + ); + + if is_touching { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!("🟢 Openings touch"); + } else { + #[cfg(not(target_arch = "wasm32"))] + tracing::debug!("🟡 Openings don't touch"); + } + + is_touching + }) + .fold(None, |accumulator, (index, _)| { + let range_of_touch = accumulator.map_or(index..index, |range| { + std::cmp::min(range.start, index)..std::cmp::max(range.end, index) + }); + + Some(range_of_touch) + }) +} + +#[cfg(test)] +mod test { + use super::*; + + fn vertex(opening: super::Opening) -> Vertex { + super::Vertex { + coordinate: crate::polygon::Coordinate::zero(), + opening, + } + } + + fn run(mut vertices: Vec) -> Vec<(usize, std::ops::Range)> { + vertices.reverse(); + OpeningsIterator::new(&vertices).collect::>() + } + + // TODO: + // I actually think side by side openings would themselves be a bug, but I haven't + // verified that so better test for it just in case. + #[test] + fn openings_side_by_side_should_not_panic() { + let vertices = vec![ + vertex(super::Opening::Start(0)), + vertex(super::Opening::End(1)), + vertex(super::Opening::Start(3)), + vertex(super::Opening::End(4)), + ]; + assert_eq!(run(vertices), vec![(3, 0..1), (1, 3..4)]); + } + + #[test] + #[should_panic(expected = "Opening::Start not followed by Opening::End")] + fn start_not_followed_by_end_panics() { + let vertices = vec![ + vertex(super::Opening::Start(0)), + vertex(super::Opening::Null), + vertex(super::Opening::End(0)), + ]; + run(vertices); + } + + #[test] + #[should_panic(expected = "Dangling Opening::Start")] + fn start_in_final_position_panics() { + let vertices = vec![ + vertex(super::Opening::Null), + vertex(super::Opening::Null), + vertex(super::Opening::Start(0)), + ]; + run(vertices); + } + + #[test] + #[should_panic(expected = "Dangling Opening::End")] + fn end_in_initial_position_panics() { + let vertices = vec![ + vertex(super::Opening::End(0)), + vertex(super::Opening::Start(0)), + vertex(super::Opening::End(0)), + ]; + run(vertices); + } + + #[test] + #[should_panic(expected = "Dangling Opening::End")] + fn dangling_end_panics() { + let vertices = vec![ + vertex(super::Opening::Null), + vertex(super::Opening::End(0)), + vertex(super::Opening::Start(0)), + vertex(super::Opening::End(0)), + ]; + run(vertices); + } +} diff --git a/crates/viewshed-reconstructor/src/wasm.rs b/crates/viewshed-reconstructor/src/wasm.rs new file mode 100644 index 0000000..72182dc --- /dev/null +++ b/crates/viewshed-reconstructor/src/wasm.rs @@ -0,0 +1,130 @@ +//! Support using this crate in the browser with WASM. + +// #![cfg(target_arch = "wasm32")] + +#[cfg(target_arch = "wasm32")] +use js_sys::Array; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +/// WASM only supports simple types, so this is a simple representation of a polygon. +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub struct PlainPolygon { + /// The exterior coordinates of the polygon. x/y components are flattened, so the first + /// coordinate is found at [0,1]. + exterior: Vec, + /// The interior coordinates of the polygon. To find the starting/ending indices of each + /// hole see `hole_indices`. x/y components are flattened, so the first coordinate is + /// found at [0,1]. + interiors: Vec, + /// Indices of where each hole starts and ends in `interiors`. + hole_indices: Vec, +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +impl PlainPolygon { + /// Getter for `exterior`. + #[wasm_bindgen(getter)] + #[must_use] + pub fn exterior(&self) -> Vec { + self.exterior.clone() + } + + /// Getter for `interiors`. + #[wasm_bindgen(getter)] + #[must_use] + pub fn interiors(&self) -> Vec { + self.interiors.clone() + } + + /// Getter for `hole_indices`. + #[wasm_bindgen(getter)] + #[must_use] + pub fn hole_indices(&self) -> Vec { + self.hole_indices.clone() + } +} + +#[cfg(target_arch = "wasm32")] +impl PlainPolygon { + /// Instantiate. + #[inline] + #[must_use] + pub fn new(growable_polygon: &crate::growable_polygon::GrowablePolygon) -> Self { + let mut exterior = Vec::with_capacity(growable_polygon.vertices.len() * 2); + for vertex in &growable_polygon.vertices { + exterior.push(vertex.coordinate.x); + exterior.push(vertex.coordinate.y); + } + + let mut interiors = Vec::new(); + let mut hole_indices = Vec::with_capacity(growable_polygon.holes.len()); + + for hole in &growable_polygon.holes { + hole_indices.push( + u32::try_from(interiors.len()).expect("Couldn't cast `interiors.len()` to `u32`"), + ); + + for vertex in hole { + interiors.push(vertex.coordinate.x); + interiors.push(vertex.coordinate.y); + } + } + + Self { + exterior, + interiors, + hole_indices, + } + } +} + +/// Reconstruct a viewshed from raw polar segments. +/// +/// # Panics +/// When reconstructing the viewshed fails. +#[expect( + unreachable_pub, + reason = "We won't it to be `pub` for WASM but not avaiable outside the crate" +)] +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +#[must_use] +pub fn reconstruct(js_data: &js_sys::Array, dem_scale: f32) -> js_sys::Array { + console_error_panic_hook::set_once(); + let mut rust_data: Vec> = Vec::new(); + + for segments_for_angle in js_data.iter() { + let inner_js_array: js_sys::Array = segments_for_angle.unchecked_into(); + let mut inner_rust_vec = Vec::new(); + + for segment in inner_js_array.iter() { + #[expect( + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::as_conversions, + reason = " + We're only worried about the truncation here, but it's very unlikely. + Remember that this value is actually a bitpack of 2 `u16`s. + " + )] + let bitpack = segment + .as_f64() + .expect("Expected valid JavaScript `number`") as u32; + + inner_rust_vec.push(crate::segment::Segment(bitpack)); + } + rust_data.push(inner_rust_vec); + } + + let growable_polygons = crate::joiner::Joiner::join(&rust_data, dem_scale); + + let js_array = Array::new(); + for growable_polygon in growable_polygons { + let plain_polygon = PlainPolygon::new(&growable_polygon); + js_array.push(&JsValue::from(plain_polygon)); + } + js_array +}