这次遇到了一个小问题,postgresql只能到处geojson(毕竟是一个 标准 格式),而客户需求的是ArcGIS支持的EsriJson格式。需要在数据之间进行一个转换。再网上查阅了一定资料,最后发现下面的代码比较可行。这里分享一下:
package com.cic.analysis.business.utils; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.cic.common.utils.StringUtils; import java.math.BigDecimal;import java.util.*; public class EsriGeoJsonUtil {//EsriJson转geoJson public static String esri2geo(String ersiJson){ Map geoMap = new HashMap(); try { List geoFs = new ArrayList(); geoMap.put("type", "FeatureCollection"); Map esriMap = (Map) JSON.parse(ersiJson); Object esriFs = esriMap.get("features"); if(esriFs instanceof List){ esriFs = (List<Map<String, Object>>) esriFs; for(int i=0; i< ((List) esriFs).size(); i++){ Map esriF = (Map) ((List) esriFs).get(i); Map geoF = new HashMap(); geoF.put("type", "Feature"); geoF.put("properties", esriF.get("attributes")); Map<String, Object> geometry = (Map<String, Object>) esriF.get("geometry"); if(null != geometry.get("x")){ geoF.put("geometry", geoPoint(geometry)); }else if(null != geometry.get("points")){ geoF.put("geometry", geoPoints(geometry)); }else if(null != geometry.get("paths")){ geoF.put("geometry", geoLine(geometry)); }else if(null != geometry.get("rings")){ geoF.put("geometry", geoPoly(geometry)); } geoFs.add(geoF); } geoMap.put("features", geoFs); } }catch (Exception e){ e.printStackTrace(); } return new JSONObject(geoMap).toString(); } //geoJosn转EsriJson public static String geo2ersi(String geoJson, String idAttribute){ Map esriMap = new HashMap(); try { Map geoMap = (Map) JSON.parse(geoJson); esriMap = getEsriGeo(geoMap, idAttribute); Map spatialReference = new HashMap(); spatialReference.put("wkid", 4326); esriMap.put("spatialReference",spatialReference); }catch (Exception e){ e.printStackTrace(); } return new JSONObject(esriMap).toString(); } public static Map getEsriGeo(Map geoMap, String idAttribute){ Map esriMap = new HashMap(); idAttribute = StringUtils.isNotEmpty(idAttribute)? idAttribute:"OBJECTID"; String type = geoMap.get("type").toString(); switch (type){ case "Point": List<BigDecimal> coords = (List<BigDecimal>) geoMap.get("coordinates"); esriMap.put("x", coords.get(0)); esriMap.put("y", coords.get(1)); break; case "MultiPoint": esriMap.put("points",geoMap.get("coordinates")); break; case "LineString": List<Object> coordsList = new ArrayList<>(); coordsList.add(geoMap.get("coordinates")); esriMap.put("paths",coordsList); break; case "MultiLineString": esriMap.put("paths",geoMap.get("coordinates")); break; case "Polygon": List<List<List<BigDecimal>>> coordinates = (List<List<List<BigDecimal>>>) geoMap.get("coordinates"); List<List<List<BigDecimal>>> rings = orientRings(coordinates); esriMap.put("rings", rings); break; case "MultiPolygon": List<List<List<List<BigDecimal>>>> mcoordinates = (List<List<List<List<BigDecimal>>>>) geoMap.get("coordinates"); List<List<List<BigDecimal>>> mrings = flattenMultiPolygonRings(mcoordinates); esriMap.put("rings", mrings); break; case "Feature": if (null != geoMap.get("geometry")) { Map geometry = getEsriGeo((Map) geoMap.get("geometry"), idAttribute); esriMap.put("geometry", geometry); } if(null != geoMap.get("properties")){ Map properties = (Map) geoMap.get("properties"); if (null != geoMap.get("id")) { properties.put(idAttribute, geoMap.get("id")); } esriMap.put("attributes", properties); } break; case "FeatureCollection": List<Object> esriFs = new ArrayList<>(); List<Map> features = (List<Map>) geoMap.get("features"); for (int i = 0; i < features.size(); i++) { esriFs.add(getEsriGeo(features.get(i), idAttribute)); } esriMap.put("features", esriFs); esriMap.put("geometryType","esriGeometryPolygon"); break; case "GeometryCollection": List<Object> esriFsc = new ArrayList<>(); List<Map> geometries = (List<Map>) geoMap.get("geometries"); for (int i = 0; i < geometries.size(); i++) { esriFsc.add(getEsriGeo(geometries.get(i), idAttribute)); } esriMap.put("geometries", esriFsc); esriMap.put("geometryType","esriGeometryPolygon"); break; } return esriMap; } public static Map geoPoint(Map<String, Object> geometry){ Map geo = new HashMap(); geo.put("type", "point"); BigDecimal x = (BigDecimal) geometry.get("x"); BigDecimal y = (BigDecimal) geometry.get("y"); List<BigDecimal> coords = new ArrayList<>(); coords.add(x); coords.add(y); geo.put("coordinates", coords); return geo; } public static Map geoPoints(Map<String, Object> geometry){ Map geo = new HashMap(); List<Object> points = (List<Object>) geometry.get("points"); if(points.size()==1){ geo.put("type", "Point"); geo.put("coordinates", points.get(0)); }else{ geo.put("type", "MultiPoint"); geo.put("coordinates", points); } return geo; } public static Map geoLine(Map<String, Object> geometry){ Map geo = new HashMap(); List<Object> paths = (List<Object>) geometry.get("paths"); if(paths.size()==1){ geo.put("type", "LineString"); geo.put("coordinates", paths.get(0)); }else{ geo.put("type", "MultiLineString"); geo.put("coordinates", paths); } return geo; } public static Map geoPoly(Map<String, Object> geometry){ Map geo = new HashMap(); List<List<List<BigDecimal>>> rings = (List<List<List<BigDecimal>>>) geometry.get("rings"); if(rings.size()==1){ geo.put("type", "Polygon"); geo.put("coordinates", rings); }else{ List<List<List<List<BigDecimal>>>> coords = new ArrayList(); String type = ""; int len = coords.size() - 1; for(int i=0; i< rings.size(); i++){ if(ringIsClockwise( rings.get(i))){ List<List<List<BigDecimal>>> item = new ArrayList<>(); item.add(rings.get(i)); coords.add(item); len++; }else{ coords.get(len).add(rings.get(i)); } } if(coords.size() == 1){ type="Polygon"; }else{ type="MultiPolygon"; } geo.put("type", type); geo.put("coordinates",coords.size()==1?coords.get(0): coords); } return geo; } public static boolean ringIsClockwise(List<List<BigDecimal>> rings){ int total = 0; List<BigDecimal> pt1 = null; List<BigDecimal> pt2 = null; for(int i=0; i< rings.size()-1; i++){ pt1 = rings.get(i); pt2 = rings.get(i+1); total += (pt2.get(0).doubleValue() - pt1.get(0).doubleValue())* (pt2.get(1).doubleValue() + pt1.get(1).doubleValue()); } return total>=0; } public static List<List<List<BigDecimal>>> orientRings ( List<List<List<BigDecimal>>> polygon) { List<List<List<BigDecimal>>> ringsList = new ArrayList<>(); List<List<BigDecimal>> outerRing = closeRing(polygon.get(0)); if (outerRing.size() >= 4) { if (!ringIsClockwise(outerRing)) { Collections.reverse(outerRing); } ringsList.add(outerRing); polygon.remove(0); for (int i = 0; i < polygon.size(); i++) { List<List<BigDecimal>> hole = closeRing(polygon.get(i)); if (hole.size() >= 4) { if (ringIsClockwise(hole)) { Collections.reverse(hole); } ringsList.add(hole); } } } return ringsList; } public static List<List<BigDecimal>> closeRing (List<List<BigDecimal>> coords) { if (!pointsEqual(coords.get(0), coords.get(coords.size()-1))) { coords.add(coords.get(0)); } return coords; } public static boolean pointsEqual (List<BigDecimal> a, List<BigDecimal> b) { for (int i = 0; i < a.size(); i++) { if (a.get(i).compareTo(b.get(i)) != 0) { return false; } } return true; } public static List<List<List<BigDecimal>>> flattenMultiPolygonRings (List<List<List<List<BigDecimal>>>> rings) { List<List<List<BigDecimal>>> polygonList = new ArrayList<>(); for (int i = 0; i < rings.size(); i++) { List<List<List<BigDecimal>>> polygons = orientRings(rings.get(i)); for (int x = polygons.size() - 1; x >= 0; x--) { List<List<BigDecimal>> polygon = polygons.get(x); polygonList.add(polygon); } } return polygonList; } }package com.cic.analysis.business.utils; import org.junit.Test; import static org.junit.Assert.*; public class EsriGeoJsonUtilTest { @Test public void esri2geo() { String geoJson="{\n" + " \"type\": \"FeatureCollection\",\n" + " \"features\": [\n" + " {\n" + " \"type\": \"Feature\",\n" + " \"properties\": {\n" + " \"color\":\"#dddddd\",\n" + " \"id\":\"2222\"\n" + " },\n" + " \"geometry\": {\n" + " \"type\": \"Polygon\",\n" + " \"coordinates\": [\n" + " [\n" + " [\n" + " -9.84375,\n" + " 55.57834467218206\n" + " ],\n" + " [\n" + " -48.515625,\n" + " 7.013667927566642\n" + " ],\n" + " [\n" + " 67.1484375,\n" + " -8.754794702435618\n" + " ],\n" + " [\n" + " 31.9921875,\n" + " 48.69096039092549\n" + " ],\n" + " [\n" + " -9.84375,\n" + " 55.57834467218206\n" + " ]\n" + " ]\n" + " ]\n" + " }\n" + " }\n" + " ]\n" + "}"; System.out.println(EsriGeoJsonUtil.geo2ersi(geoJson,"")); }}{"features":[{"geometry":{"rings":[[[-9.84375,55.57834467218206],[31.9921875,48.69096039092549],[67.1484375,-8.754794702435618],[-48.515625,7.013667927566642],[-9.84375,55.57834467218206]]]},"attributes":{"color":"#dddddd","id":"2222"}}],"spatialReference":{"wkid":4326},"geometryType":"esriGeometryPolygon"}
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删