本博客合集是我的openlayers學(xué)習(xí)筆記缤至,希望能幫助到剛開始接觸openlayers的同學(xué)
@commnet 所用openlayers版本:v5.3.0
@commnet 閱讀本文前需要對前端知識有一定的了解
@comment 本文內(nèi)容只提供參考盐欺,建議結(jié)合openlayers官網(wǎng)的API和examples來學(xué)習(xí)
@comment 部分代碼參考了@老胡
有些情景需要在地圖上對圖形進(jìn)行定位,如點擊了某文本中的“泰坦尼克號”鏈接凰棉,希望自動在地圖上定位出該船的位置梁剔。
在確定了地圖視角和位置的情況下瞬哼,圖形也就定位了奄薇,常有以下幾種方式的定位(請忽略我這吃力的網(wǎng)速):
- 地圖內(nèi)容區(qū)外接圖形(內(nèi)容區(qū)外接多邊形的上下頂點)
- 地圖內(nèi)容區(qū)以最大的整數(shù)zoom,定位完整圖形(當(dāng)前zoom是能看到完整多邊形最大的整數(shù)zoom了)
- 地圖內(nèi)容區(qū)以最小的整數(shù)zoom脑豹,讓圖形鋪滿地圖
- 地圖內(nèi)容區(qū)以某分辨率郑藏,中心定位圖形(中間的小圓圈)
- 地圖內(nèi)容區(qū)相對于地圖視窗大小,以指定偏移量定位圖形(小圓圈偏移到了指定的正方形區(qū)域中)
注:這里的“內(nèi)容區(qū)”是我的理解瘩欺,可以把地圖的view理解成css中的盒模型必盖,當(dāng)view.fit函數(shù)(下面會提到)沒有指定padding參數(shù)時,內(nèi)容區(qū)就是整個view俱饿,一旦指定了padding參數(shù)歌粥,內(nèi)容區(qū)就變成了padding圈起來的視區(qū)了。
- 創(chuàng)建5個功能測試按鈕和地圖容器
<button id="zoomtoswitzerlandbest">外接匹配</button><br />
<button id="zoomtoswitzerlandconstrained">最佳分辨率匹配</button><br />
<button id="zoomtoswitzerlandnearest">最佳范圍匹配</button><br />
<button id="zoomtolausanne">點居中</button><br />
<button id="centerlausanne">定位點到指定位置</button>
<div class="mapcontainer">
<div id="map" class="map"></div>
<div class="padding-top"></div>
<div class="padding-left"></div>
<div class="padding-right"></div>
<div class="padding-bottom"></div>
<div class="center"></div>
</div>
- 添加樣式
.mapcontainer {
position: relative;
margin-bottom: 20px;
}
.map {
width: 1000px;
height: 600px;
}
div.ol-zoom {
top: 178px;
left: 158px;
}
div.ol-rotate {
top: 178px;
right: 58px;
}
.map div.ol-attribution {
bottom: 30px;
right: 50px;
}
.padding-top {
position: absolute;
top: 0;
left: 0px;
width: 1000px;
height: 170px;
background: rgba(255, 255, 255, 0.5);
}
.padding-left {
position: absolute;
top: 170px;
left: 0;
width: 150px;
height: 400px;
background: rgba(255, 255, 255, 0.5);
}
.padding-right {
position: absolute;
top: 170px;
left: 950px;
width: 50px;
height: 400px;
background: rgba(255, 255, 255, 0.5);
}
.padding-bottom {
position: absolute;
top: 570px;
left: 0px;
width: 1000px;
height: 30px;
background: rgba(255, 255, 255, 0.5);
}
.center {
position: absolute;
border: solid 1px black;
top: 490px;
left: 560px;
width: 20px;
height: 20px;
}
- 創(chuàng)建地圖對象
//在矢量圖層上添加一個多邊形(ol.geom.Polygon)和一個點(ol.geom.Point)
var source = new ol.source.Vector({
url: '../data/switzerland.geojson',
format: new ol.format.GeoJSON()
});
//創(chuàng)建樣式對象
var style = new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.6)'
}),
stroke: new ol.style.Stroke({
color: '#319FD3',
width: 1
}),
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.6)'
}),
stroke: new ol.style.Stroke({
color: '#319FD3',
width: 1
})
})
});
//創(chuàng)建矢量圖層
var vectorLayer = new ol.layer.Vector({
source: source,
style: style
});
var view = new ol.View({
center: [0, 0],
zoom: 1
});
//地圖包含底圖和矢量圖層
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectorLayer
],
target: 'map',
view: view
});
- 為5個功能測試按鈕添加點擊事件拍埠,注釋中詳細(xì)說明了幾種定位的用法和區(qū)別
//多邊形的外接匹配:地圖的內(nèi)容區(qū)外接多邊形
var zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest');
zoomtoswitzerlandbest.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = feature.getGeometry();
//將view理解成css中的盒模型失驶,多邊形相對于padding里的內(nèi)容區(qū)進(jìn)行定位
//constrainResolution默認(rèn)為true,這里設(shè)為false即不限制分辨率枣购,zoom不必是整數(shù)嬉探,因此可以實現(xiàn)精確的外接定位
view.fit(polygon, {
padding: [170, 50, 30, 150],
constrainResolution: false
});
console.log(map.getView().getZoom())
}, false);
//多邊形的最佳分辨率匹配:再繼續(xù)放大,多邊形就超出內(nèi)容區(qū)了
var zoomtoswitzerlandconstrained =
document.getElementById('zoomtoswitzerlandconstrained');
zoomtoswitzerlandconstrained.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = feature.getGeometry();
//如果不寫constrainResolution棉圈,默認(rèn)為true
//即該定位結(jié)果是在zoom為整數(shù)的前提下涩堤,能看到完整多邊形的最大分辨率
view.fit(polygon, {
padding: [170, 50, 30, 150]
});
console.log(map.getView().getZoom())
}, false);
//多邊形的最佳范圍匹配
var zoomtoswitzerlandnearest =
document.getElementById('zoomtoswitzerlandnearest');
zoomtoswitzerlandnearest.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = feature.getGeometry();
//設(shè)置nearest為true,以最小的整數(shù)zoom迄损,讓圖形鋪滿地圖
view.fit(polygon, {
padding: [170, 50, 30, 150],
nearest: true
});
console.log(map.getView().getZoom())
}, false);
//將點以某分辨率居中
var zoomtolausanne = document.getElementById('zoomtolausanne');
zoomtolausanne.addEventListener('click', function() {
var feature = source.getFeatures()[1];
var point = feature.getGeometry();
//將點point以分辨率minResolution居中
view.fit(point, {
padding: [170, 50, 30, 150],
minResolution: 250
});
}, false);
//將點相對map.getSize()以指定偏移量定位
var centerlausanne = document.getElementById('centerlausanne');
centerlausanne.addEventListener('click', function() {
var feature = source.getFeatures()[1];
var point = feature.getGeometry();
var size = map.getSize();
console.log(size)
//相對于size定躏,點point距離頂部偏移了500px账磺,距離左邊偏移了570px
view.centerOn(point.getCoordinates(), size, [570, 500]);
}, false);