利用Geotools开源库对等高线进行批量赋值的方法研究
2016-01-29魏峰远
卢 伟,魏峰远
(1. 河南理工大学测绘与国土信息工程学院,河南 焦作 454003; 2. 北京博阳世通
信息技术有限公司,北京 100101)
LU Wei,WEI Fengyuan
利用Geotools开源库对等高线进行批量赋值的方法研究
卢伟1,2,魏峰远1
(1. 河南理工大学测绘与国土信息工程学院,河南 焦作 454003; 2. 北京博阳世通
信息技术有限公司,北京 100101)
Elevation Values Batch Assigning Automatically Based on Geotools
LU Wei,WEI Fengyuan
摘要:等高线是表达地形起伏最为常用的一种方式,是GIS的基础数据模型,如果利用彩色和阴影渲染,其直观性可进一步提高。随着计算机及遥感、航空摄影的发展,很多软件(如ArcMap)都具备了地形图矢量化功能,但是通常待处理的等高线量较大,若逐条赋值,其效率与正确性必然受到影响。本文首先对Geotools进行了基本介绍,然后结合代码,详细阐述了利用Geotools实现对已经矢量化完毕的等高线进行批量赋值的过程。
引文格式: 卢伟,魏峰远. 利用Geotools开源库对等高线进行批量赋值的方法研究[J].测绘通报,2015(9):125-127.DOI:10.13474/j.cnki.11-2246.2015.0297
关键词:等高线;矢量化;批量赋值;Geotools;几何查询
中图分类号:P208
文献标识码:B
文章编号:0494-0911(2015)09-0125-03
收稿日期:2014-07-18
作者简介:卢伟(1988—),女,硕士,主要研究方向为基础数据库建设、室内定位等。E-mail:13261583834@163.com
一、前言
随着空间和网络技术的发展,GIS技术越来越为人们所重视,而数字化地面要素是GIS应用的基础资料,其中等高线更是GIS中最重要的要素之一[1]。等高线是一组具有空间关系的曲线,是表达地形起伏最为常用的方式,如果利用彩色和阴影渲染[2],其直观性可进一步提高。利用现有的测量手段并通过计算机处理,有多种方式也可以达到相同或类似的效果,如DEM、TIN、GRID等。只要获得这些数据中的其中一种,就可以得到其他表达地表起伏的数据格式。目前,在获得数字化的等高线方面有以下几种方式:
1) 利用合成孔径雷达(SAR)卫星、航空摄影等方式获取地表的高程影像,通过计算机生成数字高程模型(DEM),然后由DEM生成等高线[3]。
2) 利用其他表达地形的模型(如TIN、GRID等)进行转换。
3) 利用以往测量得到的纸质地形图进行矢量化,并对矢量化后的等高线进行高程赋值[4]。
以往的地质测量都是以纸质地图进行存档的[5]。随着计算机及遥感、航空摄影的发展,人们获取地形地貌的方式越来越多,老式的纸质地图在分析与表达时逐渐显露出其局限性,但在获取等高线方面,它仍是一个重要来源。目前很多软件(如ArcMap)都具备了地形图矢量化功能,但是通常待处理的等高线量较大,若逐条赋值,其效率与正确性必然受到影响。因此,如何快速地对纸质地形图进行矢量化并进行批量赋值是一个很重要的问题。矢量化是数字图像处理的内容[6],本文主要论述使用Geotools开源包对矢量化后的等高线进行批量赋值的方法与实现。
二、Geotools简介
Geotools是使用Java语言编写的开源GIS工具包[6-7]。它起源于1996年英国利兹大学的一个硕士研究项目,到目前最新版本Geotools 10.1已经发展了17年之久。它最初的目的是提供一个可以创造交互式的地理可视化客户端,现在它作为开放地理基金会(OSGeo)最初支持的项目之一,已经发展成为一个实现标准OGC规范接口的功能完善的GIS工具包。它主要提供各种GIS算法,并对各种空间数据格式进行读写与显示[8]。
1. Geotools中的空间查询
Geotools使用gt-opengis包中的Filter与Expression接口表达约束,使用它们从数据源中提取特定的要素以创建查询(Query)。空间查询按查询方式主要分为两类:根据属性条件查询要素和根据几何要素查询。在查询要素之前首先要定义好查询条件。
(1) 使用CQL(common query manguage)进行属性查询
Filter filter=CQL.toFilter(“contour=0”);
(2) 使用FilterFactory进行几何查询
这里有两种方式可以选择,分别为FilterFactory与FilterFactory2,它们都可以直接创建查询,其主要差别为FilterFactory2比FilterFactory在使用JTS操作几何方式具备更多的方法。下面为使用FilterFactory2进行几何查询的代码:
FilterFactory2 ff=
CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints);
Filter filter=ff.contains(ff.property("THE_GEOM"),ff.literal(geometry));
其中,“THE_GEOM”通常是Shapefile几何字段名;geometry为空间查询的几何范围。
2. Geotools中的几何运算
Geotools实现了OGC规范,主要利用JTS包进行几何运算。Geotools中的几何运算有7种,分别为:Buffer、Distance、ConvexHull、Intersection、Union、Difference、SymDifference。其中运算对象为几何对象,运算结果为另一个几何对象或数值。本文中用到的是线(Line)与折线(Polyline)的Intersection运算。其结果应该为一个多点(MultiPoint)(在本文中MultiPoint中的点数多于1个,则说明有重复选择的情况,则需要重新进行选择):
Geometry intersection=
polyline.intersection(line);
MultiPoin tmp=(MultiPoint)intersection;
三、等高线批量赋值
等高线批量赋值的基本思想是每次以一条直线选择一系列相邻的未赋值等高线(这些等高线高程值递增或递减),然后求出这些等高线与直线的交点。按直线的方向求出后面各条等高线与首个相交等高线的距离,并以此距离对这些交点进行排序。最后根据首条等高线递增或递减的顺序对等高线进行赋值。
1. 加载底图与等高线矢量文件
在Geotools中使用FileDataStore与GridCoverage2DReader分别对Shapefile与栅格数据进行读取,对栅格数据的要求是已经经过空间校正,并具有正确的坐标系。代码如下:
Layer rasterLayer=
newGridReaderLayer(reader,rasterStyle);
map.addLayer(rasterLayer);
Layer
shpLayer=newFeatureLayer(shapefileSource,shpStyle);
map.addLayer(shpLayer);
加载数据后利用Geotools提供的Swing组件进行数据显示。
2. 赋值等高线的选择
在批量赋值之前,首先对一批需要赋值的相邻等高线进行选择,在进行选择时根据底图栅格确定所选对象递增或递减。具体代码如下:
SimpleFeatureCollection grabFeaturesFromPolyline(LineStringlineString)
throws Exception
{
FilterFactory2 ff=CommonFactoryFinder.getFilterFactory2();
FeatureType schema=shapefileSource.getSchema();
String geometryPropertyName=schema.getGeometryDescriptor().getLocalName();
CoordinateReferenceSystem targetCRS=schema.getGeometryDescriptor()
.getCoordinateReferenceSystem();
CoordinateReferenceSystem defaultCRS=ProjectionUtils.getDefaultCRS();
MathTransform transform=CRS.findMathTransform(defaultCRS,targetCRS);
LineString targetLineString=(LineString) JTS.transform(lineString,transform);
ReferencedEnvelope bbox=JTS.toEnvelope(targetLineString);
Filter filter1=ff.bbox(ff.property(geometryPropertyName),bbox);
Filter filter2=ff.intersects(ff.property(geometryPropertyName),ff.literal(targetLineString));
Filter filter=ff.and(filter1,filter2);
return shapefileSource.getFeatures(filter);
}
在利用线要素对数据源进行查询时,为了提高查询效率,本文利用了包围盒与线要素联合查询。
3. 等高线的排序与赋值
上一步所得到的是一个要素集,也就是与线要素相交的所有等高线的集合。在得到这些线要素后,需要根据与线要素相交的顺序进行排序,以按等高线递增或递减进行批量赋值。本文采取的方式是首先求出线要素与各要素等高线的交点,然后根据这些交点与线要素起点的距离对要素选择集中的等高线进行排序。具体代码如下:
Coordinate firstPt=lineString.getCoordinateN(0);
SimpleFeatureIterator iterator=collection.features();
Map
HashMap
while(iterator.hasNext()){
SimpleFeature feature=iterator.next();
Geometry geometry=(Geometry)
feature.getDefaultGeometry();
Geometry points=
geometry.intersection(lineString);
Coordinate pt=points.getCoordinate();
map.put(pt.distance(firstPt),feature);
}
List
newArrayList SimpleFeature>>(map.entrySet()); Collections.sort(infoIds,new Comparator publicint compare(Entry SimpleFeature>o1, Entry double cha=o2.getKey()-o1.getKey(); if (cha>0) return 1; else return -1; } }); 在对等高线进行排序时,使用了Java中HashMap中的自定义Sort函数,得到的infoIDs集合就是按照交点与线要素起点的距离进行的排序。在得到排序后的等高线后,只需要逐条取出各条等高线,然后根据它的FeatureID,对要素源进行查询更新。具体代码如下: public void updateSimpleFeature(FeatureId fid,String name,Object value) throwsIOException{ Transaction transaction=new DefaultTransaction("Example1"); String typeName= shpDataStore.getTypeNames()[0]; FeatureSource SimpleFeature>featureSource=null; SimpleFeatureStore store= (SimpleFeatureStore)shpDataStore .getFeatureSource(typeName); store.setTransaction(transaction); FilterFactory2 ff= CommonFactoryFinder.getFilterFactory2(GeoTools .getDefaultHints()); Filter filter=ff.id(fid); SimpleFeatureTypefeatureType= store.getSchema(); try{ store.modifyFeatures(name,value,filter); transaction.commit(); } catch(Exception eek){ try { transaction.rollback(); }catch(IOException e){ e.printstackTrace(); } } } 等高线批量赋值工具界面由3部分组成:菜单栏、工具栏、地图显示区。主要功能包括添加底图、添加Shapefile、编辑Shapefile、系统设置及地图基本操作等。等高线批量赋值的基本流程为:将图层缩放到未赋值的等高线处,使用赋值工具画出一条线,选择相邻的一组等高线。确定初始等高线的值及高差,即可为该组等高线赋值。在利用ArcGIS软件对1989年出版的焦作市修武县1∶5万地形图等高线进行矢量化后,利用本文实现的等高线批量赋值工具进行赋值操作。对等高线赋值前后的变化效果如图1、图2所示。 图1 等高线赋值前 图2 等高线赋值后 四、结论 本文中所使用的根据等高线顺序进行赋值的方法并不是很难实现,如果使用ArcMap中内嵌的VB开发[9]或ArcEngine进行二次开发,开发效率也许会进一步提高。但是这些都需要依托庞大的二次开发组件,并且没有许可也不能单独运行。本文提出的基于Geotools的等高线批量赋值方法,在开发方式上使用的是免费的开源工具包,依托其完善的GIS功能可以方便开发出相应功能,软件可以方便传播与使用。在本文中使用了Geotools的Swing可视化组件、查询包、更新包及Java中HashMap的Sort函数,实现了等高线的批量赋值。相比以往逐条等高线进行人工赋值,等高线批量赋值可以极大地提高工作效率,并降低失误率。 参考文献: [1]曹宁,张晓煜,李剑萍,等. 基于ArcView的等高线批赋值[J]. 农业网络信息,2007(9):61-63. [2]胡耀锋,胡曙光. 坐标转换中地貌重构算法研究[J]. 测绘通报,2008(1):62-65. [3]张尧,樊红,黄旺. 基于Delaunay三角网的等高线树生成方法[J]. 测绘学报,2012,41(3):461-467. [4]朱蕊. 多源空间矢量数据一致性处理技术研究[D].郑州:信息工程大学,2012. [5]王东华,刘建军,商瑶玲,等. 国家1∶50000基础地理信息数据库动态更新[J]. 测绘通报,2013(7):1-4. [6]王太宁. 基于GeoTools的开源GIS应用的研究与实践[D].大连:大连理工大学,2010. [7]冯亦参. 基于Geotools实现WebGIS应用软件[J]. 微计算机信息,2006(31):260-261. [8]雷兵. 地理信息查询工具Geotools的设计与实现[J]. 测绘科技动态,1998(3):20-24. [9]邓世学. VBA编程实现批量对等高线赋值[J]. 电脑编程技巧与维护,2012(6):14-15. [10]纪洋,武文波,杨晓伟. 等高线自动矢量化的后处理[J]. 辽宁工程技术大学学报:自然科学版,2008(S1):37-39. [11]李国辉, 许文帅, 龙毅,等.面向等高线与河流冲突处理的多约束移位方法[J].测绘学报, 2014, 43 (11): 1204-1210. 徕卡测量新技术应用专栏4. 系统实现