openlayers学习(七)量测距离和面积

本文介绍使用OpenLayers实现地图上的距离和面积测量。通过绘制线和多边形,自动计算并显示对应的地理距离和面积,支持不同单位的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现量测距离和面积

官网示例:https://openlayers.org/en/latest/examples/measure.html

1、初始化地图

var rootLayer = new ol.layer.Tile({
    source: new ol.source.XYZ({
        url: 'http://mt2.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=G'
    }) //加载谷歌影像地图
});

var view = new ol.View({
    center: [113, 23],
    projection: 'EPSG:3857',
    zoom: 10
});
map = new ol.Map({
    layers: [rootLayer],
    target: 'map',
    view: view
});

2、初始化绘图方法

var type = typeSelect.value == 'area' ? 'Polygon' : 'LineString';
draw = new ol.interaction.Draw({
    source: source,
    type: type
});
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;
    var output;
    if (geom instanceof ol.geom.Polygon) {
        var p=geom.clone();
        var circleIn4326 = p.transform(map.getView().getProjection(),'EPSG:3857');
        output = formatArea(circleIn4326);
    } else if (geom instanceof ol.geom.LineString) {
        var p=geom.clone();
        var circleIn4326 = p.transform(map.getView().getProjection(),'EPSG:3857');
        output = formatLength(circleIn4326);
    }
    document.getElementById('label').innerText=output;
   });
});

draw.on('drawend', function () {
    sketch = null;
    ol.Observable.unByKey(listener);
});

3、量测面积函数

var formatArea = function (polygon) {

    var area = ol.sphere.getArea(polygon);
    var 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;
};

4、量测距离的方法

var formatLength = function (line) {
    var length = ol.sphere.getLength(line);
    var output;
    if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
    } else {
        output = Math.round(length * 100) / 100 + ' ' + 'm';
    }
    return output;
};

效果如下

量距离

量面积

完整代码如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Draw Shapes</title>
    <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
    <script src="https://unpkg.com/elm-pep"></script>
    <style>
        .map {
            width: 100%;
            height: 400px;
        }
    </style>
    <link rel="stylesheet" href="../../lib/openlayerv6.4.3/css/ol.css">
    <script src="../../lib/openlayerv6.4.3/build/ol.js"></script>
</head>
<script>
    var map;
    var typeSelect;
    var draw; // global so we can remove it later
    var source;


    function init() {
        var rootLayer = new ol.layer.Tile({
            source: new ol.source.XYZ({
                url: 'http://mt2.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=G'
            }) //加载谷歌影像地图
        });

        var view = new ol.View({
            center: [113, 23],
            projection: 'EPSG:4326',
            zoom: 10
        });
        map = new ol.Map({
            layers: [rootLayer],
            target: 'map',
            view: view
        });

        source = new ol.source.Vector({wrapX: false});

        var vector = new ol.layer.Vector({
            source: source,
        });
        map.addLayer(vector);
        typeSelect = document.getElementById('type');

        /**
         * Handle change event.
         */
        typeSelect.onchange = function () {
            map.removeInteraction(draw);
            addInteraction();
        };

        addInteraction();
    }

    var type;
    var df;
    var sketch;

    function addInteraction() {
        var type = typeSelect.value == 'area' ? 'Polygon' : 'LineString';
        draw = new ol.interaction.Draw({
            source: source,
            type: type
        });
        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;
                var output;
                if (geom instanceof ol.geom.Polygon) {
                    var p=geom.clone();
                    var circleIn4326 = p.transform(map.getView().getProjection(),'EPSG:3857');
                    output = formatArea(circleIn4326);
                } else if (geom instanceof ol.geom.LineString) {
                    var p=geom.clone();
                    var circleIn4326 = p.transform(map.getView().getProjection(),'EPSG:3857');
                    output = formatLength(circleIn4326);
                }
                document.getElementById('label').innerText=output;
            });
        });

        draw.on('drawend', function () {
            sketch = null;
            ol.Observable.unByKey(listener);
        });

    }

    /**
     * Format area output.
     * @param {Polygon} polygon The polygon.
     * @return {string} Formatted area.
     */
    var formatArea = function (polygon) {

        var area = ol.sphere.getArea(polygon);
        var 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;
    };

    var formatLength = function (line) {
        var length = ol.sphere.getLength(line);
        var output;
        if (length > 100) {
            output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
        } else {
            output = Math.round(length * 100) / 100 + ' ' + 'm';
        }
        return output;
    };
</script>
<body οnlοad="init()">
<div id="map" class="map"></div>
<form class="form-inline">
    <label>Shape type &nbsp;</label>
    <select id="type">
        <option value="length">Length (LineString)</option>
        <option value="area">Area (Polygon)</option>
    </select>
</form>
<label id="label"></label>
</body>
</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值