01、vue+openlayers6实现自定义测量功能(提供源码)

首先先封装一些openlayers的工具函数,如下所示:

import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Style from 'ol/style/Style';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Circle from 'ol/style/Circle';
import Polygon from 'ol/geom/Polygon';
import LineString from 'ol/geom/LineString';
import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
import Text from 'ol/style/Text';
import { getLength } from 'ol/sphere';
import { getArea } from 'ol/sphere';
import Draw from 'ol/interaction/Draw';
import { unByKey } from 'ol/Observable';

let draw;
let drawSource;//定义绘制图层
let drawLayer;//定义绘制图层
let sketch;
let output = 0;
let lastPolygonLabelFeature; //记录上一个面标注要素
let lastLengthLabelFeature; //记录上一个点标注要素

// 初始化测量绘制图层
export function initDrawLayer(map) {
    drawSource = new VectorSource({
        crossOrigin: "anonymous",
    });
    drawLayer = new VectorLayer({
        source: drawSource,
        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",
                }),
            }),
        }),
    });
    map.addLayer(drawLayer);
    map.on("pointermove", function (evt) {
        if (evt.dragging) {
            return;
        }
        let Coord;
        if (sketch) {
            let geom = sketch.getGeometry();
            if (geom instanceof Polygon) {
                if (lastPolygonLabelFeature) {
                    // console.log(lastPolygonLabelFeature);
                    //  鼠标移动,不停的添加和删除
                    drawSource.removeFeature(
                        lastPolygonLabelFeature
                    );
                }
                Coord = geom.getInteriorPoint().getCoordinates();
                //新建一个要素ol.Feature
                lastPolygonLabelFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastPolygonLabelFeature.setStyle(
                    createLabelStyle(lastPolygonLabelFeature, 0, 0)
                );
                drawSource.addFeature(lastPolygonLabelFeature);
            } else if (geom instanceof LineString) {
                if (lastLengthLabelFeature) {
                    drawSource.removeFeature(
                        lastLengthLabelFeature
                    );
                }
                Coord = geom.getLastCoordinate();
                // 新建一个要素ol.Feature
                lastLengthLabelFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastLengthLabelFeature.setStyle(
                    createLabelStyle(lastLengthLabelFeature, 35, -10)
                );
                // 设置要素样式
                drawSource.addFeature(lastLengthLabelFeature);
            }

        }
    });
    map.on("click", function (evt) {
        let coordinate = evt.coordinate; //鼠标单击点的坐标
        // //console.log(coordinate);
        if (output == "0") {
            lastPolygonLabelFeature = null;
            if (lastLengthLabelFeature) {
                drawSource.removeFeature(lastLengthLabelFeature);
                lastLengthLabelFeature = null;
            }
            return;
        }
        var Coord;
        if (sketch) {
            var geom = sketch.getGeometry();
            if (geom instanceof Polygon) {
                if (lastPolygonLabelFeature) {
                    drawSource.removeFeature(
                        lastPolygonLabelFeature
                    );
                }
                Coord = geom.getInteriorPoint().getCoordinates();
                //新建一个要素ol.Feature
                var newFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastPolygonLabelFeature = newFeature;
                newFeature.setStyle(
                    createLabelStyle(newFeature, 0, 0)
                ); //设置要素样式
                drawSource.addFeature(newFeature);
            } else if (geom instanceof LineString) {
                Coord = geom.getLastCoordinate();
                //新建一个要素ol.Feature
                let newFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                newFeature.setStyle(
                    createLabelStyle(newFeature, 35, -10)
                ); //设置要素样式
                drawSource.addFeature(newFeature);
            }
            let pointFeature = new Feature({
                geometry: new Point(coordinate), //几何信息
                name: output,
            });
            drawSource.addFeature(pointFeature);
        }
    });
}

// 定义测量结果的显示的样式
function createLabelStyle(feature, offsetX, offsetY) {
    return new Style({
        text: new Text({
            textAlign: "center", //位置
            textBaseline: "middle", //基准线
            font: "normal 10px sans-serif", //文字样式
            text: feature.get("name"), //文本内容
            fill: new Fill({
                //文本填充样式(即文字颜色)
                color: "white",
            }),
            stroke: new Stroke({
                color: "black",
                width: 5,
            }),
            offsetX: offsetX,
            offsetY: offsetY,
        }),
    });
}

function formatLength(line) {
    let length = getLength(line, {
        projection: "EPSG:3857",
        radius: 6378137,
    });
    let output;
    if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + " " + "千米";
    } else {
        output = Math.round(length * 100) / 100 + " " + "米";
    }
    return output;
}

function formatArea(polygon) {
    var area = getArea(polygon, {
        projection: "EPSG:3857",
        radius: 6378137,
    });
    var output;
    if (area > 10000) {
        output =
            Math.round((area / 1000000) * 100) / 100 + " " + "平方公里";
    } else {
        output = Math.round(area * 100) / 100 + " " + "平方米";
    }
    return output;
}

function addInteraction(drawType, map) {
    let type = drawType == "area" ? "Polygon" : "LineString";
    draw = new Draw({
        source: drawSource,
        type: type,
        style: new Style({
            fill: new Fill({
                color: "rgba(255, 0, 0, 0.2)",
            }),
            stroke: new Stroke({
                color: "rgb(255,116,3)",
                width: 2,
            }),
            image: new Circle({
                radius: 5,
                stroke: new Stroke({
                    color: "rgba(255, 0, 0, 0.1)",
                }),
                fill: new Fill({
                    color: "rgba(255,116,3, 0.3)",
                }),
            }),
        }),
    });
    map.addInteraction(draw);
    var listener;
    draw.on(
        "drawstart",
        function (evt) {
            // set sketch
            sketch = evt.feature;
            listener = sketch
                .getGeometry()
                .on("change", function (evt) {
                    var geom = evt.target;
                    if (geom instanceof Polygon) {
                        output = formatArea(geom);
                    } else if (geom instanceof LineString) {
                        output = formatLength(geom);
                    }
                });
        }
    );
    draw.on(
        "drawend",
        function () {
            sketch = null;
            unByKey(listener);
            output = "0";
        }
    );
}

export function measureDistance(map) {
    if (draw) {
        map.removeInteraction(draw);
    }
    addInteraction("length", map);
}

export function measureArea(map) {
    if (draw) {
        map.removeInteraction(draw);
    }
    addInteraction("area", map);
}

export function measureClear(map) {
    map.removeInteraction(draw);
    drawLayer.setSource(null);
    drawSource = new VectorSource({
        crossOrigin: "anonymous",
    });
    drawLayer.setSource(drawSource);
    lastPolygonLabelFeature = null;
    lastLengthLabelFeature = null;
    sketch = null;
    output = "0";
}

export function interactionClear(map) {
    map.removeInteraction(draw);
}

然后再vue的组件中调用以上方法,代码如下:

在组件的monted中调用 initDrawLayer(map);方法

 //根据传入type值调用对应方法
         measure(type) {
            const that = this;
            
            if (type =="distance" ) {
                that.hideOverlay();
                measureDistance(window.map);
            }else  if (type =="area" ) {
                that.hideOverlay();
                measureArea(window.map);
            }else  if (type =="clear" ) {
                that.hideOverlay();
                measureClear(window.map);
            }
        }

最终实现效果如下:

源码地址连接:https://github.com/enjoyMaps/map_vue

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值