Подписаться через RSS2Email.ru
|
Руководство по PostGIS. Глава 4. Использование PostGIS.
4.7. Использование Mapserver
|
Назад |
|
Вперед
|
4.7. Использование Mapserver-а
"Minnesota Mapserver" - интернет сервер веб-карт, который поддерживает
OpenGIS-овую Спецификацию сервера веб-карт.
4.7.1. Основы использования
Для использования PostGIS с Mapserver-ом, вы должны знать, как
конфигурировать Mapserver, а это выходит за рамки данной документации. В этом
разделе описывается специфика использования PostGIS и детали
конфигурирования.
Для использования PostGIS-а с Mapserver-ом вам понадобятся:
Mapserver получает доступ к данным PostGIS/PostgreSQL, как и любой другой
клиент PostgreSQL, с помощью libpq. Это означает, что Mapserver может
быть установлен на любую машину с сетевым доступом к серверу PostGIS, если
только в сисетме есть клиентские библиотеки PostgreSQL libpq.
-
Скомпилируйте и установите Mapserver с любыми нужными вам опциями включив
опцию конфигурации "--with-postgis".
-
В 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".
-
Постройте пространственные (GiST) индексы на тех данных, с помощью которых
будете рисовать какие-либо слои.
CREATE INDEX [имя_индекса] ON [имя_таблицы] USING GIST ( [геометрический_столбец] );
-
Если вы собираетесь запрашивать свои слои с помощью 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.
Последнее редактирование: 2008-04-10 12:09:18
Метки материала:
PostGIS, Mapserver, карта, руководство, OpenGIS, PostgreSQL, map, SQL
Оставьте, пожалуйста, свой комментарий к публикации
|