如何确定点坐标是否存在于其他两个点坐标之间的路径上?

2024-09-29 19:19:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个应用程序,它可以从房屋列表中提取数据,并计算到最近的商店和火车站的距离。我已经得到了所有商店、列表和火车站的纬度、经度坐标,目前我使用geopy.distance

import geopy.distance
distanceToShop = geopy.distance.distance(shopCoordinate, listingCoordinate).km
distanceToStation = geopy.distance.distance(stationCoordinate, listingCoordinate).km

这会在两点之间产生一个以公里为单位的值。然后,我筛选出离商店和火车站不够近的位置。对于火车站,我容忍的距离比商店要长。有时商店太远,无法过滤,但在去车站的路上。在这种情况下,我会容忍到商店的距离更长,因为它在去车站的路上

在这种情况下,商店位于房子和车站之间。车站位于坐标(40.651100,-73.949626)处。房子在坐标(40.651401,-73.937987)处。房屋和车站之间的距离为0.98公里

在下面的场景中,车间位于坐标(40.650913,-73.948301)处,从房屋到车间的距离为870米

从房子到商店的可接受距离为650米。但是,如果商店正在从车站出发的路上,则可以接受更长的距离。如果我因为最近的商店太远(870m>;650m)而天真地放弃了房子,那么这所房子就不符合条件,但在这种情况下,商店就在从车站(回家的路上)出发的路上,所以应该符合条件

Representation of problem on a map

更稳健的解决方案是计算两点之间的面积(例如正方形),并确定商店是否位于正方形内。这将产生更现实的结果

Representation of square drawn on map

我如何通过编程来确定情况是否如此?有我可以学习的图书馆吗

编辑:已解决-找到一种计算方向角(两个坐标之间的角度)的方法,该方法可以操作并用于计算其他坐标。通过计算方位角,我可以将其偏移+/-90度,为目标和目标坐标创建角点。然后使用另一个导入(shapely),我从坐标中绘制了一个多边形,并检查该矩阵中是否存在商店

编辑2:使用GeographicalIB.geodesic的更整洁的解决方案,导入更少:

import geopy.distance
from geographiclib.geodesic import Geodesic
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon

def getAreaCorners(origin, target, distanceInMeters, angle):
    geod = Geodesic.WGS84
    bearing = geod.Inverse(origin[0], origin[1], target[0], target[1])['azi1']
    rightBearing = bearing + angle
    if rightBearing < 0: rightBearing += 360
    leftBearing = bearing - angle
    if leftBearing < 0: leftBearing += 360
        
    og1 = geod.Direct(origin[0], origin[1], rightBearing, distanceInMeters)
    og2 = geod.Direct(origin[0], origin[1], leftBearing, distanceInMeters)
    og1 = (og1['lat2'], og1['lon2'])
    og2 = (og2['lat2'], og2['lon2'])
    
    tg1 = geod.Direct(target[0], target[1], rightBearing, distanceInMeters)
    tg2 = geod.Direct(target[0], target[1], leftBearing, distanceInMeters)
    tg1 = (tg1['lat2'], tg1['lon2'])
    tg2 = (tg2['lat2'], tg2['lon2'])
    return [og1, og2, tg2, tg1]

def isShopOnPath(areaCoordinateList, shopCoordinate):
    polygon = Polygon(areaCoordinateList)
    shopCoordinatePoint = Point(shopCoordinate)
    return polygon.contains(shopCoordinatePoint)

origin = (40.650809, -73.949583)
target = (40.644661, -73.943108)
shopCoordinate = (40.650467, -73.948553)
distanceInMeters = 100
angle = 90

distanceToShop = round(geopy.distance.distance(shopCoordinate, target).km,2)
distanceToStation = round(geopy.distance.distance(origin, target).km,2)

print('House is {} km from station. Shop is {} km from house.'.format(distanceToStation, distanceToShop))
if distanceToShop >= 0.65:
    if isShopOnPath(getAreaCorners(origin, target, distanceInMeters, angle), shopCoordinate):
        print('Shop is too far, but on the way from the station.')
    else:
        print('Shop is too far and not on the way from the station')
else:
    print('Shop is less than 650m from the house.')

Tags: fromimport距离targetorigin商店distance车站

热门问题