e052bd5d26c3e0332844b9b21ef0bc1c.png

地图标注是将空间位置点与该点的信息相关联,通过图标、文字等形式把点相关的信息展现到地图上。

随便打开一个电子地图就可以看到许多标注:

0105c60487666957cd1cfff1690ad64e.png

可以说地图没有了标注就丧失了一半信息,甚至是全部信息!

地图标注的表现形式多样,包括简单的图片标注,文字标注,图文标注等。

OpenLayers可以使用ol.Feature类或者ol.Overlay类来实现标注。

一、使用ol.Feature类实现标注

1.1、使用ol.Feature类实现文字标注

使用ol.style.Style样式类为使用ol.Feature类创建的要素提供样式,这样就能构建出文字样式了。

示例一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用ol.Feature类实现文字标注</title>
    <link rel="stylesheet" href="../v5.3.0/css/ol.css" />
    <script src="../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 标注样式
        const labelStyle = new ol.style.Style({
            text: new ol.style.Text({
                font: 'bold 20px serif',
                text: '北京',
                fill: new ol.style.Fill({
                    color: 'rgba(255, 0, 0, 1)'
                })
            })
        });

        const vectorSource = new ol.source.Vector();
        const vectorLayer = new ol.layer.Vector({
            source: vectorSource
        });

        // 用于充当标注的要素
        let labelFeature = new ol.Feature({
            geometry: new ol.geom.Point([12956325,4851028])
        });
        // 设置标注的样式
        labelFeature.setStyle(labelStyle);
        // 将标注要素添加到矢量图层中
        vectorSource.addFeature(labelFeature);

        const map = new ol.Map({
            target: 'map',                          // 关联到对应的div容器
            layers: [
                new ol.layer.Tile({                 // 瓦片图层
                    source: new ol.source.Stamen({
                        layer: 'terrain'
                    })     
                }),
                vectorLayer
            ],
            view: new ol.View({                     // 地图视图
                projection: 'EPSG:3857',
                center: [0, 0],
                zoom: 0
            })
        });
    </script>
</body>
</html>

16700e5d8b19cb6cf7bbab6e857f30d2.png

通常从WebGIS服务器端传到前端的要素数据(GeoJSON,TopoJSON等),都包含要素的信息,比如地名,街道名等,可以读取这些信息然后作为文字标注渲染到地图上。

示例二:街道标注

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用ol.Feature类实现街道标注</title>
    <link rel="stylesheet" href="../v5.3.0/css/ol.css" />
    <script src="../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 街道标注的样式
        const style = new ol.style.Style({
            text: new ol.style.Text({
                font: 'bold 11px "Open Sans", "Arial Unicode MS", "sans-serif"',
                placement: 'line',
                fill: new ol.style.Fill({
                    color: 'white'
                })
            })
        });

        const map = new ol.Map({
            target: 'map',
            layers: [
                // 使用必应影像地图作为底图
                new ol.layer.Tile({
                    source: new ol.source.BingMaps({
                        key: 'AmMSiUpOokUvbXi9sfQbdzPJQqpZ-9ZTMPJ-0uhNsB8cF3H4RMVSSuh4CTTeh2yG',
                        imagerySet: 'Aerial'
                    })
                }),
                // 加载维也纳部分街道数据
                new ol.layer.Vector({
                    // declutter: true,
                    source: new ol.source.Vector({
                        format: new ol.format.GeoJSON(),
                        url: 'vienna-streets.geojson'
                    }),
                    style: function(feature){       // 遍历每个要素并为其设置标注
                        style.getText().setText(feature.get('name'));
                        return style;
                    }
                })
            ],
            view: new ol.View({
                extent: [1817379, 6139595, 1827851, 6143616],   // 视图范围
                center: ol.extent.getCenter([1817379, 6139595, 1827851, 6143616]),
                zoom: 17,
                minZoom: 14
            })
        });
    </script>
</body>
</html>

效果:

3e976912c605f5c0c472246f8b6ee92c.png

关于要素文字标注的更多信息可以参考这个官方示例:

Vector Labels​openlayers.org

1.2、使用ol.Feature类实现图片标注

使用ol.style.Icon类可以为使用ol.Feature类创建的要素提供图片样式,这样就构建了图片标注。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用ol.Feature类实现图片标注</title>
    <link rel="stylesheet" href="../v5.3.0/css/ol.css" />
    <script src="../v5.3.0/build/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 标注样式
        const labelStyle = new ol.style.Style({
            image: new ol.style.Icon({
                src: './beijing.jpg',
                scale: 0.1,
            })
        });

        const vectorSource = new ol.source.Vector();
        const vectorLayer = new ol.layer.Vector({
            source: vectorSource
        });

        // 用于充当标注的要素
        let labelFeature = new ol.Feature({
            geometry: new ol.geom.Point([12956325,4851028])
        });
        // 设置标注的样式
        labelFeature.setStyle(labelStyle);
        // 将标注要素添加到矢量图层中
        vectorSource.addFeature(labelFeature);

        const map = new ol.Map({
            target: 'map',                          // 关联到对应的div容器
            layers: [
                new ol.layer.Tile({                 // 瓦片图层
                    source: new ol.source.Stamen({
                        layer: 'terrain'
                    })     
                }),
                vectorLayer
            ],
            view: new ol.View({                     // 地图视图
                projection: 'EPSG:3857',
                center: [0, 0],
                zoom: 0
            })
        });
    </script>
</body>
</html>

效果:

2430d14c5218f05efbdd35306a4eefa7.png

二、使用ol.Overlay实现标注

ol.Overlay类主要用于实现弹窗功能,但是它也能用于实现标注。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用ol.Overlay类实现标注</title>
    <link rel="stylesheet" href="../v5.3.0/css/ol.css" />
    <script src="../v5.3.0/build/ol.js"></script>
    <style>
        #beijing{
            width: 40px;
            height: 20px;
            border: 1px solid #F00;
            border-radius: 10px;
            background-color: #F00;
            opacity: 0.8;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <div id="beijing">
        <a target="_blank" href="https://baike.baidu.com/item/%E5%8C%97%E4%BA%AC/128981?fr=aladdin">北京</a>
    </div>
    
    <script>

            const map = new ol.Map({
                target: 'map',
                layers: [
                    new ol.layer.Tile({                 // 瓦片图层
                        source: new ol.source.Stamen({
                            layer: 'terrain'
                        })     
                    })
                ],
                view: new ol.View({
                    center: [12956325,4851028],
                    zoom: 2
                })
            });

            // 用于作为标注的Overlay
            const marker = new ol.Overlay({
                position: [12956325,4851028],       // 标注位置
                positioning: 'center-center',       // 标注相对与锚点的方位
                element: document.getElementById("beijing")     // 充当标注的DOM元素
            });
            // 将Overlay对象加入map
            map.addOverlay(marker);
    </script>
</body>
</html>

效果:

7d7d8551f0731de6009a2357e611b686.png

因为添加了超链接,所以点击标注就能弹出链接页!

Logo

电影级数字人,免显卡端渲染SDK,十行代码即可调用,工业级demo免费开源下载!

更多推荐