【问题标题】:how to find values within a radius from a central position of latitude and longitude value如何从纬度和经度值的中心位置查找半径内的值
【发布时间】:2020-09-03 05:17:41
【问题描述】:

我正在尝试从中心纬度位置计算特定半径内包含的所有值。我使用的代码如下所示:

import numpy as np
import matplotlib.pylab as pl
import netCDF4 as nc
import haversine

f = nc.Dataset('air_temp.nc')


def haversine(lon1, lat1, lon2, lat2):
# convert decimal degrees to radians 
lon1 = np.deg2rad(lon1)
lon2 = np.deg2rad(lon2)
lat1 = np.deg2rad(lat1)
lat2 = np.deg2rad(lat2)

# haversine formula 
dlon = lon2 - lon1 
dlat = lat2 - lat1 
a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
c = 2 * np.arcsin(np.sqrt(a)) 
r = 6371
return c * r

# Latitude / longitude grid
#lat = np.linspace(50,54,16)
lat = f.variables['lat'][:]
#lon = np.linspace(6,9,12)
lon = f.variables['lon'][:]
clat = 19.7
clon = 69.7
max_dist = 750      # max distance in km

# Calculate distance between center and all other lat/lon pairs
distance = haversine(lon[:,np.newaxis], lat, clon, clat) 

# Mask distance array where distance > max_dist
distance_m = np.ma.masked_greater(distance, max_dist)

# Dummy data
air = f.variables['air'][0,:,:,:]
data = np.squeeze(air)
data = np.transpose(data)
#data = np.random.random(size=[lon.size, lat.size])
data_m = np.ma.masked_where(distance  >max_dist, data)
# Test: set a value outside the max_dist circle to a large value:
#data[0,0] = 10
#avg = np.nanmean(data_m)-273

我使用过半正弦函数来求距离。现在我面临的问题是我需要距离中心点 2.5 度半径范围内的值,但我得到的都是公里。因此,如果有人可以通过说出我做错了什么或如何以正确的程序来帮助我,我们将不胜感激

【问题讨论】:

  • 半径为 2.5 度的“圆”与半径以千米为单位的“圆”不同。度数的长度随地球表面的位置而变化。 Haversine 公式专门用于计算以公里为单位的距离。如果您需要以度为单位的距离,您可以使用 lat 和 long 偏移的平方和的根,尽管正如我所说,这可能会给您一个非常奇怪的形状,具体取决于您所在的位置。
  • @simonN thnx 浏览我的代码。我实际上并没有得到您所说的代码的哪一部分,请您详细说明。
  • 代码本身并不是真正的问题。你说你想要 2.5 度内的点,但你有找到 750 公里内的点的代码。您的代码只是解决了一个与您说您感兴趣的问题不同的问题。您需要将函数“haversine”替换为生成“距离”(以度为单位)并将您的 max_dist 更改为 2.5 的函数。
  • 好吧,明白你的意思了..会尝试看看..谢谢 cmets mate
  • @simmon 我搜索了以度为单位的半正弦公式,但没有得到任何具体的想法。如果你知道的话,你能帮我看看怎么做吗?

标签: python pandas numpy matplotlib


【解决方案1】:

就直线(或者更确切地说是最短弧线)距离而言,1 度始终是 111 公里(假设地球是一个完美的球体(*已编辑,而不是“正方形”)。

地球上任意两点之间最短圆弧的中心始终是地球的中心。 1 度 = 2π/360 弧度,所以距离为 R(2π/360) = 6371(2π/360) = 111.19。

更新:

你错过的不是haversine计算或者degree-km转换,而是对NetCDF的元数据格式和NumPy的meshgrid的理解。 f.variables['lat'] 给你 37 个纬度值,f.variables['lon'] 给你 144 个经度值,所以如果你想暴力搜索所有这些值,你需要使用 np.meshgrid 生成一个 37*144=5328 点的网格。

功能代码如下:

import numpy as np

def haversine(lon1, lat1, lon2, lat2):
    # convert decimal degrees to radians
    lon1 = np.deg2rad(lon1)
    lon2 = np.deg2rad(lon2)
    lat1 = np.deg2rad(lat1)
    lat2 = np.deg2rad(lat2)

    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
    c = 2 * np.arcsin(np.sqrt(a))
    r = 6371
    return c * r

# center point
ctr_lon, ctr_lat = 69.7, 19.7

# the lon/lat grids
lon = np.arange(0, 360, 2.5)
lat = np.arange(-45, 46, 2.5)

# get coordinates of all points on the grid
grid_lon, grid_lat = np.meshgrid(lon, lat)
dists_in_km = haversine(grid_lon, grid_lat, ctr_lon, ctr_lat)
dists_in_deg = dists_in_km / 111

# find nearby points
thr = 2.5
for i in range(grid_lon.shape[0]):
    for j in range(grid_lon.shape[1]):
        this_lon = grid_lon[i, j]
        this_lat = grid_lat[i, j]
        dist = dists_in_deg[i, j]
        if dist <= thr:
            print('lon=%.1f  lat=%.1f dist=%.2fdeg' % (this_lon, this_lat, dist))

输出:

lon=70.0  lat=17.5 dist=2.22deg
lon=67.5  lat=20.0 dist=2.09deg
lon=70.0  lat=20.0 dist=0.41deg

这是有道理的。

【讨论】:

  • 所以这意味着如果我需要 2.5 度,我需要乘以 111.19*2.5...是否正确
  • 但如果我这样做了,那么它们就不是在这样的距离内的任何值......所有的坐标值都更高......像 8469、9000 等
  • 实际上我想要做的是从那个中心纬度点我想得到中心点周围2.5度半径内的所有值
  • @DebashisPaul IDK 'air_temp.nc' 的地理位置元数据是什么,但如果它是您在 cmets 中指出的,它们似乎相距甚远......最接近 19.7 的纬度是 16 ;最接近 69.7 的经度是 12...
  • 数据的元数据是 2.5*2.5 的网格数据,带 lat, lon, time..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多