cusf-standalone-predictor/predict/js/pred/pred-map.js

216 wiersze
7.8 KiB
JavaScript

/*
* CUSF Landing Prediction Version 2
* Jon Sowman 2010
* jon@hexoc.com
* http://www.hexoc.com
*
* http://github.com/jonsowman/cusf-standalone-predictor
*
* This file contains all of the prediction javascript functions
* that are explicitly related to Google Map manipulation
*
*/
// Initialise the map canvas with (lat, long, zoom)
function initMap(centre_lat, centre_lon, zoom_level) {
// Make the map and set center
var latlng = new google.maps.LatLng(centre_lat, centre_lon);
var myOptions = {
zoom: zoom_level,
scaleControl: true,
scaleControlOptions: { position: google.maps.ControlPosition.BOTTOM_LEFT } ,
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: latlng
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
// Enable or disable user control of the map canvas, including scrolling,
// zooming and clicking
function enableMap(map, state) {
if ( state != false && state != true) {
appendDebug("Unrecognised map state");
} else if (state == false) {
map.draggable = false;
map.disableDoubleClickZoom = true;
map.scrollwheel = false;
map.navigationControl = false;
} else if (state == true ) {
map.draggable = true;
map.disableDoubleClickZoom = false;
map.scrollwheel = false;
map.navigationControl = true;
}
}
// This should be called on a "mousemove" event handler on the map canvas
// and will update scenario information display
function showMousePos(GLatLng) {
var curr_lat = GLatLng.lat().toFixed(4);
var curr_lon = GLatLng.lng().toFixed(4);
$("#cursor_lat").html(curr_lat);
$("#cursor_lon").html(curr_lon);
// if we have a prediction displayed
// show range from launch and land:
if ( current_uuid != 0 && map_items['launch_marker'] != null ) {
var launch_pt = map_items['launch_marker'].position;
var land_pt = map_items['land_marker'].position;
var range_launch = distHaversine(launch_pt, GLatLng, 1);
var range_land = distHaversine(land_pt, GLatLng, 1);
$("#cursor_pred_launchrange").html(range_launch);
$("#cursor_pred_landrange").html(range_land);
}
}
// Takes an array of points and the name of the gmap object and plots
// the polygon onto the map
function drawPolygon(points, gmap_object) {
var newPoly = new google.maps.Polyline({
path: points,
strokeColor: "#FF0000",
strokeOpacity: 0.4,
//fillColor: "#FFFFFF",
//fillOpacity: 0,
strokeWeight: 2
});
map_items['delta_square'] = newPoly;
newPoly.setMap(gmap_object);
}
// Read the latitude and longitude currently in the launch card and plot
// a marker there with hover information
function plotClick() {
// Clear the old marker
clearMapItems();
// Get the new values from the form
click_lat = parseFloat($("#lat").val());
click_lon = parseFloat($("#lon").val());
// Make sure the data is valid before we try and do anything with it
if ( isNaN(click_lat) || isNaN(click_lon) ) return;
var click_pt = new google.maps.LatLng(click_lat, click_lon);
clickMarker = new google.maps.Marker({
position: click_pt,
map: map,
icon: 'images/target-1-sm.png',
title: 'Currently selected launch location (' + click_lat + ', '
+ click_lon+')'
});
map_items['clickMarker'] = clickMarker;
// Redraw the delta square
drawDeltaSquare(map);
map.panTo(click_pt);
map.setZoom(8);
}
// Uses the currently selected lat, lon and delta values in the launch
// card to draw a square of the GFS data to be downloaded for the prediction
function drawDeltaSquare(map) {
// Clear the old delta square if it exists
if ( map_items['delta_square'] ) map_items['delta_square'].setMap(null);
// Get the values from the form
var lat = Math.round(parseFloat($("#lat").val()));
var lon = Math.round(parseFloat($("#lon").val()));
var dlat = parseFloat($("#delta_lat").val());
var dlon = parseFloat($("#delta_lon").val());
// Construct a rectange of points
var points = [
new google.maps.LatLng(lat+dlat, lon+dlon),
new google.maps.LatLng(lat-dlat, lon+dlon),
new google.maps.LatLng(lat-dlat, lon-dlon),
new google.maps.LatLng(lat+dlat, lon-dlon),
new google.maps.LatLng(lat+dlat, lon+dlon)
]
// Draw this polygon onto the map canvas
drawPolygon(points, map);
}
// Given a GLatLng object, write the latitude and longitude to the launch card
function setFormLatLon(GLatLng) {
appendDebug("Trying to set the form lat long");
$("#lat").val(GLatLng.lat().toFixed(4));
$("#lon").val(GLatLng.lng().toFixed(4));
// Remove the event handler so another click doesn't register
setLatLonByClick(false);
// Change the dropdown to read "other"
SetSiteOther();
// Plot the new marker for launch location
appendDebug("Plotting the new launch location marker");
plotClick();
}
// Enable or disable an event handler which, when a mouse click is detected
// on the map canvas, will write the coordinates of the clicked place to the
// launch card
function setLatLonByClick(state) {
if ( state == true ) {
// Check this listener doesn't already exist
if (!clickListener) {
appendDebug("Enabling the set with click listener");
clickListener = google.maps.event.addListener(map, 'click', function(event) {
appendDebug("Got a click from user, setting values into form");
$("#error_window").fadeOut();
setFormLatLon(event.latLng);
});
}
// Tell the user what to do next
throwError("Now click your desired launch location on the map");
} else if ( state == false ) {
appendDebug("Removing the set with click listener");
google.maps.event.removeListener(clickListener);
clickListener = null;
} else {
appendDebug("Unrecognised state for setLatLonByClick");
}
}
// An associative array exists globally containing all objects we have placed
// onto the map canvas - this function clears all of them
function clearMapItems() {
$("#cursor_pred").hide();
if( getAssocSize(map_items) > 0 ) {
appendDebug("Clearing previous map trace");
for( i in map_items ) {
map_items[i].setMap(null);
}
}
map_items = [];
}
// The Haversine formula to calculate the distance across the surface between
// two points on the Earth
distHaversine = function(p1, p2, precision) {
var R = 6371; // earth's mean radius in km
var dLat = rad(p2.lat() - p1.lat());
var dLong = rad(p2.lng() - p1.lng());
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
if ( precision == null ) {
return d.toFixed(3);
} else {
return d.toFixed(precision);
}
}
// Given a latitude, longitude, and a field to write the result to,
// find the name of the place using Google "reverse Geocode" API feature
function rvGeocode(lat, lon, fillField) {
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(parseFloat(lat), parseFloat(lon));
var coded = "Unnamed";
geocoder.geocode({'latLng': latlng}, function(results, status) {
if ( status == google.maps.GeocoderStatus.OK ) {
// Successfully got rv-geocode information
appendDebug("Got a good response from the geocode server");
coded = results[1].address_components[1].short_name;
} else {
appendDebug("The rv-geocode failed: " + status);
}
// Now write the value to the field
$("#"+fillField+"").val(coded);
});
}