0
点赞
收藏
分享

微信扫一扫

openlayer地图使用笔记

陌岛 2022-03-30 阅读 75
前端框架

openlayer地图使用

第一部分: 认识和学习ol

简述:

OpenLayers是一个用于开发WebGIS客户端的JavaScript包

目前OpenLayers已经成为一个拥有众多开发者和帮助社区的成熟、流行的框架。

基本概念:

一般地图构成: 一个底图 + 其他各种图层 + 控件

引入js css

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>openlayers-exercise</title>
    <script src="reference/ol/ol.js"></script>
    <script src="reference/jq/jquery-3.2.1.js"></script>
    <style>
        #map {
            width: 700px;
            height: 700px;
        }
    </style>
</head>

<body>
    <div id="map" class="map"></div>
</body>
<script src="./js/lyxmap.js"></script>

</html>

一个最简单的map

lyxmap.js 一个底图+ 最少一个layers

var map;

//layers、target、view是地图最基本的部分,是必需的
map = new ol.Map({
    layers: [                      //layers 可以理解为组件容器,里面可以放置多种组件
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
    ],
    target: 'map',
    view: new ol.View({             // view可以理解为视口
        projection: 'EPSG:4326',     // 要指定编码格式
        center: [120.372451, 29.56432],   // 经纬度中心点
        zoom: 8
    })
});

地图出来了。

1.1叠加图层

首先需要明白的一点是,Source和Layer是一对一的关系,有一个Source,必然需要一个Layer,然后把这个Layer添加到Map上,就可以显示出来了。通过官网的API搜索ol.source可以发现有很多不同的Source,但归纳起来共三种:ol.source.Tile,ol.source.Image和ol.source.Vector。
ol.source.Tile对应的是瓦片数据源,现在网页地图服务中,绝大多数都是使用的瓦片地图,而OpenLayers 3作为一个WebGIS引擎,理所当然应该支持瓦片。
ol.source.Image对应的是一整张图,而不像瓦片那样很多张图,从而无需切片,也可以加载一些地图,适用于一些小场景地图。
ol.source.Vector对应的是矢量地图源,点,线,面等等常用的地图元素(Feature),就囊括到这里面了。这样看来,只要这两种Source就可以搞定80%的需求了。
从复杂度来分析,ol.source.Image和ol.source.Vector都不复杂,其数据格式和来源方式都简单。而ol.source.Tile则不一样,由于一些历史问题,多个服务提供商,多种标准等诸多原因,导致要支持世界上大多数的瓦片数据源,就需要针对这些差异提供不同的Tile数据源支持。在更进一步了解之前,我们先来看一下OpenLayers 3现在支持的Source具体有哪些:

img

我们主要来分析一下ol.source.Tile,这个由于各种原因比较复杂,其叶子节点类有很多,大致可以分为几类:

在线服务的Source,包括ol.source.BingMaps(使用的是微软提供的Bing在线地图数据),ol.source.MapQuest(使用的是MapQuest提供的在线地图数据)(注: 由于MapQuest开始收费,ol v3.17.0就移除了ol.source.MapQuest),ol.source.OSM(使用的是Open Street Map提供的在线地图数据),ol.source.Stamen(使用的是Stamen提供的在线地图数据)。没有自己的地图服务器的情况下,可直接使用它们,加载地图底图。
支持协议标准的Source,包括ol.source.TileArcGISRest,ol.source.TileWMS,ol.source.WMTS,ol.source.UTFGrid,ol.source.TileJSON。如果要使用它们,首先你得先学习对应的协议,之后必须找到支持这些协议的服务器来提供数据源,这些服务器可以是地图服务提供商提供的,也可以是自己搭建的服务器,关键是得支持这些协议。
ol.source.XYZ,这个需要单独提一下,因为是可以直接使用的,而且现在很多地图服务(在线的,或者自己搭建的服务器)都支持xyz方式的请求。国内在线的地图服务,高德,天地图等,都可以通过这种方式加载,本地离线瓦片地图也可以,用途广泛,且简单易学,需要掌握。
总结概括呢就是如果你没有地图服务器,那么你要加载地图就只能调用地图商发布的在线服务,包括在线服务的Source:ol.source.BingMaps,ol.source.OSM等地图;还有一种是ol.source.XYZ格式的在线服务地图,包括国内的一些在线服务地图,高德、百度、天地图等。

如果你有自己的地图服务器,那么你就可以发布地图服务然后在OpenLayers中调用自己发布的服务了,例如我们常见的几种发布的服务:ol.source.TileArcGISRest—ArcGIS发布的服务还有Geoserver发布的服务等等。

1、在线地图服务的加载,

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>在线地图加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>
 
<body>
	<div> 显示/隐藏:
    <input type="checkbox" checked="checked" onclick="checkERSI(this);" />加载ArcGIS地图
    <input type="checkbox" checked="checked" onclick="checkOSM(this);"/>加载Open Street Map地图
    <input type="checkbox" checked="checked" onclick="checkTDT(this);"/>加载天地图
    <input type="checkbox" checked="checked" onclick="checkAmap(this);"/>加载高德地图
</div>
<div>
    图层顺序:
    <input name="seq" type="radio" value="" onclick="upArcGIS(this);" />ArcGIS地图在最上
    <input name="seq" type="radio" value=""  onclick="upOSM(this);"/>OSM地图在最上
    <input name="seq" type="radio" value="" checked="checked" onclick="upTDT(this);"/>天地图在最上
    <input name="seq" type="radio" value="" checked="checked" onclick="upAmap(this);"/>高德地图在最上
  
</div>
	<div id="map" style="width: 100%"></div>
 
 
<script>
 
    // 创建4个图层
    //ArcGIS地图
    var esriMapLayer = new ol.layer.Tile({
    		source: new ol.source.XYZ({
      		url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
    		}),
    		title:"ESRI影像"
  	});
  	//OSM地图
  	var osmLayer = new ol.layer.Tile({
        source: new ol.source.OSM(),
        title:"OSM影像"
    });
    //天地图
    var tiandituSatelliteLayer = new ol.layer.Tile({
    	source: new ol.source.XYZ({
      	url: "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=008a8816d2eee25a677670273eaee891",
      	crossOrigin: "anonymous"
    	}),
    	title:"天地图影像"
  	});
  	//高德地图
  	var gaodeMapLayer = new ol.layer.Tile({
    	source: new ol.source.XYZ({
        	url:'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
    	})
	}); 
 
	
    
   
 
  var map=new ol.Map({
      // 在地图上添加上面创建的四个图层,图层顺序自下而上,依次是ESRI地图,OSM地图,天地图和高德地图
        layers: [esriMapLayer, osmLayer, tiandituSatelliteLayer,gaodeMapLayer],
        view: new ol.View({
            center: [120.374,36.073],
             projection: 'EPSG:4326',
            zoom: 10
        }),
        target: 'map'
        
  });
  map.getView().fit([120.33944,36.049352, 120.442925,36.126585], map.getSize());
 
  // 隐藏显示esri图层
  function checkERSI(elem) {
      esriMapLayer.setVisible(elem.checked);
  }
 
    // 隐藏显示osm图层
  function checkOSM(elem) {
      osmLayer.setVisible(elem.checked);
  }
 
  // 隐藏显示天地图图层
  function checkTDT(elem) {
      tiandituSatelliteLayer.setVisible(elem.checked);
  }
   // 隐藏显示高德地图图层
   function checkAmap(elem) {
      gaodeMapLayer.setVisible(elem.checked);
  }
   
 
  // 置顶esri图层到最上面
  function upArcGIS (elem) {
      if (elem.checked) {
          esriMapLayer.setZIndex(3);
          osmLayer.setZIndex(osmLayer.getZIndex()-1);
          tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
          gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
      }
  }
 
  // 置顶osm图层到最上面
  function upOSM (elem) {
      if (elem.checked) {
          osmLayer.setZIndex(3);
          esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
          tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
          gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
      }
  }
 
  // 置顶天地图图层到最上面,
  function upTDT(elem) {
      if (elem.checked) {
          tiandituSatelliteLayer.setZIndex(3);
          esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
          osmLayer.setZIndex(osmLayer.getZIndex()-1);
          gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
      }
  }
  
  // 置顶高德地图图层到最上面
  function upAmap(elem) {
      if (elem.checked) {
          gaodeMapLayer.setZIndex(3);
          esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
          osmLayer.setZIndex(osmLayer.getZIndex()-1);
           tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
      }
  }
  
  
 
</script>
</body>
 
</html>

摘抄上面的代码 先来运行代码看一下效果如下图:

Tile 瓦片图层

var basemap = new ol.layer.Tile({
    source: new ol.source.OSM()
});

  //高德地图
var gaodeMapLayer = new ol.layer.Tile({
        source: new ol.source.XYZ({
            url: 'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
        })
    });

var osmLayer = new ol.layer.Tile({
        source: new ol.source.OSM(),
        title: "OSM影像"
});
    
 上面有三个瓦片类的图层,可以依次放到map的layers中查看。   
map = new ol.Map({
    layers: [ osmLayer],
    target: 'map',
    view: new ol.View({
        projection: 'EPSG:4326',
        center: [120.372451, 29.56432],
        zoom: 8
    })
});    
1648299030192

加载Image图层

    下面这个图层是使用自己geoserverr 配置的图层。
    // 乡镇图层(无名字)
     var xz = new ol.layer.Image({
        zIndex: 3,
        source: new ol.source.ImageWMS({
            url: 'http://自己服务器的ip:8080/geoserver/zjlwjc/wms',
            params: {
                'LAYERS': '*****:ji******',
                'STYLES': 'zjlwjc:JinDon'
            },
            ratio: 1,
            serverType: 'geoserver'
        }),
    });
    
1648300058870

地图开发实战之Geoserver配置与发布地图服务, 感兴趣可以查看。

https://blog.csdn.net/MagicMHD/article/details/91430148

加载 ol.layer.Vector 矢量图层

    var vectorLayer = new ol.layer.Vector({
        zIndex: 99,
        source: vectorSource,
    });
    map.addLayer(vectorLayer)
 见第二部分:地图撒点案例   

2.2 new ol.source 数据源

new ol.layer.Tile 的 source使用 new ol.source.WMTS

官方解释: Layer source for tile data from WMTS servers. 解析瓦片的

new ol.layer.Image 的 source使用 new ol.source.ImageWM

官方解释:Source for WMS servers providing single, untiled images. 解析图片的

那么 ,ol.source的种类有多少 官网上给出约48中

1.2 Openlayer:学习笔记之控件

Openlayer:学习笔记之控件_css

这些控制器在实现上,并不是在画布上绘制的,而是使用传统的HTML元素来实现的,便于同地图分离,也便于界面实现。 具体可参考 https://blog.51cto.com/u_15349906/3717226

第二部分 业务场景和实现

  1. 展示地图
  2. 根据业务展示瓦片地图获取图片地图
  3. 添加点 和点的点击事件 mark lable文字标注和样式调整
  4. 对图层的事件操作: 飞视角 zoom调整

地图撒点:

一个点,标记到地图上,逻辑。

与加载矢量要素相同,分别实例化矢量图层(ol.layer.Vector)和矢量数据源(ol.source.Vector),将矢量图层加载到地图容器中。

其中,数据源中设置的矢量点要素,通过实例化ol.Feature创建,分别设置要素的几何信息(geometry)与属性信息(如name、population)等。矢量要素的样式通过setStyle方法进行设置,由createLabelStyle函数实现。

ol.Feature的关键参数如下:

  • geometry:几何图形对象,标注点一般设置为ol.geom.Point对象
  • 自定义的属性项:如name、population等,可根据需要自行定义,这些属性项可通过get方法进行获取,如feature.get(‘name’)。
// 添加点标记

    /** 设置点图层 */
    矢量特征对象
    3 var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([119.68827577544099, 29.10216260533227]),
        name: 'Null Island',
        population: 4000,
        rainfall: 500,
    });
  矢量特征对象  --样式
    var iconStyle = new ol.style.Style({
        image: new ol.style.Icon({
            anchor: [0.5, 46],
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: "图片的地址",
            scale: 0.2,
        }),
        text: new ol.style.Text({
            text: "**区人民政府",
            offsetX: 0,
            offsetY: -12,
            scale: 1.2,
            backgroundFill: "#000",
            font: "10px sans-serif",
            fill: new ol.style.Fill({
                color: '#FF1400'
            }),
        })
    });

    iconFeature.setStyle(iconStyle);
2为矢量图层提供特征源
    var vectorSource = new ol.source.Vector({
        features: [iconFeature],
    });
1矢量图层
    var vectorLayer = new ol.layer.Vector({
        zIndex: 99,
        source: vectorSource,
    });
 
 map.addLayer(vectorLayer)

当地图上的点很多时, 会出现点重合,覆盖。引出另一个功能。

Openlayers 实例-点聚合

待续…

举报

相关推荐

0 条评论