#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); }
Комментариев нет:
Отправить комментарий