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