<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Azavea Labs &#187; IDL</title>
	<atom:link href="http://www.azavea.com/blogs/labs/tag/idl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.azavea.com/blogs/labs</link>
	<description>Insight on what our engineers are doing</description>
	<lastBuildDate>Thu, 26 Jan 2012 16:14:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>OpenLayers Map Centering and the International Date Line</title>
		<link>http://www.azavea.com/blogs/labs/2009/08/openlayers-map-centering-and-the-international-date-line/</link>
		<comments>http://www.azavea.com/blogs/labs/2009/08/openlayers-map-centering-and-the-international-date-line/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 18:37:57 +0000</pubDate>
		<dc:creator>Carissa Brittain</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[IDL]]></category>
		<category><![CDATA[openlayers]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=232</guid>
		<description><![CDATA[I recently came across another piece of OpenLayers to be aware of when working with maps that wrap the International Date Line. I store the map extent throughout a user's session so they can leave the map page, come back, and still see the same set of results as when they left. Unfortunately, the map was sometimes taking a stored location in the North Pacific and displaying Northern Africa instead! Obviously not what I want it to do...]]></description>
			<content:encoded><![CDATA[<p>I recently came across another piece of OpenLayers to be aware of when working with maps that wrap the International Date Line. I store the map extent throughout a user&#8217;s <a title="Temporary communication contracts, anyone?" href="http://en.wikipedia.org/wiki/Session_(computer_science)" target="_blank">session </a>so they can leave the map page, come back, and still see the same set of results as when they left. Unfortunately, the map was sometimes taking a stored location in the <a title="Lots of water..." href="http://www.pmel.noaa.gov/np/pages/seas/npmap1.html" target="_blank">North Pacific</a> and displaying <a title="... lots of sand" href="http://en.wikipedia.org/wiki/Northern_Africa" target="_blank">Northern Africa</a> instead! Obviously not what I want it to do. Before I get into why this happens, here&#8217;s a few OpenLayers object introductions to make sure we&#8217;re all on the same page.</p>
<p>The <a title="OpenLayers.Layer" href="http://dev.openlayers.org/apidocs/files/OpenLayers/Layer-js.html">Layer object</a> can understand what projection you&#8217;re working in, if you happen to give it one. If the displayed map area happens to wrap around the IDL (and your layers are set up correctly), the Layer object gracefully acknowledges the IDL and produces correct coordinates.</p>
<p>In contrast, the <a title="OpenLayers.BaseTypes.Bounds" href="http://dev.openlayers.org/apidocs/files/OpenLayers/BaseTypes/Bounds-js.html" target="_blank">Bounds object</a> is pure math. It&#8217;s meant to be as projection-agnostic as possible without actually messing up coordinates in objects that do know about <a title="An intro to the subject" href="http://members.shaw.ca/quadibloc/maps/mapint.htm" target="_self">projections </a>and their quirks. This can be a very good thing, since doing math without worrying about projections is a lot faster and works just fine in most cases.</p>
<p>The problem I ran into comes from one little Layer object configuration option that is uncharacteristically poorly documented: wrapDateLine. The issue it tells you to reference (#487) talks about using <a title="Like clocks" href="http://en.wikipedia.org/wiki/Modular_arithmetic" target="_blank">modular arithmatic</a> to fix how layers handle the IDL&#8230; I&#8217;m not a math person, but handling the IDL is exactly what I want it to do! Too bad they couldn&#8217;t have mentioned this in the documentation.  <img src='http://www.azavea.com/blogs/labs/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   What the Map winds up doing if you don&#8217;t have this config option set is using the Bounds object&#8217;s straight-up math to get the center of the extent. Unfortunately, using straight math when the IDL is in play puts the center of the map at the longitude exactly opposite of where logic dictates it should go. If the wrapDateLine configuration item is set, then the Layer tells the Map &#8220;<a title="Hi Ho Silver!" href="http://www.otr.net/?p=lone" target="_blank">Whoa, there!</a> The Bounds object doesn&#8217;t know about the IDL, but I do. Use my math first.&#8221; So the Map uses the Layer&#8217;s math to turn the extent into coordinates that the Bounds object&#8217;s math will work correctly on. Viola! <a title="I'm sailing away..." href="http://go.hrw.com/atlas/norm_map/npacific.gif" target="_blank">The North Pacific</a>!</p>
<p>So the simple fix is to have <a title="OpenLayers example code" href="http://openlayers.org/dev/examples/wrapDateLine.html">wrapDateLine: true</a> in your layer configuration object.</p>
<p>To see this bit of oddness &#8216;in action&#8217;, go to the <a title="OpenLayers example code" href="http://openlayers.org/dev/examples/google.html">OpenLayers Google Map example</a> and pan the map so that the IDL is in view. Using FireBug, enter the commands <strong>map.getCenter()</strong> and <strong>map.getExtent().getCenterLonLat()</strong>. The resulting coordinate longitudes will be on opposite sides of the planet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2009/08/openlayers-map-centering-and-the-international-date-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Azavea R&amp;D: sourcemap.org (pt. 2)</title>
		<link>http://www.azavea.com/blogs/labs/2009/06/azavea-rd-sourcemaporg2/</link>
		<comments>http://www.azavea.com/blogs/labs/2009/06/azavea-rd-sourcemaporg2/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 15:13:58 +0000</pubDate>
		<dc:creator>David Zwarg</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[Cartography]]></category>
		<category><![CDATA[IDL]]></category>
		<category><![CDATA[mit]]></category>
		<category><![CDATA[sourcemap]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=115</guid>
		<description><![CDATA[So why does the International Date Line (IDL) cause so many headaches?  It seems like a really simple problem, but it ends up touching a bunch of mapping concepts, none of which are easily dealt with.  I ran across this when working on the Sourcemap project, when we wanted to relatively realistic travel paths.  When I say "relatively", I mean, don't travel from Japan to California via France.]]></description>
			<content:encoded><![CDATA[<p>So why does the <a href="http://en.wikipedia.org/wiki/International_date_line">International Date Line (IDL)</a> cause so many <a href="http://www.azavea.com/blogs/labs/index.php/2009/04/distance-math-what/">headaches</a>?  It seems like a really simple problem, but it ends up touching a bunch of mapping concepts, none of which are easily dealt with.  I ran across this when working on the <a href="http://www.sourcemap.org/">Sourcemap</a> project, when we wanted to relatively realistic travel paths.  When I say &#8220;relatively&#8221;, I mean, don&#8217;t travel from Japan to California via France  (and not via <a href="http://maps.google.com/maps?f=d&amp;source=s_d&amp;saddr=japan&amp;daddr=california,+ca&amp;hl=en&amp;geocode=&amp;mra=ls&amp;dirflg=d&amp;sll=34.887365,-148.54983&amp;sspn=167.800164,226.40625&amp;ie=UTF8&amp;z=3">Kayak</a>, either).</p>
<p>For Sourcemap, we started visualizing larger and larger networks, and began noticing that nothing from China was ever connected to anything in North America vai the Pacific Ocean. When you want to visualize a globally connected network, it helps if the network knows that the map is a globe, and creates connections in the direction that minimizes the distance between points.  Using the built in cartography of OpenLayers, we get the following map:</p>
<p style="text-align: center;"><a href="http://www.azavea.com/blogs/labs/wp-content/uploads/2009/05/eurocentric.png"><img class="size-medium wp-image-118 aligncenter" src="http://www.azavea.com/blogs/labs/wp-content/uploads/2009/05/eurocentric-300x172.png" alt="eurocentric" width="300" height="172" /></a></p>
<p>Where the network is always constrained within the rectangle of -180, -90, 180, 90 (x<sub>min</sub>, y<sub>min</sub>, x<sub>max</sub>, y<sub>max</sub>).  I approached this a couple of ways, and the one that turned out to be the easiest exploits a lesser-known &#8216;feature&#8217; of OpenLayers, whereby a Longitude that exceeds the coordinate system (e.g. -200) is indeed rendered on the opposite side of the IDL (e.g. +160).</p>
<p>This is excellent! Now I know that OpenLayers can render multiple instances of a feature in a single map.  Instead of adding single vector features, I added multipart features{multipoint and multiline), with each individual feature in that multipart offset by 360 degrees from the next.</p>
<p>Interestingly enough, OpenLayers also does some flipping of your features when you cross the IDL.  When you grab the map and pan across the IDL, your features will flip into the coordinate system that contains the center point of the map.  For this reason, I created 3 versions of everything, and placed them at (x &#8211; 360), (x), and (x + 360).  This allows for continuous coverage on the map, even when the features are flipped over the IDL.</p>
<p>The result:</p>
<p style="text-align: center;"><img class="aligncenter size-medium wp-image-128" src="http://www.azavea.com/blogs/labs/wp-content/uploads/2009/06/wraparound-475x272.png" alt="Over the IDL" width="300" height="172" /></p>
<p style="text-align: left;">Now the maps reflect more accurately the trip of objects around the world! Each line is the shortest path between points, and are allowed to cross the IDL if necessary.  For the purposes of Sourcemap, it was important to be able to show these trips, since we are discussing ways of modeling the transportation networks of goods around the world.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2009/06/azavea-rd-sourcemaporg2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Distance? Math? What?</title>
		<link>http://www.azavea.com/blogs/labs/2009/04/distance-math-what/</link>
		<comments>http://www.azavea.com/blogs/labs/2009/04/distance-math-what/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 18:52:21 +0000</pubDate>
		<dc:creator>Carissa Brittain</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[IDL]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=31</guid>
		<description><![CDATA[A few days ago, I became painfully aware that the distance equation we all learn in geometry class, while it works perfectly well on flat, local projections,  is woefully inadequate when we&#8217;re talking about global coordinate systems. In the midst of implementing Google Maps in our up-coming Sajara sample application, I realized that the International [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, I became painfully aware that the distance equation we all learn in geometry class, while it works perfectly well on flat, local projections,  is woefully inadequate when we&#8217;re talking about global coordinate systems.</p>
<p>In the midst of implementing <a title="Google Maps API" href="http://code.google.com/apis/maps/documentation/index.html" target="_blank">Google Maps</a> in our up-coming <a title="Sajara Product Site" href="http://www.azavea.com/Products/Sajara/Home.aspx" target="_blank">Sajara</a> sample application, I realized that the <a title="Wikipedia: IDL" href="http://en.wikipedia.org/wiki/International_Date_Line" target="_blank">International Date Line</a> was causing problems. Large problems. Whenever the IDL was <a title="Play Ball!" href="http://en.wikipedia.org/wiki/List_of_baseball_jargon_(I)#in_play">in play</a>, I never retrieved the correct results from our database. One large problem was how we defined our <a title="Openlayers bounding box" href="http://dev.openlayers.org/apidocs/files/OpenLayers/BaseTypes/Bounds-js.html#OpenLayers.Bounds">bounding box</a> inside Sajara itself. Once that was fixed, however, I realized that something was still wrong. The Nearest-to-Farthest sort was not behaving quite right: it was really doing a Nearest-on-this-side-of-the-IDL-first sort! The IDL was acting like a <a href="http://en.wikipedia.org/wiki/Hadrian%27s_wall">wall</a> for our distance sort.</p>
<div id="attachment_39" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-39" src="http://www.azavea.com/blogs/labs/wp-content/uploads/2009/04/distance-300x234.gif" alt="distance" width="300" height="234" /><p class="wp-caption-text">Example of linear distance with IDL in play. X = center of map</p></div>
<p style="text-align: center">
<p>Here&#8217;s what we used before (in <a title="Transact SQL" href="http://en.wikipedia.org/wiki/TSQL">sql-speak</a>):</p>
<pre><span style="color: #800000">RETURN sqrt(power(@FromX - @ToX,2) + power(@FromY - @ToY,2))</span></pre>
<p>Your standard square-root of difference-squared plus difference-squared. This formula is fast and worked perfectly well so long as I operated under these two criteria:</p>
<p>1. a FLAT <a href="http://en.wikipedia.org/wiki/Map_projection">projection</a><br />
2. POSITIVE numbers only</p>
<p>Once either of those things aren&#8217;t true anymore, I can&#8217;t use the basic distance formula. In my case, both things stopped being true at the same time! The solution? Something fairly math-magical to my mind, but accepted as THE formula to get at the distance between any two global coordinates: the <a title="Haversine Formula" href="http://en.wikipedia.org/wiki/Haversine_formula">Haversine Formula</a>. Delving into descriptions of the formula brings up concepts such as <a href="http://mathworld.wolfram.com/SphericalTriangle.html">spherical triangles</a>, the planet&#8217;s <a title="Elipticity" href="http://en.wikipedia.org/wiki/Ellipsoid">elipticity</a>, <a title="Great Circles" href="http://en.wikipedia.org/wiki/Great_circle">great circles</a> and other things very important to <a title="Polynesian Navigation" href="http://www.teara.govt.nz/NewZealanders/MaoriNewZealanders/CanoeNavigation/2/en">navigation</a>. It&#8217;s accurate down to about a meter, which is plenty for anything I&#8217;ll be doing with it.</p>
<p>Haversine Formula <a title="javascript implementation" href="http://www.movable-type.co.uk/scripts/latlong.html">in Javascript</a>:</p>
<pre style="margin-left: 0pt"><span style="color: #800000">var R = 6371; // radius of the earth
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var distance = R * c;</span></pre>
<p>So here is the resulting SQL function that gives me the right distance between any two global coordinates.. basically a direct translation of the above javascript into T-SQL:</p>
<pre style="margin-left: 0pt"><span style="color: #800000">CREATE FUNCTION [dbo].[distance] (@FromX float, @FromY float, @ToX float, @ToY float)
RETURNS float AS BEGIN
DECLARE @R AS FLOAT;
SET @R = 6371;
DECLARE @DLAT AS FLOAT;
DECLARE @DLON AS FLOAT;
DECLARE @A AS FLOAT;
DECLARE @C AS FLOAT;
DECLARE @D AS FLOAT;
SET @DLAT = RADIANS(@ToY - @FromY);
SET @DLON = RADIANS(@ToX - @FromX);
SET @A =
SIN(@DLAT/2) * SIN(@DLAT/2) +
COS(RADIANS(@FromY)) * COS(RADIANS(@ToY)) * SIN(@DLON/2) * SIN(@DLON/2);
SET @C = 2 * ATN2(SQRT(@A), SQRT(1-@A));
SET @D = @R * @C;
RETURN @D
END</span></pre>
<p><a title="http://en.wikipedia.org/wiki/Haversine_formula " href="http://en.wikipedia.org/wiki/Haversine_formula" target="_blank"><br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2009/04/distance-math-what/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

