I've been searching extensively for a way of converting from ordanance survey coords to valid esri coordinates. I've found quite a few pages that convert to lat long (if a little off) but nothing to convert to esri (which I believe is utm.)
This is for use in python or JavaScript / actionscript etc - I'm not too worried about syntax more an understanding of the maths involved.
Thanks
Ian
This type of conversion is called a "geodetic transformation". OS and UTM are both "transverse mercator" projections, wherein the ellipsoid of the earth is unwrapped into a cylinder, which is then unrolled into a flat sheet and sub-divided into grid sections. OS coordinates are specific to regions (eg: OSGB for Great Britain), whereas UTM is a "universal" system and specifies a system of grids for the whole earth. Regional grids are used in order to reduce the side-effects of distortion introduced by the mercator projection. It follows that converting between such systems is possible, but can also be quite complex depending in the accuracy desired.
It seems there are only indirect methods, as you have already referred to, the most common being to convert from OSGB36 to WGS84 (lat/long) and then to UTM.
Here are some resources which might be helpful:
Convert WGS84 lat/long to UTM: http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm. Note the inclusion of specific parameters for each region. For example, if you were converting coordinates for Britain, the parameters for "Airy 1830" would be used. (also links to a spreadsheet and webpage with conversions).
Similar information as above on Wikipedia.
JavaScript to convert OSGB36 to WGS84 (7 metre accuracy): http://www.nearby.org.uk/tests/GeoTools.html
A more accurate JavaScript conversion using a Helmert transformation (5 metre accuracy): http://www.movable-type.co.uk/scripts/latlong-convert-coords.html and http://www.movable-type.co.uk/scripts/latlong-gridref.html
Comprehensive coverage of the OSGB36 coordinate system, including transformations to and from other coordinate systems: http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf
Miscellaneous links and resources: http://www.ordnancesurvey.co.uk/oswebsite/gps/information/resourceinfolinks/gpslinks.html
As for accuracy, it is summed up in this excerpt from ordnancesurvey.co.uk:
... OSGB36 contains randomly variable scale errors, mainly due to it being
computed in blocks and the fact that scale and azimuth were
controlled entirely by the 11 stations from the
Principle Triangulation. These scale variations
mean that OSGB36 can be described as inhomogeneous ...
The inhomogenity of OSGB36 does not affect its
adequacy as a mapping datum but it does make a
simple transformation between ETRS89 and OSGB36 too inaccurate for national use.
For example, the accuracy of a national 7 parameter (3
shifts, 3 rotations and a scale change) transformation is approximately 5 metres
Here is a link to more comprehensive information regarding the ARC/INFO file format.
Quick google search: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/arcgislink/docs/examples.html
Related
I have two .shp files whose .prj files are identical and whose extents are different. I'd like to set them to the same extent so they line up on the map.
In ArcGis I have tried:
Exporting both to a new coordinate system-defined feature dataset
Removing the .prj file and then re defining the projection of each file
"project"ing both to the same Coordinate system.
Setting the data frame Coordinate System, then reintroducing the shapefiles in hopes that they'll project "on the fly"
In QGIS I have tried:
Setting project CRS
Setting layer to project and project to layer
Saving the shapefiles in specific CRS.
It seems odd to me that this is an issue in the first place: why can't Arc or Q detect this asynchronicity and give the user the option to choose one over the other?
What am I missing here?
Should I look into creating a spatial reference for one of the files, that matches the other?
Any clues/ suggestions/ clarifications?
I know this is a popular issue, and I figure there must be some simple explanation for the above, but I'm not finding it anywhere despite spending hours puzzling over the situation. Perhaps I just don't have the right vocabulary to ask the question. Any help appreciated.
some information about the files:
Extents for shp1:
top: 672344.187336 ft
bottom: 629117.938976 ft
right:7660465.885171 ft
left: 7627858.786745 ft
Extents for shp2:
top: 5984.800593 ft
bottom: 4784.800593 ft
right: 4616.411043 ft
left: 3776.411043 ft
Layer Properties-Source for both shp1 and shp2:
Projected Coordinate System: NAD_1983_HARN_StatePlane_Oregon_North_FIPS_3601_Feet_Intl
Projection: Lambert_Conformal_Conic
False_Easting: 8202099.73753281
False_Northing: 0.00000000
Central_Meridian: -120.50000000
Standard_Parallel_1: 44.33333333
Standard_Parallel_2: 46.00000000
Latitude_Of_Origin: 43.66666667
Linear Unit: Foot
Geographic Coordinate System: GCS_North_American_1983_HARN
Datum: D_North_American_1983_HARN
Prime Meridian: Greenwich
Angular Unit: Degree
.prj data for both shp1 and shp2:
PROJCS["NAD_1983_HARN_StatePlane_Oregon_North_FIPS_3601_Feet_Intl",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",8202099.737532808],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",44.33333333333334],PARAMETER["Standard_Parallel_2",46.0],PARAMETER["Latitude_Of_Origin",43.66666666666666],UNIT["Foot",0.3048]]
For those who might have the same problem, in the course of answering this question (r/gis/reddit proved the most useful) I learned:
There are local coordinate systems which might not show up on Arc or Q. In this case, the data was derived from a CAD file, a DWG that I converted for a project.
One can change the data frame projected coordinate system within Arc trying to find a fit. In this case there was none, no matter how long or hard I tried
Some Coordinate systems are simply so local they aren't useful, or as a redditor put it, "garbage", so don't waste your time trying to make them fit.
4.The Spatial Adjust tool can be used to effectively georeference a dataset with an unknown coordinate system to one which is known. So in my case, I took the .shp and then used the spatial adjust toolset to "rubbersheet" it to some clearly defined data. Easy. Took a few minutes. Made it fit, defined projection, called it good.
I am conducting a spatial econometrics study on housing prices.
In order to calculate spatial auto-correlation between house locations using some econometric software (like Matlab), I use decimal latitude/longitude coordinates of each house as the location in the entry of the program.
I was recently surprised by the question of a researcher asking me if the coordinates that I enter in Matlab are indeed Cartesian coordinates and not geographic ones? Otherwise, he said, estimates leads to wrong results!
I didn't respond to him because I ignored the difference between geographic coordinates and cartesian coordinates.
Today I find in wikipedia the definition of the projected coordinate system that I use (Universal Transverse Mercator) that it "uses a 2-dimensional Cartesian coordinate system to give locations on the surface of the Earth". I am confused.
Are UTM coordinates already cartesian ones? If not, how are they related?
I have a map of a mountainous landscape, http://skimap.org/data/989/60/1218033025.jpg. It contains a number of known points, the lat-longs of which can be easily found out using Google maps. I wish to be able to pin any latitude longitude coordinate on the map, of course within the bounds of the landscape.
For this, I tried an approach that seems to be largely failing. I assumed the map to be equivalent to an aerial photograph of the Swiss landscape, without any info about the altitude or other coordinates of the camera. So, I assumed the plane perpendicular to the camera lens normal to be Ax+By+Cz-d=0.
I attempt to find the plane constants, using the known points. I fix my origin at a point, with z=0 at the sea level. I take two known points in the landscape, and using the equation for a line in 3D, I find the length of the projection of this line segment joining the two known points, on the plane. I multiply it by another constant K to account for the resizing of this length on a static 2d representation of this 3D image. The length between the two points on a 2d static representation of this image on this screen can be easily found in pixels, and the actual length of the line joining the two points, can be easily found, since I can calculate the distance between the two points with their lat-longs, and their heights above sea level.
So, I end up with an equation directly relating the distance between the two points on the screen 2d representation, lets call it Ls, and the actual length in the landscape, L. I have many other known points, so plugging them into the equation should give me values of the 4 constants. For this, I needed 8 known points (known parameters being their name, lat-long, and heights above sea level), one being my orogin, and the second being a fixed reference point. The rest 6 points generate a system of 6 linear equations in A^2, B^2, C^2, AB, BC and CA. Solving the system using a online tool, I get the result that the system has a unique solution with all 6 constants being 0.
So, it seems that the assumption that the map is equivalent to an aerial photograph taken from an aircraft, is faulty. Can someone please give me some pointers or any other ideas to get this to work? Do open street maps have a Mercator projection?
I would say that this impossible to do in an automatic way. The skimap should be considered as an image rather than a map, a map is an projection of the real world into one plane, since this doesn't fit skimaps very well they are drawn instead.
The best way is probably to manually define a lot of points in the skimap with known or estimated coordinates and use them to estimate the points betwween. To get an acceptable result you probably have to assign coordinates to each pixel in the skimap.
You could do something like the following: http://magazin.unic.com/en/2012/02/16/making-of-interactive-mobile-piste-map-by-laax/
I am solving the exact same issue. It is pretty hard and lots of maths. Taking me a few weeks to solve it. Interpolation is the key as well with lots of manual mapping. I would say that for a ski mountain it will take at least 1000/1500 points to be able to get the very basic. So, not a trivial task unless you can automate the collection of these points (what I am doing!) ;)
I'm making a core-location driven app where I must calculate lots of things for a given latitude/longitude pair, such as:
Distance to another lat/long coordinate
The target lat/long coordinate when traveling a distance x into direction y
Is there something open sourced which can be used?
Since you are using CoreLocation, you can use CoreLocation's distanceFromLocation as #progrmr points out.
On the other hand, since you specified open source, and that ain't open sourced, you can look at GeographicLib implementations as suggested by #MikeT.
(My original answer, suggesting the Haversine formula, was flawed. As #MikeT points out, the Haversine formula is only valid for spheres. And the Earth is not a perfect sphere.)
Original, flawed answer:
It sounds like you want the Haversine formula.
The Wikipedia page for the Haversine formula explains what it is and (at the bottom, under "External links") contains links to many implementations. I haven't checked, but I have to imagine that at least some of them are open source projects.
There are some C functions on github that does heading from a coordinate pair, or destination coordinates given start and heading. Distance between coordinates you can do with CLLocation.
These are based on the Spherical Law of Cosines and derived from the algorithms here and here.
GeographicLib has been implemented in several programming languages, including Java. The library calculates lengths and related mathematical properties of geodesics on ellipsoids of revolution (or spheroid). The calculation errors are generally in the range of micrometers.
To find the distance between two coordinates:
GeodesicData g = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2,
GeodesicMask.DISTANCE);
then get g.s12 for the distance between the two points.
The second example in the question, to project a location given distance and direction, is found using the Direct methods.
I am in charge of a program that is used to create a set of nodes and paths for consumption by an autonomous ground vehicle. The program keeps track of the locations of all items in its map by indicating the item's position as being x meters north and y meters east of an origin point of 0,0. In the real world, the vehicle knows the location of the origin's lat and long, as it is determined by a dgps system and is accurate down to a couple centimeters. My program is ignorant of any lat long coordinates.
It is one of my goals to modify the program to keep track of lat long coords of items in addition to an origin point and items' x,y position in relation to that origin. At first blush, it seems that I am going to modify the program to allow the lat long coords of the origin to be passed in, and after that I desire that the program will automatically calculate the lat long of every item currently in a map. From what I've researched so far, I believe that I will need to figure out the math behind converting to lat long coords from a UTM like projection where I specify the origin points and meridians etc as opposed to whatever is defined already for UTM.
I've come to ask of you GIS programmers, am I on the right track? It seems to me like there is so much to wrap ones head around, and I'm not sure if the answer isn't something as simple as, "oh yea theres a conversion from meters to lat long, here"
Currently, due to the nature of DGPS, the system really doesn't need to care about locations more than oh, what... 40 km? radius away from the origin. Given this, and the fact that I need to make sure that the error on my coordinates is not greater than .5 meters, do I need anything more complex than a simple lat/long to meters conversion constant?
I'm knee deep in materials here. I could use some pointers about what concepts to research.
Thanks much!
Given a start point in lat/long and a distance and bearing, finding the end point is a geodesic calculation. There's a great summary of geodesic calculations and errors on the proj.4 website. They come to the conclusion that using a spherical model can get results for distance between points with at most 0.51% error. That, combined with a formula to translate between WGS-84 and ECEF (see the "LLA to ECEF" and "ECEF to LLA" sections, seems like it gets you what you need.
If you want to really get the errors nailed down by inverse projecting your flat map to WGS-84, proj.4 is a projection software package. It has source code, and comes with three command line utilities - proj, which converts to/from cartographic projection and cartesian data; cs2cs, which converts between different cartographic projections; and geod, which calculates geodesic relationships.
The USGS publishes a very comprehensive treatment of map projections.
I'd do a full-up calculation if you can. That way you'll always be as accurate as you can be.
If you happen to be using C++ the GDAL is a very good library.
For a range of 40km, you may find that approximating the world to a 2D flat surface may work, although a UTM transform would be the ideal way to go - in any case, I'd advocate using the actual WGS84 co-ordinates & ellipsoid for calculations such as great circle distance, or calculating bearings.
If you get bored, you could go down a similar line to something I've been working on, that can be used as a base class for differing datums such as OSGB36 or WGS84...