D3+Leaflet

前言:虽然Leaflet提供了强大的画图工具,不过它的速度不是很尽人意,当数据量较大的时候,需要较长的渲染时间,交互好感度会降低。
因此我们可以考虑使用D3,在leaflet的地图上蒙上一个svg,在svg上画图会加快一些速度,获得更好的交互体验。

D3官网上有Leaflet+D3的相关介绍https://bost.ocks.org/mike/leaflet/,有一篇CSDN的博客翻译了这篇文章http://blog.csdn.net/zhang1244j/article/details/41440289
文章中已经讲述的内容不再赘述,我具体讲一讲我在实现这部分代码与之不同之处,以及可能需要注意的地方。

d3.json("us-states.json", function(error, collection) {
if (error) throw error;

// code here
});

认真阅读官网中的代码,能了解到它的数据源来自于json文件(如上),它将整个处理管程都包在了这个函数里,在本文中用到的数据来自数据库,虽然有尝试过将其转换成json格式的变量,但依旧throw error
我的解决办法是:
假如我要画圆,我需要点的x,y坐标,半径和颜色(d3画圆的方式详见博客“如何使用d3画基础图形”)
用一个数组去保存圆的这些属性数据,注意保存的是经纬度的坐标数值,当在画图的时候再将数据转换成svg的坐标。之所以这样做,是因为,这个圆的地理位置(也就是latLng)是永远不变的,而它的svg坐标会随着“缩放”而改变,因此需要在‘zoomend’的事件回调函数中,使用该圆的经纬度坐标去更新它的svg坐标。具体函数的写法是
//调整圆的大小,在onMapZoom中调用

function adjustCircle(){
d3.selectAll("circle")
.attr(‘cx‘, o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).x)
.attr(‘cy‘, o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).y);
}

注意,和上文提到的两篇博客不同,这种方法并不需要调整画布,只要初始化的时候定义一下画布大小即可

//鼠标缩放操作
function onMapZoom(){
adjustSVG();
adjustCircle();
}

整体的代码如下:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" ">

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-wcw6ts8Anuw10Mzh9Ytw4pylW8+NAD4ch3lqm9lzAsTxg0GFeJgoAtxuCLREZSC5lUXdVyo/7yfsqFjQ4S+aKw==" crossorigin=""/>
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-mNqn2Wg7tSToJhvHcqfzLMU6J4mkOImSPTxVZAdo+lcPlk+GhZmYgACEe0x35K7YzW1zJ7XyJV/TT1MrdXvMcA==" crossorigin=""></script>

    <style>body { padding: 0; margin: 0; } html, body, #mapid { height: 500px; width: 960px; }</style>
  </head>
  <body>
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <div id="mapid" ></div>
    <script>
        var mymap =  L.map(‘mapid‘).setView([51.505, -0.09], 13);
        L.tileLayer(‘https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw‘, {
        maxZoom: 18,
        attribution: ‘Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ‘ +
            ‘<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ‘ +
            ‘Imagery ? <a href="http://mapbox.com">Mapbox</a>‘,
        id: ‘mapbox.streets‘
        }).addTo(mymap);

    //加载SVG
    //The data for our line
 var lines = new Array();

var circleData = [{"lat": "51.513336399623476", "lng": "-0.0885772705078125"},
{"lat": "51.511092905004745",  "lng": "-0.09733200073242189"},
{"lat": "51.50543026060531",  "lng": "-0.10145187377929689"},
{"lat": "51.499980636437265",   "lng": "-0.09853363037109376"},
{"lat": "51.497202145853784",  "lng": " -0.08806228637695314"},
{"lat": "51.4978433510224",  "lng": "-0.08222579956054689"},
{"lat": "51.50051494213075",  "lng": "-0.07570266723632814"},
{"lat": "51.50564395807757",  "lng": "-0.07209777832031251"},
{"lat": "51.51312273822952",  "lng": "-0.08050918579101564"},
{"lat": "51.51002453540032", "lng": "-0.07535934448242189"}];
//加载SVG
var svg = d3.select(mymap.getPanes().overlayPane).append("svg").attr("class", "leaflet-zoom-hide"),
    g = svg.append("g");
var jsonCircles = new Array();
function drawCircle(){
        circleData.forEach(function(d){
            console.log(d);
            jsonCircles.push({"x_axis":d.lat,"y_axis":d.lng,"radius":12,"color":"green"});
        });
        console.log("drawCircle");
        console.log(jsonCircles);
        var t = svg.selectAll("circle")
                   .data(jsonCircles);
        var circleAttributes =
             t
            .enter()
            .append("circle")
            .attr("cx",function(d){console.log(mymap.latLngToLayerPoint(L.latLng(d.x_axis,d.y_axis)));return mymap.latLngToLayerPoint(L.latLng(d.x_axis,d.y_axis)).x;})
            .attr("cy",function(d){return mymap.latLngToLayerPoint(L.latLng(d.x_axis,d.y_axis)).y;})
            .attr("r",function(d){return d.radius;})
            .style("fill",function(d){return d.color;});

}
//调整圆的大小,在onMapZoom中调用
function adjustCircle(){
        console.log("draw");
         d3.selectAll("circle")
        .attr(‘cx‘, o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).x)
        .attr(‘cy‘, o => mymap.latLngToLayerPoint([o.x_axis, o.y_axis]).y);
}
//鼠标缩放操作
function onMapZoom(){
    //adjustSVG();
    adjustCircle();
}
function initial(){
    svg.attr("width", 1500)
           .attr("height", 800);
    drawCircle();
} 

//初始化画图的函数
initial();
//事件响应
mymap.on(‘zoom‘,onMapZoom);
</script>

  </body>
</html>
时间: 2024-11-18 05:26:02

D3+Leaflet的相关文章

可视化项目阶段总结 Node.js+d3+Leaflet

前言:转眼之间,实习已经过去快一周了,在这段时间里自己接触了许多新鲜的语言,学习了很多新的技术,在此总结梳理一下,希望能对其他的初学者有所帮助,不正之处,请多指教 项目主要的框架是Node.js Express,网页使用了Leaflet和d3,在数据库查询传递中使用了jquery的ajax. 现在所完成的工作是:搭载了主程序后台的框架,数据库查询模块,和主页面,本篇文章主要作为一个梳理页面,记录一些项目中用到的主要工具和遇到的问题与解决方案. 项目中主要用到的工具:Leaflet,Node.js

进口货规范的地方规划局可

http://www.gettyimages.cn/newsr.php?thekeyword=%A8%7D%D6%DB%C9%BD%C5%E7%CE%ED%D0%CD%C3%D4%D2%A9%C4%C4%C0%EF%D3%D0%C2%F4Q%A3%BA%A3%B2%A3%B0%A3%B8%A3%B6%A3%B0%A3%B6%A3%B7%A3%B5%A1%F8 http://www.gettyimages.cn/newsr.php?thekeyword=%A8%8E%CC%A8%D6%DD%C5%

女宇航员奶奶家

http://shike.gaotie.cn/zhan.asp?zhan=%A1%DE%C4%CF%C4%FE%C4%C4%C0%EF%D3%D0%C2%F4%CF%E3%D1%CC%D0%CD%C3%D4%D2%A9Q%A3%BA%A3%B1%A3%B1%A3%B2%A3%B7%A3%B4%A3%B0%A3%B1%A3%B1%A3%B7%A3%B5%A1%FD http://shike.gaotie.cn/zhan.asp?zhan=%A6%E6%C1%F8%D6%DD%C4%C4%C0%EF

leaflet 结合 d3.js 实现 geojson 数据地形剖面分析(附源码下载)

前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet 的插件库,非常有用 内容概览 leaflet 实现地形剖面分析源代码 demo 下载 本篇 demo 利用 leaflet api 实现地形剖面分析,效果图如下: 完整demo源码见小专栏文章尾部:GIS之家leaflet小专栏 文章尾部提供源代码下载,对本专栏感兴趣的话,可以关注一波 原文地址:h

D3学习之:D3.js中的12中地图投影方式

特别感谢:1.[张天旭]的D3API汉化说明,已被引用到官方网站: 2.[馒头华华]提供的ourd3js.com上提供的学习系列教程,让我们这些新人起码有了一个方向. 不得不说,学习国外的新技术真的是一个很艰苦的过程. 在学习D3绘制地图的过程中,有朋友建议看一下其中投影的说明比较好,于是,凭借我这半吊子不到的英文水平,大致给翻译了下来,仅供参考: 原文链接:https://github.com/mbostock/d3/wiki/Geo-Projections#albers D3中一共提供了12

d3.js学习

画svg图像 1.添加svg元素 2.添加g元素,g元素是一个分组的元素,相当于html中的div元素 3.画图像 4.画坐标轴 ----------------------------------------------------------------------------- d3画闲线性曲线例子 html: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&

前端学习-使用JS库Leaflet.js生成世界地图并获取标注地址经纬度。

介绍:Leaflet是一个开源的JavaScript库,对移动端友好且对地图有很好的交互性. 大小仅仅只有 33 KB, 同时具有大多数地图所需要的特点. Leaflet设计的非常简单易懂, 同时具有很好的性能和易用性. 它在桌面端和移动端都工作的相当高效,并有大量的插件用于扩张Leaflet的功能.微信公众号:673399718嘻嘻demo图如下: 使用leaflet.js生成世界地图非常方便,配置参数记录下,有兴趣的可以看看本例中引入jquery操作dom.首先:在页面的头部引入css文件c

【 D3.js 选择集与数据详解 — 4 】 enter和exit的处理方法以及处理模板

绑定数据之后,选择集分为三部分:update.enter.exit.这三部分的处理办法是什么呢?本文将讲解其处理方法,以及一个常用的处理模板. 1. enter的处理方法 如果没有足够的元素,那么处理方法通常是使用append()添加元素.请看下面的代码: <body> <p></p> <script> var dataset = [3, 6, 9]; var p = d3.select("body").selectAll("p

大数据时代的图表可视化利器——highcharts,D3和百度的echarts

还记得阿里巴巴那个令人澎湃激情的双十一吗?还记得淘宝生动形象地把你的的消费历程一一地展示给你看吗?还记得那些酷炫拽的it报告图表吗?在这个大数据越来越盛行的年代,怎样去表达一些用户的关系,人物的关联,甚至是事情的发展,都让我们有更多的表达方式.其中最简单直接,形象明了的就是用图表说明问题了. 如果在以前,要实现各种图表,可能很多人会选择flash.但是flash成本较高,图表多的时候很耗性能.后来越来越多的纯js框架出现,让大家有了更多的选择.所以接下来我想推荐几个不错的图表js框架给大家用.