I have a rectangular polygon and I want to extend the boundaries by 10 km for example.
How would I do that ?
I could use extend method, but how Do I find the distance of 10 km in lat lng ?
So far I have :
bounds = new google.maps.LatLngBounds();
pt = new google.maps.LatLng(lat,lng);
bounds.extend(pt)
It depends on how exact an answer you need.
You could use the following approximation:
Latitude: 1 deg = 110.57 km; Longitude: 1 deg = 111.320 km source: http://en.wikipedia.org/wiki/Latitude
For a more exact formula, you need to check http://www.movable-type.co.uk/scripts/latlong.html . It has various formulas and also some code. You are looking for the section called 'Destination point given distance and bearing from start point'
It depends where you are looking at but a longitude is 111km and a latitude 110km:http://en.m.wikipedia.org/wiki/Latitude.
Related
I am working on an user interface that shows many pins on a map.
During the development I am randomly generating 1500 map pins just to be placed on the map to test look/feel/performance etc. issues.
The code which does that looks like this:
for (var i = 0; i <= 1500; i += 1) {
$scope.mapPins.push({
latitude: (Math.random() * 2) + 51,
longitude: (Math.random() * 4) + 3,
icon: themeImages[Math.floor(Math.random() * themeImages.length)],
title: 'Sample title',
infoContent: 'Sample content'
});
}
Naturally the area of the pins covered is a rectangle for latitudes 51-53 and longitudes 3-7. For those who are wondering where it is, it is the area roughly around Netherlands.
Now, there's a little problem that the Netherlands is not a rectangular area and a lot of these coordinates fall over the sea and I would like my coordinates to be only on the land.
Is there a witty mathematical way how I can pool coordinates from a non-rectangular area?
Of course I could make a google.maps polygon object that covers a nonrectangular shape and then via google api test every random generated pin whether it falls within the bounds of this shape etc, but that would be an overkill for UI design phase. Basically my question is whether there is a neat mathematical trick that would allow me to randomly generate coordinates from a non-rectangular space.
Leave your code as it is, the rectangle is the bounding box over your area of interest.
Then add a line
if (isPointInpolygon(polygon, longitudeOrX, latitudeOrY) {
// use this location
}
now you only need to search for a point in polygon function, which is easy to find.
you can directly use the coordinates in (long, lat) order, longitude is related to x coordinate, lat to y.
The polygon has to be filled with the coordinates of the country not insode the water.
If you have islands, then maybe you need multiple such polygons, then iterate over all.
Not to be a stickler but you're actually generating 1501 map pins :)
It is very unlikely that you'll find a simpler solution than using a simple pointinpolygon check.
Use the Google Maps Drawing library (https://developers.google.com/maps/documentation/javascript/drawing#using_the_library) to draw a polygon around the boundary of the Netherlands and save it however you want (e.g., in database, or just copy the string that defines the boundary's coordinates).
Then in your script above, define the google maps polygon (similar to what is done here in the official docs: https://developers.google.com/maps/documentation/javascript/shapes#polygons), then use the containsLocation method in the Google Maps Geometry library (https://developers.google.com/maps/documentation/javascript/examples/poly-containsLocation) to check if your random map pins lie within the boundaries of the Netherlands before adding them to the map.
For example:
var netherlandsCoords = [
// comma-separated list of coordinates defining the Netherlands boundary
];
var netherlandsBoundary = new google.maps.Polygon({
path: netherlandsCoords
});
for (var i = 0; i <= 1500; i += 1) {
var lat = (Math.random() * 2) + 51;
var lng = (Math.random() * 4) + 3;
var latlng = new google.maps.LatLng(lat, lng);
if (google.maps.geometry.poly.containsLocation(latlng, netherlandsBoundary)) {
$scope.mapPins.push({
latitude: lat,
longitude: lng,
icon: themeImages[Math.floor(Math.random() * themeImages.length)],
title: 'Sample title',
infoContent: 'Sample content'
});
}
}
I was wondering if there is any way of getting the dimensions (in degrees or kilometers) of a google static map image, given the zoom level and the size of the map in pixels.
I have seen a formula to get the longitude in degrees:
(widthInPixels/256)*(360/pow(2,zoomLevel));
And this is pretty accurate. However the ratio between km and degrees changes depending on how close you are to the poles or the equator, so this formula won't work (even if I substitute the 360 for 180)
Has anyone got a formula or any tips for this?
You can use MKMetersBetweenMapPoints to find dimensions in km.
//Let's say region is represents the piece of map
MKMapPoint pWest = MKMapPointForCoordinate( CLLocationCoordinate2DMake(region.center.latitude, region.center.longitude-region.span.longitudeDelta/2.0));
MKMapPoint pEast = MKMapPointForCoordinate( CLLocationCoordinate2DMake(region.center.latitude, region.center.longitude+region.span.longitudeDelta/2.0));
CLLocationDistance distW = MKMetersBetweenMapPoints(pWest, pEast)/1000.0;//map width in km
MKMapPoint pNorth = MKMapPointForCoordinate( CLLocationCoordinate2DMake(region.center.latitude+region.span.latitudeDelta/2.0, region.center.longitude));
MKMapPoint pSouth = MKMapPointForCoordinate( CLLocationCoordinate2DMake(region.center.latitude-region.span.latitudeDelta/2.0, region.center.longitude));
CLLocationDistance distH = MKMetersBetweenMapPoints(pNorth, pSouth)/1000.0;;//map height in km
I'm using this method to calculate distance between 2 coordinates
http://code.google.com/apis/maps/articles/phpsqlsearch.html#findnearsql
for example i have two coordinates(lat and lng)
first coordinate: 37, -122
second coordinate:37.386337, -122.085823
I get this distance 27.1097282198804(miles) between these coordinates by using the method above.
Please tell me any way to verify this distance?
You can also use the Google Maps API Geometry Library.
firstLatLng = new google.maps.LatLng(37,-122);
secondLatLng = new google.maps.LatLng(37.386337, -122.085823);
distance = google.maps.geometry.spherical.computeDistanceBetween(firstLatLng,secondLatLng);
Ok pretty self explanatory. I'm using google maps and I'm trying to find out if a lat,long point is within a circle of radius say x (x is chosen by the user).
Bounding box will not work for this. I have already tried using the following code:
distlatLng = new google.maps.LatLng(dist.latlng[0],dist.latlng[1]);
var latLngBounds = circle.getBounds();
if(latLngBounds.contains(distlatLng)){
dropPins(distlatLng,dist.f_addr);
}
This still results in markers being places outside the circle.
I'm guess this is some simple maths requiring the calculation of the curvature or an area but I'm not sure where to begin. Any suggestions?
Unfortunately Pythagoras is no help on a sphere. Thus Stuart Beard's answer is incorrect; longitude differences don't have a fixed ratio to metres but depend on the latitude.
The correct way is to use the formula for great circle distances. A good approximation, assuming a spherical earth, is this (in C++):
/** Find the great-circle distance in metres, assuming a spherical earth, between two lat-long points in degrees. */
inline double GreatCircleDistanceInMeters(double aLong1,double aLat1,double aLong2,double aLat2)
{
aLong1 *= KDegreesToRadiansDouble;
aLat1 *= KDegreesToRadiansDouble;
aLong2 *= KDegreesToRadiansDouble;
aLat2 *= KDegreesToRadiansDouble;
double cos_angle = sin(aLat1) * sin(aLat2) + cos(aLat1) * cos(aLat2) * cos(aLong2 - aLong1);
/*
Inaccurate trig functions can cause cos_angle to be a tiny amount
greater than 1 if the two positions are very close. That in turn causes
acos to give a domain error and return the special floating point value
-1.#IND000000000000, meaning 'indefinite'. Observed on VS2008 on 64-bit Windows.
*/
if (cos_angle >= 1)
return 0;
double angle = acos(cos_angle);
return angle * KEquatorialRadiusInMetres;
}
where
const double KPiDouble = 3.141592654;
const double KDegreesToRadiansDouble = KPiDouble / 180.0;
and
/**
A constant to convert radians to metres for the Mercator and other projections.
It is the semi-major axis (equatorial radius) used by the WGS 84 datum (see http://en.wikipedia.org/wiki/WGS84).
*/
const int32 KEquatorialRadiusInMetres = 6378137;
Use Google Maps API geometry library to calculate distance between circle's center and your marker, and then compare it with your radius.
var pointIsInsideCircle = google.maps.geometry.spherical.computeDistanceBetween(circle.getCenter(), point) <= circle.getRadius();
It's very simple. You just have to calculate distance between centre and given point and compare it to radius. You can Get Help to calculate distance between two lat lang from here
The following code works for me: my marker cannot be dragged outside the circle, instead it just hangs at its edge (in any direction) and the last valid position is preserved.
The function is the eventhandler for the markers 'drag' event.
_markerDragged : function() {
var latLng = this.marker.getPosition();
var center = this.circle.getCenter();
var radius = this.circle.getRadius();
if (this.circleBounds.contains(latLng) &&
(google.maps.geometry.spherical.computeDistanceBetween(latLng, center) <= radius)) {
this.lastMarkerPos = latLng;
this._geocodePosition(latLng);
} else {
// Prevent dragging marker outside circle
// see (comments of) http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/
// see http://www.mvjantzen.com/blog/?p=3190 and source code of http://mvjantzen.com/cabi/trips4q2012.html
this.marker.setPosition(this.lastMarkerPos);
}
},
Thanks to http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/
and http://www.mvjantzen.com/blog/?p=3190 .
I've been a bit silly really. Thinking about it we can use Pythagorus' theorem.
We have a maximum distance away from a point (X miles), and two latitudes and two longitudes. If we form a triangle using these then we can solve for the distance from the point.
So say we know point1 with coordinates lat1,lng1 is the center of the circle and point2 with coordinates lat2,lng2 is the point we are trying to decide is in the circle or not.
We form a right angled triangle using a point determined by point1 and point2. This, point3 would have coordinates lat1,lng2 or lat2,lng1 (it doesn't matter which). We then calculate the differences (or if you prefer) distances - latDiff = lat2-lat1 and lngDiff = lng2-lng1
we then calculate the distance from the center using Pythagorus - dist=sqrt(lngDiff^2+latDiff^2).
We have to translate everything into meters so that it works correctly with google maps so miles are multiplied by 1609 (approx) and degrees of latitude/longitude by 111000 (approx). This isn't exactly accurate but it does an adequate job.
Hope that all makes sense.
I'm trying to find a function lng = f(lat) that would help me draw a line between 2 given GPS coordinates, (lat1, lng1) and (lat2, lng2).
I've tried the traditional Cartesian formula y=mx+b where m=(y2-y1)/(x2-x1), but GPS coordinates don't seem to behave that way.
What would be a formula/algorithm that could help me achieve my goal.
PS: I'm using Google Maps API but let's keep this implementation agnostic if possible.
UPDATE: My implementation was wrong and it seems the algorithm is actually working as stated by some of the answers. My bad :(
What you want to do should actually work. Keep in mind however that if north is on top, the horizontal (x) axis is the LONGITUDE and the vertical (y) axis is the LATITUDE (I think you might have confused this).
If you parametrize the line as lat = func(long) you will run into trouble with vertical lines (i.e. those going exactly north south) as the latitude varies while the longitude is fixed.
Therefore I'd rather use another parametrization:
long(alpha) = long_1 + alpha * (long_2 - long_1)
lat(alpha) = lat_1 + alpha * (lat_2 - lat_1)
and vary alpha from 0 to 1.
This will not exactly coincide with a great circle (shortest path on a sphere) but the smaller the region you are looking at, the less noticeable the difference will be (as others posters here pointed out).
Here is a distance formula I use that may help. This is using javascript.
function Distance(lat1, lat2, lon1, lon2) {
var R = 6371; // km
var dLat = toRad(lat2 - lat1);
var dLon = toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRad(lat1)) * Math.cos(toRad(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 * 0.621371;
var r = Math.round(d * 100) / 100;
return r;
}
For short distances, where the earth curvature doesn't make a significant difference, it works fine to draw a line using regular two-dimensional geometry.
For longer distances the shortest way between two lines does not project as a straight line on a map, but as a curve. (For example, the shortest way from Sweden to Alaska would be straight over the noth pole, not past Canada and Iceland.) You would have to use three-dimensional geometry to draw a line on a surface of a sphere, then project that onto the map in the same way the earth surface is projected on the map.
Is your goal to find this equation or to actually draw a line?
If the latter, since you're using the Maps API, specify geodesic: true and draw it with a Polyline:
http://code.google.com/apis/maps/documentation/javascript/reference.html#Polyline