D3.js 使用geojson绘制地图

D3.js 使用geojson绘制地图

  • 前言
    • 初始化项目
    • 获取数据并绘图
      • http请求数据
      • 定义坐标并绘图
    • 总结

前言

利用geojson文件或者类似包含对象属性和坐标(只要坐标是在统一参考系下)的文件利用SVG绘图无非是以下思路:
1、准备源数据和DOM
2、根据源数据和节点尺寸计算比例尺
3、根据比例尺重新将源坐标数据格式化到DOM对应位置
4、利用SVG绘制点(Point)、线(Poluline)、面(Polygon)等元素
工具的使用熟悉即可。这里谈一下比例尺的计算,简单思路,获取原始坐标的范围(Extent),Extent包含Xmin,Ymin,Xmax,Ymax四个坐标,再将之于DOM的范围即[[0,0],[0,height],[width,height],[width,0]]做等比换算。
而上述内容,当我们认识到D3后便知道不再需要考虑这么多细节,甚至比例尺只需要d3.scale.linear()就基本足以解决了。
话不多说,开撸。

初始化项目

先确保你已经正确安装配置了nodejs,然后随便找到你准备新建项目的文件夹,开打命令行执行以下命令:

npm init -y
npm install d3@3.5.17 --save
npm install d3-geo --save
npm install lite-server -g

安装完毕后在该文件夹下新建index.html和app.js,并添加相应的引用:

 

<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
        <title>d3 with geoJsontitle>
    head>
    <body>
        <script src="node_modules/d3//d3.min.js"> script>
        <script src="node_modules/d3-geo/dist/d3-geo.min.js">script>
        <script src="node_modules/d3-array/dist/d3-array.min.js">script>
        <script src="app.js">script>
        <style>
        .main {
        height: 800px;
        width: 100%;
        }
        style>
        
        <div id="tips" style="bottom:100px;left: 0;position:absolute;height: 100px;width:100px">
            
        div>
        
        <svg id='map' class="main">
            
        svg>
        <hr>
        
        <div id='log'>
        div>
    body>
html>

app.js就先空着,一会再说。
新建文件夹assets,在assets下再新建文件夹geoJson,然后去下载需要的geojson文件放在这里。你的项目结构现在看来至少是这样的:
D3.js 使用geojson绘制地图_第1张图片
项目准备就先这样,继续往下。

获取数据并绘图

http请求数据

这里直接用原生Http方式请求数据:

const Http = new XMLHttpRequest();
var url = './assets/geoJson/china.json';
//获取Geojson文件,避免回调嵌套换行太多,这里直接返回一个promise
function getGeoData() {
    return new Promise(function (resolve, reject) {
        Http.open("get", url);
        Http.send();
        Http.onreadystatechange = function () {
            if (Http.readyState == 4 && Http.status == 200) {
                resolve(JSON.parse(Http.responseText))
            }
        }
    })
}

关于Http和Promise的知识可以直接点击它们跳转,此处不再赘述。

定义坐标并绘图

定义一个绘图方法,接收传入的参数并将所有元素在目标DOM节点上绘制。

var containerWidth = 0;
var containerHeight = 0;
function draw(nodes) {
    //墨卡托坐标系
    let projection = d3.geoMercator()
    //坐标映射
    projection.fitExtent([
        [0, 0],
        [containerWidth, containerHeight]
    ], nodes);
    let path = d3.geoPath(projection);
    //绘图
    let polygonNode = svg.selectAll("path")
        .data(nodes.features)
        .enter()
        .append("path")
        .attr("d", path)
        }

回到packge.json所在文件夹,输入

lite-serve

浏览器自动打开后,这个时候你应该看到下图所示的东西:
D3.js 使用geojson绘制地图_第2张图片
这个看起来确实是难看了点,我们再直接用链式语法给元素定义各类属性和样式:

//链式语法定义属性和样式
  var polygonNode = svg.selectAll("path")
        .data(nodes.features)
        .enter()
        .append("path")
        .attr("d", path)
        .attr("fill", "grey")
        .attr('opacity', 0.5)
        .attr('stroke', 'yellow')
        .attr('stroke-width', function (d) {
            return 1
        })

当然,除了上面这些,你还可以给各元素添加事件。
完整代码和其他内容请移步我的GITHUB。

总结

简单说一下上述内容用到的东西。
1、npm新建项目
2、http请求数据(JSON)
3、d3选择器
4、d3.geo
5、其他
以上内容不过前端冰山一角,甚至对于d3.js而言也不过万中其一,且行且学。
千里之行,始于足下。

你可能感兴趣的:(JAVASCRIPT)