OpenLayers之图文标记

第一次更新:

代码说明:

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-----------------------------------
 */

结果


图文标注 结果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 3,875评论 0 0
  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 2,574评论 0 7
  • 前端开发知识点 HTML&CSS对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:布局、盒子模型...
    Hebborn_hb阅读 843评论 0 1
  • HTML基础 本文包括 HTML基本知识与结构 HTML常见标签 标签写法与嵌套的讨论 HTML、CSS、java...
    廖少少阅读 2,082评论 2 21
  • 2017年6月16日 亲爱的圣灵,真理的圣灵,你是如此美善,我甚爱你,是你一次又一次的将神的大能,彰显在我生命中,...
    陈小兰阅读 133评论 0 0