d3.geoPath() 对比 d3.geo.path()

d3.geoPath() vs d3.geo.path()

我正在尝试使用 geoproject 来关注 Mike Bostock's process to project to the bounding box of a feature in a topojson file. My topojson file is already projected to Texas State Mapping System (EPSG 3081) from the command line

d3.geoConicConformal().parallels([34 + 55 / 60, 27 + 25 / 60]).rotate([100, -31 - 10 / 60])

但是,完全复制他的代码并修改相关位以匹配我的数据集会导致此行出现错误 "Uncaught TypeError: path.bounds is not a function":

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(projection);.现在我的地图看起来很奇怪,但是 path.bounds 行没有像以前那样的错误:

尽管使用了 this StackExchange answer 中的公式,但我的投影定义似乎是错误的。

我根据 Mike Bostock's response to a comment on his Medium article 将代码从 geoProjection() 更改为 geoIdentity()。我的地图似乎已正确投影、缩放和居中,但全黑白配色方案无济于事。我为各个层添加了一些快速着色,现在看起来很破:

然后我想可能是因为我没有在 topojson.mesh 函数中添加 ", function(a,b) { return a !== b; }",但是这样做让事情变得更糟:

我在 mapshaper.org 再次检查了我的 topojson 文件,但我的几何是正确的:

此时我被难住了。我实现 topojson 以呈现数据的方式有问题,但它与我在示例中看到的代码相匹配。

这里有了突破。通过将对功能的调用从 topojson.mesh 更改为 topojson.feature,问题立即自行解决。我不知道为什么 .mesh works in this example,但它绝对不适合我。

编辑: 我已经确定了示例中使用 .mesh 的原因。它仅 select 内部边界,因此不渲染海岸线,从制图的角度来看这是个好主意。我意识到的是不要对这些路径应用填充以防止我之前遇到的绘图错误。