vue+openlayer實現選房平面圖
前言
使用openlayer實現選房平面圖的需求:
1.選用地圖背景圖
2.將geojson數據(沒有後臺所以就寫死了2個數據)生成房間圖層塊覆蓋背景圖上對應的房間塊
3.根據條件,可選區域與不可區域圖形塊顏色不一樣
4.點擊圖層能獲取到對應的數據,同時選中的圖層塊樣式發生改變
代碼詳解
地圖背景展示
根據官方案例,只需要提供一個div,然後將Map對象掛載到div元素上
const extent = [0, 0, 50, 50];//地圖範圍
const projection = new Projection({//地圖投影
code: 'xkcd-image',
units: 'pixels',
extent,
});
this.map = new Map({
layers: [
new ImageLayer({
source: new Static({ //這就是靜態背景圖片
url: '/img/A-10.png',//圖片路徑,放在靜態文件夾public(vue-cli3.0)或static(vue-cli2.0)裏,根據腳手架版本來
projection,
imageExtent: extent,//圖片位置
}),
}),
vectorLayer,//多個圖層,下面會講到
],
target: 'map',
view: new View({
projection,
center: getCenter(extent),
zoom: 1,//地圖默認比例
maxZoom: 4,//地圖最大比例
minZoom: 1,//地圖最小
}),
});
這樣一個帶圖片背景的地圖就做好了
然後就要渲染上面的圖層了
圖層渲染
步驟大概爲:GeoJSON轉換json數據爲feature->vectoryresource->獲取樣式->vectorlayer->map添加vectorlayer
根據GeoJSON獲取圖層
const geojsonObject = {
type: 'FeatureCollection',
crs: {
type: 'name',
properties: {
name: 'EPSG:3857',
},
},
features: [{
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [[[14.599609375, 16.9677734375], [21.6796875, 17.08984375], [21.6796875, 4.7607421875], [14.84375, 4.7607421875]]],
},
id: '007ABA46-7B0C-4F90-B6D4-8F6546363E',
properties: { modelId: '2311', id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E', type: 'room' },
},
{
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [[[21.5576171875, 17.08984375], [28.6376953125, 17.08984375], [28.515625, 5.0048828125], [21.5576171875, 5.126953125]]],
},
id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E',
properties: { modelId: '2310', id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E', type: 'room' },
},
],
};
以上是geoJSON的內容,properties是可以給圖層添加的一些參數,便於處理業務需要,type即指定feature的類型,這裏是指定爲多邊形,coordinates爲多邊形的座標
(new GeoJSON()).readFeatures(geojsonObject)//將GeoJSON轉換成features
獲取樣式
主要是邊框色,填充色以及填充的文本樣式
//獲取樣式方法
//可將feature的數據傳過來進行判斷返回對應的樣式
const getStyles = (param) => {
console.log(param);
const style = new Style({
stroke: new Stroke({//邊框
color: '#2d9fd8',
width: 0,
}),
fill: new Fill({//填充色
color: '#2d9fd8',
//color:[0, 11, 214, 0.5];0.5爲透明度
}),
text: new Text({ // 文本樣式
className: 'map-font',
font: '14px Microsoft YaHei',
fill: new Fill({
color: 'black',
}),
}),
});
if (param === '2311') {//對圖層裏的參數進行判斷
style.getStroke().setColor('#cccccc');
style.getFill().setColor('#cccccc');
}
style.getText().setText(param);//可在圖層上顯示文本
return style;
};
const styleFunction = (feature) => getStyles(feature.values_.modelId);//傳入feature的參數
map添加vectorlayer
const vectorLayer = new VectorLayer({
source: vectorSource,
style: styleFunction,
title: '',
type: 'room',
});
可以直接將vectorlayer在初始化時就塞進map裏,也可以調用map的addLayer()方法
this.map.addLayer(vectorLayer)
map添加選中交互事件,並添加秀忠後的樣式
// 選中之後的樣式
const selectSingleClick = new Select({
style: new Style({
stroke: new Stroke({
color: '#2d9fd8',
width: 0,
}),
fill: new Fill({
color: [0, 11, 214, 0.5],
}),
}),
});
//map添加選中事件
this.map.addInteraction(selectSingleClick);
// 點擊圖層之後的處理
selectSingleClick.on('select', (e) => {
const features = e.target.getFeatures().getArray();
if (features.length > 0) {
const feature = features[0];//獲取當前圖層
//const type = feature.getGeometry().getType();
const property = feature.getProperties();//獲取當前圖層裏的參數
//const coordinate = getCenter(feature.getGeometry().getExtent());
alert(property.modelId);//彈出框展示feature裏properties裏的modelId
}
});
效果展示
(因爲不能泄露地圖,所以就自己隨便畫了個醜醜的,將就看-><-)
可以看到只覆蓋了兩個圖層,數字也是覆蓋上去的
下面看點擊之後的效果
選中後的圖層顯示爲選中設置的樣式,之前覆蓋的字體沒了,所以如果在選中之後也要顯示字體的要在Select裏重新添加文本
可以進https://github.com/Daizymis/Demo/tree/master/aap/src/components/roommap參考完整源碼