Openlayers 教程 - 通过 Feature(polygon)创建网格图层

2023-12-20 13:51:38

Openlayers 教程 - 通过 Feature(polygon)创建网格图层

本文介绍以下,根据多边形数据创建网格图层,一般应用于公里网格。

本文包括核心代码、完整代码以及在线示例。


核心代码

网格图层最开始通过循环实现,但是效果不太好,这里通过 turf 实现:


// 网格参数
let options = {
    // 单位
    units: 'kilometers',
    // 网格数据范围
    mask: JSON.parse(getGeoJsonByFeature(feature)),
};

// 创建网格数据
let squareGrid = turf.squareGrid(
    // 网格范围
    feature.getGeometry().getExtent(),
    // 网格边长
    0.1,
    options);

let features = getFeatureByGeoJson(squareGrid);

networkLayer.getSource().addFeatures(features);

// 创建一个选择交互实例
const selectInteraction = new ol.interaction.Select({
    // 设置触发选择的事件条件为点击事件
    condition: ol.events.condition.pointerMove,
    // 设置图层
    layers: [networkLayer],
});

// 将选择交互添加到地图实例中
map.addInteraction(selectInteraction);



完整代码:


<html lang="en">
<head>
    <meta charSet="utf-8">
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
    <style>
        /* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
        .map {
            height: 400px;
            width: 100%;
            float: left;
        }
    </style>
    <!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
    <script src="http://openlayers.vip/examples/resources/ol.js"></script>
    <script src="./turf.min.js"></script>
    <script src="./tiandituLayers.js"></script>
    <title>OpenLayers example</title>
    <script>
        var _hmt = _hmt || [];
        (function () {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>
<body>
<h2>OpenLayers feature grid</h2>
<!--地图容器,需要指定 id -->
<div id="map" className="map"></div>
<script type="text/javascript">
    var map = new ol.Map({
        // 地图容器
        target: 'map',
        // 地图图层,比如底图、矢量图等
        layers: [
            getIMG_CLayer(),
            getIBO_CLayer(),
            getCIA_CLayer(),
        ],
        // 地图视野
        view: new ol.View({
            projection: "EPSG:4326",
            // 定位
            center: [115.67724700667199, 37.73879478106912],
            // 缩放
            zoom: 6,
            maxZoom: 18,
            minZoom: 1,
        })
    });

    // 获取颜色
    function getStyle(color = '#00ffff') {
        return new ol.style.Style({
            //边框样式
            stroke: new ol.style.Stroke({
                color: color,
                width: 2,
            }),
            //填充样式
            fill: new ol.style.Fill({
                color: 'rgba(0, 0, 255, 0.2)',
            }),
        })
    }

    // 初始化图层
    var layer = initVectorLayer();

    //创建网格图层
    const networkLayer = initVectorLayer();

    networkLayer.setStyle(getStyle('#ffffff'))

    // 初始默认数据
    let polygon = "POLYGON((116.26201501649226 40.00016773213365,116.26416078370417 39.99651992787339,116.26690736573542 39.996734504594585,116.26785150330866 39.99639118184068,116.26973977845515 39.99712074269273,116.27313009064997 39.99733531941392,116.27416005891169 39.99518955220201,116.27476087373103 39.991241340532085,116.27321592133845 39.98909557332017,116.27188554566706 39.984975700273296,116.27201429169978 39.98334491719224,116.27437463563288 39.980469589128276,116.27317300599421 39.97986877430894,116.27072683137263 39.979997520341655,116.26828065675105 39.98132789601304,116.26471868317927 39.981499557389995,116.26227250855769 39.983774070634624,116.259268434461 39.98484695424058,116.25707975190485 39.98716438282945,116.25429025452937 39.99111259449937,116.25729432862605 39.99488914479234,116.25883928101862 39.99690616597154,116.26201501649226 40.00016773213365))";

    let feature = getFeatureByWKT(polygon);

    layer.getSource().addFeature(feature);

    map.getView().fit(layer.getSource().getExtent(), {
        duration: 1,//动画的持续时间,
        callback: null,
    });

    /**
     * @todo 矢量图层
     * @returns {VectorLayer}
     * @constructor
     */
    function initVectorLayer() {
        //实例化一个矢量图层Vector作为绘制层
        let source = new ol.source.Vector();
        //创建一个图层
        let customVectorLayer = new ol.layer.Vector({
            source: source,
            zIndex: 2,
            //设置样式
            style: getStyle(),
        });
        //将绘制层添加到地图容器中
        map.addLayer(customVectorLayer);

        return customVectorLayer;
    }

    /**
     * @todo wkt格式数据转化成图形对象
     * @param {string} wkt   "POINT(112.7197265625,39.18164062499999)" 格式数据
     * @param {string|Projection} sourceCode 源投影坐标系
     * @param {string|Projection} targetCode 目标投影坐标系
     * @returns {Feature}
     */
    function getFeatureByWKT(wkt, sourceCode, targetCode) {
        try {
            let view = map.getView();
            if (!wkt) {
                return null;
            }
            let format = new ol.format.WKT();

            let feature;

            feature = format.readFeature(wkt, {
                featureProjection: targetCode || view.getProjection(),
                dataProjection: sourceCode || view.getProjection(),
            });

            return feature;
        } catch (e) {
            console.log(e);
            return null;
        }
    }

    /**
     *  todo 通过feature获取geojson字符串
     * @param feature
     * @param code
     * @param sourceCode
     * @returns {null|*}
     */
    function getGeoJsonByFeature(feature, sourceCode, targetCode) {

        if (!feature) {
            return null;
        }

        let view = map.getView();

        let geojson;

        if (feature instanceof Array) {

            geojson = (new ol.format.GeoJSON()).writeFeatures(feature, {
                dataProjection: sourceCode || view.getProjection(),    // 设定JSON数据使用的坐标系
                featureProjection: targetCode || view.getProjection() // 设定当前地图使用的feature的坐标系
            });

        } else {

            geojson = (new ol.format.GeoJSON()).writeFeature(feature, {
                dataProjection: sourceCode || view.getProjection(),    // 设定JSON数据使用的坐标系
                featureProjection: targetCode || view.getProjection() // 设定当前地图使用的feature的坐标系
            });
        }

        return geojson;
    }

    /**
     * @todo 图形对象转化成GeoJson格式数据(postgis)
     * @param {string|object} geojson geojson字符串或者对象
     * @param {string|Projection} sourceCode 源投影坐标系
     * @param {string|Projection} targetCode 目标投影坐标系
     * @returns {Feature}
     */
    function getFeatureByGeoJson(geojson, sourceCode, targetCode) {

        let view = map.getView();

        if (!geojson) {
            return null;
        }

        let feature;

        if ((typeof geojson) == 'string') {
            // 替换 null 字符
            while (geojson.indexOf('null') != -1) {
                // geojson = geojson
                geojson = geojson.replace("null", "");
            }
        }

        feature = (new ol.format.GeoJSON()).readFeatures(geojson, {
            dataProjection: sourceCode || view.getProjection(),    // 设定JSON数据使用的坐标系
            featureProjection: targetCode || view.getProjection() // 设定当前地图使用的feature的坐标系
        });

        return feature;
    }

    /**
     * todo 增加网格
     * @param feature wkt或者feature
     * @param unit 米
     */
    function addNetworkGrid() {

        // 网格参数
        let options = {
            // 单位
            units: 'kilometers',
            // 网格数据范围
            mask: JSON.parse(getGeoJsonByFeature(feature)),
        };

        // 创建网格数据
        let squareGrid = turf.squareGrid(
            // 网格范围
            feature.getGeometry().getExtent(),
            // 网格边长
            0.1,
            options);

        let features = getFeatureByGeoJson(squareGrid);

        networkLayer.getSource().addFeatures(features);

        // 创建一个选择交互实例
        const selectInteraction = new ol.interaction.Select({
            // 设置触发选择的事件条件为点击事件
            condition: ol.events.condition.pointerMove,
            // 设置图层
            layers: [networkLayer],
        });

        // 将选择交互添加到地图实例中
        map.addInteraction(selectInteraction);
    }

    // 还原样式
    function restore() {
        networkLayer.getSource().clear();
    }
</script>
<button id="unionFeature" onClick="addNetworkGrid()">创建网格</button>
<button id="restore" onClick="restore()">还原</button>
</body>
</html>


在线示例

在这里插入图片描述

在线示例:Openlayers 教程 - 多边形创建网格数据

文章来源:https://blog.csdn.net/linzi19900517/article/details/134913410
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。