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

如何使地图可视区域内的阿尔卑斯山峰查询结果均匀分布?

解决地图缩小后山峰查询结果分布不均的方案

方案1:网格划分采样

将当前可视区域均匀划分为多个网格,每个网格内选取最高海拔的若干山峰,最后合并结果并补全数量,确保每个区域都有山峰入选,避免结果集中在单一高海拔地带。

比如划分为4×4网格,每个网格取1个最高海拔山峰,若总数不足20,再从剩余山峰中补选高海拔的:

// 计算网格步长
const latStep = (lat_max - lat_min) / 4;
const lngStep = (lng_max - lng_min) / 4;

const mountains = [];

// 遍历所有网格
for (let i = 0; i < 4; i++) {
  for (let j = 0; j < 4; j++) {
    const gridLatMin = lat_min + i * latStep;
    const gridLatMax = lat_min + (i + 1) * latStep;
    const gridLngMin = lng_min + j * lngStep;
    const gridLngMax = lng_min + (j + 1) * lngStep;

    const gridPeaks = await prisma.mountain.findMany({
      where: {
        lat: { gt: gridLatMin, lt: gridLatMax },
        lng: { gt: gridLngMin, lt: gridLngMax },
      },
      orderBy: { elevation: "desc" },
      take: 1,
    });

    mountains.push(...gridPeaks);
  }
}

// 补选剩余数量的高海拔山峰
if (mountains.length < 20) {
  const existingIds = mountains.map(m => m.id);
  const additionalPeaks = await prisma.mountain.findMany({
    where: {
      lat: { gt: lat_min, lt: lat_max },
      lng: { gt: lng_min, lt: lng_max },
      id: { notIn: existingIds },
    },
    orderBy: { elevation: "desc" },
    take: 20 - mountains.length,
  });
  mountains.push(...additionalPeaks);
}

方案2:空间加权排序

结合山峰的海拔高度与到可视区域中心的距离,计算加权得分并排序,让既高海拔又空间分散的山峰优先入选。需要数据库支持基础的数学计算(或空间函数):

用平面距离近似计算(无需空间扩展)

const centerLat = (lat_min + lat_max) / 2;
const centerLng = (lng_min + lng_max) / 2;

const mountains = await prisma.$queryRaw`
  SELECT *, 
    (elevation * 1000) / (
      SQRT(POW(lat - ${centerLat}, 2) + POW(lng - ${centerLng}, 2)) + 1
    ) AS weighted_score
  FROM mountain
  WHERE lat > ${lat_min} AND lat < ${lat_max}
    AND lng > ${lng_min} AND lng < ${lng_max}
  ORDER BY weighted_score DESC
  LIMIT 20;
`;

用空间函数精确计算(需PostGIS等扩展)

const centerLat = (lat_min + lat_max) / 2;
const centerLng = (lng_min + lng_max) / 2;

const mountains = await prisma.$queryRaw`
  SELECT *, 
    (elevation * 1000) / (ST_Distance(
      ST_Point(lng, lat), 
      ST_Point(${centerLng}, ${centerLat})
    ) + 1) AS weighted_score
  FROM mountain
  WHERE lat > ${lat_min} AND lat < ${lat_max}
    AND lng > ${lng_min} AND lng < ${lng_max}
  ORDER BY weighted_score DESC
  LIMIT 20;
`;

可通过调整1000这个系数,平衡海拔和空间分布的优先级。

方案3:分层空间抽样

先将可视区域内的山峰按海拔分为高、中、低三层,再在每层内按空间维度排序抽样,确保不同海拔段的山峰都有展示:

// 1. 获取可视区域内的海拔范围
const elevationRange = await prisma.mountain.aggregate({
  where: {
    lat: { gt: lat_min, lt: lat_max },
    lng: { gt: lng_min, lt: lng_max },
  },
  _min: { elevation: true },
  _max: { elevation: true },
});

const minElev = elevationRange._min.elevation;
const maxElev = elevationRange._max.elevation;
const mid1 = minElev + (maxElev - minElev) / 3;
const mid2 = minElev + 2 * (maxElev - minElev) / 3;

// 2. 分层抽样:按海拔段分配数量
const highPeaks = await prisma.mountain.findMany({
  where: {
    lat: { gt: lat_min, lt: lat_max },
    lng: { gt: lng_min, lt: lng_max },
    elevation: { gte: mid2 },
  },
  orderBy: { lng: "asc" }, // 按经度排序实现空间分散
  take: 7,
});

const midPeaks = await prisma.mountain.findMany({
  where: {
    lat: { gt: lat_min, lt: lat_max },
    lng: { gt: lng_min, lt: lng_max },
    elevation: { gte: mid1, lt: mid2 },
  },
  orderBy: { lng: "asc" },
  take: 7,
});

const lowPeaks = await prisma.mountain.findMany({
  where: {
    lat: { gt: lat_min, lt: lat_max },
    lng: { gt: lng_min, lt: lng_max },
    elevation: { lt: mid1 },
  },
  orderBy: { lng: "asc" },
  take: 6,
});

// 合并结果
const mountains = [...highPeaks, ...midPeaks, ...lowPeaks];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:21:34