地图的开发研究–基于openlayers+geoserver+tomcat的离线地图–postgis空间数据库

此节主要介绍以下内容:    

       1、安装配置postgresqlpostgis,升级postgresql为空间数据库,导入.shp格式的地图,转化为空间数据

2深入研究geoserver的用法和功能,实现其连接postgis空间数据库,发布地图

3完成geoserver的发布数据库的地图,并使用Udig修改地图样式

4学习geoserverWFS服务,实现按照过滤条件高亮查询的图层。 

1…..前期准备工作:

   前周主要学习的都是geoserver调用的本地.shp格式的地图数据,其实geoserver的数据源可以有很多种,如下所示:

     可见,geoserver可以读取很多的数据源,经过内部机制处理,发布为一个地图图层,本周学习的是以PostGis Database空间数据库作为数据源,前期使用uboss平台的时候,框架组曾经使用过postgresql数据库,只知道其优势就是可以存储地图数据,具体没有研究过,所以本周进行了相应的学习和配置。

关于PostgreSQL

   通过上网查阅资料可以发现,PostgreSQL(以下简称PG数据库) 是一个自由的对象关系数据库服务器(数据库管理系统),除了作为普通关系数据库所具有的的特征外,我看到其最吸引的优势是其数据类型,包括:任意精度的数值无限制长度文本几何图元IP地址IPv6地址无类域间路由地址块,MAC地址数组…………此外,用户可以创建自定义数据类型,通常通过PostgreSQLGiST机制,它们也能被很好得索引,比如PostGIS地理信息系统的数据类型 同时也要指出的是,PostgreSQL 对接口的支持也是非常丰富的,几乎支持所有类型的数据库客户端接口。这一点也可以说是 PostgreSQL 一大优点。

  

关于PostGIS

     在PostgreSQL中已经定义了一些基本的集合实体类型,这些类型包括:点(POINT)、线(LINE)、线段(LSEG)、方形(BOX)、多边形(POLYGON)和圆(CIRCLE;另外,PostgreSQL定义了一系列的函数和操作符来实现几何类型的操作和运算;同时,PostgreSQL引入空间数据索引R-tree

     尽管在PostgreSQL提供了上述几项支持空间数据的特性,但其提供的空间特性很难达到GIS的要求,主要表现在:缺乏复杂的空间类型;没有提供空间分析;没有提供投影变换功能。PostGIS是对象关系型数据库系统PostgreSQL的一个扩展,PostGIS提供如下空间信息服务功能:空间对象、空间索引、空间操作函数和空间操作符。同时,PostGIS遵循OpenGIS的规范。PostGIS还提供以下功能:数据库坐标变换,球体长度运算,三维的几何类型,空间聚集函数,栅格数据类型。(如果要深层次的研究可以参考:http://www.opengeo.cn/dz/forum.php?mod=viewthread&tid=71&reltid=49&pre_thread_id=0&pre_pos=7&ext=CB)

 关于安装配置:

     PostgreSQL的安装和普通的数据库安装差别不大,端口,用户名,密码等等,其中需要注意的是选择数据库存储区域的运行时语言环境(字符编码格式)。在选择语言环境时,若选择“default locale”会导致安装不正确;同时,PostgreSQL 不支持 GBK 和 GB18030 作为字符集,如果选择其它四个中文字符集:中文繁体 香港(Chinese[Traditional], Hong Kong S.A.R.)、中文简体 新加坡(Chinese[Simplified], Singapore)、中文繁体 台湾(Chinese[Traditional], Taiwan)和中文繁体 澳门(Chinese[Traditional], Marco S.A.R.),会导致查询结果和排序效果不正确。建议选择“C”,即不使用区域。安装完成后使用

进行管理;

   升级PostgreSQL为postgis空间数据库,此处需要注意的是版本的要对应,开始升级的时候版本不一致,导致安装失败,无法建立空间数据库。我安装的PostgreSQL是9.3的所以官网下载了相应的升级插件,如下:


  升级后PostgreSQL插件里面会出现PostGIS Shapfile and DBF loader ,说明已经产生了一个postgis空间数据库根据名字就可以知道,可以导入.shp格式的地图,不过需要注意的是,导入的时候如果地图数据含有中文数据,一定要在options的字符集设置为GBK,否则导入失败。导入成功后,就会发现空间数据库下产生地图的数据表:


   其实看到这里的时候,我才明白当初在geoserver导入本地地图的时候,曾经看到过这些字段名,可以说明geoserver和此时的导入的解析结果是一致的,导入是成功的。

2…..geoserver以PostGIS作为数据源

上面已经前期工作准备就绪,现在就可以连接PostGIS,以刚才导入的数据作为数据源,形成图层。

  在选择的工作区下,添加数据存储,进行如下配置,

   提交无误后,会自动跳到图层管理页面,因为数据库中存在三个空间数据表,点击发布,进行图层配置(上周已描述)之后就可以通过图层预览功能看到相应的图层:


   看到这个地图,可以说明geoserverpostgresql数据库可以正常连接,同时经过测试发现,修改postgresql空间数据库的表记录时,相应的图层的数据也会改变,这就为我们今后通过修改数据库的信息从而发布新的图层提供了极大的便利,我们可以像以前关系数据库的操作一样操作地图。

3.….使用Udig修改图层的样式:

uDig是一个 open source (EPL and BSD桌面应用程序框架,构建在Eclipse RCPGeoTools(一个开源的Java GIS工具包)上的桌面GIS(地理信息系统是一款开源桌面GIS软件,基于JavaEclipse平台,可以进行shp格式地图文件的编辑和查看;是一个开源空间数据查看器/编辑器,对OpenGIS标准,关于互联网GIS、网络地图服务器和网络功能服务器有特别的加强。通过此软件可以创建本地地图,可以连接geoserver的地图,可以连接数据库的地图图层…………


  此处我主要使用的是通过geoserverWMS服务和Udig进行连接,在Udig内查看相应工作区的图层,这次我学习的是发布的全国地图的样式修改,右击图层,改变样式选项,可以看到如下图的编辑,Label选项的内容又见到了上述熟悉的几个字段,这里我显示的是名字(如北京市,辽宁省等地名),另外需要注意的是如果有中文显示,字体选项的脚本语言要是中文GB2312


在相应的设置完成后,点击XML,复制其中的内容或者导出样式文件,这里我选择的是复制,然后到geoserver配置界面新建样式,将样式内容粘贴到配置框,如下:


然后到刚才在Udig打开的图层配置界面,选中此图层样式,前后对比效果如下:




3.….使用geoserverWFS服务,按照过滤条件高亮查询的图层

  利用Geoserver可以把数据作为 maps/images来 发布(利用WMS来实现),上次已经使用实现过,也可以直接发布实际的数据(利用WFS来实现),所以这次学习使用了这个服务来实现,同时也提供了修改,删除和新增的功能(利用WFS-T)

   Wfs服务包含getFeature操作,用来检索要素信息,支持返回gml格式的地理要素表达。根据getFeature提供的参数FILTER,我们就可以实现条件查询。

   Filter是一种基于XML的并且符合OGC规范的语言。SLD用它来实现复杂的Rule选择。WFS在所有需要定位操作对象的地方都会使用Filter。Filter的作用是构建一个表达式,返回值就是Feature的集合,换句话说Filter就如他的名字一般为我们从一个集合中过滤出一个满足我们要求的子集。而过滤的方法就是Filter定义的操作符。Filter定义了三种操作符:地理操作符(Spatial operators),比较操作符(Comparison operators)和逻辑操作符(Logical operators)。

   所以就通过自定义XML语句作为查询条件:

XML = '<?xml version="1.1.0" encoding="UTF-8"?>' ;
        XML = '<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2"' ;
        XML += '  xmlns:topp="http://www.openplans.org/topp"' ;
        XML += '  xmlns:wfs="http://www.opengis.net/wfs"' ;
        XML += '  xmlns:ogc="http://www.opengis.net/ogc"' ;
        XML += '  xmlns:gml="http://www.opengis.net/gml"';
        XML += '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
        XML += '  xsi:schemaLocation="http://www.opengis.net/wfs';
        XML+= ' http://schemas.opengis.net/wfs/1.1.0/WFS-basic.xsd">';        
        //上面是查询用的gml的前缀
        XML += '<wfs:Query typeName="mytest:bou2_4p">';
        XML += '<wfs:PropertyName>mytest:NAME</wfs:PropertyName>';
        XML += '<wfs:PropertyName>mytest:the_geom</wfs:PropertyName>';  
        XML += '<ogc:Filter>' ;
        XML += '<ogc:Intersects>' ;
        XML += '<ogc:PropertyName>mytest:the_geom</ogc:PropertyName>' ;
        XML += ' <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">';
// 查询条件 北京地界BBOX范围
  XML += '<gml:coordinates>116.817265,40.5296504</gml:coordinates>' ;
        XML += '</gml:Point>' ;
        XML += '</ogc:Intersects>' ;
        XML += '</ogc:Filter>';
        XML += '</wfs:Query>' ;
        XML += '</wfs:GetFeature>';

调用WFS服务:

var request = OpenLayers.Request.POST({
                 url: "http://localhost:8080/geoserver/wfs?",
                 data: xmlPara,
                 callback: onComplete
             });   

然后通过Vector临时图层(自己这样理解的)添加查询的地理要素,浮在原地图图层上面:

 var temVectorLayer=new OpenLayers.Layer.Vector("Vector Layer");
  var polygon = feature.geometry.components[0].clone();
  var vec = new OpenLayers.Feature.Vector(polygon);
  temVectorLayer.addFeatures([vec]);

  

效果图:

总结:

   这一周主要是对geoserver的再研究,发现它的功能还是很多的,为了学习其功能和用法,学习的东西很多,如空间数据库的安装配置,如Udig软件的使用,拓宽了自己的知识面,由于geoserver符合OPG规范,所以今后学习其他的地图服务器的时候会容易点。在实现过程中遇到很多问题,不过还是很好的解决了,例如加载wfs的写法后,发现怎么加载都没反应,后来在IE中调试发现,报“拒绝访问”的错误,百度后得知存在跨域问题。先要改变全局变量OpenLayers.ProxyHost的值,设置成服务器的地址,url则为提供数据的地址,它和服务器不在同一个域中,这实际上是利用服务器进行了中转,因为服务器去跨域取数据要灵活的多。具体要修改的就是修改OpenLayers\examples\proxy.cgi配置文件,

添加geoserver服务器的地址,问题就解决了,最终实现了WFS服务。

  

 

遗留问题:

 1.样式使用问题:geoserver直接加载本地.shp格式的地图发布的图层使用样式没有问题,但是连接postgis数据库的地图使用样式时,地图都无法发布使用,网上查了原因,说是因为地图中含有中文数据(我使用的是上述的北京地图,含有地名等中文),要修改样式xmlencoding=GBK可是修改之后还是不行,现在问题还没解决。

 2.关于使用WFS实现过滤条件查询:上述使用的是自己写的XML,但是后来网上说OpenLayers已经写好了Filter过滤条件和转成xml的类,这样Filter标签里的内容不用逐个编写了,以后的章节将会对此进行讲解

function conformationFilter(geo) {
var filter_1_0 = new OpenLayers.Format.Filter.v1_0_0();
//也可以使用1.1版本构造过滤条件
    //var filter_1_1 = new OpenLayers.Filter({ version: "1.1.0" });
    var xml = new OpenLayers.Format.XML(); //构造xml格式的文件
    var filter = new OpenLayers.Filter.Logical({//逻辑操作符
        type: OpenLayers.Filter.Logical.AND, //并且更改为或者
        filters: [
        new OpenLayers.Filter.Spatial({
            type: OpenLayers.Filter.Spatial.INTERSECTS, //INTERSECTS, //相交OK
            value: geo,
            projection: "EPSG:4326"
        }),
 //构造指定格式的xml
    return result = xml.write(filter_1_0.write(filter));

3.其实这段时间做的GIS地图都很简单,因为图层很少,所以放大或者缩小地图的时候加载速度问题不是很明显,目前对于此方法的解决方法很普遍流行的是地图瓦片的技术,和geoserver结合使用的就是geowebcachegeowebcache就相当于是openlayergeoserver之间的中介,首先,geowebcache会根据你的配置信息,把相应的地图图层切好图,存放在磁盘中,然后在使用openlayer加载地图服务的时候,把地图服务的地址指向geowebcachegeowebcache接收到这些请求后,会根据请求的位置和比例尺在切片目录中找到对应的瓦片,然后返回给你,省去了动态生成地图的过程,速度大幅度提高,而且由于请求的图片资源是事先生成好的,浏览器加载这些图片之后,下一次再去请求同样的图片,就会从浏览器的缓存中拉去,速度进一步提高!

转载自:https://blog.csdn.net/songjian1314/article/details/17263865

You may also like...

退出移动版