D3 + Google地图+多点路径

Amw 5G

我正在Google地图上绘制点(到目前为止很好),然后根据基础数据中的点顺序在每个点之间绘制一条线(不太好)。就像一条小径或路线。

与我看到的少数几个示例不同,我的数据不是采用GeoJSON格式,因此我真的想尽可能保持这种状态。我试图适应此处此处发布的例证但没有成功。

我的结果最终没有画线,并且我无法确定这是由于投影错误还是与D3语法相关的其他原因。我已经尝试通过console.log()语句进行调试,但是在GIS投影方面我却很忙。

这是绘制点的代码

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true"></script>
<script src="../js/d3.v3.min.js"></script>
<style type="text/css">

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

        .markers {
          position: absolute;
        }

        svg.pts {
          position: absolute;
        }

        .markers border {
          position: absolute;
         stroke: black;
         stroke-width: 2px;
        }

        .markers svg.pts {
          width: 60px;
          height: 20px;
          padding-right: 100px;
          font: 10px sans-serif;
        }

        .markers circle {
          fill: brown;
          stroke: black;
          stroke-width: 1.5px;
        }


        .SvgOverlay path {
            stroke: Orange;
            stroke-width: 2px;
            fill: Orange;
            fill-opacity: .3;
        }

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

var map = new google.maps.Map(d3.select("#map").node(), {
  zoom: 15,
  center: new google.maps.LatLng(29.371397, -81.54938), //N/S E/W
  mapTypeId: google.maps.MapTypeId.ROADMAP 
});

        var data =      [ //note this is not in GeoJSON format
{name:"pt1",lng:-81.55082967,lat:29.374915304},
{name:"pt2",lng:-81.55211713,lat:29.373504039},
{name:"pt3",lng:-81.5842252,lat:29.417969924},
{name:"pt4",lng:-81.55230021,lat:29.374245073},
{name:"pt5",lng:-81.55115,lat:29.37263},
{name:"pt6",lng:-81.58737814,lat:29.358476912},
{name:"pt7",lng:-81.59230268,lat:29.359308171},
{name:"pt8",lng:-81.58783883,lat:29.356449048},
{name:"pt9",lng:-81.58189168,lat:29.420264027},
{name:"pt10",lng:-81.58288,lat:29.4202},
{name:"pt11",lng:-81.56079477,lat:29.359527893},
{name:"pt12",lng:-81.55861145,lat:29.356670068},
{name:"pt13",lng:-81.57961314,lat:29.420893275},
{name:"pt14",lng:-81.579302,lat:29.419368},
{name:"pt15",lng:-81.55979967,lat:29.359768002},
{name:"pt16",lng:-81.55823261,lat:29.36122515},
{name:"pt17",lng:-81.58189168,lat:29.420264027},
{name:"pt18",lng:-81.57997524,lat:29.421120323},
{name:"pt19",lng:-81.58148399,lat:29.420030491},
{name:"pt20",lng:-81.57839075,lat:29.420766158},
{name:"pt21",lng:-81.57982489,lat:29.42002304},
{name:"pt22",lng:-81.580266,lat:29.420212},
{name:"pt23",lng:-81.5820392,lat:29.42048164},
{name:"pt24",lng:-81.57894731,lat:29.420509033},
{name:"pt25",lng:-81.57819629,lat:29.418834169}
];


        var overlay = new google.maps.OverlayView();

        overlay.onAdd = function() {
          var layer = d3.select(this.getPanes().overlayLayer).append("div")
                .attr("height", "100%")
                .attr("width", "100%")
                .attr("class", "markers")
                .attr("id", "layer");

          layer[0][0].style.width = "1366px";
          layer[0][0].parentNode.style.width = "100%";
          layer[0][0].parentNode.style.height = "100%";
          layer[0][0].parentNode.parentNode.style.width = "100%";
          layer[0][0].parentNode.parentNode.style.height = "100%";
          layer[0][0].parentNode.parentNode.parentNode.style.width = "100%";
          layer[0][0].parentNode.parentNode.parentNode.style.height = "100%";
          layer[0][0].parentNode.parentNode.parentNode.parentNode.style.width = "100%";
          layer[0][0].parentNode.parentNode.parentNode.parentNode.style.height = "100%";

          // Add points
          overlay.draw = function() {
            var projection = this.getProjection(),
                padding = 10;

            var point = layer.selectAll("svg")
                .data( data )
                .each(transform) // update existing markers
              .enter().append("svg:svg")
                .each(transform)
                .attr("class", "point pts")
        // Add marker on points
            point.append("svg:circle")
                .attr("r", 4.5)
                .attr("cx", padding )
                .attr("cy", padding );

            // Add a label on points
            point.append("svg:text")
                .attr("x", padding + 7)
                .attr("y", padding)
                .attr("dy", ".31em")
                .text( function(d) { 
                  return d.name; }
                );
            //Here is where I'd like to add lines connecting the points, in order
            //of appearance in the data object


            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) {
              //console.log(d);
              e = _projection( d.lat, d.lng )
              return d3.select(this)
                  .style("left", e[0] + "px")
                  .style("top", e[1] + "px");
            }


          };
        };

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

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

这里是一个的jsfiddle

提出的关于通过数据对象添加路径的建议是最受赞赏的。

本·鲁道夫

好的,所以我看了看您的代码并对其进行了重构。但是,这是在两点之间绘制的路径的基本工作版本:http : //jsfiddle.net/AJvt4/3/不过有一个警告,那就是地图平移时overlayPane不会展开。我不太熟悉Google地图,因此不确定在这里我能提供多少帮助。以下是所做更改的说明:

首先,我创建了一个包含svg的文件来容纳onAdd事件中的所有d3元素

var svg = layer.append('svg')
    .attr('x', 0)
    .attr('y', 0)

另外,onAdd如果我添加了d3路径生成器(您可以在此处阅读更多内容):

var lineFn = d3.svg.line()
    .x(function (d) {
    e = _projection(d.lat, d.lng);
    return e[0] + padding
})
    .y(function (d) {
    e = _projection(d.lat, d.lng);
    return e[1] + padding
})

为了画出一条线,我在add事件处理程序中添加了它

var line = svg.selectAll('.path').data([data])
    line.enter().append('path')
    line.attr('class', 'path')
        .attr('d', lineFn)

请务必注意数据([data]周围的数组这是因为d3期望一个数组数组,每个内部数组保持指向一条线。这样可以更轻松地绘制多条线。在您的情况下,只有一行。

您会注意到一些其他更改,使代码更具d3风格。希望能帮助您入门!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章