【天地图】使用天地图api绘制GeoJson数据

已被阅读 1383 次 | 文章分类:gis随笔 | 2022-03-07 00:17

天地图没有直接提供加载GeoJson数据或者文件的api,但是我们可以借助绘制多边形的方式实现

1 实现效果

绘制如下的矢量多边形效果;

2 实现技术

(1) 首先用ajax请求geojson文件,从文件解析并获取到坐标数据

下面这个方法就是解析geojson返回的featurecollection中的坐标方式;其中可能有多段线稍微处理一下即可

                                    
/**
 * 从featureCollection获取所有linestring
 * @param {*} featureCollection 
 * @returns  返回线段数组
 */
function  getLinesFromGeojson(featureCollection){
    let lines=[];
    let geometries=featureCollection.geometries
    for(let i=0;i<geometries.length;i++){
        let geometry=geometries[i]
        let type=geometry.type;
        if(type==="LineString"){
            let line=geometry.coordinates
            lines.push(line)
        }
        if(type==="MultiLineString"){
            let subLines=geometry.coordinates
           lines=lines.concat(subLines) 
        }
    }
    return lines
}
                                    
                                

(2) 创建两个多边形,一个正常绘制;另一个背景偏移蒙版;可以表现出一定的立体效果;效果可以自己调样式

                                    
/**
 * 创建polygon
 * @param {*} points 多边形坐标 二维数组
 * @param {*} option 
 * @returns  返回polygon
 */
function createPolygon(coors,option){
    let points=[];
    coors.forEach((lonlat)=>{
        points.push(new T.LngLat(lonlat[0], lonlat[1]));
    })
    return new T.Polygon(points,{
        color: option.lineColor||"#47D4DE", 
        weight:  option.lineWidth||1, 
        opacity:  option.lineOpacity||1, 
        fillColor: option.fillColor||"black", 
        fillOpacity: option.fillOpacity||1
    });
}
                                    
                                

3 主要代码

代码是vue工程编写;可根据情况适当更改

                                    
// 初始化地图
    initMap(){
        var zoom = 8;
        var imageURL = "http://t0.tianditu.gov.cn/img_w/wmts?" +"SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +"&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的key";
        this.map = new T.Map("mapContainer", {
            layers: [this.createBaseLayer(imageURL)],
            minZoom: 5, maxZoom: 18
        });

        window.map=this.map;
        this.map.centerAndZoom(new T.LngLat(116.40969, 39.89945), zoom);
        this.map.enableScrollWheelZoom();
    },
    // 创建底图
    createBaseLayer(url){
        let layer = new T.TileLayer(url, {minZoom: 1, maxZoom: 18});
        return layer
    },
    // 异步加载Geojson数据
    async initPolygon(geojsonUrl,styleOption){
        let res= await axios.get(geojsonUrl);
        let featureCollection=res.data;
        let lines=tdtUtil.getLinesFromGeojson(featureCollection)
        lines.forEach((coors)=>{
            let polygon=tdtUtil.createPolygon(coors,styleOption);
            this.map.addOverLay(polygon);
        })   
    },
    // 初始化偏移矢量多边形
    async initOffsetPolygon(geojsonUrl,styleOption){
        let res= await axios.get(geojsonUrl);
        let featureCollection=res.data;
        let lines=tdtUtil.getLinesFromGeojson(featureCollection)
        lines.forEach((coors)=>{
            let polygon=tdtUtil.createOffsetPolygon(coors,styleOption);
            this.map.addOverLay(polygon);
        })   
    }
                                    
                                

初始调用

                                    
mounted(){
    // 初始化地图
    this.initMap();
    // 初始化区边界
    this.initPolygon("./static/district_county_bound.json",
    {
        fillOpacity:0.001
    });
    // 初始化市边界
    this.initPolygon("./static/district_city_bound.json",
    {
        lineWidth:3,
        fillOpacity:0.001
    });
    // 市背景蒙版
    this.initOffsetPolygon("./static/district_city_bound.json",
    {
        lineWidth:0.6,
        fillOpacity:0.5,
    });
  }
                                    
                                

4 api工具类

常用方法整理在一起使用直接调用,也比较方便;后续有需求会继续完善;所以单独上传;见天地图工具类封装

                                    
// 天地图api方法封装
// 工具类

/**
 * 创建polygon
 * @param {*} points 多边形坐标 二维数组
 * @param {*} option 
 * @returns  返回polygon
 */
function createPolygon(coors,option){
    let points=[];
    coors.forEach((lonlat)=>{
        points.push(new T.LngLat(lonlat[0], lonlat[1]));
    })
    return new T.Polygon(points,{
        color: option.lineColor||"#47D4DE", 
        weight:  option.lineWidth||1, 
        opacity:  option.lineOpacity||1, 
        fillColor: option.fillColor||"black", 
        fillOpacity: option.fillOpacity||1
    });
}

/**
 * 创建偏移polygon(适合做表现为立体效果的polygon)
 * @param {*} points 多边形坐标 二维数组
 * @param {*} option 
 * @returns 返回polygon
 */
 function createOffsetPolygon(coors,option){
    let points=[];
    coors.forEach((lonlat)=>{
        points.push(new T.LngLat(lonlat[0]-0.015, lonlat[1]-0.035));
    })
    return new T.Polygon(points,{
        color: option.lineColor||"#47D4DE", 
        weight:  option.lineWidth||1, 
        opacity:  option.lineOpacity||1, 
        fillColor: option.fillColor||"black", 
        fillOpacity: option.fillOpacity||1
    });
}
/**
 * 从featureCollection获取所有linestring
 * @param {*} featureCollection 
 * @returns  返回线段数组
 */
function  getLinesFromGeojson(featureCollection){
    let lines=[];
    let geometries=featureCollection.geometries
    for(let i=0;i<geometries.length;i++){
        let geometry=geometries[i]
        let type=geometry.type;
        if(type==="LineString"){
            let line=geometry.coordinates
            lines.push(line)
        }
        if(type==="MultiLineString"){
            let subLines=geometry.coordinates
           lines=lines.concat(subLines) 
        }
    }
    return lines
}
/**
 * 创建marker;默认或者自定义图片的marker
 * @param {*} coors 
 * @param {*} icon 
 * @returns 返回marker
 */
function createMarker(coors,icon){
    let marker= new T.Marker(new T.LngLat(coors[0],coors[1]));
    if(icon){
        //创建icon对象
        var icon = new T.Icon({
            iconUrl: icon.url,
            iconSize: new T.Point(icon.width, icon.height),
            iconAnchor: new T.Point(10, 25)
        });
        marker.setIcon(icon)
    }
    return marker
    
}
/**
 * 创建自定义覆盖物
 * @param {*} domId domid
 * @returns 返回覆盖物对象
 */
function createCustomOverlay(domId){
    var DefinedOverlay = T.Overlay.extend({
        initialize: function (lnglat,options) {
            this.lnglat = lnglat;
            this.setOptions(options);
        },
        onAdd: function (map) {
            this.map = map;
            this._div = document.getElementById(domId);
            map.getPanes().overlayPane.appendChild(this._div);
            this.update(this.lnglat);
        },
        onRemove: function () {
            var parent = this.div.parentNode;
            if (parent) {
                parent.removeChild(this.div);
                this.map = null;
                this.div = null;
            }
        },
        setLnglat: function (lnglat) {
            this.lnglat = lnglat;
            this.update();
        },
        getLnglat: function () {
            return this.lnglat;
        },
        setPos: function (pos) {
            this.lnglat = this.map.layerPointToLngLat(pos);
            this.update();
        },
        /**
         * 更新位置
         */
        update: function () {
            var pos = this.map.lngLatToLayerPoint(this.lnglat);
            this._div.style.top = ( pos.y -255) + "px";
            this._div.style.left = (pos.x - 135) + "px";
        }
    })
    return DefinedOverlay
}
export default{
    createPolygon:createPolygon,
    createOffsetPolygon:createOffsetPolygon,
    getLinesFromGeojson:getLinesFromGeojson,
    createMarker:createMarker,
    createCustomOverlay:createCustomOverlay
}
                                    
                                

QQ群:713985494 | 技术问题解答

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号