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

时间:2017-02-23 16:33:58

标签: javascript d3.js svg geojson topojson

我尝试按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.geo.path();

如果我将路径定义更改为var path = d3.geoPath();,则几何图形会正确绘制:

var path = d3.geoPath();

这不会起作用(我不知道为什么geoPath()首先起作用)因为那时我对路径的其余调用都会失败。

当我输入这个时,我意识到我忘记了对我的投影变量的调用。我改变了.projection();到.projection(投影);现在我的地图看起来很奇怪,但路径上没有错误。如前所述:

.projection(projection);

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

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

Correctly projected, scaled, and centered, but broken features.

然后我想也许是因为我没有添加&#34;,函数(a,b){return a!== b; }&#34;到topojson.mesh函数,但这样做会让事情变得更加糟糕:

Filtering for a!==b

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

Geometry check at mapshaper.org

此时我很难过。我实现topojson渲染数据的方式出了问题,但它与我在示例中看到的代码相匹配。

1 个答案:

答案 0 :(得分:3)

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

enter image description here

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