• java 使用GeoTools工具 geojson 与shp 相互转换


    记录使用geotools工具,实现shp和geojson数据互转

     

     爬坑:不使用依赖:vividsolutions ,因为 1.8 与 geotools 20以后版本jts 不一致,会报错。

    1. <dependency>
    2. <groupId>com.vividsolutions</groupId>
    3. <artifactId>jts</artifactId>
    4. <version>1.8</version>
    5. <type>pom</type>
    6. </dependency>

    ----------------------------------------------------------开启编码-------------------------------------------------------

    1. 引起pom依赖jar

    
        
            org.geotools
            gt-shapefile
            20.3
        
        
            org.geotools
            gt-api
            20.3
        
        
            org.geotools
            gt-geojson
            20.3
        
        
            org.geotools
            gt-geometry
            20.3
        
        
            org.geotools
            gt-jts-wrapper
            20.3
        
        
            org.geotools
            gt-main
            20.3
        
        
            org.geotools
            gt-epsg-hsql
            20.3
        
        
            org.geotools
            gt-opengis
            20.3
        
        
            org.geotools
            gt-data
            20.3
        
        
            org.geotools
            gt-referencing
            20.3
        
        
            com.alibaba
            fastjson
            1.2.83
        
    
    
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.0
                
                    1.8
                    1.8
                    true
                
            
        
    

    2. 上代码,自动识别坐标系,默认为84坐标

    1. import com.alibaba.fastjson.JSON;
    2. import com.alibaba.fastjson.JSONArray;
    3. import com.alibaba.fastjson.JSONObject;
    4. import org.geotools.referencing.CRS;
    5. import org.locationtech.jts.geom.*;
    6. import org.geotools.data.FeatureWriter;
    7. import org.geotools.data.Transaction;
    8. import org.geotools.data.shapefile.ShapefileDataStore;
    9. import org.geotools.data.shapefile.ShapefileDataStoreFactory;
    10. import org.geotools.data.simple.SimpleFeatureCollection;
    11. import org.geotools.data.simple.SimpleFeatureIterator;
    12. import org.geotools.data.simple.SimpleFeatureSource;
    13. import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
    14. import org.geotools.geojson.feature.FeatureJSON;
    15. import org.geotools.geojson.geom.GeometryJSON;
    16. import org.geotools.referencing.crs.DefaultGeographicCRS;
    17. import org.opengis.feature.simple.SimpleFeature;
    18. import org.opengis.feature.simple.SimpleFeatureType;
    19. import org.opengis.referencing.crs.CoordinateReferenceSystem;
    20. import java.io.*;
    21. import java.nio.charset.Charset;
    22. import java.util.*;
    23. /**
    24. * @author qiaobing1226
    25. * @since 2022/10/28 上午10:52
    26. * 参考:https://blog.csdn.net/qiaobing1226/article/details/127612665
    27. */
    28. public class Shp2GeojsonUtils {
    29. private static final String POINT = "Point";
    30. private static final String MULTIPOINT = "MultiPoint";
    31. private static final String LINESTRING = "LineString";
    32. private static final String MULTILINESTRING = "MultiLineString";
    33. private static final String POLYGON = "Polygon";
    34. private static final String MULTIPOLYGON = "MultiPolygon";
    35. private static final String THE_GEOM = "the_geom";
    36. private static final String PROPERTIES = "properties";
    37. private static final String GEOMETRY = "geometry";
    38. private static final String GBK = "GBK";
    39. /**
    40. * geoJson转换为shp文件
    41. *
    42. * @param jsonPath
    43. * @param shpPath
    44. * @return
    45. */
    46. public static Map geoJson2Shape(String jsonPath, String shpPath) {
    47. Map map = new HashMap<>();
    48. GeometryJSON geoJson = new GeometryJSON();
    49. try {
    50. JSONObject json = readGeoJsonFile(jsonPath);
    51. JSONArray features = (JSONArray) json.get("features");
    52. JSONObject feature0 = JSONObject.parseObject(features.get(0).toString());
    53. // 获取属性名称
    54. Set properties = JSONObject.parseObject(feature0.getString(PROPERTIES)).keySet();
    55. String strType = ((JSONObject) feature0.get(GEOMETRY)).getString("type");
    56. String strCrs = json.getJSONObject("crs").getJSONObject(PROPERTIES).getString("name");
    57. CoordinateReferenceSystem crs = CRS.decode(strCrs);
    58. ShapefileDataStore shapefileDataStore = dataStore(properties, strType, shpPath, crs);
    59. if (shapefileDataStore == null) {
    60. return map;
    61. }
    62. // 设置Writer
    63. FeatureWriter writer = shapefileDataStore.getFeatureWriter(shapefileDataStore.getTypeNames()[0],
    64. Transaction.AUTO_COMMIT);
    65. for (int i = 0, len = features.size(); i < len; i++) {
    66. String strFeature = features.get(i).toString();
    67. Reader reader = new StringReader(strFeature);
    68. SimpleFeature feature = writer.next();
    69. switch (strType) {
    70. case POINT:
    71. feature.setAttribute(THE_GEOM, geoJson.readPoint(reader));
    72. break;
    73. case MULTIPOINT:
    74. feature.setAttribute(THE_GEOM, geoJson.readMultiPoint(reader));
    75. break;
    76. case LINESTRING:
    77. feature.setAttribute(THE_GEOM, geoJson.readLine(reader));
    78. break;
    79. case MULTILINESTRING:
    80. feature.setAttribute(THE_GEOM, geoJson.readMultiLine(reader));
    81. break;
    82. case POLYGON:
    83. feature.setAttribute(THE_GEOM, geoJson.readPolygon(reader));
    84. break;
    85. case MULTIPOLYGON:
    86. feature.setAttribute(THE_GEOM, geoJson.readMultiPolygon(reader));
    87. break;
    88. }
    89. Iterator iterator = properties.iterator();
    90. while (iterator.hasNext()) {
    91. String str = iterator.next().toString();
    92. JSONObject element = JSONObject.parseObject(features.get(i).toString());
    93. feature.setAttribute(str, JSONObject.parseObject(element.getString(PROPERTIES)).get(str));
    94. }
    95. writer.write();
    96. }
    97. writer.close();
    98. shapefileDataStore.dispose();
    99. map.put("status", 200);
    100. map.put("message", "shp转换success");
    101. } catch (Exception e) {
    102. map.put("status", 400);
    103. map.put("message", e.getMessage());
    104. e.printStackTrace();
    105. }
    106. return map;
    107. }
    108. /**
    109. * 读取geojosn文件
    110. *
    111. * @param jsonPath
    112. * @return
    113. */
    114. private static JSONObject readGeoJsonFile(String jsonPath) {
    115. // 读文件到Stringbuffer
    116. StringBuffer sb = new StringBuffer();
    117. BufferedReader br = null;
    118. try {
    119. br = new BufferedReader(new FileReader(jsonPath));
    120. String str;
    121. while ((str = br.readLine()) != null) {// 逐行读取
    122. sb.append(str + "\r\n");
    123. }
    124. br.close();
    125. } catch (Exception e) {
    126. if (br != null) {
    127. try {
    128. br.close();
    129. } catch (Exception exception) {
    130. exception.printStackTrace();
    131. }
    132. }
    133. e.printStackTrace();
    134. }
    135. return JSONObject.parseObject(sb.toString());
    136. }
    137. /**
    138. * 设置shp文件属性
    139. *
    140. * @param properties
    141. * @param strType
    142. * @param shpPath
    143. * @return
    144. */
    145. private static ShapefileDataStore dataStore(Set properties, String strType, String shpPath, CoordinateReferenceSystem crs) {
    146. try {
    147. Class geoType = null;
    148. switch (strType) {
    149. case POINT:
    150. geoType = Point.class;
    151. break;
    152. case MULTIPOINT:
    153. geoType = MultiPoint.class;
    154. break;
    155. case LINESTRING:
    156. geoType = LineString.class;
    157. break;
    158. case MULTILINESTRING:
    159. geoType = MultiLineString.class;
    160. break;
    161. case POLYGON:
    162. geoType = Polygon.class;
    163. break;
    164. case MULTIPOLYGON:
    165. geoType = MultiPolygon.class;
    166. break;
    167. }
    168. // 创建shape文件对象
    169. File file = new File(shpPath);
    170. Map params = new HashMap();
    171. params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
    172. ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
    173. // 定义图形信息和属性信息
    174. SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
    175. //默认84坐标
    176. tb.setCRS(crs == null ? DefaultGeographicCRS.WGS84 : crs);
    177. tb.setName("shapefile");
    178. // 类型,Point/MultiPoint/LineString/MultiLineString/Polygon/MultiPolygon
    179. tb.add("the_geom", geoType);
    180. Iterator propertiesIter = properties.iterator();
    181. // 设置属性
    182. while (propertiesIter.hasNext()) {
    183. String str = propertiesIter.next().toString();
    184. // 此处设置为string
    185. tb.add(str, String.class);
    186. }
    187. ds.createSchema(tb.buildFeatureType());
    188. // 设置编码
    189. Charset charset = Charset.forName(GBK);
    190. ds.setCharset(charset);
    191. return ds;
    192. } catch (Exception ex) {
    193. ex.printStackTrace();
    194. }
    195. return null;
    196. }
    197. /**
    198. * shp文件转换geojson数据
    199. *
    200. * @param shpPath
    201. * @return
    202. */
    203. public static Map shp2Geojson(String shpPath, String jsonPath) {
    204. Map map = new HashMap();
    205. //新建json对象
    206. JSONObject geojsonObject = new JSONObject();
    207. geojsonObject.put("type", "FeatureCollection");
    208. try {
    209. JSONArray array = new JSONArray();
    210. String fileName = readShpContent(shpPath, array);
    211. geojsonObject.put("features", array);
    212. geojsonObject.put("name", fileName);
    213. String crs = getCoordinateSystemWKT(shpPath);
    214. //GEOGCS表示这个是地址坐标系,PROJCS则表示是平面投影坐标系
    215. JSONObject crsJson = new JSONObject();
    216. JSONObject proJson = new JSONObject();
    217. crsJson.put("type", "name");
    218. if (crs.startsWith("PROJCS")) {
    219. proJson.put("name", "urn:ogc:def:crs:EPSG::3857");
    220. crsJson.put("properties", proJson);
    221. } else {
    222. proJson.put("name", "urn:ogc:def:crs:OGC:1.3:CRS84");
    223. crsJson.put("properties", proJson);
    224. }
    225. geojsonObject.put("crs", crsJson);
    226. // itertor.close();
    227. long startTime = System.currentTimeMillis();
    228. //将json字符串使用字符流写入文件
    229. /* File outputfile=new File(jsonPath);
    230. BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(outputfile));
    231. bufferedWriter.write(JSON.toJSONString(geojsonObject));
    232. bufferedWriter.flush();
    233. bufferedWriter.close();*/
    234. File outputfile = new File(jsonPath);
    235. FileOutputStream fileOutputStream = new FileOutputStream(outputfile);
    236. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "utf-8");
    237. outputStreamWriter.write(JSON.toJSONString(geojsonObject));
    238. outputStreamWriter.flush();
    239. outputStreamWriter.close();
    240. //将json字符串使用字节流写入文件
    241. /* File outputfile=new File(jsonPath);
    242. BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(outputfile));
    243. byte[] bytes= JSON.toJSONString(geojsonObject).getBytes("utf-8");
    244. bufferedOutputStream.write(bytes);
    245. //fileOutputStream.write(JSON.toJSONString(geojsonObject));
    246. bufferedOutputStream.flush();
    247. bufferedOutputStream.close();*/
    248. // long endTime=System.currentTimeMillis();
    249. // System.out.println("当前程序耗时:"+(endTime-startTime)+"ms");
    250. } catch (Exception e) {
    251. map.put("status", "failure");
    252. map.put("message", e.getMessage());
    253. e.printStackTrace();
    254. }
    255. //
    256. return geojsonObject;
    257. }
    258. private static String readShpContent(String shpPath, JSONArray array) {
    259. String fileName = "";
    260. try {
    261. FeatureJSON fjson = new FeatureJSON();
    262. //获取featurecollection
    263. File file = new File(shpPath);
    264. ShapefileDataStore shpDataStore = null;
    265. shpDataStore = new ShapefileDataStore(file.toURL());
    266. //设置编码
    267. /* Charset charset = Charset.forName("GBK");
    268. shpDataStore.setCharset(charset);*/
    269. fileName = shpDataStore.getTypeNames()[0];
    270. SimpleFeatureSource featureSource = null;
    271. featureSource = shpDataStore.getFeatureSource(fileName);
    272. SimpleFeatureCollection result = featureSource.getFeatures();
    273. SimpleFeatureIterator itertor = result.features();
    274. //遍历feature转为json对象
    275. while (itertor.hasNext()) {
    276. SimpleFeature feature = itertor.next();
    277. StringWriter writer = new StringWriter();
    278. fjson.writeFeature(feature, writer);
    279. String temp = writer.toString();
    280. Object geometry = JSONObject.parseObject(temp).getString(GEOMETRY);
    281. byte[] b = temp.getBytes("iso8859-1");
    282. temp = new String(b, GBK);
    283. JSONObject json = JSON.parseObject(temp);
    284. array.add(json);
    285. }
    286. itertor.close();
    287. } catch (Exception e) {
    288. e.printStackTrace();
    289. }
    290. return fileName;
    291. }
    292. /**
    293. * 获取Shape文件的坐标系信息,GEOGCS表示这个是地址坐标系,PROJCS则表示是平面投影坐标系
    294. *
    295. * @shpPath
    296. */
    297. public static String getCoordinateSystemWKT(String shpPath) {
    298. ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
    299. ShapefileDataStore dataStore = null;
    300. try {
    301. dataStore = (ShapefileDataStore) factory.createDataStore(new File(shpPath).toURI().toURL());
    302. return dataStore.getSchema().getCoordinateReferenceSystem().toWKT();
    303. } catch (UnsupportedOperationException | IOException e) {
    304. e.printStackTrace();
    305. } finally {
    306. dataStore.dispose();
    307. }
    308. return "";
    309. }
    310. /**
    311. * 工具类测试方法
    312. *
    313. * @param args
    314. */
    315. public static void main(String[] args) throws Exception {
    316. Shp2GeojsonUtils shpToGeojson = new Shp2GeojsonUtils();
    317. // // shape2Geojson
    318. String shpPath = "/Users/ecarx/Desktop/geojson/上下高架mct/123/AD_Road.shp";
    319. String jsonPath = "/Users/ecarx/Desktop/geojson/AD_Road.geojson";
    320. Map map = shpToGeojson.shp2Geojson(shpPath, jsonPath);
    321. // geojson2Shape
    322. // String shpPath = "/Users/ecarx/Desktop/geojson/上下高架mct/123/AD_Road.shp";
    323. // String jsonPath = "/Users/ecarx/Desktop/geojson/上下高架mct/AD_Road.geojson";
    324. // Map map = shpToGeojson.geoJson2Shape(jsonPath, shpPath);
    325. // System.out.println(map.toString());
    326. }
    327. }

  • 相关阅读:
    开发中,遇到后端返回的数据列表不更新怎么办?
    什么是地理信息系统(GIS)?
    从实现一个React到深度理解React框架核心原理
    PTA 编程题(C语言)-- 连续因子
    合并单元格
    TS第一讲-----基础类型
    同样的SQL,怎么突然就慢了?
    R语言作图——Heatmap(热图)
    【编程题】【Scratch二级】2021.12 绘制多边形
    day82【Leetcode】
  • 原文地址:https://blog.csdn.net/qiaobing1226/article/details/127612665