ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何用 d3-geo 的 stream API 遍历 GeoJSON 的几何片段?

如何用 d3-geo 的 stream API 遍历 GeoJSON 的几何片段? 如何用 d3-geo 的 stream API 遍历 GeoJSON 的几何片段【免费下载链接】d3Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:项目地址: https://gitcode.com/GitHub_Trending/d3/d3如果你需要逐点、逐线、逐环地读一份 GeoJSON 的几何结构——比如统计每个环包含多少个坐标点、把几何转成自定义格式、或在投影之外对几何做变换——而不是直接生成 SVG path 字符串d3-geo 提供的 stream流接口就是文档中给出的路径。d3-geo/stream.md 明确说明streams 不物化中间表示而是通过一系列函数调用把几何流过你的代码以最小化开销且这些调用目前是同步的。前提是你已经能加载 D3任意 JavaScript 环境均可按 getting-started 用import * as d3 from d3或 CDN 方式引入即可本文以 ES module 为例。先理解 stream 协议六个回调与调用顺序stream 是一个实现若干方法的小对象d3-geo 用这些方法把几何推送给它。stream.md 定义了必须实现的方法集合方法含义引自文档stream.point(x, y, z)指示一个点坐标为x、yz可选。坐标系未指定、取决于实现例如 projection streams 要求输入为度数的球面坐标。在线条或多边形环之外它表示一个 Point / MultiPoint 点几何在线条或环之内表示一个控制点stream.lineStart()指示一条线或一个环的开始在多边形内表示一个环的开始stream.lineEnd()指示一条线或一个环的结束。注意与 GeoJSON 不同环上冗余的闭合坐标不会通过point给出而是由多边形内的lineEnd隐含stream.polygonStart()指示一个多边形开始多边形的第一条线是外环后续线是内部孔洞stream.polygonEnd()指示一个多边形结束stream.sphere()指示球体以 ⟨0,0,0⟩ 为中心的單位球两个关键判断规则直接来自文档写处理逻辑时必须记住stream 是有状态的inherently statefulpoint的含义取决于它当前是否处在lineStart之内一条 line 和一个 ring 的区分则依赖是否处在polygonStart之内。你的实现需要自己维护这个状态。环的朝向约定多边形的第一条 ring 是外环通常顺时针之后的 ring 是孔洞通常逆时针见 lineStart 条目。入口函数是 geoStreamd3.geoStream(object, stream);object要遍历的 GeoJSON 对象。feature 和 geometry object 都支持作为输入stream实现了上述方法的对象。一个文档明确指出的限制stream 接口只描述几何本身因此额外的 feature properties 对流不可见——如果你需要properties里的字段要在geoStream调用外层自行保存不能指望流里能读到。用 geoTransform 得到一个可用的流记录几何片段自己手写六个方法当然可行但文档在 projection.md 中给出了一个更省事的做法d3.geoTransform(methods)。它会用你给定的methods定义一个任意 transform未定义的方法使用 pass-through 方法把输入原样传播到输出流。这意味着你只需实现关心point的记录器其余结构方法自动透传。下面这段代码把文档中记录器模式this.stream是输出流回调内通过this.stream.point(...)向下游转发坐标组合到d3.geoStream上用于逐个记录 GeoJSON 中出现的每个几何片段。它不依赖投影this.stream只是把调用原样继续传播可以直接在任意支持 ESM 的环境中运行import * as d3 from d3; // 一个记录器 transform只实现 point其余方法由 geoTransform 自动 pass-through const recordPoints d3.geoTransform({ point(x, y) { // 每收到一个几何片段坐标就记录一条 // 通过 this.stream 转发给输出流保持协议完整 console.log(point: [${x}, ${y}]); this.stream.point(x, y); } }); // 输入可以是任意 GeoJSON geometry object const square { type: Polygon, coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]] }; d3.geoStream(square, recordPoints);运行后你会按坐标出现顺序收到point回调。注意输入里虽然写了 5 个坐标首尾重复但文档 lineEnd 一节明确说明环的冗余闭合坐标不会以point的形式出现——所以你只会收到 4 个point调用而不是 5 个。如果除了点之外还要识别哪些片段属于同一条线、同一个环、同一个多边形在记录器中补上结构方法即可同样依据geoTransform的 pass-through 机制这里全部显式实现以便观察import * as d3 from d3; const events []; const inspector d3.geoTransform({ point(x, y) { events.push(point(${x}, ${y})); this.stream.point(x, y); }, lineStart() { events.push(lineStart); this.stream.lineStart(); }, lineEnd() { events.push(lineEnd); this.stream.lineEnd(); }, polygonStart() { events.push(polygonStart); this.stream.polygonStart(); }, polygonEnd() { events.push(polygonEnd); this.stream.polygonEnd(); }, sphere() { events.push(sphere); this.stream.sphere(); } }); const square { type: Polygon, coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]] }; d3.geoStream(square, inspector); console.log(events);结果验证对照文档给出的标准调用序列验证方式直接采用 stream.md 中的官方示例文档规定上面的square这个 Polygon 输入坐标[[0,0],[0,1],[1,1],[1,0],[0,0]]将产生如下一系列对 stream 的方法调用以下为文档原文给出的示例结果stream.polygonStart(); stream.lineStart(); stream.point(0, 0); stream.point(0, 1); stream.point(1, 1); stream.point(1, 0); stream.lineEnd(); stream.polygonEnd();把上节inspector打印出的events与这个序列逐项比对应完全一致顺序、次数、坐标值。比对时可以同时确认三件事外层是polygonStart/polygonEnd说明这是多边形而非独立线条环内只有 4 个point调用第 5 个闭合坐标被lineEnd隐含与文档描述一致若换成LineString或Point输入则不应出现polygonStartpoint的语义也随之变化在线/环外即为独立的点几何——这正是point 的语义取决于所处上下文这条规则的实际表现。限制与下一步按 stream.md 与 projection.md 的说法需要注意这些边界坐标系取决于 stream 实现自定义记录器拿到什么坐标完全由你接的流决定若把几何接给投影流projection.stream(stream)输入必须是度数的球面坐标且任何输入几何都会先被投影再流到输出流文档列出的典型投影过程包括转弧度、三轴旋转、小圆裁剪或换日线切割、自适应重采样、scale 与 translate。feature properties 不可见流只描述几何需要 properties 时在外层自行关联。调用是同步的文档明确这些方法调用目前是同步的不要为它设计异步处理流程。winding order 约定D3 使用自己的绕序约定小于半球的外环顺时针与 GeoJSON RFC 7946 的约定相反详见 d3-geo.md 中的 warning。如果遍历的目的最终是渲染下一步可以按 paths 用d3.geoPath(projection)直接生成 SVG path 数据或渲染到 Canvas如果要做任意几何变换则参考 geoTransform 一节中给出的 reflectY 与仿射矩阵两个 transform 示例它们演示了完整的 transform 定义与传递方式。【免费下载链接】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),仅供参考
返回列表