Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru
Руководство по PostGIS. Глава 4. Использование PostGIS. 4.7. Использование Mapserver
Назад Вперед

4.7. Использование Mapserver-а

"Minnesota Mapserver" - интернет сервер веб-карт, который поддерживает OpenGIS-овую Спецификацию сервера веб-карт.

4.7.1. Основы использования

Для использования PostGIS с Mapserver-ом, вы должны знать, как конфигурировать Mapserver, а это выходит за рамки данной документации. В этом разделе описывается специфика использования PostGIS и детали конфигурирования.

Для использования PostGIS-а с Mapserver-ом вам понадобятся:

  • PostGIS версии 0.6 или выше.

  • Mapserver версии 3.5 или выше.

Mapserver получает доступ к данным PostGIS/PostgreSQL, как и любой другой клиент PostgreSQL, с помощью libpq. Это означает, что Mapserver может быть установлен на любую машину с сетевым доступом к серверу PostGIS, если только в сисетме есть клиентские библиотеки PostgreSQL libpq.

  1. Скомпилируйте и установите Mapserver с любыми нужными вам опциями включив опцию конфигурации "--with-postgis".

  2. В map-файл вашего Mapserver-а добавьте слой PostGIS. Например:

    LAYER
      CONNECTIONTYPE postgis
      NAME "widehighways"
      # Коннект к удаленной пространственной базе данных
      CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
      # Получение линий из столбца 'geom' таблицы 'roads'
      DATA "geom from roads"
      STATUS ON
      TYPE LINE
      # Из имеющихся линий выбрать только широкие дороги
      FILTER "type = 'highway' and numlanes >= 4"
      CLASS
        # Супермагистрали сделать более яркими и установить их ширину в 2 пикселя
        EXPRESSION ([numlanes] >= 6)
        COLOR 255 22 22
        SYMBOL "solid"
        SIZE 2
      END
      CLASS
        # Все остальные - более темные и широной в 1 пиксель
        EXPRESSION ([numlanes] < 6)
        COLOR 205 92 82
      END
    END

    Приведенный пример содержит следующие PostGIS-специфические директивы:

    CONNECTIONTYPE

    Для слоев PostGIS всегда должен быть установлен в "postgis".

    CONNECTION

    Соединение с базой данных управляется "строкой коннекта", которая содержит стандартный набор указанных ниже ключей и значений (умолчальные значения есть <>):

    user=<имя пользователя> password=<пароль> dbname=<имя базы> hostname=<имя сервера> port=<5432>

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

    DATA

    Этот параметр указывается в форме "<столбец> from <имя_таблицы>", где столбец подразумевает пространственный столбец, представленный на карте.

    FILTER

    Фильтр должен быть правильной строкой SQL, соответствующей логике, обычно следующей после ключевого слова "WHERE" в SQL-запросе. Так, например, для выбора только 6-рядных (или более) улиц, используется фильтр "num_lanes >= 6".

  3. Постройте пространственные (GiST) индексы на тех данных, с помощью которых будете рисовать какие-либо слои.

    CREATE INDEX [имя_индекса] ON [имя_таблицы] USING GIST ( [геометрический_столбец] );
  4. Если вы собираетесь запрашивать свои слои с помощью Mapserver-а, вам понадобится "индекс oid".

    При запросах Mapserver требует уникальных идентификаторов для каждой пространственной записи, и модуль Mapserver-а для PostGIS использует PostgreSQL-ные значения oid в качестве таких идентификаторов. Побочным эффектом этого является то, что для быстрого доступа к произвольной записи в запросе требуется индекс по oid.

    Для создания "индекса oid" используйте следующий SQL:

    CREATE INDEX [имя_индекса] ON [имя_таблицы] ( oid );

4.7.2. Часто задаваемые вопросы

4.7.2.1. Когда я использую EXPRESSION в своем map-файле, условие никогда не возвращает истину, даже когда я знаю, что в моей таблице существует нужное значение.
4.7.2.2. FILTER, который я использую для моих шейп-файлов, не работает для моей таблицы PostGIS с теми же самыми данными.
4.7.2.3. Мой слой PostGIS выдается медленнее, чем мой слой шейп-файла, это нормально?
4.7.2.4. Мой слой PostGIS выдается хорошо, но запросы реально тормозят. Что неправильно?
4.7.2.1.

Когда я использую EXPRESSION в своем map-файле, условие никогда не возвращает истину, даже когда я знаю, что в моей таблице существует нужное значение.

В отличие от шейп-файлов, имена полей PostGIS, встречающиеся в EXPRESSIONS, должны быть написаны в нижнем регистре.

EXPRESSION ([numlanes] >= 6)
4.7.2.2.

FILTER, который я использую для моих шейп-файлов, не работает для моей таблицы PostGIS с теми же самыми данными.

В отличие от шейп-файлов, фильтры для слоев PostGIS используют синтаксис SQL (ини присоединяются к предложению SQL коннектором PostGIS для рисования слоев в Mapserver-е).

FILTER "type = 'highway' and numlanes >= 4"
4.7.2.3.

Мой слой PostGIS выдается медленнее, чем мой слой шейп-файла, это нормально?

Как правило, ожидание слоев PostGIS на 10% дольше, чем эквивалентных слоев шейп-файлов, из-за дополнительных накладных расходов: соединение с базой данных, преобразование данных и передача данных между базой и Mapserver-ом.

Если вы столкнулись с серьезной проблемой производительности, то, вероятно, вы не создали пространственного индекса на своей таблице.

postgis# CREATE INDEX geotable_gix ON geotable USING GIST ( geocolumn );
postgis# SELECT update_geometry_stats(); -- For PGSQL < 8.0
postgis# VACUUM ANALYZE; -- For PGSQL >= 8.0
4.7.2.4.

Мой слой PostGIS выдается хорошо, но запросы реально тормозят. Что неправильно?

Для ускорения запросов вы должны иметь уникальный ключ в своей пространственной таблице и индекс на нем.

С помощью пункта USING UNIQUE в своей строке DATA вы можете указать mapserver-у какой уникальный ключ использовать:

DATA "the_geom FROM geotable USING UNIQUE gid"

Если ваша таблица не имеет определенного уникального столбца, PostgreSQL позволяет вам "подделать" уникальный столбец с помощью "oid" в качестве такого столбца. "oid" является умолчальным уникальным столбцом на случай, если вы такового не декларировали. Вы сможете увеличить скорость выполнения запросов, создав индекс на значении oid вашей пространственной таблицы.

postgis# CREATE INDEX geotable_oid_idx ON geotable (oid);

4.7.3. Продвинутое использование

USING предложений псевдо-SQL используется для того, чтобы предоставить mapserver-у некоторую информацию, которая поможет ему понять результаты более сложных запросов. Более конкретно: если вьюха или вложенный SELECT используются в качестве исходной таблицы (справа от "FROM" в определении DATA), то mapserver-у затруднительно автоматически определить уникальный идентификатор для каждой строки и SRID для таблицы. USING может предоставить эту информацию mapserver-у следующим образом:

DATA "the_geom FROM (
  SELECT
    table1.the_geom AS the_geom,
    table1.oid AS oid,
    table2.data AS data
  FROM table1
  LEFT JOIN table2
  ON table1.id = table2.id
) AS new_table USING UNIQUE oid USING SRID=-1"
USING UNIQUE <уникальный_id>

Mapserver требует уникального идентификатора для каждой строки, чтобы определить строку при создании карты запроса. Он, как правило, использует oid в качастве уникального идентификатора, но вьюхи и вложенные SELECT-ы не имеют автоматически создаваемого столбца oid. Если вы желаете использовать функциональность запросов Mapserver-а, вам следует добавлять уникальные столбцы в свои вьюхи и вложенные SELECT-ы, и объявлять их в USING UNIQUE. Для этого вы можете, например, выбрать oid одной из таблиц, или любой другой столбец, который будет гарантированно уникальным в результирующем множестве.

Когда вы создаете карту запросов, предложение USING может быть полезным также и для простых предложений DATA. Ранее было рекомендовано создавать в используемых таблицах индекс по столбцу oid для ускорения выполнения карты запросов. Но с помощью пункта USING можно указать Mapserver-у использовать первичный ключ вашей таблицы в качестве идентификатора для карты запросов, и тогда отпадает необходимость создавать дополнительный индекс.

Замечание

"Запрос карты" ("Querying a Map") - действие, возникающее при клике на карту для запроса информации о данном месте. Не следует путать его с "картой запроса" для SQL-запроса в определении DATA.

USING SRID=<srid>

Чтобы вернуть mapserver-у правильные данные, PostGIS должен знать, какая пространственная ссылочная система исопльзуется в геометриях. Обычно, эту информацию можно найти в базе данных PostGIS в таблице "geometry_columns", однако, это невозможно для таблиц, создающихся "на лету" вложенными SELECT-ами и вьюхами. Поэтому используйте опцию USING SRID=, которая позволяет указывать корректный SRID в определении DATA.

Предупреждение

Парсер Mapserver для слоев PostGIS довольно приметивен и в некоторых местах является чувствительным к регистру. Проследите, чтобы все ключевые слова SQL и все ваши пункты USING были в верхнем регистре, а также, чтобы пункт USING UNIQUE предшествовал пункту USING SRID.

4.7.4. Примеры

Давайте начнем с простого примера работы с описанными выше таблицами. Рассмотрим следующее Mapserver-ное опредление слоя:

LAYER
  CONNECTIONTYPE postgis
  NAME "roads"
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  DATA "the_geom FROM roads"
  STATUS ON
  TYPE LINE
  CLASS
    COLOR 0 0 0
  END
END

Этот слой отобразит все геометрии улиц из таблицы улиц как черные линии.

Теперь, при приближении к масштабу 1:100000, будем показывать только шоссе. Следующие два слоя позволят добиться этого эффекта:

LAYER
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  DATA "the_geom FROM roads"
  MINSCALE 100000
  STATUS ON
  TYPE LINE
  FILTER "road_type = 'highway'"
  CLASS
    COLOR 0 0 0
  END
END
LAYER
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  DATA "the_geom FROM roads"
  MAXSCALE 100000
  STATUS ON
  TYPE LINE
  CLASSITEM road_type
  CLASS
    EXPRESSION "highway"
    SIZE 2
    COLOR 255 0 0
  END
  CLASS
    COLOR 0 0 0
  END
END

Первый слой используется, когда запрашиваемый масштаб больше, чем 1:100000, и отображает только дороги типа "шоссе", как черные линии. Опция FILTER отфильтровывает для показа только дороги типа "шоссе" ("highway").

Второй слой используется, когда масштаб меньше 1:100000, и отобразит шоссе как две красные линии, а другие дороги, - как сплошные черные линии.

Итак, мы сделали несколько интересных штук, используя только функционал mapserver-а, с довольно простым предложением DATA. Теперь предположим, что названия улиц по какой-то причине хранятсЯ в другой таблице, и нам нужно присоединить ее, чтобы пометить улицы.

LAYER
  CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
  DATA "the_geom FROM (SELECT roads.oid AS oid, roads.the_geom AS the_geom,
        road_names.name as name FROM roads LEFT JOIN road_names ON
        roads.road_name_id = road_names.road_name_id)
        AS named_roads USING UNIQUE oid USING SRID=-1"
  MAXSCALE 20000
  STATUS ON
  TYPE ANNOTATION
  LABELITEM name
  CLASS
    LABEL
      ANGLE auto
      SIZE 8
      COLOR 0 192 0
      TYPE truetype
      FONT arial
    ENDl
  END
END

Этот слой примечаний добавляет зеленые метки на все улицы в масштабе 1:20000 или меньше. Также здесь демонстрируется использование SQL вместе с определением DATA.


Назад Выше Вперед
4.6. Сложные запросы Начало 4.8. Клиенты Java (JDBC)
Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2008-04-10 12:09:18

Метки материала: PostGIS, Mapserver, карта, руководство, OpenGIS, PostgreSQL, map, SQL

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.