当前位置: 首页 > Web前端 > JavaScript

OpenLayers简介(一)

时间:2023-03-26 22:12:52 JavaScript

OpenLayers简介OpenLayers(https://openlayers.org/)是一个高性能、功能丰富的JavaScript类库,用于帮助开发Web地图应用,可以满足几乎所有的地图开发需要。具有以下特点:支持任意XYZ瓦片资源,同时支持OGC的WMTS规范瓦片服务和ArcGIS规范瓦片服务。支持矢量切片,包括pbf、GeoJSON和TopoJSON格式。支持矢量图层,可以渲染GeoJSON、TopoJSON。、KML、GML等格式的矢量数据支持OGC制定的WMS、WFS等GIS网络服务规范支持在移动设备上运行可以通过css为地图控件设置样式面向对象开发,在OpenLayers一切皆对象与另一个流行的地图库leaflet不同,openLayers完全以面向对象的方式开发,几乎内置了地图开发所需的所有功能,而leaflet的核心库只提供基础功能,其他功能都是扩展的通过第三方插件。在使用上,leaflet比较容易上手,OpenLayers比较难上手,所以如果业务有预见性,比较简单的话还是推荐使用leaflet。OpenLayers虽然很强大,但是因为万物皆对象,使用起来比较麻烦,而且文档极其丑陋,对新手极其不友好。这也是本系列文章的初衷,旨在根据实际业务开发场景,沉淀一些内容,帮助新手使用OpenLayers。这是本系列的第一篇文章,主要介绍地图的实例化和基本的元素操作,以后会不定期更新。本文基于OpenLayersv6+版本,代码基于Vue。安装npmiol以实例化地图。显示基本地图首先需要提供容器,设置宽高,然后引入OpenLayers添加地图层。地图服务可以使用内置的开源地图OSM,或者其他在线瓦片服务,如:百度、高德、天图、必应、谷歌等,具体服务地址可以百度。本文使用高德的服务。详情请参考:https://www.jianshu.com/p/e34f85029fd7。

从'ol/Map'导入地图从'ol/View'导入视图从'ol/layer'导入{XYZ,OSM}from'ol/source'import{fromLonLat}from'ol/proj'//fromLonLat方法可以将坐标从经度/纬度转换为其他投影//使用内置OSM//consttileLayer=newTileLayer({//source:newOSM()//})//使用高德consttileLayer=newTileLayer({source:newXYZ({url:'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'})})letmap=newMap({layers:[tileLayer],view:newView({center:fromLonLat([120.771441,30.756433]),//地图中心点zoom:15,//缩放级别minZoom:0,//最小缩放级别maxZoom:18,//最大缩放级别constraintResolution:true//因为有非整数缩放级别,设置这个参数为true表示每次缩放后自动缩放到最接近的整数级别,这个必须设置,非整数级别缩放时,地图会变成蓝色rred}),target:this.$refs.olMap//DOMContainer})这样就可以显示一个基本的地图:可以拖动和缩放,但不能旋转。如果需要支持旋转,需要添加旋转交互:import{defaultsasdefaultInteractions,DragRotateAndZoom,}from'ol/interaction'letmap=newMap({//...interactions:defaultInteractions().extend([newDragRotateAndZoom()])})这样你就可以在按住鼠标的同时传递鼠标shift键旋转地图OpenLayers内置了许多开箱即用的控件,常用如下:import{defaults,FullScreen,MousePosition,ScaleLine}from'ol/control'letmap=newMap({//...controls:defaults().extend([newFullScreen(),//全屏newMousePosition(),//显示鼠标当前位置的经纬度newScaleLine()//显示比例尺])})地图也有很多事件,你可以监听你需要的事件来执行相应的操作,使用如下:map.on('moveend',e=>{//console.log('mapmovement',e)})map.on('rendercomplete',()=>{//console.log('渲染完成')})map.on('click',e=>{//console.log('mapclick',e)})显示地图基本就到这里了,我们来看看一些常见的使用场景。显示元素在地图上显示一些自定义元素可以说是最基本也是最普遍的需求。如果要展示的元素结构或者样式比较复杂,可以使用Overlay,它可以在地图上展示DOM元素,并且会和地图一起移动。importOverlayfrom'ol/Overlay'//可以给元素添加任意内容或者属性或者样式,也可以给元素绑定事件letel=document.createElement('div')letmarker=newOverlay({element:el,//要显示的元素position:fromLonLat([longitude,latitude],'EPSG:4326'),//地图投影的位置offset:[-17,-17],//像素点元素显示的偏移量autoPan:true,//自动移动地图使元素完全显示小图标、多边形、线条类需要用到矢量对象Feature。首先,让我们看看如何显示一个图片图标:/source'import{Style,Icon}from'ol/style'//实例化特征letfeature=newFeature({geometry:newPoint([120.12636255813723,30.313142215804806])//地理几何Geometry的选择点})//如果feature.set('data',data)//设置样式,这里是显示一个图片iconfeature.setStyle([newStyle({image:newIcon({anchor:[0.5,1],//显示位置size:[18,28],//sizesrc:require('../../assets/images/mouse_location_ing.png')//Imageurl})})])//Vectorsourceletsource=newVectorSource({features:[feature]})//实例化的时候不需要加feature,按照-upmethodAdd:source.addFeatures([feature])//清除feature:source.clear()//Vectorlayerletvector=newVectorLayer({source:source})//可以在单个特征上设置样式或者在单个特征上统一设置在矢量图层上/*letvector=newVectorLayer({source:source,style:newStyle({image:newIcon({anchor:[0.5,1],//显示位置size:[18,28],//sizesrc:require('../../assets/images/mouse_location_ing.png')//imageurl})})})*/map.addLayer(vector)上面实现添加一个icon如果你想在地图上添加多个功能,只需实例化多个功能。效果如下:有时候需要支持拖动特性来修改它的位置。为此,需要Translate交互的支持:import{Translate}from'ol/interaction'//...//...lettranslate=newTranslate({layers:[vector]})map.addInteraction(translate)//可以监听拖拽开始和结束事件,拖拽最终的经纬度可以从e中获取translate.on('translateend',(e)=>{console.log(e)})translate.on('translatestart',(e)=>{console.log(e)})删除为了直接显示在地图上,也可以自己添加,即在鼠标点击的位置添加一个元素,需要使用Draw交互:import{Draw}from'ol/interaction'letdraw=newDraw({source:source,type:'Point',style:newStyle({image:newIcon({anchor:[0.5,1],//显示位置size:[18,28],//大小src:require('../../assets/images/mouse_location_ing.png')//图片url})})})//监听完成事件draw.on('drawend',(e)=>{console.log(e)//如果你只需要放置一个,你可以移除交互,否则你可以随时添加map.removeInteraction(draw)})map.addInteraction(draw)因为如果图标太多,你不知道一个icon代表什么,所以经常需要给icon添加一个tooltip,当鼠标上移时显示。如何实现?事实上,工具提示本质上是一个DOM元素。Overlay上面已经介绍过了,用它来实现。请看:{{olPopupText}}
importOverlayfrom'ol/Overlay'//创建Overlayerthis.tooltipOverlay=newOverlay({element:this.$refs.olPopup,positioning:'bottom-center',//根据position属性offset的位置进行相对点定位:[0,-30],//在定位autoPan之上的偏移量:true})map.addOverlay(this.tooltipOverlay)//给地图绑定鼠标移动事件,检测鼠标位置是否有要素,并显示tooltipmap.on('pointermove',(e)=>{this.olPopupText=''mapif它是目标特征.forEachFeatureAtPixel(e.pixel,(f,layer)=>{if(layer!==this.vectorLayer||!f.get('data')){returnfalse}this.olPopupText=f.get('data')this.tooltipOverlay.setPosition(f.getGeometry().getCoordinates())})})这样当鼠标向上移动时,就会显示tooltip:接下来我们看如何绘制多边形。绘制图形仍然使用之前的Draw交互:import{Draw}from'ol/interaction'letsource=newVectorSource()letvector=newVectorLayer({source:source})map.addLayer(vector)letdraw=newDraw({source:source,type:'Circle'})map.addInteraction(draw)非常简单。实例化一个Draw对象并设置类型。上面设置的是Circle,画出的是圆:接下来我们看正方形和长方形。在上面的例子中修改:import{createRegularPolygon,createBox}from'ol/interaction/Draw'//createRegularPolygon方法返回一个执行后创建正方形的geometryFunction//createBox方法返回一个执行后创建矩形的geometryFunctionletdraw=newDraw({来源:来源,type:'Circle',//没错,还是CirclegeometryFunction:createBox()})其他类型设置对应的类型即可。例如,将不规则多边形绘制为POLYGON。具体类型请参考文档:https://openlayers.org/en/latest/apidoc/module-ol_geom_GeometryType.html在实际使用场景中,仍然会出现需要修改已有多边形的情况,Modify交互为required:import{Modify}from'ol/interaction'letmodify=newModify({source})map.addInteraction(modify)现在可以拖动多边形的端点来修改它。以上对几何体的操作和显示都使用了内置的默认样式。如果需要自定义样式,可以通过样式配置进行修改。元素的基本使用就到这里。获取地图当前区域的范围出于性能考虑,如果是在地图上显示元素,最好只显示当前显示区域的元素。要显示的数据一般是向后端请求的,所以可以将当前区域的范围发送给后端,后端只返回该区域的数据,这时需要获取当前范围://获取纬度和当前地图区域上下左右四个点的经度letrange=map.getView().calculateExtent(map.getSize())letstate={minLon:range[0],minLat:range[1],maxLon:range[2],maxLat:range[3],zoomLevel:map.getView().getZoom()//当前缩放级别,缩放级别可以用来判断是否聚合元素进行显示再见,因为我才刚刚入门,所以可能有不对的地方或者可能有一些更好的实现方法,欢迎大家指出。