項目背景vue-cli3.0
public下html需要引入文件
<link rel="stylesheet" href="<%= BASE_URL %>./css/gr-ol.css" type="text/css">
<script src="<%= BASE_URL %>./js/ol.js" type="text/javascript"></script>
這里地圖為公共組件,方法寫在公共組件的init方法里,kpst._this為地圖對象
調用
//測距/面
var draw = me.map._this.interactions.getArray()[10]
me.map._this.removeInteraction(draw);
if (data.name == '測距' || data.name == '測面') {
me.map._this.interactions.array_ = arr.slice(0, 10)
if (data.name == '測距') {
me.mtype = 'LineString'
} else {
me.mtype = 'Polygon'
}
me.map._this.measure(me.mtype) //map已掛載到vue原型Vue.prototype.map = map
} else if (data.name == '清除') {
me.map._this.clear()
}
方法掛載
// 測距、面
//創建一個當前要繪制的對象
var sketch
//創建一個幫助提示框對象
var helpTooltipElement;
//創建一個幫助提示信息對象
var helpTooltip;
//創建一個測量提示框對象
var measureTooltipElement;
//創建一個測量提示信息對象
var measureTooltip;
//繼續繪制多邊形的提示信息
var continuePolygonMsg
//繼續繪制線段的提示信息
var continueLineMsg
//幫助提示信息
var helpMsg
//定義矢量數據源
var source = new ol.source.Vector();
//定義矢量圖層
var vector = new ol.layer.Vector({
source: source,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255,255,255,0.2)'
}),
stroke: new ol.style.Stroke({
color: '#e21e0a',
width: 2
}),
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
//創建比例尺控件
var scaleLineControl = new ol.control.ScaleLine({
units: 'metric',
target: 'scalebar',
className: 'ol-scale-line'
});
function measure(mtype) {
sketch = new ol.Feature();
// continuePolygonMsg = 'Click to continue drawing the polygon';
// continueLineMsg = 'Click to continue drawing the line';
//將矢量圖層添加到地圖中
kpst._this.removeLayer(vector);
kpst._this.addLayer(vector);
//添加比例尺控件
kpst._this.removeControl(scaleLineControl);
kpst._this.addControl(scaleLineControl);
//鼠標移動觸發的函數
var pointerMoveHandler = function (evt) {
//如果是平移地圖則直接結束
if (evt.dragging) {
return;
}
//幫助提示信息
helpMsg = 'Click to start drawing';
if (sketch) {
//獲取繪圖對象的幾何要素
var geom = sketch.getGeometry();
//如果當前繪制的幾何要素是多線段,則將繪制提示信息設置為多線段繪制提示信息
// if (geom instanceof ol.geom.Polygon) {
// helpMsg = continuePolygonMsg;
// } else if (geom instanceof ol.geom.LineString) {
// helpMsg = continueLineMsg;
// }
}
//設置幫助提示要素的內標簽為幫助提示信息
// if (helpTooltipElement)
// helpTooltipElement.innerHTML = helpMsg;
//設置幫助提示信息的位置
// if (helpTooltip)
helpTooltip.setPosition(evt.coordinate);
//移除幫助提示要素的隱藏樣式
// $(helpTooltipElement).removeClass('hidden');
removeClass(document.getElementsByClassName('tooltip')[0], 'hidden')
};
//觸發pointermove事件
kpst._this.on('pointermove', pointerMoveHandler);
//當鼠標移除地圖視圖的時為幫助提示要素添加隱藏樣式
document.querySelector('.ol-viewport').onmouseout = function () {
addClass(document.getElementsByClassName('tooltip')[0], 'hidden')
}
// 判斷class有無
function hasClass(ele, cls) {
if (ele) {
cls = cls || '';
if (cls.replace(/\s/g, '').length == 0) return false; //當cls沒有參數時,返回false
return new RegExp(' ' + cls + ' ').test(' ' + ele.className + ' ');
}
}
//添加class
function addClass(ele, cls) {
if (!hasClass(ele, cls) && ele) {
ele.className = ele.className == '' ? cls : ele.className + ' ' + cls;
}
}
// 去除class
function removeClass(ele, cls) {
if (hasClass(ele, cls) && ele) {
var newClass = ' ' + ele.className.replace(/[\t\r\n]/g, '') + ' ';
while (newClass.indexOf(' ' + cls + ' ') >= 0) {
newClass = newClass.replace(' ' + cls + ' ', ' ');
}
ele.className = newClass.replace(/^\s+|\s+$/g, '');
}
}
//定義一個交互式繪圖對象
var draw;
//添加交互式繪圖對象的函數
function addInteraction() {
//創建一個交互式繪圖對象
draw = new ol.interaction.Draw({
//繪制的數據源
source: source,
//繪制類型
type: mtype,
//樣式
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255,255,255,0.2)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0,0,0,0.5)',
lineDash: [10, 10],
width: 2
}),
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke({
color: 'rgba(0,0,0,0.7)'
}),
fill: new ol.style.Fill({
color: 'rgba(255,255,255,0.2)'
})
})
})
});
//將交互繪圖對象添加到地圖中
kpst._this.addInteraction(draw);
//創建測量提示框
createMeasureTooltip();
//創建幫助提示框
createHelpTooltip();
//定義一個事件監聽
var listener;
//定義一個控制鼠標點擊次數的變量
var count = 0;
//繪制開始事件
draw.on('drawstart', function (evt) {
//The feature being drawn.
sketch = evt.feature;
//提示框的坐標
var tooltipCoord = evt.coordinate;
//監聽幾何要素的change事件
//Increases the revision counter and dispatches a 'change' event.
listener = sketch.getGeometry().on('change', function (evt) {
//The event target.
//獲取繪制的幾何對象
var geom = evt.target;
//定義一個輸出對象,用於記錄面積和長度
var output;
if (geom instanceof ol.geom.Polygon) {
kpst._this.removeEventListener('singleclick');
kpst._this.removeEventListener('dblclick');
//輸出多邊形的面積
output = formatArea(geom);
//Return an interior point of the polygon.
//獲取多變形內部點的坐標
tooltipCoord = geom.getInteriorPoint().getCoordinates();
} else if (geom instanceof ol.geom.LineString) {
//輸出多線段的長度
output = formatLength(geom);
//Return the last coordinate of the geometry.
//獲取多線段的最后一個點的坐標
tooltipCoord = geom.getLastCoordinate();
}
//設置測量提示框的內標簽為最終輸出結果
// if (measureTooltipElement)
measureTooltipElement.innerHTML = output;
//設置測量提示信息的位置坐標
// if (measureTooltip)
measureTooltip.setPosition(tooltipCoord);
});
//地圖單擊事件
kpst._this.on('singleclick', function (evt) {
//設置測量提示信息的位置坐標,用來確定鼠標點擊后測量提示框的位置
// if (measureTooltip)
measureTooltip.setPosition(evt.coordinate);
//如果是第一次點擊,則設置測量提示框的文本內容為起點
if (count == 0 && measureTooltipElement) {
measureTooltipElement.innerHTML = "起點";
}
//根據鼠標點擊位置生成一個點
var point = new ol.geom.Point(evt.coordinate);
//將該點要素添加到矢量數據源中
source.addFeature(new ol.Feature(point));
//更改測量提示框的樣式,使測量提示框可見
measureTooltipElement.className = 'tooltip tooltip-static';
//創建測量提示框
createMeasureTooltip();
//點擊次數增加
count++;
});
//地圖雙擊事件
kpst._this.on('dblclick', function (evt) {
//根據
var point = new ol.geom.Point(evt.coordinate);
source.addFeature(new ol.Feature(point));
});
}, this);
//繪制結束事件
draw.on('drawend', function (evt) {
count = 0;
//設置測量提示框的樣式
measureTooltipElement.className = 'tooltip tooltip-static';
//Set the offset for this overlay.
//設置偏移量
measureTooltip.setOffset([0, -7]);
//清空繪制要素
sketch = null;
//清空測量提示要素
measureTooltipElement = null;
//創建測量提示框
createMeasureTooltip();
//Removes an event listener using the key returned by on() or once().
//移除事件監聽
ol.Observable.unByKey(listener);
//移除地圖單擊事件
kpst._this.removeEventListener('singleclick');
}, this);
}
//創建幫助提示框
function createHelpTooltip() {
//如果已經存在幫助提示框則移除
if (helpTooltipElement) {
helpTooltipElement.parentNode.removeChild(helpTooltipElement);
}
//創建幫助提示要素的div
if (!helpTooltipElement)
helpTooltipElement = document.createElement('div');
//設置幫助提示要素的樣式
helpTooltipElement.className = 'tooltip hidden';
//創建一個幫助提示的覆蓋標注
helpTooltip = new ol.Overlay({
element: helpTooltipElement,
offset: [15, 0],
positioning: 'center-left'
});
//將幫助提示的覆蓋標注添加到地圖中
kpst._this.addOverlay(helpTooltip);
}
//創建測量提示框
function createMeasureTooltip() {
//創建測量提示框的div
// if (!measureTooltipElement)
measureTooltipElement = document.createElement('div');
measureTooltipElement.setAttribute('id', 'lengthLabel');
//設置測量提示要素的樣式
measureTooltipElement.className = 'tooltip tooltip-measure';
//創建一個測量提示的覆蓋標注
measureTooltip = new ol.Overlay({
element: measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center'
});
//將測量提示的覆蓋標注添加到地圖中
kpst._this.addOverlay(measureTooltip);
}
//格式化測量長度
var formatLength = function (line) {
//定義長度變量
var length;
//計算平面距離
length = Math.round(line.getLength() * 100) / 100;
//定義輸出變量
var output;
//如果長度大於1000,則使用km單位,否則使用m單位
if (length > 100) {
output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //換算成KM單位
} else {
output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m為單位
}
return output;
};
//格式化測量面積
var formatArea = function (polygon) {
//定義面積變量
var area;
//獲取平面面積
area = polygon.getArea();
// }
//定義輸出變量
var output;
//當面積大於10000時,轉換為平方千米,否則為平方米
if (area > 1000) {
output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>';
} else {
output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>';
}
return output;
};
//添加交互繪圖對象
addInteraction();
}
// 清除提示對象
function clear() {
source.clear()
kpst._this.getOverlays().clear();
kpst._this.removeLayer(vector);
kpst._this.removeControl(scaleLineControl);
}
kpst._this.measure = measure
kpst._this.clear = clear