簡體   English   中英

如何讀取具有可變數組深度和結構的復雜JSON字符串?

[英]How to read complex JSON string with variable array depth and structure?

我有很多JSON數據,這些數據是在嵌套列表中組織的。 每個列表都包含其他列表,這些列表可能包含其他列表等。 最深的清單包括一對窮人和緯度,例如

[[[..... [16.353542354,48.2354242424],[16.46353535,48.2546754646] ....] .....]。

它看起來像這樣的圖形:

Coord列表

我基本上不知道這些列表是如何嵌套的。 它們一直不同。 接下來的困難部分是我需要從中獲取“坐標多邊形”。 這意味着僅由坐標對組成的列表屬於同一個多邊形。 例如:

[...... [[16.23542424,48.2342424242],[16.2423242352354,48.12342534634],[16.35353453535,48.345635353]] ......

這意味着存在由3對坐標組成的多邊形(因此有3個角)。 我確信這可以通過某種String解析來解決。 我想知道這是否可能與基本的JSON.simple(或可能任何其他API)可能性。 問題是JSON對它正在解析的數據一無所知。 我必須告訴JSON對象是什么,並且必須使用類型轉換來獲取正確的數據。 在此處查看這些示例 現在我需要相反的方式,但我永遠不知道數據是什么類型(“它是另一個列表還是數據坐標對”) ,因為這些列表非常動態。 怎么能以方便的方式完成? 我可以用一些“推送和彈出行為”來編寫一些字符串解析算法來逐字符地比較JSON字符串,但我想知道是否有更好的方法來做到這一點?

[UPDATE]
我發現這是一種標准化的JSON格式,稱為GeoJSON。 如果您知道如何閱讀數據,那就很清楚了。 多邊形由多邊形組成,多邊形可以有多個孔,由Polygon對象中的第二個數組表示。 見規格表: 多邊形組合區

我基本上不知道這些列表是如何嵌套的

您確切知道這些列表的嵌套程度。 在你的json的頂部,你有:

"type": "Multipolygon"

對我而言,這意味着List<Polygon> 現在,什么是Polygon 嗯,這顯然是List<Coordinate> 最后,我們知道Coordinate是一個包含兩個元素的列表。

總之,我們有List<List<List<double>>> 陣列的深度是已知的。

class Location {
    private double _lat;
    private double _long;

    public Location(double lat, double long) { _lat = lat; _long = long }

    public static Location fromJSONArray(JSONArray json) {
        int n = json.length();
        if(n != 2) throw new IllegalArgumentException('json');

        return new Location(json.getDouble(0), json.getDouble(1));
    }
}
class Polygon : List<Location> {
    public static Polygon fromJSONArray(JSONArray json) {
        int n = json.length();
        Polygon p = new Polygon();
        for(int i = 0; i < n; i++) {
            p.add(Location.fromJSONArray(json.getJSONArray(i)));
        }
        return polygon;
    }
}

private List<Polygon> parseLists(JSONArray nestedList) throws JSONException
{
    List<Polygon> polygons = new ArrayList<Polygon>();
    int n = json.length();
    for(int i = 0; i < n; i++) {
        polygons.add(Polygon.fromJSONArray(json.getJSONArray(i)));
    }
    return polygons;
}

用什么語言解析JSON。 從理論上講,這個想法可以應用於大多數語言。 如果它的javascript你可以使用

  for(var key in myJSONObjectVariable){
       var current = myJSONObjectVariable[key];
       //Have some logic or inner loops taking place on current
  }

但是,根據JSON數據的不可預測程度,我認為你可能是對的。 然而,字符串解析可能是要走的路

你有多個問題,所以我建議你把問題分解為幾個步驟。

第1步,你需要以某種方式在你的嵌套中的某個地方找到一個不同的列表。

您沒有提到您正在使用的編程語言,因此該問題的答案會有所不同。 如果您直接在JavaScript中執行此操作,則訪問任何不同的列表是一個簡單的數據訪問:

geometry.coordinates[0][1]

或者作為列表的Java映射(沒有錯誤檢查null返回或無效的數組索引,只是一個例子)

geometry.get("coordinates").get(0).get(1)      

如果您正在使用Java或C ++或類似的東西,您可能會發現使用JSON庫並將數據轉換為適當的語言結構(例如矢量圖)會更容易。 我不會嘗試直接操作JSON字符串。

然后,一旦您能夠以適當的語言獲取數據內容,第2步將評估您根據規則檢索的內容並確定您檢索的數據類型

下面的代碼將遞歸在任何深度進入提取緯度和經度值resultantArray ,使用JSON Java庫 (罐可以從下載這里 ):

public void run() throws JSONException
{
    JSONArray nestedList =
        new JSONArray("[" + "[ 1, 2 ]," + "[ [ 1, 2 ], [ 1, 2 ], [ 1, 2 ] ]," + "[ 3, 4 ],"
            + "[ [ [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ] ], [ 1, 2 ], [ 1, 2 ], [ 1, 2 ] ] ] ]");
    parseLists(nestedList);
}

private void parseLists(JSONArray nestedList) throws JSONException
{
    List<Location> resultantArray = new ArrayList<Location>();
    parseNestedList(nestedList, resultantArray);
    System.out.println(resultantArray.size());
}

private void parseNestedList(JSONArray json, List<Location> resultantArray) throws JSONException
{
    int elementCount = json.length();
    if (elementCount <= 0)
    {
        return;
    }
    if (json.get(0) instanceof JSONArray)
    {
        for (int i = 0; i < elementCount; i++)
        {
            parseNestedList((JSONArray) json.get(i), resultantArray);
        }
    }
    else
    {
        resultantArray.add(new Location(Double.parseDouble(json.get(0).toString()), Double.parseDouble(json
            .get(1)
            .toString())));
    }
}

一旦做到這一點,你應該運行你的算法,以確定考慮到該項目的多邊形resultantArray為點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM