I am using geolocation to get the users current location and monitor it using the watchPosition method. However, is there a way of calculating the distance between the users starting position and current position? Below is my code:
var x = document.getElementById("info");
function getLocation() {
if(navigator.geolocation) {
navigator.geolocation.watchPosition(showPosition, showError, {
enableHighAccuracy: true,
maximumAge: 60000,
timeout: 27000
})
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
var flightPathCoordinates = [];
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude + "<br>Accuracy: " + position.coords.accuracy + "<br>Altitude: " + position.coords.altitude + "<br>Altitude Accuracy: " + position.coords.altitudeAccuracy + "<br>Heading: " + position.coords.heading + "<br>Speed: " + position.coords.speed + "<br>Speed (mph): " + position.coords.speed * 2.2369 + "<br>Speed (km): " + position.coords.speed * 3.6 + "<br>Timestamp: " + new Date(position.timestamp).toLocaleString() + "<br>Distance Travelled (km): " + calculateDistance(position.coords.latitude, position.coords.longitude, position.coords.latitude, position.coords.longitude);
// Distance Calculator
function calculateDistance(lat1, lon1, lat2, lon2) {
if(typeof (Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function () {
return this * Math.PI / 180;
}
}
var R = 6371; // km
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
Number.prototype.toRad = function () {
return this * Math.PI / 180;
}
lat = position.coords.latitude;
lon = position.coords.longitude;
latlon = new google.maps.LatLng(lat, lon)
mapholder = document.getElementById('mapholder')
var myOptions = {
center: latlon,
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
}
}
var map = new google.maps.Map(document.getElementById("mapholder"), myOptions);
Any help would be very much appreciated as I am quite new to this.
Thanks!
This has been adapted from the Google Maps API, and reworked to be independent of the library.
Example - calculate the distance from the center of New York City to the center of Philadelphia.
Fiddle for miles: http://jsfiddle.net/DXNzu/
Fiddle for kilometers: http://jsfiddle.net/DXNzu/1/
JS
function distanceFrom(points) {
var lat1 = points.lat1;
var radianLat1 = lat1 * (Math.PI / 180);
var lng1 = points.lng1;
var radianLng1 = lng1 * (Math.PI / 180);
var lat2 = points.lat2;
var radianLat2 = lat2 * (Math.PI / 180);
var lng2 = points.lng2;
var radianLng2 = lng2 * (Math.PI / 180);
var earth_radius = 3959; // or 6371 for kilometers
var diffLat = (radianLat1 - radianLat2);
var diffLng = (radianLng1 - radianLng2);
var sinLat = Math.sin(diffLat / 2);
var sinLng = Math.sin(diffLng / 2);
var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);
var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));
return distance.toFixed(3);
}
var distance = distanceFrom({
// NYC
'lat1': 40.713955826286046,
'lng1': -74.00665283203125,
// Philly
'lat2': 39.952335,
'lng2': -75.163789
});
The result is 80.524 miles or 129.583 kilometers.
you can use Haversine formula
rad = function(x) {return x*Math.PI/180;}
distHaversine = function(p1, p2) { // Points are Geolocation.coords objects
var R = 6371; // earth's mean radius in km
var dLat = rad(p2.latitude - p1.latitude);
var dLong = rad(p2.longitude - p1.longitude);
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;
return d.toFixed(3);
}
Two tips
typeof is not a function. Use it like this: typeof something
Do not put polyfills in listeners. you are repeating the polyfill action in every time listener fires.
Related
i am new in gis. I am working in JavaScript.
suppose there is center latlong. another point is target(latlong) in n miters far from center. how to calculate this location difference(center - latlong) from center and n in miter.
guys please help me.
lets consider earth is properly spherical.
function distance(lat1, lon1, lat2, lon2) {
var radius = 6371e3; // meters
var dLon = gis.toRad(lon2 - lon1),
lat1 = gis.toRad(lat1),
lat2 = gis.toRad(lat2),
distance = Math.acos(Math.sin(lat1) * Math.sin(lat2) +
Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLon)) * radius;
return distance;
}
above javascript function is for calculating distance,
function(lat, long, distance){
//can i calculate lat_difference, long difference
}
here is your code:-
<script>
Math.radians = function(degrees) {
return degrees * Math.PI / 180;
};
function calculateDistance(lat,lon,lat_center,lon_center){
var distance = ( 6371 * Math.acos( Math.cos( Math.radians(lat) ) * Math.cos( Math.radians( lat_center ) )
* Math.cos( Math.radians( lon_center ) - Math.radians(lon) ) + Math.sin( Math.radians(lat) ) * Math.sin(Math.radians(lat_center)) ) )*1000;
console.log(distance+" meter");
return distance;
}
var lat = '38.898556';
var lon = '-77.037852';
var lat_center = '38.897147';
var lon_center = '-77.043934';
calculateDistance(lat,lon,lat_center,lon_center);//will return 549 meter
//for getting lat and lon from a distance from a given point
//lat1 = latitude of start point in degrees
//long1 = longitude of start point in degrees
//d = distance in KM
//angle = bearing in degrees
function get_gps_distance(lat1,long1,d,angle)
{
//# Earth Radious in KM
var R = 6378.14;
//# Degree to Radian
var latitude1 = lat1 * (Math.PI/180);
var longitude1 = long1 * (Math.PI/180);
brng = angle * (Math.PI/180);
latitude2 = Math.asin(Math.sin(latitude1)*Math.cos(d/R) + Math.cos(latitude1)*Math.sin(d/R)*Math.cos(brng));
longitude2 = longitude1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(latitude1),Math.cos(d/R)-Math.sin(latitude1)*Math.sin(latitude2));
// # back to degrees
latitude2 = latitude2 * (180/Math.PI);
longitude2 = longitude2 * (180/Math.PI);
// # 6 decimal for Leaflet and other system compatibility
lat2 = latitude2;
long2 =longitude2;
var tab = {};
// Push in array and get back
tab[0] = lat2;
tab[1] = long2;
return tab;
}
get_gps_distance('38.898556','-77.037852',.549,90);
</script>
I got the script that calculates the distance and I spent my coordinates with 2 points ( pos1 , pos2 ) ( both are geolocated ) Then I put a loop that recharges the script every 5/10 seconds and I saved the distance with a LocalStorage out a loop .
Now I want out of the loop there is a variable that calculates the total distance , or rather that calculates all distances that are passed by the loop.
This is the code:
(function(){
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
pos1 = position.coords.latitude;
pos11= position.coords.longitude;
console.log('latitudine ' + pos1);
console.log('longitudine ' + pos11);
//Passano 2 secondi
setTimeout(function(){
pos2 = 45.2968571;
pos22 = 12.034978499999966;
console.log('latitudine ' + pos2);
console.log('longitudine ' + pos22);
alert("Sono passati 2 secondi");
},2000);
// Converte in radianti
setTimeout(function(){
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
// From Caspar Kleijne's answer ends
// From cletus' answer starts
var R = 6371; // km
var dLat = (pos2-pos1).toRad();
var dLon = (pos22-pos11).toRad();
var lat1 = pos1.toRad();
var lat2 = pos2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var distance1 = R * c;
var distance2 = distance1;
console.log(distance1, distance2);
alert('hai percorso: ' + distance1 + 'm ');
var distance2 = localStorage.setItem('key', distance2);
},2000);
})
}
setTimeout(arguments.callee, 10000);
})();
(function(){
setTimeout(function(){
var distanza = localStorage.getItem('key', 'distance2');
var distanza1 = distanza;
// here i wont calculate the total distance
console.log('prima: ' + distanza + 'n\totale: ' + total);
},6000);
setTimeout(arguments.callee,10000);
})();
I am using the Haversine formula to calculate the distance between two points on earth. I have the following code:
var app = angular.module('app', []);
app.controller('firstCtrl', function($scope, $timeout) {
var myLat, myLon, locLat, locLon;
navigator.geolocation.watchPosition(GetLocation)
$scope.ASiteLocs = [{
"name": "IL5077 BRUSSELS",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.58543899999999,38.955472,0"
}
}, {
"name": "IL5076 KAMPSVILLE",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.661923,39.29403,0"
}
}, {
"name": "IL5146 CARROLLTON",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.39965700000001,39.309142,0"
}
}, {
"name": "IL5153 GREENFIELD",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.208747,39.364077,0"
}
}];
$scope.SSiteLocs = [];
$scope.SiteLocs = $scope.SSiteLocs.concat($scope.ASiteLocs);
repoSortOrder = "site.name";
function GetLocation(location, myLat, myLon) {
myLat = location.coords.latitude;
myLon = location.coords.longitude;
document.getElementById("lat").innerHTML = myLat;
document.getElementById("lon").innerHTML = myLon;
$timeout(function() {
calculate();
});
}
$scope.getCoordDistance = function(myLat, myLon, locLat, locLon) {
var lat1 = locLat; //41.887055
var lon1 = locLon; //-88.469233
var lat2 = myLat; //41.888668
var lon2 = myLon; //-87.640371
var R = 3959;
var x1 = lat2 - lat1;
var dLat = x1 * Math.PI / 180;
var x2 = lon2 - lon1;
var dLon = x2 * Math.PI / 180;
a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
angular.forEach($scope.SSiteLocs, function(object) {
object.carrier = 'Sprint';
});
angular.forEach($scope.ASiteLocs, function(object) {
object.carrier = 'AT&T';
});
var i = 0;
locX = 1;
var calculate = function() {
angular.forEach($scope.SiteLocs, function(location) {
var clength = location.Point.coordinates.length;
if (location.Point.coordinates.substring(clength - 2, clength) === ",0") {
location.Point.coordinates = location.Point.coordinates.substring(0, clength - 2).split(",");
Lat = location.Point.coordinates[0];
Lon = location.Point.coordinates[1];
Com = ",";
location.Point.coordinates = Lon.concat(Com, Lat);
myLat = Number(document.getElementById("lat").innerHTML)
myLon = Number(document.getElementById("lon").innerHTML)
locLat = Lat;
locLon = Lon;
d = $scope.getCoordDistance(myLat, myLon, locLat, locLon);
location.distance = d.toFixed(1);
if(i < 15){
console.log("********LOCATON " + locX + "***********")
console.log("myCoords: " + myLat + "," + myLon);
console.log("locCoords: " + locLat + "," + locLon);
console.log("d: " + d);
console.log("***************************")
i++;
locX++;
}
}
});
};
});
The results from the formula are up to about 9-10 thousand when they should be no where near that high. If I use the commented out coordinates it returns correctly (42.6 Miles)
Since the test coordinates work I know it is not a math problem. Does anybody know what is causing the formula to not work correctly?
EDIT
Here is a plunker of the full proj. if that helps. EDIT2 I discovered something odd, the results are different in different browsers, so, chrome displays one set of numbers and IE displays another, ect.
Your point coordinates are longitude latitude
BRUSSELS",
"
"Point": {
"coordinates": "-90.58543899999999,38.955472
In your code
Lat = location.Point.coordinates[0];
Lon = location.Point.coordinates[1];
Either change them in your object(preferable) See Google latlng class
"Point": {
"coordinates": "38.955472,-90.58543899999999
or
Lat = location.Point.coordinates[1];
Lon = location.Point.coordinates[0];
With your settings distance is aprox 9000 miles with coordinates transposed distance is aprox 200
In addition to what kirinthos said in his response, you can easily test this by comparing your results with Google Maps. I have a function in my app that does this. The point1 and point2 parameters are simple Latlng objects.I wanted the results in kilometers so I divide by 1000.
function calculateDistanceBetweenTwoPoints(point1, point2) {
return (google.maps.geometry.spherical.computeDistanceBetween(point1, point2) / 1000).toFixed(2);
}
You'll need the following in your HTML page:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,places"></script>
I'm not entirely sure, here, without testing it but it looks like the GetLocation function is overwriting the closure scope of the variables myLat and myLon by declaring them as function arguments, so you're assigning the value of location.coords.latitude into the function scope myLat variable, instead of the myLat declared at the beginning of your code block.
throw a console.log(myLat, myLon); into the beginning of getCoordDistance and check their values. I'll bet they're not what you expect.
edit: it actually may have been the lack of semicolons and stuff. here's a small snippet of your code re-calibrated to run in an isolated environment like jsbin.com. It appears to work fine. you were missing 4 semicolons, so unless this assignment is failing, it should work: myLon = Number(document.getElementById("lon").innerHTML)
there were complaints of variable "i" and "locX" not being defined
var myLat, myLon;
var ASiteLocs = [{
"name": "IL5077 BRUSSELS",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.58543899999999,38.955472,0"
}
}, {
"name": "IL5076 KAMPSVILLE",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.661923,39.29403,0"
}
}, {
"name": "IL5146 CARROLLTON",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.39965700000001,39.309142,0"
}
}, {
"name": "IL5153 GREENFIELD",
"styleUrl": "#waypoint",
"Point": {
"coordinates": "-90.208747,39.364077,0"
}
}];
var SSiteLocs = [];
var SiteLocs = SSiteLocs.concat(ASiteLocs);
function GetLocation(location, myLat, myLon) {
myLat = location.coords.latitude;
myLon = location.coords.longitude;
document.getElementById("lat").innerHTML = myLat;
document.getElementById("lon").innerHTML = myLon;
}
function getCoordDistance(myLat, myLon, locLat, locLon) {
var lat1 = locLat; //41.887055
var lon1 = locLon; //-88.469233
var lat2 = myLat; //41.888668
var lon2 = myLon; //-87.640371
var R = 3959;
var x1 = lat2 - lat1;
var dLat = x1 * Math.PI / 180;
var x2 = lon2 - lon1;
var dLon = x2 * Math.PI / 180;
a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
function calculate() {
SiteLocs.forEach(function(location) {
var clength = location.Point.coordinates.length;
if (location.Point.coordinates.substring(clength - 2, clength) === ",0") {
location.Point.coordinates = location.Point.coordinates.substring(0, clength - 2).split(",");
Lat = location.Point.coordinates[0];
Lon = location.Point.coordinates[1];
Com = ",";
location.Point.coordinates = Lon.concat(Com, Lat);
myLat = -90.208747;
myLon = 39.364077;
locLat = Lat;
locLon = Lon;
d = getCoordDistance(myLat, myLon, locLat, locLon);
location.distance = d.toFixed(1);
//console.log("********LOCATON " + locX + "***********");
console.log("myCoords: " + myLat + "," + myLon);
console.log("locCoords: " + locLat + "," + locLon);
console.log("d: " + d);
console.log("***************************");
}
});
};
The idea is to draw an arc centered on a specific point, using angles.
Note: Not the chord, nor the sector, nor the area between the chord and the arc.
Memento: http://en.wikipedia.org/wiki/Arc_(geometry)
A full circle parameters:
- center at coordinates LatC,LngC
- radius of 1 609 meters
- start angle of 0 degrees
- end angle of 360 degrees
example http://jsfiddle.net/GGvQH/3/
new google.maps.Circle({
center: new google.maps.LatLng(18.4894, 73.910158),
radius: 1609,
...
});
An arc of 180° (PI/2 radiant) oriented to north would be like:
- center at coordinates LatC,LngC
- radius of 1 609 meters
- start angle of 270 degrees (9 o'clock)
- end angle of 90 degrees (3 o'clock)
First of all, I do not want to plot a polyline for each arc, using tons of points to get a smooth effect: need to recompute for each scale and may cost resources... or is it?
There is an idea with polygons intersection
Google Maps API v3 - circle sector
...do anyone have seen a working jsfiddle?
Note: http://jsfiddle.net/Morlock0821/4dRB2/1/ is very close to the arc, but I do not want a closed surface.
Another idea with bearing... but I am reluctant to redefine the earth's radius to get the tiny arc I want.
https://developers.google.com/maps/documentation/javascript/examples/geometry-headings
(in this case, I want only the purple line, not the red one).
Any help would be greatly appreciated.
This is the code I use in this example:
function drawArc(center, initialBearing, finalBearing, radius) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / EarthRadiusMeters) * r2d;
var rlng = rlat / Math.cos(center.lat() * d2r);
var extp = new Array();
if (initialBearing > finalBearing) finalBearing += 360;
var deltaBearing = finalBearing - initialBearing;
deltaBearing = deltaBearing/points;
for (var i=0; (i < points+1); i++)
{
extp.push(center.DestinationPoint(initialBearing + i*deltaBearing, radius));
bounds.extend(extp[extp.length-1]);
}
return extp;
}
Used like this, where startPoint is the start of the arc, endPoint is the end of the arc and centerPoint is the center, but you can specify center, angles and radius.
var arcPts = drawArc(centerPoint, centerPoint.Bearing(startPoint), centerPoint.Bearing(endPoint), centerPoint.distanceFrom(startPoint));
var piePoly = new google.maps.Polygon({
paths: [arcPts],
strokeColor: "#00FF00",
strokeOpacity: 0.5,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map
});
Ancillary functions, may no longer be necessary if you include the geometry library
var EarthRadiusMeters = 6378137.0; // meters
/* Based the on the Latitude/longitude spherical geodesy formulae & scripts
at http://www.movable-type.co.uk/scripts/latlong.html
(c) Chris Veness 2002-2010
*/
google.maps.LatLng.prototype.DestinationPoint = function (brng, dist) {
var R = EarthRadiusMeters; // earth's mean radius in meters
var brng = brng.toRad();
var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();
var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist/R) +
Math.cos(lat1)*Math.sin(dist/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist/R)*Math.cos(lat1),
Math.cos(dist/R)-Math.sin(lat1)*Math.sin(lat2));
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
// === A function which returns the bearing between two LatLng in radians ===
// === If v1 is null, it returns the bearing between the first and last vertex ===
// === If v1 is present but v2 is null, returns the bearing from v1 to the next vertex ===
// === If either vertex is out of range, returns void ===
google.maps.LatLng.prototype.Bearing = function(otherLatLng) {
var from = this;
var to = otherLatLng;
if (from.equals(to)) {
return 0;
}
var lat1 = from.latRadians();
var lon1 = from.lngRadians();
var lat2 = to.latRadians();
var lon2 = to.lngRadians();
var angle = - 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 ) );
if ( angle < 0.0 ) angle += Math.PI * 2.0;
if ( angle > Math.PI ) angle -= Math.PI * 2.0;
return parseFloat(angle.toDeg());
}
/**
* Extend the Number object to convert degrees to radians
*
* #return {Number} Bearing in radians
* #ignore
*/
Number.prototype.toRad = function () {
return this * Math.PI / 180;
};
/**
* Extend the Number object to convert radians to degrees
*
* #return {Number} Bearing in degrees
* #ignore
*/
Number.prototype.toDeg = function () {
return this * 180 / Math.PI;
};
/**
* Normalize a heading in degrees to between 0 and +360
*
* #return {Number} Return
* #ignore
*/
Number.prototype.toBrng = function () {
return (this.toDeg() + 360) % 360;
};
code snippet (using geometry library):
var EarthRadiusMeters = 6378137.0; // meters
/* Based the on the Latitude/longitude spherical geodesy formulae & scripts
at http://www.movable-type.co.uk/scripts/latlong.html
(c) Chris Veness 2002-2010
*/
google.maps.LatLng.prototype.DestinationPoint = function(brng, dist) {
var R = EarthRadiusMeters; // earth's mean radius in meters
var brng = brng.toRad();
var lat1 = this.lat().toRad(),
lon1 = this.lng().toRad();
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist / R) +
Math.cos(lat1) * Math.sin(dist / R) * Math.cos(brng));
var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist / R) * Math.cos(lat1),
Math.cos(dist / R) - Math.sin(lat1) * Math.sin(lat2));
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
/**
* Extend the Number object to convert degrees to radians
*
* #return {Number} Bearing in radians
* #ignore
*/
Number.prototype.toRad = function() {
return this * Math.PI / 180;
};
/**
* Extend the Number object to convert radians to degrees
*
* #return {Number} Bearing in degrees
* #ignore
*/
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
};
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function createMarker(latlng, html) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
bounds.extend(latlng);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
}
function drawArc(center, initialBearing, finalBearing, radius) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / EarthRadiusMeters) * r2d;
var rlng = rlat / Math.cos(center.lat() * d2r);
var extp = new Array();
if (initialBearing > finalBearing) finalBearing += 360;
var deltaBearing = finalBearing - initialBearing;
deltaBearing = deltaBearing / points;
for (var i = 0;
(i < points + 1); i++) {
extp.push(center.DestinationPoint(initialBearing + i * deltaBearing, radius));
bounds.extend(extp[extp.length - 1]);
}
return extp;
}
function drawCircle(point, radius) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var EarthRadiusMeters = 6378137.0; // meters
var earthsradius = 3963; // 3963 is the radius of the earth in miles
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / EarthRadiusMeters) * r2d;
var rlng = rlat / Math.cos(point.lat() * d2r);
var extp = new Array();
for (var i = 0; i < points + 1; i++) // one extra here makes sure we connect the
{
var theta = Math.PI * (i / (points / 2));
ey = point.lng() + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
ex = point.lat() + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
extp.push(new google.maps.LatLng(ex, ey));
bounds.extend(extp[extp.length - 1]);
}
// alert(extp.length);
return extp;
}
var map = null;
var bounds = null;
function initialize() {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(-33.9, 151.2),
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
bounds = new google.maps.LatLngBounds();
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
var startPoint = new google.maps.LatLng(48.610335003092956, -1.6123447775299600);
var endPoint = new google.maps.LatLng(48.596190206866830, -1.5551704322317228);
var centerPoint = new google.maps.LatLng(48.565630000000006, -1.6050300000000002);
createMarker(startPoint, "start: " + startPoint.toUrlValue(6) + "<br>distance to center: " + (google.maps.geometry.spherical.computeDistanceBetween(centerPoint, startPoint) / 1000).toFixed(3) + " km<br>Bearing: " + google.maps.geometry.spherical.computeHeading(centerPoint, startPoint) + "<br><a href='javascript:map.setCenter(new google.maps.LatLng(" + startPoint.toUrlValue(6) + "));map.setZoom(20);'>zoom in</a> - <a href='javascript:map.fitBounds(bounds);'>zoom out</a>");
createMarker(endPoint, "end: " + endPoint.toUrlValue(6) + "<br>distance to center: " + (google.maps.geometry.spherical.computeDistanceBetween(centerPoint, endPoint) / 1000).toFixed(3) + " km<br>Bearing: " + google.maps.geometry.spherical.computeHeading(centerPoint, endPoint) + "<br><a href='javascript:map.setCenter(new google.maps.LatLng(" + endPoint.toUrlValue(6) + "));map.setZoom(20);'>zoom in</a> - <a href='javascript:map.fitBounds(bounds);'>zoom out</a>");
createMarker(centerPoint, "center: " + centerPoint.toUrlValue(6));
var arcPts = drawArc(centerPoint, google.maps.geometry.spherical.computeHeading(centerPoint, startPoint), google.maps.geometry.spherical.computeHeading(centerPoint, endPoint), google.maps.geometry.spherical.computeDistanceBetween(centerPoint, startPoint));
// add the start and end lines
arcPts.push(centerPoint);
bounds.extend(centerPoint);
arcPts.push(startPoint);
var piePoly = new google.maps.Polygon({
paths: [arcPts],
strokeColor: "#00FF00",
strokeOpacity: 0.5,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map
});
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry"></script>
<div id="map_canvas"></div>
I want to show specific information depending on where i am.
I have five cities with different information, and i want to show that city(information) that i'm closest to.
How to i do that the simplest way, using javascript.
Ex.
If i store the cities lat, long in an array
var cities = [
['new york', '111111', '222222', 'blablabla']
['boston', '111111', '222222', 'blablabla']
['seattle', '111111', '222222', 'blablabla']
['london', '111111', '222222', 'blablabla']
]
And with my current location(lat, long) i want the city that i'm closet to.
Here is a basic code example using HTML5 geolocation to get the user's position. It then calls NearestCity() and calculates the distance (km) from the location to each city. I passed on using the Haversine formulae and instead used the simpler Pythagoras formulae and an equirectangular projection to adjust for the curvature in longitude lines.
// Get User's Coordinate from their Browser
window.onload = function() {
// HTML5/W3C Geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(UserLocation);
}
// Default to Washington, DC
else
NearestCity(38.8951, -77.0367);
}
// Callback function for asynchronous call to HTML5 geolocation
function UserLocation(position) {
NearestCity(position.coords.latitude, position.coords.longitude);
}
// Convert Degress to Radians
function Deg2Rad(deg) {
return deg * Math.PI / 180;
}
function PythagorasEquirectangular(lat1, lon1, lat2, lon2) {
lat1 = Deg2Rad(lat1);
lat2 = Deg2Rad(lat2);
lon1 = Deg2Rad(lon1);
lon2 = Deg2Rad(lon2);
var R = 6371; // km
var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
var y = (lat2 - lat1);
var d = Math.sqrt(x * x + y * y) * R;
return d;
}
var lat = 20; // user's latitude
var lon = 40; // user's longitude
var cities = [
["city1", 10, 50, "blah"],
["city2", 40, 60, "blah"],
["city3", 25, 10, "blah"],
["city4", 5, 80, "blah"]
];
function NearestCity(latitude, longitude) {
var minDif = 99999;
var closest;
for (index = 0; index < cities.length; ++index) {
var dif = PythagorasEquirectangular(latitude, longitude, cities[index][1], cities[index][2]);
if (dif < minDif) {
closest = index;
minDif = dif;
}
}
// echo the nearest city
alert(cities[closest]);
}
With HTML5, you can pull the location of the user and then compares this example using a Haversine function (function below taken from here):
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
You can calculate the distance by latitude with your location and the cities locations. And find the shortest and draw. To calculate you can read more in http://www.movable-type.co.uk/scripts/latlong.html