OpenLayers 4.3.2 版本解析:ol.Sphere 球面测量函数 getLength 与 getArea 的导出修复
OpenLayers 4.3.2 版本解析ol.Sphere 球面测量函数 getLength 与 getArea 的导出修复【免费下载链接】openlayersOpenLayers项目地址: https://gitcode.com/gh_mirrors/op/openlayersOpenLayers v4.3.2 是一次聚焦的小版本修复发布整个版本只包含一个修复项将ol.Sphere.getLength与ol.Sphere.getArea两个球面测量函数纳入公开 API 导出对应 PR #7140由 fredj 提交。本文以该版本记录为切入点结合当前仓库中 src/ol/sphere.js 的实现与 test/browser/spec/ol/sphere.test.js 测试用例系统讲解这两个函数的设计初衷、参数语义、底层算法、API 演进脉络与实战用法帮助你在地图应用中正确完成大圆距离、球面长度与球面面积的计算。v4.3.2 修复了什么根据 changelog/v4.3.2.md 的记载The v4.3.2 release includes a single fix.[#7140] Export ol.Sphere.getLength and ol.Sphere.getArea (fredj)v4.3.2 的发布说明非常简短——整个版本仅包含单个修复a single fix即把ol.Sphere.getLength和ol.Sphere.getArea导出为公开 API。这与上游同一 PR 编号在 changelog/v4.4.0.md 中再次出现标注为 openlayers的情况相互印证说明该导出修复随 4.3.x 与 4.4.0 两条发布线先后落地。要理解这次修复的价值需要回溯 v4.3.0 引入的新特性。在 changelog/v4.3.0.md 中OpenLayers 明确宣布The newol.Sphere.getArea()andol.Sphere.getLength()methods can be used to calculate spherical measures on geometries. This is the recommended over using thegeometry.getArea()orgeometry.getLength()methods.也就是说v4.3.0 新增了基于球面的几何测量函数并建议开发者优先使用它们而不是几何对象自带的getArea()/getLength()方法// 不推荐平面算法未考虑地球曲率 geometry.getArea(); // 推荐球面算法结果以米为单位 ol.Sphere.getArea(geometry);问题在于v4.3.0 虽然引入了这两个函数却未将其纳入对外导出的 API 白名单导致外部应用无法直接调用。v4.3.2 正是补齐了这一导出缺口使这两个函数成为稳定、可依赖的公共接口。球面测量函数的完整 API 形态在当前仓库中这两个函数位于 src/ol/sphere.js模块化后以命名导出named export的形式暴露getLength(geometry, options)返回几何对象的球面长度单位为米metersgetArea(geometry, options)返回几何对象的球面面积单位为平方米square meters。参数与默认值两个函数共享同一组选项对象SphereMetricOptions源码注释定义于 src/ol/sphere.js选项类型默认值说明projectionProjectionLikeEPSG:3857输入几何所在的投影坐标系。默认假定几何为 Web MercatorEPSG:3857坐标函数内部会将其变换到 EPSG:4326 后再计算radiusnumber6371008.8球体半径。默认使用 WGS84 椭球体的平均地球半径mean Earth radius其中默认半径常量DEFAULT_RADIUS 6371008.8定义于 src/ol/sphere.js其含义为 WGS84 椭球体平均半径1/3 * (2a b)a 为长半轴、b 为短半轴。源码注释同时给出公式出处为 Wikipedia 的 Earth radius#Mean radius 条目。支持与不支持的几何类型从 src/ol/sphere.js 的getLength实现可以精确看到各几何类型的处理逻辑Point / MultiPoint长度为 0点没有长度LineString / LinearRing累加相邻顶点间的大圆距离MultiLineString / Polygon对每条环分别计算长度后求和多边形长度为所有环之和MultiPolygon逐多边形、逐环累加GeometryCollection递归调用自身对各子几何求和其他未知类型抛出Unsupported geometry type: ...异常。getAreasrc/ol/sphere.js则对Point、MultiPoint、LineString、MultiLineString、LinearRing 返回 0线状要素无面积对 Polygon 取外环面积再减去各内环面积洞MultiPolygon 与 GeometryCollection 同样递归累加。需要注意一个实现细节除GeometryCollection外函数会先geometry.clone().transform(projection, EPSG:4326)将几何变换到经纬度坐标系再基于经纬度做球面计算而GeometryCollection由于内部可能包含不同坐标系子几何由递归调用逐个子几何自行处理变换。底层算法大圆距离与球面多边形面积getLength 的核心getDistance 大圆距离getLength的每一步长度累加都调用内部函数getDistance(c1, c2, radius)src/ol/sphere.js其本质是**球面余弦定律haversine 公式**的变体const lat1 toRadians(c1[1]); const lat2 toRadians(c2[1]); const deltaLatBy2 (lat2 - lat1) / 2; const deltaLonBy2 toRadians(c2[0] - c1[0]) / 2; const a Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * Math.cos(lat1) * Math.cos(lat2); return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));计算过程是先把两点经纬度转成弧度构造 haversine 中间量a再用atan2求得球心角最后乘以球半径得到大圆距离米。getLengthInternalsrc/ol/sphere.js则把一条线的相邻顶点两两调用getDistance并求和从而得到折线在球面上的累计长度——注意这是大圆距离之和不是简单的平面欧氏距离累加。getArea 的核心球面多边形面积算法getArea使用 JPL 2007 年技术报告《Some Algorithms for Polygons on a Sphere》Robert. G. Chamberlain 与 William H. DuquetteJPL Publication 07-03中给出的算法相关引用写在源码注释中src/ol/sphere.js。内部函数getAreaInternal(coordinates, radius)src/ol/sphere.js对环上每个顶点做如下累加area toRadians(x2 - x1) * (2 Math.sin(toRadians(y1)) Math.sin(toRadians(y2)));最终面积由(area * radius * radius) / 2.0得出。需要注意两点环的走向决定面积符号源码注释明确指出顺时针环得到正值、逆时针环得到负值因此getArea在外层总是取Math.abs()洞的处理多边形面积 外环面积绝对值 − 各内环面积绝对值实现见 src/ol/sphere.js这保证了带洞多边形能算出正确净面积。测试如何验证这两个函数test/browser/spec/ol/sphere.test.js 为getLength、getArea、getDistance提供了详尽的断言可直接作为结果正确性的可执行证据getDistance覆盖 15 组经纬度点对例如[0,0]到[45,45]的距离断言为6671704.814011975米误差 1e-6并验证了对称性[45,-45]等组合结果一致getLength对 EPSG:3857 投影坐标的 LineString 断言长度4407939.124914191米对同样的地理坐标EPSG:4326{projection: EPSG:4326}选项断言得到完全一致的结果——这直接验证了投影选项自动变换的行为MultiLineString 长度恰为单线两倍、GeometryCollection 长度为其子几何之和getArea读取 WKT 格式的伊利诺伊州多边形spec/ol/format/wkt/illinois.wkt断言球面面积为145652224192.4434平方米同时验证了 EPSG:4326 坐标直接计算与先变换到 EPSG:3857 再计算默认投影结果一致误差 1e-3以及 GeometryCollection 面积为其组成部分之和。这些测试用例是理解函数语义的最佳参考答案例如想确认某条航线的大圆距离数值是否合理可以直接对照getDistance的期望值。API 演进从 ol/Sphere 构造器到模块化函数v4.3.2 的导出修复只是这条演进链上的一环。把多个版本的 changelog 串联起来可以看清完整脉络v4.3.0新增ol.Sphere.getArea()/ol.Sphere.getLength()静态方法推荐取代几何自带的平面测量方法changelog/v4.3.0.mdv4.3.2补上这两个方法的公开导出本次修复的核心v5.0.0彻底移除ol/Sphere构造器改为模块化函数导出迁移说明详见 changelog/upgrade-notes.md// ol4 时代的旧写法 import Sphere from ol/sphere; const sphere new Sphere(Sphere.DEFAULT_RADIUS); const area sphere.getGeodesicArea(polygon); const distance sphere.haversineDistance(g1, g2);// ol5 的新写法当前仓库 [src/ol/sphere.js](https://link.gitcode.com/i/2051647ce41b79ceb8a580cb32842b1c) 即为该形态 import {getArea, getDistance} from ol/sphere; const area getArea(polygon); const distance getDistance(g1, g2);映射关系是getGeodesicArea→getAreahaversineDistance→getDistance。同时ol/geom/Polygon的circular函数不再要求Sphere作为首参见 changelog/upgrade-notes.md。当前仓库源码中还保留着getDistance与offset按距离和方位角推算目标点两个模块级函数属于同一套球面计算工具集。实战用法与代码示例结合当前仓库 API推荐以下调用方式ES Module 形态import {getArea, getLength} from ol/sphere; // 1. Web MercatorEPSG:3857几何使用默认投影与默认半径 const length getLength(lineStringGeometry); // 单位米 const area getArea(polygonGeometry); // 单位平方米 // 2. 地理坐标EPSG:4326几何需显式声明投影 const length4326 getLength(geoLineString, {projection: EPSG:4326}); const area4326 getArea(geoPolygon, {projection: EPSG:4326}); // 3. 自定义球体半径例如使用自定义椭球平均半径或月球半径 const lengthOnMars getLength(line, {radius: 3389500});适用场景路线/航线的球面距离测量、面积量算工具如 measure 类应用、跨投影的几何统计。由于结果始终以米为单位且与投影无关最适合在需要真实地理度量值的场景中使用。使用要点输入几何默认按 EPSG:3857 处理若坐标是经纬度EPSG:4326务必传{projection: EPSG:4326}否则会先被当作 Web Mercator 米制坐标变换得到错误量级的数值点/多点几何长度为 0线状几何面积为 0这是算法定义而非 bug面积结果受球面假设限制——球面算法假设多边形边是大圆线段与真实椭球面如 WGS84存在细微差异需要更高精度时应在理解该误差的前提下使用未知几何类型会抛出Unsupported geometry type异常传入自定义几何类型时需谨慎。小结OpenLayers v4.3.2 虽是一个只含单条修复的小版本但其意义并不小它把 v4.3.0 引入的ol.Sphere.getLength与ol.Sphere.getArea正式纳入公共 API让球面测量能力成为可稳定依赖的官方接口。这两个函数以 WGS84 平均地球半径与 haversine 大圆距离、JPL 球面多边形面积算法为数学基础支持任意几何类型并自动完成投影变换其正确性由 test/browser/spec/ol/sphere.test.js 中精确到 1e-6 数量级的断言背书。理解这次修复及其演进脉络v4.3.0 引入 → v4.3.2 导出 → v5.0.0 模块化能帮助你在新旧版本代码迁移与实际测量需求中少走弯路。延伸阅读changelog/v4.3.2.md本次发布说明、changelog/v4.3.0.md特性引入说明、changelog/upgrade-notes.mdv5 迁移指南、src/ol/sphere.js完整实现源码。【免费下载链接】openlayersOpenLayers项目地址: https://gitcode.com/gh_mirrors/op/openlayers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考