Пример работы с системой через ORBISMap REST API.

В примере будут использоваться:

Функции

Код, приведенный ниже, для удобства собран в этом модуле.

Импортируем необходимые библиотеки и определяем константы, которые будут использоваться в функциях, осуществляющих запросы к серверу:

import requests 
import json

# в проекте есть пользователь с логином test_user и достаточными правами на выполнение всех запросов, рассмотренных в примере
USER = 'test_user'
PASS = 'pass'

HOST = 'http://oms.local'  # хост, на котором развернут проект ORBISMap SERVER
API_VER = '/api/2.2'  # версия используемого ORBISMap REST API
PROJECT = '/test_project'  # проект

OMS_API_PATH = HOST + API_VER + PROJECT


Получить токен авторизации

Определим функцию для получения токена авторизации, который будем использовать в запросах, требующих его. Все запросы на изменение/добавление REST-ресурса требуют токена авторизации.


def login(user=USER, pswd=PASS):
    """ Получить токен авторизации """

    # формируется итоговый url
    url = OMS_API_PATH + '/login/'

    # post параметры запроса
    params = {'user': user, 'pass': pswd}

    # выполнение запроса к серверу
    r = requests.post(url, data=params)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить токен авторизации.')

    # декодируем ответ из json в объект python
    token = json.loads(r.text)

    # извлекаем токен авторизации и возвращаем в виде строки
    return token.get('token')

Завершить авторизованную сессию


def logout(token):
    """ Завершить авторизованную сессию """
    url = OMS_API_PATH + '/logout/?token=%s' % token

    # выполнение запроса к серверу
    r = requests.post(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось разлогиниться.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Создать карту


def create_map(token, data):
    """ Создать карту """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    # формируем итоговый url
    url = '''%(base_url)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'token': token
    })

    # кодируем словарь в формат json
    payload = json.dumps(data)

    # выполняем POST-запрос к серверу
    r = requests.post(url, data=payload, headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось создать карту.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить объект карты


def get_map(map_code):
    """ Получить объект карты """

    url = '''%(base_url)s/%(map_code)s/?''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
    })

    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить карту.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить дерево слоев


def get_layers_tree(map_code, params=None):
    """ Получить дерево слоев. """

    # формируем итоговый url
    url = '''%(base_url)s/%(map_code)s/layers/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code
    })

    # добавляем параметры, если есть
    if params:
        url += '?%s' % params.lstrip('&').lstrip('?')

    # выполняем GET-запрос к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить дерево слоев.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Сохранить дерево публикации


def update_layers_tree(token, map_code, data):
    """ Сохранить дерево публикации слоев """
    headers = {'Content-type': 'application/json'}

    url = '''%(base_url)s/%(map_code)s/publish/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'token': token
    })

    # выполняем POST-запрос к серверу
    r = requests.post(url, data=json.dumps(data), headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось сохранить дерево публикации слоев.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить начальные настройки публичной карты


def get_publish_settings(map_code):
    """ Получить начальные настройки публичной карты. """

    url = '''%(base_url)s/''' % ({
        'base_url': OMS_API_PATH,
    })

    data = {
        'map_code': map_code
    }

    r = requests.get(url, data=data)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить начальные настройки публичной карты.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Создать слой


def create_layer(token, map_code, data):
    """ Создать слой """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    # формируем итоговый url
    url = '''%(base_url)s/%(map_code)s/layers/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'token': token
    })

    # кодируем словарь в формат json
    payload = json.dumps(data)

    # выполняем POST-запрос к серверу
    r = requests.post(url, data=payload, headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось создать слой.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить слой


def get_layer(map_code, layer_code):
    """ Получить слой """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
    })

    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить слой.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Изменить слой


def update_layer(token, map_code, layer_code, data):
    """ Изменить слой """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    # формируем итоговый url
    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'token': token
    })

    # выполняем PUT/PATCH-запрос к серверу
    r = requests.put(url, data=json.dumps(data), headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось изменить слой.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить легенду слоя


def get_layer_legend(map_code, layer_code):
    """ Получить легенду слоя """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/legend/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code
    })

    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить легенду слоя.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить структуру слоя


def get_layer_structure(map_code, layer_code):
    """ Получить структуру слоя """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/structure/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code
    })

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить структуру слоя.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Изменить колонку


def update_layer_field(token, map_code, layer_code, field_code, data):
    """ Изменить колонку """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/structure/%(field_code)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'field_code': field_code,
        'token': token
    })

    # выполнение запроса к серверу
    r = requests.put(url, data=json.dumps(data), headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось изменить колонку.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Загрузка данных в слой


def import_file(token, map_code, layer_code, file_path, file_name, data=None):
    """ Импортирует данные в слой. """
    from mimetypes import MimeTypes

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/import/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'token': token
    })

    # определяем mime-тип импортируемого файла
    mime_type = MimeTypes().guess_type(file_path)

    # формируем параметр files POST-запроса
    files = {
        'file_name': (file_name, open(file_path, 'rb'), mime_type[0], {'Expires': '0'})
    }

    if data is None:
        data = dict()

    # выполнение запроса к серверу
    r = requests.post(url, data=data, files=files)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось импортировать файл.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Выгрузка данных слоя


def export(map_code, layer_code, frmt, params=None):
    """ Экспортирует данные из слоя. """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/export/?format=%(format)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'format': frmt
    })

    if params is None:
        url += '&%s' % frmt.lstrip('&')

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось экспортировать файл.')

    # пишем ответ в файл
    open('tmp.%s' % frmt, 'wb').write(r.content)

Получить количество объектов


def get_objects_count(map_code, layer_code, params=None):
    """ Получить количество объектов"""

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/count/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code
    })

    if params:
        url += '?%s' % params.lstrip('?').lstrip('&')

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить количество объектов.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить список объектов


def get_objects(map_code, layer_code, params=None):
    """ Получить список объектов. """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code
    })

    if params:
        url += '?%s' % params.lstrip('?').lstrip('&')

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить список объектов.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()


Получить объект


def get_object(map_code, layer_code, obj_id, params=None):
    """ Получить объект. """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'obj_id': obj_id
    })

    if params:
        url += '?%s' % params.lstrip('?').lstrip('&')

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить список объектов.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Создать объект


def create_object(token, map_code, layer_code, data):
    """ Создать объект. """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'token': token
    })

    # выполнение запроса к серверу
    r = requests.post(url, data=json.dumps(data), headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось создать объект.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Изменить объект


def update_object(token, map_code, layer_code, obj_id, payload, lng=None):
    """ Изменить объект. """

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'obj_id': obj_id,
        'token': token
    })

    if lng:
        url += '&lng=%s' % lng

    # выполнение запроса к серверу
    r = requests.patch(url, data=json.dumps(payload), headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось изменить объект.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Удалить объект


def delete_object(token, map_code, layer_code, obj_id):
    """ Удалить объект. """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'obj_id': obj_id,
        'token': token
    })

    # выполнение запроса к серверу
    r = requests.delete(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось удалить объект.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить геопространственные данные объекта


def get_object_geom(token, map_code, layer_code, obj_id):
    """ Получить геопространственные данные объекта"""

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/geom/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'token': token,
        'obj_id': obj_id
    })

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить геометрию объекта.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Изменить геопространственные данные объекта


def update_object_geom(token, map_code, layer_code, obj_id, geojson, crs=None):
    """ Изменить геопространственные данные объекта"""

    # инициализируем переменную с правильными заголовками
    headers = {'Content-type': 'application/json'}

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/geom/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'token': token,
        'obj_id': obj_id,
        'geomSR': crs
    })

    if crs:
        url += '&geomSR=%s' % crs

    # выполнение запроса к серверу
    r = requests.put(url, data=geojson, headers=headers)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось обновить геометрию объекта.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Добавить файл к объекту


def add_file(token, map_code, layer_code, obj_id, field, file_path, file_name, lng=None):
    """ Добавляет файл к объекту слоя. """
    from mimetypes import MimeTypes

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/files/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'obj_id': obj_id,
        'token': token
    })

    if lng:
        url += '&lng=%s' % lng

    # определяем mime-тип добавляемого файла
    mime_type = MimeTypes().guess_type(file_path)

    # формируем параметр files POST-запроса
    files = {
        'file_name': (file_name, open(file_path, 'rb'), mime_type[0], {'Expires': '0'})
    }

    data = {
        'field': field
    }

    # выполнение запроса к серверу
    r = requests.post(url, data=data, files=files)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось добавить файл к объекту.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Удалить файл объекта


def delete_file(token, map_code, layer_code, obj_id, field, file_id, lng=None):
    """ Удаляет файл объекта слоя. """

    url = '''%(base_url)s/%(map_code)s/layers/%(layer_code)s/objects/%(obj_id)s/files/%(file_id)s/?token=%(token)s''' % ({
        'base_url': OMS_API_PATH,
        'map_code': map_code,
        'layer_code': layer_code,
        'obj_id': obj_id,
        'file_id': file_id,
        'token': token
    })

    if lng:
        url += '&lng=%s' % lng

    data = {
        'field': field
    }

    # выполнение запроса к серверу
    r = requests.delete(url, data=data)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось удалить файл объекта.')

    # декодируем и возвращаем в виде python объекта ответ сервера
    return r.json()

Получить изображение


def get_image(file_uuid, filename, params=None):
    """ Получить изображение. """

    url = '''%(base_url)s/image/%(file_id)s/''' % ({
        'base_url': OMS_API_PATH,
        'file_id': file_uuid
    })

    if params:
        url += "?%s" % params.lstrip('&').lstrip('?')

    # выполнение запроса к серверу
    r = requests.get(url)

    # если вернулся ответ со статусом отличным от 200, то печатаем тело ответа сервера и вызываем исключение
    if r.status_code != 200:
        print('Ответ сервера: ', r.text)
        raise Exception('Не удалось получить изображение.')

    # сохраняем изображение
    with open(filename, 'wb') as f:
        f.write(r.content)


Сценарий примера

  1. Создаем карту c кодом test_api и именем Тест API.
  2. Добавляем в карту слой с кодом layer1 и именем Слой 1.
  3. Добавляем в карту слой с кодом layer2 и именем Слой 2.
  4. Добавляем в карту слой с кодом layer3 и именем Слой 3.
  5. Получаем полное дерево публикации.
  6. Меняем порядок слоев в карте.
  7. Получаем полное дерево публикации карты.
  8. Получаем дерево публикаций (только отмеченные слои) карты.
  9. Отмечаем слой с кодом layer2.
  10. Получаем дерево публикаций (только отмеченные слои) карты.
  11. Получаем структуру слоя с кодом layer2.
  12. Импортируем данные в слой с кодом layer2.
  13. Получаем структуру слоя с кодом layer2.
  14. Получаем список объектов слоя с кодом layer2.
  15. Добавляем объект без геопространственных данных в слой с кодом layer2.
  16. Добавляем объект с геопространственными данными в слой с кодом layer2 .
  17. Получаем последние 5 объектов слоя с кодом layer2.
  18. Удаляем последний объект из слоя с кодом layer2.
  19. Получаем последние 5 объектов слоя с кодом layer2.

Импортируем стандартный модуль os и функции для выполнения запросов.

import os
from api_example_functions import *

Получаем токен авторизации с помощью функции login

TOKEN = login()

Формируем словарь для создания карты с кодом test_api и именем Тест API

new_map_data = {
    "code": "test_api",  # код создаваемой карты
    "name": "Тест API"  # имя создаваемой карты
}

1. Создаем карту,

передав словарь на вход функции create_map:

create_map_resp = create_map(TOKEN, new_map_data)

В результате получаем словарь, сформированный из ответа сервера

create_map_resp
{
    'code': 'test_api',
    'css_style': 'srs:"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"\n',
    'group_layers': 1,
    'has_publication': True,
    'id': 990,
    'name': 'Тест API'
}

Формат переменной create_map_resp описан тут

Формируем словарь для создания слоя с кодом layer1 и именем Слой 1

new_layer_data = {
    'code': 'layer1',  # код создаваемого слоя
    'name': 'Слой 1',  # имя создаваемого слоя
}

2. Создаем слой,

передав словарь на вход функции create_layer:

create_layer_resp = create_layer(TOKEN, 'test_api', new_layer_data)
create_layer_resp
{
    'bbox': {},
    'code': 'layer1',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #191919;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #333333;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #f2f2f2;\n\tline-color: #b2b2b2;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #f2f2f2;\n\tline-color: #b2b2b2;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 991,
    'map_layer_id': 991,
    'name': 'Слой 1',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 1.0,
    'type': 'layer'
}

Формат переменной create_layer_resp (и всех последующих ответов на создание слоя) описан тут

Формируем словарь для создания слоя с кодом layer2 и именем Слой 2

new_layer2_data = {
    'code': 'layer2',  # код создаваемого слоя
    'name': 'Слой 2',  # имя создаваемого слоя
}

3. Создаем слой,

передав словарь на вход функции create_layer:

create_layer2_resp = create_layer(TOKEN, 'test_api', new_layer2_data)
create_layer2_resp
{
    'bbox': {},
    'code': 'layer2',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #baba19;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #c1c133;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #fbfbf2;\n\tline-color: #e8e8b2;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #fbfbf2;\n\tline-color: #e8e8b2;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 992,
    'map_layer_id': 992,
    'name': 'Слой 2',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 2.0,
    'type': 'layer'
}

Формируем словарь для создания слоя с кодом layer3 и именем Слой 3

new_layer3_data = {
    'code': 'layer3',  # код создаваемого слоя
    'name': 'Слой 3',  # имя создаваемого слоя
}

4. Создаем слой,

передав словарь на вход функции create_layer:

create_layer3_resp = create_layer(TOKEN, 'test_api', new_layer3_data)
create_layer3_resp
{
    'bbox': {},
    'code': 'layer3',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #19ba84;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #33c192;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #f2fbf8;\n\tline-color: #b2e8d6;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #f2fbf8;\n\tline-color: #b2e8d6;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 993,
    'map_layer_id': 993,
    'name': 'Слой 3',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 3.0,
    'type': 'layer'
}

На данном этапе у нас должна быть карта с 3мя слоями, давайте в этом убедимся.

5. Сделаем запрос на получение полного дерева публикации

(параметр type=full) с помощью функции get_layers_tree

full_pub_tree = get_layers_tree(create_map_resp['code'], params='type=full')
full_pub_tree
[   
    {
        'code': 'layer1',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 991,
        'map_layer_id': 991,
        'name': 'Слой 1',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 1.0,
        'type': 'layer'
    },
    {
        'code': 'layer2',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 992,
        'map_layer_id': 992,
        'name': 'Слой 2',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 2.0,
        'type': 'layer'
    },
    {
        'code': 'layer3',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 993,
        'map_layer_id': 993,
        'name': 'Слой 3',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 3.0,
        'type': 'layer'
    }
]

Формат переменной full_pub_tree (и всех последующих ответов на получение дерева публикации) описан тут

6. Поменяем местами слои

с кодами layer1 и layer3 воспользовавшись функцией update_layer:

_resp = update_layer(TOKEN, 'test_api', 'layer1', {'parent_id': create_map_resp['id'], 'sort': 3.5})
_resp
{
    'bbox': {},
    'code': 'layer1',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #191919;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #333333;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #f2f2f2;\n\tline-color: #b2b2b2;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #f2f2f2;\n\tline-color: #b2b2b2;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 991,
    'map_layer_id': 991,
    'name': 'Слой 1',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 3.0,
    'type': 'layer'
}

Формат переменной _resp (и всех последующих ответов на создание/получение/изменение слоя) описан тут

_resp = update_layer(TOKEN, 'test_api', 'layer3', {'parent_id': create_map_resp['id'], 'sort': 0.5})
_resp
{
    'bbox': {},
    'code': 'layer3',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #19ba84;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #33c192;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #f2fbf8;\n\tline-color: #b2e8d6;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #f2fbf8;\n\tline-color: #b2e8d6;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 993,
    'map_layer_id': 993,
    'name': 'Слой 3',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 1.0,
    'type': 'layer'
}

7. Еще раз получим дерево публикаций,

чтобы убедиться, что порядок поменялся. Для этого снова используем функцию get_layers_tree:

full_pub_tree = get_layers_tree(create_map_resp['code'], params='type=full')
full_pub_tree
[
    {
        'code': 'layer3',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 993,
        'map_layer_id': 993,
        'name': 'Слой 3',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 1.0,
        'type': 'layer'
    },
    {
        'code': 'layer2',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 992,
        'map_layer_id': 992,
        'name': 'Слой 2',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 2.0,
        'type': 'layer'
    },
    {
        'code': 'layer1',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 991,
        'map_layer_id': 991,
        'name': 'Слой 1',
        'parent_id': 0,
        'render_type': 0,
        'selected': False,
        'sort': 3.0,
        'type': 'layer'
    }
]

8. Выполним запрос на получение дерева публикации

c параметрами по умолчанию, для того, чтобы убедиться, что на текущий момент все 3 слоя не отображаются на публичной карте:

_resp = get_layers_tree(create_map_resp['code'])
_resp
[]

9. Изменим дерево публикаций,

используя функцию update_layers_tree.

_resp = update_layers_tree(TOKEN, 'test_api', [{'parent_id': 0, 'id': create_layer2_resp['id'], 'map_layer_id': create_layer2_resp['map_layer_id'], 'selected': True}])
_resp
[
    {
        'code': 'layer2',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 992,
        'map_layer_id': 992,
        'name': 'Слой 2',
        'parent_id': 0,
        'render_type': 0,
        'selected': True,
        'sort': 10000.0,
        'type': 'layer'
    }
]

10. Выполним запрос на получение дерева публикации

чтобы убедиться, что теперь слой с кодом layer2 отображается в "дереве публикации":

_resp = get_layers_tree(create_map_resp['code'])
_resp
[
    {
        'code': 'layer2',
        'g_type': 'Unknown',
        'icon': '',
        'icon_retina': '',
        'id': 992,
        'map_layer_id': 992,
        'name': 'Слой 2',
        'parent_id': 0,
        'render_type': 0,
        'selected': True,
        'sort': 10000.0,
        'type': 'layer'
    }
]

11. Получим структуру слоя

с кодом layer2 используя функцию get_layer_structure:

layer2_struct = get_layer_structure('test_api', 'layer2')
layer2_struct
[
    {
        'code': 'orbis_id',
        'id': 5265,
        'localized_name': False,
        'localized_value': False,
        'name': '',
        'parent_id': 0,
        'required': False,
        'sort': 0.1,
        'type': 'number'
    },
    {
        'code': 'geom',
        'id': 5266,
        'localized_name': False,
        'localized_value': False,
        'name': '',
        'parent_id': 0,
        'required': False,
        'sort': 0.2,
        'type': 'geom'
    }
]

Формат переменной layer2_struct (и всех последующих ответов на получение структуры слоя) описан тут

12. Импортируем данные в слой

используя функцию import_file:

_resp = import_file(TOKEN, 'test_api', 'layer2', 'mir.zip', 'mir.zip', {'action': '1'})
_resp
{
    'bbox': {},
    'code': 'layer2',
    'css_style': "// Default style for points\n['mapnik::geometry_type'=1] {\n\tmarker-fill: #ffffff;\n\tmarker-line-color: #baba19;\n\tmarker-line-width: 2;\n\tmarker-allow-overlap: true;\n}\n// Default style for linestrings\n['mapnik::geometry_type'=2] {\n\tline-color: #c1c133;\n\tline-width: 2;\n}\n// Default style for polygons\n['mapnik::geometry_type'=3] {\n\tpolygon-fill: #fbfbf2;\n\tline-color: #e8e8b2;\n\tline-width: 1;\n}\n// Default style for collections\n['mapnik::geometry_type'=4] {\n\tpolygon-fill: #fbfbf2;\n\tline-color: #e8e8b2;\n\tline-width: 1;\n}\n",
    'g_type': 'Unknown',
    'icon': 'static/geoicons/unknown.png',
    'icon_retina': '',
    'id': 992,
    'map_layer_id': 992,
    'name': 'Слой 2',
    'parent_id': 990,
    'render_type': 0,
    'selected': False,
    'sort': 2.0,
    'type': 'layer'
}

13. Посмотрим, как изменилась структура слоя

с кодом layer2:

layer2_struct = get_layer_structure('test_api', 'layer2')
layer2_struct
[
    {
        'code': 'orbis_id',
        'id': 5265,
        'localized_name': False,
        'localized_value': False,
        'name': '',
        'parent_id': 0,
        'required': False,
        'sort': 0.1,
        'type': 'number'
    },
    {
        'code': 'geom',
        'id': 5266,
        'localized_name': False,
        'localized_value': False,
        'name': '',
        'parent_id': 0,
        'required': False,
        'sort': 0.2,
        'type': 'geom'
    },
    {
        'code': 'label',
        'id': 5269,
        'localized_name': False,
        'localized_value': False,
        'name': 'label',
        'parent_id': 0,
        'required': False,
        'sort': 3.0,
        'type': 'string'
    },
    {
        'code': 'label_en',
        'id': 5270,
        'localized_name': False,
        'localized_value': False,
        'name': 'label_en',
        'parent_id': 0,
        'required': False,
        'sort': 4.0,
        'type': 'string'
    }
]

14. Получим список объектов слоя,

используя функцию get_objects с параметрами по умолчанию:

print(get_objects('test_api', 'layer2'))

[{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 5}, {'id': 6}, {'id': 7}, {'id': 8}, {'id': 9}, {'id': 10}, {'id': 11}, {'id': 12}, {'id': 13}, {'id': 14}, {'id': 15}, {'id': 16}, {'id': 17}, {'id': 18}, {'id': 19}, {'id': 20}, {'id': 21}, {'id': 22}, {'id': 23}, {'id': 24}, {'id': 25}, {'id': 26}, {'id': 27}, {'id': 28}, {'id': 29}, {'id': 30}, {'id': 31}, {'id': 32}, {'id': 33}, {'id': 34}, {'id': 35}, {'id': 36}, {'id': 37}, {'id': 38}, {'id': 39}, {'id': 40}, {'id': 41}, {'id': 42}, {'id': 43}, {'id': 44}, {'id': 45}, {'id': 46}, {'id': 47}, {'id': 48}, {'id': 49}, {'id': 50}, {'id': 51}, {'id': 52}, {'id': 53}, {'id': 54}, {'id': 55}, {'id': 56}, {'id': 57}, {'id': 58}, {'id': 59}, {'id': 60}, {'id': 61}, {'id': 62}, {'id': 63}, {'id': 64}, {'id': 65}, {'id': 66}, {'id': 67}, {'id': 68}, {'id': 69}, {'id': 70}, {'id': 71}, {'id': 72}, {'id': 73}, {'id': 74}, {'id': 75}, {'id': 76}, {'id': 77}, {'id': 78}, {'id': 79}, {'id': 80}, {'id': 81}, {'id': 82}, {'id': 83}, {'id': 84}, {'id': 85}, {'id': 86}, {'id': 87}, {'id': 88}, {'id': 89}, {'id': 90}, {'id': 91}, {'id': 92}, {'id': 93}, {'id': 94}, {'id': 95}, {'id': 96}, {'id': 97}, {'id': 98}, {'id': 99}, {'id': 100}, {'id': 101}, {'id': 102}, {'id': 103}, {'id': 104}, {'id': 105}, {'id': 106}, {'id': 107}, {'id': 108}, {'id': 109}, {'id': 110}, {'id': 111}, {'id': 112}, {'id': 113}, {'id': 114}, {'id': 115}, {'id': 116}, {'id': 117}, {'id': 118}, {'id': 119}, {'id': 120}, {'id': 121}, {'id': 122}, {'id': 123}, {'id': 124}, {'id': 125}, {'id': 126}, {'id': 127}, {'id': 128}, {'id': 129}, {'id': 130}, {'id': 131}, {'id': 132}, {'id': 133}, {'id': 134}, {'id': 135}, {'id': 136}, {'id': 137}, {'id': 138}, {'id': 139}, {'id': 140}, {'id': 141}, {'id': 142}, {'id': 143}, {'id': 144}, {'id': 145}, {'id': 146}, {'id': 147}]

15. Добавим в слой объект

не содержащий геопространственных данных используя функцию create_object:

obj1 = create_object(TOKEN, 'test_api', 'layer2', {'fields': {'label': 'Калуга', 'label_en': 'Kaluga'}})
obj1
{'fields': {'label': 'Калуга', 'label_en': 'Kaluga'}, 'id': 148}

16. Добавим в слой объект

содержащий геопространственные данные используя функцию create_object:

obj2 = create_object(TOKEN, 'test_api', 'layer2', {'fields': {'label': 'Тула', 'label_en': 'Tula'}, 'geom': {"type": "Point", "coordinates": [1, 1]}})
obj2
{'fields': {'label': 'Тула', 'label_en': 'Tula'}, 'id': 149}

17. Получим последние 5 объектов

слоя с кодом layer2. В ответ включим все поля объектов и геопространственные данные:

last_five = get_objects('test_api', 'layer2', params='fields=*&sort=orbis_id,d&limit=5&returnGeom=1')
last_five
[
    {
        'fields': {'label': 'Тула', 'label_en': 'Tula'},
        'geom': {'coordinates': [0.999999999999989, 0.999999999999989], 'type': 'Point'},
        'id': 149
    },
    {
        'fields': {'label': 'Калуга', 'label_en': 'Kaluga'},
        'id': 148
    },
    {
        'fields': {'label': 'Бишкек', 'label_en': None}, 
        'geom': {'coordinates': [74.5695, 42.78214], 'type': 'Point'},
        'id': 147
    },
    {
        'fields': {'label': 'Яунде', 'label_en': None},
        'geom': {'coordinates': [11.51361, 3.86499999999999], 'type': 'Point'},
        'id': 146
    },
    {
        'fields': {'label': 'Виндхук', 'label_en': None},
        'geom': {'coordinates': [17.07694, -22.55944], 'type': 'Point'},
        'id': 145
    }
]

18. Удалим последний объект

из слоя с кодом layer2 используя функцию delete_object:

last_object_id = last_five[0]['id']
print(last_object_id)
149
_resp = delete_object(TOKEN, 'test_api', 'layer2', last_object_id)
_resp
True

19. Получим последние 5 объектов

слоя с кодом layer2.

last_five = get_objects('test_api', 'layer2', params='fields=*&sort=orbis_id,d&limit=5&returnGeom=1')
last_five
[
    {
        'fields': {'label': 'Калуга', 'label_en': 'Kaluga'},
        'id': 148
    },
    {
        'fields': {'label': 'Бишкек', 'label_en': None},
        'geom': {'coordinates': [74.5695, 42.78214], 'type': 'Point'},
        'id': 147
    },
    {
        'fields': {'label': 'Яунде', 'label_en': None},
        'geom': {'coordinates': [11.51361, 3.86499999999999], 'type': 'Point'},
        'id': 146
    },
    {
        'fields': {'label': 'Виндхук', 'label_en': None},
        'geom': {'coordinates': [17.07694, -22.55944], 'type': 'Point'},
        'id': 145
    },
    {
        'fields': {'label': 'Западный остров', 'label_en': None},
        'geom': {'coordinates': [96.88406, -12.49724], 'type': 'Point'},
        'id': 144
    }
]