1.效果图(测距)
2.测面
3.封装measure.Vue(把样式放到要引入的页面)
<template>
<div>
<div class="btns-box">
<el-button type="primary" @click="measure('LineString')">测距</el-button>
<el-button type="primary" @click="measure('Polygon')">测面</el-button>
<el-button type="primary" @click="clearMeasure">清除测量轨迹</el-button>
</div>
</div>
</template>
<script>
import 'ol/ol.css'
import Draw from 'ol/interaction/Draw'
import Map from 'ol/Map'
import Overlay from 'ol/Overlay'
import View from 'ol/View'
import TileArcGISRest from 'ol/source/TileArcGISRest'
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'
import { LineString, Polygon } from 'ol/geom'
import { OSM, Vector as VectorSource } from 'ol/source'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { getArea, getLength } from 'ol/sphere'
import { unByKey } from 'ol/Observable'
import CONSTANT from '@/utils/constant.js'
let layerIndex = 0
export default {
name: 'Measure',
props: {
drawLineMap: {
type: Object,
default: () => {
}
}
},
data() {
return {
map: null,
raster: null,
vector: new VectorLayer({
source: new VectorSource(),
style: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new Stroke({
color: '#ffcc33',
width: 2
}),
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: '#ffcc33'
})
})
})
}),
sketch: null, // Currently drawn feature
helpTooltipElement: null, // The help tooltip element.
helpTooltip: null, // Overlay to show the help messages.
measureTooltipElement: null, // The measure tooltip element.
measureTooltip: null, // Overlay to show the measurement.
// Message to show when the user is drawing a polygon.
continuePolygonMsg: '单击继续绘制多边形',
// Message to show when the user is drawing a line
continueLineMsg: '单击继续绘制直线',
draw: null, //global so we can remove it later
listener: null,
shapeType: null,
drawCache: {},
}
},
created() {
setTimeout(() => {
this.map = this.drawLineMap
this.map.addLayer(this.vector)
}, 1000)
},
methods: {
// 测距、测面
measure(type) {
this.shapeType = type
layerIndex++
this.drawCache[layerIndex] = {
feature: null,
measureTooltip: null
}
if (this.draw) {
this.map.removeInteraction(this.draw)
}
// 添加map事件
this.addMapEvent()
},
// 清除测量
clearMeasure() {
for (const i in this.drawCache) {
this.map.removeOverlay(this.drawCache[i].measureTooltip)
this.vector.getSource().removeFeature(this.drawCache[i].feature)
}
this.drawCache = {}
layerIndex = 0
},
addMapEvent() {
console.log(111)
console.log(this.map)
this.map.on('pointermove', (evt) => {
this.draw ? this.pointerMoveHandler(evt) : this.map.removeOverlay(this.helpTooltip)
})
this.map.getViewport().addEventListener('mouseout', () => {
this.helpTooltipElement && this.helpTooltipElement.classList.add('hidden')
})
this.addInteraction()
},
addInteraction() {
this.draw = new Draw({
source: this.vector.getSource(),
type: this.shapeType,
style: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 2
}),
image: new CircleStyle({
radius: 5,
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.7)'
}),
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
})
})
})
})
this.map.addInteraction(this.draw)
this.createMeasureTooltip()
this.createHelpTooltip()
this.drawHandler()
},
/**
* Handle pointer move.
* @param {import('../src/ol/MapBrowserEvent').default} evt The event.
*/
pointerMoveHandler(evt) {
if (evt.dragging) {
return
}
/** @type {string} */
var helpMsg = '单击开始绘图'
if (this.sketch) {
var geom = this.sketch.getGeometry()
if (geom instanceof LineString) {
helpMsg = this.continueLineMsg
}
}
this.helpTooltipElement.innerHTML = helpMsg
this.helpTooltip.setPosition(evt.coordinate)
this.helpTooltipElement.classList.remove('hidden')
},
/**
* Format length output.
* @param {LineString} line The line.
* @return {string} The formatted length.
*/
formatLength(line) {
const sourceProj = this.map.getView().getProjection() // 获取投影坐标系
var length = getLength(line, { projection: sourceProj })
var output
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km'
} else {
output = Math.round(length * 100) / 100 + ' ' + 'm'
}
return output
},
/**
* Format area output.
* @param {Polygon} polygon The polygon.
* @return {string} Formatted area.
*/
formatArea(polygon) {
const sourceProj = this.map.getView().getProjection() //获取投影坐标系
const geom = polygon.clone().transform(sourceProj, 'EPSG:3857')
const area = getArea(geom)
let output
if (area > 10000) {
output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>'
} else {
output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>'
}
return output
},
/**
* Creates a new measure tooltip
*/
createMeasureTooltip() {
if (this.measureTooltipElement) {
this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement)
}
this.measureTooltipElement = document.createElement('div')
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'
this.measureTooltip = new Overlay({
element: this.measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center'
})
this.map.addOverlay(this.measureTooltip)
},
/**
* Creates a new help tooltip
*/
createHelpTooltip() {
if (this.helpTooltipElement) {
this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement)
}
this.helpTooltipElement = document.createElement('div')
this.helpTooltipElement.className = 'ol-tooltip hidden'
this.helpTooltip = new Overlay({
element: this.helpTooltipElement,
offset: [15, 0],
positioning: 'center-left'
})
this.map.addOverlay(this.helpTooltip)
},
drawHandler() {
this.draw.on('drawstart', (evt) => {
this.sketch = evt.feature
let tooltipCoord = evt.coordinate
this.listener = this.sketch.getGeometry().on('change', (evt) => {
let output
const geom = evt.target
if (geom instanceof LineString) {
output = this.formatLength(geom)
tooltipCoord = geom.getLastCoordinate()
} else if (geom instanceof Polygon) {
output = this.formatArea(geom)
tooltipCoord = geom.getInteriorPoint().getCoordinates()
}
const closeBtn =
'<i class=\'tooltip-close-btn tooltip-close-btn_' + layerIndex + '\' data-index=\'' + layerIndex + '\'></i>'
this.measureTooltipElement.innerHTML = output + closeBtn
this.measureTooltip.setPosition(tooltipCoord)
this.drawCache[layerIndex].measureTooltip = this.measureTooltip
})
})
this.draw.on('drawend', (evt) => {
this.drawCache[layerIndex].feature = evt.feature
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'
this.measureTooltip.setOffset([0, -7])
// unset sketch
this.sketch = null
// unset tooltip so that a new one can be created
this.measureTooltipElement = null
this.createMeasureTooltip()
unByKey(this.listener)
this.map.removeInteraction(this.draw)
this.draw = null
// 删除图层
const self = this
document.querySelector('.tooltip-close-btn_' + layerIndex).addEventListener('click', function() {
self.vector.getSource().removeFeature(self.drawCache[this.dataset.index].feature)
self.map1.removeOverlay(self.drawCache[this.dataset.index].measureTooltip)
delete self.drawCache[this.dataset.index]
})
})
}
},
mounted() {
}
}
</script>
<style lang="scss" scoped>
.btns-box {
float: left;
margin-left: 5px;
}
//测距,测面
::v-deep .ol-tooltip {
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 4px;
color: white;
padding: 4px 14px 4px 8px;
opacity: 0.7;
white-space: nowrap;
font-size: 12px;
}
::v-deep .ol-tooltip-measure {
opacity: 1;
font-weight: bold;
}
::v-deep .ol-tooltip-static {
background-color: #ffcc33;
color: black;
border: 1px solid white;
}
::v-deep .ol-tooltip-measure:before,
::v-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: -5px;
left: 50%;
}
::v-deep .ol-tooltip-static:before {
border-top-color: #ffcc33;
}
//测面、测距的样式
::v-deep .tooltip-close-btn {
font-style: normal;
position: absolute;
color: #2d8cf0;
right: 0px;
top: -7px;
font-weight: bold;
font-size: 15px;
cursor: pointer;
&:hover {
color: #fff;
}
}
</style>
4.使用
1.向引入的页面引入measure.vue
import Measure from './components/Measure.vue'
2.使用
<Measure
:draw-line-map = "drawLineMap"
:draw-area-map = "drawAreaMap"
:clear-measure-map ="clearMeasureMap"
style="float: left;margin-left: 8px"
></Measure>
3.data(){
return{
drawLineMap: {},
drawAreaMap: {},
clearMeasureMap: {},
}
}
4.new Map()之后 this.drawLineMap=new Map()
5.成功