OpenLayer+PostGIS+GeoServer–无额外后台实现地理分析与查询框架

一 传统开发流程

1.1 传统流程

在一般情况下,人们使用PostGIS存储空间数据,以Geoserver发布数据服务,以OpenLayer客户端展示地图。客户端操作与地理查询,如果查询等比较复杂,一般会使用ajax将ol的请求参数传给后台,由后台完成操作后返回前端。流程如下:

1.2 框架问题说明

1 GeoServer只是简单发布了地理数据,单个图层,只能接受简单的wms显示,wfs查询,wps分析。产生的问题是,面对多个图层的叠加分析与查询,几乎做不到,所以很多图层的分析只能交由后台服务器完成。

2 使用后台服务器处理地理数据,产生的问题是,对数据库的访问比较频繁,分析的结果,由于是空间数据,对数据的解析存储有要求,工作量增大。

3 作为GIS专业开发人员的苦恼是我曾加入一个j2ee项目组,作为java的门外汉,我做一个哪怕最简单的查询,都要写好多个java类文件与数据结构类文件,为了满足j2ee框架需求。这令我感到很苦恼,在我看来,作为业务开发人员,他们需要这个框架,但作为地图开发人员,我的精力都在研究各个地图技术和框架上而不是语言本身,既不必要也无精力。能不能有个gis开发框架,使我专注于地理数据的查询与分析而脱离业务框架本身的束缚,这让我感到很有必要。

二 独立于业务的地理数据操作框架


结构说明:1 复杂的多图层的分析,全是在数据库中以function脚本编写。
2 geoserver发布要显示地图表。发布function作为视图参数。 对geoserver来说,table,view,function本质都是数据源,是一样的,所以都可以发布。
3 使用时,普通的表用来显示地图,function用来分析地图。
优势:无论加入哪个项目组,我根本不用关心他们的框架与数据结构,集成时,自己负责地图,业务负责业务,各司其职。
原来后台服务全被改写到数据库中,这样,在运算速度上也比驱动的快且少了一个额外的后台。

三 框架使用示例

以最最简单的需求作为说明示例:
需求: 我要根据道路名称,查询道路某个距离的缓冲区内的兴趣点。
3.1 实现具体分析功能的数据库function脚本
CREATE OR REPLACE FUNCTION queryplottingbyroad(
                IN roadname text,
				in distance double precision,
				OUT gid int,
				OUT shapearea double precision,
				out swglm text,
				out idcode text,
				out gljg_dm text,
				out editdate timestamp without time zone,
				out geom geometry
        )
         returns SETOF record AS
$BODY$
DECLARE
		queryGeom geometry;
		rec record;
		sql text;
BEGIN
	--依据道路名称查询道路图形
	sql:='select geom from road where name='''||roadname||'''';
	raise notice 'sql:%',sql;
	EXECUTE sql into rec;
	--对查询的道路进行缓冲
	queryGeom:=ST_Buffer(rec.geom,distance);
	--查询落在缓冲区内或与缓冲区相交的指定图层数据
	sql:='select * from plottingwithqx t where ST_Within(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857)) or ST_Intersects(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857))';
	raise notice 'sql:%',sql;
	--查询数据搜集返回调用者
	for rec in execute sql loop
		gid:= rec.gid;
		shapearea:= rec.shapearea;
		swglm:=	rec.swglm;
		idcode:= rec.idcode;
		gljg_dm:= rec.gljg_dm;	
		editdate:= rec.editdate;		
		geom:= rec.geom;
		return next;
	end loop;
	return;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE STRICT;

3.2 Geoserer发布function

在  图层》发布视图服务中发布一个视图服务,具体参照geoserver官网。
3 客户端调用
以wms查询为例:
http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'东方红路';distance:100&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=

viewparams是客户端把参数放这个里面,传给geoserver,然后服务器解析参数,查询数据库并返回结果。上方的url请求返回 道路名称为’东方红路’的100米范围内的查询图层的符合要求数据。

查询 200米范围内的指定图层符号要求数据
http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'东方红路';distance:200&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=

效果如下,范围扩大之后,多了一条记录。

使用wfs查询也是一样的,使用viewparams将参数传给服务器,服务器查询数据库。
总的来说,将传统流程的复杂分析,摒弃了后台,直接放在数据库中的function中完成,由geoserver作为后台,响应客户端请求,无论wms,wfs都可以,并根据参数返回图片或数据。

转载自:https://mtr-1.oss-cn-beijing.aliyuncs.com/qyblog/2019/04/42171949.jpg

You may also like...