openlayers地圖使用—跟隨地圖比例尺動態標繪大小的一種方式
預期:隨著地圖比例尺放大縮小,地圖上的標繪隨著變化尺寸
思路:通過VectorImage和動態修改Feature尺寸實現Feature跟隨地圖比例尺尺寸變化
優點:結合第1和第2種方式的優點,效果較好,且有過渡效果,數量越多,過渡效果越好(標繪的尺寸突變越不明顯)地圖響應迅速,地圖操作不卡頓,圖片縮放過渡自然
頁面
<script src="https://cdn.bootcdn.net/ajax/libs/openlayers/8.1.0/dist/ol.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/openlayers/8.1.0/ol.min.css" rel="stylesheet"><style>.olMap {width: 100%;height: 500px;}</style>
</head><div id="map" class="olMap"></div>
js代碼
var map = null; // 地圖var vectorSource = null;//圖源var feas = [];// features集合// 初始化地圖function initMap() {// 矢量圖層vectorSource = new ol.source.Vector();// 創建矢量圖層 繪制標注const vLayer = new ol.layer.Vector({source: vectorSource})// 創建一個新的 VectorImageLayer 實例 const vectorLayerx = new ol.layer.VectorImage({source: vectorSource,zIndex: 99,style: function (feature) {// 定義樣式函數,根據需要自定義樣式 const style = new Style({image: new ol.style.Icon({src: '../assets/bg02.jpg', // 替換為你自己的圖標URL size: [160, 160] // 圖標大小 })});return style;}});// 高德地圖var gaodeMapLayer = new ol.layer.Tile({title: "高德地圖",source: new ol.source.XYZ({url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',wrapX: false})});//地圖容器map = new ol.Map({target: 'map',layers: [gaodeMapLayer,vectorLayerx],view: new ol.View({center: ol.proj.transform([103.23, 35.33], 'EPSG:4326', 'EPSG:3857'), //地圖初始中心點zoom: 12,minZoom: 1,maxZoom: 29}),})}initMap()/*** @description: 繪制一些圖片* 特點:修改了圖層類型,相比較與普通圖層 更絲滑* @param {*} num* @return {*}* @author: ldl*/function drawSome(num) {vectorSource.clear()feas = []// 添加若干圖片for (let i = 0; i < num; i++) {// 創建一個活動圖標需要的Feature,并設置隨機位置const r1 = Math.random();const r2 = Math.random();let rand1 = r1 / 100 + i / 1000 + i / 1000;let rand2 = r2 / 100 + i / 1000 + i / 1000;rand1 = r1 > 0.45 ? rand1 : -rand1;rand2 = r2 > 0.45 ? rand2 : -rand2;const feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.transform([103.23 + rand1, 35.33 + rand2], 'EPSG:4326', 'EPSG:3857'))})feature.setId(9999 + i);// 設置Feature的樣式,使用小旗幟圖標feature.setStyle(new ol.style.Style({image: new ol.style.Icon({src: "./bg02.jpg",anchor: [0.5, 1],scale: getScaleImgae(3000)})}))feas.push(feature)vectorSource.addFeature(feature)}}// 修改標繪的尺寸function reDrawFeatures() {// 添加若干圖片for (let i = 0; i < feas.length; i++) {const feature = feas[i]// 設置縮放等級feature.getStyle().getImage().setScale(getScaleImgae(3000))}}// 計算不同比例尺下 實際距離在屏幕上的寬度pxfunction getLengthPixel(length) {return length / map.getView().getResolution()}// 計算不同比例尺下,圖片在屏幕上應該縮放的大小function getScaleImgae(length) {// 圖片源文件的實際寬度pxconst info = { width: 800 }const scale = getLengthPixel(length) / info.widthreturn scale}drawSome(20000)setInterval(() => {reDrawFeatures()}, 300)
如上,繪制20000個標繪,標繪的縮放效果依然流暢。
總結三種實現跟隨地圖比例尺動態標繪大小的方式(見實現方式1和實現方式2):
1.第2種方式,非常適合標繪數量小于10000個的情形,使用ImageStatic實現,過渡自然;
2. 第3種方式,適合比較多的標繪,過渡效果較第2種方式差一丟丟,但是不會卡頓地圖操作;
3. 第1種方式是直接修改Feature的樣式,過渡效果相對其他方式最差。