123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- <template>
- <div class="measure" v-drag="'.measure .ant-card-head'">
- <a-card v-show='value' title="测量" style="width: 284px; box-shadow: 0 0 5px #357ee5;">
- <a-icon slot="extra" type="close" style='cursor: pointer; color: #FFFFFF;' @click="$emit('input',false)"/>
- <a-radio-group v-model="type" @change="onChange">
- <a-radio value="LineString">
- <img src="../../../assets/MeasureTool16.png">
- 测量距离
- </a-radio>
- <a-radio value="Polygon">
- <img src="../../../assets/MeasureAreaTool16.png">
- 测量面积
- </a-radio>
- </a-radio-group>
- <div style="margin: 16px 0px;">
- <span class="ant-input-group-wrapper">
- <span class="ant-input-wrapper ant-input-group">
- <span class="ant-input-group-addon">测量结果:</span>
- <input type="text" style="cursor: text" v-model="output" readonly class="ant-input ant-input-disabled">
- </span>
- </span>
- </div>
- </a-card>
- </div>
- </template>
- <script>
- import 'ol/ol.css';
- import {Vector as VectorSource} from "ol/source";
- import {Vector as VectorLayer} from "ol/layer";
- import {Circle, Fill, Stroke, Style} from "ol/style";
- import {LineString, Polygon} from "ol/geom";
- import {getArea, getLength} from "ol/sphere";
- import {Draw} from "ol/interaction";
- import {unByKey} from "ol/Observable";
- import Overlay from "ol/Overlay";
- export default {
- name: 'measureTool',
- inject: ['baseMap'],
- mounted() {
- },
- data() {
- return {
- type: 'LineString',
- continuePolygonMsg: '单击继续绘制图形,双击结束',
- continueLineMsg: '单击继续绘制图形,双击结束',
- sketch: '',
- helpTooltipElement: '',
- helpTooltip: '',
- measureTooltipElement: '',
- measureTooltip: '',
- draw: '',
- source: '',
- vector: '',
- map: '',
- figure: ''
- }
- },
- props: {
- value: {
- type: Boolean,
- default: false,
- required: true
- },
- output: ''
- },
- methods: {
- onChange() {
- this.map = this.baseMap.map;
- // this.type = e.target.value;
- if (this.draw !== '') {
- this.map.removeInteraction(this.draw);
- }
- this.addInteraction();
- },
- initVectorLayer() {
- this.source = new VectorSource();
- this.vector = new VectorLayer({
- source: this.source,
- style: new Style({
- fill: new Fill({
- color: 'rgba(255, 255, 255, 0.2)',
- }),
- stroke: new Stroke({
- color: '#ffcc33',
- width: 2,
- }),
- image: new Circle({
- radius: 7,
- fill: new Fill({
- color: '#ffcc33',
- }),
- }),
- }),
- });
- this.map.addLayer(this.vector);
- },
- /**
- * 创建鼠标移动事件处理方案
- * */
- pointerMoveHandler(evt) {
- if (evt.dragging) {
- return;
- }
- /** @type {string} */
- let helpMsg = '单击开始绘制';
- 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');
- },
- /**
- * 初始化测量工具
- * */
- initMeasureTool() {
- this.map.on('pointermove', this.pointerMoveHandler);
- this.map.getViewport().addEventListener('mouseout', () => {
- this.helpTooltipElement.classList.add('hidden');
- });
- },
- /**
- * 关闭测量工具
- * */
- closeMeasureTool(theMap) {
- theMap.removeInteraction(this.draw);
- if (this.vector) {
- this.vector.getSource().clear();
- }
- debugger;
- },
- /**
- * 添加绘制交互
- * */
- addInteraction() {
- if (this.source === '' || this.vector === '') {
- this.initVectorLayer();
- }
- this.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(0, 0, 0, 0.7)',
- }),
- fill: new Fill({
- color: 'rgba(255, 255, 255, 0.2)',
- }),
- }),
- }),
- });
- this.map.addInteraction(this.draw);
- this.initMeasureTool();
- this.createMeasureTooltip();
- this.createHelpTooltip();
- let listener;
- this.draw.on('drawstart', (evt) => {
- this.sketch = evt.feature;
- /** @type {import("../src/ol/coordinate.js").Coordinate|undefined} */
- let tooltipCoord = evt.coordinate;
- listener = this.sketch.getGeometry().on('change', (evt) => {
- const geom = evt.target;
- if (geom instanceof Polygon) {
- this.figure = this.formatArea(geom);
- tooltipCoord = geom.getInteriorPoint().getCoordinates();
- } else if (geom instanceof LineString) {
- this.figure = this.formatLength(geom);
- tooltipCoord = geom.getLastCoordinate();
- }
- this.measureTooltipElement.innerHTML = this.figure;
- this.measureTooltip.setPosition(tooltipCoord);
- });
- });
- this.draw.on('drawend', () => {
- this.$emit('update:output', this.figure);
- this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
- this.measureTooltip.setOffset([0, -7]);
- // 清空sketch,这样就可以新建一个sketch
- this.sketch = null;
- this.measureTooltipElement = null;
- this.createMeasureTooltip();
- unByKey(listener);
- });
- },
- formatLength(line) {
- const length = getLength(line, {
- projection: "EPSG:4490"
- });
- let output;
- if (length > 1000) {
- output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
- } else {
- output = Math.round(length * 100) / 100 + ' ' + 'm';
- }
- return output;
- },
- formatArea(polygon) {
- const area = getArea(polygon, {
- projection: "EPSG:4490"
- });
- let output;
- if (area > 10000) {
- output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km²';
- } else {
- output = Math.round(area * 100) / 100 + ' ' + 'm²';
- }
- return output;
- },
- /**
- * 创建新的帮助提示
- */
- createHelpTooltip() {
- if (this.helpTooltipElement) {
- this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
- this.map.removeOverlay(this.map.getOverlayById('helpTooltip_overlay'));
- }
- this.helpTooltipElement = document.createElement('div');
- this.helpTooltipElement.className = 'ol-tooltip hidden';
- this.helpTooltip = new Overlay({
- id: 'helpTooltip_overlay',
- element: this.helpTooltipElement,
- offset: [15, 0],
- positioning: 'center-left',
- });
- this.map.addOverlay(this.helpTooltip);
- },
- /**
- * 创建新的测量提示
- */
- createMeasureTooltip() {
- if (this.measureTooltipElement) {
- this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
- this.map.removeOverlay(this.map.getOverlayById('measureTooltip_overlay'));
- }
- this.measureTooltipElement = document.createElement('div');
- this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
- this.measureTooltip = new Overlay({
- id: 'measureTooltip_overlay',
- element: this.measureTooltipElement,
- offset: [0, -15],
- positioning: 'bottom-center',
- stopEvent: false,
- insertFirst: false,
- });
- this.map.addOverlay(this.measureTooltip);
- },
- }
- }
- </script>
- <style>
- .ol-control button {
- background-color: rgba(24, 129, 253, 0.6);
- }
- .ol-control button:focus, .ol-control button:hover {
- text-decoration: none;
- background-color: rgba(24, 129, 253, .8)
- }
- .ol-scale-line {
- background-color: rgba(24, 129, 253, 0.6);
- }
- .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: #ffcc33;
- color: black;
- border: 1px solid white;
- }
- .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: #ffcc33;
- }
- </style>
|