openlayer3-加载第三方地图,百度,谷歌等
OpenLayers 3 之加载地图
摘要
在浏览器中加载一幅地图,而且是可交互(包含缩放、平移、查询和分析等高级功能)的,该怎么做呢?我们当然知道要想网页中的内容是动态的,可交互的,要使用JavaScript,地图应用也不例外,不过要从底层开发的话,要费老鼻子的劲儿了!OpenLayers便是一个减轻你的工作量的框架,利用它可以轻松地加载一幅动态可交互的地图到浏览器中!
下面便是一个利用OpenLayers加载地图的小例子,我们先看看运行结果,并分析一下原理,捋一捋源码!
正文
例程如下:
[html] view plain copy
- >
- <html< span=""> lang="en">
- <link< span=""> rel="stylesheet" href="http://openlayers.org/en/v3.3.0/css/ol.css" type="text/css">
- src="http://openlayers.org/en/v3.3.0/build/ol.js" type="text/javascript">
- My Map
- <div< span=""> id="map" class="map">
- type="text/javascript">
- var map = new ol.Map({
- target: 'map',
- layers: [
- new ol.layer.Tile({
- source: new ol.source.MapQuest({layer: 'sat'})
- })
- ],
- view: new ol.View({
- center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
- zoom: 4
- })
- });
在浏览器中打开,Duang Duang Duang 。。 。 - -| ,运行结果如下:
为什会有这些效果,咱来个庖丁解牛,分解分解,捋一捋!这是一个普通的Html网页,没错,但是它引用了OpenLayers的CSS样式和js文件:
[html] view plain copy
- rel="stylesheet" href="http://openlayers.org/en/v3.3.0/css/ol.css" type="text/css">
[html] view plain copy
- src="http://openlayers.org/en/v3.3.0/build/ol.js" type="text/javascript">
然后又扯了一段代码:
[html] view plain copy
- type="text/javascript">
- var map = new ol.Map({
- target: 'map',
- layers: [
- new ol.layer.Tile({
- source: new ol.source.MapQuest({layer: 'sat'})
- })
- ],
- view: new ol.View({
- center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
- zoom: 4
- })
- });
在这段代码中,主要是实例化了一个OpenLayers的Map对象,于是就显示了地图!Map是何许人也?它是OpenLayers中最主要的对象!要初始化一幅地图,需要一个view,一个或多个图层(layers),一个目标容器(target)。在GitHub上的OpenLayers主页上的Map定义可以看到:
[html] view plain copy
- ol.MapProperty = {
- LAYERGROUP: 'layergroup',
- SIZE: 'size',
- TARGET: 'target',
- VIEW: 'view'
- };
定义了一个数组,主要有layers、target和view,代表map对象 的三个主要属性。
[html] view plain copy
- ol.Map.prototype.getTarget = function() {
- return /** @type {Element|string|undefined} */ (this.get(ol.MapProperty.TARGET));
- };
- goog.exportProperty(
- ol.Map.prototype,
- 'getTarget',
- ol.Map.prototype.getTarget);
getTarget主要是取得以上的数组的TARGET属性值,而exportProperty是Google的Closure库的一个函数,函数原型是:
[html] view plain copy
- goog.exportProperty = function(object, publicName, symbol) {
- object[publicName] = symbol;
- };
就是将一个自定义的属性symbol导出到object定义的对象中,而publicName就是导入后的属性名。
[html] view plain copy
- ol.Map.prototype.getTargetElement = function() {
- var target = this.getTarget();
- return goog.isDef(target) ? goog.dom.getElement(target) : null;
- };
根据id名来找到放置map的HTML元素。
[html] view plain copy
- ol.Map.prototype.getLayerGroup = function() {
- return /** @type {ol.layer.Group} */ (this.get(ol.MapProperty.LAYERGROUP));
- };
- goog.exportProperty(
- ol.Map.prototype,
- 'getLayerGroup',
- ol.Map.prototype.getLayerGroup);
这便是和以上同理,将layerGroup初始化!
[html] view plain copy
- layers: [
- new ol.layer.Tile({
- source: new ol.source.MapQuest({layer: 'sat'})
- })
- ]
用OpenLayers提供的瓦片作为Map的图层,取用名称为“sat”的图层。
[html] view plain copy
- ol.Map.prototype.getView = function() {
- return /** @type {ol.View} */ (this.get(ol.MapProperty.VIEW));
- };
- goog.exportProperty(
- ol.Map.prototype,
- 'getView',
- ol.Map.prototype.getView);
同理,初始化view。
[html] view plain copy
- view: new ol.View({
- center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
- zoom: 4
- })
设置一些视区的参数,其中center是设置地图中心,transform函数是将给定的坐标从4326转到3857坐标系下,4326即是WGS84坐标系!zoom参数是设置缩放等级!
至此,地图已经成功加载到网页中,并且可以进行缩放和平移(初始化Map对象时,默认加上此功能)。
总结
我们本着知其然,并知其所以然的人道主义精神,分解了OpenLayers3的Map对象,主要用于显示地图。但是我们肯定不会满足于仅仅显示并缩放地图,我们还想点击相应的兴趣点,地图要能与我交互,弹出一个框,显示详细信息的框!
我们下次再说哈!
OpenLayers系列(3)——使用第三方地图API(GoogleMap),聚合多个地图数据
使用第三方API及地图数据
首先是一个调用GoogleMap的例子
[html] view plaincopyprint?
- >
- <html< span=""> lang='en'>
- <meta< span=""> charset='utf-8' />
- <script< span=""> type='text/javascript' src='OpenLayers.js'>
- <script< span=""> type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=false'>//引用Google地图在线脚本
- <script< span=""> type='text/javascript'>
- var map;
- function init() {
- map = new OpenLayers.Map('map_element', {});
- var google_hybrid = new OpenLayers.Layer.Google(//创建Google图层子类
- "Google Hybrid",
- {type: google.maps.MapTypeId.HYBRID}//当前google支持的map type之一
- );
- var google_physical = new OpenLayers.Layer.Google(
- "Google Physical",
- {type: google.maps.MapTypeId.TERRAIN}
- );
- var google_satellite = new OpenLayers.Layer.Google(
- "Google Satellite",
- {type: google.maps.MapTypeId.SATELLITE}
- );
- var google_streets = new OpenLayers.Layer.Google(
- "Google Streets",
- {}
- );
- map.addLayers([google_hybrid,google_physical,google_satellite,
- google_streets]);
- map.addControl(new OpenLayers.Control.LayerSwitcher());
- if(!map.getCenter()){
- map.zoomToMaxExtent();
- }
- }
- <body< span=""> onload='init();'>
- <div< span=""> id='map_element' style='width: 500px; height: 500px;'>
于之前的例子一样,运行后效果图如下:
代码分析
首先,引用第三方脚本,这里是google map js;
其次,使用OpenLayers支持的Layer子类创建相应的图层对象。这里的第三方库必须是OpenLayers自己已经支持的,幸运的是它已经支持几乎所有流行的第三方map server,如:Google map, Yahoo! map, Bing map, OpenStreetMaps等。在创建相应地图的图层时,必须查看对应的文档以确定它所支持的layer以及这些layer是base layer还是overlay layer。上例中所使用的几个图层均是base layer,可以google map官方网站(https://developers.google.com/maps/documentation/javascript/maptypes)找到相应文档。
调用第三方API到这里就完成了,不需要太多的工作。但这也只是为接下来的内容做准备。
聚合多个地图数据
就是说要在同一张地图上使用来自不同map server的数据,根据业务需要来调整图层。
要完成这一工作,首先必须清楚一个概念:投影(Projection)。
任何一个map server都有自己的投影规则,相应的会有不同的坐标系统。要想在同一地图上显示来自不同地图服务器的数据,必须要确保让不同的map server使用同一投影规则并投影到同一种坐标系中。这就要看map server本身是否支持多种投影规则了,如果两个服务器本身就不支持统一的投影,那根本不可能在同一地图上显示其数据。
Google map支持的投影规则是流行的球形墨卡托投影法,其使用的坐标系与之前例子中的WMS不同,google map使用x y 坐标系而WMS使用经纬度坐标系。为了统一,必须一开始设定一种两个服务器同时支持的投影规则。
要把Google map和其他图层聚合在一起需要三步:
1.设置合适的地图投影属性
2.确保其他图层的sphericalMercator属性被设置为true(该投影规则是google目前所用的)
3.使其他光栅图层(即非矢量和图片类型的图层)如WMS映射到地图投影中。
示例(Google map & WMS & Vector layer)
代码:
[html] view plaincopyprint?
- >
- <html< span=""> lang='en'>
- <meta< span=""> charset='utf-8' />
- <script< span=""> type='text/javascript' src='OpenLayers.js'>
- <script< span=""> type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=false'>
- <script< span=""> type='text/javascript'>
- var map;
- function init() {
- map = new OpenLayers.Map('map_element',{
- maxExtent: new OpenLayers.Bounds(//设置地图域
- -128 * 156543.0339,
- -128 * 156543.0339,
- 128 * 156543.0339,
- 128 * 156543.0339),
- maxResolution: 156543.0339,//最大分辨率
- units: 'm',//度量单位
- projection: new OpenLayers.Projection('EPSG:900913'),//投影规则
- displayProjection: new OpenLayers.Projection("EPSG:4326"),//显示的投影规则
- });
- var google_streets = new OpenLayers.Layer.Google(
- "Google Streets",
- {numZoomLevels: 20}
- );//google map默认sphericalMercator=true
- var wms_layer = new OpenLayers.Layer.WMS(
- 'OpenLayers WMS',
- 'http://vmap0.tiles.osgeo.org/wms/vmap0',
- {layers: 'basic,clabel,ctylabel,statelabel', transparent: true},
- {isBaseLayer: false,//确保用WMS做overlay layer
- opacity: .7}
- );
- var vector_layer = new OpenLayers.Layer.Vector(
- 'Editable Vectors');//创建一个矢量图层
- //添加一个矢量编辑工具条,该工具条可以在矢量图层上添加点或多边形
- map.addControl(new OpenLayers.Control.EditingToolbar(vector_layer));
- map.addLayers([google_streets, wms_layer, vector_layer]);
- map.addControl(new OpenLayers.Control.LayerSwitcher());
- if(!map.getCenter()){
- map.zoomToMaxExtent();
- }
- }
- <body< span=""> onload='init();'>
- <div< span=""> id='map_element' style='width: 500px; height: 500px;'>
版权声明:本文为博主原创文章,未经博主允许不得转载。
OpenLayers 3加载本地Google切片地图
OpenLayers 3加载本地Google切片地图
时间: 2015-07-28 22:54:19 阅读: 740 评论: 0 收藏: 0 [点我收藏+]
OpenLayers 提供了ol.source.XYZ 接口用以加载切片地图。
本地切片地图是用地图切片下载器下载的Google道路图层,由于软件未激活,所以每张切片地图上都有软件作者的联系方式,请忽略。
下载下来的切片地图通过Windows自带的iis发布,这样就可以通过网络地址来访问切片数据。
首先,根据ol3的接口创建了一个js方法,这个方法会根据传来的参数创建一个类型为ol.layer.Tile的图层。
var TileLayer = function (options) { var layer = new ol.layer.Tile({ extent: ol.proj.transformExtent(options.mapExtent, options.fromProject, options.toProject), source: new ol.source.XYZ({ attributions: [options.attribution], url: options.url, tilePixelRatio: options.tilePixelRatio, // THIS IS IMPORTANT minZoom: options.mapMinZoom, maxZoom: options.mapMaxZoom }) }); return layer; }
配置Google切片地图的参数,并调用TileLayer方法,把返回的layer添加到地图中就可以看到Google地图正确的覆盖到OpenLayers提供的底图上。
//定义Google切片参数 var defaults = { url: ‘http://localhost:8082/{z}/{x}/{y}.png‘, mapExtent: [-2.0037508342787E7, -2.0037508342787E7, 2.0037508342787E7, 2.0037508342787E7], mapMinZoom: 1, mapMaxZoom: 14, attribution: new ol.Attribution({ html: ‘Tiles © GoogleMap‘ }), tilePixelRatio: 1, fromProject: "EPSG:102100", toProject: "EPSG:3857" }; var layer = new TileLayer(defaults);
配置中的formProject是指Google地图使用的投影,toProject是指底图使用的投影。
fromProject: "EPSG:102100", toProject: "EPSG:3857"
使用这种配置看似比较复杂,但是在很多情况下还是比较有用的,比如我们可以改变mapExtent来控制切片涂层加载的范围,改变zoom控制加载切片的比例范围,等等。
OpenLayers 3 之 加载百度地图
分类:
WebGIS(28)
OpenLayers(17)
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
虽然百度地图有自己的 JavaScript API,但是有时候,一个项目已经用 OpenLayers 做了很多功能,不可能弃之不用,同时,又想使用百度地图,该怎么办呢?所以很多人想使用 OpenLayers 调用百度地图,本文就讨论一下其可能性和实现原理。
一、 地图调用原理分析
我们以百度地图为例,分析其地图调用原理,我们都使用过百度地图,在网速不快的情况下,肯定有过感受,地图是一块一块加载的,从这里我们就可以看出,地图是被切成了很多块的小图片,调用时按照一定规则请求需要的“切片”,可视区域以外的“切片”不加载,这样可以减小数据传输数据量,使地图加载更快。
我们 F12 查看浏览器的网络图片请求,可以证实我们看到的现象,每一个图片切片都是 256*256 尺寸的图片:
图1 地图请求
仔细看每一个请求:
其中,http://online0.map.bdimg.com/onlinelabel/?,表示百度地图的图片缓存地址;qt=tile 表示请求类型(Quest Type)为 切片(tile);x=707&y=217,请求的切片位于整张地图中的坐标位置;z=12,是指当前的地图缩放级别是 第 12 级,为什么会分级呢?因为浏览地图时我们注意到地图是可以放大缩小的,放大后我们可以看到地物的更多细节,同时 z 值会越大;styles=pl,可能是返回地图的样式;udt=20151021,应该是上一次切片的更新时间(Update DateTime)是2015年10月21号,为什么需要更新地图呢?因为地图是真实世界的抽象,真实世界就是处在不断的变化中的,所以地图要实时更新;至于后两个参数 scaler=1&p=1 ,本人不是百度的员工,就不太清楚是什么了。
所有的“切片”请求,一共有 21 个,用网格形式表示“切片”布局如下图(其中横坐标和纵坐标是由请求 URL 中的 x 和 y 参数决定的):
图2 切片分布示意图
那么我们清楚了地图请求的原理,下一步就是要验证一下请求百度的地图是否需要一定的权限呢?我们点击每一个请求的 URL ,可以看到其对应的图片,说明不需要特殊的权限便可以访问百度的切片地图,这样我们就可以自己编写程序来调用百度的切片地图。
二、 编写调用程序
现在,我们要着手编写程序调用百度地图了,最终的结果是在浏览器中显示地图,那么我们首先要根据用户的交互确定两个主要的参数:缩放级别、视图中需要的切片 x y 索引。然后构造相应的请求 URL,再按照相应的索引拼接地图切片,这样我们就能完成调用地图了。
好了,讲完原理,我们是否要马上就开始着手编写吗?不要这么着急下手,我们在开始一项任务的时候,首先在比如 GitHub 的开源项目网站上寻找一下是否有已经实现你需要功能的开源项目,要尽量避免重复造轮子。OpenLayers 便是我们理想的 JavaScript 工具库,实现了大部分我们需要的操作,所以我们不必再需要自己从头开始构建。
首先贴出实现调用效果图:
图3 OpenLayers 3 调用百度地图
2.1 关键代码
下面是调用的关键代码:
<script type="text/javascript"> var projection = ol.proj.get("EPSG:3857"); var resolutions = []; for(var i=0; i<19; i++){ resolutions[i] = Math.pow(2, 18-i); } var tilegrid = new ol.tilegrid.TileGrid({ origin: [0,0], resolutions: resolutions }); var baidu_source = new ol.source.TileImage({ projection: projection, tileGrid: tilegrid, tileUrlFunction: function(tileCoord, pixelRatio, proj){ if(!tileCoord){ return ""; } var z = tileCoord[0]; var x = tileCoord[1]; var y = tileCoord[2]; if(x<0){ x = "M"+(-x); } if(y<0){ y = "M"+(-y); } return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=20151021&scaler=1&p=1"; } }); var baidu_layer = new ol.layer.Tile({ source: baidu_source }); var map = new ol.Map({ target: 'map', layers: [baidu_layer], view: new ol.View({ center: [12959773,4853101], zoom: 12 }) }); script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
注:
1、页面需要引用 openlayers 3.10.1, js 和 css
2、页面需要有一个 DIV 元素,其 ID 属性为 “map”
我们分析一下以上的关键代码,首先,初始化一个图片切片地图数据源,var baidu_source = new ol.source.TileImage({}),ol.source.TileImage 是 OpenLayers 中专门负责调用地图以切片图片存放的类,其中给定了三个参数,projection 参数指定了地图切片使用的坐标系,一般是 EPSG:3857(球形墨卡托投影坐标系),谷歌地图、必应地图都是使用的这个坐标系,可以说是国际通用的惯例,tileGrid 指定了切片使用的网格的模式,tileUrlFunction 指定一个回调函数,这个回掉函数第一个参数中包含三个变量,主要是 当前缩放级别(z),切片的 x y 索引,每次用户与地图交互,比如 缩放、平移等,就会触发会触发回调函数,该函数根据传入的变量参数构造图片切片的 URL 地址。
然后,使用图片切片地图数据源初始化一个 切片图层: var baidu_layer = new ol.layer.Tile({source: baidu_source }); 最后将图层加入到地图中(最后一段代码),这样我们就完成了核心代码,刷新页面,你就会看到上图的效果。
三、 总结
结果表明,使用 OpenLayers 3 可以成功调用百度地图。文章里主要讲了百度地图的切片地图的调用原理,并简要阐释了切片地图的组织结构,以及使用 OpenLayers 3 调用百度地图的关键代码。
本文并没有对其他的地图做实验,如 谷歌地图、必应地图、腾讯地图、搜狗地图、天地图等地图。如果需要使用相关地图,你可以使用本文的方法检查其可用性,找出其请求规律,然后根据实际情况构造 URL ,替换关键代码中 tileUrlFunction 中 return 的URL。
好的,就写到这里,有什么问题,可以到文章下面评论。
参考文章
OpenLayers学习--加载ArcGIS缓存
数据准备
使用ArcGIS发布地图,并切图得到松散的缓存瓦片数据,一般存储路径为:C:\arcgisserver\directories\arcgiscache
使用ArcGIS10.2之前的ArcGIS Server数据目录可能不一样,请自己找到arcgiscache 文件夹。
本实例使用的缓存配置如下图:
发布数据
本步骤主要目的是将ArcGIS缓存的瓦片发布的到服务器上,使外网可以访问到瓦片数据。
将缓存路径发布的IIS上(路径为:http://localhost:9999),如下图:
加载缓存类(该类可以加载任何ArcGIS发布的数据)
关键步骤就是重现getURL()方法,当地图刷新的时候可以找到服务器中切片存放的路径。
OpenLayers加载缓存文件的代码如下:
[javascript] view plain copy
- OpenLayers.Layer.ESRICache = OpenLayers.Class(OpenLayers.Layer.TMS, {
- tileOriginCorner: 'tl',
- type: 'png',
- initialize: function (name, url, options) {
- OpenLayers.Layer.TMS.prototype.initialize.apply(this, [name, url,options]);
- },
- getURL: function (bounds) {
- var z = map.getZoom();
- var res = map.getResolution(z);
- var x = parseInt((bounds.getCenterLonLat().lon - this.tileOrigin.lon) / (256 * res));
- var y = parseInt((this.tileOrigin.lat - bounds.getCenterLonLat().lat) / (256 * res));
- x = 'C' + OpenLayers.Number.zeroPad(x, 8, 16);
- y = 'R' + OpenLayers.Number.zeroPad(y, 8, 16);
- z = 'L' + OpenLayers.Number.zeroPad(z, 2, 10);
- return this.url + z + '/' + y + '/' + x + '.' + this.type;
- },
- });
使用示例
初始化地图图层:
[javascript] view plain copy
- var esri = new OpenLayers.Layer.ESRICache("ArcGIS缓存", 'http://localhost:9999/',
- {
- resolutions: [
- 0.01903568804664224,
- 0.00951784402332112,
- 0.00475892201166056,
- 0.00237946100583028,
- 0.00118973050291514
- ],
- maxExtent: [103.59974, 24.621635, 109.55483, 29.224079],
- tileOrigin: new OpenLayers.LonLat(-400, 400)
- });
初始化地图:
[javascript] view plain copy
- map = new OpenLayers.Map('map', {
- projection: "EPSG:4326",
- displayProjection:"EPSG:4326",
- //maxExtent: [103.59974, 24.621635, 109.55483, 29.224079],
- controls:[]
- });
- map.addLayer(esri);
OK,打开浏览器查看地图
openlayers 加载 arcgis rest服务
openlayers 加载 arcgis rest服务
var mapOptions = { maxExtent: new OpenLayers.Bounds(-174,18.4,-63.5,71), maxResolution: 0.25, projection: "EPSG:4326"}; map = new OpenLayers.Map( 'map', mapOptions ); layer = new OpenLayers.Layer.ArcGIS93Rest( "ArcGIS Server Layer", "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/export", {layers: "show:0,2"}); map.addLayer(layer);
有效参数的设置:api给出的是
format{String} MIME type of desired image type.layers{String} Comma-separated list of layers to display.srs{String} Projection ID.
其中 layers 测试,show:0,2,显示出来的图层,hide:0 可隐藏对应图层
其中,0,1,2表示Layer的索引,与wms layers的设置顺序正好相反,wms是逆序,
OpenLayers 3 之 加载天地图
分类:
OpenLayers(17)
WebGIS(28)
Web前端(1)
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
要使用 OpenLayers 3 加载天地图,首先要弄清楚天地图发布的原理,以及遵循的发布规范,上一篇中我们提到了使用 OpenLayers 3 加载百度地图,我们提到一般网络地图为了加快访问速度,都采用缓存切片地图的方式,天地图也不例外,而且原理极其类似,但是其切片的索引组织方式还是有一些不同,虽然都是切片,但是切片的起始坐标原点不一致,百度地图是屏幕的左下角,而天地图是屏幕的左上角(与谷歌地图一致),且所在的坐标系是球形墨卡托投影坐标系(EPSG:3857)。
针对这种形式发布的地图切片,OpenLayers 3 中有一个对应的数据源(ol.source)类 – ol.source.TileImage,上一篇的 OpenLayers 3 加载百度地图,就是使用的这个类。当然,我们使用这个类,加载天地图也是可以的,但是天地图的发布方式和切片组织方式与谷歌地图是一致的,在 OpenLayers 3 中有针对加载谷歌地图专门写好的类 - ol.source.XYZ,这个类是 ol.source.TileImage 的一个特例,继承了 ol.source.TileImage,其中 XYZ 分别对应切片所在的 x y 坐标和当前的缩放级别 z。
注:代码部分基于上一篇文章, OpenLayers 3 之 加载百度地图。
确定服务地址
天地图共有 8 个服务地址,子域名分别从 t0 到 t7,如下列表所示。获取的方法和上一篇中获取百度地图服务地址是一样的,F12 查看了浏览器的通信信息:
- http://t0.tianditu.com/DataServer?
- http://t1.tianditu.com/DataServer?
- http://t2.tianditu.com/DataServer?
- http://t3.tianditu.com/DataServer?
- http://t4.tianditu.com/DataServer?
- http://t5.tianditu.com/DataServer?
- http://t6.tianditu.com/DataServer?
- http://t7.tianditu.com/DataServer?
加载路网
我们查看一个路网切片的 url 地址: http://t4.tianditu.com/DataServer?T=vec_c&x=3233&y=673&l=12,一共有四个参数,T=vec_c表示请求的是路网数据,x 表示切片的 x 轴坐标,y 表示切片的y轴坐标,z表示切片所在的缩放级别。我们使用 ol.source.XYZ 加载切片,并将获取的数据初始化一个切片图层 ol.layer.Tile:
var tian_di_tu_road_layer = new ol.layer.Tile({ title: "天地图路网", source: new ol.source.XYZ({ url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}" }) }); map.addLayer(tian_di_tu_road_layer);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
我们可以看到 ol.source.XYZ 有一个 url 参数,表示切片地址的模板: http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z},在使用 OpenLayers 时候,用户的操作都会被转化为相应的x、y、z值,并赋予地址模板,这样就可以根据用户的操作请求需要的切片了。
加载完成后,发现只有路网图片,并没有路段的名称等注记层,我们并没有做错什么,只是天地图是将路网图层和注记图层分开发布的,我们还要单独请求注记图层,然后叠加在路网上面,才会看到和百度地图一样的效果:
图1 天地图路网切片
我们可以想象,注记图层应该是一个除了文字之外都是透明的 PNG 格式的图片,接下来我们就来加载注记图层:
图2 天地图注记图层切片
加载注记图层
使用同样的方法,加载注记图层,可以看到其 url 参数中,只有 T 参数变化了,cva_w 表示请求的切片类型是注记图层切片:
var tian_di_tu_annotation = new ol.layer.Tile({ title: "天地图文字标注", source: new ol.source.XYZ({ url: 'http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}' }) }); map.addLayer(tian_di_tu_annotation);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
通过加载路网和注记图层后,我们就可以看到效果了:
图3 天地图调用结果
加载卫星影像
天地图除了路网数据和注记数据之外,还有卫星影像切片数据,所以我们可以使用同样的方法加载卫星影像,同样, url 参数中的 T参数值 img_w 表示请求的数据类型是卫星影像切片。代码和效果图如下:
var tian_di_tu_satellite_layer = new ol.layer.Tile({ title: "天地图卫星影像", source: new ol.source.XYZ({ url: 'http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}' }) }); map.addLayer(tian_di_tu_satellite_layer);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
图4 天地图卫星影像切片
总结
从结果看,天地图并没有对地图进行偏移处理,这点来看要比百度地图好多了。天地图本意就是服务大众,所以其数据可以供人们免费调用,也开放了数据服务接口,但其服务文档太过简单,没有LBS或者GIS相关知识的人,文档相当于没有,就算是懂点专业知识,也要鼓捣很长时间。
总之,我们调用天地图的数据作为底图还是非常合适的,不用承担法律责任,因为它是开放的,可以免费使用。
好的,就写到这里,有什么问题,可以在文章下面留言。
OpenLayers 3 之 地图图层数据来源(ol.source)详解
分类:
WebGIS(28)
OpenLayers(17)
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
source 是 Layer 的重要组成部分,表示图层的来源,也就是服务地址。除了在构造函数中制定外,可以使用 layer.setSource(source) 稍后指定。
一、包含的类型
- ol.source.BingMaps ,必应地图的切片数据,继承自ol.source.TileImage;
- ol.source.Cluster,聚簇矢量数据,继承自ol.source.Vector;
- ol.source.ImageCanvas,数据来源是一个 canvas 元素,其中的数据是图片,继承自 ol.source.Image;
- ol.source.ImageMapGuide,Mapguide 服务器提供的图片地图数据,继承自 ol.source.Image,fire ol.source.ImageEvent;
- ol.source.ImageStatic,提供单一的静态图片地图,继承自ol.source.Image;
- ol.source.ImageVector,数据来源是一个 canvas 元素,但是其中的数据是矢量来源 ol.source.Vector,继承自 ol.source.ImageCanvas;
- ol.source.ImageWMS,WMS 服务提供的单一的图片数据,继承自 ol.source.Image,触发 ol.source.ImageEvent;
- ol.source.MapQuest,MapQuest 提供的切片数据,继承自 ol.source.XYZ;
- ol.source.OSM,OpenStreetMap 提供的切片数据,继承自 ol.source.XYZ;
- ol.source.Stamen,Stamen 提供的地图切片数据,继承自 ol.source.XYZ;
- ol.source.TileVector,被切分为网格的矢量数据,继承自 ol.source.Vector;
- ol.source.TileDebug,并不从服务器获取数据,而是为切片渲染一个网格,继承自 ol.source.Tile;
- ol.source.TileImage,提供切分成切片的图片数据,继承自 ol.source.Tile,触发 ol.source.TileEvent;
- ol.source.TileUTFGrid,TileJSON 格式 的 UTFGrid 交互数据,继承自 ol.source.Tile;
- ol.source.TileJSON,TileJSON 格式的切片数据,继承自 ol.source.TileImage;
- ol.source.TileArcGISRest,ArcGIS Rest 服务提供的切片数据,继承自 ol.source.TileImage;
- ol.source.WMTS,WMTS 服务提供的切片数据。继承自 ol.source.TileImage;
- ol.source.XYZ,XYZ 格式的切片数据,继承自 ol.source.TileImage;
- ol.source.Zoomify,Zoomify 格式的切片数据,继承自 ol.source.TileImage。
上面介绍的都是可以实例化的类,还有一部分基类,不能被实例化,只负责被继承,有:
- ol.source.Image,提供单一图片数据的类型,直接继承自 ol.source.Source;
- ol.source.Tile,提供被切分为网格切片的图片数据,继承自 ol.source.Source;
- ol.source.Vector,提供矢量图层数据,继承自 ol.source.Source;
二、用法说明
1. ol.source.Vector
矢量图层的数据来源
1.1 事件
包含四个事件,addfeature,changefeature,clear,removefeature。
addfeature,当一个要素添加到 source 中触发;
changefeature,当要素变化时触发;
clear,当 source 的 clear 方法调用时候触发;
removefeature,当要素移除时候发生。
1.2 参数
接受的参数:
/** * @typedef {{attributions: (Array.<ol.Attribution>|undefined), * features: (Array.<ol.Feature>|undefined), * format: (ol.format.Feature|undefined), * loader: (ol.FeatureLoader|undefined), * logo: (string|olx.LogoOptions|undefined), * strategy: (ol.LoadingStrategy|undefined), * url: (string|undefined), * wrapX: (boolean|undefined)}} * @api */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- attribution,地图右下角的 logo 包含的内容;
- features,地理要素,从字符串读取的数据;
- format,url属性设置后,加载要素使用的数据格式,采用异步的 AJAX 加载;
- loader,加载要素使用的加载函数;
- logo,logo包含的内容;
- strategy,加载要素使用的策略,默认是 一次性加载所有要素;
- url,要素数据的地址;
- wrapX,是否在地图水平坐标轴上重复,默认是 true。
1.3 实例
features 方法
假如有一个包含空间数据的字符串,geojsonObject,是GeoJSON字符串格式,那么可以用来初始化一个图层。
var vectorSource = new ol.source.Vector({ features: (new ol.format.GeoJSON()).readFeatures(geojsonObject) }); var vectorLayer = new ol.layer.Vector({ source: vectorSource, style: style }); map.addLayer(vectorLayer);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
url + format 方法
如果有一个文件作为数据源,那么可以配置 url 属性来加载数据:
var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ url: 'data/geojson/countries.geojson', format: new ol.format.GeoJSON() }) });
- 1
- 2
- 3
- 4
- 5
- 6
这两种方法中都会指定数据来源格式, 矢量数据源支持的格式包含很多:gml、EsriJSON、geojson、gpx、igc、kml、osmxml、ows、polyline、topojson、wfs、wkt、wms capabilities(兼容 wms 的格式)、 wms getfeatureinfo、 wmts capabilities、xlink、xsd等格式。这些格式都有readFeatures 、readFeature 和readGeometry 方法用于读取数据。
2. ol.source.Tile
提供被切分为切片的图片地图数据
可配置的选项
/** * @typedef {{attributions: (Array.<ol.Attribution>|undefined), * extent: (ol.Extent|undefined), * logo: (string|olx.LogoOptions|undefined), * opaque: (boolean|undefined), * tilePixelRatio: (number|undefined), * projection: ol.proj.ProjectionLike, * state: (ol.source.State|undefined), * tileGrid: (ol.tilegrid.TileGrid|undefined), * wrapX: (boolean|undefined)}} */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
与 vector 一样的选项就不介绍了,介绍与 vector 特有的选项:
- extent,地图视图默认的坐标范围;
- opaque,不透明与否,一个布尔值,默认 false;
- tilePixelRatio,切片的大小调整选项,如 256 × 256,和 512 × 512;
- projection,投影;
- state,地图所处的状态,包括undefined,loading,ready,error;
- tileGrid,覆盖在地图上的格网;
接受的事件
- tileloadstart,切片开始加载时触发的事件;
- tileloadend,切片加载完毕触发事件;
- tileloaderror,切片加载出错时的处理。
3. ol.source.Image
提供单一的图片地图。
可以配置的选项
/** * @typedef {{attributions: (Array.<ol.Attribution>|undefined), * extent: (null|ol.Extent|undefined), * logo: (string|olx.LogoOptions|undefined), * projection: ol.proj.ProjectionLike, * resolutions: (Array.<number>|undefined), * state: (ol.source.State|undefined)}} */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- resolutions,地图分辨率。其他的选项都与以上的一样。
触发的事件
- imageloadstart,图片地图开始加载触发的事件;
- imageloadend,图片地图加载完毕触发的事件;
- imageloaderror,图片地图加载出错时触发的事件。
四、总结
source 是 layer 中必须的选项,定义着地图数据的来源,与数据有关的函数,如addfeature、getfeature等函数都定义在 source 中,而且数据源支持多种格式。
专业从事基于C#,WinForm ,WPF,Silverlight,WCF以及MS Sql Server 2000/2005/2008/2012 Oracle 9i/10g/11g数据库系统的ERP,CRM,企业进销存等各种数据库管理系统开发。Asp.net,Asp.net mvc,Webservice,WCF, Webapi等服务程序开发。
基于Oracle MySQL MSSql postgresql各种数据库的管理系统数据同步服务。以及基于MapXtreme, Arcgis Engine ,以及基于Arcgis for silverlight/Javascript的WebGIS等相关的GIS系统二次开发。基于Windows 10 Mobile的移动端开发方案。针对各种系统的二次开发维护,并提供相关开发的技术性支持,如程序BUG解决,应用系统架构,技术难题攻克等相关技术服务。
联系方式: QQ :80163278(devgis) 邮箱:devgis@qq.com