预先投影的几何图形 v 让浏览器执行此操作(又名效率 v 灵活性)

2024-01-31

为了提高在线地图的性能,特别是在智能手机上,我遵循 Mike Bostock 的建议,在将其上传到服务器之前尽可能多地准备地理数据(按照他的命令行制图 https://medium.com/@mbostock/command-line-cartography-part-1-897aa8f8ca2c)。例如,我通常通过投影 TopoJSON 数据d3.geoConicEqualArea(),在命令行中,而不是让查看者的浏览器在加载地图时执行这项繁重的工作。

但是,我也想使用类似的方法.scale, .fitSize, .fitExtent and .translate动态地,这意味着我无法预先“烘焙”比例或将值转换为 TopoJSON 文件。

博斯托克推荐 https://bl.ocks.org/mbostock/5663666 using d3.geoTransform()作为预测的代理,例如d3.geoConicEqualArea()如果您正在处理已经投影的数据但仍想缩放或转换它。例如,要翻转 y 轴上的投影,他建议:

var reflectY = d3.geoTransform({
      point: function(x, y) {
        this.stream.point(x, -y);
      }
    }),

    path = d3.geoPath()
        .projection(reflectY);

我的问题:如果我使用这个D3功能,我不是仍然强迫观看者的浏览器进行大量的数据处理,从而使性能变差吗?预处理数据的目的就是为了避免这种情况。或者我是否高估了涉及的处理工作d3.geoTransform()上面的函数?


如果我使用这个D3功能,我不还是在强迫观看者的浏览器吗? 做大量的数据处理,这会让性能变差吗?这 预处理数据的目的就是为了避免这种情况。或者我是 高估了 d3.geoTransform() 涉及的处理工作 上面的函数?

简短回答:您高估了转换投影数据所需的工作量。


D3 geoProjections 的球形性质

d3 geoProjection 相对独特。许多平台、工具或库采用由纬度和经度对组成的点,并将它们视为位于笛卡尔平面上。这在很大程度上简化了数学计算,但代价是:路径遵循笛卡尔路由。

D3 按其本来面目对待经纬度点:三维椭球上的点。这需要更多的计算成本,但提供了其他好处 - 例如沿着大圆路线路由路径段。

将坐标视为 3d 地球上的点时 d3 产生的额外计算成本为:

  1. 球形数学

看一下简单的地理投影before缩放、居中等:

function mercator(x, y) {
  return [x, Math.log(Math.tan(Math.PI / 4 + y / 2))];
}

这可能比您上面建议的转换需要更长的时间。

  1. Pathing

在笛卡尔平面上,两点之间的直线很容易,在球面上,这很困难。画一条从东经 179 度延伸到西经 179 度的线 - 将它们视为在笛卡尔平面上,这很容易 - 画一条穿过地球的线。在球形地球上,这条线穿过反子午线。

因此,在展平路径时,需要沿路线进行采样,点之间的大圆距离需要弯曲,因此需要额外的点。我不确定 d3 中的过程,但它肯定会发生。

笛卡尔平面上的点不需要额外的采样 - 它们已经是平坦的,点之间的线是直的。无需检测线路是否以其他方式环绕地球。

投影后操作

一旦投影,像 .fitSize 这样的东西将强制进行额外的工作,这本质上就是您对 d3.geoTransform() 提出的建议:需要根据特征进行转换和缩放预计位置和尺寸.

这在 d3v3 中非常明显(之前有fitSize()) 当自动居中要素时:计算涉及投影要素的 svg 范围。


基本准科学性能比较

使用美国人口普查局 shapefile,我创建了三个 geojson 文件:

  • 一个使用 WGS84(经/纬度)(文件大小:389 kb)
  • 一个在节点中使用 geoproject 并进行简单的 d3.geoAlbers 转换(文件大小:386 kb)
  • 一种在节点中使用 geoprojectd3.geoAlbers().fitSize([500,500],d)(文件大小 385 kb)

速度的黄金标准应该是选项 3,数据根据预期的显示范围进行缩放和居中,这里不需要转换,我将使用空投影来测试它

我继续使用以下方法将它们投影到 500x500 svg:

//  For the unprojected data
var projection = d3.geoAlbers()
 .fitSize([500,500],wgs84);

var geoPath = d3.geoPath().projection(projection)


// for the projected but unscaled and uncentered data  
var transform = d3.geoIdentity()
   .fitSize([500,500],albers);

  var projectedPath = d3.geoPath()
    .projection(transform);

// for the projected, centered, and scaled data
var nullProjection = d3.geoPath()

运行数百次,我得到的平均渲染时间(数据已预加载)为:

  • 71 毫秒:WGS84
  • 33 毫秒:预计但未缩放且未居中
  • 21 毫秒:投影、缩放和居中

我可以肯定地说,无论数据是否实际居中和缩放,预投影数据都会带来显着的性能提升。

注意我用过d3.geoIdentity()相对于d3.geoTransform()因为它允许使用fitSize(),如果需要,您可以在 y 上反映:.reflectY(true);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

预先投影的几何图形 v 让浏览器执行此操作(又名效率 v 灵活性) 的相关文章

  • 传单 GeoJSON 点*后面*多边形

    我有两个传单 geojson 层 它们都有点和多边形特征 我希望能够在地图上对它们进行排序 但是当我今天这样做时 尝试通过按特定顺序添加它们来排序它们 使用 BringToBack bringToFront 等 两个图层中的点图标都位于所有
  • 使用 D3.js SVG 进行 2D 多边形布尔运算

    我有 2 个使用 D3 js 创建的简单面积图 数据和代码如下 让我们称它们为Graph A Graph B 我想用它们根据它们的相交方式创建 3 个新路径 多边形 Path 1 Graph A Graph B Path 2 Graph B
  • 如何在 Three.js 中将 geoJSON 绘制为网格而不是线条,并填充颜色?

    我正在使用 Three js 制作一个地球仪 并将添加一些数据层 所有图层都将从 geoJSON 创建 我已将其设置为使地球仪 第一个数据文件 包含国家 地区 显示为线条 这使用三GeoJSON https github com jdomi
  • 如何使用线性模型函数的色标填充背景?

    我正在分析Alberto Cairo的 功能艺术 中的datavis示例 我推荐给你 那本书里有这样的例子 我在 R 中尝试 在左下图 散点图 中 我使用书中的数据 并计算了人口函数中的军事效果lm efect pop 以及人口 效应函数的
  • 在三角形内强制图表 d3.js

    我正在研究 d3 js 力图 我有一个问题 是否可以在具有某些坐标的三角形内制作力图 这是我的代码 var width 500 var height 500 margin var marginLeft 10 var marginTop 10
  • 如何将颜色条添加到已有的绘图图形中?

    我有以下图表 其数据 位置和颜色值 来自外部源 import plotly graph objs as go from plotly offline import init notebook mode iplot data go Scatt
  • 用渐变色绘制一个 D3 圆

    如何用渐变颜色画一个圆 比如说 从黄色到蓝色的渐变 通常 要创建黄色圆圈 我们可以使用以下代码 var cdata 50 40 var xscale 40 var xspace 50 var yscale 70 var svg d3 sel
  • 使用canvg将C3.js SVG可视化到Canvas - 折线图填充黑色矩形,“错误:元素'parsererror'尚未实现”

    我正在尝试使用 Canvg 将 SVG 转换为 Canvas 这里是jsfiddle http jsfiddle net sridev24 vcz468f9 我收到一条错误消息 错误 元素 parsererror 尚未实现 我可以理解 ca
  • 如何在 R 中的绘图区域之外画一条线或添加文本?

    感谢您的阅读 我发现我无法在绘图区域之外绘制线 点或添加文本 如果我从绘图内部 轴内 区域到 xlab 主标题区域绘制一条线 则仅显示绘图内的部分 在多重绘图 mfrow 中 线 点只会在最后一个活动绘图内绘制 plot 0 l locat
  • 选择 G 元素内的路径并更改样式

    本质上 我试图让除悬停的路径之外的所有路径都变成灰色 而选择的路径则保持其原始颜色 我已经能够将所有其他路径变成灰色 但是我在使用 select this 函数并实际访问我想要更改样式的路径时遇到了问题 看来我实际上已经成功地找到了 g 组
  • 如何将多个 topojson 文件合并为单个 topojson 文件

    我有美国州 topojson 和加拿大州 topojson 我想将它们合并到单个文件中 有人可以告诉我如何将两个文件合并为单个 topojson 文件 我在创建地图时使用墨卡托投影 我遇到了类似的问题 最终将 topojson 文件转换为
  • d3 (v4) 树布局和打字稿:类型“HierarchyNode”上不存在属性“x”

    我正在尝试在使用时使用正确的 ts 类型d3 hierarchy具有树布局的根 例如 interface MyCustomGraphType id string children MyCustomGraphType let treeData
  • d3.js V4 按钮缩放实现表现得很奇怪

    我正在尝试实现 d3 平移和缩放功能 默认的平移和缩放工作正常 但要求是我们还需要放大和缩小按钮 我还实现了缩放按钮 它也有效 奇怪的是 当我第一次移动图像并单击缩放按钮时 图像会移回到以前的位置 不仅是当我第一次用鼠标缩放并使用按钮再次开
  • 具有水平和垂直组合布局的可折叠树

    我正在尝试在 D3 中创建一个可折叠树 它结合了水平 第一级和第二级 和垂直 3 级 布局 这里有一个jsfiddle http jsfiddle net artemkolotilkin z7tb23Lo 到目前为止我所得到的 除了一件事之
  • 如何使用数据对象中的值指定 d3.js 选择器?

    我在 Web 应用程序中使用 d3 js 描述我想要做的事情的最简单方法是查看下面链接的 Fiddle 但基本设置是我有一个包含数据对象的数组 my data id B text I want this text in B id C tex
  • d3 地理投影从正交到 X 的过渡

    我正在开发一个教育地图项目 其中显示不同的地图投影 我想在选择不同投影之间实现变形过渡 我找到了一个很好的例子来实现它 并且我没有遇到太多的麻烦来重新创建它 不幸的是 我还需要裁剪投影的功能 这与目标状态完美配合 但在改变投影时则不然 当选
  • d3 同步 2 个独立的缩放行为

    我有以下 d3 d3fc 图表 https codepen io parliament718 pen BaNQPXx https codepen io parliament718 pen BaNQPXx 该图表的主要区域有缩放行为 y 轴有
  • Highcharter 已弃用函数的输出与建议的不同

    我正在用 Josh Kunst 的出色作品制作一个时间序列情节highcharterR 中的库 使用此数据 gt dput t structure c 2 2 267822980 325286564 66697091 239352431 9
  • 将画布的鼠标坐标转换为地理坐标

    我正在尝试使用 Python Tkinter 创建包含意大利所有城市的地图Canvas 我在网上找到了一张意大利地图的图片 其中突出显示了一些城市 并将其插入到我的Canvas 之后 我使用一个函数来确定 2 个突出显示的城市的画布坐标 i
  • 如何使用 d3.v4 中的 JSON 数据创建树布局 - 不使用 stratify()

    我正在尝试将一些 d3 代码从 v3 更新到版本 4 我有一个使用 JSON 数据的树形图 d3 v4 示例展示了如何使用 stratify 将表格数据 例如flare csv 转换为分层数据https bl ocks org mbosto

随机推荐

  • project.json 中的框架和导入部分:它们是什么?

    到底是什么frameworks and imports的部分project jsonASP NET Core 1 0 项目的文件以及它们的作用是什么 我一直在尝试寻找 官方 文档以更好地理解它 下面是我最近启动的一个 Yeoman 支架 A
  • 在java servlet中处理“多部分/相关”

    在 Jetty 8 下运行的 Servlet 接收以下请求 Header Content Type multipart related boundary example Data example content type text xml
  • Java中如何获取for循环的最后一个值?

    import java util Scanner public class Problem1 public static void main String args input Scanner kb new Scanner System i
  • 访问网站时如何检查自己的会话哈希?

    我有兴趣了解当我访问网站时人们在我的会话和 cookie 中存储了什么 有什么方法可以查看请求之间以及我在 Safari Chrome 或 Firefox 中的页面上时发生的情况吗 在 Firefox 中 您可以使用其他Firebug ht
  • Google Sheets 脚本:按名称引用图表

    我试图在 图表 工作表中创建一个 用户界面 这将允许他们从下拉列表中选择一个图表 然后它将显示在该下拉列表的正下方 最终会有大量图表 可能在另一个 图表数据 表上 所以我的想法是将图表从数据表移动到图表表 来回移动 不确定这是否可以做到 我
  • 有条件调用构造函数[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 假设某个类foo有两个自定义构造函数 例如foo foo bar const and foo foo baz const 根据某些条件调用其中任
  • 我可以从空 std 容器的 front() 得到什么?

    If front 返回一个引用 并且容器是空的 我会得到什么 未定义的引用 这是否意味着我需要检查empty 在每个之前front 你会得到未定义的行为 在调用 front 之前 你需要使用 empty 检查容器是否为空 检查容器是否包含某
  • 下载已上传的 Lambda 函数

    我使用 upload zip 在 AWS Python 中创建了一个 lambda 函数 我丢失了这些文件 需要进行一些更改 有什么方法可以下载该 zip 吗 Yes 导航到您的 lambda 函数设置 在右上角您将有一个名为 的按钮 Ac
  • 与模板类交朋友:编译错误

    我试图使用指向实现惯用语的指针来隐藏我正在使用 Concurrency unbounded buffer 来自 VC 2010 的事实 问题是 我正在使用模板执行此操作 但陷入了编译错误 这是代码 阻塞队列 h pragma once na
  • 如何在 php 中制作访客计数器? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我如何计算
  • 如何多次使用ConsoleCancelEventHandler

    我一直忙于编写一个充当前端的应用程序 它有一个 GUI 可以使用按钮和类似的东西来获取命令行选项 并将它们传递给命令行 exe 它使用应用程序的控制台来显示命令行应用程序的输出 这工作正常 但是当使用 Ctrl C 或尝试关闭控制台窗口时
  • 安装 Realm 后出错:必须首先使用有效主机创建 RPC 会话

    我最近使用以下方式安装了领域 npm i realm S react native link realm 重要编辑仅当从设备调试时才会出现此问题 一切仍然有效 但这一次 当我尝试启用Debug Js Remotely从开发菜单中 我收到错误
  • 在 Ruby 中构建长字符串的简洁方法

    在编写 Ruby 客户端脚本 时 我看到了三种构建更长字符串的方法 包括行结束符 所有这些对我来说 闻起来 都有点难看 有没有更干净 更好的方法 变量递增 if render quote quote Now that there is th
  • 项目生成的nuget包依赖于另一个不创建nuget包的项目

    如果我有一个构建 nuget 包的项目 P1 并且让它依赖于一个不构建 nuget 包的项目 P2 则生成的包仍将引用 P2作为 nuget 包 重现步骤 使用 2 个 C 项目 P1 和 P2 创建解决方案 使P1依赖于P2 将以下行添加
  • 使用 JMH 计算指标

    如何计算 JMH 中的 CPU 时间和内存量 例如 我有 代码 State Scope Thread BenchmarkMode Mode All public class JMHSample My int x 1 int y 2 Gene
  • Spring MVC Controller中JsonView的动态选择

    我知道可以用注释控制器方法 JsonView 在 Spring MVC 中静态定义单个视图类 不幸的是 这意味着我可能拥有的每种类型的视图都需要不同的端点 我看到其他人也问过这个问题before https stackoverflow co
  • 为什么在将 Marshmallow 与 SQLAlchemy 自动映射一起使用时出现“Decimal 类型的对象不可 JSON 序列化”?

    Using automap base from sqlalchemy ext automap映射我的桌子 不能够shema dumps result getting raise TypeError f Object of type o cl
  • 使用 HTML5 文件输入时单击按钮从多个文件上传器中删除文件

    如何添加remove这里的按钮就像简单地在文件队列中一一删除一样 我之所以不使用带有 OOB 插件的免费文件上传插件 是因为我的客户要求是出于安全目的 他们需要简单的上传 ui 而不需要任何复杂的插件 function var dropZo
  • 如何描述关系数据库的性能问题?

    我有一个查询在运行关系型数据库这不能满足用户的期望 我应该提供哪些信息以及应该避免哪些信息 以便我能够在该网站上获得有效的帮助 For 甲骨文数据库提供以下信息 描述问题的症状 描述导致问题的行为 查询的行为是否稳定或者问题是否仅发生 有时
  • 预先投影的几何图形 v 让浏览器执行此操作(又名效率 v 灵活性)

    为了提高在线地图的性能 特别是在智能手机上 我遵循 Mike Bostock 的建议 在将其上传到服务器之前尽可能多地准备地理数据 按照他的命令行制图 https medium com mbostock command line carto