简体   繁体   English

如何读取具有可变数组深度和结构的复杂JSON字符串?

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

I have a lot of JSON data which is organized in nested lists. 我有很多JSON数据,这些数据是在嵌套列表中组织的。 Each list consists of other lists and those lists could contain other lists and so on. 每个列表都包含其他列表,这些列表可能包含其他列表等。 The deepest list consists of a pair of longitute and latitude, eg 最深的清单包括一对穷人和纬度,例如

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

It would look as graph like this: 它看起来像这样的图形:

Coord列表

I basically don't know how nested those lists are. 我基本上不知道这些列表是如何嵌套的。 They differ all the time. 它们一直不同。 The next difficult part is that I need to get "coordinate polygons" from it. 接下来的困难部分是我需要从中获取“坐标多边形”。 That means that the lists that only consist of pairs of coordinates belong to the same polygon. 这意味着仅由坐标对组成的列表属于同一个多边形。 For example: 例如:

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

This would mean that there is a polygon consisting of 3 pairs of coordinates (so 3 corners). 这意味着存在由3对坐标组成的多边形(因此有3个角)。 I'm sure that this is solvable with some kind of String parsing. 我确信这可以通过某种String解析来解决。 I wonder if this is possible with basic JSON.simple (or maybe any other API) possibilities. 我想知道这是否可能与基本的JSON.simple(或可能任何其他API)可能性。 The problem is that JSON doesn't know anything about the data it is parsing. 问题是JSON对它正在解析的数据一无所知。 I have to tell JSON what the object is and have to use type conversion to get the correct data. 我必须告诉JSON对象是什么,并且必须使用类型转换来获取正确的数据。 See these examples here . 在此处查看这些示例 Now I need the other way around, but I never know what type is the data ("is it still another list or is the data the pair of coordiantes") , because those lists are very dynamic. 现在我需要相反的方式,但我永远不知道数据是什么类型(“它是另一个列表还是数据坐标对”) ,因为这些列表非常动态。 How can this be done in a convenient way? 怎么能以方便的方式完成? I could write some string parsing algorithm with some "push and pop behavior" to compare the JSON string character by character, but I wonder if there isn't a better way to do this? 我可以用一些“推送和弹出行为”来编写一些字符串解析算法来逐字符地比较JSON字符串,但我想知道是否有更好的方法来做到这一点?

[UPDATE] [UPDATE]
I figured out that this is a standardized JSON format, called GeoJSON. 我发现这是一种标准化的JSON格式,称为GeoJSON。 If you know how to read the data, it's pretty clear. 如果您知道如何阅读数据,那就很清楚了。 A Multipolygon consists of Polygons, and Polygons can have holes, represented by a 2nd Array in a Polygon object. 多边形由多边形组成,多边形可以有多个孔,由Polygon对象中的第二个数组表示。 See spec: Polygon , Multipolygon 见规格表: 多边形组合区

I basically don't know how nested those lists are 我基本上不知道这些列表是如何嵌套的

You know exactly how deeply nested these lists are. 您确切知道这些列表的嵌套程度。 At the top of your json, you have: 在你的json的顶部,你有:

"type": "Multipolygon"

To me, that implies List<Polygon> . 对我而言,这意味着List<Polygon> Now, what's a Polygon ? 现在,什么是Polygon Well, that's obviously a List<Coordinate> . 嗯,这显然是List<Coordinate> Finally, we know a Coordinate is a list with two elements. 最后,我们知道Coordinate是一个包含两个元素的列表。

To conclude, we have List<List<List<double>>> . 总之,我们有List<List<List<double>>> The depth of the arrays is known. 阵列的深度是已知的。

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;
}

What language are looking to parse JSON with. 用什么语言解析JSON。 Theoretically the idea can apply in most languages. 从理论上讲,这个想法可以应用于大多数语言。 If its javascript you can use 如果它的javascript你可以使用

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

Depending on how unpredictable the JSON data is however, I think you may be right though. 但是,根据JSON数据的不可预测程度,我认为你可能是对的。 String parsing may be the way to go however 然而,字符串解析可能是要走的路

You have multiple issues here, so I would first suggest you break down the problem into steps. 你有多个问题,所以我建议你把问题分解为几个步骤。

Step 1, you need to somehow get to a distinct list somewhere in your nesting. 第1步,你需要以某种方式在你的嵌套中的某个地方找到一个不同的列表。

You don't mention what programming language you are using so the answer to that problem will vary. 您没有提到您正在使用的编程语言,因此该问题的答案会有所不同。 If you are doing this directly in JavaScript then accessing any distinct list is a simple data access: 如果您直接在JavaScript中执行此操作,则访问任何不同的列表是一个简单的数据访问:

geometry.coordinates[0][1]

or as a Java map of lists (no error checking for null returns or invalid array indexes, just an example) 或者作为列表的Java映射(没有错误检查null返回或无效的数组索引,只是一个例子)

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

If you are using Java or C++ or something like that, you may find it easier to use a JSON library and convert the data into a language appropriate structure, a map of vectors for example. 如果您正在使用Java或C ++或类似的东西,您可能会发现使用JSON库并将数据转换为适当的语言结构(例如矢量图)会更容易。 I would not attempt to manipulate the JSON string directly. 我不会尝试直接操作JSON字符串。

Then, once you have the ability to fetch the data contents in a language appropriate manner, step 2 would be to evaluate what you retrieve against your rules and determine what type of data it is you retrieved. 然后,一旦您能够以适当的语言获取数据内容,第2步将评估您根据规则检索的内容并确定您检索的数据类型

The following code would recursively extract the latitude and longitude values at any depth into resultantArray , using the JSON Java library (the jar can be downloaded from here ): 下面的代码将递归在任何深度进入提取纬度和经度值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())));
    }
}

Once that is done, you should run your algorithm to identify polygons considering the entries in the resultantArray as points. 一旦做到这一点,你应该运行你的算法,以确定考虑到该项目的多边形resultantArray为点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM