1、什么是GeoJSON
关于什么是GeoJSON,百度百科给出这样的定义:GeoJSON是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法的地理空间信息数据交换格式。
GeoJSON支持以下几何类型:点、线、面、多点、多线和多面。GeoJSON是一个包含属性特征的几何对象。
GeoJSON****规范****(RFC 7946)
2015年,互联网工程工作组(IETF)与最初的规范作者一起,形成了一个GeoJSON WG来标准化GeoJSON。RFC 7946于2016年8月发布,是GeoJSON格式的新标准规范,取代了2008年的GeoJSON规范。
有一个GeoJSON在线生成的网站,在地图上绘制图形,自动生成GeoJSON文件,可以与GeoJSON规范对照学习GeoJSON的格式。网址为:http://geojson.io。
2、为什么进行相互转换
为何要对Shapefile和geojson格式两种文件进行相互转换?个人认为有两点原因:
(1)传统的Shapefile文件存储需要结合arcsde等数据库引擎,且数据量庞大,无法满足空间大数据的发展需求。将Shapefile转换成转换成geojson采用hadoop等大数据框架、hbase等文件数据库进行分布式存储读取管理是一种有效的解决方式。
(2)ArcGIS Server等商用软件为WebGIS的开发带来了极大的便利,但是商用软件昂贵的价格以及其对部署性能的高要求使得WebGIS的开发困难重重。GeoJSON是基于JSON格式的文件,能够与javascript完美结合,实现前端可视化展示,再利用geotools等开源技术可实现各种空间分析。
3、转换方式
基于java语言,采用geotools代码库进行Shapefile和geojson进行格式转换。其关键代码如下:
package com.geotools.convent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class shpTogeojson {
/**
* geojson转换为shp文件
*
* @param jsonPath
* @param shpPath
* @return
*/
public Map geojson2Shape(String jsonPath, String shpPath) {
Map map = new HashMap();
GeometryJSON gjson = new GeometryJSON();
try {
// 读文件到Stringbuffer
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(jsonPath));
String str;
while ((str = br.readLine()) != null) {// 逐行读取
sb.append(str + "\r\n");
}
br.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
JSONObject json = JSONObject.fromObject(sb.toString());
JSONArray features = (JSONArray) json.get("features");
JSONObject feature0 = JSONObject.fromObject(features.get(0).toString());
// 获取属性名称
Set properties = JSONObject.fromObject(feature0.get("properties")).keySet();
String strType = ((JSONObject) feature0.get("geometry")).getString("type").toString();
Class<?> geoType = null;
switch (strType) {
case "Point":
geoType = Point.class;
break;
case "MultiPoint":
geoType = MultiPoint.class;
break;
case "LineString":
geoType = LineString.class;
break;
case "MultiLineString":
geoType = MultiLineString.class;
break;
case "Polygon":
geoType = Polygon.class;
break;
case "MultiPolygon":
geoType = MultiPolygon.class;
break;
}
// 创建shape文件对象
File file = new File(shpPath);
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
// 定义图形信息和属性信息
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setCRS(DefaultGeographicCRS.WGS84);
tb.setName("shapefile");
tb.add("the_geom", geoType);// 类型,Point/MultiPoint/LineString/MultiLineString/Polygon/MultiPolygon
Iterator propertiesIter = properties.iterator();
// 设置属性
while (propertiesIter.hasNext()) {
String str = propertiesIter.next();
tb.add(str, String.class);// 此处设置为string,如需修改请自行改写代码
}
ds.createSchema(tb.buildFeatureType());
// 设置编码
Charset charset = Charset.forName("GBK");
ds.setCharset(charset);
// 设置Writer
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0],
Transaction.AUTO_COMMIT);
for (int i = 0, len = features.size(); i < len; i++) {
String strFeature = features.get(i).toString();
Reader reader = new StringReader(strFeature);
SimpleFeature feature = writer.next();
switch (strType) {
case "Point":
feature.setAttribute("the_geom", gjson.readPoint(reader));
break;
case "MultiPoint":
feature.setAttribute("the_geom", gjson.readMultiPoint(reader));
break;
case "LineString":
feature.setAttribute("the_geom", gjson.readLine(reader));
break;
case "MultiLineString":
feature.setAttribute("the_geom", gjson.readMultiLine(reader));
break;
case "Polygon":
feature.setAttribute("the_geom", gjson.readPolygon(reader));
break;
case "MultiPolygon":
feature.setAttribute("the_geom", gjson.readMultiPolygon(reader));
break;
}
Iterator propertiesset = properties.iterator();
while (propertiesset.hasNext()) {
String str = propertiesset.next();
JSONObject featurei = JSONObject.fromObject(features.get(i).toString());
feature.setAttribute(str, JSONObject.fromObject(featurei.get("properties")).get(str));
}
writer.write();
}
writer.close();
ds.dispose();
map.put("status", "success");
map.put("message", shpPath);
} catch (Exception e) {
map.put("status", "failure");
map.put("message", e.getMessage());
e.printStackTrace();
}
return map;
}
/**
* shp转换为Geojson
*
* @param shpPath
* @return
*/
public Map shape2Geojson(String shpPath, String jsonPath) {
Map map = new HashMap();
FeatureJSON fjson = new FeatureJSON();
try {
StringBuffer sb = new StringBuffer();
sb.append("{\"type\": \"FeatureCollection\",\"features\": [");
File file = new File(shpPath);
ShapefileDataStore shpDataStore = null;
shpDataStore = new ShapefileDataStore(file.toURL());
// 设置编码
Charset charset = Charset.forName("GBK");
shpDataStore.setCharset(charset);
String typeName = shpDataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = null;
featureSource = shpDataStore.getFeatureSource(typeName);
SimpleFeatureCollection result = featureSource.getFeatures();
SimpleFeatureIterator itertor = result.features();
StringBuffer array = new StringBuffer();
while (itertor.hasNext()) {
SimpleFeature feature = itertor.next();
StringWriter writer = new StringWriter();
fjson.writeFeature(feature, writer);
array.append(writer.toString());
array.append(",");
}
// 删除多余的逗号
array.deleteCharAt(array.length() - 1);
itertor.close();
sb.append(array.toString());
sb.append("]}");
// 写入文件
File f = new File(jsonPath);// 新建文件
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write(sb.toString());
bw.flush();
bw.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
map.put("status", "success");
map.put("message", sb.toString());
} catch (Exception e) {
map.put("status", "failure");
map.put("message", e.getMessage());
e.printStackTrace();
}
return map;
}
/**
* 工具类测试方法
*
* @param args
*/
public static void main(String[] args) {
shpTogeojson fileFormat = new shpTogeojson();
long start = System.currentTimeMillis();
// shape2Geojson
// String shpPath = "D:/geojsonTest/gaosu.shp";
// String jsonPath = "D:/geojsonTest/gaosu.geojson1";
// Map map = fileFormat.shape2Geojson(shpPath, jsonPath);
// geojson2Shape
String shpPath = "D:/geojsonTest/gaosu1.shp";
String jsonPath = "D:/geojsonTest/gaosu.geojson";
Map map = fileFormat.geojson2Shape(jsonPath, shpPath);
System.out.println(shpPath +" "+ jsonPath + ",共耗时" + (System.currentTimeMillis() - start) + "ms");
}
}