JSON

JavaScript Object Notation (JSON) - это популярный и легкий формат обмена данными. ArcGIS Velocity может использовать JSON, созданный из данных наблюдений Интернета вещей (IoT), из различных источников.

JSON поддерживается в качестве формата данных для следующих типов каналов и источников данных:

  • Каналы — Azure Event Hub, Azure Service Bus, AWS IoT, Cisco Edge Intelligence, HTTP Poller, HTTP Receiver, Kafka, WebSocket, RabbitMQ, MQTT
  • Источники данных — Azure Blob storage, Amazon S3, HTTP Poller

Задание конфигурации JSON

При настройке канала или источника данных, производится выборка для определения типа используемых данных. Если при выборке данные определяются как JSON, можно задать следующие дополнительные параметры, относящиеся к указываемой конфигурации JSON:

Корневой узел

Если это применимо, укажите корневой узел структуры JSON, в котором находятся сообщения. Оставьте пустым, если структура JSON содержит все сообщения в массиве на корневом уровне. Например, в следующем пример JSON показаны данные с несколькими уровнями и объектами:

{
  "requestInfo": {
    "requestTime": 1573591345,
    "requestingUser": "Greg Smith"
  },
  "responseInfo": {
    "dataLastUpdated": 1573239432
  },
  "sensorData": [{
    "vehicleID": "17256",
    "driverName": "Peter Jones",
    "latitude": 35.21027,
    "longitude": -81.291326,
    "speed": 64.3,
    "heading": 161.34,
    "status": "Out for delivery",
    "lastBreak": 1573591581
  }, {
    "vehicleID": "11954",
    "driverName": "Frank Jenkins",
    "latitude": 35.23425,
    "longitude": -81.092657,
    "speed": 25.8,
    "heading": 54.64,
    "status": "Returning to warehouse",
    "lastBreak": 1573581253
  }]
}

Если был задан корневой узел sensorData, в Velocity будут использованы только следующие данные:

[{
  "vehicleID": "17256",
  "driverName": "Peter Jones",
  "latitude": 35.21027,
  "longitude": -81.291326,
  "speed": 64.3,
  "heading": 161.34,
  "status": "Out for delivery",
  "lastBreak": 1573591581
}, {
  "vehicleID": "11954",
  "driverName": "Frank Jenkins",
  "latitude": 35.23425,
  "longitude": -81.092657,
  "speed": 25.8,
  "heading": 54.64,
  "status": "Returning to warehouse",
  "lastBreak": 1573581253
}]

Результатом будет получение схемы ниже:

Итоговая страница Подтвердить схему с заданным корневым узлом sensorData

Разбить

Параметр Разбить определяет, следует ли разбивать вложенный JSON на отдельные поля. Эти новые поля именуются путем добавления имен объектов более низкого уровня к объекту более высокого уровня через разделитель - подчеркивание. В примере ниже объект position содержит объекты latitude и longitude. Если выполнено разбиение, объект position разбивается на два поля, position_latitude и position_longitude.

При разбиении JSON может содержать несколько уровней глубины. К новым именам полей будут добавляться имена объектов с подчеркиванием, пока не будет достигнут объект самого глубокого уровня.

Например, в следующем пример JSON показаны объекты position и vehicleInformation:

[{
  "vehicleID": "17256",
  "driverName": "Peter Jones",
  "position": {
    "latitude": 35.21027,
    "longitude": -81.291326
  },
  "vehicleInformation": {
    "lastService": 1571431836,
    "warningCodes": 2
  },
  "speed": 64.3,
  "heading": 161.34,
  "status": "Out for delivery",
  "lastBreak": 1573591581
}, {
  "vehicleID": "11954",
  "driverName": "Frank Jenkins",
  "position": {
    "latitude": 35.23425,
    "longitude": -81.092657
  },
  "vehicleInformation": {
    "lastService": 1560531836,
    "warningCodes": 2
  },
  "speed": 25.8,
  "heading": 54.64,
  "status": "Returning to warehouse",
  "lastBreak": 1573581253
}]

Если включена опция Разбить, в примере выше, JSON будет обработан как показано ниже, где элементы в объектах position и vehicleInformation разбиты по соответствующим полям:

[{
  "vehicleID": "17256",
  "driverName": "Peter Jones",
  "position_latitude": 35.21027,
  "position_longitude": -81.291326,
  "vehicleInformation_lastService": 1571431836,
  "vehicleInformation_warningCodes": 2,
  "speed": 64.3,
  "heading": 161.34,
  "status": "Out for delivery",
  "lastBreak": 1573591581
}, {
  "vehicleID": "11954",
  "driverName": "Frank Jenkins",
  "position_latitude": 35.23425,
  "position_longitude": -81.092657,
  "vehicleInformation_lastService": 1560531836,
  "vehicleInformation_warningCodes": 2,
  "speed": 25.8,
  "heading": 54.64,
  "status": "Returning to warehouse",
  "lastBreak": 1573581253
}]

Схема будет использована, как в примере ниже. Хотя имена полей vehicleInformation_lastService и vehicleInformation_warningCodes обрезаны в интерфейсе, в приложении они остаются без изменений:

Итоговая страница Подтвердить схему из JSON с разбиением

Исключения разбиения

Параметр Исключения разбиения позволяет указать одно или более имен элементов JSON, которые дролжны остаться как одиночные строковые элементы, а не разбиваться на отдельные поля, например, объект JSON, представляющий массив, или объект, содераший другие элементы. Рассмотрим следующий JSON:

[{
  "ship_ID": "17256",
  "call_sign": "3FCB8",
  "ship_type": "Cargo",
  "last_known_position": {
    "timestamp": "2019-06-24T18:30:56+00:00",
    "geometry": {
      "type": "Point",
      "coordinates": [
        79.19315,
        7.18374
      ]
    },
    "heading": 109
  }
}, {
  "ship_ID": "29435",
  "call_sign": "9GEF3",
  "ship_type": "Passenger",
  "last_known_position": {
    "timestamp": "2019-06-24T18:30:47+00:00",
    "geometry": {
      "type": "Point",
      "coordinates": [
        73.24954,
        10.43512
      ]
    },
    "heading": 120
  }
}]

Если отмечена опция Разбить и указано Исключения разбиения для значения geometry, в примере выше JSON будет выглядеть как показано ниже. В поле last_known_position_geometry объект JSON не включен в разбиение. Это связано с тем, что исходный элемент JSON geometry, был указан в параметре Исключения разбиения. Это используется, если вы хотите сохранить объекты JSON. Часто это применяется для объектов геометрии, отображающих пространственное расположение объектов. В этом случае этот атрибут будет находиться в формате геометрии GeoJSON.

[{
  "ship_ID": "17256",
  "call_sign": "3FCB8",
  "ship_type": "Cargo",
  "last_known_position_timestamp": "2019-06-24T18:30:56+00:00",
  "last_known_position_geometry": {
    "type": "Point",
    "coordinates": [
      79.19315,
      7.18374
    ]
  },
  "last_known_position_heading": 109
}, {
  "ship_ID": "29435",
  "call_sign": "9GEF3",
  "ship_type": "Passenger",
  "last_known_position_timestamp": "2019-06-24T18:30:47+00:00",
  "last_known_position_geometry": {
    "type": "Point",
    "coordinates": [
      73.24954,
      10.43512
    ]
  },
  "last_known_position_heading": 120
}]

Схема используется, как показано ниже, и указывается получение информации о канале или расположении источника данных из одного поля.

Итоговая страница Подтвердить схему из JSON с разбиением и исключенным из разбиения полем геометрии

Разбить массивы

Параметр Разбить массивы определяет, следует ли разбивать массивы на отдельные поля. Имена новых полей образуются путем добавления значения arrayName с подчеркиванием и числа объектов массива. Если массив является массивом объектов, к имени поля также добавляется нижнее подчеркивание, и имя, связанное со значением. При разбиении массива объектов JSON может содержать несколько уровней глубины. К новым именам полей будут добавляться имена объектов с подчеркиванием, пока не будет достигнут объект самого глубокого уровня.

Например, в следующем пример JSON показаны объекты массива cargoInformation:

{
    "name": "iss",
    "id": 25544,
    "latitude": -13.210305423781,
    "longitude": -118.47517068897,
    "velocity": 27564.442053654,
    "visibility": "daylight",
    "cargoInformation": [{
            "sensorsID": 1,
            "age": 5432
        }, {
            "sensorsID": 2,
            "age": 9876
        }
    ],
    "footprint": 4521.609615023,
    "timestamp": 1654531549,
    "daynum": 2459737.170706,
    "solar_lat": 22.696540649846,
    "solar_lon": 298.23268983658,
    "units": "kilometers"
}

Если включена опция Разбить массив, в примере выше, JSON будет обработан как показано ниже, где элементы в объекте cargo information разбиты по соответствующим полям:

{
    "name": "iss",
    "id": 25544,
    "latitude": -13.210305423781,
    "longitude": -118.47517068897,
    "velocity": 27564.442053654,
    "visibility": "daylight",
    "cargoInformation_0_sensorsID": 1,
    "cargoInformation_0_age": 5432,
    "cargoInformation_1_sensorsID": 2,
    "cargoInformation_1_age": 9876,
    "footprint": 4521.609615023,
    "timestamp": 1654531549,
    "daynum": 2459737.170706,
    "solar_lat": 22.696540649846,
    "solar_lon": 298.23268983658,
    "units": "kilometers"
}

Схема будет использована, как в примере ниже. Хотя имена полей cargoInformation обрезаны в интерфейсе, в приложении они остаются без изменений:

Разбиение массивов в формате JSON

Исключения разбиения массива

Параметр Исключения разбиения массива позволяют указать один или несколько имен массивов JSON, которые следует оставить в качестве одного строкового элемента, а не разбивать на отдельные поля. Рассмотрим следующий JSON:

{
    "name": "iss",
    "id": 25544,
    "latitude": -13.210305423781,
    "longitude": -118.47517068897,
    "velocity": 27564.442053654,
    "visibility": "daylight",
    "cargoInformation": [{
            "sensorsID": 1,
            "age": 5432
        }, {
            "sensorsID": 2,
            "age": 9876
        }
    ],
    "sensorValues": [1,2,3,4,5],
    "footprint": 4521.609615023,
    "timestamp": 1654531549,
    "daynum": 2459737.170706,
    "solar_lat": 22.696540649846,
    "solar_lon": 298.23268983658,
    "units": "kilometers"
}

Если отмечена опция Разбить массивы и указано Исключения разбиения массива для значения sensorValues, в примере выше JSON будет выглядеть как показано ниже. В массиве sensorValues не разбивается и остается ежиной строкой. Для указания нескольких массивов в исключениях разбиения, используйте запятые в параметре Исключения разбиения массива.

{
    "name": "iss",
    "id": 25544,
    "latitude": -13.210305423781,
    "longitude": -118.47517068897,
    "velocity": 27564.442053654,
    "visibility": "daylight",
    "cargoInformation_0_sensorsID": 1,
    "cargoInformation_0_age": 5432,
    "cargoInformation_1_sensorsID": 2,
    "cargoInformation_1_age": 9876,
    "sensorValues": [1,2,3,4,5],
    "footprint": 4521.609615023,
    "timestamp": 1654531549,
    "daynum": 2459737.170706,
    "solar_lat": 22.696540649846,
    "solar_lon": 298.23268983658,
    "units": "kilometers"
}

Схема будет использована, как в примере ниже.

Исключение разбиения массива JSON

Советы и ограничения

При работе с данными в формате JSON в Velocity необходимо ознакомится с информацией и ограничениями, описанными ниже.

Данные JSON, содержащие массивы

Массивы добавляют в JSON гибкость, однако при построении объектов ArcGIS из данных JSON могут возникнуть трудности с неопределяемой длиной. Если весь документ или определенный корневой узел представляет собой массив объектов, индивидуальные объекты будут рассматриваться как отдельные объекты. Массивы в объекте JSON образуются в виде строк. Вы можете проводить последующую обработку строк, используя инструменты анализа.

Значения Null

В формате JSON данные представлены в виде пар имя-значение. Если значение пустое, многие приложения, создающие данные в формате JSON, просто пропустят имя объекта.

Это важно помнить при выполнении первой настройки или редактирования канала, или источника данных. Velocity отбирает образцы потока данных или файлов, для определения наилучшего формата данных и схемы. Если во всех выборках отсутствуют элементы JSON, поскольку эти выборки содержат пустые значения, эти поля будут пропущены в схеме канала или источника данных.

В результате сообщения, поступившие позднее, у которых есть значения данных для этих элементов JSON, не будут обработаны в наблюдениях или записях, которые будут анализироваться каналами или аналитикой в Velocity.

Производные типы полей

Оригинальные данные JSON не имеют строгих типов, поэтому иногда бывает необходимо исправить типы полей, полученные из выборок. Тем не менее, менять типы полей следует с осторожностью. Лучше всего сделать тип поля более инклюзивным, а не менее. Например, небольшая выборка данных может не показать, что определенное поле должно быть Float64, а не Float32.

Кроме того, не рекомендуется изменение типа поля с формата числа с плавающей точкой (Float64 или Float32) на целочисленный (Int64 или Int32). Изменение типов полей не предназначено для преобразования числовых значений на лету. Для данных JSON при понижении формата - с плавающей точки до целого числа - дробная часть будет удалена без округления. Чтобы преобразовать числовые значения, используйте инструмент Вычислить поле или Сопоставить поля.

Размер файла LAS

Рекомендуется хранить файлы JSON в Velocity размером не более 100 МБ. Если у вас имеются данные большего объема, рекомендуется разбить эти файлы, чтобы размер каждого не превышал 100 МБ.