美文网首页
在网页上绘制地图

在网页上绘制地图

作者: buenos_dan | 来源:发表于2020-05-17 10:57 被阅读0次

环境
angular , d3

  1. 下载所绘地图的json文件
    一张地图中,省市的边界,城市的坐标位置,名称等信息,均以json文件格式保存。这样的GeoJson文件,可以在诸多网站中获得。一个比较推荐的,提供中国省市地图的网站是 DATAV.GeoAtlas。这里我们点击下载geojson文件,用于后面的绘制。
    http://datav.aliyun.com/tools/atlas

    DATAV.GeoAtlas网站.png
  2. 将json数据读入程序
    如何使用java或js读json文件,方法有很多,这里就不展开讨论了。需要注意的是,程序设计人员需要决策的一件事情是,应该在前端读文件还是在后端读文件。下面以我的例子展示,使用的是在后端读文件,传给前端的方式。

   //后端读取json文件
   @GetMapping("/map/province")
    public ResponseEntity<JSONObject> getProvinceMap() throws IOException {
        log.debug("load province map json");
        //这里为了方便,直接指定文件名,工程中通常根据需要从别处获得文件名。
        String mapFileName = "广东省.json"
        String docPath = System.getProperty("user.dir") + "/src/main/resources/config/map/";
        File file = new File(docPath, mapFileName);
        String content = FileUtils.readFileToString(file, "UTF-8");
        JSONObject jsonObject = JSONObject.parseObject(content);
        return ResponseEntity.ok().body(jsonObject);
    }
  1. 在前端网页上绘制地图
<!-- 在html中添加一个svg元素,此后的绘制操作均在这个svg里实现-->
 <div>
        <svg id="map" class="map-svg" #map></svg>
 </div>
//ts里,引入d3
import * as d3 from 'd3';
import { ContainerElement } from 'd3';
//引入拓扑服务,调用其getProvinceMap的GET请求,从后端拿到数据
import { TopologyService } from 'app/cpe/service/topology.service';

export class CpeProvinceMapComponent implements OnInit {
  //获DOM中svg元素
  @ViewChild('map') mapSvg: ElementRef;

 ngOnInit() {
        this.topologyService.getProvinceMap().subscribe(mapJson => {
            this.mapJson = mapJson;
            this.generateProvinceMap();
        });
    }

   generateProvinceMap() {
        const svg = d3.select('#map');

        // 1.定义投影和生成器
        const projection = d3
            .geoMercator()
            .center([113, 23])       // 地图中心位置,113是经度,23是纬度
            .scale(5000)             // 设置缩放量
            .translate([0, 0]);      // 设置平移量

        // 定义地理路径生成器,使每一个坐标都会先调用此投影,才产生路径值
        const path = d3.geoPath().projection(projection); // 设定投影

        const groups = svg.append('g');           //省市边界
        const cityPoint = svg.append('g');        //城市圆点
        const cityLabel = svg.append('g');       //城市名称标签

        // 添加城市标签
        cityLabel
            .selectAll('label')
            .data(this.mapJson.features) // 绑定数据
            .enter()
            .append('text')
            .text(function(d, i) {
                return d.properties.name;
            })
            .attr('x', function(d, i) {
                return projection(d.properties.center)[0];
            })
            .attr('y', function(d, i) {
                return projection(d.properties.center)[1] - 5;
            })
            .attr('font-size', 10);

        // 添加城市圆点
        cityPoint
            .selectAll('circle')
            .data(this.mapJson.features) // 绑定数据
            .enter()
            .append('circle')
            .attr('class', 'point')
            .attr('cx', function(d, i) {
                return projection(d.properties.center)[0];
            })
            .attr('cy', function(d, i) {
                return projection(d.properties.center)[1];
            })
            .attr('stroke', 'red')
            .attr('stroke-width', 1)
            .attr('fill', 'white')
            .attr('r', 2);

        const enableCities = this.enableCities;
        // 添加城市边界
        groups
            .selectAll('path')
            .data(this.mapJson.features)                        // 绑定数据
            .enter()
            .append('path')
            .on('mouseover', function(d, i) {                  //鼠标移入移出的变色处理
                    d3.select(this).style('fill', '#2CD8FF');
                }
            })
            .on('mouseout', function(d, i) {
                   d3.select(this).style('fill', '#1890ff');
            })
            .style('fill',  '#1890ff' )
            .style('stroke', 'black')
            .attr('d', path);
    }
}

总结,绘制地图还是比较容易的一件事,上述的代码仅为示意,不一定能正确运行,且由于展示了整个绘制过程,导致重点不是很清晰,这里指出,绘制地图的关键是下面这段代码,同时先学习svg的path,circle, text的绘制,会对读懂示意代码有很大的帮助。

        // 1.定义投影和生成器
        const projection = d3
            .geoMercator()
            .center([113, 23])       // 地图中心位置,113是经度,23是纬度
            .scale(5000)             // 设置缩放量
            .translate([0, 0]);      // 设置平移量

        // 定义地理路径生成器,使每一个坐标都会先调用此投影,才产生路径值
        const path = d3.geoPath().projection(projection); // 设定投影

        const groups = svg.append('g');           //省市边界

        // 添加城市边界
        groups
            .selectAll('path')
            .data(this.mapJson.features)            // 绑定数据
            .enter()
            .append('path')
            .style('fill',  '#1890ff' )
            .attr('d', path);
  1. 效果展示


    d3绘制广东省地图.png

结束!

相关文章

网友评论

      本文标题:在网页上绘制地图

      本文链接:https://www.haomeiwen.com/subject/fnyjohtx.html