ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

d3 球面数学 API:d3-geo 低层球面几何函数(面积、边界框、质心、距离、插值与旋转)详解

d3 球面数学 API:d3-geo 低层球面几何函数(面积、边界框、质心、距离、插值与旋转)详解 d3 球面数学 APId3-geo 低层球面几何函数面积、边界框、质心、距离、插值与旋转详解【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3本文聚焦 d3 地理模块d3-geo中的“球面数学”Spherical math低层工具集geoArea、geoBounds、geoCentroid、geoDistance、geoLength、geoInterpolate、geoContains与geoRotation。掌握这些函数后你可以在不依赖地图投影的情况下直接对 GeoJSON 对象做球面面积、距离、长度、包含判定与三轴旋转计算并为自定义地理分析测距、圈选、大圆弧动画、地图视角变换打下基础。一、为什么需要“球面数学”d3-geo 的核心设计是用球面几何表示地理数据而不是平面坐标。正如 docs/d3-geo.md 所述球面上多边形和折线的边是测地线大圆弧段而非直线投影到平面后只有极射平面投影gnomonic能将其保持为直线因此 d3 采用自适应采样来在精度与性能之间取得平衡。在这一模型下地理量应当直接在球面上计算而不是先投影到平面再测量。d3-geo 因此提供了一组与投影无关的“低层工具”low-level utilities for spherical geometry即本文介绍的 8 个 API。它们与投影/路径 API 的关系是互补的球面函数平面等价物投影路径上计算基准geoAreapath.area球面单位steradian 球面度geoBoundspath.bounds球面经纬度单位度geoCentroidpath.centroid球面geoLengthpath.measure球面大弧长度单位弧度geoDistancepath.measure两点 LineString球面大弧距离单位弧度geoInterpolate、geoContains、geoRotation—纯球面几何也就是说*path*.area/*path*.bounds/*path*.centroid/*path*.measure见 路径 API会观察投影所执行的裁剪并输出平面量而geo*数学函数绕开投影直接输出球面量。二、API 总览与获取方式这些函数都是 d3 顶层导出的标准 API在 docs/api.md 的 d3-geo 章节中汇总d3.geoArea(object)—— 计算 GeoJSON 对象的球面面积d3.geoBounds(object)—— 计算球面包围盒d3.geoCentroid(object)—— 计算球面质心d3.geoDistance(a, b)—— 计算两点大弧距离d3.geoInterpolate(a, b)—— 返回沿大圆弧的插值函数d3.geoContains(object, point)—— 点包含判定d3.geoRotation(angles)—— 创建三轴球面旋转函数。从源码结构看本仓库的 src/index.js 通过export * from d3-geo;将 d3-geo 的全部 API 原样并入 d3 顶层命名空间test/d3-test.js 中的测试会遍历 package.json 的每个依赖模块并断言“d3 导出了该模块的全部除version外的导出”因此geoArea等函数在import * as d3 from d3后必然可用。d3-geo 的版本约束为^3.1.1见 package.json具体实现在 d3-geo 独立包中area.js、bounds.js、centroid.js、distance.js、length.js、interpolate.js、contains.js、rotation.js等模块本仓库文档 docs/d3-geo/math.md 即该 API 的权威说明。三、逐函数详解1. geoArea(object)球面面积d3.geoArea(object)返回指定 GeoJSONobject的球面面积单位是 球面度steradian。它是*path*.area的球面等价物——区别在于结果不受任何投影或clipAngle/clipExtent裁剪影响。单位换算提示整个球面的面积为 4π steradian≈12.566。若需要近似平方公里可乘以地球平均半径平方6371 km² 再按需换算这是通用地理学做法d3 本身不做单位转换。2. geoBounds(object)球面包围盒d3.geoBounds(object)返回指定 GeoJSONobject的球面包围盒。返回值是二维数组[[left, bottom], [right, top]]其中left为最小经度bottom为最小纬度right为最大经度top为最大纬度所有坐标以度为单位。一个容易踩坑的点原文档特别提醒在投影后的平面坐标中最小纬度通常对应最大 y 值最大纬度通常对应最小 y 值y 轴向下。若你要把geoBounds的结果换算到屏幕/画布坐标系做定位或缩放必须做这个 y 方向翻转。3. geoCentroid(object)球面质心d3.geoCentroid(object)返回指定 GeoJSONobject的球面质心即[longitude, latitude]度。它是*path*.centroid的球面等价物。典型用途在地图上给州/省/国家边界打标签、做符号地图symbol map时的中心点定位——但注意path.centroid输出的是平面坐标且会受裁剪影响geoCentroid输出的是球面经纬度两者选择取决于你后续要与哪种坐标系打交道。4. geoDistance(a,b)两点大弧距离d3.geoDistance(a, b)返回两点a、b之间的大弧距离单位是弧度。每个点必须以二元数组[longitude, latitude]度给出。它等价于对“由两点组成的 LineString”调用*path*.measure的球面版本。换算提示弧度乘以地球平均半径约 6371 km即可得到近似地表距离km若想要“海里”或“英里”再除以对应的单位长度即可。例如import { geoDistance } from d3-geo; // 北京 (116.4, 39.9) → 巴黎 (2.35, 48.86)单位弧度 const radians geoDistance([116.4, 39.9], [2.35, 48.86]); const km radians * 6371; // 近似地表距离5. geoLength(object)大弧长度d3.geoLength(object)返回指定 GeoJSONobject的大弧长度单位是弧度。对多边形而言返回的是外环周长加上所有内环孔洞周长之和。它是*path*.measure的球面等价物。适用对象包括 LineString、MultiLineString、Polygon、MultiPolygon 等Point 类几何长度为零。6. geoInterpolate(a,b)沿大圆弧插值d3.geoInterpolate(a, b)给定两点a、b均为[longitude, latitude]度返回一个插值函数。该插值函数接收单个参数tt∈ [0, 1]t 0 返回点at 1 返回点b中间值沿同时经过a和b的大圆弧插值若a与b互为对径点antipodes则任选一条大弧。这是制作“飞行弧线”动画的基础设施把它交给 d3 的过渡系统即可让符号沿地球表面最短路径运动而不是在平面上画直线。import { geoInterpolate } from d3-geo; const interpolate geoInterpolate([0, 0], [180, 45]); interpolate(0); // [0, 0] interpolate(0.5); // 沿大弧的中点注意一般不是 [90, 22.5] interpolate(1); // [180, 45]7. geoContains(object,point)球面点包含判定d3.geoContains(object, point)当且仅当指定 GeoJSONobject包含指定point时返回true否则返回false。point必须是[longitude, latitude]度二元数组。判定规则按几何类型区分Point / MultiPoint使用精确匹配测试Sphere恒返回true其他几何类型Polygon、MultiPolygon 等应用一个epsilon 容差阈值避免浮点误差导致“点在边界上”的误判。这使它能用于点击拾取、空间筛选例如“该城市落在哪个国家多边形内”等场景且无需先做投影。8. geoRotation(angles)三轴球面旋转d3.geoRotation(angles)为给定角度返回一个旋转函数。angles必须是二元素或三元素的数字数组[lambda, phi, gamma]分别表示绕三条球面轴的旋转角度对应yaw偏航、pitch俯仰、roll滚转三个分量。若省略gamma默认取 0。它对应投影 API 中的*projection*.rotate见 投影文档。旋转函数提供两个成员rotation(point)给定旋转后的点返回rotation(point)输出新的[longitude, latitude]度数组表示point旋转后的位置rotation.invert(point)rotation的逆运算给定旋转后的点还原出旋转前的[longitude, latitude]度数组。import { geoRotation } from d3-geo; const rotate geoRotation([-150, 0]); // 仅偏航 150° const rotated rotate([0, 0]); // 旋转后的经纬度 const original rotate.invert(rotated); // 还原[0, 0]旋转与逆旋转成对提供使得“把数据旋转到目标视角”和“把屏幕拾取点反算回地理坐标”可以闭环这对做可交互地图视角变换非常关键。四、完整可运行示例以下示例在一个脚本里串联面积、边界框、质心、距离与插值输入是一个简单的 GeoJSON 多边形Node.js 环境依赖本仓库 package.json 中的d3-geo^3.1.1或直接安装d3-geo使用import { geoArea, geoBounds, geoCentroid, geoDistance, geoLength, geoInterpolate } from d3-geo; // 一个位于 (0,0)–(10,10) 的小多边形度 const square { type: Polygon, coordinates: [[ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ]] }; console.log(geoArea(square)); // 球面面积单位 steradian console.log(geoBounds(square)); // [[0, 0], [10, 10]]单位度 console.log(geoCentroid(square)); // 球面质心 [lon, lat] console.log(geoLength(square)); // 外环周长单位弧度 console.log(geoDistance([0, 0], [10, 10])); // 对角线大弧距离弧度 const t geoInterpolate([0, 0], [10, 10]); console.log(t(0.5)); // 大弧中点度五、使用注意事项与投影/裁剪的关系与投影路径方法的分工*path*.area/*path*.bounds/*path*.centroid/*path*.measure观察投影执行的裁剪projection.clipAngle、projection.clipExtent输出平面量geo*数学函数输出球面量与任何投影无关。做“真实地理度量”用后者做“与渲染像素对齐的度量”用前者。单位约定geoArea用 steradiangeoDistance/geoLength用弧度geoBounds/geoCentroid/geoInterpolate/geoRotation的输入输出均为度。混用弧度与度是最常见的错误来源建议统一在脚本入口做一次换算。环绕顺序winding order约定从文档与源码结构看d3-geo 采用自己的环绕约定——小于半球的多边形外环应为顺时针大于半球如海洋的外环为逆时针内环孔洞与外环方向相反。这与 GeoJSON RFC 7946 的约定相反构造手写多边形喂给geoArea/geoLength/geoContains时需注意此约定否则“内外”可能颠倒。详见 docs/d3-geo.md 中的 CAUTION 提示。对径点行为geoInterpolate在a、b互为对径点时选择任意大弧结果不具备唯一性属于定义允许的退化情形。版本与获取本仓库为 d3 7.9.0ESMtype: moduled3-geo 以^3.1.1依赖引入并由 src/index.js 全量再导出因此上述所有geo*函数在import * as d3 from d3后直接可用。六、小结d3-geo 的球面数学 API 是一套“无投影”的地理计算底座geoArea/geoLength/geoDistance给出面积、长度与距离注意 steradian 与弧度单位geoBounds/geoCentroid给出定位信息注意平面坐标系 y 轴翻转geoInterpolate提供大弧插值geoContains提供容差点包含判定geoRotation及其invert提供可逆的三轴旋转。它们共同支撑起投影之外的全部球面地理分析若要进一步渲染则可将结果交给 路径生成器 与 投影projection.rotate与geoRotation使用同一套角度约定。所有函数的精确签名与边界行为以 docs/d3-geo/math.md 为最终依据。【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表