Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用d3.js和geojson显示地图_D3.js - Fatal编程技术网

使用d3.js和geojson显示地图

使用d3.js和geojson显示地图,d3.js,D3.js,我正在玩D3的地理模块。我对D3有一些经验,但这是我第一次尝试地理模块。我在albers projection中获取了最初显示US map()edit(现在可以在中下载的zip中找到文件)的以下代码(来自),并修改为获取印度的Geojson(indiastates1.json如下)。该代码可以很好地处理US文件,但不显示任何与India json文件相关的内容。 我是不是遗漏了什么。感谢您的帮助。不过我把投影改成了墨卡托 <!DOCTYPE html> <html lang="

我正在玩D3的地理模块。我对D3有一些经验,但这是我第一次尝试地理模块。我在albers projection中获取了最初显示US map()edit(现在可以在中下载的zip中找到文件)的以下代码(来自),并修改为获取印度的Geojson(indiastates1.json如下)。该代码可以很好地处理US文件,但不显示任何与India json文件相关的内容。 我是不是遗漏了什么。感谢您的帮助。不过我把投影改成了墨卡托

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3: Setting path fills</title>
        <script type="text/javascript" src="../d3/d3.v3.js"></script>
        <style type="text/css">
            /* No style rules here yet */       
        </style>
    </head>
    <body>
        <script type="text/javascript">

            //Width and height
            var w = 500;
            var h = 300;

            //Define map projection
            var projection = d3.geo.mercator()
                                   .translate([w/2, h/2])
                                   .scale([500]);

            //Define path generator
            var path = d3.geo.path()
                             .projection(projection);

            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Load in GeoJSON data
            d3.json("indiastates1.json", function(json) {

                //Bind data and create one path per GeoJSON feature
                svg.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill", "steelblue");

            });

        </script>
    </body>
</html>
你(或浏览器)只是找错了地方。我认为d3会自动以美国为中心进行这些地理预测。您需要做的就是使用transform将“India”移动到svg视口。具体地说,您需要将视口的原点转换到以x,y像素为单位的坐标指定的位置,或者至少我是这么认为的。我试着去看印度

.attr("transform", "translate(-800,200)")
它似乎完成了任务

如果您检查元素,就很容易找到这些东西,然后您可以使用路径为您提供一些转换位置的提示

更新


解决这个问题的更好方法是计算中心和比例,如本文所述。尤其是简和迈克的回答都非常好。最后的第二篇文章中也有对代码的解释。

之所以会出现这个问题,是因为美国地图的位置使我们居中。 您可能已经加载了India文件,但它可能不在屏幕上,或者非常小。 可以通过更改“比例”、“中心”和“平移”的值手动执行校正。 但更好的方法是自动从代码中找到比例和转换

var b = path.bounds(#data#),
                s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
                 //scaled the bounding box 
                t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
// new projection
              projection = d3.geo.mercator()
                             .scale(s).translate(t);
              path = path.projection(projection);

这是一个简单的示例,演示了如何围绕要素集合中的所有要素(不仅仅是一个要素或默认要素)将地图投影居中,它基于,这很好,但基于仅缩放一个要素,并且还显示可以使用整个要素集合

对代码的主要更改包括:

  • 将初始平移和缩放替换为中性平移和缩放:

       var projection = d3.geo.mercator()
           .scale(1)
           .translate([0, 0]);
    
  • 加载json后,添加代码以基于整个要素集合的边界框动态更新投影:

       var b = path.bounds( json ),
       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];
    
       projection
            .scale(s)
            .translate(t);
    
因此,更新后的完整示例如下所示:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3: Setting path fills</title>
        <script type="text/javascript" src="../d3/d3.v3.js"></script>
        <style type="text/css">
            /* No style rules here yet */       
        </style>
    </head>
    <body>
        <script type="text/javascript">

            //Width and height
            var w = 500;
            var h = 300;

            //Define map projection
            var projection = d3.geo.mercator()
                                   .translate([0, 0])
                                   .scale(1);

            //Define path generator
            var path = d3.geo.path()
                             .projection(projection);

            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Load in GeoJSON data
            d3.json("indiastates1.json", function(json) {

                // Calculate bounding box transforms for entire collection
                var b = path.bounds( json ),
                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    
                projection
                  .scale(s)
                  .translate(t);


                //Bind data and create one path per GeoJSON feature
                svg.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill", "steelblue");

            });

        </script>
    </body>
</html>

D3:设置路径填充
/*这里还没有样式规则*/
//宽度和高度
var w=500;
var h=300;
//定义地图投影
var projection=d3.geo.mercator()
.translate([0,0])
.比额表(1);
//定义路径生成器
var path=d3.geo.path()
.投影(投影);
//创建SVG元素
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,w)
.attr(“高度”,h);
//加载GeoJSON数据
d3.json(“indiastates1.json”,函数(json){
//计算整个集合的边界框变换
var b=path.bounds(json),
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];
//更新投影
投影
.比例尺
.翻译(t);
//绑定数据并为每个GeoJSON功能创建一个路径
svg.selectAll(“路径”)
.data(json.features)
.输入()
.append(“路径”)
.attr(“d”,路径)
.样式(“填充”、“钢蓝”);
});

非常感谢。知道了。我也在类似的行上怀疑,就像在chrome上一样,因为console并没有抛出任何错误,当我在元素上点击svg时,它似乎在浏览器的某个地方高亮显示,但不知道在哪里!因此,问题在于找到合适的变换来重新定位它。在为转换找到正确的数字时,您是否进行了反复试验?路径(即d=后的位,即M150.158 128.215、486.1589Z)告诉您它的显示位置。这个虚构的例子中的数字表示路径开始是150,在你的例子中,我认为第一个数字大约是900,所以我只是将视口移动了800,然后向下移动了一点,因为检查器将其显示在屏幕顶部。要获得更完整的答案,请尝试在Firefox中显示无错误的空白屏幕是否正常?应将
“indiastates1.json”
文件放在何处?否,这表明它要么找不到您的输入,并且没有运行任何东西,要么输入被损坏,Javascript正在生成SVG,但SVG无法呈现。使用开发工具查看SVG输出,并查看网络选项卡中的文件是否加载
indiastate1.json
应该替换为指向实际文件所在位置的路径,但也要检查,因为它可能在我写这篇文章的5年内发生了更改(不记得这是在D3切换到使用
fetch
和promises之前还是之后)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3: Setting path fills</title>
        <script type="text/javascript" src="../d3/d3.v3.js"></script>
        <style type="text/css">
            /* No style rules here yet */       
        </style>
    </head>
    <body>
        <script type="text/javascript">

            //Width and height
            var w = 500;
            var h = 300;

            //Define map projection
            var projection = d3.geo.mercator()
                                   .translate([0, 0])
                                   .scale(1);

            //Define path generator
            var path = d3.geo.path()
                             .projection(projection);

            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Load in GeoJSON data
            d3.json("indiastates1.json", function(json) {

                // Calculate bounding box transforms for entire collection
                var b = path.bounds( json ),
                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    
                projection
                  .scale(s)
                  .translate(t);


                //Bind data and create one path per GeoJSON feature
                svg.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill", "steelblue");

            });

        </script>
    </body>
</html>