【问题标题】:Determining if a place (given coordinates) is on land or on ocean确定一个地方(给定坐标)是在陆地上还是在海洋上
【发布时间】:2018-10-11 13:32:28
【问题描述】:

我有一些来自 ISS(国际空间站)的坐标,我想知道记录坐标时 ISS 是在陆地上还是在海洋上空,我应该离线执行此操作,但我不确定采用哪种方法使用。 python标准库的一部分,我仅限于使用这些库:

numpy
scipy
tensorflow
pandas
opencv-python
opencv-contrib-python
evdev
matplotlib
logzero
pyephem
scikit-image
scikit-learn
reverse-geocoder

不过,如果您知道如何使用其他一些库来做到这一点,那就太好了。

使用此代码,我可以获取坐标并将它们写入文件:

import logging
import logzero
from logzero import logger
import os
import ephem
import time

dir_path = os.path.dirname(os.path.realpath(__file__))
logzero.logfile(dir_path+"/coordinates.csv")

# Set a custom formatter
formatter = logging.Formatter('%(name)s - %(asctime)-15s - %(levelname)s: %(message)s');
logzero.formatter(formatter)

name = "ISS (ZARYA)"
line1 = "1 25544U 98067A   18282.18499736  .00001222  00000-0  25998-4 0  9992"
line2 = "2 25544  51.6418 170.6260 0003545 261.4423 234.4561 15.53790940136242"
iss = ephem.readtle(name, line1, line2)

iss.compute()

latitude = iss.sublat
longitude = iss.sublong

# Save the data to the file
logger.info("%s,%s", latitude, longitude )

你们有什么想法吗? 提前致谢。

【问题讨论】:

  • 国际空间站是什么意思?
  • 这是国际空间站。我会把它添加到问题中。
  • 数据中的什么逻辑告诉您坐标是在陆地或海洋上空记录的?
  • 我正在寻找一种方法来检查坐标是在陆地还是海洋中
  • 我实际上想过检查坐标是否在某些范围内,但由于海洋不是正方形,这是不可行的

标签: python coordinates


【解决方案1】:

来自 Karin Todd 的global-land-mask 非常易于使用且高效:

from global_land_mask import globe
print(globe.is_land(49.22, -2.23))
# → True
print(globe.is_land(49.22, -2.25))
# → False

它可以通过pip获得,它唯一的依赖是numpy

【讨论】:

  • 优秀。这样,我可以创建一个静态 cpp 文件来检查经度是否可能是错误的(例如,globe.is_land(lat, lon) 为假但globe.is_land(lat, -lon) 为真)
【解决方案2】:

mpl_toolkits.basemap 或许可以提供帮助。

from mpl_toolkits.basemap import Basemap
bm = Basemap()   # default: projection='cyl'
print(bm.is_land(99.0, 13.0))  #True
print(bm.is_land(0.0, 0.0)) # False

文档:here,相关方法如下:

is_land(xpt, ypt) 如果给定的 x,y 点(在投影坐标中)在陆地上,则返回 True,否则返回 False。土地的定义基于与类实例关联的 GSHHS 海岸线多边形。陆地区域内湖泊上方的点不计为陆地点。

注意:您可能需要小心与 Basemap 对象一起使用的投影。

【讨论】:

【解决方案3】:

最后,我只能使用这些库来解决我的问题。 我使用这个网站geoplaner 获得了海洋形状的粗略轮廓(这真的很粗糙,因为我是手工完成的,但它对我的目的来说效果很好,我认为在线应该有一些更准确的多边形,但我不知道如何使用它们)。

我对每个海洋都这样做并得到了这个(请注意,我使用的坐标并未完全覆盖海洋,例如我避开了南大洋):

    atlanticOcean = [(-24.6,68.5), (25.3,69.8), (5.7,61.4), (4.6,52.2), (-6.3,48.4),
            (-9.45,43.5), (-9.63,37.6), (-6.3,35.5), (-10.5,31.1), (-10.5,28.4),
            (-16.1,24.5), (-17.2,14.7), (-8.2,4.1), (6.3,3.6), (9.9,3.4),
            (9,-1.7), (13.8,-12.6), (11.7,-16.5), (14.5,-22.3), (16.1,-28.67),
            (18.9,-34.5), (18.9,-55.7), (-66,-55.7), (-68.5,-50.4), (-58.6,-39.3), (-48.1,-28.2),
            (-48.1,-25.7), (-41.6,-22.7), (-38.7,-17.4), (-39.5,-13.7), (-36.9,-12.5),
            (-34.9,-10.4), (-35.0,-5.5), (-50,-0.1), (-53,5.5), (-57.2,6.1),
            (-62.8,10.9), (-67.8,10.9), (-74.2,10.8), (-76.9,8.5), (-81.6,9.4),
            (-82.7,14), (-87.4,16.1), (-86.3,21.6), (-90.2,21.7), (-91.2,19.2),
            (-95.7,18.8), (-97.1,25.5), (-91.0,28.9), (-84,29.7), (-82.9,27.3),
            (-80.9,24.9), (-79.3,26.7), (-81.1,31.3), (-75.4,35.2), (-73.8,40.3),
            (-69.6,41.4), (-65.1,43.5), (-60,45.8), (-52.2,47.1), (-54.9,52.9),
            (-44.5,60.1), (-38.8,65.1)]

indianOcean =  [(21.40,-34.15), (27.37,-33.71), (40.03,-15.61), (39.68,-3.50), (51.80,10.16), 
                (58.84,22.26), (65.69,25.18), (71.32,19.83), (77.47,6.86), (80.24,12.53),
                (80.90,15.85), (89.05,22.12), (91.38,22.08), (94.54,17.74), (94.02,16.02),
                (97.00,16.82), (98.19,8.33), (100.78,3.18), (94.98,6.29), (105.0,-6.52),
                (118.16,-9.26), (123.52,-11.25), (129.93,-11.08), (128.62,-14.51), (125.89,-3.57),
                 (118.51,-20.37), (113.06,-22.18), (115.26,-34.44), (123.52,-34.88), (130.99,-32.09),
                (137.23,-36.59), (137.50,-66.47), (102.26,-65.79), (85.65,-66.22), (75.01,-69.50),
                (69.04,-67.67), (54.18,-65.76), (37.48,-68.65)]

现在,太平洋更复杂了,因为它延伸到地图的两侧,并且您可以有两个连续的点,经度分别为 -179 和 179,这导致该多边形在 xy 平面中无法很好地表示。我所做的就是把它分成两部分,所以我得到了这个:

pacificEast = [(149.9,-37.8),(153.9,-28.5),(143.2,-11.5),(152.1,-0.9),(127.9,5.7),
                (122.9,23.8),(123.4,31),(128.9,33.7),(129.8,29.4),(141.6,35),
                (142.8,41),(148,43.3),(144.6,45.5),(146.2,49.3),(144.9,54.2),
                (136.8,55.2),(143.1,59.1),(153.7,59.2),(159.4,61.6),(160.3,60.5),
                (161.4,60.3),(155.4,57),(156.6,50.3),(160.8,52.8),(164.1,55.8),
                (163.8,58.1),(167.3,60.1),(170.7,59.8), (179.9,-77.1),
                (166.4,-77.1), (173.8,-71.8), (142.9,-66.8), (146.9,-44.8)]

pacificWest = [(-179.9,62.2),(-179.7,64.7),
                (-177.3,65.3),(-173.6,63.4),(-166,62.2),(-165.8,60.9),(-168.4,60.4),
                (-166.6,58.9),(-158.5,57.8),(-153.1,57),(-144.8,59.9),(-136.1,56.9),
                (-131.7,51.9),(-125.2,48.4),(-124.5,44.6),(-124.4,40.7),(-117.6,32.7),
                (-110.7,23.2),(-105.8,19.7),(-96.1,15.3),(-87.9,12.4),(-83.7,7.3),
                (-78.7,6.1),(-80.2,0.9),(-82.2,-0.6),(-81.2,-6.3),(-76.7,-14.4),
                (-70.4,-18.9),(-73.7,-36.7),(-76,-46.2),(-75.1,-53),(-73.4,-55.1),
                (-66.6,-56.3),(-64.6,-55),(-59.6,-63.4),(-68.4,-65.7),(-75.8,-72.2),
                (-98.6,-71.8),(-126.8,-73.2),(-146.8,-75.7),(-162.6,-78.4),(-179.9,-77.1)]

据我了解,使用 matplotlib 您可以使用 path 从顶点(坐标列表)创建多边形,然后您可以使用 contains_point() 函数检查该点是否在任一多边形中(因此它在“海洋”中)或不在(在“陆地”中):

    p1 = path.Path(atlanticOcean)
    p2 = path.Path(indianOcean)
    p3 = path.Path(pacificEast)
    p4 = path.Path(pacificWest)

    target = [(lon, lat)]

    result1 = p1.contains_points(target)
    result2 = p2.contains_points(target)
    result3 = p3.contains_points(target)
    result4 = p4.contains_points(target)

    # if target is in one of the polygons, it is in ocean
    if result1==True or result2==True or result3==True or result4==True: 
        print("In Ocean")     
    else:
        print("Land")

对我来说 lon 和 lat 变量是我用问题中的程序计算的 ISS 变量。

【讨论】:

    猜你喜欢
    • 2018-06-02
    • 2012-02-24
    • 2018-04-03
    • 2014-06-21
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    相关资源
    最近更新 更多