6. Приложения

6.1. Приложение 1. Примеры скриптов плагинов

Отправка файлов в объект слоя

if after.getServiceObjectLayerId() is not None and after.getServiceObjectId() is not None:
    attach_list = []
    if len(after.getPhotos()) > 0:
        body_photo = list(map(lambda attach_name: {
            'path': f"/department_files/photos/{attach_name.getName().replace('_', '/')}",
            'fileName': attach_name.getName().replace('/', '_'),
            'isUrl': True
        }
        , after.getPhotos()))
        for photo in after.getPhotos():
            photo_location = photo.getOriginLocation() if photo.getOriginLocation() is not None else photo.getAttachmentLocation()
            if photo_location is not None and model.getLocation() is None:
                geom = {'coordinates': [(photo_location[0], photo_location[1])], 'type': 'MultiPoint'}

        if model.getLocation() is not None:
            geom = {'coordinates': [(model.getLocation()[0], model.getLocation()[1])], 'type': 'MultiPoint'}

    if len(after.getVideos()) > 0:
        for item in after.getVideos():
            attach_list.append(item.getName())
        attach_path = 'video'

    if len(after.getSounds()) > 0:
        for item in after.getSounds():
            attach_list.append(item.getName())
        attach_path = 'sounds'

    if len(after.getFiles()) > 0:
        for item in after.getFiles():
            attach_list.append(item.getName())
        attach_path = 'dif_files'

    body_files = list(map(lambda attach_name: {
        'path': f"/department_files/{attach_path}/{attach_name.replace('_', '/')}",
        'fileName': attach_name,
        'isUrl': True
    }
    , attach_list))

    req = patch(f"/layers/{after.getServiceObjectLayerId()}/features/{after.getServiceObjectId()}/files")
    req.props({'photos': body_photo, 'files': body_files})

    return [
        req,
        patch(f"/layers/{after.getServiceObjectLayerId()}/features/{after.getServiceObjectId()}").prop('geometry', geom)
        ]

Проверка количества фото

if after.get('photo_count') is not None and after.get('photo_count') != before.get('photo_count') and subject.getId() != after.getUser().getId():
    return invalid("\nИзменять доп.поле 'Количество ракурсов' может только создатель задания.\n"
                "\nВерните, пожалуйста, прежнее значение.")

if len(after.getPhotos()) is not None and after.get('photo_count') is not None and after.getStatus().getId() != before.getStatus().getId():
    if len(after.getPhotos()) < int(after.get('photo_count')) and after.getStatus().getId() == 4:
        send_photo_count = int(after.get('photo_count')) - len(after.getPhotos())
        return invalid(f"Недостаточно фото для изменения этапа. Вам необходимо добавить еще {send_photo_count}")

6.2. Приложение 2. Примеры расширенных стилей слоев

Пример стиля точечного слоя с разделением на этапы с использованием стандартных значков (кругов)

  /* @title Новые */
  [ assigned_status = 1 ] {
  mark: symbol('circle');
}
  [ assigned_status = 1 ]
  :mark{
    fill:#ff0000;
    stroke:#000000;
    stroke-width:1;
    size:16;
}

  /* @title В работе */
  [ assigned_status = 2 ] {
  mark: symbol('circle');
}
  [ assigned_status = 2 ]
  :mark{
    fill:#00ff00;
    stroke:#000000;
    stroke-width:1;
    size:16;
}

  /* @title Выполненные*/
  [ assigned_status = 3 ] {
  mark: symbol('circle');
}
  [ assigned_status = 3 ]
  :mark{
    fill:#0000ff;
    stroke:#000000;
    stroke-width:1;
    size:16;
}

  Где:

  /* @title Новые */ – название категории, которое будет отображаться в легенде.
  [ assigned_status = 1 ] – поле, по которому идет фильтрация, и значение поля.
  mark: symbol('circle') – форма значка (круг).
  fill:#00ff00 – цвет заливки значка (указывается в шестнацатеричном виде).
  stroke:#000000 – цвет обводки значка (указывается в шестнацатеричном виде).
  stroke-width:1 – ширина обводки значка в пикселях.
  size:16 – размер значка в пикселях.

Пример стиля точечного слоя с разделением на этапы с использованием иконок

/* @title Новые */
[ assigned_status = 1 ] {
   mark-opacity: 1.0;
   mark-rotation: 0.0;
   mark-size: 36.0;
   mark: url(https://public.activemap.ru/dictionary/icons/58/view);
}
/* @title В работе */
[ assigned_status = 2 ] {
   mark-opacity: 1.0;
   mark-rotation: 0.0;
   mark-size: 36.0;
   mark: url(https://public.activemap.ru/dictionary/icons/59/view);
}
/* @title Выполненные*/
[ assigned_status = 3 ] {
   mark-opacity: 1.0;
   mark-rotation: 0.0;
   mark-size: 36.0;
   mark: url(https://public.activemap.ru/dictionary/icons/60/view);
}

Где:

/* @title Новые */ – название категории, которое будет отображаться в легенде.
[ assigned_status = 1 ] – поле, по которому идет фильтрация, и значение поля.
mark-opacity: 1.0 – прозрачность иконки.
mark-rotation: 0.0 – угол вращения иконки.
mark-size: 36.0 – размер иконки в пикселях.
url(https://belgorod.geofsm.ru/dictionary/icons/218/view) – ссылка на иконку. Ее можно получить, нажав правой кнопкой мыши по иконке и выбрав "Копировать URL картинки".

6.3. Приложение 3. Примеры настроек и параметров подложки

Яндекс

new M.Yandex(type,options)
//type – Тип map, satellite, hybrid, publicMap, publicMapHybrid
//options – {traffic: true|false}

Google

new M.Google(type)
//type – Тип SATELLITE, ROADMAP, HYBRID, TERRAIN

Bing

new M.BingLayer(key,options)
/*
key – ключ апи получать на bing.com
options – {
type: 'Aerial' | 'Road'
}
*/

Космоснимки

new M.Kosmosnimki()

OpenStreetMaps

new M.TileLayer.OpenStreetMap()
new M.TileLayer.OpenStreetMap.Mapnik()
new M.TileLayer.OpenStreetMap.BlackAndWhite()
new M.TileLayer.OpenStreetMap.DE()

Динамически создаваемые

M.TileLayer

new M.TileLayer(url,options)
/*
url – http://{s}.domain/path/{x}/{y}/{z}.png
options: {
        minZoom: 0,  – Минимальный зум
        maxZoom: 18, – Максимальный зум
        tileSize: 256, – Размер тайла
        subdomains: 'abc', – Поддомены
        errorTileUrl: '', – Url тайла с ошибкой
        attribution: '', – Описание правообладателей
        opacity: 1, – Прозрачность
        scheme: 'xyz', – Тип xyz  или tms
        zoomOffset: 0, – Сдвиг зума
        crs: M.CRS.EPSG900913, – проекция
    }
*/

Пример:

new M.TileLayer('http://geoportal.ntsomz.ru/get_tile_external.php?x={x}&y={y}&scale={z}')

M.TileLayer.WMS

new M.TileLayer.WMS(url,options)
/*
url – http://domain/path
options: {
        minZoom: 0,  – Минимальный зум
        maxZoom: 18, – Максимальный зум
        tileSize: 256, – Размер тайла
        errorTileUrl: '', – Url тайла с ошибкой
        attribution: '', – Описание правообладателей
        opacity: 1, – Прозрачность
        zoomOffset: 0, – Сдвиг зума
        crs: M.CRS.EPSG900913, – проекция
        version: '1.1.1', – Версия WMS
        layers: '', – Список слоев
        styles: '', – Список стилей
        format: 'image/jpeg', – Формат картинок
        transparent: false – Прозрачный
    }
*/

Групповая

new M.LayerGroup([new M.TileLayer('http://basemap.geo4.me/worldmap/{z}/{x}/{y}.png'),
    new M.TileLayer.WMS('http://lbt.geo4.me/service/wms', {layers: 'mt_routes:public_routes', styles: 'public_routesstyle', crs: M.CRS.EPSG900913, transparent: true, format: 'image/png'})],
 {
     crs: M.CRS.EPSG900913
 }
)

Вот так работает:

{"Карта России":  "new M.LayerGroup([new M.TileLayer(\"https://basemap.geo4.me/worldmap/{z}/{x}/{y}.png\",{attribution:\"«Участники OpenStreetMap», <a href='http://www.
openstreetmap.org/copyright/'>CC-BY-SA</a>\", minZoom: 2, maxZoom: 26}), new M.TileLayer.WMS(\"http://len-vokzal.geo4.me/geoserver/wms\", {layers: \"scheme_group\", styles:
 \"\", crs: M.CRS.EPSG900913, format: \"image/png\", transparent: true})],{crs: M.CRS.EPSG900913})"}