44 KiB
Геозони
Скетчнот від Nitya Narasimhan. Натисніть на зображення, щоб побачити його у більшому розмірі.
Це відео дає огляд геозон та їх використання в Azure Maps, теми, які будуть розглянуті в цьому уроці:
🎥 Натисніть на зображення вище, щоб переглянути відео
Тест перед лекцією
Вступ
У попередніх трьох уроках ви використовували IoT для відстеження вантажівок, які перевозять вашу продукцію з ферми до центру обробки. Ви збирали GPS-дані, надсилали їх у хмару для зберігання та візуалізували їх на карті. Наступний крок для підвищення ефективності вашого ланцюга постачання — отримувати сповіщення, коли вантажівка наближається до центру обробки, щоб команда, яка займається розвантаженням, могла бути готова з навантажувачами та іншим обладнанням одразу після прибуття транспортного засобу. Це дозволить швидко розвантажити вантажівку, і ви не будете платити за час простою водія та транспортного засобу.
У цьому уроці ви дізнаєтеся про геозони — визначені геопросторові області, наприклад, зону в межах 2 км від центру обробки, — і як перевіряти, чи знаходяться GPS-координати всередині або за межами геозони, щоб визначити, чи прибув ваш GPS-сенсор у зону або залишив її.
У цьому уроці ми розглянемо:
- Що таке геозони
- Визначення геозони
- Перевірка точок щодо геозони
- Використання геозон у безсерверному коді
🗑 Це останній урок у цьому проєкті, тому після завершення уроку та завдання не забудьте очистити свої хмарні сервіси. Вам знадобляться ці сервіси для виконання завдання, тому спочатку переконайтеся, що завдання виконано.
За потреби зверніться до посібника з очищення проєкту для отримання інструкцій.
Що таке геозони
Геозона — це віртуальний периметр для реальної географічної області. Геозони можуть бути колами, визначеними як точка та радіус (наприклад, коло діаметром 100 м навколо будівлі), або багатокутниками, що охоплюють певну область, наприклад, шкільну зону, межі міста чи територію університету або офісного кампусу.
💁 Ви, можливо, вже використовували геозони, навіть не знаючи про це. Якщо ви встановлювали нагадування в додатку iOS Reminders або Google Keep на основі місця розташування, ви використовували геозону. Ці додатки створюють геозону на основі вказаного місця і сповіщають вас, коли ваш телефон входить у геозону.
Існує багато причин, чому важливо знати, чи знаходиться транспортний засіб всередині або за межами геозони:
- Підготовка до розвантаження — отримання сповіщення про прибуття транспортного засобу на місце дозволяє команді підготуватися до розвантаження, зменшуючи час очікування. Це може дозволити водієві здійснити більше доставок за день із меншими затримками.
- Податковий облік — у деяких країнах, таких як Нова Зеландія, податки на дороги для дизельних транспортних засобів нараховуються залежно від ваги транспортного засобу лише на громадських дорогах. Використання геозон дозволяє відстежувати пробіг на громадських дорогах у порівнянні з приватними дорогами, наприклад, на фермах або в лісозаготівельних районах.
- Моніторинг крадіжок — якщо транспортний засіб повинен залишатися в певній зоні, наприклад, на фермі, і він залишає геозону, це може свідчити про крадіжку.
- Дотримання правил розташування — деякі частини робочого майданчика, ферми або фабрики можуть бути заборонені для певних транспортних засобів, наприклад, для тих, що перевозять штучні добрива та пестициди, щоб уникнути їх потрапляння на поля з органічною продукцією. Якщо геозона порушена, транспортний засіб знаходиться поза зоною відповідності, і водій може бути сповіщений.
✅ Чи можете ви придумати інші способи використання геозон?
Azure Maps, сервіс, який ви використовували в попередньому уроці для візуалізації GPS-даних, дозволяє визначати геозони та перевіряти, чи знаходиться точка всередині або за межами геозони.
Визначення геозони
Геозони визначаються за допомогою GeoJSON, так само як і точки, які були додані на карту в попередньому уроці. У цьому випадку, замість FeatureCollection
із значеннями Point
, це буде FeatureCollection
, що містить Polygon
.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.13393688201903,
47.63829579223815
],
[
-122.13389128446579,
47.63782047131512
],
[
-122.13240802288054,
47.63783312249837
],
[
-122.13238388299942,
47.63829037035086
],
[
-122.13393688201903,
47.63829579223815
]
]
]
},
"properties": {
"geometryId": "1"
}
}
]
}
Кожна точка багатокутника визначається як пара довготи та широти в масиві, і ці точки знаходяться в масиві, який задається як coordinates
. У Point
у попередньому уроці coordinates
був масивом із двома значеннями — широтою та довготою. Для Polygon
це масив масивів із двома значеннями — довготою та широтою.
💁 Пам'ятайте, GeoJSON використовує
довгота, широта
для точок, а неширота, довгота
.
Масив координат багатокутника завжди має на одну точку більше, ніж кількість вершин багатокутника, оскільки остання точка збігається з першою, закриваючи багатокутник. Наприклад, для прямокутника буде 5 точок.
На зображенні вище є прямокутник. Координати багатокутника починаються з верхнього лівого кута (47,-122), потім рухаються вправо (47,-121), вниз (46,-121), вліво (46,-122) і повертаються до початкової точки (47,-122). Це дає багатокутнику 5 точок — верхній лівий, верхній правий, нижній правий, нижній лівий і знову верхній лівий для замикання.
✅ Спробуйте створити GeoJSON-багатокутник навколо вашого дому або школи. Використовуйте інструмент, наприклад, GeoJSON.io.
Завдання — визначення геозони
Щоб використовувати геозону в Azure Maps, спочатку її потрібно завантажити у ваш обліковий запис Azure Maps. Після завантаження ви отримаєте унікальний ідентифікатор, який можна використовувати для перевірки точки щодо геозони. Для завантаження геозон в Azure Maps потрібно використовувати веб-API карт. Ви можете викликати веб-API Azure Maps за допомогою інструменту curl.
🎓 Curl — це інструмент командного рядка для виконання запитів до веб-інтерфейсів.
-
Якщо ви використовуєте Linux, macOS або останню версію Windows 10, curl, ймовірно, вже встановлений. Виконайте наступну команду в терміналі або командному рядку, щоб перевірити:
curl --version
Якщо ви не бачите інформації про версію curl, вам потрібно буде встановити його з сторінки завантаження curl.
💁 Якщо ви досвідчений користувач Postman, ви можете використовувати його замість curl, якщо вам так зручніше.
-
Створіть файл GeoJSON, що містить багатокутник. Ви будете тестувати його за допомогою вашого GPS-сенсора, тому створіть багатокутник навколо вашого поточного місця розташування. Ви можете створити його вручну, відредагувавши приклад GeoJSON, наведений вище, або скористатися інструментом, наприклад, GeoJSON.io.
GeoJSON повинен містити
FeatureCollection
, що включаєFeature
ізgeometry
типуPolygon
.Ви ПОВИННІ також додати елемент
properties
на тому ж рівні, що й елементgeometry
, і він повинен міститиgeometryId
:"properties": { "geometryId": "1" }
Якщо ви використовуєте GeoJSON.io, вам доведеться вручну додати цей елемент до порожнього
properties
, або після завантаження JSON-файлу, або в редакторі JSON у додатку.Цей
geometryId
має бути унікальним у цьому файлі. Ви можете завантажити кілька геозон як кількаFeatures
уFeatureCollection
в одному GeoJSON-файлі, за умови, що кожна з них має різнийgeometryId
. Багатокутники можуть мати однаковийgeometryId
, якщо вони завантажені з іншого файлу в інший час. -
Збережіть цей файл як
geofence.json
і перейдіть до місця його збереження у вашому терміналі або консолі. -
Виконайте наступну команду curl, щоб створити геозону:
curl --request POST 'https://atlas.microsoft.com/mapData/upload?api-version=1.0&dataFormat=geojson&subscription-key=<subscription_key>' \ --header 'Content-Type: application/json' \ --include \ --data @geofence.json
Замініть
<subscription_key>
у URL на API-ключ вашого облікового запису Azure Maps.URL використовується для завантаження даних карти через API
https://atlas.microsoft.com/mapData/upload
. Запит включає параметрapi-version
, щоб вказати, яку версію API Azure Maps використовувати. Це дозволяє API змінюватися з часом, зберігаючи зворотну сумісність. Формат даних, що завантажуються, встановлено якgeojson
.Це виконає POST-запит до API завантаження і поверне список заголовків відповіді, включаючи заголовок
location
.content-type: application/json location: https://us.atlas.microsoft.com/mapData/operations/1560ced6-3a80-46f2-84b2-5b1531820eab?api-version=1.0 x-ms-azuremaps-region: West US 2 x-content-type-options: nosniff strict-transport-security: max-age=31536000; includeSubDomains x-cache: CONFIG_NOCACHE date: Sat, 22 May 2021 21:34:57 GMT content-length: 0
🎓 Під час виклику веб-інтерфейсу ви можете передавати параметри до запиту, додаючи
?
, за яким слідують пари ключ-значення у форматіkey=value
, розділені символом&
. -
Azure Maps не обробляє це одразу, тому вам потрібно буде перевірити, чи завершено запит на завантаження, використовуючи URL, вказаний у заголовку
location
. Зробіть GET-запит до цього місця, щоб перевірити статус. Вам потрібно буде додати ваш ключ підписки до кінця URLlocation
, додавши&subscription-key=<subscription_key>
, замінивши<subscription_key>
на API-ключ вашого облікового запису Azure Maps. Виконайте наступну команду:curl --request GET '<location>&subscription-key=<subscription_key>'
Замініть
<location>
на значення заголовкаlocation
, а<subscription_key>
на API-ключ вашого облікового запису Azure Maps. -
Перевірте значення
status
у відповіді. Якщо це неSucceeded
, зачекайте хвилину і спробуйте знову. -
Коли статус повернеться як
Succeeded
, зверніть увагу наresourceLocation
у відповіді. Це містить деталі про унікальний ідентифікатор (UDID) для об'єкта GeoJSON. UDID — це значення післяmetadata/
, але не включаючиapi-version
. Наприклад, якщоresourceLocation
був:{ "resourceLocation": "https://us.atlas.microsoft.com/mapData/metadata/7c3776eb-da87-4c52-ae83-caadf980323a?api-version=1.0" }
Тоді UDID буде
7c3776eb-da87-4c52-ae83-caadf980323a
.Збережіть цей UDID, оскільки він знадобиться для перевірки геозони.
Перевірка точок щодо геозони
Після завантаження багатокутника в Azure Maps ви можете перевірити, чи знаходиться точка всередині або за межами геозони. Для цього потрібно зробити запит до веб-API, передавши UDID геозони, а також широту та довготу точки для перевірки.
Під час цього запиту ви також можете передати значення, яке називається searchBuffer
. Це значення вказує API Maps, наскільки точно потрібно повертати результати. Це важливо, оскільки GPS не є абсолютно точним, і іноді місця можуть бути зміщені на кілька метрів або більше. За замовчуванням searchBuffer
становить 50 м, але ви можете встановлювати значення від 0 м до 500 м.
Коли результати повертаються з API-запиту, одна з частин результату — це distance
, яка вимірюється до найближчої точки на краю геозони. Значення буде позитивним, якщо точка знаходиться за межами геозони, і негативним, якщо вона всередині. Якщо ця відстань менша за searchBuffer
, повертається фактична відстань у метрах, інакше значення буде 999 або -999. 999 означає, що точка знаходиться за межами геозони на відстані, більшій за searchBuffer
, -999 означає, що точка знаходиться всередині геозони на відстані, більшій за searchBuffer
.
На зображенні вище геозона має буфер пошуку 50 м.
- Точка в центрі геозони, далеко всередині буфера пошуку, має відстань -999.
- Точка далеко за межами буфера пошуку має відстань 999.
- Точка всередині геозони та буфера пошуку, на відстані 6 м від геозони, має відстань 6 м.
- Точка за межами геозони, але всередині буфера пошуку, на відстані 39 м від геозони, має відстань 39 м.
Важливо знати відстань до краю геозони та комбінувати цю інформацію з іншими даними, такими як інші GPS-зчитування, швидкість і дорожні дані, під час прийняття рішень на основі місця розташування транспортного засобу.
Наприклад, уявіть GPS-зчитування, які показують, що транспортний засіб рухався дорогою, яка проходить поруч із геозоною. Якщо одне GPS-зчитування є неточним і показує, що транспортний засіб знаходиться всередині геозони, хоча доступу для транспортних засобів немає, це зчитування можна ігнорувати.
На зображенні вище показано геозону, яка охоплює частину кампусу Microsoft. Червона лінія позначає маршрут вантажівки вздовж 520, а кола вказують на GPS-зчитування. Більшість із них точні та знаходяться вздовж 520, але одне зчитування є неточним і знаходиться всередині геозони. Це зчитування не може бути правильним — немає доріг, які дозволили б вантажівці раптово звернути з 520 на кампус, а потім повернутися на 520. Код, який перевіряє цю геозону, повинен враховувати попередні зчитування перед тим, як діяти на основі результатів тесту геозони.
✅ Які додаткові дані вам потрібні, щоб перевірити, чи можна вважати GPS-зчитування правильним?
Завдання — перевірка точок у геозоні
-
Почніть із створення URL для запиту до веб-API. Формат такий:
https://atlas.microsoft.com/spatial/geofence/json?api-version=1.0&deviceId=gps-sensor&subscription-key=<subscription-key>&udid=<UDID>&lat=<lat>&lon=<lon>
Замініть
<subscription_key>
на ключ API для вашого облікового запису Azure Maps.Замініть
<UDID>
на UDID геозони з попереднього завдання.Замініть
<lat>
і<lon>
на широту та довготу, які ви хочете перевірити.Цей URL використовує API
https://atlas.microsoft.com/spatial/geofence/json
для запиту геозони, визначеної за допомогою GeoJSON. Він орієнтований на версію API1.0
. ПараметрdeviceId
є обов’язковим і повинен бути назвою пристрою, з якого отримано широту та довготу.За замовчуванням буфер пошуку становить 50 м, і ви можете змінити це, передавши додатковий параметр
searchBuffer=<distance>
, встановивши<distance>
як відстань буфера пошуку в метрах, від 0 до 500. -
Використовуйте curl для виконання GET-запиту до цього URL:
curl --request GET '<URL>'
💁 Якщо ви отримуєте код відповіді
BadRequest
із помилкою:Invalid GeoJSON: All feature properties should contain a geometryId, which is used for identifying the geofence.
це означає, що у вашому GeoJSON відсутній розділ
properties
ізgeometryId
. Вам потрібно виправити GeoJSON, а потім повторити наведені вище кроки, щоб повторно завантажити файл і отримати новий UDID. -
Відповідь міститиме список
geometries
, по одному для кожного полігону, визначеного в GeoJSON, який використовувався для створення геозони. Кожна геометрія має 3 поля, які нас цікавлять:distance
,nearestLat
іnearestLon
.{ "geometries": [ { "deviceId": "gps-sensor", "udId": "7c3776eb-da87-4c52-ae83-caadf980323a", "geometryId": "1", "distance": 999.0, "nearestLat": 47.645875, "nearestLon": -122.142713 } ], "expiredGeofenceGeometryId": [], "invalidPeriodGeofenceGeometryId": [] }
-
nearestLat
іnearestLon
— це широта та довгота точки на краю геозони, яка найближча до місця, що перевіряється. -
distance
— це відстань від місця, що перевіряється, до найближчої точки на краю геозони. Від’ємні числа означають, що точка знаходиться всередині геозони, додатні — зовні. Це значення буде меншим за 50 (буфер пошуку за замовчуванням) або 999.
-
-
Повторіть це кілька разів із точками всередині та поза геозоною.
Використання геозон у безсерверному коді
Тепер ви можете додати новий тригер до вашого додатка Functions, щоб перевіряти дані GPS із IoT Hub на відповідність геозоні.
Групи споживачів
Як ви пам’ятаєте з попередніх уроків, IoT Hub дозволяє відтворювати події, які були отримані хабом, але не оброблені. Але що станеться, якщо підключиться кілька тригерів? Як хаб знатиме, які події вже оброблені?
Відповідь — ніяк! Натомість ви можете визначити кілька окремих підключень для зчитування подій, і кожне з них може керувати відтворенням непрочитаних повідомлень. Ці підключення називаються групами споживачів. Коли ви підключаєтеся до кінцевої точки, ви можете вказати, до якої групи споживачів хочете підключитися. Кожен компонент вашого додатка підключатиметься до різної групи споживачів.
Теоретично до кожної групи споживачів можуть підключитися до 5 додатків, і всі вони отримуватимуть повідомлення, коли вони надходять. Найкраща практика — мати лише один додаток, який отримує доступ до кожної групи споживачів, щоб уникнути дублювання обробки повідомлень і забезпечити правильну обробку всіх чергових повідомлень під час перезапуску. Наприклад, якщо ви запустите свій додаток Functions локально, а також у хмарі, обидва оброблятимуть повідомлення, що призведе до дублювання об’єктів у сховищі.
Якщо ви переглянете файл function.json
для тригера IoT Hub, створеного на попередньому уроці, ви побачите групу споживачів у розділі прив’язки тригера подій:
"consumerGroup": "$Default"
Коли ви створюєте IoT Hub, за замовчуванням створюється група споживачів $Default
. Якщо ви хочете додати додатковий тригер, ви можете зробити це, використовуючи нову групу споживачів.
💁 У цьому уроці ви використовуватимете іншу функцію для перевірки геозони, ніж ту, яка використовується для зберігання даних GPS. Це демонструє, як використовувати групи споживачів і розділяти код, щоб його було легше читати та розуміти. У виробничому додатку є багато способів організувати це — об’єднати обидві функції в одну, використовувати тригер у сховищі для запуску функції перевірки геозони або використовувати кілька функцій. Немає "правильного способу", усе залежить від решти вашого додатка та ваших потреб.
Завдання — створення нової групи споживачів
-
Виконайте наступну команду, щоб створити нову групу споживачів із назвою
geofence
для вашого IoT Hub:az iot hub consumer-group create --name geofence \ --hub-name <hub_name>
Замініть
<hub_name>
на назву, яку ви використовували для свого IoT Hub. -
Якщо ви хочете побачити всі групи споживачів для IoT Hub, виконайте наступну команду:
az iot hub consumer-group list --output table \ --hub-name <hub_name>
Замініть
<hub_name>
на назву, яку ви використовували для свого IoT Hub. Це покаже список усіх груп споживачів.Name ResourceGroup -------- --------------- $Default gps-sensor geofence gps-sensor
💁 Коли ви запускали монітор подій IoT Hub на попередньому уроці, він підключався до групи споживачів
$Default
. Саме тому ви не можете одночасно запускати монітор подій і тригер подій. Якщо ви хочете запускати обидва, ви можете використовувати інші групи споживачів для всіх ваших додатків Functions і залишити$Default
для монітора подій.
Завдання — створення нового тригера IoT Hub
-
Додайте новий тригер подій IoT Hub до вашого додатка
gps-trigger
, створеного на попередньому уроці. Назвіть цю функціюgeofence-trigger
.⚠️ Ви можете звернутися до інструкцій зі створення тригера подій IoT Hub з проєкту 2, уроку 5, якщо це необхідно.
-
Налаштуйте рядок підключення IoT Hub у файлі
function.json
. Файлlocal.settings.json
спільний для всіх тригерів у додатку Functions. -
Оновіть значення
consumerGroup
у файліfunction.json
, щоб посилатися на нову групу споживачівgeofence
:"consumerGroup": "geofence"
-
Вам знадобиться ключ підписки для вашого облікового запису Azure Maps у цьому тригері, тому додайте новий запис до файлу
local.settings.json
із назвоюMAPS_KEY
. -
Запустіть додаток Functions, щоб переконатися, що він підключається та обробляє повідомлення. Тригер
iot-hub-trigger
із попереднього уроку також запуститься та завантажить об’єкти в сховище.Щоб уникнути дублювання зчитувань GPS у сховищі, ви можете зупинити додаток Functions, який працює у хмарі. Для цього використовуйте наступну команду:
az functionapp stop --resource-group gps-sensor \ --name <functions_app_name>
Замініть
<functions_app_name>
на назву, яку ви використовували для свого додатка Functions.Ви можете перезапустити його пізніше за допомогою наступної команди:
az functionapp start --resource-group gps-sensor \ --name <functions_app_name>
Замініть
<functions_app_name>
на назву, яку ви використовували для свого додатка Functions.
Завдання — перевірка геозони з тригера
Раніше в цьому уроці ви використовували curl для запиту геозони, щоб перевірити, чи знаходиться точка всередині або зовні. Ви можете зробити подібний веб-запит із вашого тригера.
-
Щоб запитати геозону, вам потрібен її UDID. Додайте новий запис до файлу
local.settings.json
із назвоюGEOFENCE_UDID
і цим значенням. -
Відкрийте файл
__init__.py
із нового тригераgeofence-trigger
. -
Додайте наступний імпорт на початку файлу:
import json import os import requests
Пакет
requests
дозволяє виконувати виклики веб-API. Azure Maps не має SDK для Python, тому вам потрібно виконувати виклики веб-API, щоб використовувати його з Python-коду. -
Додайте наступні 2 рядки на початку методу
main
, щоб отримати ключ підписки Maps:maps_key = os.environ['MAPS_KEY'] geofence_udid = os.environ['GEOFENCE_UDID']
-
Усередині циклу
for event in events
додайте наступне, щоб отримати широту та довготу з кожної події:event_body = json.loads(event.get_body().decode('utf-8')) lat = event_body['gps']['lat'] lon = event_body['gps']['lon']
Цей код перетворює JSON із тіла події на словник, а потім витягує
lat
іlon
із поляgps
. -
Використовуючи
requests
, замість створення довгого URL, як ви робили з curl, ви можете використовувати лише частину URL і передати параметри як словник. Додайте наступний код для визначення URL для виклику та налаштування параметрів:url = 'https://atlas.microsoft.com/spatial/geofence/json' params = { 'api-version': 1.0, 'deviceId': 'gps-sensor', 'subscription-key': maps_key, 'udid' : geofence_udid, 'lat' : lat, 'lon' : lon }
Елементи в словнику
params
відповідатимуть ключам і значенням, які ви використовували під час виклику веб-API через curl. -
Додайте наступні рядки коду для виклику веб-API:
response = requests.get(url, params=params) response_body = json.loads(response.text)
Це викликає URL із параметрами та отримує об’єкт відповіді.
-
Додайте наступний код нижче цього:
distance = response_body['geometries'][0]['distance'] if distance == 999: logging.info('Point is outside geofence') elif distance > 0: logging.info(f'Point is just outside geofence by a distance of {distance}m') elif distance == -999: logging.info(f'Point is inside geofence') else: logging.info(f'Point is just inside geofence by a distance of {distance}m')
Цей код припускає одну геометрію та витягує відстань із цієї єдиної геометрії. Потім він записує різні повідомлення залежно від відстані.
-
Запустіть цей код. У вихідних даних журналу ви побачите, чи знаходяться координати GPS всередині або зовні геозони, із зазначенням відстані, якщо точка знаходиться в межах 50 м. Спробуйте цей код із різними геозонами на основі розташування вашого GPS-сенсора, спробуйте перемістити сенсор (наприклад, підключений до Wi-Fi через мобільний телефон або з іншими координатами на віртуальному IoT-пристрої), щоб побачити зміни.
-
Коли будете готові, розгорніть цей код у вашому додатку Functions у хмарі. Не забудьте розгорнути нові налаштування додатка.
⚠️ Ви можете звернутися до інструкцій із завантаження налаштувань додатка з проєкту 2, уроку 5, якщо це необхідно.
⚠️ Ви можете звернутися до інструкцій із розгортання вашого додатка Functions із проєкту 2, уроку 5, якщо це необхідно.
💁 Ви можете знайти цей код у папці code/functions.
🚀 Виклик
У цьому уроці ви додали одну геозону, використовуючи GeoJSON-файл із одним полігоном. Ви можете завантажити кілька полігонів одночасно, якщо вони мають різні значення geometryId
у розділі properties
.
Спробуйте завантажити GeoJSON-файл із кількома полігонами та налаштуйте свій код, щоб визначити, до якого полігону найближчі GPS-координати або в якому вони знаходяться.
Післялекційна вікторина
Огляд і самостійне навчання
- Прочитайте більше про геозони та їхні варіанти використання на сторінці про геозони у Вікіпедії.
- Прочитайте більше про API геозон Azure Maps у документації Microsoft Azure Maps Spatial - Get Geofence.
- Прочитайте більше про групи споживачів у документації Microsoft про функції та термінологію Azure Event Hubs - Event consumers.
Завдання
Надсилання сповіщень за допомогою Twilio
Відмова від відповідальності:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.