I have markers that were plotted in a legacy system on a EPSG4326 map with a bounds of -180 to 180 latitude and -180 to 180 longitude. I'm now trying to plot these onto a EPSG4326 map that has a bounds of -90 to 90 latitude and -180 to 180 longitude. How can I convert the original coordinate to the new coordinate system so it appears on the new map at the same location? I'm trying to tackle this within a JavaScript application using the Leaflet mapping library. Any pointers or insight would be greatly appreciated.
As an example, the location of London on the source map that represents latitude in -180 to 180 range is approximately (Lat: 61.8750, Lon: 0.1278) and on destination map where latitude is -90 to 90 it would be about (Lat: 51.5074, Lon: 0.1278).
I figured it out!
newlat = (180.0/Math.PI*(2.0*Math.atan(Math.exp(oldlat*Math.PI/180.0))-Math.PI/2.0))
Thus if oldlat = 61.8750, newlat = 52.482780222078226 which is what I needed and solves my problem perfectly, converting a latitude with different extents into the new extents.
The reverse (if needing to reconvert) formula is:
oldlat = ((180.0/Math.PI)*Math.log(Math.tan((90.0+newlat)*Math.PI/360.0)))
Related
I am using geopy to simply calculate the distance between two long,lat co-ordinates.
However I am confused on what scale the longitude should be on.
The latitude co-ordinated go from -90 to +90, and currently I've put my Longitude on a scale from 0-360 degrees - should this be -180 to 180 to satisfy :
great_circle(NYC, test).miles
where NYC and test are the co-ord pairs.
Thanks,
Izzy
Geopy Point latitude must be in range [-90; 90], longitude should be in range [-180; 180].
Longitude is automatically normalized (e.g. 185 is normalized to -175), while out-of-band latitudes would result in a ValueError being thrown. See the Point normalization testcases for getting the better idea on how normalization works: test/test_point.py
An example from docs for calculating distance between two points:
>>> from geopy import distance
>>> newport_ri = (41.49008, -71.312796)
>>> cleveland_oh = (41.499498, -81.695391)
>>> print(distance.distance(newport_ri, cleveland_oh).miles)
538.39044536
When using the embedded interactivity embedded interactivity function on the iOS SDK I can click a map tile and get the data coords in LAT LON but I would like to have the result in EPSG 3857 WGS 84...is this possible? If so what is the transform command?
Looks like I am going to answer my own question. I could not find a transform function. So I passed the LAT LONG coordinate pair to the webservice and did the transformation on the server.
You can do this with Leaflet/Mapbox.
Here's an example
var latlng = L.latLng(45, -120);
var sphericalMercator = L.Projection.SphericalMercator.project(latlng);
sperhicalMercator.x => -2.0943951023931953
sphericalMercator.y => 0.8813735870195429
You'll still need to multiply these coordinates by 6378137 (earth's radius in meters) (why Leaflet doesn't do this, I don't know...), and you get the spherical mercator equivalent to the original lat/long (45, -120):
(-13358338.8952, 5621521.48619)
Say I have a square which consists of four CLLocationCoordinate2D points, which are in lat, lon, and I want to find the area of the square in meters. I convert the CLLocationCoordinate2D points into MKMapPoints, and I find the area in X-Y space. However, the area I find is in the units of MKMapPoint, which don't directly translate to meters. How can I translate this area in MKMapPoint-space back into meters?
The MapKit function MKMetersBetweenMapPoints makes this easier.
For example, if you wanted to get the area of the currently displayed region:
MKMapPoint mpTopLeft = mapView.visibleMapRect.origin;
MKMapPoint mpTopRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y);
MKMapPoint mpBottomRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y + mapView.visibleMapRect.size.height);
CLLocationDistance hDist = MKMetersBetweenMapPoints(mpTopLeft, mpTopRight);
CLLocationDistance vDist = MKMetersBetweenMapPoints(mpTopRight, mpBottomRight);
double vmrArea = hDist * vDist;
The documentation states that the function takes "into account the curvature of the Earth."
You can use the Haversine formula to calculate it, assuming that the earth is a perfect sphere.
To understand how lat/lon vs meters works in the context of the earth, you may find it interesting to read about Nautical miles.
You can find some more resources and some sample code by googling objective-c Haversine formula.
Enjoy!
I want the exact position on mkmapkit that is x y cordinate from lat lon values .
I used the followind code
CLLocationCoordinate2D neCoord;
neCoord.latitude = 72.2234;
neCoord.longitude = 23.340876;
//Here i have passed hardcoded lat lon
nePoint = [map_view convertCoordinate:neCoord toPointToView:map_view];
But i get the cordinates to be negative values.
So any idea or suggestions for the same are accepted.
Maybe you're getting negative numbers because the MKMapView isn't showing the region where the coordinates are? If they're both negative, then the location is NW of the current displayed map region.
I wanted to test the mapKit and wanted to make my own overlay to display the accuracy of my position.
If i have a zoom factor of for example .005 which radius does my circle around me has to have(If my accuracy is for example 500m)?
Would be great to get some help :)
Thanks a lot.
Look at the documentation for MKCoordinateSpan, which is part of the map's region property. One degree of latitude is always approx. 111 km, so converting the latitudeDelta to meters and then getting to the meters per pixel should be easy. For longitudinal values it is not quite so easy as the distance covered by one degree of longitude varies between 111 km (at the equator) and 0 km (at the poles).
My way to get meters per pixel:
MKMapView *mapView = ...;
CLLocationCoordinate2D coordinate = ...;
MKMapRect mapRect = mapView.visibleMapRect;
CLLocationDistance metersPerMapPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
CGFloat metersPerPixel = metersPerMapPoint * mapRect.size.width / mapView.bounds.size.width;
To add to another answer, a difference of one minute of latitude corresponds to one nautical mile: that's how the nautical mile was defined. So, converting to statute miles, 1 nautical mile = 1.1508 statue miles, or 6076.1 ft. or 1852 meters.
When you go to longitude, the size of the longitude circles around the Earth shrink as latitude increases, as was noted on the previous answer. The correct factor is that
1 minute of longitude = (1852 meters)*cos(theta),
where theta is the latitude.
Of course, the Earth is not a perfect sphere, but the simple calculation above would never be off by more than 1%.