作为大数据分析的重要工具,Hadoop在这一领域发挥着不可或缺的作用。有些人认为随着Spark的兴起和应用,Hadoop的MapReduce计算框架已经过时(而事实也是如此),Spark的高效、易用确实功能强大,在大数据分析计算中其作用也日渐提高。但无论分析工具如何改进,Hadoop带给我们的HDFS、HIVE以及NoSQL的代表HBASE在今天这个以数据为核心的大数据时代,依旧是不可或缺的。扯了这么多,就来说说笔者最近进行地理大数据池化时遇到的格式转换问题,即将shapefile转换为GeoJson。
数据在键值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
下面的例子可能更加一目了然:
{
"dog":[
{
"name":"旺财",
"food":"骨头"
},
{
"name":"奇福",
"food":"肉"
}
]
}
这个例子中,dog为一类实体,其中分为具体的个体,每个个体有自己的属性。这些结构和信息在整体上就是数据,在具体应用中可以是网页中各种各样的数据。
GeoJson其实就是按照这些规范组织起来的存储带有空间信息数据的格式,是一种对各类地理数据结构编码的格式规范,其最大的意义也是用于共享交换和简化数据体积、形式等。地理数据中矢量数据应用最广,WebGIS或是地理信息分析中大多以矢量为载体,矢量数据包括点、线、面、多面。GeoJson实例如下:
{"type":"Feature",
"geometry": {
"type":"Point","coordinates":[127.7156,47.5683] },
"properties":{"AREA":54.4471,"PERIMETER":68.4888,"?????":2,"????_1":23,"ADCODE93":230000,"ADCODE99":230000,"NAME":"????","POLYGONID":2,"SCALE":1.0,"ANGLE":0.0},
"id":"?????_label.1"
}
2.Shapefile为啥要转格式
我们可以设想一下shp文件的应用场景 :
(1)本地小规模地理数据分析统计等应用功能。这种应用场景下,需求数据量小,完全可以在本地单机环境下直接借助GIS工具对shp进行分析。若要求自动化,则可以结合二次开发设计小程序完全可以满足业务需求,这种场景下转换的意义并不明显。
(2)WebGIS网站需要进行地理数据分析操作功能。这种应用场景下,需求数据量一般情况也不大,在配置webgis时可根据地图服务发布工具来发布可分析和操作的地图服务来满足这一业务需求。若存在地理数据交互和传输,可以转换地图服务中的空间属性和非空间属性信息为GeoJson格式进行操作。
(3)本地存在大规模的shp数据,需要入库存储及分析管理等应用。这种应用场景下,Hadoop、Spark的大数据存储和分析框架最为适合。Hadoop分布式文件系统(HDFS)和数据库系统(HBASE)是以文本或更为基础的二进制流来存储数据,理论上所有类型的数据都可以直接放入其中储存,但我们的应用并非只是建立一个大规模的用于数据储存的仓库,它还应满足进行大数据分析、挖掘等应用需求,这种条件下,将shp转为GeoJson确实为一种非常合适的解决办法。Geojson格式包含了数据最根本的空间信息与属性信息,且其以键值对的形式组织,与hadoop的数据组织思想一致,以这个格式存入HDFS或转化为Hbase,在进行分析时并不需要进行数据取出加格式转换和还原文件等操作,用户可以根据Mapreduce或Spark框架直接对存储的数据进行分析,所以,转换为GeoJson是非常合适的选择。
3.如何转换
若为网页环境,则直接可以借助大佬ArcGIS发布的ArcGIS API for JavaScript中已封装好现有的工具即可;若是桌面或后台环境那么就要考虑语言和方法了。若是对GeoJson的格式有了一定理解且不怕麻烦,完全可以借助C#、Java等语言进行编写,在这个过程中唯一需要考虑的是,你需要一个工具来读取shp元素或是arcsde中的feature元素。.NET作为ArcGIS从10.x版本开始钦定的首要支持开发框架,比起Java的不更新开发工具包待遇,C#的地位高的不是一点半点。C#部分要实现这个转换似乎可以借助NuGet包 geoJson.net(博主GRACE_ETERNITY用这个工具实现了geometry部分的转换),印象中10.2.2后的ArcGIS工具箱似乎开始提供了这个shptogeojson转换功能,估计新版本的sdk for .net中也会存在吧!总之,作为大佬宠儿的C#就不需费心。我们关键要讨论的是Java中这一功能的实现。
Java作为大数据开发支持性优秀的语言,在分析地理大数据时应用需求较大。本着自己动手,丰衣足食的开源精神,要实现shp到geojson的转换免不了要折腾。
首先,是工具的选取。ArcGIS官方对Java的Arcobject工具是可用的,笔者用过10.2.2的,可用于读取shp,但要获取arcsde中的内容,则需要ArcSDE SDK for Java,网上可搜集的资源都是9.3版本的,且为32位版,若你装的64位的eclipse jdk oracle数据库及客户端啥的使用时就头大了。开源的开发还是要用开源的工具,GDAL及GeoTools是不错的选择。GDAL功能强大,有ogr工具库,可以一行代码完成shp转geojson,但需要自己编译,windows环境下可能下得到别人编译好的jar,而对于linux环境下,则可以根据大牛博主箜_Kong这部分的博客,很强大。若连编译也不想整,直接拿来用,可以借助GeoTools工具FeatureJson和GeometryJson类的write方法来实现,罗嗦了这么多,下面贴出FeatureJson类实现这一功能的代码:
ShapefileDataStoreFactory sfdsf=new ShapefileDataStoreFactory();
ShapefileDataStore sfds=(ShapefileDataStore)sfdsf.createDataStore(fille URL);
sfds.setCharset(Charset.forName("GBK"));
SimpleFeatureSource featureSource=sfds.getFeatureSource();
SimpleFeatureCollection feacollection =featureSource.getFeatures();
SimpleFeatureIterator iterator=feacollection.features();
FeatureJSON fJson=new FeatureJSON();
while(iterator.hasNext()){
SimpleFeature sFeature=iterator.next();
fJson.writeFeature(sFeature, outputStream);
}
outputStream.flush();