我有很多JSON数据,这些数据是在嵌套列表中组织的。每个列表都包含其他列表,这些列表可能包含其他列表等。最深的清单包括一对穷人和纬度,例如
[[[..... [16.353542354,48.2354242424],[16.46353535,48.2546754646] ....] .....]。
它看起来像这样的图形:
我基本上不知道这些列表是如何嵌套的。它们一直不同。接下来的困难部分是我需要从中获取“坐标多边形”。这意味着仅由坐标对组成的列表属于同一个多边形。例如:
[...... [[16.23542424,48.2342424242],[16.2423242352354,48.12342534634],[16.35353453535,48.345635353]] ......
这意味着存在由3对坐标组成的多边形(因此3个角)。 我确信这可以通过某种String解析来解决。我想知道这是否可能与基本的JSON.simple(或可能任何其他API)可能性。问题是JSON对它正在解析的数据一无所知。我必须告诉JSON对象是什么,并且必须使用类型转换来获取正确的数据。请参阅这些示例here。现在我需要另一种方式,但我永远不知道数据是什么类型(“它是另一个列表还是数据一对坐标”),因为这些列表非常动态。怎么能以方便的方式完成?我可以用一些“推送和弹出行为”来编写一些字符串解析算法,以逐字符比较JSON字符串,但我想知道是否有更好的方法来做到这一点?
[UPDATE]
我发现这是一种标准化的JSON格式,称为GeoJSON。如果您知道如何阅读数据,那就很清楚了。多边形由多边形组成,多边形可以有多个孔,由Polygon对象中的第二个数组表示。见规格:
Polygon,Multipolygon
答案 0 :(得分:2)
我基本上不知道这些列表是如何嵌套的
您确切知道这些列表的嵌套程度。在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;
}
答案 1 :(得分:0)
用什么语言解析JSON。从理论上讲,这个想法可以应用于大多数语言。如果它的javascript你可以使用
for(var key in myJSONObjectVariable){
var current = myJSONObjectVariable[key];
//Have some logic or inner loops taking place on current
}
根据JSON数据的不可预测性,我认为你可能是对的。然而,字符串解析可能是要走的路
答案 2 :(得分:0)
这里有多个问题,所以我建议您将问题分解为几个步骤。
第1步,你需要以某种方式在你的嵌套中的某个地方找到一个不同的列表。
您没有提到您正在使用的编程语言,因此该问题的答案会有所不同。如果您直接在JavaScript中执行此操作,则访问任何不同的列表是一种简单的数据访问:
geometry.coordinates[0][1]
或作为列表的Java映射(没有错误检查null返回或无效的数组索引,只是一个例子)
geometry.get("coordinates").get(0).get(1)
如果您使用的是Java或C ++或类似的东西,您可能会发现使用JSON库并将数据转换为适当的语言结构(例如矢量图)会更容易。我不会尝试直接操作JSON字符串。
然后,一旦您能够以适当的语言获取数据内容,第2步将评估您根据规则检索的内容,并确定您检索的数据的类型 。
答案 3 :(得分:0)
以下代码将使用JSON Java library(可以从here下载jar)以递归方式将任意深度的纬度和经度值提取到resultantArray
中:
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
中的条目视为点。