Openlayers實(shí)現(xiàn)根據(jù)半徑繪制圓形
實(shí)現(xiàn)一個(gè)什么效果呢,就是在openlayers上面,繪制三個(gè)圓形,繪制完成之后,三個(gè)圓心連接起來(lái),然后標(biāo)記出每?jī)蓚€(gè)圓心之間的距離。
期望效果

寫(xiě)在前面
其實(shí)這個(gè)效果很好實(shí)現(xiàn)的,之前有幾篇博文呢,關(guān)于 openlayers 根據(jù)半徑繪制圓形,根據(jù)經(jīng)緯度坐標(biāo)繪制連線啥的都有涉及過(guò),所以說(shuō)如果要想實(shí)現(xiàn)今天想做的功能拼接一下就可以了,做一個(gè)快樂(lè)的代碼裁縫。
繪制圓形
簡(jiǎn)單的什么安裝 openlayers,導(dǎo)入,使用這里就不說(shuō)了,如果不清楚直接看之前的博客,今天不多廢話直接進(jìn)入正題。
首先第一步,我們先繪制著三個(gè)藍(lán)色的圓形。
關(guān)鍵代碼如下,特別說(shuō)一下哈,這是關(guān)鍵代碼,之前有人問(wèn)說(shuō)你代碼跑不起來(lái),我特別無(wú)語(yǔ),這是關(guān)鍵代碼,那些基本的創(chuàng)建變量啥的,一看報(bào)錯(cuò)就知道沒(méi)有創(chuàng)建,自己創(chuàng)建就行啦!沒(méi)有那么難啊!適當(dāng)?shù)母囊幌戮秃昧寺铩?/p>
// 繪制圓
addPoint() {
// 下面這個(gè)經(jīng)緯度都是寫(xiě)死的哈,一會(huì)連線和標(biāo)簽都是一樣的數(shù)據(jù)
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
let features = []
sites.forEach((item, index) => {
let feature = new Feature({
title: item.name,
geometry: new Circle(fromLonLat(item.site), this.getRadius(2000)),
})
feature.setStyle(
new Style({
fill: new Fill({
color: 'rgba(32, 157, 230, 1)'
}),
})
)
features.push(feature)
})
let source = new VectorSource()
source.addFeatures(features)
let layer = new VectorLayer({
opacity: 0.2
})
layer.setSource(source)
map.addLayer(layer)
},
好的,上面這一步完成之后呢,刷新頁(yè)面看到的效果應(yīng)該是下面的樣子。

添加圓形標(biāo)識(shí)
好了哈,我們給每個(gè)圓形添加一個(gè)文字標(biāo)識(shí),就是 覆蓋物1,、覆蓋物2、覆蓋物3這種。
關(guān)鍵代碼:
// 添加標(biāo)識(shí)
addLabel() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
let features = []
sites.forEach((item, index) => {
let feature = new Feature({
title: item.name,
geometry: new Point(fromLonLat(item.site)),
})
feature.setStyle(
new Style({
text: new Text({
textAlign: 'center',
textBaseline: 'middle',
font: 'normal 17px 微軟雅黑',
text: item.name,
fill: new Fill({
color: 'red'
}),
})
})
)
features.push(feature)
})
let sourceLabel = new VectorSource()
sourceLabel.addFeatures(features)
let layerLabel = new VectorLayer({
opacity: 1
})
layerLabel.setSource(sourceLabel)
map.addLayer(layerLabel)
},
上面的代碼執(zhí)行完成之后,就得到了下面的效果了。

繪制連線
接下來(lái)就是吧圓兩兩相連,用虛線也好,用實(shí)線也好,連接起來(lái),這個(gè)也很簡(jiǎn)單,直接上代碼。
// 添加連線
addLink() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
sites.push(sites[0])
let linkData = []
sites.forEach(item => {
linkData.push(fromLonLat(item.site))
})
let features = []
let featureLine = new Feature({
geometry: new LineString(linkData),
});
let lineStyle = new Style({
stroke: new Stroke({
color: '#000',
lineDash: [10, 10, 10, 10], // 重點(diǎn)在這
width: 2,
}),
});
// 添加線的樣式
featureLine.setStyle(lineStyle);
features.push(featureLine)
let sourceLink = new VectorSource()
sourceLink.addFeatures(features)
let layerLink = new VectorLayer()
layerLink.setSource(sourceLink)
map.addLayer(layerLink)
},
上面的代碼執(zhí)行完成之后呢,圓就兩兩相連了。

標(biāo)注距離
這個(gè)有兩個(gè)步驟,第一個(gè)步驟,計(jì)算距離,第二個(gè)步驟,標(biāo)注距離。
這個(gè)直接使用連線的圖層操作就可以了,所以說(shuō)修改連線代碼,繼續(xù)來(lái)計(jì)算距離,獲取距離后進(jìn)行標(biāo)注。
// 添加連線
addLink() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
sites.push(sites[0])
let linkData = []
sites.forEach(item => {
linkData.push(fromLonLat(item.site))
})
let features = []
let featureLine = new Feature({
geometry: new LineString(linkData),
});
let lineStyle = new Style({
stroke: new Stroke({
color: '#000',
lineDash: [10, 10, 10, 10], // 重點(diǎn)在這
width: 2,
}),
});
// 添加線的樣式
featureLine.setStyle(lineStyle);
features.push(featureLine)
let distanceList = []
for (let index = 0; index < sites.length - 1; index++) {
let site = fromLonLat([(sites[index].site[0] + sites[index + 1].site[0]) / 2, (sites[index].site[1] + sites[index + 1].site[1]) / 2])
let length = getDistance(sites[index].site, sites[index + 1].site);
distanceList.push({
site,
length,
})
}
distanceList.forEach((item) => {
let feature = new Feature({
title: '這是測(cè)試用的',
geometry: new Point(item.site),
})
feature.setStyle(
new Style({
text: new Text({
textAlign: 'center', //位置
textBaseline: 'middle', //基準(zhǔn)線
font: 'normal 12px 微軟雅黑', //文字樣式
text: item.length.toFixed(0) + 'm', //文本內(nèi)容
padding: [1, 1, 1, 1],
backgroundFill: new Fill({ //文本填充樣式(即文字顏色)
color: '#d5e2f9'
}),
fill: new Fill({ //文本填充樣式(即文字顏色)
color: 'red'
}),
})
})
)
features.push(feature)
})
let sourceLink = new VectorSource()
sourceLink.addFeatures(features)
let layerLink = new VectorLayer()
layerLink.setSource(sourceLink)
map.addLayer(layerLink)
},
好了,到此為止,最開(kāi)始想要實(shí)現(xiàn)的效果就都出來(lái)了。

好了,下面放一下全部代碼吧。
<template>
<div style="width:100%;height: 100%;position: relative;">
<div id="map"></div>
</div>
</template>
<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import * as olProj from 'ol/proj';
import Draw from 'ol/interaction/Draw';
import Overlay from 'ol/Overlay';
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
import { OSM, Vector as VectorSource } from 'ol/source';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import Feature from 'ol/Feature';
import { Point, MultiLineString, LineString, Polygon } from "ol/geom";
import { fromLonLat } from 'ol/proj';
import Circle from 'ol/geom/Circle';
import { ScaleLine, defaults as defaultControls } from 'ol/control';
import { circular } from 'ol/geom/Polygon';
import * as olSphere from 'ol/sphere';
import LinearRing from 'ol/geom/LinearRing';
import { getTransform } from 'ol/proj';
import { getArea, getLength, getDistance } from 'ol/sphere';
import { unByKey } from 'ol/Observable';
import WMTS from 'ol/source/WMTS';
import ImageLayer from 'ol/layer/Image';
import ImageWMS from 'ol/source/ImageWMS';
import TileWMS from 'ol/source/TileWMS';
import WMTSTileGrid from 'ol/tilegrid/WMTS';
import * as olExtent from 'ol/extent';
import GeoJSON from 'ol/format/GeoJSON';
import Text from 'ol/style/Text';
var map = null; // /地圖實(shí)例
var view = null; // 視圖實(shí)例
export default {
name: "Home",
components: {
},
data() {
return { }
},
mounted() {
this.initMap()
},
methods: {
// 初始化地圖
initMap() {
// 實(shí)例化Map
map = new Map({ // 創(chuàng)建一個(gè)地圖
layers: [new TileLayer({
source: new OSM(),
}),],
target: 'map',
view: new View({
center: fromLonLat([116.403218, 39.92372]),
zoom: 15,
constrainResolution: true, // 設(shè)置縮放級(jí)別為整數(shù)
smoothResolutionConstraint: false, // 關(guān)閉無(wú)級(jí)縮放地圖
}),
});
view = map.getView()
// 加載圓形
this.addPoint()
},
// 繪制圓
addPoint() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
let features = []
sites.forEach((item, index) => {
let feature = new Feature({
title: item.name,
geometry: new Circle(fromLonLat(item.site), this.getRadius(2000)),
})
feature.setStyle(
new Style({
fill: new Fill({
color: 'rgba(32, 157, 230, 1)'
}),
})
)
features.push(feature)
})
let source = new VectorSource()
source.addFeatures(features)
let layer = new VectorLayer({
opacity: 0.2
})
layer.setSource(source)
map.addLayer(layer)
this.addLabel()
this.addLink()
},
// 添加標(biāo)識(shí)
addLabel() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
let features = []
sites.forEach((item, index) => {
let feature = new Feature({
title: item.name,
geometry: new Point(fromLonLat(item.site)),
})
feature.setStyle(
new Style({
text: new Text({
textAlign: 'center', //位置
textBaseline: 'middle', //基準(zhǔn)線
font: 'normal 17px 微軟雅黑', //文字樣式
text: item.name, //文本內(nèi)容
fill: new Fill({ //文本填充樣式(即文字顏色)
color: 'red'
}),
})
})
)
features.push(feature)
})
let sourceLabel = new VectorSource()
sourceLabel.addFeatures(features)
let layerLabel = new VectorLayer({
opacity: 1
})
layerLabel.setSource(sourceLabel)
map.addLayer(layerLabel)
},
// 添加連線
addLink() {
let sites = [{
site: [116.400819, 39.916263],
name: '覆蓋物1'
}, {
site: [116.450819, 39.917263],
name: '覆蓋物2'
}, {
site: [116.350819, 39.857263],
name: '覆蓋物3'
}]
sites.push(sites[0])
let linkData = []
sites.forEach(item => {
linkData.push(fromLonLat(item.site))
})
let features = []
let featureLine = new Feature({
geometry: new LineString(linkData),
});
let lineStyle = new Style({
stroke: new Stroke({
color: '#000',
lineDash: [10, 10, 10, 10], // 重點(diǎn)在這
width: 2,
}),
});
// 添加線的樣式
featureLine.setStyle(lineStyle);
features.push(featureLine)
let distanceList = []
for (let index = 0; index < sites.length - 1; index++) {
let site = fromLonLat([(sites[index].site[0] + sites[index + 1].site[0]) / 2, (sites[index].site[1] + sites[index + 1].site[1]) / 2])
let length = getDistance(sites[index].site, sites[index + 1].site);
distanceList.push({
site,
length,
})
}
distanceList.forEach((item) => {
let feature = new Feature({
title: '這是測(cè)試用的',
geometry: new Point(item.site),
})
feature.setStyle(
new Style({
text: new Text({
textAlign: 'center', //位置
textBaseline: 'middle', //基準(zhǔn)線
font: 'normal 12px 微軟雅黑', //文字樣式
text: item.length.toFixed(0) + 'm', //文本內(nèi)容
padding: [1, 1, 1, 1],
backgroundFill: new Fill({ //文本填充樣式(即文字顏色)
color: '#d5e2f9'
}),
fill: new Fill({ //文本填充樣式(即文字顏色)
color: 'red'
}),
})
})
)
features.push(feature)
})
let sourceLink = new VectorSource()
sourceLink.addFeatures(features)
let layerLink = new VectorLayer()
layerLink.setSource(sourceLink)
map.addLayer(layerLink)
},
// 半徑計(jì)算
getRadius(radius) {
let metersPerUnit = map.getView().getProjection().getMetersPerUnit();
let circleRadius = radius / metersPerUnit;
return circleRadius;
},
},
};
</script>
<style scoped>
#map {
width: 100%;
height: 100%;
background-color: azure;
}
</style>
<style scoped>
/deep/.ol-tooltip {
position: relative;
background: rgba(0, 0, 0, 0.7);
border-radius: 4px;
color: white;
padding: 4px 8px;
opacity: 0.7;
white-space: nowrap;
font-size: 12px;
cursor: default;
user-select: none;
}
/deep/.ol-tooltip-measure {
opacity: 1;
font-weight: bold;
}
/deep/.ol-tooltip-static {
background-color: #ffcc33;
color: black;
border: 1px solid white;
}
/deep/.ol-tooltip-measure:before,
/deep/.ol-tooltip-static:before {
border-top: 6px solid rgba(0, 0, 0, 0.5);
border-right: 6px solid transparent;
border-left: 6px solid transparent;
content: "";
position: absolute;
bottom: -6px;
margin-left: -7px;
left: 50%;
}
/deep/.ol-tooltip-static:before {
border-top-color: #ffcc33;
}
</style>到此這篇關(guān)于Openlayers實(shí)現(xiàn)根據(jù)半徑繪制圓形的文章就介紹到這了,更多相關(guān)Openlayers繪制圓形內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Js參數(shù)值中含有單引號(hào)或雙引號(hào)問(wèn)題的解決方法
本文是對(duì)Js參數(shù)值中含有單引號(hào)或雙引號(hào)問(wèn)題的解決方法進(jìn)行了總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
微信小程序事件 bindtap bindinput代碼實(shí)例
這篇文章主要介紹了微信小程序事件 bindtap bindinput代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
跟我學(xué)習(xí)javascript的基本類型和引用類型
跟我學(xué)習(xí)javascript的基本類型和引用類型,利用圖解的方式,告訴大家javascript的基本類型和引用類型的區(qū)別和聯(lián)系,感興趣的小伙伴們可以參考一下2015-11-11
uniapp項(xiàng)目打包為桌面應(yīng)用的方法步驟
本文主要介紹了uniapp項(xiàng)目打包為桌面應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
原生js實(shí)現(xiàn)類似彈窗抖動(dòng)效果
這篇文章主要介紹了原生js實(shí)現(xiàn)類似彈窗抖動(dòng)效果的相關(guān)資料,推薦給大家,需要的朋友可以參考下2015-04-04

