openlayers在加载百度地图的基础上加要素图层

注意:

这个方法是openlayers加载百度的在线服务瓦片图层,openlayers加载百度地图坐标会有偏差,引入一个坐标转换源文件即可,这种方法可以将偏差降低最小,文件内容参照https://blog.csdn.net/du_5pet/article/details/86679606

var baidu = new ol.layer.Tile({
    source: new ol.source.XYZ({
        projection: 'baidu',
        maxZoom: 18,
        tileUrlFunction: function(tileCoord) {
            var x = tileCoord[1];
            var y = tileCoord[2];
            var z = tileCoord[0];

            // return "http://online3.map.bdimg.com/tile/?qt=vtile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=udt=20170908&scaler=1&p=1"

            return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=udt=20170908&scaler=1&p=1"


            // return "http://api0.map.bdimg.com/customimage/tile?x=" + x
            //   + "&y=" + y + "&z=" + z
            //   + "&udt=20170908&scale=2&ak=ZUONbpqGBsYGXNIYHicvbAbM"
            //   + "&styles=t%3Awater%7Ce%3Aall%7Cc%3A%23044161%2Ct%3Aland%7Ce%3Aall%7Cc%3A%23004981%2Ct%3Aboundary%7Ce%3Ag%7Cc%3A%23064f85%2Ct%3Arailway%7Ce%3Aall%7Cv%3Aoff%2Ct%3Ahighway%7Ce%3Ag%7Cc%3A%23004981%2Ct%3Ahighway%7Ce%3Ag.f%7Cc%3A%23005b96%7Cl%3A1%2Ct%3Ahighway%7Ce%3Al%7Cv%3Aoff%2Ct%3Aarterial%7Ce%3Ag%7Cc%3A%23004981%2Ct%3Aarterial%7Ce%3Ag.f%7Cc%3A%2300508b%2Ct%3Apoi%7Ce%3Aall%7Cv%3Aoff%2Ct%3Agreen%7Ce%3Aall%7Cv%3Aoff%7Cc%3A%23056197%2Ct%3Asubway%7Ce%3Aall%7Cv%3Aoff%2Ct%3Amanmade%7Ce%3Aall%7Cv%3Aoff%2Ct%3Alocal%7Ce%3Aall%7Cv%3Aoff%2Ct%3Aarterial%7Ce%3Al%7Cv%3Aoff%2Ct%3Aboundary%7Ce%3Ag.f%7Cc%3A%23029fd4%2Ct%3Abuilding%7Ce%3Aall%7Cc%3A%231a5787%2Ct%3Alabel%7Ce%3Aall%7Cv%3Aoff&t = 1505487396397";
        },
        tileGrid: new ol.tilegrid.TileGrid({
            resolutions: bmercResolutions,
            origin: [0, 0],
            extent: ol.extent.applyTransform(extent, projzh.ll2bmerc),
            tileSize: [256, 256]
        })
    })
});

//先声明一个点位图层,并设置好样式 
var add_point_layer = new ol.layer.Vector({
    source: new ol.source.Vector({
        projection: 'EPSG:4326',
        format: new ol.format.GeoJSON()
    }),
    style: new ol.style.Style({
        image: new ol.style.Icon({
            src: 'addpoint.png',
            scale: 0.6
        })
    })
});

//比例尺
var controls = new Array();
var scaleLineControl = new ol.control.ScaleLine({
    units: "metric",
    target: document.getElementById('scale-line')
});
controls.push(scaleLineControl);

var map = new ol.Map({
    target: 'map',  
    layers: [
        baidu,
        add_point_layer 
    ],
    // 设置显示地图的视图
    view: new ol.View({
        //这个百度的瓦片图层加载的是3857投影,所以map的center得转换一下坐标系,转成你要加载的图层要素的投影
        center: ol.proj.transform([108.939147,34.253041], 'EPSG:4326', 'EPSG:3857'),
        zoom: 10,              
        maxZoom: 18,
        minZoom: 5
    }),
    controls: ol.control.defaults({
    }).extend(controls)

});

//点击按钮加载出点位图层
$("#btn").click(function(){
        $.ajax({
            type: "post",
            url:url,
            dataType: "json",
            data: {
                region: city
            },
            contentType: "application/x-www-form-urlencoded;charset=utf-8",
            async: true,
            xhrFields: {
                widthCredentials: true
            },
                success: function (data) {
                console.log(data)
                if (data.length == 0) {
                    alert("没有数据")
                } else {
                    //遍历拿到的要素数据
                    for (var i = 0; i < data.features.length; i++) {
                        //经纬度,后台返回的要素都是4326坐标系的
                        var lonlat = data.features[i].geometry.coordinates;
                        var address = data.features[i].properties.point_name;
                        var data1 = JSON.stringify(data)
                        //4326的数据加载在3857的百度地图上,所以两个projection得写清楚
                        var geojson = new ol.format.GeoJSON().readFeatures(data1,{
                            dataProjection: "EPSG:4326",
                            featureProjection: "EPSG:3857"
                        });
                        add_point_layer.getSource().addFeatures(geojson);
                        //添加注记
                        var pointDiv = document.createElement("div");
                        pointDiv.innerHTML = address;
                        pointDiv.className = "add_pointLayer";//设置字体样式
                        var add_anchor = new ol.Overlay({
                            element: pointDiv,
                            positioning: 'top-center' 
                        });
                        //点位图标中心点,得把4326的坐标转为3857的才能加载出来这个overlay
                        add_anchor.setPosition(ol.proj.transform(lonlat, 'EPSG:4326', 'EPSG:3857'));
                        map.addOverlay(add_anchor);
                    }
                }
            },
            error: function (data) {
                console.log(data);
            }
    });

})

最后就加载成功了,效果大致如下

openlayers在加载百度地图的基础上加要素图层

项目中所有的geojson都是4326投影坐标系的,所以在加载的要素时候都必须加上

var data1 = JSON.stringify(data);
var geojson = new ol.format.GeoJSON().readFeatures(data1,{
    dataProjection: "EPSG:4326",
    featureProjection: "EPSG:3857"
});
add_point_layer.getSource().addFeatures(geojson);

由于项目中对的图层的操作还挺多,用openlayers的方法比较全。但是项目尾期要底图改成百度地图,只能用这个百度在线瓦片图层而不能用百度官方的地图API,否则项目中所有加载图层的方法都得改成百度的API,费时费力。