Javascript 使用(d3 v4)以d3路径作为层的google地图

Javascript 使用(d3 v4)以d3路径作为层的google地图,javascript,d3.js,Javascript,D3.js,我有下面的代码,它获取一个谷歌地图,然后在上面附加一个图层,但是在投影中有一个问题,它给了我一个错误,并且没有单独在谷歌地图上显示图层,任何帮助都将不胜感激。 请注意,我使用的是d3的版本4。 有什么建议吗 <script> var map = new google.maps.Map(d3.select("#map").node(), { zoom: 7, center: new google.maps.LatLng(31.5852,36.2384),

我有下面的代码,它获取一个谷歌地图,然后在上面附加一个图层,但是在投影中有一个问题,它给了我一个错误,并且没有单独在谷歌地图上显示图层,任何帮助都将不胜感激。 请注意,我使用的是d3的版本4。 有什么建议吗

<script>
    var map = new google.maps.Map(d3.select("#map").node(), {
      zoom: 7,
      center: new google.maps.LatLng(31.5852,36.2384),
      mapTypeId: google.maps.MapTypeId.ROADMAP });

 d3.json("Export.json", function(error, jordanLevel2) {
      if (error) throw error
      var overlay = new google.maps.OverlayView();

      overlay.onAdd = function() {

        var layer = d3.select(this.getPanes().overlayLayer).append("div");

        overlay.draw = function() {

          layer.select('svg').remove();

          var w = 900;
          var h = 900;


          var overlayProjection = this.getProjection();

          // Turn the overlay projection into a d3 projection
          var googleMapProjection = function(coordinates) {
            var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]);
            var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates);
            return [pixelCoordinates.x, pixelCoordinates.y];
          }

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


          var svg = layer.append("svg")
            .attr('width', w)
            .attr('height', h)

          var g = svg.append('g')
            .attr("id", "mapGroup");


          g.selectAll("path")
            .data(jordanLevel2.features)
            .enter()
            .append("path")
            .attr("d", path)
            .attr('class', 'state selected')

            .style('opacity', .7);

        }
      }
      overlay.setMap(map);

    });

var map=new google.maps.map(d3.select(“#map”).node(){
缩放:7,
中心:新google.maps.LatLng(31.5852,36.2384),
mapTypeId:google.maps.mapTypeId.ROADMAP});
d3.json(“Export.json”,函数(错误,jordanLevel2){
如果(错误)抛出错误
var overlay=new google.maps.OverlayView();
overlay.onAdd=函数(){
var layer=d3.select(this.getPanes().overlayer).append(“div”);
overlay.draw=函数(){
layer.select('svg').remove();
var w=900;
var h=900;
var overlyprojection=this.getProjection();
//将叠加投影转换为d3投影
var googleMapProjection=函数(坐标){
var googleCoordinates=new google.maps.LatLng(坐标[1],坐标[0]);
var pixelCoordinates=重叠投影。fromLatLngToDivPixel(谷歌坐标);
返回[pixelCoordinates.x,pixelCoordinates.y];
}
var path=d3.geoPath().projection(googleMapProjection);
var svg=layer.append(“svg”)
.attr('宽度',w)
.attr('高度',h)
var g=svg.append('g')
.attr(“id”、“地图组”);
g、 选择全部(“路径”)
.数据(jordanLevel2.特征)
.输入()
.append(“路径”)
.attr(“d”,路径)
.attr('class','state selected')
.style('opacity',.7);
}
}
覆盖.setMap(map);
});

解决方案

如果上述代码与D3 v3配合使用,则需要将
googleMapProjection
函数替换为以下
D3.geoTransform
函数:

transform = d3.geoTransform({point: function(x, y) {
                  d = new google.maps.LatLng(y, x);
                  d = overlayProjection.fromLatLngToDivPixel(d);
                  this.stream.point(d.x, d.y);
                }
              });
然后,将
路径
变量替换为:

var path = d3.geoPath().projection(transform);
解释

我认为您已经了解了v4中所做的更改,Mike Bostock在回答一个有点相关的问题时解释了这些更改。具体来说,因为这是一个平面变换(因为我们正在将纬度/经度坐标转换为像素),所以我们需要使用
d3.geoTransform()

在v3和v4中,我们都使用了一个函数,其中输入应该是覆盖形状轮廓的lat/long坐标*,您试图在google地图上绘制覆盖形状。然后,该函数像以前一样使用
fromLatLngToDivPixel
方法将这些值转换为svg覆盖内的像素位置,然后使用
projection.stream
方法将这些值传递回路径对象,然后在绘制覆盖时调用路径对象

据我所知,v3和v4之间的区别如下:

  • 您不能使用回退投影,因此必须使用该方法
  • googleMapProjection
    函数的替代品,
    transform
    单独获取x和y坐标,而不是在单个数组中同时获取

  • *或相对坐标,例如使用topojson解决方案

    如果上述代码与D3 v3配合使用,则需要将
    googleMapProjection
    函数替换为以下
    D3.geoTransform
    函数:

    transform = d3.geoTransform({point: function(x, y) {
                      d = new google.maps.LatLng(y, x);
                      d = overlayProjection.fromLatLngToDivPixel(d);
                      this.stream.point(d.x, d.y);
                    }
                  });
    
    然后,将
    路径
    变量替换为:

    var path = d3.geoPath().projection(transform);
    
    解释

    我认为您已经了解了v4中所做的更改,Mike Bostock在回答一个有点相关的问题时解释了这些更改。具体来说,因为这是一个平面变换(因为我们正在将纬度/经度坐标转换为像素),所以我们需要使用
    d3.geoTransform()

    在v3和v4中,我们都使用了一个函数,其中输入应该是覆盖形状轮廓的lat/long坐标*,您试图在google地图上绘制覆盖形状。然后,该函数像以前一样使用
    fromLatLngToDivPixel
    方法将这些值转换为svg覆盖内的像素位置,然后使用
    projection.stream
    方法将这些值传递回路径对象,然后在绘制覆盖时调用路径对象

    据我所知,v3和v4之间的区别如下:

  • 您不能使用回退投影,因此必须使用该方法
  • googleMapProjection
    函数的替代品,
    transform
    单独获取x和y坐标,而不是在单个数组中同时获取
  • *或相对坐标,例如与地形相关的坐标