Чтение вложенного массива целиком с помощью Utf8JsonReader - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь проанализировать определение геометрии GeoJSON, используя System.Text.Json s Utf8JsonReader.
Моя проблема в том, что свойство coordinates определения геометрии может быть расположено до определения type,coordinates может быть

  • простым массивом парных чисел ([0, 1]) для геометрий типа Point,
  • массивом массивов парных чисел ([[0,1],[2,3]]) длягеометрии типа LineString
  • массив массивов массивов двойников ([[[0,0],[10,0],[10,10],[0,0]],[[1,1],[9,9],[1,9],[1,1]]]) для геометрий типа Polygon с отверстиями и даже
  • массив перечисленных выше для геометрийтип MultiPolygon.

Таким образом, я не могу правильно проанализировать свойство coordinates, если не знаю type.
. Есть ли способ прочитать его целиком и проанализировать позже, используя Utf8JsonReader?

1 Ответ

0 голосов
/ 24 октября 2019

Я достиг того, что мне нравилось делать, используя следующую функцию

private ReadOnlySpan<byte> ReadCoordinateData(ref Utf8JsonReader reader)
{
    reader.ReadToken(JsonTokenType.StartArray);
    var res = new MemoryStream();
    res.Write(System.Text.Encoding.UTF8.GetBytes("["), 0, 1);
    int openBrackets = 1;

    bool wasCloseBracket = false;
    bool addComma = false;
    byte bytComma = System.Text.Encoding.UTF8.GetBytes(",")[0];
    while (openBrackets > 0)
    {
        // add a comma to separate arrays
        if (reader.TokenType == JsonTokenType.StartArray)
        {
            if (wasCloseBracket)
                res.WriteByte(bytComma);
            addComma = false;
            openBrackets++;
        }

        if (reader.TokenType == JsonTokenType.Number && addComma)
            res.WriteByte(bytComma);

        byte[] seq = reader.HasValueSequence
            ? reader.ValueSequence.ToArray()
            : reader.ValueSpan.ToArray();
        res.Write(seq, 0, seq.Length);

        addComma = reader.TokenType == JsonTokenType.Number;

        if (reader.TokenType == JsonTokenType.EndArray)
        {
            openBrackets--;
            addComma = false;
            wasCloseBracket = true;
        }
        else
        {
            wasCloseBracket = false;
        }

        if (!reader.Read())
            throw new JsonException();
    }

    return new ReadOnlySpan<byte>(res.ToArray());
}

...