openlayers入门开发系列之地图展示篇

GIS之家一直打算写一个openlayers入门开发系列文章(openlayers目前版本用4.x),只是一直没抽出时间来整理;本文是openlayers入门开发系列的第一篇:地图展示篇,后续会持续更新一系列入门开发文章。

整个系列的系统主界面会随着功能增加而对应改变,大体布局如下:

地图展示篇运用到了openlayers的核心类

ol.Map

这是OpenLayers的核心组件,对于要渲染的地图,需要一个视图、一个或多个图层和目标容器;

关于Map详情看官方的api说明,里面具有有哪些函数、属性以及事件等等。

官方默认的Map创建代码如下:

var map = new ol.Map({
  view: new ol.View({
    center: [0, 0],
    zoom: 1
  }),
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    })
  ],
  target: 'map'
});

ol.View

View对象表示地图的简单2D视图,用来改变地图的中心、分辨率和旋转的对象。初始化View对象有很多参数属性,比如center,zoom,extent,extent等等,这些设置跟地图加载展示息息相关,详情看官方的api说明。

ol.source.TileWMS

这是图层类,用于WMS服务器的瓦片数据的层源,详情看官方的api说明。

地图展示篇核心代码实现过程,加载geoserver部署的瓦片数据

1.地图配置文件Config.js,配置地图服务信息:

bxmap.config = bxmap.config || {};
/**
 * 地图图层配置,能力包括
 * 1.地图分屏及地图内容不同;
 * 2.不同平台发布
 * 3.底图切换,及底图多层时分等级(例如底图包括:影像图层、道路图层、注记图层)
 */
bxmap.config.MapConfig = {
    "projection":"EPSG:3857",
    "geoserver_url": "http://localhost:8180/geoserver",
    "tile_grids": [
        {
            "grid_id":"grid_GDImage",
            "extent":[-2.0037507842788246E7,-3.024097195838617E7,2.0037507842788246E7,3.0240971958386205E7],
            "origin":[-2.0037508342787E7,2.0037508342787E7],
            "resolutions":[156543.03392800014,78271.51696399994,39135.75848200009,19567.87924099992,9783.93962049996,4891.96981024998,2445.98490512499,1222.992452562495,611.4962262813797,305.74811314055756,152.87405657041106,76.43702828507324,38.21851414253662,19.10925707126831,9.554628535634155,4.77731426794937,2.388657133974685,1.1943285668550503,0.5971642835598172,0.29858214164761665],
            "tile_size":[256,256]
        }
    ],
    "layers":                       
        {"layer_id":"GISSERVER_AnJiMapImg","server":"geoserver","level":0,"name":"AnJiMapImg","visible":true,"format":"image/jpeg","tile_grid":"","url":"/gwc/service/wms"},
    ],
    "olviews":[
            {"view_id":"id_view_1","center":[13302958.014575263,3575060.50586022],"zoom":12,"max_zoom":18,"min_zoom":8}
    ],
    "maps":[
        {
            "map_id":"map_1",
            "description":"地图",
            "layer_groups":[
               {
                   "group_id":"GDImage_map",
                                "layers":[
                                    {"id":"map_1","pid":"root","title":"安吉县","tip":"安吉县"},
                                    {"id":"g-1","pid":"map_1","title":"影像图","tip":"影像图","visible":true,"inswitcher":false,"layers":["GISSERVER_AnJiMapImg"]}
                   ]
                }
            ],
            "olview":"id_view_1"
        }
    ]
};

地图配置参数说明:

projection:地图坐标系;

geoserver_url:geoserver服务器地址;

tile_grids:设置geoserver部署的瓦片服务WMS的参数信息值,比如瓦片大小、分辨率,切图原始点坐标、范围等等;

layers:配置地图加载图层组信息;

olviews:配置地图View组信息,主要是设置地图初始化位置;

maps:配置地图组信息,每个地图里面配置图层以及视图;

2.地图展示实现核心代码部分:

(1)创建一个地图实例:

 //初始化地图
var bmap = bxmap.Map.createDefaultMap('map','map_1'); //创建一个地图实例

(2)createDefaultMap函数

/**
 * 根据配置文件创建地图
 * @param target target - {Element|String}地图dom
 * @param mapId 配置文件{bxmap.config.MapConfig}中map_id
 * @returns {bxmap.Map} 返回地图
 */
bxmap.Map.createDefaultMap = function(target, mapId){
	var reader = new bxmap.reader.MapConfigReader(bxmap.config.MapConfig, [mapId]);
	var container = new bxmap.layer.DefaultLayerContainer({
		"reader": reader,
		"map_id": mapId
	});
	var bmap = new bxmap.Map({
		"target" : target,
		"container" : container
	});
	return bmap;
}

(3)bxmap.Map自定义类,继承ol基类

bxmap.Map = function(options) {
	ol.Object.call(this);
    /**
	 * @readonly
	 * @description zoomToExtent/zoomToFeature可放大到的最大级别
     * @type {number}
     */
	this.ZoomMaxLevel = 15;
	/**
	 * @private
	 * @description 设置
	 */
	this.setting = {
		"bx_add_mouse_layer":"bx_add_mouse_layer",//是否已添加鼠标样式图层
		"wrap":"wrap"//地图包装类
	};
	/**
	 * @private
	 * @description ol地图对象
	 * @type {ol.Map}
	 */
	this.map = null; //{ol.Map}
	/**
	 * @public
	 * @description 清除对象容器
	 * @type {bxmap.DataClear}
	 */
	this.dataClear = null;//new bxmap.DataClear();
	
	var opt_options = options || {};
	this._layerContainer = opt_options.container; //{bxmap.layer.LayerContainer}
	this._linkable = opt_options.linkable == undefined ? true :opt_options.linkable;
	if(this._layerContainer != null){
		var view = this._layerContainer.getView();
		this.initializeMap(opt_options.target, view);
		this.updateBaseLayerGroup(this._layerContainer);
	}
	this._linkMouseStyleLayer = null;//地图联动鼠标样式
}
ol.inherits(bxmap.Map, ol.Object);

(4)initializeMap 创建地图对象

/**
 * 初始化
 * 
 * @param options
 * target - 地图dom
 */
bxmap.Map.prototype.initializeMap = function(target, view) {
	var target = target ? target : 'map';
	var map = this.map = new ol.Map({
		controls : ol.control.defaults({
			attribution : false, // 禁用默认属性
			zoom : false// 禁用默认zoom控件
		}),
		interactions : ol.interaction.defaults({
			shiftDragZoom : false,// 禁用shift矩形放大功能
			doubleClickZoom: false //禁用双击放大,由于双击放大地图为找到监听事件
		}),
		loadTilesWhileInteracting: true,
		target : target,
		view : view
	});

	map.getViewport().setAttribute('tabindex', '0');
	
	//map.addControl(new ol.control.ZoomSlider());
	//初始化添加鼠标样式图层为fasle
	map.set(this.setting.bx_add_mouse_layer,false);
	//包装对象
	map.set(this.setting.wrap,this);
}

(5)bxmap.reader.MapConfigReader

bxmap.reader.MapConfigReader.prototype.readLayer = function(data){
	var layer = null;
	var server = data["server"];
	switch(server){
		case "geoserver":
			layer = this.readGeoserverTileWMS(data);
			break;
		default:
			break;
	}
	if(layer){
		layer.setVisible((data["visible"] == null ? true:data["visible"]));//是否可见
		layer.setZIndex((data["level"] == null ? 0:data["level"]));//设置图层等级
		layer.set(bxmap.CONFIG_LAYER_ID,data["layer_id"]);//图层id
		layer.set("swipetype",data["swipetype"]);//swipetype,有效值left,right
	}
	return layer;
}

(6)readGeoserverTileWMS 加载geoserver瓦片服务WMS

/**
 * @description 读取geoserver WMS/WMS-C图层
 * @param options
 * @param options.projection {ol.ProjectionLike<ol.proj.Projection>|String|undefined} 坐标系
 * @param options.url {String} 服务地址
 * @param options.tile_grid {ol.tilegrid.TileGrid} 瓦片方案
 * @param options.name {String} 图层名称
 * @param options.version {String} 服务版本1.1.0/1.3.0,默认是1.1.0
 * @param param.format {String} 服务图片格式
 * @static
 * @function
 * @memberof bxmap.reader
 * @retruns {ol.source.TileWMS}
 * @example <caption> 读取WMS图层 </caption>
 * //具体的值需要看geoserver服务提供的能力
 * var layer = bxmap.reader.readGeoserverTileWMS({
 *	projection:"EPSG:3857",
 *	url: "http://demo.opengeo.org/geoserver/wms",
 *	name: "ne:ne_10m_admin_1_states_provinces_lines_shp",
 *	version: "1.3.0",
 *	format: "image/jpeg"
 * });
 * @example <caption> 读取WMS-C图层 </caption>
 * //wms服务和瓦片服务主要区别是:
 * // 1.url wms服务是/wms,瓦片服务是/gwc/service/wms
 * // 2.tilegrid 瓦片服务需要瓦片方案
 * var tilegrid = new ol.tilegrid.TileGrid({
 * 	"origin" : [-2.0037508342787E7,2.0037508342787E7],
 * 	"resolutions" : [156543.03392800014,78271.51696399994,39135.75848200009,...],
 * 	"tileSize" : [256,256]
 * });
 * var layer = bxmap.reader.readGeoserverTileWMS({
 *	projection:"EPSG:3857",
 *	url: "http://demo.opengeo.org/geoserver/gwc/service/wms",
 *	name: "ne:ne_10m_admin_1_states_provinces_lines_shp",
 *	version: "1.3.0",
 *	format: "image/jpeg"
 * });
 */
bxmap.reader.readGeoserverTileWMS = function(options){
	var projection = options["projection"];
	var url = options["url"];
	var tileGrid = options["tile_grid"];
	var layerName = options["name"];
	var version = options["version"];
	var format = options["format"];
	
	var params = {
		"LAYERS" : layerName,
		"TILED" : true,
		"VERSION" : "1.1.0"
	};
	if(version){
		params["VERSION"] = version;
	}
	if(format){
		params["FORMAT"] = format;
	}
	
	//gerserver发布的图层WMS/WMS-C
	var source = new ol.source.TileWMS({
		projection : projection,
		url : url,
		params: params,
		tileGrid : tileGrid
	});

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

备注:入门开发系列的demo是基于openlayers api基础上封装以及继承拓展的一些类,比如Map类以及渲染地图器Reader等等,上面的代码只是部分核心代码,其实无非就是两个地方,大概如下:

//gerserver发布的图层WMS/WMS-C
var source = new ol.source.TileWMS({
		projection : projection,
		url : url,
		params: params,
		tileGrid : tileGrid
});

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

var map = new ol.Map({
  view: new ol.View({
    center: [0, 0],
    zoom: 1
  }),
  layers: [
     layer 
  ],
  target: 'map'
});

 

作者: GIS之家

GIS之家微信号:gishome;GIS之家拥有自己的GIS开发团队,均是高校GIS研究生,具备丰富的webgis开发项目工作经验,专注以及热爱研究webgis技术的团队

发表评论

电子邮件地址不会被公开。