Skip to content

Instantly share code, notes, and snippets.

@hakunin
Created March 25, 2010 18:30
Show Gist options
  • Save hakunin/343931 to your computer and use it in GitHub Desktop.
Save hakunin/343931 to your computer and use it in GitHub Desktop.
class FlightRouteDisplay {
function __construct($path) {
$this->path = $path;
}
function render()
{
$id = "route".(rand(100000, 999999));
// map over czech republic
$zoom = 6;
$latlong = '49.359235, 17.479736';
$apikey ="ABQIAAAAkBsuW648kLNaw0dn5_xzvRRLCYMPMKHvmKFpoXYpmsMnvv_zVxTIF849oC5JfwxnH8evTinI584S0g";
Response::add('head', '<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key='.$apikey.'" type="text/javascript"></script>');
$heliports = tree::getTypesWhere('heliport', '1');
$positions = array();
foreach ($heliports as $heliport) {
$positions []= $heliport->position;
$heli_ids []= $heliport->id;
}
$positions = '[['.join('], [', $positions).']]';
return '
<div id="'.$id.'_map_canvas" class="google_map" style="display:block; width:770px; height:455px;"></div>
<input type="hidden" name="'.$name.'" value="'.$this->path.'" id="'.$id.'"/>
<div id="route_info"></div>
<script>(function() {
var Point = function(x, y) {
var self = this;
self.x = x;
self.y = y;
this.plus = function(p) {
return new Point(self.x + p.x, self.y + p.y);
}
this.mul = function(n) {
return new Point(self.x * n, self.y * n);
}
this.toArray = function() {
return [self.x, self.y];
}
}
Point.fromGPoint = function(ll) {
return new Point(ll.lat(), ll.lng());
}
var LineSegment = function(a, b) {
var self = this;
this.a = a;
this.b = b;
this.length = function() {
return Math.sqrt(Math.pow(1*a.x-b.x, 2) + Math.pow(1*a.y-b.y, 2));
}
//var tolerance = 0.0025;
var tolerance = 0;
this.pointWithinRegion = function(c) {
var ac = new LineSegment(a, c);
var cb = new LineSegment(c, b);
return !((
(Math.pow(ac.length(), 2) + Math.pow(self.length(), 2)) < (Math.pow(cb.length(),2) -tolerance)
) || (
Math.pow(ac.length(), 2) > (Math.pow(self.length(), 2) + Math.pow(cb.length(),2) +tolerance)
))
}
this.distanceToPoint = function(c) {
var ac = new LineSegment(a, c);
var cb = new LineSegment(c, b);
var cxLen = (
Math.pow(ac.length(), 2) - Math.pow(cb.length(), 2) - Math.pow(self.length(), 2)
) / (-2*self.length());
return Math.sqrt(
Math.pow(cb.length(), 2) - Math.pow(cxLen, 2)
);
}
this.toPoint = function() {
return new Point(Math.abs(a.x - b.x), Math.abs(a.y - b.y));
}
this.toString = function() {
return "{a:"+a.toArray()+", b:"+b.toArray()+"}";
}
this.toHash = function() {
return {a:a.toArray(), b:b.toArray()};
}
}
var map = new GMap2(document.getElementById(\''.$id.'_map_canvas\'), {draggableCursor:"auto", draggingCursor:"move"});
map.setCenter(new GLatLng('.$latlong.'), '.$zoom.');
map.addControl(new GLargeMapControl()); // Zoom control
map.addMapType(G_PHYSICAL_MAP);
// Create a hierarchical map type control
var hierarchy = new GHierarchicalMapTypeControl();
// make Hybrid the Satellite default
hierarchy.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels", true);
map.addControl(hierarchy);
map.addControl(new GScaleControl());
//map.disableDoubleClickZoom();
var heliportIcon = new GIcon(G_DEFAULT_ICON);
heliportIcon.image = "'.file::pathTo('').'/public/heliport.png";
var stations = [];
var Station = (function(ll, map, route, name) {
var self = this;
self.position = ll;
self.name = name;
self.map = map;
self.route = route;
self.marker = new GMarker(self.position, {
icon:heliportIcon,
draggable:false,
bouncy:false
});
self.map.addOverlay(self.marker);
GEvent.addListener(self.marker, "click", function(overlay, point) {
self.route.setStation(self);
});
})
var Route = (function(map, info_el) {
var self = this;
self.coordinates = [];
self.markers = [];
self.map = map;
self.info_el = info_el;
self.setStation = function(station) {
self.station = station;
self.markers[0] = station.marker;
self.coordinates[0] = station.position;
self.refreshMarkerAt(0);
}
self.refreshMarkerAt = function(n) {
self.coordinates[n] = self.markers[n].getLatLng();
self.resetPath();
}
self.addPoint = function(ll, position) {
position = (position ? position : self.coordinates.length)
var marker = new GMarker(ll, {draggable:true, bouncy:false, dragCrossMove:false});
self.map.addOverlay(marker);
self.coordinates.splice(position, 0, ll);
self.markers.splice(position, 0, marker);
GEvent.addListener(marker, "drag", function() {
var markers = self.markers;
var l = markers.length;
var m, n;
for (m = 0; m < l; m++) {
if (markers[m] == marker) {
n = m; break;
}
}
self.refreshMarkerAt(n);
});
GEvent.addListener(marker, "contextmenu", function() {
self.removeMarker(marker);
});
GEvent.addListener(marker, "dblclick", function() {
self.removeMarker(marker);
});
}
this.removeMarker = function(marker) {
var markers = self.markers;
var l = markers.length;
var m, n;
for (m = 0; m < l; m++) {
if (markers[m] == marker) {
n = m; break;
}
}
self.coordinates.splice(n, 1);
self.markers.splice(n, 1);
//map.removeOverlay(markers[n]);
marker.hide();
self.resetPath();
}
GEvent.addListener(map, "click", function(overlay, ll) {
if (overlay) {
return; //clicked a marker
}
self.inspertPointAt(ll);
self.resetPath();
});
this.getCoordinates = function() {
var coords = self.coordinates.slice(0);
coords.push(coords[0]);
return coords;
}
this.inspertPointAt = function(ll) {
var position, shortest, distance;
var p = Point.fromGPoint(ll);
var coords = self.getCoordinates();
for (c = 0; c+1 < coords.length; c++) {
var ls = new LineSegment(
Point.fromGPoint(coords[c]),
Point.fromGPoint(coords[c+1])
)
if (!ls.pointWithinRegion(p)) {
continue;
}
distance = ls.distanceToPoint(p);
if (!shortest || (distance < shortest)) {
shortest = distance;
position = c+1;
}
}
self.addPoint(ll, position);
}
this.resetPath = function() {
if (self.route) {
self.map.removeOverlay(self.route);
self.map.removeOverlay(self.black);
self.map.removeOverlay(self.heliportRoute);
}
var coords = self.getCoordinates();
self.black = new GPolyline(coords, \'black\', 5, 1);
var length = Math.floor(self.black.getLength()/1000*100)/100;
coords.pop();
values = [];
for (var c = 0; c < coords.length; c++) {
var coor = coords[c];
values.push(coor.lat()+\',\'+coor.lng());
}
document.getElementById("'.$id.'").value = values.join(";");
var station = coords.shift();
self.heliportRoute = new GPolyline([coords[0], station, coords[coords.length -1]], \'#FFD800\', 3, 1);
self.route = new GPolyline(coords, \'#FF745B\', 3, 1);
self.map.addOverlay(self.black);
self.map.addOverlay(self.heliportRoute);
self.map.addOverlay(self.route);
var netto_length = Math.floor(new GPolyline(coords, \'#ff0000\', 2, 1).getLength()/1000*100)/100;
var yellow_length = Math.floor(self.heliportRoute.getLength()/1000*100)/100;
document.getElementById("redRoute").value = netto_length;
document.getElementById("yellowRoute").value = yellow_length;
document.getElementById("overallRoute").innerHTML = length + " km";
}
});
var route = new Route(map, document.getElementById(\'route_info\'));
var stationPositions = '.$positions.';
var p;
for (p = 0; p < stationPositions.length; p++) {
stations.push(new Station(new GLatLng(stationPositions[p][0], stationPositions[p][1]), map, route));
}
var coords = document.getElementById("'.$id.'").value.split(";");
if (coords.length > 1) {
for (var c = 0; c < coords.length; c++) {
var ll = coords[c].split(",");
var gll = new GLatLng(ll[0], ll[1]);
if (c == 0) {
var found = false;
for (var s = 0; s < stations.length; s++) {
if (stations[s].position.equals(gll)) {
//console.log(\'station is\', coords[c]);
route.setStation(stations[s]);
found = true;
break;
}
}
if (found) {
continue;
} else {
alert(\'Nenašel jsem stanici!\');
}
}
route.inspertPointAt(gll);
}
route.resetPath();
}
if (coords.length <= 1) {
route.setStation(stations[0]);
}
})();
</script>
';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment