中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

openlayers操作分享(xiang):如何從容(rong)的在vue中食(shi)用(yong)openlayers6

這篇文章,分享下我對openlayers的一些經驗和理解,會夾雜大量搜索出來得文檔,是我正式使用時可以實現的,廢話不多說,我們從下載開始

一,openlayers安裝且初始化地圖

創建vue項目就省略了,OpenLayers通過NPM 安裝

npm install ol -S

Vue頁面

  OpenLayers 加載地圖可以加載離線地圖,也可以下載離線瓦片地圖加載,

地圖相關配置,我放在data中,以便后面動態改變。(底圖我用的是天地圖,如果想測試,可以用第二段的默認地圖地圖)

1. 效果圖

在這里插入圖片描述
通過 addLayer 添加圖層,通過removeLayer 刪除圖層

2. html(創建 checkbox 用來切換圖層)

<template>
    <div id="content">
        <div id="map" ref="map"></div>
        <div id="mouse-position">
            <el-checkbox-group v-model="checkList">
                <el-checkbox label="天地圖影像圖" @change="changImage"></el-checkbox>
                <el-checkbox label="天地圖影像標注" @change="changText"></el-checkbox>
            </el-checkbox-group>
        </div>
    </div>
</template>

3. js (通過map.addLayer 實現)

<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import XYZ from "ol/source/XYZ";
import { fromLonLat } from "ol/proj";

export default {
    name: "tree",
    data() {
        return {
            map: null,
            checkList: []
        };
    },
    methods: {
        // 初始化一個 openlayers 地圖
        initMap() {
            let target = "map";
            let tileLayer = [
                new TileLayer({
                    source: new XYZ({
                        url:
                            "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
                    })
                })
            ];
            let view = new View({
                center: fromLonLat([104.912777, 34.730746]),
                zoom: 4.5
            });
            this.map = new Map({
                target: target, 
                layers: tileLayer,
                view: view 
            });
        },
        // 天地圖影像圖層
        changImage: function(checked, e) {
            if (checked) {
                this.TiandiMap_img = new TileLayer({
                    name: "天地圖影像圖層",
                    source: new XYZ({
                        url:
                            "//t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d", //parent.TiandituKey()為天地圖密鑰
                        wrapX: false
                    })
                });
                // 添加到地圖上
                this.map.addLayer(this.TiandiMap_img);
            } else {
                this.map.removeLayer(this.TiandiMap_img);
            }
        },
        // 天地圖影像注記圖層
        changText: function(checked, e) {
            if (checked) {
                this.TiandiMap_cia = new TileLayer({
                    name: "天地圖影像注記圖層",
                    source: new XYZ({
                        url:
                            "//t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d", //parent.TiandituKey()為天地圖密鑰
                        wrapX: false
                    })
                });
                // 添加到地圖上
                this.map.addLayer(this.TiandiMap_cia);
            } else {
                this.map.removeLayer(this.TiandiMap_cia);
            }
        }
    },
    mounted() {
        this.initMap();
    }
};

4. css 樣式

<style lang="scss" scoped>
html,
body {
    height: 100%;
    #content {
        width: 100%;
        position: relative;
        #mouse-position {
            float: left;
            position: absolute;
            top: 75px;
            right: 10px;
            width: 200px;
            height: 50px;
            padding: 10px;
            background-color: rgba(0, 0, 0, 0.6);
            /*在地圖容器中的層,要設置z-index的值讓其顯示在地圖上層*/
            z-index: 2000;
            color: white;
            .el-checkbox {
                color: white;
            }
            /* 鼠標位置信息自定義樣式設置 */
            .custom-mouse-position {
                color: rgb(0, 0, 0);
                font-size: 16px;
                font-family: "微軟雅黑";
            }
        }
    }
}
</style>

二,openlayers 添加圖片到地圖上

原文檔鏈接

首先初始化圖片圖層:

initImageLayer: function (extent) {
        this.imageLayer = new ol.layer.Image({
            // source: this.imageSource
        })
        this.map.addLayer(this.imageLayer);
    },

然后添加圖片:

addImage: function (extent, url) {
        var imageExtent = extent;//左下角右上角[113, 30.2, 115, 32.2]
        this.imageSource = new ol.source.ImageStatic({
            url: url,
            projection: 'EPSG:3857',
            imageExtent: ol.proj.transformExtent(imageExtent, 'EPSG:4326', 'EPSG:3857')
        })
        this.imageLayer.setSource(this.imageSource);
    }

三,openlayers 添加Polygon區域分類

地圖遮罩通常用來突出顯示某一塊特定區域,先來看下效果。(中間帶白邊的為遮罩層)

地圖遮罩

原理:在原地圖上增加一個矢量圖層,在圖層中添加一個面要素,并對面要素使用半透明的樣式。

var map,baseLayer;

//定義圖層樣式
var mystyle = new ol.style.fill({
    fill: new ol.style.Fill({
        color:"rgba(72,61,139, 0.2)",//重點在這里,采用rgba顏色,最后一個值用來表示透明度
    }),
    stroke: new ol.style.Stroke({
        color:"#BDBDBD",
        width:2
    }) 
})
var vectorSource = new ol.source.Vector();
var vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    style: mystyle
})

/**
 * 初始化地圖
 */
function initMap(){
    baseLayer = new ol.layer.Tile({
        source: new ol.source.TileWMS({
            url: "//localhost:8080/geoserver/china/wms",
            params:{
                'LAYERS': "china:baseMap;",
                'TILED': false
            },           
        })
    });
    
    var view = new ol.View({
        center: [116.727085860608, 35.20619600133295],
        zoom:10.5,
        projection: "EPSG:4326"
    });

    map = new ol.Map({
        target: "map",
        view: view,
        layers:[baseLayer,vectorLayer]
    });
}

/**
 * 根據名稱加載遮罩層
 * @param {*} name1 
 */
function addCoverLayer(name1){
	//清除原來的要素
    vectorSource.clear();

    $.getJSON('/region.geojson',function(data){
        var features = (new ol.format.GeoJSON()).readFeatures(data);        
        features.forEach(function(element) {
            //從數據中取出name字段值為name1的區域,進行加載
            if(element.get("name") === name1){
                vectorSource.addFeature(element);
            }
        });
    })
}

四,openlayers 添加Polygon區域動態遮罩,外部全黑,規定區域常亮

在深色背景的底圖上,對要突出的區域采用半透明遮罩,以此來突出該區域。暫且稱之為中心遮罩,遮罩前后對比如下圖:遮罩前

遮罩后

但是有時底圖顏色偏白,這時候不再適合對要突出的區域采用遮罩,而是要對突出區域之外進行遮罩處理。暫且稱為四周遮罩如下圖:

遮罩前遮罩后

代碼實現

(function(){
    
    var map, converLayer;
    function initMap() {
        var baselayer = new ol.layer.Tile({
            source: new ol.source.XYZ({
                url: '//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}'
            })
        });
    
        map = new ol.Map({
            target: 'map',
            layers: [baselayer],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [112, 36],
                zoom: 6
            })
        });

        var mystyle = new ol.style.Style({
            fill: new ol.style.Fill({
                color:"rgba(72,61,139, 0.4)",
            }),
            stroke: new ol.style.Stroke({
                color:"#BDBDBD",
                width:2
            })
        });
        converLayer = new ol.layer.Vector({
            source: new ol.source.Vector(),
            style: mystyle
        });
        map.addLayer(converLayer);
    }

    //todo
    //添加遮罩
    function addconver(data) {
        $.getJSON(data, function(data) {
            var fts = new ol.format.GeoJSON().readFeatures(data);
            var ft = fts[0];
            var converGeom = erase(ft.getGeometry());

            var convertFt = new ol.Feature({
                geometry: converGeom
            })
            converLayer.getSource().addFeature(convertFt);
        })
    }

    // 擦除操作,生成遮罩范圍
    function erase(geom) {
	  var extent = [-180,-90,180,90];
	  var polygonRing = ol.geom.Polygon.fromExtent(extent);
	  if (!geom instanceof ol.geom.Polygon) {
	    console.log('geom的類型必須是Polygon')
	    return
	  } 
	  var coords = geom.getCoordinates();
	  coords.forEach(coord =>{ 
	      var linearRing = new ol.geom.LinearRing(coord[0]);
	      polygonRing.appendLinearRing(linearRing);
	  })
	  return polygonRing;
	}
    

    initMap();
    var dataURL = '/static/data/shanxi.geojson'
    addconver(dataURL);
})();

五,openlayers Polygon數據格式分享

GeoJSON對象
GeoJSON總是由一個單獨的對象組成。這個對象表示幾何、特征或者特征集合。

GeoJSON對象可能有任何數目成員(名/值對)。

GeoJSON對象必須由一個名字為”type”的成員。這個成員的值是由GeoJSON對象的類型所確定的字符串。 type成員的值必須是下面之一: * “Point”, “MultiPoint”, “LineString”, “MultiLineString”, “Polygon”, “MultiPolygon”, “GeometryCollection”, “Feature”, 或者 “FeatureCollection”。這兒type成員值必須如這兒所示。

GeoJSON對象可能有一個可選的”crs”成員,它的值必須是一個坐標參考系統的對象。

GeoJSON對象可能有一個”bbox”成員,它的值必須是邊界框數組。

六,openlayers 加載wind風場

風場數據文件

安裝ol-wind

npm install ol-wind  

頁面中引入

import { WindLayer } from 'ol-wind'

方法代碼如下:

  // 添加風場
  addWindLayer () {
    const windLayer:any = new WindLayer(windData, {
      forceRender: false,
      windOptions: {
        colorScale: ['rgb(36,104, 180)', 'rgb(60,157, 194)', 'rgb(128,205,193 )', 'rgb(151,218,168 )', 'rgb(198,231,181)', 'rgb(238,247,217)', 'rgb(255,238,159)', 'rgb(252,217,125)', 'rgb(255,182,100)', 'rgb(252,150,75)', 'rgb(250,112,52)', 'rgb(245,64,32)', 'rgb(237,45,28)', 'rgb(220,24,32)', 'rgb(180,0,35)'],
        velocityScale: 1 / 8000,
        paths: 1000
      },
      zIndex: 5, // 圖層渲染的Z索引,默認按加載順序疊加
      opacity: 0.75
      // projection: 'EPSG:4326'
    })
    this.windLayer = windLayer
    this.map.addLayer(windLayer)
  }

七,openlayers 添加聚合標點

聚合標注,是指在不同地圖分辨率下,通過聚合方式展現標注點的一種方法。

其設計目的是為了減少當前視圖下加載標注點的數量,提升客戶端渲染速度。因為如果在地圖上添加很多標注點,當地圖縮放到小級別(即大分辨率)時會出現標注重疊的現象,既不美觀,渲染效率也會受到影響。此時,可以根據地圖縮放級數(zoom)的大小,將當前視圖的標注點進行聚合顯示。

OpenLayers也考慮到加載大數據量標注點的情況,提供了相應的聚合標注功能,以提升顯示速度,增強用戶體驗。OpenLayers封裝了支持聚合的矢量要素數據源(ol.source.Cluster),通過此數據源實現矢量要素的聚合功能。

前面兩篇文章 我們講了矢量圖層 VectorLayer的常用的場景,聚合標注這篇我們繼續寫一篇 VectorLayer矢量圖層 的使用,足見矢量圖層在openlayers中的應用是很廣泛的也是最常用的。可以看下圖所示的放大縮小地圖聚合分散的實現效果。

聚合:標注中的數字相加, 分散:標注中的數字相減

在這里插入圖片描述

1. ol.source.Cluster 參數

使用聚合效果就其實就是使用了這個方法,下面是他的兩個主要的參數說明

 let clusterSource = ol.source.Cluster({
    distance: parseInt(20, 10), // 標注元素之間的間距,單位是像素。
    source: source,//數據源
});

2. Cluster類實現聚合分散詳解

2.1 我們先看下mounted方法 :初始化一些數據
準備聚合的城市經緯度數據clusterData,和城市聚合值的數據points ,然后調用下實現聚合的方法
this.addCluster()

mounted() {
    let clusterData = {
        成都市: { center: { lng: 104.061902, lat: 30.609503 } },
        廣安市: { center: { lng: 106.619126, lat: 30.474142 } },
        綿陽市: { center: { lng: 104.673612, lat: 31.492565 } },
        雅安市: { center: { lng: 103.031653, lat: 30.018895 } },
        自貢市: { center: { lng: 104.797794, lat: 29.368322 } },
        宜賓市: { center: { lng: 104.610964, lat: 28.781347 } },
        內江市: { center: { lng: 105.064555, lat: 29.581632 } }
    };
    let points = [
        { name: "成都市", value: 85 },
        { name: "綿陽市", value: 36 },
        { name: "廣安市", value: 50 },
        { name: "雅安市", value: 555 },
        { name: "自貢市", value: 55 },
        { name: "宜賓市", value: 666 },
        { name: "內江市", value: 777 }
    ];
    // 實現聚合分散方法
    this.addCluster(clusterData, points, true);
}

2.2 addCluster() 方法詳解

聚合標注的矢量圖層的數據源 source 不在單單是 new VectorSource() 而是需要在包裹一層,那就是在 new Cluster 聚合方法中的 source 添加矢量圖層的數據 new VectorSource()

繼續我們創建一個矢量圖層 VectorLayer 里面有兩個參數需要設置,一個是 source數據源, 一個是 style 樣式,先看設置source 是clusterSource。也就是,需要配置兩個參數第一個標注元素之間的間距;第二個是數據源,這里是數據源就說我們實例的矢量圖層的數據源new VectorSource(),這里暫時設置為空,后面動態添加即可。

let source = new VectorSource();
let clusterSource = new Cluster({
    distance: parseInt(20, 10),
    source: source
});
let layer = new VectorLayer({
    source: clusterSource,
    style: this.clusterStyle.call(this)
});

把標注的圖層添加到地圖中去
我們根據初始化的數據去遍歷匹配。clusterData 中的城市名和points城市名一致的時候。創建點要素new Feature 信息,可以通過 feature.set(key,value) 的形式動態設置值在要素信息中。
把要素信息添加到矢量圖層 source 中。

2.3 addCluster() 方法完整代碼

// 設置聚合分散效果
addCluster(clusterData, points, clearup) {
    let source = new VectorSource();
    let clusterSource = new Cluster({
        distance: parseInt(20, 10),
        source: source
    });
    let layer = new VectorLayer({
        source: clusterSource,
        style: this.clusterStyle.call(this)
    });
    this.map.addLayer(layer);
    for (const key in clusterData) {
        points.forEach(e => {
            if (e.name == key) {
                let point = fromLonLat([
                    clusterData[key].center.lng,
                    clusterData[key].center.lat
                ]);
                var f = new Feature({
                    geometry: new Point(point)
                });
                f.set("name", e.name);
                f.set("value", e.value);
                source.addFeature(f);
            }
        });
    }
},

2.4 clusterStyle () 矢量圖層樣式方法詳解

total :通過不斷監聽獲取前面 set 的值,進行累加計算。設置到Text中。
回到這個案例中,下面我們可以看下,滾動下地圖,可以看到,會監聽要素的feature的變化。相當于vue的watch一樣效果,這也是動態樣式的應用場景之一。通過不斷監聽去 觸發new Cluster() 方法里面的distances 的屬性,進行不斷監聽,判斷 distances 的分辨率(像素)如果匹配設置的值, 達到放到縮小實現聚合分散的效果的同時,不斷重新計算total值,并設置到text中。

clusterStyle() {
	return (feature, solution) => {
	    console.log(feature);
	    // .... 省略
	})
}

在這里插入圖片描述

2.5 clusterStyle () 方法完整代碼

// 設置聚合分散的圖標樣式
clusterStyle() {
    return (feature, solution) => {
        var total = 0;
        feature.get("features").forEach((value, index) => {
        	// 通過value.get("屬性名") 獲取設置的值
            total += value.get("value"); // 獲取累加的數值
        });
        var style = new Style({
            image: new CircleStyle({
                radius: 15, //設置圓角大小
                stroke: new Stroke({
                    color: "blue" //設置園stroke顏色
                }),
                fill: new Fill({
                    color: "rgba(24,144,255,100)" //設置填充顏色
                })
            }),
            text: new Text({
                text: total.toString(), // 文字顯示的數值
                fill: new Fill({
                    color: "#FFF" // 文字顯示的顏色
                })
            })
        });
        return style;
    };
},

3. 完整代碼

<template>
    <div id="app">
        <div id="Map" ref="map"></div>
    </div>
</template>
<script>
import "ol/ol.css";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ";
import { Map, View, Feature, ol } from "ol";
import {
    Style,
    Stroke,
    Fill,
    Icon,
    Text,
    Circle as CircleStyle
} from "ol/style";
import { Polygon, Point } from "ol/geom";
import { defaults as defaultControls } from "ol/control";
import { Cluster } from "ol/source";
import { fromLonLat } from "ol/proj";

import areaGeo from "@/geoJson/sichuan.json";
export default {
    data() {
        return {
            map: null,
            areaLayer: null
        };
    },
    methods: {
        /**
         * 初始化地圖
         */
        initMap() {
            this.map = new Map({
                target: "Map",
                controls: defaultControls({
                    zoom: true
                }).extend([]),
                layers: [
                    new TileLayer({
                        source: new XYZ({
                            url:
                                "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
                        })
                    })
                ],
                view: new View({
                    center: fromLonLat([104.065735, 30.659462]),
                    zoom: 6.5,
                    maxZoom: 19,
                    minZoom: 3
                })
            });
        },
        /**
         * 設置區域
         */
        addArea(geo = []) {
            if (geo.length == 0) return false;
            let areaFeature = null;
            // 設置圖層
            this.areaLayer = new VectorLayer({
                source: new VectorSource({
                    features: []
                })
            });
            // 添加圖層
            this.map.addLayer(this.areaLayer);
            geo.forEach(g => {
                let lineData = g.features[0];
                if (lineData.geometry.type == "MultiPolygon") {
                    areaFeature = new Feature({
                        geometry: new MultiPolygon(
                            lineData.geometry.coordinates
                        ).transform("EPSG:4326", "EPSG:3857")
                    });
                } else if (lineData.geometry.type == "Polygon") {
                    areaFeature = new Feature({
                        geometry: new Polygon(
                            lineData.geometry.coordinates
                        ).transform("EPSG:4326", "EPSG:3857")
                    });
                }
            });
            areaFeature.setStyle(
                new Style({
                    fill: new Fill({ color: "#4e98f444" }),
                    stroke: new Stroke({
                        width: 3,
                        color: [71, 137, 227, 1]
                    })
                })
            );
            this.areaLayer.getSource().addFeatures([areaFeature]);
        },
        addCluster(clusterData, points, clearup) {
            let source = new VectorSource();
            let clusterSource = new Cluster({
                distance: parseInt(20, 10),
                source: source
            });
            let layer = new VectorLayer({
                source: clusterSource,
                style: this.clusterStyle.call(this)
            });
            this.map.addLayer(layer);
            for (const key in clusterData) {
                points.forEach(e => {
                    if (e.name == key) {
                        let point = fromLonLat([
                            clusterData[key].center.lng,
                            clusterData[key].center.lat
                        ]);
                        var f = new Feature({
                            geometry: new Point(point)
                        });
                        f.set("name", e.name);
                        f.set("value", e.value);
                        source.addFeature(f);
                    }
                });
            }
        },
        clusterStyle() {
            return (feature, solution) => {
                var total = 0;
                feature.get("features").forEach((value, index) => {
                    total += value.get("value");
                });
                var style = new Style({
                    image: new CircleStyle({
                        radius: 15,
                        stroke: new Stroke({
                            color: "blue"
                        }),
                        fill: new Fill({
                            color: "rgba(24,144,255,100)"
                        })
                    }),
                    text: new Text({
                        text: total.toString(),
                        fill: new Fill({
                            color: "#FFF"
                        }),
                        font: "12px Calibri,sans-serif",
                        stroke: new Stroke({
                            color: "red",
                            width: 5
                        })
                    })
                });
                return style;
            };
        }
    },
    mounted() {
        this.initMap();
        let clusterData = {
            成都市: { center: { lng: 104.061902, lat: 30.609503 } },
            廣安市: { center: { lng: 106.619126, lat: 30.474142 } },
            綿陽市: { center: { lng: 104.673612, lat: 31.492565 } },
            雅安市: { center: { lng: 103.031653, lat: 30.018895 } },
            自貢市: { center: { lng: 104.797794, lat: 29.368322 } },
            宜賓市: { center: { lng: 104.610964, lat: 28.781347 } },
            內江市: { center: { lng: 105.064555, lat: 29.581632 } }
        };
        let points = [
            { name: "成都市", value: 85 },
            { name: "綿陽市", value: 36 },
            { name: "廣安市", value: 50 },
            { name: "雅安市", value: 555 },
            { name: "自貢市", value: 55 },
            { name: "宜賓市", value: 666 },
            { name: "內江市", value: 777 }
        ];
        this.addCluster(clusterData, points, true);
    }
};
</script>
<style lang="scss" scoped>
// 此處非核心,已經刪除
</style>

八,openlayers 聚合標點點擊事件

這個事件的研究不多做解說原理,直接上我的實戰代碼

mapClick (e:any) {
    const feature = this.map.forEachFeatureAtPixel(e.pixel,
      (feature: any) => {
        if (feature.data) {
          this.featureClick(feature.data)
        } else {
          if (feature.getProperties().features) { // 聚合情況下
            if (feature.getProperties().features.length === 1) {
              console.log(feature.getProperties().features[0])
            }
          }
        }
      })
    if (feature) { // 這里說明我們點擊的是點標記,
      const lnglat = feature.get('lnglat')// 我們可以通過給點標記傳不同的值,來判斷點擊不同的點標記觸發的事件。
      if (lnglat) {
        // 含有lnglat 參數的點標記觸發事件
      }
    }
  }

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

 

posted @ 2021-11-19 10:30  林恒  閱讀(1530)  評論(0)    收藏  舉報