Created
March 25, 2010 18:30
-
-
Save hakunin/343931 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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&v=2&sensor=false&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