效果展示

代码
<template>
<div>
<div style="margin-bottom: 20px">
<el-select v-model="type" placeholder="请选择" @change="changType">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div id="Measure" class="dynamic-component-demo"></div>
</div>
</template>
<script>
import { getArea, getLength } from "ol/sphere";
const formatLength = function (line) {
const 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;
};
const formatArea = function (polygon) {
const area = getArea(polygon);
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;
};
import Map from "ol/Map";
import View from "ol/View";
import { transform } from "ol/proj";
import Overlay from "ol/Overlay";
import { gaodeMapLayer } from "@/utils/MapLayer.js";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer } from "ol/layer";
import { Circle, Fill, Stroke, Style } from "ol/style";
import { unByKey } from "ol/Observable";
import Draw from "ol/interaction/Draw";
import { LineString, Polygon } from "ol/geom";
export default {
name: "Measure",
data() {
return {
type: "LineString",
options: [
{ label: "周长", value: "LineString" },
{ label: "面积", value: "Polygon" },
],
map: null,
vector: null,
sketch: null,
helpTooltipElement: null,
draw: null,
listener: null,
measureTooltip: null,
measureTooltipElement: null,
source: new VectorSource(),
continueLineMsg: "Click to continue drawing the line",
continuePolygonMsg: "Click to continue drawing the polygon",
};
},
mounted() {
this._initMap();
},
methods: {
changType(val) {
let { draw, map } = this;
map.removeInteraction(draw);
this.addInteraction(map);
},
_initMap() {
const vector = new VectorLayer({
source: this.source,
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "#409eff",
width: 5,
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: "#409eff",
}),
}),
}),
});
const map = new Map({
layers: [gaodeMapLayer, vector],
view: new View({
center: transform([104.06, 30.67], "EPSG:4326", "EPSG:3857"),
zoom: 9,
minZoom: 1,
maxZoom: 21,
rotation: 0,
}),
target: "Measure",
});
this.createMeasureTooltip(map);
this.createHelpTooltip(map);
this.addInteraction(map);
map.on("pointermove", this.pointerMoveHandler);
map.getViewport().addEventListener("mouseout", () => {
this.helpTooltipElement.classList.add("hidden");
});
this.map = map;
},
createMeasureTooltip(map) {
let { measureTooltipElement } = this;
if (measureTooltipElement) {
measureTooltipElement.parentNode.removeChild(measureTooltipElement);
}
let measure_tooltip_element = document.createElement("div");
measure_tooltip_element.className = "ol-tooltip ol-tooltip-measure";
let measure_tool_tip = new Overlay({
element: measure_tooltip_element,
offset: [0, -15],
positioning: "bottom-center",
stopEvent: false,
insertFirst: false,
});
this.measureTooltipElement = measure_tooltip_element;
this.measureTooltip = measure_tool_tip;
console.log(this.measureTooltipElement, "createMeasureTooltip");
map.addOverlay(measure_tool_tip);
},
createHelpTooltip(map) {
if (this.helpTooltipElement) {
this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
}
let help_tooltip_element = document.createElement("div");
help_tooltip_element.className = "ol-tooltip hidden";
let help_tool_tip = new Overlay({
element: help_tooltip_element,
offset: [15, 0],
positioning: "center-left",
});
this.helpTooltipElement = help_tooltip_element;
this.helpTooltip = help_tool_tip;
map.addOverlay(help_tool_tip);
},
addInteraction(map) {
let _this = this;
const draw = new Draw({
source: this.source,
type: this.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 Circle({
radius: 5,
stroke: new Stroke({
color: "rgba(255, 0, 0, 0.9)",
}),
fill: new Fill({
color: "rgba(0, 0, 0, 0)",
}),
}),
}),
});
draw.on("drawstart", (evt) => {
_this.sketch = evt.feature;
let tooltipCoord = evt.coordinate;
_this.listener = _this.sketch
.getGeometry()
.on("change", function (evt) {
const geom = evt.target;
let output;
if (geom instanceof Polygon) {
output = formatArea(geom);
tooltipCoord = geom.getInteriorPoint().getCoordinates();
} else if (geom instanceof LineString) {
output = formatLength(geom);
tooltipCoord = geom.getLastCoordinate();
}
_this.measureTooltipElement.innerHTML = output;
_this.measureTooltip.setPosition(tooltipCoord);
});
});
draw.on("drawend", () => {
_this.measureTooltipElement.className = "ol-tooltip ol-tooltip-static";
_this.measureTooltip.setOffset([0, -7]);
_this.sketch = null;
_this.measureTooltipElement = null;
_this.createMeasureTooltip(map);
unByKey(_this.listener);
});
map.addInteraction(draw);
this.draw = draw;
},
pointerMoveHandler(evt) {
if (evt.dragging) {
console.log("拖到地图的时候");
return;
}
let helpMsg = "Click to start drawing";
if (this.sketch) {
const geom = this.sketch.getGeometry();
if (geom instanceof Polygon) {
helpMsg = this.continuePolygonMsg;
} else if (geom instanceof LineString) {
helpMsg = this.continueLineMsg;
}
}
this.helpTooltipElement.innerHTML = helpMsg;
this.helpTooltip.setPosition(evt.coordinate);
this.helpTooltipElement.classList.remove("hidden");
},
},
};
</script>
<style>
.ol-tooltip {
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 4px;
color: white;
padding: 4px 8px;
opacity: 0.7;
white-space: nowrap;
font-size: 12px;
cursor: default;
user-select: none;
}
.ol-tooltip-measure {
opacity: 1;
font-weight: bold;
}
.ol-tooltip-static {
background-color: #409eff;
color: #fff;
font-weight: bolder;
border: 1px solid white;
opacity: 1;
}
.ol-tooltip-measure:before,
.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: -7px;
left: 50%;
}
.ol-tooltip-static:before {
border-top-color: #409eff;
}
</style>