OpenLayers 调整标注样式

前言

要素标注是一个常用功能,就是将要素信息如名称等显示在地图上,方便查找和使用。在OpenLayers中要素标注很灵活,使用起来也很方便,可以修改标注样式以及标注权限。在本文中主要介绍如何修改文本放置样式和文字样式

1. 创建标注要素

在地图上创建三组点要素,第一组只设置textAlign文本框放置属性,其值有"start"、"end"、"left"、"right"、"center";第二组在第一组的基础上,设置justify属性,用于调整文本放置属性,其值有"left"、"center"、"right";第三组在第二组的基础上修改justify属性,观察文本样式变化。

css 复制代码
const features = [    // 第一组    {        geometry: new ol.geom.Point([94.11434654171987, 28.972402471968656]),
        textAlign: "left" // 标注文本框位于point右边,point右边是标注文本框
    }, {
        geometry: new ol.geom.Point([103.45228063165628, 28.972402471968656]),
        textAlign: "center" // 标注文本框位于point中心
    },
    {
        geometry: new ol.geom.Point([112.03997466732001, 28.972402471968656]),
        textAlign: "right" // 标注文本框位于point左边,point左边是标注文本框
    },

    // 第二组
    {
        geometry: new ol.geom.Point([94.11434654171987, 26.972402471968656]),
        textAlign: "left", // 文本对齐
        justify: "center" // 文本框内的文本对齐
    }, {
        geometry: new ol.geom.Point([103.45228063165628, 26.972402471968656]),
        textAlign: "center",
        justify: "center"
    },
    {
        geometry: new ol.geom.Point([112.03997466732001, 26.972402471968656]),
        textAlign: "right",
        justify: "center"
    },
    // 第三组
    {
        geometry: new ol.geom.Point([94.11434654171987, 24.972402471968656]),
        textAlign: "left",
        justify: "left"
    }, {
        geometry: new ol.geom.Point([103.45228063165628, 24.972402471968656]),
        textAlign: "center",
        justify: "left"
    },
    {
        geometry: new ol.geom.Point([112.03997466732001, 24.972402471968656]),
        textAlign: "right",
        justify: "left"
    },
]

2. 创建样式函数

创建样式函数设置标注文本框和文本样式,fill属性设置文本填充色,backgroundFill属性设置文本框背景颜色,backgroundStroke属性设置文本框线框颜色,padding属性设置文本框内边距。一些其他样式属性请参考:[https://openlayers.org/en/v9.2.4/apidoc/module-ol_style_Text-Text.html](https://openlayers.org/en/v9.2.4/apidoc/module-ol_style_Text-Text.html)

php 复制代码
function createStyle({ textAlign, justify }) {
    return new ol.style.Style({
        image: new ol.style.Circle({
            radius: 10, // 单位像素
            fill: new ol.style.Fill({
                color: "rgba(255, 0, 0, 0.1)"
            }),
            stroke: new ol.style.Stroke({
                color: "red",
                width: 1.5 // 单位像素
            })
        }),
        text: new ol.style.Text({
            font: '16px sans-serif',
            textAlign,
            justify,
            text: `Justify text inside boxntextAlign: ${textAlign}` +
                (justify ? `\njustify: ${justify}` : ''),
            fill: new ol.style.Fill({
                color: [148, 0, 211, 1],
            }),
            backgroundFill: new ol.style.Fill({
                color: [128, 0, 128, 0.25]
            }),
            // 设置边框边线色
            backgroundStroke: new ol.style.Stroke({
                color: [255, 182, 193, 0.5],
                width: 2.5,
                lineJoin: 'miter',
                lineCap: "round"
            }),
            padding: [10, 10, 10, 10], // 文本框内间距
            // offsetX: 100
        })
    })
}

3. 创建标注图层

根据点要素创建点图层并添加到地图中,然后调用setStyle方法设置要素样式进行标注。

php 复制代码
const vectorPoints = new ol.layer.Vector({
    source: new ol.source.Vector({
        features: new ol.Collection(
            features.map(featureOptions => {
                const feature = new ol.Feature({
                    geometry: featureOptions.geometry
                })
                // 设置要素样式
                feature.setStyle(createStyle(featureOptions))
                return feature
            })
        ),
        format: new ol.format.GeoJSON()
    })
})
map.addLayer(vectorPoints)

4. 完整代码

其中libs文件夹下的包需要更换为自己下载的本地包或者引用在线资源。本示例引用了layui组件,请自行替换。

xml 复制代码
<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>OpenLayers 要素标注</title>
    <meta charset="utf-8" />

    <link rel="stylesheet" href="../../css/ol9.2.4.css">
    <link rel="stylesheet" href="../../libs/layui/css/layui.css">

    <script src="../../js/config.js"></script>

    <script src="../../libs/js/proj4.js"></script>
    <script src="../../libs/js/ol9.2.4.js"></script>
    <script src="../../libs/layui/layui.js"></script>
    <script src="../../libs/js/geotiff.min.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 14px;
            font-family: '微软雅黑';
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }

        #map {
            position: absolute;
            top: 50px;
            bottom: 0;
            width: 100%;
        }

        #top-content {
            position: absolute;
            width: 100%;
            height: 50px;
            line-height: 50px;
            background: linear-gradient(135deg, #ff00cc, #ffcc00, #00ffcc, #ff0066);
            color: #fff;
            text-align: center;
            font-size: 32px;
        }

        #top-content span {
            font-size: 32px;
        }
    </style>
</head>

<body>
    <div id="top-content">
        <span>OpenLayers 要素标注</span>
    </div>
    <div id="map" title="地图显示"></div>
</body>

</html>

<script>
    //地图投影坐标系
    const projection = ol.proj.get('EPSG:3857');
    //==============================================================================//
    //============================天地图服务参数简单介绍==============================//
    //================================vec:矢量图层==================================//
    //================================img:影像图层==================================//
    //================================cva:注记图层==================================//
    //======================其中:_c表示经纬度投影,_w表示球面墨卡托投影================//
    //==============================================================================//
    const TDTImgLayer = new ol.layer.Tile({
        title: "天地图影像图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + TDTTOKEN,
            attibutions: "天地图影像描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const TDTImgCvaLayer = new ol.layer.Tile({
        title: "天地图影像注记图层",
        source: new ol.source.XYZ({
            url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=" + TDTTOKEN,
            attibutions: "天地图注记描述",
            crossOrigin: "anoymous",
            wrapX: false
        })
    })
    const map = new ol.Map({
        target: "map",
        loadTilesWhileInteracting: true,
        view: new ol.View({
            center: [102.845864, 25.421639],
            zoom: 6.5,
            worldsWrap: false,
            minZoom: 1,
            maxZoom: 20,
            projection: 'EPSG:4326',
        }),
        layers: [TDTImgLayer],
        // 地图默认控件
        controls: ol.control.defaults.defaults({
            zoom: false,
            attribution: true,
            rotate: true
        })
    })
    map.on('click', evt => {
        console.log("获取地图坐标:", evt.coordinate)
    })

    const features = [
        // 第一组
        {
            geometry: new ol.geom.Point([94.11434654171987, 28.972402471968656]),
            textAlign: "left" // 标注文本框位于point右边,point右边是标注文本框
        }, {
            geometry: new ol.geom.Point([103.45228063165628, 28.972402471968656]),
            textAlign: "center" // 标注文本框位于point中心
        },
        {
            geometry: new ol.geom.Point([112.03997466732001, 28.972402471968656]),
            textAlign: "right" // 标注文本框位于point左边,point左边是标注文本框
        },

        // 第二组
        {
            geometry: new ol.geom.Point([94.11434654171987, 26.972402471968656]),
            textAlign: "left", // 文本对齐
            justify: "center" // 文本框内的文本对齐
        }, {
            geometry: new ol.geom.Point([103.45228063165628, 26.972402471968656]),
            textAlign: "center",
            justify: "center"
        },
        {
            geometry: new ol.geom.Point([112.03997466732001, 26.972402471968656]),
            textAlign: "right",
            justify: "center"
        },
        // 第三组
        {
            geometry: new ol.geom.Point([94.11434654171987, 24.972402471968656]),
            textAlign: "left",
            justify: "left"
        }, {
            geometry: new ol.geom.Point([103.45228063165628, 24.972402471968656]),
            textAlign: "center",
            justify: "left"
        },
        {
            geometry: new ol.geom.Point([112.03997466732001, 24.972402471968656]),
            textAlign: "right",
            justify: "left"
        },
    ]

    function createStyle({ textAlign, justify }) {
        return new ol.style.Style({
            image: new ol.style.Circle({
                radius: 10, // 单位像素
                fill: new ol.style.Fill({
                    color: "rgba(255, 0, 0, 0.1)"
                }),
                stroke: new ol.style.Stroke({
                    color: "red",
                    width: 1.5 // 单位像素
                })
            }),
            text: new ol.style.Text({
                font: '16px sans-serif',
                textAlign,
                justify,
                text: `Justify text inside boxntextAlign: ${textAlign}` +
                    (justify ? `\njustify: ${justify}` : ''),
                fill: new ol.style.Fill({
                    color: [148, 0, 211, 1],
                }),
                backgroundFill: new ol.style.Fill({
                    color: [128, 0, 128, 0.25]
                }),
                // 设置边框边线色
                backgroundStroke: new ol.style.Stroke({
                    color: [255, 182, 193, 0.5],
                    width: 2.5,
                    lineJoin: 'miter',
                    lineCap: "round"
                }),
                padding: [10, 10, 10, 10], // 文本框内间距
                // offsetX: 100 // X方向偏移100px
            })
        })
    }
    const vectorPoints = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: new ol.Collection(
                features.map(featureOptions => {
                    const feature = new ol.Feature({
                        geometry: featureOptions.geometry
                    })
                    // 设置要素样式
                    feature.setStyle(createStyle(featureOptions))
                    return feature
                })
            ),
            format: new ol.format.GeoJSON()
        })
    })
    map.addLayer(vectorPoints)
</script>

OpenLayers示例数据下载,请回复关键字:ol数据

全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试

【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注 !

相关推荐
abigale039 分钟前
webpack+vite前端构建工具 -4webpack处理css & 5webpack处理资源文件
前端·css·webpack
500佰21 分钟前
如何开发Cursor
前端
InlaidHarp23 分钟前
Elpis DSL领域模型设计理念
前端
lichenyang45325 分钟前
react-route-dom@6
前端
番茄比较犟27 分钟前
widget的同级移动
前端
每天吃饭的羊31 分钟前
面试题-函数入参为interface类型进行约束
前端
屋外雨大,惊蛰出没1 小时前
Vue+spring boot前后端分离项目搭建---小白入门
前端·vue.js·spring boot
梦语花1 小时前
如何在前端项目中优雅地实现异步请求重试机制
前端
彬师傅1 小时前
JSAPITHREE-自定义瓦片服务加载
前端·javascript
番茄比较犟1 小时前
UI更新中Widget比较过程
前端