d3js v5 + Topojson v3 关于加入 csv & json 的优化
d3js v5 + Topojson v3 Optimization about joining csv & json
为了制作地图,我需要直接在代码中将一些值从csv导入json 。
为了加载 json 和 csv 文件,我对 Promise 对象使用异步操作,并使用两个循环和一个公共键在 json 文件上添加新属性。
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
if (csvId === jsonId) {
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
break;
一切正常,但在网络上显示地图需要时间。
有没有办法优化地图的加载时间?
这是我的代码示例:https://plnkr.co/edit/ccwIQzlefAbd53qnjCX9?p=preview
我使用了你的 plunkr 并向其添加了一些时间点,运行 它多次并获得了一些关于你的脚本花费时间的数据:
这是一个 block 的日志记录。
我很确定我住的地方的带宽低于平均水平,而且变化很大;文件加载时间对我来说变化很大,低至 500 毫秒,高至 1800 毫秒,其他一切都是一致的
让我们仔细看看您在问题中包含的数据操作阶段:
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
if (csvId === jsonId) {
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
break;
根据我的统计,嵌套的 for 语句运行了大约 5,151 次。 for 语句的父级运行 101。这些不应更改,因为您的数据是固定的。为什么这些周期需要这么长时间?因为你每次迭代都调用 topojson.feature():
如果我隔离这条线:
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8)
我们可以看到,这实际上只需要几毫秒。
Topojson.feature
Returns the GeoJSON Feature or FeatureCollection for the specified
object in the given topology. If the specified object is a
GeometryCollection, a FeatureCollection is returned, and each geometry
in the collection is mapped to a Feature. Otherwise, a Feature is
returned. The returned feature is a shallow copy of the source object:
they may share identifiers, bounding boxes, properties and
coordinates. (from the docs).
因此,每次我们使用 topojson.feature
时,我们实际上都是在将 topojson 转换为 geojson。我们不需要在 for 循环中这样做。让我们做一次:
var featureCollection = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8);
//Merge csv & json
//Add properties from csv to json)
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<featureCollection.features.length;j++){
var jsonId = featureCollection.features[j].properties.codgeo;
if (csvId === jsonId) {
featureCollection.features[j].properties.value1 = csvValue1;
featureCollection.features[j].properties.value0 = csvValue0;
break;
}
}
}
当然,我们必须更新渲染的代码部分以使用 featureCollection
变量,而不是 topojson
现在让我们看一下时间:
这是基于上述内容的更新 bl.ock,也有时间点。
不,我没有忘记包括一个操作时间,它对我来说平均为 1.5 毫秒。是的,我的带宽显示了可变性 - 但无论外部因素如何,花在其他操作上的时间应该明显更少
进一步增强
几何体的预投影,见此。
几何的简化,参见mapshaper.org(虽然我相信你已经这样做了)。
从 csv 或 topojson 中删除不必要的属性 - 您真的在使用 topojson 中的 population 字段吗,您是否需要 topojson 中的 libgeo 和 libgeo_m(例如:"libgeo":"Puy-de-Dôme","libgeo_m":"PUY-DE-DÔME"
) ?
为了制作地图,我需要直接在代码中将一些值从csv导入json 。 为了加载 json 和 csv 文件,我对 Promise 对象使用异步操作,并使用两个循环和一个公共键在 json 文件上添加新属性。
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
if (csvId === jsonId) {
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
break;
一切正常,但在网络上显示地图需要时间。 有没有办法优化地图的加载时间?
这是我的代码示例:https://plnkr.co/edit/ccwIQzlefAbd53qnjCX9?p=preview
我使用了你的 plunkr 并向其添加了一些时间点,运行 它多次并获得了一些关于你的脚本花费时间的数据:
这是一个 block 的日志记录。
我很确定我住的地方的带宽低于平均水平,而且变化很大;文件加载时间对我来说变化很大,低至 500 毫秒,高至 1800 毫秒,其他一切都是一致的
让我们仔细看看您在问题中包含的数据操作阶段:
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
if (csvId === jsonId) {
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
break;
根据我的统计,嵌套的 for 语句运行了大约 5,151 次。 for 语句的父级运行 101。这些不应更改,因为您的数据是固定的。为什么这些周期需要这么长时间?因为你每次迭代都调用 topojson.feature():
如果我隔离这条线:
topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8)
我们可以看到,这实际上只需要几毫秒。
Topojson.feature
Returns the GeoJSON Feature or FeatureCollection for the specified object in the given topology. If the specified object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned. The returned feature is a shallow copy of the source object: they may share identifiers, bounding boxes, properties and coordinates. (from the docs).
因此,每次我们使用 topojson.feature
时,我们实际上都是在将 topojson 转换为 geojson。我们不需要在 for 循环中这样做。让我们做一次:
var featureCollection = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8);
//Merge csv & json
//Add properties from csv to json)
for (var i=0; i< fr[1].length;i++){
var csvId = fr[1][i].codgeo;
var csvValue1 = parseFloat(fr[1][i].value1);
var csvValue0 = parseFloat(fr[1][i].value0);
for (var j=0; j<featureCollection.features.length;j++){
var jsonId = featureCollection.features[j].properties.codgeo;
if (csvId === jsonId) {
featureCollection.features[j].properties.value1 = csvValue1;
featureCollection.features[j].properties.value0 = csvValue0;
break;
}
}
}
当然,我们必须更新渲染的代码部分以使用 featureCollection
变量,而不是 topojson
现在让我们看一下时间:
这是基于上述内容的更新 bl.ock,也有时间点。
不,我没有忘记包括一个操作时间,它对我来说平均为 1.5 毫秒。是的,我的带宽显示了可变性 - 但无论外部因素如何,花在其他操作上的时间应该明显更少
进一步增强
几何体的预投影,见此
几何的简化,参见mapshaper.org(虽然我相信你已经这样做了)。
从 csv 或 topojson 中删除不必要的属性 - 您真的在使用 topojson 中的 population 字段吗,您是否需要 topojson 中的 libgeo 和 libgeo_m(例如:"libgeo":"Puy-de-Dôme","libgeo_m":"PUY-DE-DÔME"
) ?