预先投影的几何图形 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 灵活性) 的相关文章

  • 如何处理 d3 中 Beeswarm 图中的碰撞?

    我一直在玩这个例子here https gf neocities org co2bs co2bee html一会儿 我想做的是突出显示图中的单个节点 圆圈 通过使用边框使其变大 稍后我也想在其中添加文本或字母 目前 我已经圈了Bhutan图
  • NVD3 - 配置轴上的刻度

    我有一个 nvd3 折线图 它显示时间序列 但无法在 x 轴右侧获取刻度 对于较长的时间跨度 它会按预期工作 但对于较短的时间跨度 此处 12 31 05 至 01 01 06 多个刻度显示相同的日期 请看一下JSFiddle 上此图表的代
  • d3js 折线图——如何将最后一步延伸到范围末尾?

    很简单 但我无法摆脱这个问题 线是两点 值 之间的链接 从值 A 绘制到值 B 因此 假设 A 的值为 10 B 的值为 20 而 C 缺失 现在从 0 到 10 到 20 的线已经绘制完毕 我想画从 0 到 10 到 20 到 25 的线
  • 赋予 d3 序数轴标签与尺度名称不同

    我有一个序数scale具有不同值的某些标签 我想显示该比例的轴 其中轴标签与比例标签不同 我有这个代码 var width 1000 var height 600 var margins left 100 40 right 25 botto
  • MongoDB GeoJSON“无法从对象、格式错误的几何图形中提取地理密钥?”插入类型 Polygon 时

    我收到错误 无法从对象中提取地理密钥 几何图形格式错误 多边形已闭合 格式看起来不错 因为它已正确插入到 Mongo 中 我使用的是 Mongo 版本 2 6 3 在 Centos 6 5 x64 上运行 下面的多边形有什么问题 我非常仔细
  • D3 删除千位的逗号分隔符

    我有一个包含 3 列的 json 其中一列是 年份 该列仅包含年份 没有日期 当我在 x 轴上绘制它时 年份会以逗号分隔符表示数千 所以在 json 中 日期的格式是 Year 1990 在 x 轴上 结果是 1 990 我一直在试图弄清楚
  • LeafletJs只显示一个国家

    我使用 Leafletjs 和 D3 来显示地图 我只想在地图上显示英国 Leaflet和D3是否可以只显示英国 这当然是可能的 现在的解决方案取决于您是想使用 D3 绘制英国 还是想从 Tile Server 获取它 在后一种情况下 有一
  • 如何从 mysql 数据库中提取数据并使用 D3.JS 进行可视化?

    我有一个数据库MySQL我想在其中可视化D3 JS 为了做到这一点 首先我想parse中的数据JSON格式 然后编写一个基本代码 从数据库中提取数据并使用D3 JS 我环顾四周 但找不到我想要的东西 因为我是新手D3 JS 我怎样才能做到这
  • 动画 D3 地球仪 (d3.geo.azimuthal)

    我对 d3 javascript 库有疑问 我想使用方位角 http mbostock github com d3 talk 20111018 azimuthal html地球 我想从地球上的经度和纬度坐标插入点 并使地球动画化 而无需使用
  • 创建链接到 csv 文件的表

    我正在尝试创建一个链接到的表 csv使用 d3 文件 但我得到的只是一个空白网页 即使以克里米亚为例 我也得到一张空白页 我将很高兴得到指导或展示一个可行的例子或关于我做错了什么的建议 如果您询问如何从 CSV 数据创建 HTML 表 这就
  • 使用 classed("active",true) 鼠标悬停时 D3 颜色变化

    我是 js 和 D3 的新手 我已经生成了某种热图 并且想使用 D3 的 on mouseover 更改图块的颜色 我可以显式更改颜色 但想使用 CSS 活动规则 可能是一些简单的东西可以修复 任何帮助将不胜感激 完整代码如下 Thanks
  • d3.js:在 SVG 线性渐变中过渡颜色?

    正如标题所说 使用D3 js 是否可以实现线性渐变的颜色过渡 例如 如果我有这个渐变 var gradient svg append svg defs append svg linearGradient attr id gradient a
  • MongoDB $geoIntersects 不适用于包含负顶点的多边形

    我已在数据库中存储了跨越 x 轴和 y 轴的多边形 并且我想搜索包含给定点的多边形 为此 我使用 geoIntersects 运算符来指定一个点 但是 当多边形穿过轴时 MongoDB 不会返回任何多边形 我可以对查询或架构进行任何小的更改
  • 在 D3 v4 中使用 Zoom.translateExtent 约束地图平移

    我正在尝试显示单个州的地图 并将缩放和平移限制在州的边界内 除了缩放状态路径以适应较小的容器时的平移约束之外 它大部分都在工作 我认为这归结于我不明白该使用什么参数zoom translateExtent 虽然我对此很陌生 所以它可能是别的
  • d3.js - 具有树形布局,如何更改 X 轴以使用 D3 中的时间刻度?

    我有这个树布局 需要它在 X 轴上使用时间刻度来将节点固定为日期 另外 我需要保留根节点 它有一个is rootJSON 数据中的属性 在时间范围之外 Here http codepen io anon pen kIJxo是具有树布局工作的
  • D3、TS 和 Angular 2

    我正在尝试将 D3 v4 与 Angular 2 Typescript 一起使用 我目前正在研究 D3 v4 我能够遵循 stackoverflow 中类似问题的一些答案 但没有成功 我已经导入了大部分 D3 库及其类型 我使用的是 TS
  • 显示具有多个父代的 D3 树

    我目前有this http bl ocks org mbostock 4339083图已实现 我希望在描述具有多个父节点的子节点时保持结构和可折叠性 有没有办法做到这一点 我研究了力图 但我也想保留一组层次结构 这意味着 1 级的父级可以有
  • crossfilter - 计算具有属性的所有记录的百分比

    这是我的问题 我正在使用 python Flask 服务器从 mongo db 获取 json 数据 并在其中指定要导入的字段 此数据采用 json 格式 并且仅像这样获取 一旦通过 graphs js 中的 crossfilter 是否可
  • d3.js:将样式应用于单行

    正在尝试可拖动网络 http bl ocks org mbostock 4566102并希望能够对不同的链接使用不同的颜色 当我注释掉这些行时 var link svg append g attr class link selectAll
  • d3:力向图:节点过滤

    我正在浏览以下帖子 突出显示选定的节点 https stackoverflow com questions 8739072 highlight selected node its links and its children in a d3

随机推荐

  • 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