Geoserver2.11矢量切片与OL3中的调用展示

原创 2017年02月16日 07:59:21

概述:

本文讲述在Geoserver2.11中如何进行矢量切片以及OL3中的调用展示。


矢量切片简介:

一、提出

GIS的底图一直使用金字塔技术进行切图,使用户能够快速访问指定级别的地图或者影像。但是切图本身是一张图片,无法进行交互。于是又引入了矢量图层用来显示矢量点线面,这通常需要先获取矢量地理数据,然后通过前端将其绘制成不同元素便能通过鼠标进行响应交互了。

这种GIS组织方式在数据量比较小的时候并没有什么大问题,但是在数据量比较大时(例如全国的详细街区数据)存在以下几个问题。

1、同一套数据的展示在不同的需求下可能需要不同的样式(例如,白天和夜间模式)而对于传统栅格切片对此需求必须重新进行切片;

2、由于切片的分辨率固定,分辨率过高切片体积过大,分辨率过低高清屏无法清晰显示。

3、矢量数据的请求如果是按需请求每次都向服务器请求数据加重服务器压力,如果一次请求按需展示,当矢量数据过大时(例如全国的水系数据)对于前端的压力过大。


二、矢量切片的定义

矢量切片是一种利用协议缓冲(Protocol Buffers)技术的紧凑的二进制格式用来传递信息。当渲染地图时矢量切片使用一系列储存的内部数据进行制图。被组织到矢量切片的图层(比如道路、水、区域),每一层都有包含几何图形和可变属性的独立要素(例如姓名、类型等等)。通俗的说,就是将矢量数据以建立金字塔的方式,像栅格切片那样分割成一个一个描述性文件,以GeoJson格式或者以pbf等自定义格式组织,然后在前端根据显示需要按需请求不同的矢量瓦片数据进行Web绘图。


三、常见格式

GeoJson、TopoJson、pbf(Arcgis格式)、KML、 GeoRSS等


四、优势


矢量切片的优势


五、栅格切片与矢量切片的对比


矢量切片


栅格切片


Geoserver中矢量切片的发布:

在geoserver中可发布单个图层,也可发布一个图层组,上述的示例是发布的一个图层组。

1、选择发布图层(组)


选择发布图层组

2、切换到“Tile Cache”面板,设置切片参数


设置切片参数


设置切片网格

注意:

1、切片网格系统默认了几个,也是可以自定义的,具体的设置为GridSets->Create a new gridset。


设置切片网格

OL3的调用与展示:

1、代码

<!DOCTYPE html>
<html>
<head>
    <title>GeoJSON切片</title>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <script src="js/ol.js"></script>
	<script src="js/jquery-1.8.3.js"></script>
    <style>
		body,html,#map{
			padding:0px;
			margin:0px;
			height:100%;
			overflow:hidden;
			background:#ffffff;
		}
		.ol-mouseposition{
			position:absolute;
			bottom:20px;
			left:45%;
			padding:5px;
			background:#fff;
			border:1px solid #ccc;
			font-size:12px;
		}
		ul{
        	list-style: none;
        	position: absolute;
        	right:10px;
        	top:10px;
        	font-size: 14px;
			z-index:99;
        }
        ul li{
        	line-height: 28px;
        	height: 28px;
        	text-align: center;
        	width:40px;
        	float:left;
			cursor:pointer;
			background: #ffffff;
        }
        ul li.active{
        	background: #007AC2;
        	opacity: 0.8;
        	color:#ffffff;
        }
        ul li.day{
        	border:1px solid #007AC2;
        	border-right: none;
        	border-top-left-radius: 3px;
        	border-bottom-left-radius: 3px;
        }
        ul li.night{
        	border:1px solid #007AC2;
        	border-left: none;
        	border-top-right-radius: 3px;
        	border-bottom-right-radius: 3px;
        }
    </style>
</head>
<body>
	<ul id="lyrstyle">
		<li class="day active">白天</li>
		<li class="night">黑夜</li>
	</ul>
    <div id="map" class="map" tabindex="0"></div>
    <script>
		var projection4326 = new ol.proj.Projection({
			code: 'EPSG:4326',
			units: 'degrees',
		});
		var lyr = "lzugis:china";
		var dayStyle = function(feature,resolution){
			var stroke = new ol.style.Stroke({color: "rgba(0,0,255,0.4)", width: 2});
			var fill = new ol.style.Fill({color:"rgba(0,0,255,0)"});				
			var lyr = feature.f.split(".")[0];
			if(lyr=="province"){
				return new ol.style.Style({
					fill: fill,
					stroke: stroke
				});
			}
			else{
				var name = feature.get("name");
				return new ol.style.Style({
					image: new ol.style.Circle({
						radius: 5,
						fill: new ol.style.Fill({
							color: 'rgba(0,0,255,0.4)'
						})
					}),
					text: new ol.style.Text({ //文本样式
						font: '15px Calibri,sans-serif',
						fill: new ol.style.Fill({
							color: '#000000'
						}),
						text:name,
						offsetX:0,
						offsetY:12
					})
				});
			}
		};
		var nightStyle = function(feature,resolution){
			var stroke = new ol.style.Stroke({color: "rgba(255,255,255,0.4)", width: 2});
			var fill = new ol.style.Fill({color:"rgba(0,0,0,0.8)"});				
			var lyr = feature.f.split(".")[0];
			if(lyr=="province"){
				return new ol.style.Style({
					fill: fill,
					stroke: stroke
				});
			}
			else{
				var name = feature.get("name");
				return new ol.style.Style({
					image: new ol.style.Circle({
						radius: 5,
						fill: new ol.style.Fill({
							color: 'rgba(255,255,255,1)'
						})
					}),
					text: new ol.style.Text({ //文本样式
						font: '15px Calibri,sans-serif',
						fill: new ol.style.Fill({
							color: '#ffffff'
						}),
						text:name,
						offsetX:0,
						offsetY:12
					})
				});
			}
		};
		// 行政区划图层
		var vector = new ol.layer.VectorTile({
			// 矢量切片的数据源
			source: new ol.source.VectorTile({
				projection: projection4326,
				format: new ol.format.GeoJSON(),
				tileGrid: ol.tilegrid.createXYZ({
					extent: ol.proj.get('EPSG:4326').getExtent(),
					maxZoom: 22
				}),
				tilePixelRatio: 1,
				// 矢量切片服务地址
				tileUrlFunction: function(tileCoord){
					return 'http://127.0.0.1:8088/geoserver/gwc/service/tms/1.0.0/'
						+lyr+'@EPSG%3A4326@geojson/'+(tileCoord[0]-1)
						+ '/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) + '.geojson';
				}			
			}),
			style:dayStyle
		});
		var tiled = new ol.layer.Tile({
			visible: true,
			source: new ol.source.TileWMS({
				url: 'http://localhost:8088/geoserver/lzugis/wms',
				params: {'FORMAT': 'image/png', 
					'VERSION': '1.1.1',
					tiled: true,
					STYLES: '',
					LAYERS: 'lzugis:province',
					tilesOrigin: 73.4510046356223 + "," + 18.1632471876417
				}
			})
		  });
        var map = new ol.Map({
            layers: [
				//tiled,
				vector
			],
            target: 'map',
            controls: ol.control.defaults().extend([
                new ol.control.MousePosition({
					className:"ol-mouseposition",
					coordinateFormat: ol.coordinate.createStringXY(5)
				})
            ]),
            view: new ol.View({
                projection: projection4326,
				minZoom:4,
				maxZoom:18,
                center: [103.2921875, 38.581640625],
                zoom: 4
            })
        });
		
		$("#lyrstyle li.day").on("click",function(){
			$("#lyrstyle li").removeClass("active");
			$(this).addClass("active");
			vector.setStyle(dayStyle);
			var zoom = map.getView().getZoom();
			map.getView().setZoom(zoom-1);
			$("#map").css("background","#ffffff");
		});
		$("#lyrstyle li.night").on("click",function(){
			$("#lyrstyle li").removeClass("active");
			$(this).addClass("active");
			vector.setStyle(nightStyle);
			var zoom = map.getView().getZoom();
			map.getView().setZoom(zoom+1);
			$("#map").css("background","rgba(0,0,0,0.8)");
		});
    </script>
</body>
</html>
2、运行效果


从上图看出,可以很方便的对地图的风格样式进行重新定义。

---------------------------------------------------------------------------------------------------------------

技术博客

http://blog.csdn.NET/gisshixisheng

在线教程

http://edu.csdn.Net/course/detail/799

Github

https://github.com/lzugis/

联系方式

q       q:1004740957

e-mail:niujp08@qq.com

公众号:lzugis15

Q Q 群:452117357(webgis)

             337469080(Android)

版权声明:本文为LZUGIS原创文章,未经允许不得转载。

GIS 矢量切片(Vector Tile)-地图定制化的时代已经悄悄来临

前言 切片技术的简单介绍,以及传统栅格图片切片的不足 现在最流行的地图底图技术是栅格切片底图,它们本质上是将空间数据分别渲染为不同缩放级别的地图图片,然后将各个级别的图片按照一定规则切分,按照一定...

GEOServer-OpenLayer-矢量切片3:PBF格式格式展示(tms服务)

在上一篇博客中,本文通过参考GeoServer示例代码,实现了GeoJSON格式的矢量切片展示。但在主要存在以下两个方面的问题:1)PBF格式的矢量切片不能成功展示2)自定义坐标系统和格网方案描述混乱...
  • cyoubo
  • cyoubo
  • 2017年09月19日 15:35
  • 450

OpenLayer3读取Geoserver切割的离线瓦片

前言: 由于在网上搜索了很久都没有找到相关的东西,只能自己埋头研究,本文我付出了整整40个小时的心血来解读,希望大家若要转载一定要注上作者名及地址。 Geoserver的离线瓦片生成 主要的功能全在T...

基于GeoServer切片地图服务的发布

接着上一篇文章,如何将JPG格式的图片转化为带地理坐标的TIFF格式里提及的最近的一个项目,数据源是一张高分辨率的2.5维图片,现在已经成功转化成了带有地理坐标的TIFF格式。下面将介绍借助GeoSe...

geoserver发布切片影像地图

问题来源 拿到一副经过校正后的影像后,怎么使用geoserver进行切片及发布呢。本人研究了一番在此给出答案。 导入tiff影像 这个就不说了,网上一大把教程,记得要带坐标系。 进行切片 这里要注意一...

Leaflet调用geoserver发布的矢量切片

geoserver如何发布切片就不写了,大家都可以查到。index.html

GeoServer-WMTS,TMS

GeoServer-WMTS,TMS sf2gis@163.com 2016年8月23日创建 1方法:发布TMS 1.1 目标:TMS(Tiled Map Service),目标是发布切片。 ...
  • sf2gis2
  • sf2gis2
  • 2016年10月18日 22:50
  • 3764

GeoServer的Web管理界面介绍

前面我的博文中有介绍Geoserver在Linux的安装,windows版本安装只需要下载安装包后一直下一步搞定。 Geoserver安装完后,打开浏览器输入:http://localhost:808...

利用geoserver发布矢量切片,mapbox进行调用

1、新建工作区 2、添加数据存储,选择矢量数据源下的文件夹方式,注意字符集编码。点击确定提交之后会出现该文件下的所有shpfile的图层发布界面。 3、或者选择左边的图层菜单,新建图层,选择工...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Geoserver2.11矢量切片与OL3中的调用展示
举报原因:
原因补充:

(最多只允许输入30个字)