#c_sharp #json
Есть json, в котором хранятся точки, из которых, в последствии, строятся определенные 3d объекты, по сути координаты вершин. Особенность в том что лежат они на неравномерной глубине. Как видно в 31-ом "наборе" точек они лежат сразу после узла "coordinates" а в 32-ом после этого узла они делятся еще на 2 группы, а внутри группы уже искомый набор точек. Задача состоит в том что бы дойти по узлам до элементов составляющих наборы точек (зеленые элементы являются координатами собственно x y), собрать точки принадлежащие одному набору в список, отправить их на обработку и дальше двигаться по json'у. Сложность в том, что там где они делятся на группы (32-ой), надо каждую группу элементов отправлять отдельно, как если бы это была законченная (как в случае с 31-ой, прошлись по 0,1,2 собрали точки внутри отправили пошли дальше), то есть зайти 32-geometry->coordinates->0 все что внутри собрать и отправить затем в 32-geometry->coordinate->1 собрать отправить, затем только дальше. Логично было бы предположить что там где type: MultiLineString можно просто добавить еще один цикл прохода по элементам, но что то мне подсказывает что я неверно рассуждаю. Как решить эту задачу правильно с точки зрения практик парсинга json файлов? Извините за сумбурное описание, пытался детализировать как мог. update вот таким образом я пытался добраться до необходимых мне данных, но данные из 32-ой группы сливались в один list и я так и не придумал как ПРАВИЛЬНО, мне их получить. Сейчас я понимаю судя по комментариям и ответам что я подобрался к задаче с принципиально не той стороны. private void CreateRoads(JSONObject mapData) { int count = 0; foreach (var geo in mapData["features"].list) { count++; var l = new List(); for (int i = 0; i < geo["geometry"]["coordinates"].list.Count; i++) { if (!geo["geometry"]["coordinates"][i][0].IsNumber) { for (int j = 0; j < geo["geometry"]["coordinates"][i].list.Count; j++) { var c = geo["geometry"]["coordinates"][i][j]; var bm = GM.LatLonToMeters(c[1].f, c[0].f); var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y); l.Add(pm.ToVector3xz()); } } else { var c = geo["geometry"]["coordinates"][i]; var bm = GM.LatLonToMeters(c[1].f, c[0].f); var pm = new Vector2(bm.x - Rect.center.x, bm.y - Rect.center.y); l.Add(pm.ToVector3xz()); } } var m = new GameObject("road_" + count.ToString()).AddComponent (); m.transform.localPosition = new Vector3(m.transform.localPosition.x, m.transform.localPosition.y + 1f, m.transform.localPosition.z); m.transform.parent = this.transform; try { m.Initialize(geo["properties"]["id"].str, this, l, geo["properties"]["kind"].str); } catch (Exception ex) { Debug.Log(ex); } } } с десериализацией я справился, спасибо @sp7, но как разрулить разные уровни глубины у блоков пока не пойму. Что бы это было универсально, а не хардкодом. Есть мысли на тему прохода в глубину до последнего узла (отличается тем что у него чайлдов видимо) от него вверх на уровень, собираем искомые данные (списки с координатами), отправляем, уровень вверх выходим, смотрим есть ли еще на это же уровне какие то списки, нету снова вверх если вышли до блока coordinates, то переходим к следующему номеру (33,34,35) и тд...вот беда только в том что я не знаю как такой проход в глубину сделать. И гугление не помогло особо =/ var root = JsonConvert.DeserializeObject (www.text); var features = root.roads.features; List
Ответы
Ответ 1
Позволю себе высказаться. Как ранее было замечено, для того что бы было удобно работать с Json данными, их нужно как минимум десериализовать в объектный вид. Поэтому: 1) Если у вас есть эти Json данные в текстовом виде (string) скопируйте их в буфер обмена. Если данных в текстовом виде нет, получите их откуда-то из вне, преобразуйте в строку (как вариант, JObject.Parse().ToString()) и скопируйте в буфер обмена. 2) Создайте пустой С# файл, в нем не должно быть ничего, кроме указания namespace. Курсор ставим внутрь namespace. 3) Затем в Visual Studio заходим в меню Edit -> Paste Special -> Paste JSON as Classes. 4) Вуаля!!! Visual Studio создала за вас классы, которые представляют указанные Json данные. 5) Теперь когда классы С# готовы, Вы можете ваши Json данные используя JsonSerializer десериализовать в ту объектную модель, что за вас создала студия. var root = JsonConvert.DeserializeObject(jsonStr); 6) Ну и в завершении, теперь Вы просто можете работать с данными в удобном виде. Ответ 2
Взгляните вот тут, как десериализуются части JSON... Здесь делается общий парсинг, а затем можно переходить на уровни и десериализовать их вот так : JObject googleSearch = JObject.Parse(googleSearchText); // get JSON result objects into a list IListresults = googleSearch["responseData"]["results"].Children().ToList(); // serialize JSON results into .NET objects IList searchResults = new List (); foreach (JToken result in results) { SearchResult searchResult = JsonConvert.DeserializeObject (result.ToString()); searchResults.Add(searchResult); }
Комментариев нет:
Отправить комментарий