google maps api 3 - javascript - How to calculate the time of the closest point of approach? -
i working on program can calculate closest point of approach of storm city using javascript , google map api. found this method, , although not understand how scripts work, can still calculate closest distance, verified this website. code follow:
var maproute; var rtpoints; var centermap = new google.maps.latlng(22.3, 114.2); function routemap() { maproute = new google.maps.map(document.getelementbyid('maproute'), { center: centermap, zoom: 5, maptypeid: google.maps.maptypeid.satellite }); var rtpoints = [ new google.maps.latlng(20.3, 118.9), // new google.maps.latlng(21.4, 114.6), // +24hr new google.maps.latlng(22.5, 110.4), // +48hr ]; var rtpoly = new google.maps.polyline({ path: rtpoints, strokecolor: "#0000ff", strokeweight: 3, map: maproute }); var container = document.createelement("div"); container.style.fontfamily = 'arial'; container.style.fontsize = 'xx-small'; var ptr = document.createelement("input"); ptr.style.width = "100px"; ptr.type = "text"; ptr.readonly = true; ptr.id = "distptr"; container.appendchild(ptr); document.getelementbyid("control").appendchild(container); document.getelementbyid('distptr').value = math.round(bdccgeodistancetopolymtrs(rtpoly, new google.maps.latlng(22.3, 114.17))/1000); // in km } google.maps.event.adddomlistener(window, 'load', routemap); // code find distance in metres between lat/lng point , polyline of lat/lng points // in wgs84. free use. // // bill chadwick 2007 // updated google maps api v3, lawrence ross 2014 // construct bdccgeo latitude , longitude in degrees function bdccgeo(lat, lon) { var theta = (lon * math.pi / 180.0); var rlat = bdccgeogeocentriclatitude(lat * math.pi / 180.0); var c = math.cos(rlat); this.x = c * math.cos(theta); this.y = c * math.sin(theta); this.z = math.sin(rlat); } bdccgeo.prototype = new bdccgeo(); // internal helper functions ========================================= // convert geographic geocentric latitude (radians). function bdccgeogeocentriclatitude(geographiclatitude) { var flattening = 1.0 / 298.257223563;//wgs84 var f = (1.0 - flattening) * (1.0 - flattening); return math.atan((math.tan(geographiclatitude) * f)); } // convert geocentric geographic latitude (radians) function bdccgeogeographiclatitude (geocentriclatitude) { var flattening = 1.0 / 298.257223563;//wgs84 var f = (1.0 - flattening) * (1.0 - flattening); return math.atan(math.tan(geocentriclatitude) / f); } // returns 2 antipodal points of intersection of 2 great // circles defined arcs geo1 geo2 , // geo3 geo4. returns point geo, use .antipode other point function bdccgeogetintersection( geo1, geo2, geo3, geo4) { var geocross1 = geo1.crossnormalize(geo2); var geocross2 = geo3.crossnormalize(geo4); return geocross1.crossnormalize(geocross2); } //from radians meters function bdccgeoradianstometers(rad) { return rad * 6378137.0; // wgs84 equatorial radius in meters } //from meters radians function bdccgeometerstoradians(m) { return m / 6378137.0; // wgs84 equatorial radius in meters } // properties ================================================= bdccgeo.prototype.getlatituderadians = function() { return (bdccgeogeographiclatitude(math.atan2(this.z, math.sqrt((this.x * this.x) + (this.y * this.y))))); } bdccgeo.prototype.getlongituderadians = function() { return (math.atan2(this.y, this.x)); } bdccgeo.prototype.getlatitude = function() { return this.getlatituderadians() * 180.0 / math.pi; } bdccgeo.prototype.getlongitude = function() { return this.getlongituderadians() * 180.0 / math.pi ; } // methods ================================================= //maths bdccgeo.prototype.dot = function( b) { return ((this.x * b.x) + (this.y * b.y) + (this.z * b.z)); } //more maths bdccgeo.prototype.crosslength = function( b) { var x = (this.y * b.z) - (this.z * b.y); var y = (this.z * b.x) - (this.x * b.z); var z = (this.x * b.y) - (this.y * b.x); return math.sqrt((x * x) + (y * y) + (z * z)); } //more maths bdccgeo.prototype.scale = function( s) { var r = new bdccgeo(0,0); r.x = this.x * s; r.y = this.y * s; r.z = this.z * s; return r; } // more maths bdccgeo.prototype.crossnormalize = function( b) { var x = (this.y * b.z) - (this.z * b.y); var y = (this.z * b.x) - (this.x * b.z); var z = (this.x * b.y) - (this.y * b.x); var l = math.sqrt((x * x) + (y * y) + (z * z)); var r = new bdccgeo(0,0); r.x = x / l; r.y = y / l; r.z = z / l; return r; } // point on opposite side of world point bdccgeo.prototype.antipode = function() { return this.scale(-1.0); } //distance in radians point point v2 bdccgeo.prototype.distance = function( v2) { return math.atan2(v2.crosslength(this), v2.dot(this)); } //returns in meters minimum of perpendicular distance of point line segment geo1-geo2 //and distance point line segment ends in geo1 , geo2 bdccgeo.prototype.distancetolinesegmtrs = function(geo1, geo2) { //point on unit sphere above origin , normal plane of geo1,geo2 //could either side of plane var p2 = geo1.crossnormalize(geo2); // intersection of gc normal geo1/geo2 passing through p gc geo1/geo2 var ip = bdccgeogetintersection(geo1,geo2,this,p2); //need check ip or antipode between p1 , p2 var d = geo1.distance(geo2); var d1p = geo1.distance(ip); var d2p = geo2.distance(ip); //window.status = d + ", " + d1p + ", " + d2p; if ((d >= d1p) && (d >= d2p)) return bdccgeoradianstometers(this.distance(ip)); else { ip = ip.antipode(); d1p = geo1.distance(ip); d2p = geo2.distance(ip); } if ((d >= d1p) && (d >= d2p)) return bdccgeoradianstometers(this.distance(ip)); else return bdccgeoradianstometers(math.min(geo1.distance(this),geo2.distance(this))); } // distance in meters glatlng point gpolyline or gpolygon poly function bdccgeodistancetopolymtrs(poly, point) { var d = 999999999; var i; var p = new bdccgeo(point.lat(),point.lng()); for(i=0; i<(poly.getpath().getlength()-1); i++) { var p1 = poly.getpath().getat(i); var l1 = new bdccgeo(p1.lat(),p1.lng()); var p2 = poly.getpath().getat(i+1); var l2 = new bdccgeo(p2.lat(),p2.lng()); var dp = p.distancetolinesegmtrs(l1,l2); if(dp < d) d = dp; } return d; } // new glatlng distancemeters away on compass bearing azimuthdegrees // glatlng point - accurate better 200m in 140km (20m in 14km) in uk function bdccgeopointatrangeandbearing (point, distancemeters, azimuthdegrees) { var latr = point.lat() * math.pi / 180.0; var lonr = point.lng() * math.pi / 180.0; var coslat = math.cos(latr); var sinlat = math.sin(latr); var az = azimuthdegrees* math.pi / 180.0; var cosaz = math.cos(az); var sinaz = math.sin(az); var dr = distancemeters / 6378137.0; // distance in radians using wgs84 equatorial radius var sind = math.sin(dr); var cosd = math.cos(dr); return new google.maps.latlng(math.asin((sinlat * cosd) + (coslat * sind * cosaz)) * 180.0 / math.pi, (math.atan2((sind * sinaz), (coslat * cosd) - (sinlat * sind * cosaz)) + lonr) * 180.0 / math.pi); }
now question is,
as storm moving, want estimate time when storm comes closest city. (the stormcarib website can't manually entered data.) example, storm @ 20.3n 118.9e, 24 hrs later 21.4n 114.6e, 48 hrs later 22.5 110.4e. assume storm moving same direction , speed between 0-24hrs , 24-48hrs, how can calculate when storm closest?
from above scripts, can "distance" (eg 83 km), not point lat , lng. how can know lat & lng of closest point? think easier me calculate time if know location of point first. also, getting point, can add marker on google maps.
any suggestions? in advance.
Comments
Post a Comment