使用Overpass API+D3制图时CSV表头含@符号的问题求解
解决Overpass API CSV输出@lat/@lon在D3中无法访问的问题
你遇到的问题是Overpass API导出的CSV表头带@符号,D3用点语法访问会触发无效字符错误,以下是三种可行解决办法:
方法1:直接修改Overpass API的输出表头(推荐)
Overpass的out:csv语法支持给列指定自定义别名,不用默认的@lat/@lon,只需在声明时加["别名"]即可。修改后的Overpass请求URL如下:
http://overpass-api.de/api/interpreter?data=[bbox:37.8885,-122.2966,37.8906,-122.2945][out:csv(::lat["lat"],::lon["lon"],::id,wheelchair)];(node[entrance];);out;>;out skel qt;
导出的CSV表头会变成lat、lon,D3里直接用点语法访问:
.attr("cx", function(d){ return projection([+d.lon, +d.lat])[0] }) .attr("cy", function(d){ return projection([+d.lon, +d.lat])[1] })
(注:D3的projection函数接受[lon, lat]格式的数组,你原代码的参数顺序写反了,这里顺便修正)
方法2:用方括号语法访问带特殊字符的属性
如果不想修改Overpass请求,D3里可以用方括号语法替代点语法,直接读取带@的属性:
.attr("cx", function(d){ return projection([+d["@lon"], +d["@lat"]])[0] }) .attr("cy", function(d){ return projection([+d["@lon"], +d["@lat"]])[1] })
这种方式无需改动数据源,直接适配特殊列名。
方法3:预处理CSV数据重命名列
在D3加载CSV时,通过row函数预处理每一行数据,把@lat/@lon重命名为lat/lon:
d3.queue() .defer(d3.json, "map.geojson") .defer(d3.csv, "你的Overpass请求URL", function(row) { return { lat: +row["@lat"], lon: +row["@lon"], id: row["@id"], wheelchair: row.wheelchair }; }) .await(ready);
之后代码里就能用d.lat、d.lon正常访问了。
另外你的代码还有两处小错误需要修正:
filter(function(d,i){ return < 10 })需改为filter(function(d,i){ return i < 10 })- 必须给
ready函数传入参数,示例如下:
function ready(error, mapData, csvData) { // 这里定义投影、处理地图数据等逻辑 svg .selectAll("myCircles") .data(csvData.sort(function(a,b) { return +b.n - +a.n }).filter(function(d,i){ return i < 10 })) .enter() .append("circle") .attr("cx", function(d){ return projection([+d.lon, +d.lat])[0] }) .attr("cy", function(d){ return projection([+d.lon, +d.lat])[1] }) .attr("r", 5) }
内容的提问来源于stack exchange,提问作者organon
相关产品推荐
相关产品推荐

