我尝试按Mike Bostock's process投影到topojson文件中某个要素的边界框。我的topojson文件已使用geoproject投影到德克萨斯州绘图系统(EPSG 3081)from the command line:
d3.geoConicConformal().parallels([34 + 55 / 60, 27 + 25 / 60]).rotate([100, -31 - 10 / 60])
然而,准确地复制他的代码并修改相关位以匹配我的数据集会导致错误" Uncaught TypeError:path.bounds不是函数"在这一行:
var b = path.bounds(state),
这是我的完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JS Mapping Project</title>
<script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v1.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<style type="text/css">
body {
background-color: #eee;
}
svg {
background-color: #fff;
border: 1px solid #000;
}
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 1000;
var h = 850;
var projection = d3.geoProjection( function(x, y) {
return [x, y];
});
// Create a path generator.
var path = d3.geo.path()
.projection();
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in GeoJSON data
d3.json("data/topojson/boundary_quantize.json", function(error, json) {
//Add error handling
if (error) throw error;
var states = topojson.feature(json, json.objects.state),
state = states.features.filter(function(d) { return d.properties.NAME === "Texas"; })[0];
projection
.scale(1)
.translate([0, 0]);
// Compute the bounds of a feature of interest, then derive scale & translate.
var b = path.bounds(state),
s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];
// Update the projection to use computed scale & translate.
projection
.scale(s)
.translate(t);
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "2")
.attr("d", path(topojson.mesh(json, json.objects.national)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "1")
.attr("d", path(topojson.mesh(json, json.objects.state)));
svg.append("path")
.attr("stroke"," #000")
.attr("stroke-width", "0.5")
.attr("d", path(topojson.mesh(json, json.objects.county)));
});
</script>
</body>
</html>
我发现操作代码的一些事情:
如果我通过改变var path = d3.geo.path()来删除投影.projection();到var path = d3.geo.path();,错误就消失了(因为对破解代码的调用消失了)但svg绘图被破坏了:
如果我将路径定义更改为var path = d3.geoPath();,则几何图形会正确绘制:
这不会起作用(我不知道为什么geoPath()首先起作用)因为那时我对路径的其余调用都会失败。
当我输入这个时,我意识到我忘记了对我的投影变量的调用。我改变了.projection();到.projection(投影);现在我的地图看起来很奇怪,但路径上没有错误。如前所述:
尽管使用this StackExchange answer中的公式,但我的投影定义似乎是错误的。
我根据Mike Bostock's response to a comment on his Medium article将代码从geoProjection()更改为geoIdentity()。我的地图似乎是正确投影,缩放和居中,但全黑色和白色配色方案并没有帮助。我为各个层添加了一些快速着色,现在看起来非常破碎:
然后我想也许是因为我没有添加&#34;,函数(a,b){return a!== b; }&#34;到topojson.mesh函数,但这样做会让事情变得更加糟糕:
我在mapshaper.org上再次检查了我的topojson文件,但我的几何图形是正确的:
此时我很难过。我实现topojson渲染数据的方式出了问题,但它与我在示例中看到的代码相匹配。
答案 0 :(得分:3)
这里有一个突破。通过将对topojson.mesh的功能调用更改为topojson.feature,问题立即自行解决。我不知道为什么.mesh works in this example,但它绝对不适合我。
编辑:我已经确定了为什么在示例中使用了.mesh。它只选择内部边界,因此不会渲染海岸线,从制图的角度来看这是个好主意。我意识到的是不对这些路径应用填充以防止我之前出现的绘图错误。