【Day09】Openlayers从入门到微精通 - 动动你的手来量测地球2

https://openlayers.org/en/latest/examples/measure-style.html

控制测量工具Day08是透过overlay来标记,所以可以用css控制
本篇是透过feature style来控制显示的样式

HTML

只有新增控制label的checkbox开关

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"></script>    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css">    <link rel="stylesheet" href="style.css"></head><body>    <div id="map"></div>    // 开关    <label for="segments" id="segments-label">        <input type="checkbox" id="segments" checked />        隐藏或开启label    </label>    <script type="module" src="./main.js"></script></body></html>

CSS

html,body {    margin: 0;    padding: 0;}#map {    width: 100vw;    height: 100vh;}#segments-label {    position: absolute;    top: 10px;    right: 10px;}

JS

特别注意styleFunction中是如何控制点的显示,通篇重点我认为应该是这个funciton的理解,其余都只是针对样式或颜色的配置

const style = new ol.style.Style({    fill: new ol.style.Fill({        color: 'rgba(255, 255, 255, 0.2)',    }),    stroke: new ol.style.Stroke({        color: 'rgba(0, 0, 0, 0.5)',        lineDash: [10, 10],        width: 2,    }),    image: new ol.style.Circle({        radius: 5,        stroke: new ol.style.Stroke({            color: 'rgba(0, 0, 0, 0.7)',        }),        fill: new ol.style.Fill({            color: 'rgba(255, 255, 255, 0.2)',        }),    }),});const labelStyle = new ol.style.Style({    text: new ol.style.Text({        font: '25px Calibri,sans-serif',        fill: new ol.style.Fill({            color: 'rgba(255, 255, 255, 1)',        }),        backgroundFill: new ol.style.Fill({            color: 'rgba(0, 0, 0, 0.7)',        }),        padding: [3, 3, 3, 3],        textBaseline: 'bottom',        offsetY: -15,    }),    image: new ol.style.RegularShape({        radius: 8,        points: 3,        angle: Math.PI,        displacement: [0, 10],        fill: new ol.style.Fill({            color: 'rgba(0, 0, 0, 0.7)',        }),    }),});const segmentStyle = new ol.style.Style({    text: new ol.style.Text({        font: '20px Calibri,sans-serif',        fill: new ol.style.Fill({            color: 'rgba(255, 255, 255, 1)',        }),        backgroundFill: new ol.style.Fill({            color: 'rgba(0, 0, 0, 0.4)',        }),        padding: [2, 2, 2, 2],        textBaseline: 'bottom',        offsetY: -12,    }),    image: new ol.style.RegularShape({        radius: 6,        points: 3,        angle: Math.PI,        displacement: [0, 8],        fill: new ol.style.Fill({            color: 'rgba(0, 0, 0, 0.4)',        }),    }),});const segmentStyles = [segmentStyle];const formatLength = function (line) {    const length = ol.sphere.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 source = new ol.source.Vector();function styleFunction(feature, segments, drawType) {    const styles = [];    const geometry = feature.getGeometry();    const type = geometry.getType();    let point, label, line;    if (!drawType || drawType === type || type === 'Point') {        styles.push(style);        if (type === 'LineString') {            point = new ol.geom.Point(geometry.getLastCoordinate());            label = formatLength(geometry);            line = geometry;        }    }    // 线段中间    if (segments && line) {        let count = 0;        //不断计算线段长度        line.forEachSegment(function (a, b) {            const segment = new ol.geom.LineString([a, b]);            const label = formatLength(segment);            if (segmentStyles.length - 1 < count) {                segmentStyles.push(segmentStyle.clone());            }            const segmentPoint = new ol.geom.Point(segment.getCoordinateAt(0.5)); // 指定线段中间的位置标记            segmentStyles[count].setGeometry(segmentPoint);            segmentStyles[count].getText().setText(label);            styles.push(segmentStyles[count]);            count++;        });    }    // 最后一点的位置标记    if (label) {        labelStyle.setGeometry(point);        labelStyle.getText().setText(label);        styles.push(labelStyle);    }    return styles;}const vector = new ol.layer.Vector({    source: source,    style: function (feature) {        return styleFunction(feature, showSegments.checked);    },});const map = new ol.Map({    layers: [        new ol.layer.Tile({            source: new ol.source.OSM()        }),        vector    ],    target: 'map',    view: new ol.View({        projection: "EPSG:3857",        center: ol.proj.fromLonLat([120.846642, 23.488793]),        zoom: 7.5,        maxZoom: 20,        minZoom: 5,        enableRotation: false,    }),    controls: []});let draw; // global so we can remove it laterfunction addInteraction() {    const drawType = 'LineString';    draw = new ol.interaction.Draw({        source: source,        type: drawType,        style: function (feature) {            return styleFunction(feature, showSegments.checked, drawType);        },    });    draw.on('drawstart', function () {        source.clear();    });    map.addInteraction(draw);}addInteraction();const showSegments = document.getElementById('segments');showSegments.onchange = function () {    vector.changed();    draw.getOverlay().changed();};

如果成功右上可以看到控制开关,自己玩玩看吧,成果如下图
http://img2.58codes.com/2024/20165487fhGJ6C8swl.png

结论

依据这两天的操作,我们可以学到两种控制的方式

Overlay放置点这不只是可以应用在这种显示,因为是HTML的格式,所以只要与HTML有关的我们都可以操作style function可以深度控制样式,不过缺点是需要去爬API到底提供哪种参数可以使用

我个人更喜欢第二种透过style function控制,因这样可以让我们的样式更自由。

参考

https://github.com/weijung0923/learning-openlayers-micromastery/tree/day09


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章