- 3.1. Какие виды геометрических объектов имеются в моем распоряжении?
- 3.2. Как вставить объект ГИС в базу данных?
- 3.3. Как построить пространственный запрос?
- 3.4. Как повысить скорость пространственных запросов в больших таблицах?
- 3.5. Почему не поддерживаются R-Tree индексы PostgreSQL?
- 3.6. Почему я должен использовать функцию AddGeometryColumn() и все прочие функции совместимости с OpenGIS?
- 3.7. Какой способ лучше использовать для поиска всех объектов в радиусе от другого объекта?
- 3.8. Как включить в запрос перепроектирование координат?
3.1. |
Какие виды геометрических объектов имеются в моем распоряжении? |
|
В вашем распоряжении point, line, polygon, multipoint, multiline, multipolygon, and geometrycollections (точка, линия, полигон, мультиточка, мультилиния,
мультиполигон и геометрическая коллекция). Они определены в формате Well
Known Text Open GIS (с расширениями XYZ, XYM, XYZM). |
3.2. |
Как вставить объект ГИС в базу данных? |
|
Сначала вы должны создать таблицу со столбцом типа "geometry", который будет содержать
ваши ГИС-данные. Соединитесь с вашей базой данных с помощью psql и
выполните SQL:
CREATE TABLE gtest ( ID int4, NAME varchar(20) );
SELECT AddGeometryColumn('', 'gtest','geom',-1,'LINESTRING',2); |
Если не получилось добавить столбец геометрии, то, вероятно, вы не
загрузили функции и объекты PostGIS в свою базу данных. Смотрите инструкцию по
установке.
Далее, вы можете вставлять геометрию в таблицу с помощью SQL-команды insert.
Объект ГИС будет форматирован согласно формату "well-known text" Консорциума
OpenGIS:
INSERT INTO gtest (ID, NAME, GEOM)
VALUES (
1,
'Первая геометрия',
GeomFromText('LINESTRING(2 3,4 5,6 5,7 8)', -1)
); |
Подробную информацию о других объектах ГИС можно посмотреть в справочнике объектов.
Просмотр ваших ГИС-данных в таблице:
SELECT id, name, AsText(geom) AS geom FROM gtest; |
Результат должен выглядеть примерно так:
id | name | geom
---+------------------+-----------------------------
1 | Первая геометрия | LINESTRING(2 3,4 5,6 5,7 8)
(1 row) |
3.3. |
Как построить пространственный запрос? |
|
Так же, как вы строите другие запросы к базе данных, используя SQL-запрос для
получения значений, функций, логических тестов.
Есть две важных вещи, которые следует учитывать при построении пространственных
запросов: существует ли пространственный индекс, которым можно воспользовать и нужно ли произвести сложные вычисления на большом числе геометрий.
Чаще всего вам будет нужен "оператор пересечения" (&&), который
проверяет пересекаются ли границы объектов. Польза оператора && заключается в том, что он может использовать пространственный индекс, если он существует. Это ускорит выполнения запроса.
Кроме того, вы можете использовать пространственные функции, такие как
Distance(), ST_Intersects(), ST_Contains() and ST_Within() и другие для сужения
результатов поиска. Большинство пространственных запросов включают тест на индекс и тест на пространственную функцию. Тест индекса полезен тем, что ограничивает число
проверок значений теми, которые могут попасть в требуемый набор.
Далее используются пространственные функции используются для окончательной проверки условия.
SELECT id, the_geom FROM thetable
WHERE
the_geom && 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'
AND
_ST_Contains(the_geom,'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'); |
|
3.4. |
Как повысить скорость пространственных запросов в больших таблицах? |
|
Быстрые запросы в больших таблицах, вместе с поддержкой транзакций, являются назначением пространственной базы данных. Поэтому очень
важно иметь хорошие индексы.
Для создания пространственного индекса таблицы со столбцом geometry, используйте запрос "CREATE INDEX", как показано ниже:
CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometrycolumn] ); |
Опция "USING GIST" означает, что сервер должен использовать индекс GiST
(Generalized Search Tree - обобщенное поисковое дерево).
Замечание
Индексы GiST допускают потери. Индексы с потерями используют замещающие
объекты (в пространственном случае - охват объекта) для создания индекса.
Вы должны также обеспечить планировщик запросов PostgreSQL достаточной информацией о
вашем индексе, чтобы он мог выбирать когда их использовать. Чтобы
сделать это, вам нужно "собрать статистику" по вашим таблицам с геометрией.
Для PostgreSQL 8.0.x и старше, выполните команду VACUUM ANALYZE.
Для PostgreSQL 7.4.x и младше, выполните команду SELECT UPDATE_GEOMETRY_STATS() |
3.5. |
Почему не поддерживаются R-Tree индексы PostgreSQL? |
|
Ранние версии PostGIS использовали R-Tree индексы PostgreSQL. Однако индексы стали ненужны начиная с версии 0.6, когда
появились пространственные индексы со схемой R-Tree-через-GiST.
Наши тесты показали, что скорости поиска с использованием R-Tree
и GiST индексов сопоставимы. Исходные R-Tree индексы PostgreSQL имеют два ограничения,
которые делают их нежелательными для использования с геоданными (заметим, что
эти ограничения присущи текущей реализации R-Tree в PostgreSQL, а
не самой концепции R-Tree):
- R-Tree индексы в PostgreSQL не умеют работать со объектами, размер которых
превышает 8K. Индексы GiST умеют, "теряя" часть информации, заменяя собственно
объекты на их охват.
- R-Tree индексы в PostgreSQL не являются "null-безопасными", т.е. индекс на столбце геометрии, в котором содержатся геометрии
null создать нельзя.
|
3.6. |
Почему я должен использовать функцию AddGeometryColumn() и все прочие функции совместимости с OpenGIS? |
|
Если у вас нет необходимости использовать функции поддержки OpenGIS, не
используйте их. Просто создайте таблицы как в старых версиях, определите
столбцы геометрии с помощью CREATE. Вся ваша геометрия будет иметь SRID,
равный -1, а таблицы мета-данных OpenGIS не будут должным образом заполнены. Однако большинство приложений, основанных на PostGIS,
не смогут с этим работать, и мы советуем вам использовать AddGeometryColumn() при создания геометрических таблиц.
Одним из приложений, которое использует мета-данные geometry_columns, является Mapserver. Mapserver может использовать в
SRID столбцов геометрии для перепроектирования объектов на лету в текущую проекцию
карты. |
3.7. |
Какой способ лучше использовать для поиска всех объектов в радиусе от другого объекта? |
|
Чтобы использовать базу данных наиболее эффективно, лучше создать запрос, которые
будет совмешать тест на попадание объекта в радиус и охват: тест на попадание в охват использует пространственный индекс, который предоставляет быстрый доступ к подмножеству
данных, далее используется тест на нахождение в заданном радиусе от нужного объекта.
Для нахождения индексированных расстояний удобна функция ST_DWithin(geometry, geometry, distance). Она создает поисковый
прямоугольник, достаточно большой, чтобы включить все на расстояние радиуса поиска.
Затем прямоугольник используется для объектов на необходимом расстоянии в
результирующем проиндексированном подмножестве.
Например, чтобы найти все объекты в 100 метрах от POINT(1000 1000), хорошо
работает следующий запрос:
SELECT * FROM geotable
WHERE ST_DWithin(geocolumn, 'POINT(1000 1000)', 100.0); |
|
3.8. |
Как включить в запрос перепроектирование координат? |
|
Для перепроектирования, исходная и конечная система координат должны
быть определены в таблице SPATIAL_REF_SYS, а геометрии должны иметь установленный SRID. Если это сделано, то перепроектирование просто осуществляется обращением к нужному SRID.
SELECT ST_Transform(the_geom,4269) FROM geotable; |
|
Последнее обновление: August 14 2008 (Наверх) |