<template>
<div class="measure-tools" style="display: flex; flex-direction: column">
<div class="menu-box" @click="measure('distance')">
<i class="tool tool-distance"></i>
<span> 测距 </span>
</div>
<div class="menu-box" @click="measure('area')">
<i class="tool tool-area"></i>
<span> 测面 </span>
</div>
</div>
</template>
<script>
// import { length, area } from "@turf";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer } from "ol/layer";
// import GeoJSON from "ol/format/GeoJSON";
import { Draw } from "ol/interaction";
// import Point from "ol/geom/Point";
import { unByKey } from "ol/Observable.js";
import Overlay from "ol/Overlay";
// import { Feature } from "ol";
// import {
// getArea,
// getLength
// } from 'ol/sphere.js';
import { getLength } from "ol/sphere";
import { getArea } from "ol/sphere";
import LineString from "ol/geom/LineString";
import Polygon from "ol/geom/Polygon";
import DoubleClickZoom from "ol/interaction/DoubleClickZoom";
import tMessager from '@/entries/bus.ts'
import { Circle as CircleStyle, Fill, Stroke, Style } from "ol/style.js";
let piemap;
let helpTooltipElement;
export default {
name: "measure-tools",
data() {
return {
drawInteraction: null,
renderLayer: null,
};
},
props: ["parentRef", "clear"],
components: {},
mounted() {
// 此处传过来的val指的是map
tMessager.$on('getMap',(val)=>{
piemap = val
})
},
computed: {},
watch: {
clear: {
handler(newIndex) {
console.log(newIndex,'newIndex');
if (newIndex) {
this.clearMeasure();
}
},
},
},
methods: {
measure(measureType) {
let that = this;
let drawLayer = this.getLayer("lineAndArea");
if (this.drawInteraction != null) {
piemap.removeInteraction(this.drawInteraction);
}
let vector = null;
let source = null;
if (drawLayer != null) {
vector = drawLayer;
source = drawLayer.getSource();
} else {
source = new VectorSource();
vector = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "rgba(255, 0, 0, 0.5)",
lineDash: [10, 10],
width: 2,
}),
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
zIndex: 16,
});
vector.set("id", "lineAndArea");
piemap.addLayer(vector);
}
/**
* Currently drawn feature.
* @type {module:ol/Feature~Feature}
*/
let sketch;
/**
* The help tooltip element.
* @type {Element}
*/
// let helpTooltipElement;
/**
* Overlay to show the help messages.
* @type {module:ol/Overlay}
*/
let helpTooltip;
/**
* The measure tooltip element.
* @type {Element}
*/
let measureTooltipElement;
/**
* Overlay to show the measurement.
* @type {module:ol/Overlay}
*/
let measureTooltip;
/**
* Message to show when the user-manger is drawing a polygon.
* @type {string}
*/
let continuePolygonMsg = "";
/**
* Message to show when the user-manger is drawing a line.
* @type {string}
*/
let continueLineMsg = "";
createMeasureTooltip();
createHelpTooltip();
/**
* Handle pointer move.
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
*/
let pointerMoveHandler = function (evt) {
if (evt.dragging) {
return;
}
/** @type {string} */
let helpMsg = "请点击开始绘制";
if (sketch) {
let geom = sketch.getGeometry();
if (geom instanceof Polygon) {
helpMsg = continuePolygonMsg;
} else if (geom instanceof LineString) {
helpMsg = continueLineMsg;
}
}
helpTooltipElement.innerHTML = helpMsg;
helpTooltip.setPosition(evt.coordinate);
helpTooltipElement.classList.remove("hidden");
};
piemap.on("pointermove", pointerMoveHandler);
piemap.getViewport().addEventListener("mouseout", function () {
if (helpTooltipElement) {
helpTooltipElement.classList.add("hidden");
}
});
let formatLength = function (line) {
//获取投影坐标系
let sourceProj = piemap.getView().getProjection();
//ol/sphere里有getLength()和getArea()用来测量距离和区域面积,默认的投影坐标系是EPSG:3857, 其中有个options的参数,可以设置投影坐标系
let length = getLength(line, { projection: sourceProj });
//let length = getLength(line);
let output;
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + " " + "km";
} else {
output = Math.round(length * 100) / 100 + " " + "m";
}
return output;
};
let formatArea = function (polygon) {
//获取投影坐标系
let sourceProj = piemap.getView().getProjection();
let area = getArea(polygon, { projection: sourceProj });
//let area = getArea(polygon);
//console.info(area)
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;
};
function addInteraction() {
let type = measureType == "area" ? "Polygon" : "LineString";
that.drawInteraction = new Draw({
source: source,
type: type,
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)",
}),
}),
}),
});
piemap.addInteraction(that.drawInteraction);
let listener;
that.drawInteraction.on(
"drawstart",
function (evt) {
// set sketch
sketch = evt.feature;
//禁用双击放大功能
disableMapDoubleClickZoom();
/** @type {module:ol/coordinate~Coordinate|undefined} */
var tooltipCoord = evt.coordinate;
listener = sketch.getGeometry().on("change", function (evt) {
var geom = evt.target;
var output;
if (geom instanceof Polygon) {
output = formatArea(geom);
tooltipCoord = geom.getInteriorPoint().getCoordinates();
} else if (geom instanceof LineString) {
output = formatLength(geom);
tooltipCoord = geom.getLastCoordinate();
}
measureTooltipElement.innerHTML = output;
measureTooltip.setPosition(tooltipCoord);
});
},
this
);
that.drawInteraction.on(
"drawend",
function (event) {
//打开双击放大功能
measureTooltipElement.className = "tooltip tooltip-static";
measureTooltip.setOffset([0, -7]);
// unset sketch
sketch = null;
// unset tooltip so that a new one can be created
measureTooltipElement = null;
createMeasureTooltip();
unByKey(listener);
piemap.un("pointermove", pointerMoveHandler);
piemap.removeInteraction(that.drawInteraction);
helpTooltipElement.classList.add("hidden");
//地图双击事件
piemap.once("dblclick", addLastPoint);
if (measureTooltipElement) {
helpTooltipElement.parentNode.removeChild(helpTooltipElement);
helpTooltipElement = null;
}
},
this
);
}
function createHelpTooltip() {
if (helpTooltipElement) {
helpTooltipElement.parentNode.removeChild(helpTooltipElement);
}
helpTooltipElement = document.createElement("div");
helpTooltipElement.className = "tooltip hidden";
helpTooltip = new Overlay({
element: helpTooltipElement,
offset: [15, 0],
positioning: "center-left",
});
piemap.addOverlay(helpTooltip);
}
function createMeasureTooltip() {
if (measureTooltipElement) {
measureTooltipElement.parentNode.removeChild(measureTooltipElement);
}
measureTooltipElement = document.createElement("div");
measureTooltipElement.className = "tooltip tooltip-measure";
measureTooltip = new Overlay({
element: measureTooltipElement,
offset: [0, -15],
positioning: "bottom-center",
});
piemap.addOverlay(measureTooltip);
}
function disableMapDoubleClickZoom() {
const dblClickInteraction = piemap
.getInteractions()
.getArray()
.find((interaction) => {
return interaction instanceof DoubleClickZoom;
});
if (dblClickInteraction) {
piemap.removeInteraction(dblClickInteraction);
}
}
function enableMapDoubleClickZoom() {
let dblClickInteraction = new DoubleClickZoom();
piemap.addInteraction(dblClickInteraction);
}
function addLastPoint(event) {
event.stopPropagation();
enableMapDoubleClickZoom();
}
// 量测调用
addInteraction();
//绘制结束
},
// 清除测距、测面标绘内容
clearMeasure() {
console.log(piemap,'piemap');
const layers = piemap.getLayers().getArray()
const layer = layers.filter((item, index) => item.values_.id && item.values_.id === 'shuixi' || item.values_.id === 'xingzheng'|| item.values_.id === 'shuiku1'|| item.values_.id === 'shuiku2'|| item.values_.id === 'shuizha'|| item.values_.id === 'difang'|| item.values_.id === 'shuiwen'|| item.values_.id === 'yuliang'|| item.values_.id === 'xingbian'|| item.values_.id === 'shenya'|| item.values_.id === 'shipin' || item.values_.id === 'lineAndArea')
console.log(layers,'layers');
console.log(layer,'layer');
if(layer.length > 0){
layer.forEach((item) => {
item.getSource().clear();
piemap.removeLayer(item)
piemap.getOverlays().clear();
if (this.drawInteraction != null) {
piemap.removeInteraction(this.drawInteraction);
}
this.$emit('clearChange')
})
}else {
this.$emit('clearChange')
}
// let drawLayer = this.getLayer("lineAndArea");
// if (drawLayer) {
// drawLayer.getSource().clear();
// piemap.removeLayer(drawLayer);
// piemap.getOverlays().clear(); //清除覆盖对象
// if (this.drawInteraction != null) {
// piemap.removeInteraction(this.drawInteraction);
// }
// }
},
getLayer(layerId) {
console.log("woyaokaishihuale");
for (let layerTmp of piemap.getLayers().getArray()) {
if (layerTmp.get("id") == layerId) {
return layerTmp;
}
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.measure-tools {
.menu-box {
&:first-child{
margin-top: 0;
}
margin-top: 24px;
width: 76px;
height: 16px;
line-height: 20px;
text-align: center;
box-sizing: border-box;
cursor: pointer;
span {
display: inline-block;
height: 20px;
line-height: 20px;
font-size: 14px;
color: #666666;
margin-left: 3px;
}
.tool {
display: inline-block;
width: 16px;
height: 16px;
vertical-align: middle;
&.tool-distance {
background: url("/src/assets/img/image/tc1.png")
no-repeat;
background-size: 100%;
}
&.tool-area {
background: url("/src/assets/img/image/gj1.png")
no-repeat;
background-size: 100%;
}
}
}
}
:deep .hidden {
display: none;
}
</style>
<style>
.hidden {
display: none;
}
</style>
在页面内使用
<template>
<!-- 清除测距按钮 -->
<div>
<div class="menu-box" style="border-right:none" @click="clearMeasure" :class="{active:curIndex==3}" id="p3">
<i class="tool tool-qingchu"></i>
<span> 清除 </span>
</div>
</div>
<!-- 测距、测面工具 -->
<measure-tools :clear="clear" @clearChange="clearChange"></measure-tools>
</template>
import MeasureTools from "./MeasureTools.vue";
export default {
components: { MeasureTools },
data(){
return {
clear: false,
}
},
methods:{
clearChange(){
this.clear = false
},
// 清除测距、测面标绘内容
clearMeasure() {
this.curIndex=3;
this.clear = true;
this.$nextTick(()=>{
this.$refs.tree.setCheckedKeys([]);
})
},
}
}