使用d3.js的多个贴图:更改比例和中心的值

使用d3.js的多个贴图:更改比例和中心的值,d3.js,geojson,map-projections,D3.js,Geojson,Map Projections,我正在构建一个(D3V4)地图可视化,它允许用户在许多数据集(json文件)和两个不同的地区之间切换(一个国家的行政单位和首都的较小行政单位)。实际上,通过按钮和jquery,在初始国家级别上从一个数据集切换到另一个数据集效果很好 问题:切换到首都的地图/数据集时,它的说服力稍差,因为投影最初是为全国设置的,因此用户必须多次缩放才能正确显示首都的地图。调用投影时,我想更改.scale和.center的值,但经过几次尝试后,我还没有找到如何执行此操作 由于我只有两个不同的区域可以显示,我的直觉是,

我正在构建一个(D3V4)地图可视化,它允许用户在许多数据集(json文件)和两个不同的地区之间切换(一个国家的行政单位和首都的较小行政单位)。实际上,通过按钮和jquery,在初始国家级别上从一个数据集切换到另一个数据集效果很好

问题:切换到首都的地图/数据集时,它的说服力稍差,因为投影最初是为全国设置的,因此用户必须多次缩放才能正确显示首都的地图。调用投影时,我想更改.scale和.center的值,但经过几次尝试后,我还没有找到如何执行此操作

由于我只有两个不同的区域可以显示,我的直觉是,当用户通过函数切换到首都地图时,首先设置比例和中心的值,然后将它们更改为其他值(我知道在这两种情况下都要使用的.scale和.center的值)。是否有可能轻松切换这些值?你对解决这个问题有什么建议吗

当用户单击按钮切换到另一个数据集时,我将json文件路径加载到函数中,我试图以相同的方式加载scale的值,但我可能做错了。似乎关于投影的代码部分不能放在函数中

谢谢你的帮助

我的代码的一小部分:

var width = 1100, height = 770;

var projection = d3.geoConicConformal()
    .scale(19000) // value I would like to which when the region changes
    .center([4.45, 50.53]) // value I would like to which when the region changes
    .translate([width/2,height/2]);

var svg = d3.select( "#mapcontainer" )
    .append( "svg" )
    .attr("width", width)
    .attr("height", height)
    .style("border", "solid 1px black");

var path = d3.geoPath()
    .projection(projection); 

var color, jsonfile, legendtext;

function load (jsonfile, legendtext, color) {
    d3.selectAll(".currentmap").remove() ;
    d3.json(jsonfile, function(error, belgique) {
        g.selectAll("path")
        .data(belgique.features)
        .enter()
        .append("path")
        .attr("d", path)
        .style("stroke", "#fff")
        .attr( "class", "currentmap")
        .style("fill", function(d) {
            var value = d.properties.DATA;
            if (value) {return color(value);}
            else {return "rgb(250,110,110)"}
            });
            })
};

//one of the following function for each map
function BGQprovinces() { 
    jsonfile = "ATLAS/NewGeoJson/bgq-data1-provinces.json";
    legendText [= …];
    color = d3.scaleOrdinal()
                .domain( […])
        .range([…]);

    load(jsonfile, legendtext, color) ; 
    };

;

实现这一点的方法很少

fitSize和fitExtent

一种是修改投影比例并相对于比例和中心进行平移。这几乎是相同的操作,但平移平移投影平面,中心平移未投影平面。为此,您需要使用projection.fitSize([width,height],geojsonObject)或projection.fitdextent([x0,y0],[x1,y1]],geojsonObject)。后者将允许边距,例如,提供的第一个坐标是将约束特征的边界框的左上角,提供的第二个坐标是右下角

d3.json(jsonfile, function(error, belgique) {
     projection.fitSize([width,height], belgique);

    // now draw as you would:
    d3.selectAll(".currentmap").remove() ;
    g.selectAll("path")
    .data(belgique.features)
    .enter()
    .append("path")
    .attr("d", path)
    ...
请注意,要显示整个国家/地区,您需要有一个显示整个国家/地区的功能或一个显示国家/地区所有部分的功能集合。不能将阵列与fitSize或fitExtent一起使用,如果有要素阵列,可以使用以下方法创建要素集合:

var featureCollection = {"type":"featureCollection","features":featureArray}
对于您的情况,我建议使用fitSize或fitExtent

质心

如果确实希望修改“中心”(center)属性而不是“平移”(translate),或者希望更改旋转(在世界许多地方,圆锥共形的结果更可能是这样,比利时应该可以),则需要中心的地理坐标。实现这一点的一种方法是从path获取特征的质心。geoCentroid:

var centroid = path.geoCentroid(geojsonObject); 
然后使用该选项设置要旋转的投影参数:

projection.rotate([ -centroid[0],-centroid[1] ])
projection.center([0,0])
或到中心:

projection.rotate([0,0])
projection.center(centroid)
或两者的组合(取决于地图投影类型)。现在您可以应用FITSIZE或FITREST,该功能已经在中间,但现在我们可以设置规模。我之所以认为这是一个潜在的答案,是因为并非所有的投影,特别是简明投影,都会通过修改比例以及平移和/或中心来获得预期的结果


当然,对于圆锥投影,您可能还需要找到一种设置平行线的方法,但如果有其他答案出现,我将把它留给其他答案。

非常感谢您的答案@Andrewerid,您解决了我的问题!我还没有尝试第二个建议,因为fitSize和fitExtent都工作得很好(fitExtent甚至更好)。