mcpField
A
arcgis-coordinates-projection

arcgis-coordinates-projection

github.com/saschabrunnerch数据与数据库2363 次安装29 周前更新
代码仓库

关于 arcgis-coordinates-projection

面向使用 ArcGIS Maps SDK for JavaScript 的开发者,介绍坐标转换与空间参考处理。内容涵盖客户端和服务端投影、坐标格式化及测地计算,并说明如何迁移到当前算子。

主要功能

  1. 01使用客户端或服务端 API 投影几何
  2. 02处理空间参考与地理转换
  3. 03转换 Web Mercator 与地理坐标
  4. 04格式化和解析 DMS、UTM、MGRS、USNG
  5. 05计算测地距离、面积和长度

适用场景

  1. 01在坐标系之间转换几何
  2. 02以多种格式显示地图坐标
  3. 03选择准确计算所需的基准转换

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/saschabrunnerch/arcgis-maps-sdk-js-ai-context --skill arcgis-coordinates-projection

安装后在 Claude Code 中输入/arcgis-coordinates-projection确认已加载。

详细介绍

ArcGIS 坐标与投影

使用此技能进行坐标转换、投影变换、空间参考处理,以及以各种格式显示坐标。

重要:projection 模块(自 4.32 起弃用)和 geodesicUtils(自 4.33 起弃用)已在 v5.0 中移除。请改用 projectOperator 和测地几何运算符。

导入方式

直接 ESM 导入
import projectOperator from "@arcgis/core/geometry/operators/projectOperator.js";
import SpatialReference from "@arcgis/core/geometry/SpatialReference.js";
import coordinateFormatter from "@arcgis/core/geometry/coordinateFormatter.js";
import webMercatorUtils from "@arcgis/core/geometry/support/webMercatorUtils.js";
动态导入(CDN)
const projectOperator = await $arcgis.import(
  "@arcgis/core/geometry/operators/projectOperator.js",
);
const coordinateFormatter = await $arcgis.import(
  "@arcgis/core/geometry/coordinateFormatter.js",
);
const [SpatialReference, webMercatorUtils] = await $arcgis.import([
  "@arcgis/core/geometry/SpatialReference.js",
  "@arcgis/core/geometry/support/webMercatorUtils.js",
]);

坐标转换组件

基本设置
<arcgis-map basemap="topo-vector" center="-117.049, 34.485" zoom="12">
  <arcgis-zoom slot="top-left"></arcgis-zoom>
  <arcgis-coordinate-conversion
    slot="bottom-left"
  ></arcgis-coordinate-conversion>
</arcgis-map>
坐标转换微件(核心 API)
import CoordinateConversion from "@arcgis/core/widgets/CoordinateConversion.js";

const ccWidget = new CoordinateConversion({ view });
view.ui.add(ccWidget, "bottom-left");
自定义坐标格式
import CoordinateConversion from "@arcgis/core/widgets/CoordinateConversion.js";
import Format from "@arcgis/core/widgets/CoordinateConversion/support/Format.js";

const customFormat = new Format({
  name: "Custom XY",
  conversionInfo: {
    spatialReference: { wkid: 4326 },
    reverseConvert: (string) => {
      const parts = string.split(",");
      return [parseFloat(parts[0]), parseFloat(parts[1])];
    },
  },
  coordinateSegments: [
    { alias: "Lon", description: "Longitude", searchPattern: "X" },
    { alias: "Lat", description: "Latitude", searchPattern: "Y" },
  ],
  defaultPattern: "X°, Y°",
});

const ccWidget = new CoordinateConversion({
  view,
  formats: [customFormat],
});

空间参考

常见空间参考
名称WKID类型
WGS 844326地理坐标
Web Mercator102100 or 3857投影坐标
UTM Zone 11N32611投影坐标
State Plane(示例)2230投影坐标
创建空间参考
import SpatialReference from "@arcgis/core/geometry/SpatialReference.js";

// By WKID
const wgs84 = new SpatialReference({ wkid: 4326 });
const webMercator = new SpatialReference({ wkid: 102100 });

// By WKT (for custom projections)
const customSR = new SpatialReference({
  wkt: 'PROJCS["NAD_1983_StatePlane_California_VI_FIPS_0406_Feet"...',
});

// Shorthand (autocast)
const sr = { wkid: 4326 };
SpatialReference 属性
const sr = new SpatialReference({ wkid: 4326 });

console.log(sr.isGeographic); // true for lat/lon systems
console.log(sr.isWebMercator); // true for WKID 3857/102100
console.log(sr.isWGS84); // true for WKID 4326
console.log(sr.wkid); // 4326

客户端投影(projectOperator)

推荐使用此方式在客户端投影几何。

投影几何
import projectOperator from "@arcgis/core/geometry/operators/projectOperator.js";

await projectOperator.load();

const projected = projectOperator.execute(geometry, { wkid: 4326 });
使用地理变换进行投影
import projectOperator from "@arcgis/core/geometry/operators/projectOperator.js";

await projectOperator.load();

const projected = projectOperator.execute(
  geometry,
  { wkid: 4326 },
  {
    geographicTransformation: {
      steps: [{ wkid: 108190 }], // NAD_1983_To_WGS_1984_5
    },
  },
);
保持形状的投影

投影几何时保留测地形状(大圆弧):

import shapePreservingProjectOperator from "@arcgis/core/geometry/operators/shapePreservingProjectOperator.js";

await shapePreservingProjectOperator.load();

const projected = shapePreservingProjectOperator.execute(geometry, {
  wkid: 3857,
});
地理变换实用工具
import geographicTransformationUtils from "@arcgis/core/geometry/operators/support/geographicTransformationUtils.js";

// Get available transformations between two spatial references
const transformations = geographicTransformationUtils.getTransformations(
  { wkid: 4269 }, // NAD83
  { wkid: 4326 }, // WGS84
);

transformations.forEach((t) => {
  console.log(t.wkid, t.wkt);
});

服务端投影(Geometry Service)

适用于复杂投影,或客户端引擎无法满足需求的情况:

import * as geometryService from "@arcgis/core/rest/geometryService.js";
import ProjectParameters from "@arcgis/core/rest/support/ProjectParameters.js";

const gsUrl =
  "https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer";

const params = new ProjectParameters({
  geometries: [geometry],
  outSpatialReference: { wkid: 4326 },
});

const results = await geometryService.project(gsUrl, params);
const projected = results[0];

坐标转换实用工具

Web Mercator 与地理坐标互转
import webMercatorUtils from "@arcgis/core/geometry/support/webMercatorUtils.js";

const geoPoint = webMercatorUtils.webMercatorToGeographic(webMercatorPoint);
const wmPoint = webMercatorUtils.geographicToWebMercator(geoPoint);
const canProject = webMercatorUtils.canProject(fromSR, toSR);
坐标格式化器

将坐标转换为 DMS、UTM、MGRS、USNG 字符串,或从这些字符串转换坐标。

import coordinateFormatter from "@arcgis/core/geometry/coordinateFormatter.js";

await coordinateFormatter.load();

// To Degrees Minutes Seconds
const dms = coordinateFormatter.toLatitudeLongitude(point, "dms", 3);
// Output: "34°29'06.000\"N 117°02'56.400\"W"

// To MGRS
const mgrs = coordinateFormatter.toMgrs(point, "automatic", 5, false);
// Output: "11SNU1234567890"

// To UTM
const utm = coordinateFormatter.toUtm(point, "north-south-indicators", true);
// Output: "11S 500000 3800000"

// To USNG
const usng = coordinateFormatter.toUsng(point, 5, false);

// From string to point
const pointFromDMS = coordinateFormatter.fromLatitudeLongitude(
  "34°29'06\"N 117°02'56\"W",
);
const pointFromMGRS = coordinateFormatter.fromMgrs("11SNU1234567890");
const pointFromUTM = coordinateFormatter.fromUtm("11S 500000 3800000");
const pointFromUSNG = coordinateFormatter.fromUsng("11SNU1234567890");
coordinateFormatter 方法
方法说明
toLatitudeLongitude(point, format, decimals)格式:"dd"、"dm"、"dms"
toMgrs(point, mode, precision, spaces)军用网格参考系统
toUtm(point, mode, spaces)通用横轴墨卡托投影
toUsng(point, precision, spaces)美国国家格网
fromLatitudeLongitude(string)将 DMS/DD 字符串解析为 Point
fromMgrs(string)将 MGRS 解析为 Point
fromUtm(string)将 UTM 解析为 Point
fromUsng(string)将 USNG 解析为 Point

显示坐标

显示鼠标坐标
view.on("pointer-move", (event) => {
  const mapPoint = view.toMap({ x: event.x, y: event.y });
  if (mapPoint) {
    document.getElementById("coords").textContent =
      `Lat: ${mapPoint.latitude.toFixed(6)}, Lon: ${mapPoint.longitude.toFixed(6)}`;
  }
});
多格式坐标显示
import coordinateFormatter from "@arcgis/core/geometry/coordinateFormatter.js";

await coordinateFormatter.load();

view.on("pointer-move", (event) => {
  const point = view.toMap({ x: event.x, y: event.y });
  if (point) {
    document.getElementById("latlon").textContent =
      `${point.latitude.toFixed(6)}, ${point.longitude.toFixed(6)}`;
    document.getElementById("utm").textContent = coordinateFormatter.toUtm(
      point,
      "north-south-indicators",
      true,
    );
    document.getElementById("mgrs").textContent = coordinateFormatter.toMgrs(
      point,
      "automatic",
      5,
      true,
    );
  }
});

测地几何运算

用于测地计算(地球表面上的距离、面积和长度):

import geodeticDistanceOperator from "@arcgis/core/geometry/operators/geodeticDistanceOperator.js";
import geodeticAreaOperator from "@arcgis/core/geometry/operators/geodeticAreaOperator.js";
import geodeticLengthOperator from "@arcgis/core/geometry/operators/geodeticLengthOperator.js";

// Geodesic distance between two points
const distance = geodeticDistanceOperator.execute(point1, point2, {
  unit: "kilometers",
});

// Geodesic area of a polygon
const area = geodeticAreaOperator.execute(polygon, {
  unit: "square-kilometers",
});

// Geodesic length of a polyline
const length = geodeticLengthOperator.execute(polyline, { unit: "kilometers" });

完整的运算符文档请参阅 arcgis-geometry-operations。

从已移除模块迁移

已移除的模块(5.0 之前)替代方案(5.0)
projection.project(geom, sr)projectOperator.execute(geom, sr)
projection.load()projectOperator.load()
geodesicUtils.geodesicDistance(p1, p2, unit)geodeticDistanceOperator.execute(p1, p2, { unit })
geodesicUtils.geodesicArea(geom, unit)geodeticAreaOperator.execute(geom, { unit })
geodesicUtils.geodesicLength(geom, unit)geodeticLengthOperator.execute(geom, { unit })

常见注意事项

  1. 忘记加载投影引擎:使用前必须调用 projectOperator.load() 和 coordinateFormatter.load():

    // Anti-pattern: using before load
    const projected = projectOperator.execute(geom, { wkid: 4326 }); // Error
    
    // Correct: load first
    await projectOperator.load();
    const projected = projectOperator.execute(geom, { wkid: 4326 });
    
  2. 坐标顺序:在 SDK 中,地理坐标顺序为(经度、纬度),而非(纬度、经度)。点属性中,x = 经度,y = 纬度。

  3. WKID 与 WKT:存在众所周知的 ID 时,请使用 WKID。仅当 WKID 注册表中没有对应的自定义坐标系时,才使用 WKT。

  4. 基准面转换:在不同基准面之间投影(例如从 NAD83 转换为 WGS84)时,请提供地理转换以确保精度。否则,结果可能会有数米的偏差。

  5. 客户端与服务端:为提升速度,请使用客户端投影(projectOperator)。仅当客户端引擎无法处理复杂转换时,才使用服务端投影(geometryService.project())。

  6. 使用已移除的模块:projection 和 geodesicUtils 模块已在 5.0 中移除。请改用 projectOperator 和测地运算符。

参考示例

  • coordinate-conversion - 在不同坐标格式之间转换
  • coordinate-conversion-custom - 自定义坐标格式
  • widgets-coordinateconversion - CoordinateConversion 微件的用法
  • widgets-coordinateconversion-custom - 自定义坐标微件格式
  • client-projection - 在客户端投影几何
  • layers-csv-projection - 带投影的 CSV 图层

相关技能

  • 几何创建和空间运算符请参阅 arcgis-geometry-operations。
  • 服务端几何服务(投影、缓冲区等)请参阅 arcgis-rest-services。
  • 地图和视图空间参考配置请参阅 arcgis-core-maps。

评论

支持 Markdown