hejianhao
2026-04-25 84d98c1e1bf812edd0a7b8cf67183e7ab5b8e71f
fix(地图缩放): 优化站点坐标验证和缩放等级计算逻辑

- 过滤无效坐标点位,避免因NaN导致缩放计算错误
- 统一距离到缩放等级的映射规则,提高代码可维护性
- 增加点位密度检测:高密度区域固定精细视角,低密度区域确保至少显示3个点位
- 修复站点选择时name字段未正确使用pointName的问题
2个文件已修改
78 ■■■■■ 已修改文件
src/robotaxi/pages/site-search/components/favorite-popup/index.tsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/Robotaxi-public-method.ts 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/site-search/components/favorite-popup/index.tsx
@@ -93,11 +93,15 @@
      const firstSite = children[0] || {};
      onSelect({
        ...firstSite,
        name:firstSite.pointName,
        stationId: item?.stationId || firstSite?.stationId,
      });
      return;
    }
    onSelect(item);
    onSelect({
      ...item,
      name:item.pointName,
    });
  };
  const onScroll = (e) => {
src/utils/Robotaxi-public-method.ts
@@ -41,31 +41,65 @@
 */
export const getAutoScaleBySites = (sites: any[]) => {
  if (!Array.isArray(sites) || sites.length === 0) return null;
  if (sites.length === 1) return 16;
  const validSites = sites
    .map((site) => ({
      latitude: Number(site?.latitude),
      longitude: Number(site?.longitude)
    }))
    .filter((site) => Number.isFinite(site.latitude) && Number.isFinite(site.longitude)); // 过滤无效坐标点位
  if (validSites.length === 0) return null;
  if (validSites.length === 1) return 16;
  const resolveScaleByDiagonal = (diagonalMeters: number) => {
    if (diagonalMeters > 12000) return 11;
    if (diagonalMeters > 8000) return 12;
    if (diagonalMeters > 5000) return 13;
    if (diagonalMeters > 3000) return 14;
    if (diagonalMeters > 1500) return 15;
    if (diagonalMeters > 800) return 16;
    return 17;
  }; // 统一距离到缩放等级的映射规则
  const nearbyCounts = validSites.map((targetSite, targetIndex) => {
    return validSites.reduce((count, compareSite, compareIndex) => {
      if (targetIndex === compareIndex) return count; // 密度统计不包含自身
      const meters = getDistance(targetSite.latitude, targetSite.longitude, compareSite.latitude, compareSite.longitude);
      return meters <= 1000 ? count + 1 : count;
    }, 0);
  }); // 每个点位在 1km 半径内的“邻居点”数量
  const maxNearbyCount = Math.max(...nearbyCounts);
  // 高密度区:1km 内点位 > 5(按邻居数统计),固定精细视角。
  if (maxNearbyCount > 5) return 17;
  // 低密度区:1km 内点位 < 2,自动缩小到至少可见 3 个点位。
  if (maxNearbyCount < 2 && validSites.length >= 3) {
    const radiusNeedForThreePoints = validSites.reduce((maxRadius, baseSite) => {
      const neighborDistances = validSites
        .filter((site) => site !== baseSite)
        .map((site) => getDistance(baseSite.latitude, baseSite.longitude, site.latitude, site.longitude))
        .sort((a, b) => a - b);
      const radius = neighborDistances[1]; // 包含 2 个邻居时即可在屏幕中达到 3 个点位
      if (!Number.isFinite(radius)) return maxRadius;
      return Math.max(maxRadius, radius);
    }, 0); // 取最大半径,确保低密度点位也能满足“至少 3 点可见”
    if (radiusNeedForThreePoints > 0) {
      return resolveScaleByDiagonal(radiusNeedForThreePoints * 2);
    }
  }
  let minLat = Number.POSITIVE_INFINITY;
  let maxLat = Number.NEGATIVE_INFINITY;
  let minLng = Number.POSITIVE_INFINITY;
  let maxLng = Number.NEGATIVE_INFINITY;
  sites.forEach((site) => {
    const lat = Number(site?.latitude);
    const lng = Number(site?.longitude);
    if (!Number.isFinite(lat) || !Number.isFinite(lng)) return;
    if (lat < minLat) minLat = lat;
    if (lat > maxLat) maxLat = lat;
    if (lng < minLng) minLng = lng;
    if (lng > maxLng) maxLng = lng;
  validSites.forEach((site) => {
    if (site.latitude < minLat) minLat = site.latitude;
    if (site.latitude > maxLat) maxLat = site.latitude;
    if (site.longitude < minLng) minLng = site.longitude;
    if (site.longitude > maxLng) maxLng = site.longitude;
  });
  if (!Number.isFinite(minLat) || !Number.isFinite(maxLat) || !Number.isFinite(minLng) || !Number.isFinite(maxLng)) {
    return null;
  }
  const diagonalMeters = getDistance(minLat, minLng, maxLat, maxLng);
  if (diagonalMeters > 12000) return 11;
  if (diagonalMeters > 8000) return 12;
  if (diagonalMeters > 5000) return 13;
  if (diagonalMeters > 3000) return 14;
  if (diagonalMeters > 1500) return 15;
  if (diagonalMeters > 800) return 16;
  return 17;
  return resolveScaleByDiagonal(diagonalMeters);
};
/**