You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现从给定点按指定角度、距离统计扇形区域红点数量

Python实现经纬度基准扇形区域红点计数

核心需求

  • 所有待统计红色点位、参考地标点均携带(latitude, longitude)经纬度坐标信息
  • 以地标点为基准,结合给定的中心角度(参考值85°)、波束宽度(参考值50°)、有效距离范围三个约束,统计落在对应扇形覆盖区域内的红点总数

实现逻辑

要准确完成统计,需要解决两个球面坐标的核心计算问题,避免直接把经纬度当平面坐标计算带来的误差:

  1. 两点地表距离计算:采用Haversine公式计算球面两点间的实际距离,适配经纬度坐标的距离判定
  2. 相对方位角计算:以地标点为原点,计算每个红点相对于正北方向的方位角,同时处理扇形跨0°/360°边界的特殊判定场景

完整代码

import math

def haversine_distance(lat1: float, lon1: float, lat2: float, lon2: float, unit: str = "m") -> float:
    """
    计算两个经纬度点之间的地表距离
    :param lat1/lon1: 地标点纬度、经度,单位为十进制度
    :param lat2/lon2: 红点纬度、经度,单位为十进制度
    :param unit: 距离单位,默认m(米),可选km(千米)
    """
    earth_r = 6371000 if unit == "m" else 6371
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    delta_phi = math.radians(lat2 - lat1)
    delta_lambda = math.radians(lon2 - lon1)
    
    a = math.sin(delta_phi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(delta_lambda / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return earth_r * c

def calc_relative_bearing(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
    """
    计算红点相对于地标点的方位角,返回值范围0~360°,正北为0°,顺时针递增
    """
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    delta_lambda = math.radians(lon2 - lon1)
    
    y = math.sin(delta_lambda) * math.cos(phi2)
    x = math.cos(phi1) * math.sin(phi2) - math.sin(phi1) * math.cos(phi2) * math.cos(delta_lambda)
    theta = math.atan2(y, x)
    return (math.degrees(theta) + 360) % 360

def count_red_dots_in_sector(
    placemark: tuple[float, float],
    red_dots: list[tuple[float, float]],
    center_angle: float = 85,
    beam_width: float = 50,
    min_dist: float = 0,
    max_dist: float = 1000,
    dist_unit: str = "m"
) -> int:
    """
    统计扇形覆盖区域内的红点总数
    :param placemark: 参考地标点坐标,格式(纬度, 经度)
    :param red_dots: 待统计红点坐标列表,每个元素格式(纬度, 经度)
    :param center_angle: 扇形中心方位角,单位度
    :param beam_width: 扇形波束总张开宽度,单位度
    :param min_dist: 有效统计最小距离
    :param max_dist: 有效统计最大距离
    :param dist_unit: 距离单位
    """
    count = 0
    half_beam = beam_width / 2
    angle_start = (center_angle - half_beam) % 360
    angle_end = (center_angle + half_beam) % 360
    p_lat, p_lon = placemark

    for dot_lat, dot_lon in red_dots:
        # 距离校验
        dist = haversine_distance(p_lat, p_lon, dot_lat, dot_lon, unit=dist_unit)
        if not (min_dist <= dist <= max_dist):
            continue
        # 方位角校验,兼容跨0°边界的场景
        bearing = calc_relative_bearing(p_lat, p_lon, dot_lat, dot_lon)
        if angle_start > angle_end:
            in_sector = bearing >= angle_start or bearing <= angle_end
        else:
            in_sector = angle_start <= bearing <= angle_end
        if in_sector:
            count += 1
    return count


# 调用示例
if __name__ == "__main__":
    # 示例地标点
    placemark = (39.9042, 116.4074)
    # 示例待统计红点列表
    red_dots = [
        (39.9052, 116.4084),
        (39.9031, 116.4102),
        (39.9067, 116.4021)
    ]
    # 统计:中心角85°、波束宽度50°、有效范围0-500米的红点数量
    total = count_red_dots_in_sector(placemark, red_dots, max_dist=500)
    print(f"扇形区域内红点总数:{total}")

使用说明

  • 输入经纬度需为十进制度格式,若原始数据为度分秒格式需提前转换
  • 方位角默认遵循正北为0°、顺时针递增的通用规则,若业务场景以其他方向为0°基准,提前做角度偏移转换即可
  • Haversine公式在几十公里量级的统计场景下精度足够,若需覆盖超大范围统计,可替换为Vincenty公式提升距离计算精度
  • 代码默认处理了扇形跨正北(0°/360°)的边界场景,不会出现区间判断漏算问题

内容的提问来源于stack exchange,提问作者OzcanK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 09:06:20