WebGis之OpenLayers学习之路------OpenLayers开发基础

openlayers很久之前就听说过一个不错的开源架构,由于这一年来做的项目都是桌面端的,使用的GMap .Net和ArcGisEngine,所以对openlayers很少有研究,年底时间暂时充裕,花费一点时间对此开源架构进行学习和使用。

OpenLayers简介

对于OpenLayers的简介就不多说废话了,这就交到度娘手中吧,它就是一个模块化、高性能并且功能丰富的WebGIs客户端的JavaScript包,用于显示地图及空间数据,是一个免费的、开源的JavaScript库,目前版本为5.x

OpenLayers体系结构

Map:整个地图的容器,其中核心如下

  • Layer:地图图层
  • Source:对应图层的数据源
  • Style:矢量图层样式
  • View:地图表现相关的地图视图

除此之外还有一些与地图交互操作控件以及请求事件等,在最底层是OpenLayers的数据源(Image、KML、GML、JSON...)这些数据是经过Renderer渲染显示到地图容器的图层中。

OpenLayers的工作原理

Gis的核心是空间数据,关键是如何将空间数据应用到各行各业中,充分体现出空间数据的价值,针对复杂的空间数据OpenLayers是如何将这些空间数据抽象为类?如何解析各种空间数据源?又是如何渲染到客户端展示?数据加载到地图中是如何操作地图?下面我们就从这几个方面进行简单的分析。

1、数据组织

首先我们了解OPenLayers的数据结构和组织,从表面上看,空间数据是由点、线、面三要素构成,将这些要素呈现在web中需要抽象为相应的类,包括要素之间的关系,再ol中矢量数据抽象是由ol.geom.Geometry基类下的集合对象子类实现的,下图为基类与子类的继承关系。

  • Point与MultiPoint(点与多点)
  • LineString与MultiLineString(线与多线)
  • Polygon与MultiPolygon(区与多区)
  • LinearRing(线性环)
  • Cirle(圆)

对于Web网页地图应用而言,除了矢量数据,还有瓦片数据,以及图片等各类数据,接下来我们简单了解下ol的数据组织与实现原理

ol的地图数据通过图层(Layer)组织渲染的,且通过数据源(Source)设置具体的地图数据来源,因此图层和数据源就想夫妻一样形影不离,密切相关,地图数据根据数据源可分为Image、Tile、Vector三大类,对应设置到这三大类的图层中,地图图层与数据源的关系如下图所示,其中矢量图层Vector通过样式(Style)来设置矢量数据渲染的方式和外观

2、数据解析

通过上面组织图可以看出,地图的数据源可以分为Image、Tile、Vector三大类,其中Image和Tile两者得本质是一样的,都是图片,Vector为矢量基类,由于数量数据类型繁多,需要通过Format属性进行设置,即通过ol.format.Feature类得子类进行各种格式矢量数据的解析

3、数据渲染

基于OpenLayers的地图整个表现过程为:先通过URL调用数据,然后用各种格式的数据解析器解析数据,再用相应的渲染器在图层中进行渲染,最后结合相应的控件表现出来,呈现出地图样式。

openLayers渲染功能主要是依靠渲染器(Renderer)实现,通过Map的Renderer属性设置渲染方式,然后根据不同的渲染方式(Canvas、WebGL)、与图层类型(Image、Tile、Vector)匹配渲染器将图层数据渲染出来。

4、地图表现

大家都知道Web客户端通常是有Html表现出来的网页内容,通过javascript实现动态交互效果,那么基于openlayers的地图应用也同样是这个原理。

在Web网页中,地图容器通过div标签来显示的,通过Map类的target属性关联作为地图容器的html元素,即将此地图容器div与javaScript的map对象绑定,然后将layers、controls等内容加载到Map中。如下代码所示

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <style>
        .map {
            height: 800px;
            width: 100%;
        }
    </style>
    <script type="text/javascript" src="javascript/ol.js"></script>
</head>
<body>
<h2>My Map</h2>
<div id="map" class="map"></div>
<script type="text/javascript">
//    // 地图设置中心,设置到北京,在本地离线地图 offlineMapTiles刚好有一张zoom为4的成都瓦片
    var center = ol.proj.transform([117.06667, 39.66667], 'EPSG:4326', 'EPSG:3857');

    //创建地图
    var map = new ol.Map({
        view: new ol.View({
            center: center,
            zoom: 4
        }),
        target: 'map'
    });

    // 添加一个使用离线瓦片地图的层
    var offlineMapLayer = new ol.layer.Tile({
        source: new ol.source.XYZ({
            // 设置本地离线瓦片所在路径,由于例子里面只有一张瓦片,页面显示时就只看得到一张瓦片。
            //url: 'http://localhost:7080/{z}/{x}/{y}.jpg'
            //url:'http://mt0.google.cn/maps/vt?lyrs=s@773&gl=cn&x={x}&y={y}&z={z}'
            url:'http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}'
        })
    });

    map.addLayer(offlineMapLayer);

    var beijing = ol.proj.fromLonLat([116.28, 39.54]);
//var map = new ol.Map({
//    target: 'map',
//    layers: [
//        new ol.layer.Tile({
//            source: new ol.source.OSM()
//        })
//    ],
//    view: new ol.View({
//        center: beijing,
//        zoom: 4
//    })
//});
    //实例化矢量点要素,通过矢量图层添加到地图容器中
    //这样就实现了预先加载图文标注
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(beijing),
        name: '北京市',                         //名称属性
        population: 2115                       //人口数(万)
    });
    //设置点要素样式
    iconFeature.setStyle(createLabelStyle(iconFeature));
    //矢量标注的数据源
    var vectorSource = new ol.source.Vector({
        features: [iconFeature]
    });
    //矢量标注图层
    var vectorLayer = new ol.layer.Vector({
        source: vectorSource
    });
    map.addLayer(vectorLayer);

    //矢量标注样式设置函数,设置image为图标ol.style.Icon
    function createLabelStyle(feature){
        console.log(feature);
        return new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 60],              //锚点
                anchorOrigin:'top-right',       //锚点源
                anchorXUnits: 'fraction',       //锚点X值单位
                anchorYUnits: 'pixels',         //锚点Y值单位
                offsetOrigin: 'top-right',      //偏移原点
                opacity: 0.75,
                src: 'image/x_dxd.png'  //图标的URL
            }),
            text: new ol.style.Text({
                textAlign: 'center',            //位置
                textBaseline: 'middle',         //基准线
                font: 'normal 14px 微软雅黑',    //文字样式
                text: feature.get('name'),      //文本内容
                fill: new ol.style.Fill({       //文本填充样式(即文字颜色)
                    color: '#000'
                }),
                stroke: new ol.style.Stroke({
                    color: '#F00',
                    width: 2
                })
            })
        });
    }

    map.on('click', function(evt){
        var coordinate = evt.coordinate;        //鼠标单击点的坐标
        //新建一个要素ol.Feature
        var newFeature = new ol.Feature({
            geometry: new ol.geom.Point(coordinate),  //几何信息
            name: '标注点'
        });
        newFeature.setStyle(createLabelStyle(newFeature));      //设置要素样式
        vectorSource.addFeature(newFeature);
    });
</script>
</body>
</html>

上面代码就是一段简单地图加载代码,下面我们在调试状态下看一下页面具体标签

上图中很明显,我们定义了一个id为map的div容器,在div容器下面openlayers创建了ol-viewport容器(class为ol-viewport),在这个容器中分别创建了三个关键的内容层,分别渲染呈现地图容器中的内容:

  • 地图渲染层:根据地图渲染方式创建的canvas元素
  • 内容叠加层:类名为ol-overlaycontainer的div层,装载叠加层(ol.Overlay)内容
  • 地图控件层:类名为ol-overlaycontainer-stopevent的div层,装载显示地图控件或叠加内容

5、地图事件

从我们操作方面我们知道,当地图加载到web页面后,我们会对地图进行不同的操作,如:单击、双击、指针移动、改变要素等一些交互事件,下面就总结下用户和地图的交互事件

  • 地图事件(ol.MapEvent):包含moveend、postrender事件
  • 地图浏览器事件类(ol.MapBrowserEvent):包括singleclick、click、dbclick事件等
  • 对象事件类(ol.Object.Event):包括change、propertychange事件
  • 选择控件事件类(ol.interaction.Select.Event):包括select事件
  • 绘制控件事件类(ol.interaction.Draw.Event):包括drawstart、drawend事件
  • 修改控件事件类(ol.interaction.Modify.Event):包括modifystart、modiftend事件
  • 集合事件类(ol.Collection.Event):包括add、remove事件

针对各类事件openlayers提供了on与once方法添加事件监听,通过un与unByKey方法移除事件监听。

总结

目前来说,openlayers市场使用率还是挺高,经过BOSS直聘查看,设计到webgis的公司都会有一条熟悉openlayers可见这款开源webgis架构还是很火爆的,总体来说openlayers的功能是很强大的,强大到什么地步,咱们一点点研究,在这里只是简单的说了一些最基础的东西,让大家对openlayers有一个印象。最后想说的就是openlayers开发方式有2种,一种就是传统的开发方式:直接下载资源库,将资源进行加载其实本质就是html+javascript,另一种就是NodeJS:理用npm或cnpm(淘宝镜像)进行下载,再用import将模块包导入。

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值