Working with invalid Geography objects in SQL Azure

I was recently helping someone with a project that let the user to draw shapes on the map and upload the Well Know Text for the shape into a database. To do this they were making use of the Shape Toolbox and the Well Known Text modules for Bing Maps. Using these two modules together with a web service was really easy to do. However, although the generated Well Known Text is valid as a SQL Geometry object, they may not always be a valid Geography object depending on how the user drew the shape. In an attempt to account for this we came across a unique difference in the spatial functionality between SQL Azure and SQL 2012. If we were to create a Geography object using a Well Known Text that is invalid, SQL 2012 would create the object but would throw an error asking use to use the MakeValid method if we tried to do any calculations against it. However in SQL Azure it throws an error when we try to create the Geography. The Geography class has the MakeValid class in both databases and in SQL 2012 we just need to use that to fix our Geography and be on our way. However, reading through the release notes for spatial functionality in SQL Azure we find this:

In this release of SQL Azure, invalid objects are not allowed in the Geography type. Consequently, the MakeValid() method, while present and operational for the Geography type, cannot do anything more than operate over an already valid object – effectively a no-op.

What this means is that even though the MakeValid method is available it is pretty much useless to us as we can’t create invalid geographies.

To test this out for your self, try running the following SQL script against both database. SQL 2012 will work and return a value that indicates that the geography is invalid. SQL Azure with throw an error message on the first line.

Declare @g geography = geography::STGeomFromText('POLYGON ((113.991 63.771, 73.737 63.771, 73.737 42.793, 113.991 42.793, 113.991 63.771), (105.378 58.434, 83.229 58.434, 83.229 49.594, 105.378 49.594, 105.378 58.434))',4326);
Select @g.STIsValid()

 

So what can we do about this?

What makes a Geography Valid?

Before we dive into a solution we need to first understand what makes a geography object valid. The following is the basic criteria that is required:

  • No part of the shape should overlap with itself.
  • For Polygon & MultiPolygon objects:
    • Exterior rings must be ordered in a counter clockwise direction.
    • Inner rings must be ordered in a clockwise direction.
    • Rings must have the same start and end coordinates.

Solution 1 – SQL Spatial .NET Library

All the spatial functionality that is in SQL is available as a .NET library which you can use in your code. One solution to our problem is to make the Well Known Text valid in our web service before passing it to the database. This is fairly easy to do. For information on how to use the SQL Spatial .NET library in a web service take a look at this blog post I wrote. By doing this we will be using the same logic that is in SQL 2012 which allows us to create an invalid geography and then use the MakeValid method to fix it.

Solution 2 – Custom Stored Procedures

The first solution will work for a lot of situations, unfortunately the person I was helping had a Node.js backend and couldn’t make use of the .NET spatial library. So, I needed a different solution. I have written a lot of code in the past that helps to make Geographies valid in .NET in my Spatial Toolbox project, so this got me wondering how hard it would be to reuse this code logic in a Store Procedure. After a bit of work I ended up with 3 stored procedures.

I called the first stored procedure IsCCW. This method takes a Polygon ring or LineString from a Geometry object and checks to see if the coordinates are in a counter-clockwise direction. Here is the SQL script for this.

CREATE PROCEDURE IsCCW
@ring geometry,
@status bit output
AS
BEGIN
SET @status = 0;

--Ensure that there are at least 4 coordinates.
--Polygons in SQL 2008 must start and end with the same coordinate.
--As such they require a minium of 4 coordinates to be valid.
if (@ring.STNumPoints() < 4)
SET @status = 0;
ELSE
BEGIN
Declare @coordinate geometry = @ring.STPointN(1);

DECLARE @index1 int = 1;
DECLARE @i int = 1;

WHILE @i <= @ring.STNumPoints()
BEGIN
Declare @coordinate2 geometry = @ring.STPointN(@i);

IF (@coordinate2.STY > @coordinate.STY)
BEGIN
SET @coordinate = @coordinate2;
SET @index1 = @i;
END
SET @i = @i + 1
END

DECLARE @num4 int = @index1;

IF (@num4 < 0)
SET @num4 = @ring.STNumPoints() - 2;

DECLARE @num5 int = @index1 + 1;

IF(@num5 >= @ring.STNumPoints())
SET @num5 = 1;

Declare @coordinate3 geometry = @ring.STPointN(@num4);
Declare @coordinate4 geometry = @ring.STPointN(@num5);

Declare @num6 float = ((@coordinate4.STX - @coordinate.STX) * (@coordinate3.STY - @coordinate.STY)) -
((@coordinate4.STY - @coordinate.STY) * (@coordinate3.STX - @coordinate.STX));

IF (@num6 = 0)
IF (@coordinate3.STX > @coordinate4.STX)
SET @status = 1;
ELSE
SET @status = 0;

IF (@num6 > 0)
IF (@coordinate3.STX > @coordinate4.STX)
SET @status = 1;
ELSE
SET @status = 0;
END
END

 

I called the second stored procedure CreatePolygonFromRing. This method creates a valid Polygon Geometry out of a ring. Here is the SQL script for this.

CREATE PROCEDURE CreatePolygonFromRing
@ring geometry, @g geometry output
AS
BEGIN
Declare @isCCW bit;

EXEC IsCCW @ring, @isCCW output

IF (@isCCW = 1)
SET @g = geometry::STGeomFromText(REPLACE(@ring.STAsText(), 'LineString', 'Polygon(') + ')', 4326)
ELSE
BEGIN
DECLARE @wkt nvarchar(max) = 'POLYGON((';

-- reverse order of points
DECLARE @i int = @ring.STNumPoints();

WHILE @i > 0
BEGIN
SET @wkt += @ring.STPointN(@i).STX + ' ' + @ring.STPointN(@i).STY;

IF (@i > 1)
SET @wkt += ',';
SET @i = @i - 1
END

SET @wkt += '))';

SET @g = geometry::STGeomFromText(@wkt, 4326)
END
END

 

I called the third stored procedure MakeValidGeographyFromGeometry. This method takes a Geometry object and if it is a polygon uses the exterior ring to create a simple polygon, it then loops through each inner ring of the polygon and creates a simple polygon out of it and then uses it with the STDifference method to cut a hole in the main polygon. This fixes all the ring orientation issues. It then returns a valid Geography object or null if it is can’t be made valid. Here is the SQL script for this.

CREATE PROCEDURE MakeValidGeographyFromGeometry
@g geometry, @geoOut geography output
AS
BEGIN

-- Make sure geometry is valid
SET @g = @g.MakeValid()

DECLARE @i int;
Declare @tempGeom geometry;

SET @geoOut = null;

IF(@g.STIsSimple() = 1) -- Check that the geometry has no overlapping lines
IF(@g.InstanceOf('Polygon') = 1)
BEGIN
Declare @poly geometry;
Declare @isCCW bit;

Declare @ring geometry = @g.STExteriorRing();

EXEC CreatePolygonFromRing @ring, @poly output

SET @i = 1;

WHILE @i <= @g.STNumInteriorRing()
BEGIN
SET @ring = @g.STInteriorRingN(@i);

-- Turn ring into polygon
EXEC CreatePolygonFromRing @ring, @tempGeom output

-- Remove inner ring polygon from main polygon
SET @poly = @poly.STDifference(@tempGeom);

SET @i = @i + 1
END

SET @geoOut = geography::STGeomFromWKB(@poly.STAsBinary(), 4326);
END
ELSE IF(@g.InstanceOf('MultiPolygon') = 1 OR @g.InstanceOf('GeometryCollection') = 1)
BEGIN
SET @i = 2;

SET @tempGeom = @g.STGeometryN(1);
-- Convert the first geometry in the collection into geography
EXEC MakeValidGeographyFromGeometry @tempGeom, @geoOut output

DECLARE @tempGeo geography;

WHILE @i <= @g.STNumGeometries()
BEGIN
SET @tempGeom = @g.STGeometryN(@i);

-- Convert the additional geometries in the collection into geography
EXEC MakeValidGeographyFromGeometry @tempGeom, @tempGeo output

SET @geoOut = @geoOut.STUnion(@tempGeo);

SET @i = @i + 1
END
END
ELSE -- All other shapes
BEGIN
SET @geoOut = geography::STGeomFromWKB(@g.STAsBinary(), 4326);
END
END

 

At this point we have all that we need to make our Geography valid. If we go back to the original example that worked in SQL 2012 but threw an error in SQL Azure we can updated as follows to make use of these stored procedures:

Declare @g geometry = geometry::STGeomFromText('POLYGON ((113.991 63.771, 73.737 63.771, 73.737 42.793, 113.991 42.793, 113.991 63.771), (105.378 58.434, 83.229 58.434, 83.229 49.594, 105.378 49.594, 105.378 58.434))',4326);

Declare @h geography;
EXEC MakeValidGeographyFromGeometry @g, @h output

Select @h.STIsValid()

 

This now works in both databases.

4 thoughts on “Working with invalid Geography objects in SQL Azure

  1. I’ve tested with this geometry and it does not work:

    POLYGON ((-0.022710787262438581 38.845680599850965, -0.022139494352684686 38.846579619225139, -0.02199444629172043 38.846807791579124, -0.021954488076756578 38.846870627356587, -0.02166052006399697 38.84733327883152, -0.021233163755549327 38.848005686764765, -0.020286411641791707 38.849462887901588, -0.019598994035799108 38.850521024889169, -0.019492904176450332 38.8507009750304, -0.019247308261545141 38.851117684869394, -0.018885473839036319 38.851782177617551, -0.018026134877841438 38.853243126611829, -0.017602806267563859 38.853962894435156, -0.017590438956899861 38.853983754532081, -0.017588934297468391 38.853986315932815, -0.01758431284285138 38.853994183092134, -0.0175330766699166 38.853992260286731, -0.017286711630962102 38.853983045264684, -0.017085625405389566 38.853979411230782, -0.017054037148052762 38.853981669354596, -0.01700371683375855 38.853816400284764, -0.016986008059164288 38.853757399382509, -0.017184907965815625 38.853780184489452, -0.017209951467743997 38.853705033371568, -0.016750765845065275 38.853673477620248, -0.016415632269284018 38.853673848230407, -0.015537516909181344 38.853859599844263, -0.015261504650147218 38.853942041976509, -0.015201254623603416 38.853947652768213, -0.014962427815389928 38.853969589029035, -0.014858505890200159 38.8539341617874, -0.013878021113970662 38.854023357657304, -0.013830950942044566 38.854027185918547, -0.01318062349566926 38.854139915790384, -0.013134534585192348 38.854251555047981, -0.013121048707915346 38.854284155149344, -0.013120520823735238 38.854285159759407, -0.013094471325004619 38.854336732695351, -0.013001179709080457 38.854345537815874, -0.012899670803952565 38.854320861710654, -0.011213095288959562 38.853896368466188, -0.011151755884937427 38.85401785986582, -0.010762049001875211 38.853893858004732, -0.010475539303698706 38.853771611466243, -0.010328852771263646 38.853689355959709, -0.010170741227299303 38.853644876555173, -0.0098302057249224483 38.853544647898445, -0.0096281861670138649 38.853494273274656, -0.0096694787714539585 38.8533836599172, -0.00936067689583715 38.853311890386095, -0.0092158525620772615 38.853205441526711, -0.0087742755082921772 38.85314610763222, -0.0087514712487670974 38.853225253340142, -0.00872054550885106 38.853213167944283, -0.0084956928884565314 38.853099682483055, -0.008474900002866886 38.85309292131538, -0.0085356396853073953 38.853003428373661, -0.0081473299971801545 38.852882268938977, -0.0080929562264821179 38.853024115070866, -0.0078832534926213289 38.853051056266025, -0.0076945700696910528 38.853087266049663, -0.0064965956997752386 38.852595605462511, -0.0064191186120857334 38.852482467513596, -0.006262081785439611 38.852253091975655, -0.0060881418808659713 38.852054417099886, -0.0059810001010965922 38.851683131073081, -0.0057612474342132155 38.851256173967435, -0.0056044350034667838 38.851067426410104, -0.0055660753728851622 38.85097741974306, -0.00535481693113168 38.850535927816225, -0.0051832864789802006 38.850320437304418, -0.0051507952058830525 38.850200279637015, -0.0056416051506028983 38.850206477182169, -0.0061456101272814147 38.850214130033528, -0.0062819996510256734 38.850208269731894, -0.00628970641121783 38.850207981107069, -0.0064699029600871474 38.850200190259187, -0.00648060187126505 38.850199824535515, -0.0065692890153987637 38.850196548682561, -0.0067733964409135367 38.850261203692838, -0.0069204968311857148 38.850427231677315, -0.0069786741729797727 38.850478975351784, -0.007046353598046483 38.85066858091551, -0.0071324116609194224 38.850843208476718, -0.007314426402430599 38.85101752982554, -0.007436015467324586 38.851100431575404, -0.0075658787356994214 38.851136363652792, -0.0077313819551812976 38.85111065689204, -0.0079422177682458156 38.85091982360013, -0.0080498436056438711 38.850792275896715, -0.008170252347326783 38.850718997143055, -0.0082750990773644752 38.850667375977409, -0.0084477340505840024 38.85064949780368, -0.0088409179401811033 38.850665495782515, -0.0092344895542550154 38.850693279610368, -0.0098685692252551329 38.850763773059541, -0.0099939419541577642 38.8507589222668, -0.010091938662769757 38.8506842331628, -0.010047533428140116 38.850181329668466, -0.010079039396403778 38.850076373937341, -0.010128434653656334 38.850062036907978, -0.010160872450853568 38.850052641726073, -0.010240432216651284 38.850029778900314, -0.010293023130662419 38.85001472874535, -0.0102956396490105 38.850013940537352, -0.010348453109722981 38.849998704438605, -0.010385944625180672 38.850038101748559, -0.010426789778726936 38.850140470441104, -0.010599795793245515 38.85025690696645, -0.010865417666922773 38.85044924119105, -0.011062363196345034 38.850581460076206, -0.011164418882041241 38.850681893242879, -0.011265622674753973 38.850841167495631, -0.011288494417116761 38.850883549827252, -0.011344157038919358 38.850930221077363, -0.011399052499014054 38.8511850224983, -0.011540909844018212 38.851183253610635, -0.011645557723311892 38.8511486659183, -0.011602410512504668 38.8508912191205, -0.011731570067232385 38.85086157980237, -0.011914913181026205 38.850857212780959, -0.012435863263623731 38.850851333549059, -0.012863658557562696 38.850887410701439, -0.012987274379310619 38.850939178003472, -0.013079499890649517 38.85101409325744, -0.0132739728646166 38.851093219584293, -0.013478069612205422 38.851140917227667, -0.013659935053157589 38.851207936168528, -0.013926691800767936 38.851323482515959, -0.013929120929449514 38.851296573231167, -0.013930296032787917 38.851283479964252, -0.013930519650249235 38.851280591338138, -0.013946099301576727 38.85110965031933, -0.013853336460781976 38.851002943691256, -0.013519702312883701 38.850632735106153, -0.01340777312398507 38.8505087754841, -0.013199418728974651 38.850052448824449, -0.012824465235902546 38.849535914659171, -0.013191219416528772 38.849229516268622, -0.013357040417770597 38.849077943392665, -0.013396530765980182 38.8490418790097, -0.013495406927644128 38.848988155163333, -0.013514192083528194 38.848977399915334, -0.013653766656266926 38.848717492050312, -0.013702708308262679 38.848638030806008, -0.013857790500701246 38.848382406860345, -0.014030437278124471 38.84826173301645, -0.014543836991147949 38.848143162473662, -0.014886606414959903 38.848154942554693, -0.01518924369087713 38.8481740647737, -0.015439360337916217 38.848051842192163, -0.015470409305614956 38.848017797025513, -0.015473053306811226 38.848014935943468, -0.015528120673401648 38.847955225363485, -0.015523339397456055 38.847866611153172, -0.015448854669463075 38.847843306368723, -0.015100483254299755 38.8473915918787, -0.015097933559108547 38.847388504634687, -0.015066976794641234 38.847351106657335, -0.015057742118234442 38.847304314224608, -0.015043055887602533 38.847229649427071, -0.01542405154241111 38.847224674781465, -0.015676223639225762 38.847395998995545, -0.015675882827094808 38.847524109995192, -0.016241802751559356 38.847527961775171, -0.01668627490929209 38.847449631428042, -0.016671695544105563 38.847322892610194, -0.016858574991021769 38.84729626010143, -0.01704636479617061 38.847315553691914, -0.017233998872162492 38.847390971991238, -0.017330165175503568 38.847477498107857, -0.017450765149727564 38.847594103734828, -0.017609621265831817 38.847721800953273, -0.017887859331466031 38.847904428095092, -0.018162482992753179 38.848110381991425, -0.018305151025011759 38.848217411546194, -0.018563050513418874 38.848452805679045, -0.018818542966503732 38.848748089599653, -0.018993553998420429 38.848878871398163, -0.019048121841016254 38.848826199058038, -0.018881231139677056 38.848637099852546, -0.018764064559147125 38.84838157075815, -0.018455873161637347 38.847967930440532, -0.018487353965874379 38.847770086934517, -0.018906353377135473 38.847492679589628, -0.019134098910091775 38.847353541617153, -0.019088041462596857 38.847234554381053, -0.019071894239321669 38.847193260891956, -0.019184019696823842 38.847158648764783, -0.019407675848295169 38.847088989133887, -0.019457457980674109 38.847130042942808, -0.019642177159119516 38.847161028771573, -0.019782724777570516 38.847160905447119, -0.02010047093105069 38.847150160360869, -0.02021449957328969 38.847136033788331, -0.020437220588376982 38.847123242565857, -0.020443312019499608 38.847122904728529, -0.020502267926933652 38.847113811329443, -0.020548527797533831 38.84708279002254, -0.020656029730184423 38.847004422810585, -0.020704176105718241 38.84698245610798, -0.0207871980543474 38.846992288945145, -0.020861256120127628 38.847013524797148, -0.020956413934249029 38.847065114933372, -0.020999826267585325 38.847129846193454, -0.0210688171093436 38.847191937819851, -0.0211301455914984 38.847195485232547, -0.021175772697049754 38.847163128725839, -0.02115806186737865 38.847093227718489, -0.021139100570002435 38.847056241566605, -0.02107591887034008 38.8469762565654, -0.021040217255962387 38.846889704360926, -0.021005225971124673 38.846827822648365, -0.021009599925443177 38.846732755602758, -0.021113522029967725 38.846529162331578, -0.021125093123107272 38.846429674778577, -0.021126027526784542 38.846421812844738, -0.021180520846453253 38.8463105836087, -0.021271441761102759 38.846123731988776, -0.021865164859473946 38.845872772277538, -0.022021770419630209 38.845776105511476, -0.022095345634224196 38.845840235462838, -0.022175414463125775 38.845864828308713, -0.022272094190924605 38.84584097348074, -0.02239563994462352 38.845774171042258, -0.022538929800232033 38.84568667266759, -0.022673748736119326 38.845681919549129, -0.022710787262438581 38.845680599850965), (-0.013444707256034635 38.8522246766339, -0.013532687946762406 38.852195486050775, -0.013487705506216956 38.852112594545346, -0.013399724894937452 38.852141785091526, -0.013444707256034635 38.8522246766339))

  2. I’ve got this error:

    Mens 6522, Nivel 16, Estado 1, Procedimiento MakeValidGeographyFromGeometry, Línea 30
    Error de .NET Framework durante la ejecución de la rutina o agregado definido por el usuario “geometry”:
    System.ArgumentException: 24144: esta operación no se puede completar porque la instancia no es válida. Use MakeValid para convertirla en una instancia válida. Tenga en cuenta que MakeValid puede provocar que los puntos de una instancia de geometría se desplacen ligeramente.
    System.ArgumentException:
    en Microsoft.SqlServer.Types.SqlGeometry.ThrowIfInvalid()
    en Microsoft.SqlServer.Types.SqlGeometry.STDifference(SqlGeometry other)
    .
    Mens 6522, Nivel 16, Estado 1, Procedimiento MakeValidGeographyFromGeometry, Línea 34
    Error de .NET Framework durante la ejecución de la rutina o agregado definido por el usuario “geography”:
    System.ArgumentException: 24200: la entrada especificada no representa ninguna instancia de geografía válida. Use MakeValid para convertirla en una instancia válida. Tenga en cuenta que MakeValid puede provocar que los puntos de una instancia espacial se desplacen ligeramente.
    System.ArgumentException:
    en Microsoft.SqlServer.Types.SqlGeography..ctor(GeoData g, Int32 srid)
    en Microsoft.SqlServer.Types.SqlGeography.GeographyFromBinary(OpenGisType type, SqlBytes wkbGeography, Int32 srid)

    If I modify adding this lines:


    IF(@g.InstanceOf(‘Polygon’) = 1)
    BEGIN
    SET @g = @g.STUnion(@g.STPointN(1))
    Declare @poly geometry;

    EXEC polygonFromRing @ring, @tempGeom output
    — Remove inner ring polygon from main polygon
    SET @tempGeom = @tempGeom.STUnion(@tempGeom.STPointN(1))
    SET @poly = @poly.STDifference(@tempGeom);

    the error does not appear, but the interior ring then gets deformed.

    Any suggestion?

    Thanks.

  3. Not sure then. I know the Azure SQL team was planning to support the make valid function. I guess it’s not live yet. If it is just this one polygon, you can use the SQL management studio locally to correct this polygon. When I do this and use the IsValidDetailed function it says the following:

    24412: Not valid because the interior of a polygon with rings (2) and (1) is not connected.

    Here is a valid version of this polygon:

    POLYGON ((-0.022710787262421268 38.8456805998511, -0.022673748736107894 38.845681919549051, -0.022538929800272656 38.845686672667519, -0.022395639944667138 38.845774171042329, -0.022272094190780908 38.845840973480804, -0.022175414462997412 38.845864828308741, -0.022095345634083628 38.845840235462973, -0.022021770419808556 38.845776105511518, -0.021865164859626168 38.845872772277417, -0.021271441760922952 38.846123731988818, -0.021180520846502484 38.84631058360857, -0.021126027526870018 38.846421812844618, -0.021125093123193307 38.846429674778676, -0.021113522030099151 38.846529162331549, -0.0210095999255751 38.846732755602723, -0.021005225971220502 38.846827822648386, -0.021040217255918838 38.846889704361033, -0.021075918870416106 38.846976256565284, -0.021139100569873778 38.847056241566662, -0.021158061867259586 38.847093227718588, -0.021175772697100994 38.847163128725946, -0.02113014559159462 38.847195485232447, -0.021068817109299233 38.847191937819872, -0.020999826267647854 38.847129846193333, -0.020956413934064912 38.847065114933308, -0.02086125612019565 38.847013524797248, -0.020787198054400678 38.846992288945096, -0.020704176105596633 38.846982456108066, -0.020656029730046863 38.847004422810549, -0.020548527797666187 38.847082790022505, -0.020502267926815258 38.847113811329571, -0.020443312019405514 38.847122904728494, -0.020437220588207173 38.847123242565736, -0.020214499573332954 38.8471360337884, -0.020100470930942749 38.84715016036079, -0.019782724777651393 38.847160905447005, -0.019642177159278133 38.84716102877163, -0.0194574579807137 38.847130042942943, -0.019407675848159531 38.847088989133766, -0.019184019696947965 38.847158648764754, -0.019071894239274211 38.847193260892048, -0.019088041462753464 38.84723455438116, -0.019134098910071024 38.847353541617046, -0.018906353377023635 38.8474926795897, -0.018487353965703047 38.847770086934631, -0.018455873161585885 38.847967930440554, -0.018764064559284237 38.848381570758072, -0.018881231139620827 38.848637099852574, -0.019048121841069417 38.848826199058067, -0.01899355399842453 38.848878871398185, -0.018818542966484702 38.848748089599617, -0.018563050513331403 38.848452805679131, -0.0183051510249465 38.848217411546266, -0.01816248299280198 38.848110381991468, -0.017887859331525272 38.847904428095, -0.017609621265979009 38.847721800953252, -0.017450765149551503 38.8475941037348, -0.017330165175493618 38.847477498107864, -0.017233998872069355 38.847390971991352, -0.01704636479624071 38.847315553691992, -0.016858574991085867 38.847296260101359, -0.016671695544170004 38.847322892610094, -0.01668627490934611 38.847449631428184, -0.01624180275165624 38.847527961775079, -0.015675882827141569 38.847524109995319, -0.015676223639084923 38.847395998995417, -0.015424051542300924 38.847224674781415, -0.015043055887579692 38.847229649427121, -0.015057742118071845 38.847304314224537, -0.015066976794484587 38.847351106657378, -0.015097933559243404 38.847388504634708, -0.015100483254278811 38.84739159187879, -0.0154488546696161 38.847843306368723, -0.015523339397442781 38.847866611153115, -0.015528120673438593 38.847955225363556, -0.015473053306874119 38.848014935943347, -0.015470409305749382 38.848017797025641, -0.015439360337873966 38.848051842192262, -0.015189243691018348 38.8481740647737, -0.014886606415120195 38.848154942554551, -0.014543836990978236 38.84814316247369, -0.014030437278195159 38.848261733016557, -0.013857790500728237 38.848382406860274, -0.01370270830838633 38.848638030806065, -0.013653766656253204 38.84871749205027, -0.013514192083665257 38.848977399915455, -0.013495406927640842 38.848988155163426, -0.013396530766151734 38.849041879009732, -0.013357040417874035 38.849077943392764, -0.013191219416581848 38.849229516268473, -0.01282446523597831 38.849535914659157, -0.013199418728931999 38.850052448824421, -0.013407773123996306 38.850508775484208, -0.01351970231300024 38.850632735106032, -0.013853336460786275 38.851002943691384, -0.013946099301742225 38.851109650319309, -0.013930519650242971 38.851280591338117, -0.013930296032808792 38.851283479964152, -0.013929120929579278 38.851296573231032, -0.013926691800810529 38.851323482515895, -0.013659935053157796 38.851207936168557, -0.013478069612049682 38.851140917227745, -0.013273972864795272 38.851093219584364, -0.013079499890622834 38.8510140932574, -0.012987274379200503 38.850939178003571, -0.012863658557525859 38.850887410701567, -0.012435863263727169 38.850851333549066, -0.011914913180913101 38.85085721278093, -0.011731570067178194 38.850861579802469, -0.011602410512638077 38.850891219120406, -0.01164555772326426 38.851148665918387, -0.011540909844054146 38.851183253610557, -0.01139905249909547 38.851185022498257, -0.011344157039031161 38.85093022107722, -0.011288494417105756 38.8508835498273, -0.011265622674600784 38.850841167495638, -0.011164418881989225 38.850681893242957, -0.011062363196172917 38.8505814600762, -0.010865417667027496 38.850449241191185, -0.010599795793205052 38.850256906966464, -0.010426789778884298 38.850140470441175, -0.010385944625133472 38.850038101748481, -0.010348453109727835 38.849998704438569, -0.010295639649056817 38.850013940537274, -0.010293023130510092 38.850014728745428, -0.010240432216644208 38.850029778900272, -0.010160872450940803 38.850052641726023, -0.010128434653831253 38.850062036908078, -0.010079039396505151 38.850076373937327, -0.010047533428298512 38.850181329668381, -0.010091938662796032 38.850684233162781, -0.0099939419543100469 38.850758922266742, -0.0098685692252154528 38.850763773059654, -0.009234489554267 38.850693279610304, -0.0088409179400844237 38.8506654957825, -0.0084477340504089619 38.850649497803772, -0.0082750990773856024 38.850667375977537, -0.0081702523474662669 38.850718997142955, -0.00804984360580509 38.850792275896779, -0.0079422177683399538 38.850919823600087, -0.0077313819551830818 38.851110656892146, -0.007565878735632108 38.851136363652714, -0.0074360154673413894 38.851100431575475, -0.0073144264022554015 38.85101752982564, -0.0071324116611017939 38.850843208476725, -0.0070463535980320527 38.850668580915446, -0.0069786741730898244 38.850478975351876, -0.0069204968312273352 38.850427231677379, -0.00677339644107686 38.85026120369271, -0.0065692890155119987 38.8501965486827, -0.006480601871415307 38.850199824535416, -0.0064699029601842919 38.850200190259216, -0.0062897064112537 38.850207981106927, -0.0062819996511955445 38.850208269731773, -0.0061456101274581709 38.850214130033578, -0.0056416051506156814 38.850206477182191, -0.005150795205739374 38.85020027963693, -0.0051832864789541928 38.850320437304347, -0.0053548169310756871 38.85053592781636, -0.005566075373045638 38.850977419743188, -0.00560443500343046 38.851067426410026, -0.0057612474343747694 38.85125617396757, -0.0059810001010339774 38.851683131073088, -0.006088141880880092 38.852054417099943, -0.0062620817852946991 38.852253091975719, -0.00641911861221159 38.852482467513475, -0.0064965956999213179 38.852595605462568, -0.0076945700698665071 38.85308726604972, -0.00788325349272934 38.85305105626616, -0.0080929562264885156 38.853024115070724, -0.0081473299972199646 38.852882268938941, -0.00853563968537918 38.853003428373576, -0.0084749000028822609 38.853092921315444, -0.0084956928884492317 38.853099682483027, -0.008720545508775969 38.853213167944347, -0.0087514712488307982 38.8532252533401, -0.0087742755083048182 38.853146107632085, -0.0092158525621333417 38.853205441526612, -0.00936067689589935 38.853311890386223, -0.0096694787716371539 38.853383659917135, -0.0096281861668963322 38.853494273274528, -0.00983020572475553 38.853544647898531, -0.010170741227328327 38.8536448765553, -0.01032885277113822 38.853689355959666, -0.010475539303651702 38.85377161146625, -0.010762049002054373 38.853893858004867, -0.01115175588479872 38.854017859865834, -0.011213095288822694 38.853896368466074, -0.012899670803892017 38.854320861710768, -0.013001179709012873 38.854345537815995, -0.013094471325042678 38.854336732695288, -0.013120520823597567 38.854285159759307, -0.013121048707984773 38.854284155149465, -0.013134534585110113 38.854251555047959, -0.013180623495634551 38.8541399157905, -0.013830950942057533 38.85402718591854, -0.013878021113839805 38.854023357657326, -0.014858505890256118 38.853934161787514, -0.014962427815366167 38.853969589028914, -0.015201254623543995 38.853947652768142, -0.015261504650070938 38.853942041976381, -0.015537516909318585 38.853859599844142, -0.016415632269448196 38.853673848230535, -0.016750765845226608 38.853673477620276, -0.017209951467795415 38.85370503337159, -0.017184907965822446 38.853780184489345, -0.016986008058985733 38.853757399382509, -0.017003716833711206 38.853816400284764, -0.017054037148136265 38.853981669354575, -0.017085625405498874 38.85397941123086, -0.017286711630826328 38.853983045264648, -0.017533076670022719 38.853992260286681, -0.0175843128427799 38.853994183092169, -0.017588934297621713 38.853986315932858, -0.017590438956815578 38.85398375453213, -0.017602806267612858 38.853962894435043, -0.018026134877680979 38.853243126611844, -0.018885473839163135 38.851782177617586, -0.019247308261608111 38.851117684869308, -0.019492904176283205 38.850700975030307, -0.019598994035625296 38.850521024889105, -0.020286411641755264 38.849462887901709, -0.021233163755682138 38.848005686764722, -0.021660520063959635 38.847333278831613, -0.021954488076894981 38.846870627356466, -0.021994446291649684 38.846807791579074, -0.022139494352690654 38.846579619225047, -0.022710787262421268 38.8456805998511), (-0.013532687946794863 38.8521954860508, -0.013444707256008754 38.85222467663398, -0.013399724894938321 38.852141785091533, -0.013487705506329531 38.852112594545467, -0.013532687946794863 38.8521954860508))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s