2012-10-27 122 views
3

我使用谷歌地圖d3.js妄圖可視化無線覆蓋。的基本思想是,在地圖上的每個點表示將接入點,我會使用來自這些點的維諾圖作爲覆蓋的粗近似值等在谷歌地圖覆蓋中使用d3繪製路徑

所以基於此demo,我有以下:

<!DOCTYPE html> 
<html> 
    <head> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script> 
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.min.js"></script> 
    <link rel="stylesheet" href="http://mbostock.github.com/d3/ex/colorbrewer.css"> 
    <style type="text/css"> 

html, body, #map { 
    width: 100%; 
    height: 100%; 
    margin: 0; 
    padding: 0; 
} 

.stations { 
    position: absolute; 
} 

.stations, .stations svg { 
    position: absolute; 
} 

.stations border { 
    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; 
} 

    </style> 
    </head> 
    <body> 
    <div id="map"></div> 
    <script type="text/javascript"> 

// create map 
var map = new google.maps.Map(d3.select("#map").node(), { 
    zoom: 8, 
    center: new google.maps.LatLng(37.76487, -122.41948), 
    mapTypeId: google.maps.MapTypeId.TERRAIN 
}); 


var data = [ 
{ name: 'pt1', lng: -122.28, lat: 38.2 }, 
{ name: 'pt2', lng: -122.05, lat: 38.0 }, 
{ name: 'pt3', lng: -122.12, lat: 37.67 }, 
{ name: 'pt4', lng: -121.82, lat: 37.7 }, 
{ name: 'pt5', lng: -121.95, lat: 38.38 }, 
{ name: 'pt6', lng: -121.78, lat: 36.93 }, 
{ name: 'pt7', lng: -122.25, lat: 37.52 }, 
{ name: 'pt8', lng: -122.82, lat: 38.5 }, 
{ name: 'pt9', lng: -121.92, lat: 37.37 }, 
{ name: 'pt10', lng: -122.37, lat: 37.62 }, 
{ name: 'pt11', lng: -121.23, lat: 37.9 }, 
] 


// Load the station data. When the data comes back, create an overlay. 
var overlay = new google.maps.OverlayView(); 

// Add the container when the overlay is added to the map. 
overlay.onAdd = function() { 
    var layer = d3.select(this.getPanes().overlayLayer).append("div") 
     .attr("height", "100%") 
     .attr("width", "100%") 
     .attr("class", "stations") 

    // 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 marker = layer.selectAll("svg") 
     .data(data) 
     .each(transform) // update existing markers 
     .enter().append("svg:svg") 
     .each(transform) 
     .attr("class", "marker") 

    marker.append("svg:circle") 
     .attr("r", 4.5) 
     .attr("cx", padding) 
     .attr("cy", padding); 

    // add a label. 
    marker.append("svg:text") 
     .attr("x", padding + 7) 
     .attr("y", padding) 
     .attr("dy", ".31em") 
     .text(function(d) { 
      return d.name; } 
     ); 

    var v = d3.geom.voronoi(translate(data)); 
    // console.log(v) 

    var edges = layer.selectAll("path") 
     .data(v) 
     .enter().append("svg:svg") 
     .attr("class", "border") 
     .append("svg:path") 
     .attr("d", function(d){ 
      var e = transform_path(d) 
      var p = 'M' + e.join('L') + 'Z' 
      console.log('PATH: ' + p) 
      return p 
     }) 

    function translate(data) { 
     var d = [] 
     for(var i=0; i<data.length; i++){ 
     var c = [ data[i].lat, data[i].lng ] 
     d.push(c) 
     } 
     return d 
    } 

    function _projection(lat, lng) { 
     e = new google.maps.LatLng(lat, lng); 
     e = projection.fromLatLngToDivPixel(e); 
     return [ e.x - padding, e.y - padding] 
     // return [ e.x, e.y ] 
    } 

    function transform(d) { 
     e = _projection(d.lat, d.lng) 
     console.log("marker " + d.lat +', ' + d.lng + " -> left: " + e[0] +", top: " + e[1]) 
     return d3.select(this) 
      .style("left", e[0] + "px") 
      .style("top", e[1] + "px"); 
    } 

    function transform_path(data) { 
     var d = [] 
     console.log(data) 
     for(var i=0; i<data.length; i++) { 
     var c = _projection(data[i][0], data[i][2]) 
     console.log(' path point: ' + JSON.stringify(data[i]) + ' -> left: ' + c[0] + ", top: " + c[1]) 
     d.push(c) 
     } 
     // console.log(d) 
     return d 
    } 

    }; 
}; 

// Bind our overlay to the map… 
overlay.setMap(map); 

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

但是,我無法獲得任何顯示的路徑元素。任何人都可以幫忙嗎?我有jsfiddle上面的代碼。乾杯!

回答

3

在這裏您可以看到顯示的路徑。你的問題是不相關的D3,但糟糕的CSS樣式:寬度分別設置爲0px,樣式圓圈分別給予路徑等

http://jsfiddle.net/uF9PV/7/

我也注意到了設計缺陷:你應該點不是通過絕對定位與CSS定位,而是通過SVG定位(讓D3爲你做詭計)。我的建議是將覆蓋圖和Google地圖分開。棘手的部分將是確保他們一起移動(變焦和左右上下)

good luck 
+0

謝謝!是的,太多的圖層...我使用css進行標記定位,因爲它是在https://gist.github.com/899711的示例中提供的。我認爲它已被使用,因爲它會自動調整大小並隨谷歌覆蓋層窗格移動。例如,用你的小提琴,縮放/平移不適用於voronoi層(不正確的放大/位置),而標記保持正確。 – yee379

+0

我解決了放大和縮小的問題:我忘了添加.attr(「d」,function(){...})來更新.data()之後的現有條目。再次感謝! – yee379