GeoJson轉ArcGIS的EsriJson
這次遇到了一個小問題,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"}
相關文章
- 【ArcGIS For JS】前端geojson渲染行政區劃圖層並加標籤前端JSON
- ArcGIS 實現線轉面
- ArcGIS地圖投影與座標系轉換的方法地圖
- pyqt5+gdal製作s57轉geojson小程式QTJSON
- 馬上搞懂 GeoJSONJSON
- GEOJSON資料格式解析JSON
- arcgis10之緩衝區轉化成四邊形
- ArcGIS中的影像分類
- 寫給小白的地理資訊的表示法:GeoJSONJSON
- java的geojson格式測試資料模擬JavaJSON
- ArcGIS Runtime For AndroidAndroid
- geojson格式篩選及處理的解決方案JSON
- arcgis安裝教程10.2 arcgis詳細安裝步驟
- 在Canvas中繪製Geojson資料CanvasJSON
- 安利一個非常好用的 echarts geojson 生成器EchartsJSON
- arcgis js:graphicLayer刪除特定的graphicJS
- ArcGIS Desktop 工具的並行處理並行
- 在ArcGIS Pro中對Revit的bim資料進行地理配準(平移、旋轉等)
- Leaflet入門:新增點線面並匯入GeoJSON資料|Tutorial of Leaflet: Adding Points, Lines, Polygons and Import GeoJSON FileJSONGoImport
- 使用Adobe Illustrator + ArcGIS繪製地圖 | Map Design Using ArcGIS + Adobe Illustrator地圖
- NEW!獲取 ArcGIS Pro 與 ArcGIS Desktop 60天試用許可
- ArcGIS批量裁剪遙感影像
- Arcgis連線HGDB報錯
- 通俗易懂的ArcGis開發快速入門
- ArcGIS模型構建器ModelBuilder的使用方法模型UI
- ArcGis api配合vue開發入門系列(一)引入arcgis api以及載入地圖APIVue地圖
- ArcGIS for Server預設埠6080修改Server
- ArcGIS系統要求知多少
- ArcGIS Pro 專題圖製作
- ArcGIS工具 - 統計工具數量
- ArcGIS Pro SDK 003 如何呼叫Toolbox
- 不偏移的天地圖地圖服務-ArcGIS版地圖
- 論文研究區域圖的製作方法:ArcGIS
- 一個ArcGIS中我知道但是不常用的工具
- ArcGIS Editor for OSM (下載及安裝)
- ArcGIS對欄位分割查詢操作
- ArcGIs建立企業級資料庫資料庫
- ArcGIS工具 - 計算折點數量