GeoJson格式与转换(shapefile)Geotools

转自:https://blog.csdn.net/cobramonkey/article/details/71124888

作为大数据分析的重要工具,Hadoop在这一领域发挥着不可或缺的作用。有些人认为随着Spark的兴起和应用,Hadoop的MapReduce计算框架已经过时(而事实也是如此),Spark的高效、易用确实功能强大,在大数据分析计算中其作用也日渐提高。但无论分析工具如何改进,Hadoop带给我们的HDFS、HIVE以及NoSQL的代表HBASE在今天这个以数据为核心的大数据时代,依旧是不可或缺的。扯了这么多,就来说说笔者最近进行地理大数据池化时遇到的格式转换问题,即将shapefile转换为GeoJson。

  • 1.GeoJson是啥 
    谈到GeoJson,就不得不说和它看起来似乎关系密切的Json格式。Json全称JavaScript Object Notation,即Javascript对象标注。在网络传输过程中,大体量和多格式的数据会造成处理的复杂化且消耗大量的网络资源,我的理解是Json格式就是将JavaScript中的对象统一规范化,以键值对的形式保存原有对象的信息,这样在传输时,只需传输与简单文本差不多的内容即可完成网页内容的传输和网页响应。而这部分数据在具体应用时,则可以根据其应用规则来从Json格式还原。大体上说,Json是由一个个键值对组成的具有面向对象思想的数据格式,具有以下特点:
数据在键值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
  • 1
  • 2
  • 3
  • 4

下面的例子可能更加一目了然:

{
"dog":[
    {
    "name":"旺财",
    "food":"骨头"
    },
    {
    "name":"奇福",
    "food":"肉"
    }
]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这个例子中,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"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
    • 4.进一步的思考 
      GeoTools工具提供的现有功能是适用于Shapefile的,对于ArcGIS的Geodatabase中的数据支持较差,根据GeoTools官方文档中的说明,Geotools对ArcSDE中的数据进行操作时,一样需要依赖arcsde-jar-for-java jar包,也就是其依旧是根据ArcGIS提供的java类库文件来实现。上文提到arcsde-jar-for-java只能获取到9.3版本,其对于java是不可行的。ArcGIS官方还为我们提供了另外一种方式:ST_Geometry函数包。向底层迈进一步来看,空间数据存储到数据库中依旧是按照关系型数据库的组织、存储方式来进行,其特殊之处的是对于空间数据部分ArcGIS做了二层组织包装。如矢量数据以ArcSDE GeoDatabase组织存储在Oracle中,其非空间部分属性数据可以直接通过SQL 语句查询得到,而其中存储几何内容的字段则进行了包装和组织,一般shape字段为几何字段,若以”select * from 矢量数据表名”语句查询,则shape部分返回一个类似Blob的结果。而ArcGIS提供的ST_Geometry函数包就是将几何字段内容进行解析和运算的方法集合。 
      大体如此,GeoTools工具使用时相关功能的中文资料较少,开发时只能借助官方文档筛选。希望能帮到有同样需求的朋友。
原文地址:https://www.cnblogs.com/dybk/p/9292856.html