常见Longitude/Latitude/UTM的转换

This article is categorized as "Garbage" . It should NEVER be appeared in your search engine's results.

本篇笔记使用的坐标以及来源

为了方便二次验证(比如用其他在线工具看看自己的代码是不是真的有问题),这里贴一下本篇笔记涉及的坐标:

坐标来自这张图片:🔗 [gpsimage/gpsimage/images/android_samsung_galaxy.jpg at master · DenisCarriere/gpsimage] https://github.com/DenisCarriere/gpsimage/blob/master/gpsimage/images/android_samsung_galaxy.jpg

exiftool GPS position: 44 deg 14' 42.34" N, 76 deg 27' 5.50" W

坐标(Lat, Long格式): 44.2450944,-76.4515278

用🔗 [Lat Long to UTM Converter] https://www.latlong.net/lat-long-utm.html 转换为UTM以及在地图上定位:

UTM: (384104.82, 4900119.88), utm zone: 18, hemisphere: North

https://www.latlong.net/lat-long-utm.html

经纬度的写法顺序

带有N/S后缀:纬度, Latitude

带有E/W后缀:经度,Longitude

google map的表示顺序(无论是url还是复制到剪贴板的结果):(Latitude, Longitude)

本篇笔记的代码和笔记大部分情况下尽量使用(Lat, Long)的顺序,但由于习惯问题,有些地方可能还是Long, Lat的写法

UTM坐标系,easting: x, northing: y

本篇笔记表示的UTM坐标顺序:(x, y)

常见坐标写法

Lat, Long: 44.2450944,-76.4515278

google map url:  https://www.google.com/maps/place/44°14'42.34"N,76°27'5.50"W 

exiftool, GPS Position:  44 deg 14' 42.34" N, 76 deg 27' 5.50" W 

google map对这一点右键复制过来的结果:44.2450944,-76.4515278

经纬度和UTM的转换

基本逻辑

简单来说就是:

  1. 类似(44, -76)这样的经纬度就可以代表地球上的唯一一点;N/S/E/W后缀可以用经纬度的数值推算,本身没有携带额外信息
  2. 类似(44, -76)这样的经纬度可以转换为UTM (x, y)的格式
  3. 类似(25000, 35000)这样的UTM (x, y)无法代表地球上的唯一一点
  4. 类似(25000, 35000)这样的UTM (x, y)需要加上utm zone,south/north信息才可以转换为经纬度的格式(也就是映射地球上唯一一点)

经度和纬度的正负号表示,以及N/S/E/W后缀表示:

转换流程如下:

以美国为例,UTM zone的划分(这就是为什么单凭utm的(x, y)数字无法定位唯一一点):

https://www.e-education.psu.edu/geog862/node/1817

代码

用到了pyproj. 如果某个时候真的需要看具体实现的代码,可以用这种单文件的、结构简单、功能单一的代码学习:

🔗 [utm/index.es.js at master · TimothyGu/utm] https://github.com/TimothyGu/utm/blob/master/index.es.js

相关资源:

🔗 [ccgalberta.com/ccgresources/report11/2009-410_converting_latlon_to_utm.pdf] https://www.ccgalberta.com/ccgresources/report11/2009-410_converting_latlon_to_utm.pdf

🔗 [Albers Equal Area - EPSG:9822] https://epsg.io/9822-method

from pyproj import Proj


def latlong_to_utm(latitude, longitude):
    utm_zone = int((longitude + 180) // 6) + 1
    hemisphere = 'north' if latitude >= 0 else 'south'
    proj_string = f"+proj=utm +zone={utm_zone} +{hemisphere} +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
    proj_func = Proj(proj_string)
    easting, northing = proj_func(longitude, latitude)
    return easting, northing, utm_zone, hemisphere


def utm_to_latlong(easting, northing, utm_zone, hemisphere):
    # hemisphere接受以下输入:north/south/N/S/North/South/n/s
    proj_string = f"+proj=utm +zone={utm_zone} +{hemisphere} +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
    proj_func = Proj(proj_string)
    longitude, latitude = proj_func(easting, northing, inverse=True)
    return latitude, longitude

以及测试代码:

easting, northing, utm_zone, hemisphere = latlong_to_utm(44.245194, -76.451528)
print(f"(44.245194, -76.451528) -> Easting: {easting}, Northing: {northing}, UTM Zone: {utm_zone}, Hemisphere: {hemisphere}")
lat, long = utm_to_latlong(384105.01791471586, 4900130.991667096, 18, 'north')
print(f'{lat}, {long}')

使用方法:

经纬度转UTM(顺带输出一些额外信息):

easting, northing, utm_zone, hemisphere = latlong_to_utm(44.245194, -76.451528)

UTM转经纬度(需要一些额外信息:utm zone number以及north/south hemisphere)

lat, long = utm_to_latlong(384105.01791471586, 4900130.991667096, 18, 'north')

运行结果:

(44.245194, -76.451528) -> Easting: 384105.01791471586, Northing: 4900130.991667096, UTM Zone: 18, Hemisphere: north
44.245194, -76.451528

(代码)图片Exif, google map url的相互转换

不涉及longlat-UTM的转换,大部分代码还是角度/正负号/字符串处理

浮点数与度数的转换可以用下面这个例子说明:

def float_to_degrees(float_value):
    # 输入: -76.451528
    # 返回: -76°-27'-5.50"
    # 返回的格式(-76°-27'-5.50")距离google map url的后缀格式(-76°-27'-5.50"W)已经很接近了,但还要进一步处理一点东西(见function longlat_to_GmapUrl)
    degrees = int(float_value)
    float_value = (float_value - degrees) * 60
    minutes = int(float_value)
    seconds = (float_value - minutes) * 60
    return "{:d}°{:02d}'{:05.2f}\"".format(degrees, minutes, seconds)
    

def exif_degree_to_googleMap(exif_degree_str):
    # 用exiftool查看照片时会出现的信息:GPS Position: 44 deg 14' 42.34" N, 76 deg 27' 5.50" W
    # 由于这个信息已经非常接近google map的url格式了,所以直接进行简单的字符串替换就行
    # 输入:44 deg 14' 42.34" N, 76 deg 27' 5.50" W
    # 输出:https://www.google.com/maps/place/44°14'42.34"N,76°27'5.50"W
    suffix = exif_degree_str.replace(' ', '').replace('deg', '°')
    return 'https://www.google.com/maps/place/' + suffix


def longlat_to_GmapUrl(input):
    # input format: (string) lat, long (注意是lat在前long在后)
    # input example: "44.24538645689406, -76.45154925766154"
    # output example: https://www.google.com/maps/place/44°14'43.39"N,76°27'05.58"W
    lat = float(input.split(',')[0].strip())  # 44.24538645689406
    long = float(input.split(',')[1].strip())  # -76.45154925766154
    lat_suffix = "N" if lat > 0 else "S"
    long_suffix = "E" if long > 0 else "W"
    # long和lat之间用逗号或者加号都可以
    # google map用后缀(N, S, E, W)表示半球,不使用正负号,所以要用abs(long)和abs(lat)
    url_siffix = float_to_degrees(abs(lat)) + lat_suffix + ',' + float_to_degrees(abs(long)) + long_suffix  # example: 44°14'43.39"N,76°27'05.58"W
    return 'https://www.google.com/maps/place/' + url_siffix

用法以及输出结果:

常见需求

给定照片文件,在google map上查看定位

比如:https://github.com/DenisCarriere/gpsimage/blob/master/gpsimage/images/android_samsung_galaxy.jpg

先用exiftool查看,定位到最后几行:

复制GPS Position并调用 exif_degree_to_googleMap("""44 deg 14' 42.34" N, 76 deg 27' 5.50" W""") 得到google map url:

https://www.google.com/maps/place/44°14'42.34"N,76°27'5.50"W

google map任意一点制作对应google map url

先google map任意一点右键复制(Lat, Long)信息:

复制到剪贴板的格式:

44.24538645689406, -76.45154925766154

这个格式是纯数字的(Latitude, Longitude),要转换为google map url格式还要进行一点处理,所以直接调用 longlat_to_GmapUrl('44.24538645689406, -76.45154925766154') 就可以得到对应的google map url:

https://www.google.com/maps/place/44°14'43.39"N,76°27'05.58"W

注意:上面的google map url需要print,也就是print(longlat_to_GmapUrl('44.24538645689406, -76.45154925766154')),不能使用jupyter notebook那种“直接写个变量就能输出结果”的方式查看(否则url格式会不正确)


 Last Modified in 2024-11-09 

Leave a Comment Anonymous comment is allowed / 允许匿名评论