<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Bugs with 180 degrees longitude in .NET Maps SDK Questions</title>
    <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295668#M3476</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Could you provide simple reproducers for all the issues that you find with the geometry engine and attach them to this chain?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;cheers,&lt;/P&gt;&lt;P&gt;Antti&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Mon, 25 Apr 2016 15:52:49 GMT</pubDate>
    <dc:creator>AnttiKajanus1</dc:creator>
    <dc:date>2016-04-25T15:52:49Z</dc:date>
    <item>
      <title>Bugs with 180 degrees longitude</title>
      <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295666#M3474</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;There are "bugs" in multiple APIs handling of 180.&lt;/P&gt;&lt;P&gt;1. GeometryEngine.Project when converting to Web Mercator returns NaN for +/-180. It should return +/-pi*EarthWGS84Radius&lt;/P&gt;&lt;P&gt;2. Polyline graphics that span across the 180 line are connected the "long" way instead of the "short" way: a short line becomes one that spans the globe. &lt;/P&gt;&lt;P&gt;For problem 2, I understand there is a theoretical ambiguity as to which way to connect the lines. In most cases, picking the shortest path is likely to be the correct answer.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 18 Apr 2016 20:02:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295666#M3474</guid>
      <dc:creator>carloscasanova</dc:creator>
      <dc:date>2016-04-18T20:02:44Z</dc:date>
    </item>
    <item>
      <title>Re: Bugs with 180 degrees longitude</title>
      <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295667#M3475</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I've worked through many of the issues by just avoiding the GeometryEngine and using my own implementations instead. To make lines connect correctly, I test if a simple planar connect would be too long and if so, I adjust the "left" point to be the right by adding the width of the WebMercator projection before supplying the points to the runtime.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 25 Apr 2016 15:30:03 GMT</pubDate>
      <guid>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295667#M3475</guid>
      <dc:creator>carloscasanova</dc:creator>
      <dc:date>2016-04-25T15:30:03Z</dc:date>
    </item>
    <item>
      <title>Re: Bugs with 180 degrees longitude</title>
      <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295668#M3476</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Could you provide simple reproducers for all the issues that you find with the geometry engine and attach them to this chain?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;cheers,&lt;/P&gt;&lt;P&gt;Antti&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 25 Apr 2016 15:52:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295668#M3476</guid>
      <dc:creator>AnttiKajanus1</dc:creator>
      <dc:date>2016-04-25T15:52:49Z</dc:date>
    </item>
    <item>
      <title>Re: Bugs with 180 degrees longitude</title>
      <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295669#M3477</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm investigating your questions with our geometry team.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Cheers&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Mike&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 25 Apr 2016 16:40:29 GMT</pubDate>
      <guid>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295669#M3477</guid>
      <dc:creator>MichaelBranscomb</dc:creator>
      <dc:date>2016-04-25T16:40:29Z</dc:date>
    </item>
    <item>
      <title>Re: Bugs with 180 degrees longitude</title>
      <link>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295670#M3478</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Antti, I'll provide some examples below. There's more. I've written more than a thousand lines of workarounds last week and it is hard to keep track of it all! Another strange behavior I uncovered was the map view extent going null when the map center is set to NaN. Granted, NaN is nonesense, but SetViewAsync should complain/throw right away instead. The NaN made it to the map view because of innocent looking code like this:&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;static async void TestExtentAndSetView(MapView map, MapPoint point)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; var p = Project(NormalizeCentralMeridian(point), map.SpatialReference);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; var extent = NormalizeCentralMeridian(map.Extent);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; if (!Within(p, extent))&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; {&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try { await map.SetViewAsync(point, TimeSpan.FromSeconds(1.5)); }&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex) { /*log the error*/ }&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; }&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;I have since switched over to my own "envelope" and "projection" code that is easier to use and get right.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;H2&gt;&lt;STRONG&gt;GeometryEngine.Project&lt;/STRONG&gt;&lt;/H2&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;static MapPoint EsriProject(double lat, double lon)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; return (MapPoint)GeometryEngine.Project(new MapPoint(lon, lat, SpatialReferences.Wgs84), SpatialReferences.WebMercator);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;static MapPoint EsriUnProject(double x, double y)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; return (MapPoint)GeometryEngine.Project(new MapPoint(x, y, SpatialReferences.WebMercator), SpatialReferences.Wgs84);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;public void Test()&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; Action&amp;lt;double&amp;gt; xNaN = lon =&amp;gt; Assert.IsTrue(double.IsNaN(EsriProject(0, lon).X));&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; xNaN(-180);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; xNaN(180);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; xNaN(-179.99999);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&amp;nbsp; xNaN(179.99999);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;&lt;H2&gt;&lt;/H2&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;const double Wgs84EarthSemiMajorRadiusMeters = 6378137;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;const double webMercatorMaxX = Wgs84EarthSemiMajorRadiusMeters * System.Math.PI;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;var p1 = EsriUnProject(webMercatorMaxX, 0);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;var p2 = EsriUnProject(-webMercatorMaxX, 0);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;System.Console.WriteLine(p1); // prints MapPoint[X=NaN, Y=NaN, Wkid=4326]&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;System.Console.WriteLine(p2); // prints MapPoint[X=NaN, Y=NaN, Wkid=4326]&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;H2&gt;&lt;STRONG&gt;Envelopes, Polyline, etc&lt;/STRONG&gt;&lt;/H2&gt;&lt;P&gt;&lt;SPAN style="color: #333333; font-family: Arial, sans-serif; font-size: 14px;"&gt;Envelope unions do simple min/max and do not handle the wrap around. That means that the a union operation may connect the long way across the world when the intent is the short way. I've written my own "GeoRect" code that has a well defined left and right and can handle the wraparound. In other places, I do something like this:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;static void FixXsForEsri(ref double x1, ref double x2, double y1, double y2, double expectedLength)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;&amp;nbsp; var distSqd = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);&lt;/P&gt;&lt;P&gt;&amp;nbsp; bool simpleConnectWouldBeTheLongWayAcrossTheWorld = distSqd &amp;gt; expectedLength * expectedLength * 2.0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if (simpleConnectWouldBeTheLongWayAcrossTheWorld)&lt;/P&gt;&lt;P&gt;&amp;nbsp; {&lt;/P&gt;&lt;P&gt;&amp;nbsp; // Map X on negative side of the projection origin to the right.&lt;/P&gt;&lt;P&gt;&amp;nbsp; if (x2 &amp;lt; 0.0)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; x2 += GeoRectMaxBounds.WebMercator.Width;&lt;/P&gt;&lt;P&gt;&amp;nbsp; else if (x1 &amp;lt; 0.0)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; x1 += GeoRectMaxBounds.WebMercator.Width;&lt;/P&gt;&lt;P&gt;&amp;nbsp; }&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;I can see how the way Envelope behaves could be more renderer friendly. Simple min/max-ing is less "branchy" than the wrap test code. From a map API user's view, it is quite unfriendly.&lt;/P&gt;&lt;P&gt;Simple Repro:&lt;/P&gt;&lt;P&gt;var p1 = new MapPoint(179, 0, SpatialReferences.Wgs84);&lt;/P&gt;&lt;P&gt;var p2 = GeometryEngine.GeodesicMove(p1, 1e3, LinearUnits.Kilometers, 90);&lt;/P&gt;&lt;P&gt;var e1 = new Envelope(p1, p1);&lt;/P&gt;&lt;P&gt;var e2 = new Envelope(p2, p2);&lt;/P&gt;&lt;P&gt;System.Console.WriteLine(e1.Union(e2).Width); // prints 351.016847158805 degrees !!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 25 Apr 2016 17:39:18 GMT</pubDate>
      <guid>https://community.esri.com/t5/net-maps-sdk-questions/bugs-with-180-degrees-longitude/m-p/295670#M3478</guid>
      <dc:creator>carloscasanova</dc:creator>
      <dc:date>2016-04-25T17:39:18Z</dc:date>
    </item>
  </channel>
</rss>

