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

在网页上绘制地图

作者: 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