Geographic Information Systems Asked by Akim Akimov on August 14, 2020
For machine learning, I need to convert an array of coordinates in lon, lat format to simple floats where x=0,y=0 will be a most southwest coordinate and x=1,y=1 most northeast, and x=0.5,y=0.5 will be coordinate in a center.
How can I do this?
It depends on what metric you need to preserve. One obvious approach is to project it to some appropriate flat coordinate system. To do this, you can use the pyproj
library. Then, simply rescale your coordinates to be in the range [0, 1]. However, this doesn't perfectly preserve spatial relationships because longitude and latitude are on a sphere (or an ellipsoid or geoid), and x,y coordinates are on a flat surface. You should read about different map projections to see what you may be losing. A good reference is Map Projections: A Working Manual. If your positions only cover a small patch of the Earth, the errors may be acceptable to you.
A second approach is to convert the longitude and latitude to (x, y, z) coordinates in 3d space. If you approximate the earth's surface as a sphere, then the formulae should be
x = sin(pi/2-lat) * cos(lon)
y = sin(pi/2-lat) * sin(lon)
z = cos(pi/2-lat)
where lon
and lat
are in radians. In this case however, z=-1 is the south pole, z=1 is the north pole, x=1 and x=-1 are the prime meridian, and the dateline, and y=1 and y=-1 are 90 degrees East and 90 degrees West. Again, you can rescale so that coordinates are [0,1] rather than [-1,1].
Answered by Nat Wilson on August 14, 2020
If utm
coordinates are suitable for your purposes, then note that in lieu of pyproj
, the utm
package is now available and is simpler to use. Just be aware of lng
, lat
ordering vs. easting
, northing
ordering for the respective from_latlon
and to_latlon
functions, per the docs.
The below conversion example would become:
import utm
x, y = utm.from_latlon(input_lat, input_lon)
Use pyproj
for converting your lng, lat pairs to a projected coordinate system. In other words you need to convert from your geographic coordinate system (most likely EPSG code 4326) to a local projected coordinate system, e.g. a local UTM zone or regional system such as the British National Grid (EPSG code 27700).
import pyproj as proj
# setup your projections
crs_wgs = proj.Proj(init='epsg:4326') # assuming you're using WGS84 geographic
crs_bng = proj.Proj(init='epsg:27700') # use a locally appropriate projected CRS
# then cast your geographic coordinate pair to the projected system
x, y = proj.transform(crs_wgs, crs_bng, input_lon, input_lat)
Note that pyproj.transform()
also works on numpy arrays, so you can therefore transform your lon, lat arrays to x, y arrays. You can then use numpy's built-in array methods to normalise your values.
For example:
import numpy as np
x = (x - x.min()) / (x.max() - x.min())
y = (y - y.min()) / (y.max() - y.min())
However, if you are using sklearn
already, then you may as well use sklearn.preprocessing.normalize.
Answered by songololo on August 14, 2020
just use gdal.ApplyGeoTransform adn gdal.InvGeoTransform.Here's the python code:
src = gdal.Open(filename)
#if the file contains GeoTransform
geotrans = src.GetGeoTransform()
#if the file contains only GCPs
gcps = src.GetGCPs()
geotrans = gdal.GCPsToGeoTransform(gcps)
#from pixel coordinate to lat/lon
lat, lon = gdal.ApplyGeoTransform(geoTrans, x,y)
# from lat/lon to pixel coordinate
invTs = gdal.InvGeoTransform(ts)
x, y = gdal.ApplyGeoTransform(invTs, lat, lon)
Answered by hustxujinkang on August 14, 2020
Assuming we have lon = -1.7063, lat = 55.4127
.
Actually for bored ones method is:
import utm
x, y, zone, ut = utm.from_latlon(input_lat, input_lon)
which will give you
581902.0344218995 6141479.109914647 30 U
but note, pyproj is faster and some times more precise according to my tests.
Answered by Vilq on August 14, 2020
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP