代码之家  ›  专栏  ›  技术社区  ›  beetlej

d3.js-在谷歌地图上绘制站点和路径

  •  0
  • beetlej  · 技术社区  · 4 年前

    下面的代码试图在谷歌地图上绘制站点和路径,当前版本的站点在地图上正确绘制,但路径没有显示在地图上!

    var tooltip = d3.select("body")
            .append("div")
            .attr("class", "tooltip_map")
            .style('width','auto')
            .style('height','auto')
            .style('text-align','left')
            .style('visibility','hidden')
            .style('position','absolute')
            .style('padding','15px')
            .style('font','20px sans-serif')
            .style('background','white')
            .attr('pointer-events','none')
    
    // Create the Google Map…
    var map = new google.maps.Map(d3.select("#map").node(), {
      zoom: 8,
      center: new google.maps.LatLng(44.331216, 23.927536),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    
    var jsonobj = load_json()
    main(jsonobj)
    
    function main(json) {
      var overlay = new google.maps.OverlayView();
      overlay.onAdd = function() {
        var layer = d3.select(this.getPanes().overlayLayer).append("div")
          .attr("class", "stations");
           draw_marker(map,overlay,layer,json)
      };
    
      // Bind our overlay to the map…
      overlay.setMap(map);
    }
    
    function draw_marker(map,overlay,layer,json) {
        // Draw each marker as a separate SVG element.
        // We could use a single SVG, but what size would it have?
        overlay.draw = function() {
          var projection = this.getProjection(),
            padding = 10;
    
          var markerLink = layer.selectAll("link")
            .data(json.links)
            .each(pathTransform) // update existing markers
            .enter().append("line")
            .each(pathTransform)
            .attr("class", "link");
    
          var marker = layer.selectAll("svg")
            .data(json.nodes)
            .each(transform) // update existing markers
            .enter().append("svg:svg")
            .each(transform)
            .attr("class", "marker");
    
    
    
          // Add a circle.
          marker.append("svg:circle")
            .attr("r", 5)
            .attr("cx", padding)
            .attr("cy", padding)
                            .on("mouseover", function(d){
                            var desc = "hello"
                            console.log(desc)
                            tooltip.html(desc)
                            return tooltip.style("visibility", "visible");
                    })
                    .on("mousemove", function(){
                            return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
                    .on("mouseout", function(){
                            return tooltip.style("visibility", "hidden");
                    })
    
    
          // Add a label.
          marker.append("svg:text")
            .attr("x", padding + 7)
            .attr("y", padding)
            .attr("dy", ".37em")
            .text(function(d) {
              return d.id;
            });
    
          function pathTransform(d) {
    
            dsrc = new google.maps.LatLng(d.source.lat, d.source.lng);
            dtrg = new google.maps.LatLng(d.target.lat, d.target.lng);
            dsrc = projection.fromLatLngToDivPixel(dsrc);
            dtrg = projection.fromLatLngToDivPixel(dtrg);
            return d3.select(this)
              .attr("x1", dsrc.x - padding)
              .attr("y1", dsrc.y - padding)
              .attr("x2", dtrg.x - padding)
              .attr("y2", dtrg.y - padding);
    
          }
    
          function transform(d) {
    
            d = new google.maps.LatLng(d.lat, d.lng);
            d = projection.fromLatLngToDivPixel(d);
    
            return d3.select(this)
              .style("left", (d.x - padding) + "px")
              .style("top", (d.y - padding) + "px");
          }
      }
    }
    
    function load_json() {
      var jsonobj = {
        "directed": true,
        "graph": [],
        "nodes": [{
            "lat": 44.391643516091975,
            "lng": 23.159677682342053,
            "id": "1:a"
          },
          {
            "lat": 44.315988,
            "lng": 23.818359,
            "id": "a:a::"
          },
          {
            "lat": 44.29844994776969,
            "lng": 24.402314492323608,
            "id": "b:b"
          },
          {
            "lat": 44.351118152120485,
            "lng": 23.341791630955303,
            "id": "a:c"
          },
          {
            "lat": 44.889424527442685,
            "lng": 23.960970697645276,
            "id": "e:d"
          },
          {
            "lat": 43.46084400349923,
            "lng": 23.975774627524885,
            "id": "d:6104:1"
          },
          {
            "lat": 44.64680010013528,
            "lng": 23.20292820976948,
            "id": "c:6104:2"
          },
          {
            "lat": 44.40446080879215,
            "lng": 23.953536570796015,
            "id": "b:6104:3"
          },
          {
            "lat": 44.18593375168617,
            "lng": 23.769879901486856,
            "id": "af:6104:4"
          },
          {
            "lat": 44.09051846584001,
            "lng": 24.14130778735744,
            "id": "aaaa3bab:3d:7305"
          },
          {
            "lat": 44.66376251969314,
            "lng": 23.77379490100736,
            "id": "aaaa3bab:3d:5507"
          },
          {
            "lat": 44.6240449587762,
            "lng": 24.08347249542858,
            "id": "aaaa3bab:3d:6f06"
          },
          {
            "lat": 45.00138334367271,
            "lng": 24.092331272179138,
            "id": "aaaa3bab:3d:1306"
          },
          {
            "lat": 44.55033831045195,
            "lng": 24.312914121854526,
            "id": "aaaa3bab:3c:ef05"
          },
          {
            "lat": 44.74421652327631,
            "lng": 24.728457702115804,
            "id": "aaaa3bab:3c:ea03"
          },
          {
            "lat": 43.79401723931746,
            "lng": 23.77846416630604,
            "id": "aaaa3bab:3d:7200"
          },
          {
            "lat": 43.67351687345779,
            "lng": 23.00140978137842,
            "id": "aaaa3bab:3d:5d07"
          },
          {
            "lat": 43.87692500855015,
            "lng": 24.28543591328852,
            "id": "aaaa3bab:3d:550b"
          },
          {
            "lat": 44.28189405244278,
            "lng": 23.972410391551893,
            "id": "aaaa3bab:3d:2706"
          },
          {
            "lat": 43.94916218711252,
            "lng": 23.9733463072956,
            "id": "aaaa3bab:3d:2704"
          },
          {
            "lat": 44.61479884874806,
            "lng": 24.27581898293906,
            "id": "aaaa3bab:3d:2608"
          },
          {
            "lat": 44.92223011339065,
            "lng": 23.505887513934034,
            "id": "aaaa3bab:3d:6502"
          },
          {
            "lat": 44.20117807597118,
            "lng": 23.70555450810448,
            "id": "aaaa3bab:3d:2603"
          },
          {
            "lat": 43.547714841247966,
            "lng": 24.56985383484244,
            "id": "aaaa3bab:3d:2601"
          },
          {
            "lat": 43.92116991202797,
            "lng": 22.82805535024416,
            "id": "aaaa3bab:3d:5803"
          },
          {
            "lat": 44.56587414638437,
            "lng": 22.970799697228976,
            "id": "aaaa3bab:3d:7406"
          },
          {
            "lat": 44.10230727065641,
            "lng": 23.701204095342597,
            "id": "aaaa3bab:3d:7407"
          },
          {
            "lat": 45.25416535851712,
            "lng": 24.434312172789625,
            "id": "aaaa3bab:3d:7404"
          },
          {
            "lat": 44.91647619491961,
            "lng": 23.678252259828515,
            "id": "aaaa3bab:3d:7405"
          },
          {
            "lat": 45.03473433359779,
            "lng": 24.07596179597473,
            "id": "aaaa3bab:3d:7402"
          },
          {
            "lat": 45.16855171992733,
            "lng": 23.435986773864467,
            "id": "aaaa3bab:3d:7403"
          },
          {
            "lat": 44.553669079256146,
            "lng": 23.05123326220677,
            "id": "aaaa3bab:3d:7400"
          },
          {
            "lat": 43.32871087231798,
            "lng": 23.325707869122013,
            "id": "aaaa3bab:3d:5308"
          },
          {
            "lat": 43.40444516345915,
            "lng": 23.485798521785892,
            "id": "aaaa3bab:3c:f107"
          },
          {
            "lat": 43.9435337313432,
            "lng": 22.968285824722354,
            "id": "aaaa3bab:3d:7401"
          },
          {
            "lat": 44.74549949495889,
            "lng": 22.832034225254052,
            "id": "aaaa3bab:3d:7408"
          },
          {
            "lat": 44.34901730307382,
            "lng": 24.33506529636527,
            "id": "aaaa3bab:3d:7409"
          },
          {
            "lat": 43.53125851464172,
            "lng": 24.763229039168245,
            "id": "aaaa3bab:3d:6602"
          },
          {
            "lat": 44.155575603194634,
            "lng": 23.250881840942217,
            "id": "aaaa3bab:3c:e300"
          }
        ],
        "links": [{
            "source": 1,
            "target": 25
          },
          {
            "source": 1,
            "target": 26
          },
          {
            "source": 1,
            "target": 27
          },
          {
            "source": 1,
            "target": 28
          },
          {
            "source": 1,
            "target": 29
          },
          {
            "source": 1,
            "target": 30
          },
          {
            "source": 1,
            "target": 31
          },
          {
            "source": 1,
            "target": 34
          },
          {
            "source": 1,
            "target": 35
          },
          {
            "source": 1,
            "target": 36
          },
          {
            "source": 3,
            "target": 5
          },
          {
            "source": 3,
            "target": 6
          },
          {
            "source": 4,
            "target": 15
          },
          {
            "source": 4,
            "target": 9
          },
          {
            "source": 5,
            "target": 19
          },
          {
            "source": 5,
            "target": 23
          },
          {
            "source": 6,
            "target": 18
          },
          {
            "source": 6,
            "target": 20
          },
          {
            "source": 7,
            "target": 22
          },
          {
            "source": 8,
            "target": 37
          },
          {
            "source": 8,
            "target": 3
          },
          {
            "source": 10,
            "target": 11
          },
          {
            "source": 17,
            "target": 21
          }, {
            "source": 18,
            "target": 13
          }, {
            "source": 18,
            "target": 14
          }, {
            "source": 19,
            "target": 33
          }, {
            "source": 19,
            "target": 38
          }, {
            "source": 23,
            "target": 2
          }, {
            "source": 25,
            "target": 10
          }, {
            "source": 28,
            "target": 4
          }, {
            "source": 28,
            "target": 17
          }, {
            "source": 29,
            "target": 32
          }, {
            "source": 32,
            "target": 25
          }, {
            "source": 34,
            "target": 24
          }, {
            "source": 35,
            "target": 8
          }, {
            "source": 35,
            "target": 16
          }, {
            "source": 37,
            "target": 7
          }, {
            "source": 37,
            "target": 12
          }
        ],
        "multigraph": false
      }
    
      return jsonobj
    }
    html,
        body,
        #map {
          width: 100%;
          height: 100%;
          margin: 0;
          padding: 0;
        }
        
        .stations,
        .stations svg {
          position: absolute;
        }
        
        .stations link {
          position: absolute;
          stroke: black;
          stroke-width: 2px;
        }
        
        .stations svg {
          width: 60px;
          height: 20px;
          padding-right: 100px;
          font: 10px sans-serif;
        }
        
        .stations circle {
          fill: brown;
          stroke: black;
          stroke-width: 1.5px;
        }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
      <script type="text/javascript" src="http://maps.google.com/maps/api/js?key=YOUR_API_KEY""></script>
    
    <body>
      <div id="map"></div>
    </body>
    0 回复  |  直到 3 年前
        1
  •  0
  •   lucky1928    3 年前
    1. 添加一个与地图尺寸相同的svg,但由于谷歌地图(0,0)位于中心,svg(0,0。每个点都应该移动(宽/2,高/2)以匹配谷歌地图坐标。 enter image description here

    2. 每个站添加一个g元素,然后附加圆和文本。

    3. 链接字段是节点的索引,该索引没有lat和lng属性,添加以下代码将其映射到节点:

       .attr("x1", d => {
               var source = json.nodes[d.source]
               var target = json.nodes[d.target]
               d.src = coor2px(projection,source,width,height)
               d.trg = coor2px(projection,target,width,height)
               return d.src.x
       })
       .attr("y1", d => d.src.y)
       .attr("x2", d => d.trg.x)
       .attr("y2", d => d.trg.y)
      
    4. 将d3.js更改为v7,然后使用join替换每个变换。v5代码不起作用。

    var data = load_json()
    
    main(data)
    
    function main(json) {
            /*
            var m = d3.select('body').append('div')
                    .style('width','100%')
                    .style('height','100%')
                    .style("margin",0)
                    .style("padding",0)
                    */
            
            var map = new google.maps.Map(d3.select("#map").node(), {
                    zoom: 9,
                    center: new google.maps.LatLng(44.391643516091975,23.159677682342053),
                    mapTypeId: google.maps.MapTypeId.ROADMAP,//TERRAIN
                    disableDefaultUI:false,
                    navigationControl:false,
                    mapTypeControl:false,
                    scaleControl:false,
            });
            
            var overlay = new google.maps.OverlayView();
            overlay.onAdd = function() {                
                    var olayer = this.getPanes().overlayLayer
                    
                    var projection = this.getProjection()
                    var [width,height] = getMapDimension(map,projection)
                    console.log(width,height)
                    
                    var layer = d3.select(olayer).append("svg")
                            .attr("class", "stations")
                            .attr('width',width)
                            .attr('height',height)
                            .attr('transform',`translate(${-width/2},${-height/2})`)
                            //.style('border','1px solid red')
                    
                    overlay.draw = function() {                     
                            draw_marker(map,layer,projection,json,width,height)
                    }
            }
            // Bind our overlay to the map…
            overlay.setMap(map);
            //fit_screen(map,json.nodes,'lat','lng')
    }
    
    function getMapDimension(map,projection) {
            let bounds = map.getBounds();
        let ne = bounds.getNorthEast(),
            sw = bounds.getSouthWest(),
            center = bounds.getCenter();
    
            ne = coor2px(projection,{lat:ne.lat(), lng:ne.lng()},0,0)   
            sw = coor2px(projection,{lat:sw.lat(), lng:sw.lng()},0,0)
            var width = ne.x - sw.x
            var height = sw.y - ne.y
            if (height == 0) height = width
            return [width,height]
    }
    
    function fit_screen(map,data,lat,lng) {
            var lat_min = d3.min(data,d => d[lat])
            var lat_max = d3.max(data,d => d[lat])
            var lng_min = d3.min(data,d => d[lng])
            var lng_max = d3.max(data,d => d[lng])
            map.setCenter(new google.maps.LatLng(
                    ((lat_max + lat_min) / 2.0),
                    ((lng_max + lng_min) / 2.0)
            ));
    
            map.fitBounds(new google.maps.LatLngBounds(
                    new google.maps.LatLng(lat_min, lng_min),//bottom left
                    new google.maps.LatLng(lat_max, lng_max)//top right
            ));
            //map.setZoom(map.getZoom() + 1.8);
    }
    
    function draw_marker(map,layer,projection,json,width,height) {
        var markerLink = layer.selectAll(".link")
                    .data(json.links)
                    .join('line')
                    .attr("class", "link")
            .attr("x1", d => {
                            var source = json.nodes[d.source]
                            var target = json.nodes[d.target]
                            d.src = coor2px(projection,source,width,height)
                            d.trg = coor2px(projection,target,width,height)
                            return d.src.x
                    })
            .attr("y1", d => d.src.y)
            .attr("x2", d => d.trg.x)
            .attr("y2", d => d.trg.y)
                    .attr("stroke-width",2)
                    .attr("fill","none")
                    .attr("stroke","blue")
            
        var marker = layer.selectAll(".marker")
                    .data(json.nodes)
                    .join("g")
                    .attr('class','marker')
                    .attr('transform',d => {
                            var p = coor2px(projection,d,width,height)
                            return `translate(${p.x},${p.y})`
                    })
    
        marker.append("circle")
            .attr("r", 5)
                    .attr('fill','red')
    
        marker.append("text")
            .attr("x", 7)
            .attr("y", 0)
            .attr("dy", ".37em")
            .text(function(d,i) {
                            return i;
            })
                    .attr('font-size',30)
    }
    
    function coor2px(projection,d,width,height) {
            var p = new google.maps.LatLng(d.lat, d.lng);
            var p = projection.fromLatLngToDivPixel(p);
            return {x:p.x+width/2,y:p.y+height/2}
    }       
    
    function getwidth(){
       return window.innerWidth 
           || document.documentElement.clientWidth 
           || document.body.clientWidth 
           || 0;
    }
    
    function getheight(){
       return window.innerHeight 
           || document.documentElement.clientHeight 
           || document.body.clientHeight 
           || 0;
    }
    
    
    function load_json() {
      var jsonobj = {
        "directed": true,
        "graph": [],
        "nodes": [{
            "lat": 44.391643516091975,
            "lng": 23.159677682342053,
            "id": "1:a"
          },
          {
            "lat": 44.315988,
            "lng": 23.818359,
            "id": "a:a::"
          },
          {
            "lat": 44.29844994776969,
            "lng": 24.402314492323608,
            "id": "b:b"
          },
          {
            "lat": 44.351118152120485,
            "lng": 23.341791630955303,
            "id": "a:c"
          },
          {
            "lat": 44.889424527442685,
            "lng": 23.960970697645276,
            "id": "e:d"
          },
          {
            "lat": 43.46084400349923,
            "lng": 23.975774627524885,
            "id": "d:6104:1"
          },
          {
            "lat": 44.64680010013528,
            "lng": 23.20292820976948,
            "id": "c:6104:2"
          },
          {
            "lat": 44.40446080879215,
            "lng": 23.953536570796015,
            "id": "b:6104:3"
          },
          {
            "lat": 44.18593375168617,
            "lng": 23.769879901486856,
            "id": "af:6104:4"
          },
          {
            "lat": 44.09051846584001,
            "lng": 24.14130778735744,
            "id": "aaaa3bab:3d:7305"
          },
          {
            "lat": 44.66376251969314,
            "lng": 23.77379490100736,
            "id": "aaaa3bab:3d:5507"
          },
          {
            "lat": 44.6240449587762,
            "lng": 24.08347249542858,
            "id": "aaaa3bab:3d:6f06"
          },
          {
            "lat": 45.00138334367271,
            "lng": 24.092331272179138,
            "id": "aaaa3bab:3d:1306"
          },
          {
            "lat": 44.55033831045195,
            "lng": 24.312914121854526,
            "id": "aaaa3bab:3c:ef05"
          },
          {
            "lat": 44.74421652327631,
            "lng": 24.728457702115804,
            "id": "aaaa3bab:3c:ea03"
          },
          {
            "lat": 43.79401723931746,
            "lng": 23.77846416630604,
            "id": "aaaa3bab:3d:7200"
          },
          {
            "lat": 43.67351687345779,
            "lng": 23.00140978137842,
            "id": "aaaa3bab:3d:5d07"
          },
          {
            "lat": 43.87692500855015,
            "lng": 24.28543591328852,
            "id": "aaaa3bab:3d:550b"
          },
          {
            "lat": 44.28189405244278,
            "lng": 23.972410391551893,
            "id": "aaaa3bab:3d:2706"
          },
          {
            "lat": 43.94916218711252,
            "lng": 23.9733463072956,
            "id": "aaaa3bab:3d:2704"
          },
          {
            "lat": 44.61479884874806,
            "lng": 24.27581898293906,
            "id": "aaaa3bab:3d:2608"
          },
          {
            "lat": 44.92223011339065,
            "lng": 23.505887513934034,
            "id": "aaaa3bab:3d:6502"
          },
          {
            "lat": 44.20117807597118,
            "lng": 23.70555450810448,
            "id": "aaaa3bab:3d:2603"
          },
          {
            "lat": 43.547714841247966,
            "lng": 24.56985383484244,
            "id": "aaaa3bab:3d:2601"
          },
          {
            "lat": 43.92116991202797,
            "lng": 22.82805535024416,
            "id": "aaaa3bab:3d:5803"
          },
          {
            "lat": 44.56587414638437,
            "lng": 22.970799697228976,
            "id": "aaaa3bab:3d:7406"
          },
          {
            "lat": 44.10230727065641,
            "lng": 23.701204095342597,
            "id": "aaaa3bab:3d:7407"
          },
          {
            "lat": 45.25416535851712,
            "lng": 24.434312172789625,
            "id": "aaaa3bab:3d:7404"
          },
          {
            "lat": 44.91647619491961,
            "lng": 23.678252259828515,
            "id": "aaaa3bab:3d:7405"
          },
          {
            "lat": 45.03473433359779,
            "lng": 24.07596179597473,
            "id": "aaaa3bab:3d:7402"
          },
          {
            "lat": 45.16855171992733,
            "lng": 23.435986773864467,
            "id": "aaaa3bab:3d:7403"
          },
          {
            "lat": 44.553669079256146,
            "lng": 23.05123326220677,
            "id": "aaaa3bab:3d:7400"
          },
          {
            "lat": 43.32871087231798,
            "lng": 23.325707869122013,
            "id": "aaaa3bab:3d:5308"
          },
          {
            "lat": 43.40444516345915,
            "lng": 23.485798521785892,
            "id": "aaaa3bab:3c:f107"
          },
          {
            "lat": 43.9435337313432,
            "lng": 22.968285824722354,
            "id": "aaaa3bab:3d:7401"
          },
          {
            "lat": 44.74549949495889,
            "lng": 22.832034225254052,
            "id": "aaaa3bab:3d:7408"
          },
          {
            "lat": 44.34901730307382,
            "lng": 24.33506529636527,
            "id": "aaaa3bab:3d:7409"
          },
          {
            "lat": 43.53125851464172,
            "lng": 24.763229039168245,
            "id": "aaaa3bab:3d:6602"
          },
          {
            "lat": 44.155575603194634,
            "lng": 23.250881840942217,
            "id": "aaaa3bab:3c:e300"
          }
        ],
        "links": [{
            "source": 1,
            "target": 25
          },
          {
            "source": 1,
            "target": 26
          },
          {
            "source": 1,
            "target": 27
          },
          {
            "source": 1,
            "target": 28
          },
          {
            "source": 1,
            "target": 29
          },
          {
            "source": 1,
            "target": 30
          },
          {
            "source": 1,
            "target": 31
          },
          {
            "source": 1,
            "target": 34
          },
          {
            "source": 1,
            "target": 35
          },
          {
            "source": 1,
            "target": 36
          },
          {
            "source": 3,
            "target": 5
          },
          {
            "source": 3,
            "target": 6
          },
          {
            "source": 4,
            "target": 15
          },
          {
            "source": 4,
            "target": 9
          },
          {
            "source": 5,
            "target": 19
          },
          {
            "source": 5,
            "target": 23
          },
          {
            "source": 6,
            "target": 18
          },
          {
            "source": 6,
            "target": 20
          },
          {
            "source": 7,
            "target": 22
          },
          {
            "source": 8,
            "target": 37
          },
          {
            "source": 8,
            "target": 3
          },
          {
            "source": 10,
            "target": 11
          },
          {
            "source": 17,
            "target": 21
          }, {
            "source": 18,
            "target": 13
          }, {
            "source": 18,
            "target": 14
          }, {
            "source": 19,
            "target": 33
          }, {
            "source": 19,
            "target": 38
          }, {
            "source": 23,
            "target": 2
          }, {
            "source": 25,
            "target": 10
          }, {
            "source": 28,
            "target": 4
          }, {
            "source": 28,
            "target": 17
          }, {
            "source": 29,
            "target": 32
          }, {
            "source": 32,
            "target": 25
          }, {
            "source": 34,
            "target": 24
          }, {
            "source": 35,
            "target": 8
          }, {
            "source": 35,
            "target": 16
          }, {
            "source": 37,
            "target": 7
          }, {
            "source": 37,
            "target": 12
          }
        ],
        "multigraph": false
      }
    
      return jsonobj
    }
    html,
        body,
        #map {
          width: 100%;
          height: 100%;
          margin: 0;
          padding: 0;
        }
    <script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
     <script type="text/javascript" src="http://maps.google.com/maps/api/js?&libraries=geometry"></script>     
    
    <body>
    <div id="map"></div>
    </body>
    推荐文章