Skip to content

Instantly share code, notes, and snippets.

@shashashasha
Created June 14, 2011 21:56
Show Gist options
  • Save shashashasha/1026018 to your computer and use it in GitHub Desktop.
Save shashashasha/1026018 to your computer and use it in GitHub Desktop.
Great Circles
org.polymaps.paths = function() {
var paths = org.polymaps.geoJson(),
mode = "arc", // or "line"
storedPaths = [];
// a and b are location objects, c is the optional class to apply to them
paths.connect = function(a, b, c) {
var locations = [];
locations.push([a.lon, a.lat]);
if (mode == 'arc') {
var num = 100;
for (var i = 0; i < num; i++) {
var loc = paths.interpolate(a, b, i / num);
locations.push([loc.lon, loc.lat]);
}
} else if (mode == 'line') {
// ignore
}
locations.push([b.lon, b.lat]);
// create a GeoJson LineString object
var feature = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: locations
},
id: a.lat + a.lon + "," + b.lat + b.lon,
properties: {
start: a,
end: b
}
};
storedPaths.push(feature);
};
paths.refreshPaths = function() {
paths.features(storedPaths);
};
// interpolation code from modestmaps.js by Tom Carden and Mike Migurski, etc
// http://code.google.com/p/modestmaps/source/browse/trunk/js/modestmaps.js
paths.interpolate = function(l1, l2, f) {
var deg2rad = Math.PI / 180.0,
lat1 = l1.lat * deg2rad,
lon1 = l1.lon * deg2rad,
lat2 = l2.lat * deg2rad,
lon2 = l2.lon * deg2rad;
var d = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin((lat1-lat2)/2),2) + Math.cos(lat1)*Math.cos(lat2)*Math.pow(Math.sin((lon1-lon2)/2),2)));
var bearing = Math.atan2(Math.sin(lon1-lon2)*Math.cos(lat2), Math.cos(lat1)*Math.sin(lat2)-Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon1-lon2)) / -(Math.PI/180);
bearing = bearing < 0 ? 360 + bearing : bearing;
var A = Math.sin((1-f)*d)/Math.sin(d);
var B = Math.sin(f*d)/Math.sin(d);
var x = A*Math.cos(lat1)*Math.cos(lon1) + B*Math.cos(lat2)*Math.cos(lon2);
var y = A*Math.cos(lat1)*Math.sin(lon1) + B*Math.cos(lat2)*Math.sin(lon2);
var z = A*Math.sin(lat1) + B*Math.sin(lat2);
var latN = Math.atan2(z,Math.sqrt(Math.pow(x,2)+Math.pow(y,2)));
var lonN = Math.atan2(y,x);
return { lat:latN/deg2rad, lon:lonN/deg2rad };
};
return paths;
};
<html>
<head>
<title>Great Circles</title>
<script type="text/javascript" src="https://raw.github.com/simplegeo/polymaps/master/polymaps.js"></script>
<script type="text/javascript" src="greatcircle.js"></script>
<style type="text/css">
body {
margin: 0;
}
svg {
width: 100%;
height: 100%;
}
.compass .back {
fill: #eee;
fill-opacity: .8;
}
.compass .fore {
stroke: #999;
stroke-width: 1.5px;
}
.compass rect.back.fore {
fill: #999;
fill-opacity: .3;
stroke: #eee;
stroke-width: 1px;
}
.compass .direction {
fill: none;
}
.compass .chevron {
fill: none;
stroke: #999;
stroke-width: 5px;
}
.compass .zoom .chevron {
stroke-width: 4px;
}
.layer path {
fill-opacity: 0.0;
stroke: #000;
stroke-width: 1px;
}
</style>
</head>
<body>
<div id="map">
</div>
<script type="text/javascript">
// 20760 blanker
var cloudmadeURL = "http://tile.cloudmade.com/1a1b06b230af4efdbb989ea99e9841af/22677/256/{Z}/{X}/{Y}.png";
var po = org.polymaps,
div = document.getElementById("map");
var map = po.map()
.container(div.appendChild(po.svg("svg")))
.center({lat: 10, lon: 0})
.zoom(2);
map.add(po.image()
.url(po.url("http://{S}tile.cloudmade.com"
+ "/5814d279db61404b9e52115b06b9e7b3" // http://cloudmade.com/register
+ "/22677/256/{Z}/{X}/{Y}.png")
.hosts(["a.", "b.", "c.", ""])));
var paths = po.paths();
map.add(paths);
// add the compass for navigation
map.add(po.compass()
.pan("none"));
var start = randomLocation();
for (var i = 0; i < 100; i++) {
paths.connect(start, randomLocation());
}
paths.refreshPaths();
function randomLocation() {
return {lat: Math.random() * 90 - 45, lon: Math.random() * 180 - 90};
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment