OpenLayers之图文标记

作者: 多智而近妖精 | 来源:发表于2019-11-12 09:48 被阅读0次

    第一次更新:

    代码说明:

    html中是页面的基本骨架
    1. 添加checkbox标签,用户可以选择 Vector Label 或 Overlay Label 类型;
    2. 添加text标签,输入想要添加的文字标记;
    3. 添加button按钮,用来启动文字标注功能和清除地图上的标注;
    4. 添加map的div
    5. 添加标注点的div
    js代码实现功能
    1. 创建ONE类,添加Map属性,并指定相应的默认值;
    2. 在类中添加DrawingAndTextAnnotation属性,在其中声明相应的变量;
    3. 创建标签的样式;
    4. ······
      在代码注释中都有具体的解释

    html:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>添加图文标注</title>
        <link href="./css/ol.css" rel="stylesheet" type="text/css"/>
        <script src="./js/ol.js" type="text/javascript"></script>
        <script src="./externalJS/index.js" type="text/javascript"></script>
        <!--  引入第三方插件库 -->
        <script src="./libs/jquery.min.js" type="text/javascript"></script>
        <style type="text/css">
            #menu {
                width: 100%;
                height: 20px;
                padding: 5px 10px;
                left: 10px;
                font-size: 14px;
                font-family: "微软雅黑";
            }
    
            .checkbox {
                margin: 5px 15px;
            }
    
            .marker {
                width: 20px;
                height: 20px;
                border: 1px solid #088;
                border-radius: 10px;
                /*background-color:#0FF;*/
                background-color: #000000;
                opacity: 0.5;
            }
    
            .address {
                text-decoration: none;
                color: #566F89;
                font-size: 14px;
                font-weight: bold;
                text-shadow: #E4F1FF 1em 1em 1em ;
                background: #C5DFF8;
            }
        </style>
    </head>
    <body>
    
    <div id="menu">
        <label class="checkbox">
            <input type="radio" name="label" value="vector" checked="checked"/>
            Vector Label
        </label>
        <label class="checkbox">
            <input type="radio" name="label" value="overlay"/>
            Overlay Label
        </label>
        &nbsp;&nbsp;
        <label>请输入需要添加的文字:</label>
        <input type="text" id="DrawingAndTextAnnotationInputText" value=""/>
        <input type="button" class="GISButton" value="添加文字标注"
               onclick="ONE.DrawingAndTextAnnotation.DrawingAndTextAnnotationFunction(map)"/>&nbsp;&nbsp;
        <input type="button" class="GISButton" value="清除"
               onclick="ONE.DrawingAndTextAnnotation.closeDrawingAndTextAnnotationFunction()"/>
    </div>
    <div id="map" class="map" style="width: 100%; height:90%"></div>
    <div id="label" style="display:none">
        <div id="marker" class="marker" title="Marker">
            <a class="address" id="address" target="_blank" href="http://www.openlayers.org">标注点</a>
        </div>
    </div>
    
    
    <script>
        var map = new ONE.Map('map', 'http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=299087c31e3bcdab226a541ab948247c', {
            projection: 'EPSG:3857',
            zoom: 10,
            center: [12964486.5, 4883269.7]
        });
    
    </script>
    </body>
    </html>
    

    js:

    var ONE = {};
    ONE.Map = function (container, url, options) {
        //内置地图对象,用来保存DigMap.Map对象
        this.map = null;
    
        var _options = options ? options : {};
        var zoom = _options.zoom ? _options.zoom : 4;
        var center = _options.center ? _options.center : [10.54, 27.21];
        var pro = _options.projection ? _options.projection : 'EPSG:4326';
        var maxZoom = _options.maxZoom ? _options.maxZoom : 24;
        var minZoom = _options.minZoom ? _options.minZoom : 2;
    
        var map = new ol.Map({
            target: container,
            view: new ol.View({
                zoom: zoom,
                center: center,
                projection: pro,
                maxZoom: maxZoom,
                minZoom: minZoom
            })
        });
    
        var tidituLayer = new ol.layer.Tile({
            //title: '天地图',
            // source: new ol.source.XYZ({
            //     url: url
            // })
            source: new ol.source.OSM()
        });
        map.addLayer(tidituLayer);
    
        this.map = map;
        return this;
    };
    
    
    /**
     * -------------------------------图文标注功能  start-----------------------------------
     */
    
    ONE.DrawingAndTextAnnotation = {
        DTAMap: null,
        createLabelStyle: null,
        vectorSource: null,
        vectorLayer: null,
    
    };
    
    ONE.DrawingAndTextAnnotation.DrawingAndTextAnnotationFunction = function (MAP) {
    
        ONE.DrawingAndTextAnnotation.DTAMap = MAP.map;
    
        //输入框获得焦点
        document.getElementById('DrawingAndTextAnnotationInputText').focus();
    
        //创建标签的样式
        ONE.DrawingAndTextAnnotation.createLabelStyle = function (feature) {
            //返回一个样式
            return new ol.style.Style({
                //把点的样式换成ICON图标
                image: new ol.style.Icon({
                    //控制标注图片和文字之间的距离
                    anchor: [0.5, 175],
                    //标注样式的起点位置
                    anchorOrigin: 'top-right',
                    //X方向单位:分数
                    anchorXUnits: 'fraction',
                    //Y方向单位:像素
                    anchorYUnits: 'pixels',
                    //偏移起点位置的方向
                    offsetOrigin: 'top-right',
                    //图标缩放比例
                    scale: 0.25,
                    //透明度
                    opacity: 0.75,
                    //图片路径
                    src: './images/point.png'
                }),
                //文本样式
                text: new ol.style.Text({
                    //垂直文本偏移量(以像素为单位)。正值将使文本向下移动。
                    offsetY: 15,
                    //对齐方式
                    textAlign: 'center',
                    //文本基线
                    textBaseline: 'middle',
                    //字体样式
                    font: 'normal 14px 微软雅黑',
                    //文本内容
                    text: feature.get('name'),
                    //填充样式
                    //文本填充样式(即文字颜色)
                    fill: new ol.style.Fill({color: '#000000'}),
                    stroke: new ol.style.Stroke({color: '#ffcc33', width: 12})
                })
            });
        };
    
    
        //初始化矢量数据源
        ONE.DrawingAndTextAnnotation.vectorSource = new ol.source.Vector({
        });
    
        //初始化矢量图层
        ONE.DrawingAndTextAnnotation.vectorLayer = new ol.layer.Vector({
            //数据源
            source: ONE.DrawingAndTextAnnotation.vectorSource
        });
        //将矢量图层添加到map中
        ONE.DrawingAndTextAnnotation.DTAMap.addLayer(ONE.DrawingAndTextAnnotation.vectorLayer);
    
        //地图的点击事件
        ONE.DrawingAndTextAnnotation.DTAMap.on('click', ONE.DrawingAndTextAnnotation.clickEvent);
    
    };
    
    ONE.DrawingAndTextAnnotation.closeDrawingAndTextAnnotationFunction = function () {
        // 矢量标注的数据源  清除
        ONE.DrawingAndTextAnnotation.vectorSource.clear();
        //关闭地图的点击监听
        ONE.DrawingAndTextAnnotation.DTAMap.un('click', ONE.DrawingAndTextAnnotation.clickEvent);
        ONE.DrawingAndTextAnnotation.DTAMap.removeLayer(ONE.DrawingAndTextAnnotation.vectorLayer);
    
        //清除map的覆盖图层
        ONE.DrawingAndTextAnnotation.DTAMap.getOverlays().clear();
    };
    
    //地图监听事件后,执行方法
    ONE.DrawingAndTextAnnotation.clickEvent = function (evt) {
        //获取单选按钮的选项
        var type = $('input[name="label"]:checked').val();
        //获取位置坐标
        var point = evt.coordinate;
    
        var inputText = document.getElementById("DrawingAndTextAnnotationInputText").value;
        console.log("inputText:" + inputText);
    
        //如果类型是矢量标注则添加矢量标签,否则添加覆盖标签
        if (type == 'vector') {
            ONE.DrawingAndTextAnnotation.addVectorLabel(point, inputText);
        } else if (type == 'overlay') {
            ONE.DrawingAndTextAnnotation.addOverlayLabel(point, inputText);
        }
    };
    
    
    //添加矢量标签
    ONE.DrawingAndTextAnnotation.addVectorLabel = function (coordinate, inputText) {
        //初始化一个新的点要素
        var newFeature = new ol.Feature({
            geometry: new ol.geom.Point(coordinate),
            name: inputText === "" ? '标注点' : inputText
        });
        //设置点的样式
        newFeature.setStyle(ONE.DrawingAndTextAnnotation.createLabelStyle(newFeature));
        //将当前要素添加到矢量数据源中
        ONE.DrawingAndTextAnnotation.vectorSource.addFeature(newFeature);
    };
    
    //添加覆盖标注
    ONE.DrawingAndTextAnnotation.addOverlayLabel = function (coordinate, inputText) {
        //创建一个div元素
        var elementDiv = document.createElement('div');
        //设置div元素的样式类
        elementDiv.className = 'marker';
        //设置div元素的title属性
        elementDiv.title = inputText === "" ? '标注点' : inputText;
    
        //获取id为label的div标签
        var overlay = document.getElementById('label');
        //将新创建的div标签添加到overlay中
        overlay.appendChild(elementDiv);
    
        //创建一个a标签元素
        var elementA = document.createElement('a');
        //设置a标签的样式类
        elementA.className = 'address';
        //设置a标签的链接地址
        elementA.href = 'https://www.baidu.com/';
        //设置a标签的超链接文本
        ONE.DrawingAndTextAnnotation.setInnerText(elementA, elementDiv.title);
        //将a标签元素添加到div标签元素中
        elementDiv.appendChild(elementA);
    
        //新建一个覆盖层
        var newMarker = new ol.Overlay({
            //设置位置为当前鼠标点击的坐标
            position: coordinate,
            //设置覆盖层与位置之间的匹配方式
            positioning: 'center-center',
            //覆盖层元素
            element: elementDiv,
            //事件传播到地图视点的时候是否应该停止
            stopEvent: false
        });
        //将覆盖层添加到map中
        ONE.DrawingAndTextAnnotation.DTAMap.addOverlay(newMarker);
    
        //新建一个文本覆盖层
        var newText = new ol.Overlay({
            //设置位置为当前鼠标点击的坐标
            position: coordinate,
            //覆盖层元素
            element: elementA
        });
        //将文本覆盖层添加到map中
        ONE.DrawingAndTextAnnotation.DTAMap.addOverlay(newText);
    };
    
    //设置文本内容
    ONE.DrawingAndTextAnnotation.setInnerText = function (element, text) {
        if (typeof element.textContent == 'string') {
            element.textContent = text;
        } else {
            element.innerText = text;
        }
    }
    /**
     * -------------------------------图文标注功能  end-----------------------------------
     */
    

    结果


    图文标注 结果

    相关文章

      网友评论

        本文标题:OpenLayers之图文标记

        本文链接:https://www.haomeiwen.com/subject/xkqwbctx.html