Перейти к содержанию

Геосервер Martin

Подключение геосервера для работы с картой

Для отображения картографических данных в платформе можно использовать геосервер Martin, который обеспечивает доступ к данным непосредственно из базы данных в формате векторных MVT-тайлов.

Особенности работы

  • Геосервер Martin - это высокопроизводительное решение, извлекающее данные из таблиц БД с помощью функций PostGIS.
  • Слой в платформе настраивается стандартным образом, но в качестве источника данных указывается ссылка на соответствующий слой в Martin.

Подготовка базы данных:

  1. В любой таблице БД необходимо добавить поле с SRID и геометрией.
  2. Для применения изменений требуется обновить источники данных на геосервере. Если он запущен с параметром watch_mode = true, достаточно выполнить запрос к /index.json.

Важно

Для оптимизации производительности запросов, особенно на больших таблицах, необходимо создать gist-индекс для поля с геометрией.

Кэширование данных с помощью Nginx прокси

В целях снижения нагрузки на базу данных и организации кэширования слоёв следует настроить кэширующий прокси. Например, Nginx.

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

nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;

    keepalive_timeout  65;

    gzip              on;
    gzip_vary         on;
    gzip_proxied      any;
    gzip_comp_level   6;
    gzip_buffers      16 8k;
    gzip_http_version 1.1;
    gzip_min_length   256;
    gzip_types        text/plain text/css text/xml text/javascript application/x-javascript
                      application/xml application/javascript application/json application/x-protobuf;

    proxy_cache_path    /var/cache/nginx/
                        levels=1:2
                        max_size=10g
                        inactive=60m
                        use_temp_path=off
                        keys_zone=tiles_cache:10m;

    upstream martin_upstream {
        server martin:3001;
    }

    server {
        listen 3001 ssl;
        listen 3000;
        server_name  localhost:3000;
        ssl_certificate     /etc/ssl/certs/int.bittechno.ru.crt;
        ssl_certificate_key /etc/ssl/private/int.bittechno.ru.key;


        location ~ /static/(?<fwd_path>.*) {
            proxy_set_header    X-Forwarded-Host $host:$server_port;
            proxy_set_header    X-Forwarded-Proto $scheme;
            proxy_set_header    Host $host;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    X-Rewrite-URL $uri;
            proxy_redirect      off;        

            proxy_connect_timeout   15m;
            proxy_send_timeout      15m;
            proxy_read_timeout      15m;
            send_timeout            15m;

            proxy_cache             tiles_cache;
            proxy_cache_lock        on;
            proxy_cache_revalidate  on;

            # Set caching time for responses
            proxy_cache_valid       200 204 302 24h;
            proxy_cache_valid       404 1m;

            proxy_cache_use_stale   error timeout http_500 http_502 http_503 http_504;
            add_header              X-Cache-Status $upstream_cache_status;

            proxy_pass              http://martin_upstream/$fwd_path$is_args$args;
        }

        location ~ /dynamic/(?<fwd_path>.*) {
            proxy_set_header    X-Forwarded-Host $host:$server_port;
            proxy_set_header    X-Forwarded-Proto $scheme;
            proxy_set_header    Host $host;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    X-Rewrite-URL $uri;
            proxy_redirect      off;

            proxy_connect_timeout   15m;
            proxy_send_timeout      15m;
            proxy_read_timeout      15m;
            send_timeout            15m;

            proxy_pass              http://martin_upstream/$fwd_path$is_args$args;

        }

        location ~ /(?<fwd_path>.*) {
            proxy_set_header    X-Forwarded-Host $host:$server_port;
            proxy_set_header    X-Forwarded-Proto $scheme;
            proxy_set_header    Host $host;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    X-Rewrite-URL $uri;
            proxy_redirect      off;

            proxy_connect_timeout   15m;
            proxy_send_timeout      15m;
            proxy_read_timeout      15m;
            send_timeout            15m;

            proxy_pass              http://martin_upstream/$fwd_path$is_args$args;

        }
    }
}

Запуск всего кода в docker-compose:

docker-compose.yml
version: '3'

services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - 3000:3000
      - 3001:3001
    volumes:
      - ./cache:/var/cache/nginx
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./int.bittechno.ru.crt:/etc/ssl/certs/int.bittechno.ru.crt:ro
      - ./int.bittechno.ru.key:/etc/ssl/private/int.bittechno.ru.key:ro
    depends_on:
      - martin

  martin:
    image: urbica/martin
    volumes:
      - ./martin.yml:/etc/martin.yml:ro
    command: martin --config=/etc/martin.yml
    expose:
      - 3001
    restart: unless-stopped

Относительная адресация при запросах к геосерверу

Если в прокси для клиентского приложения настроено проксирование относительных адресов геосервера, это не влияет на работу самого геосервера. Ключевым требованием является корректная передача (проксирование) всех заголовков оригинального запроса.

Ссылки

Геосервер Martin - https://github.com/maplibre/martin
Стиль maplibre - https://maplibre.org/maplibre-gl-js-docs/style-spec/
PostGIS - https://postgis.net/