坐标转换

基于 gcoord 在 WGS84 / GCJ02 / BD09 / EPSG3857 间转换坐标点与 GeoJSON。

简介

transformPoint / transformGeoJSON 基于 gcoord 在 WGS84 / GCJ02 / BD09 / EPSG3857 间转换坐标:前者转单个经纬度点,后者转任意 GeoJSON 并返回新对象(不修改入参)。常用于把来自高德 / 腾讯(GCJ02)、百度(BD09)的数据纠偏到 WGS84,对齐天地图与 Mapbox 底图。

不同底图的坐标系不同,叠加数据前需统一:
  • 天地图:CGCS2000,与 WGS84 厘米级相容。MapboxTiandituLayerw(EPSG:3857 球面墨卡托)瓦片,WGS84 数据直接对齐,无需转换
  • 高德 / 腾讯:GCJ02(火星坐标,加密偏移),其数据叠到天地图 / Mapbox 前需 GCJ02 → WGS84
  • 百度:BD09,需 BD09 → WGS84

两者均从 @movk/mapbox/utils/coordinate 导入(非自动导入)。

用法

WGS84 坐标在天地图底图上直接对齐;把它转成 GCJ02(高德 / 腾讯坐标系)后叠在天地图上,反而会偏移:

WGS84:对齐天地图
GCJ02:用于高德/腾讯,叠天地图会偏移
<script setup lang="ts">
import { transformPoint } from '@movk/mapbox/utils/coordinate'

// 上海人民广场(WGS84 原始坐标,天地图直接对齐)
const wgs84: [number, number] = [121.4737, 31.2304]
// 转成 GCJ02(高德/腾讯坐标系)后叠在天地图上会偏移
const gcj02 = transformPoint(wgs84, 'WGS84', 'GCJ02')
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap :options="{ style: 'mapbox://styles/mapbox/light-v11', center: wgs84, zoom: 15 }">
      <MapboxTiandituLayer layer="vec" annotation />
      <MapboxMarker :lnglat="wgs84">
        <div class="rounded bg-success px-2 py-0.5 text-xs font-medium text-inverted">
          WGS84:对齐天地图
        </div>
      </MapboxMarker>
      <MapboxMarker :lnglat="gcj02">
        <div class="rounded bg-error px-2 py-0.5 text-xs font-medium text-inverted">
          GCJ02:用于高德/腾讯,叠天地图会偏移
        </div>
      </MapboxMarker>
    </MapboxMap>
  </div>
</template>

示例

纠偏 GeoJSON

把高德导出的 GCJ02 折线经 transformGeoJSON 转回 WGS84,对齐天地图底图。红线为原始 GCJ02(偏移),绿线为转换后 WGS84(对齐):

<script setup lang="ts">
import type { FeatureCollection } from 'geojson'
import { transformGeoJSON } from '@movk/mapbox/utils/coordinate'

// 高德导出的一段折线(GCJ02 坐标,叠在天地图上会偏移)
const raw: FeatureCollection = {
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      properties: {},
      geometry: {
        type: 'LineString',
        coordinates: [
          [121.4737, 31.2304],
          [121.48, 31.233],
          [121.486, 31.2352],
          [121.492, 31.236]
        ]
      }
    }
  ]
}

// 整体纠偏为 WGS84 对齐天地图,返回新对象,不修改 raw
const fixed = transformGeoJSON(raw, 'GCJ02', 'WGS84')
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap
      :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [121.484, 31.234], zoom: 14 }"
    >
      <MapboxTiandituLayer layer="vec" annotation />
      <MapboxLayer
        layer-id="line-raw"
        type="line"
        :source="{ type: 'geojson', data: raw }"
        :paint="{ 'line-color': '#ef4444', 'line-width': 4 }"
      />
      <MapboxLayer
        layer-id="line-fixed"
        type="line"
        :source="{ type: 'geojson', data: fixed }"
        :paint="{ 'line-color': '#22c55e', 'line-width': 4 }"
      />
    </MapboxMap>
  </div>
</template>

控制坐标精度

precision 指定输出坐标保留的小数位数,用于去抖与减小传输体积;省略则保留完整精度:

import { transformGeoJSON } from '@movk/mapbox/utils/coordinate'

const compact = transformGeoJSON(raw, 'GCJ02', 'WGS84', { precision: 6 })

API

transformPoint()

转换单个经纬度点,返回新坐标。

point
[number, number] required
经纬度点 [lng, lat]
from
CRS required
源坐标系。
to
CRS required
目标坐标系。
options.precision
number
输出坐标保留的小数位数,省略则保留完整精度。

返回 [number, number]:转换后的 [lng, lat]

transformGeoJSON()

转换任意 GeoJSON(点 / 线 / 面 / 集合),返回与入参同类型的新对象,不修改入参。

geojson
T required
任意 GeoJSON 对象(Feature / Geometry / FeatureCollection 等)。
from
CRS required
源坐标系。
to
CRS required
目标坐标系。
options.precision
number
输出坐标保留的小数位数,省略则保留完整精度。

返回 T:与入参同类型的新 GeoJSON 对象。

CRS

坐标系标识:'WGS84' | 'GCJ02' | 'BD09' | 'EPSG3857'

Changelog

No recent changes
Copyright © 2026 - 2026 YiXuan - MIT License