G I S   T o o l K i t
Справочник программиста

Главная | MAPAPI | PANAPI | Примеры
 

ЭКСПОРТ КАРТЫ В ТАБЛИЦУ БАЗЫ ДАННЫХ POSTGRESQL

Автор: Дарья Лунченко

 

Примечание:
PostgreSQL — это объектно-реляционная система управления базами данных, с открытым исходным кодом. Она поддерживает большую часть стандарта SQL и предлагает множество современных функций: сложные запросы, внешние ключи, триггер, изменяемые представления, транзакционная целостность, многоверсионность.
PostGIS — расширение объектно-реляционной СУБД PostgreSQL, предназначенное для хранения в базе географических данных.
Создание и наполнение БД PostgreSQL проводилось в программе pgAdmin 4.

 

В примере демонстрируется создание прикладной потоковой задачи ГИС "Карта" (12-я версия) для экспорта объектов карты в таблицу базы данных PostgreSQL. В качестве исходных данных используется карта Харьковской области, полученная на основе данных OSM и таблица базы данных площадных объектов PostgreSQL, содержащая поля: code (bigint) - уникальный идентификатор, keyname(character(80))- ключ объекта, ownname(character(80)) - собственное название, the_geom(geometry) - метрика объекта (рис.1).

Рисунок 1- Вид таблицы базы данных в pgAdmin4

На карте были выбраны площадные объекты слоя землепользование - новые районы под строительство и экспортированы в таблицу БД polygon_objects (рис.2).

Рисунок 2 - Результат экспорта объектов в таблицу БД

 

  1. Работа с базой данных PostgreSQL

Рассмотрим некоторые аспекты работы с БД PostgreSQL:

1) спецификация OpenGIS определяет два стандартных формата хранения метрики объектов Well-Known Text (WKT) и Well-Known Binary (WKB). В нашей БД поля для хранения метрики имеют тип данных geometry, и представляют собой формат WKB.
Примеры текстового представления (WKT) пространственных объектов приведены ниже:

  POINT(0 0)
  LINESTRING(0 0,1 1,1 2)
  POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))
  MULTIPOINT(0 0,1 2)
  MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))
  MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)),((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))
  GEOMETRYCOLLECTION(POINT(2 3),LINESTRING((2 3,3 4)))

Спецификация OpenGIS требует, чтобы внутренний формат хранения пространственных объектов включал идентификатор системы координат (spatial referencing system identifier - SRID). SRID необходим для добавления объекта в базу данных.
Ввод/вывод в этих форматах доступен с использованием следующих интерфейсов:

  text WKT = ST_AsText(geometry);
  geometry = GeomFromWKB(bytea WKB, SRID);
  geometry = GeometryFromText(text WKT, SRID);

2) так как пример является демонстрационным, пользователь может экспортировать только точечные(POINT), линейные(LINESTRING) и площадные(POLYGON) объекты карты. Также при экспорте не учитываются подобъекты;

3) для экспорта данных в существующую БД, используются SQL запросы вида:

  • получить имена полей таблицы:
 SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' 
                  AND table_name NOT IN('spatial_ref_sys') AND table_type = 'BASE TABLE'

  • получить тип данных поля таблицы:
 SELECT data_type FROM information_schema.columns WHERE table_name = ‘polygon_objects’ 
                AND column_name = ‘ownname’

  • получить тип поля геометрии:
 SELECT type  FROM geometry_columns WHERE f_table_schema = ‘public’ 
                 AND f_table_name = ‘polygon_objects’ AND f_geometry_column = ‘the_geom’

  • получить EPSG код:
 SELECT Find_SRID(‘public’, ‘polygon_objects’ ,‘the_geom’ )

  • получить поле первичного ключа:
 SELECT a.attname, format_type(a.atttypid,a.atttypmod) AS data_type 
             FROM pg_index I JOIN pg_attribute a 
             ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) 
             WHERE i.indrelid = ‘polygon_objects’::regclass AND i.indisprimary

  • вставить новую запись в таблицу площадных объектов:
 INSERT INTO polygon_objects(code, the_geom, keyname, ownname) VALUES(1,
             ST_GeomFromText(‘POLYGON((6458421.406 4030936.914, 
             6458753.732 4031153.353,6458620.269 4031344.155,
             6458303.089 4031112.154, 6458421.406 4030936.914))’, ‘S000000009715’, ‘16’)

  • вставить новую запись в таблицу линейных объектов:
 INSERT INTO line_objects (the_geom, keyname, ownname)  VALUES(
               ST_GeomFromText(‘LINESTRING(6458393.951 4030525.990, 
               6458406.265 4030682.104, 6458315.247 4030818.983)’,3395), ‘L00600000001’, ‘3’)

  • вставить новую запись в таблицу точечных объектов:
 INSERT INTO point_ojects (the_geom, key , ownname) VALUES 
               (ST_GeomFromText(‘POINT(6458130.369 4030841.558)’, 3395), ‘kiosk’, ‘Кулиничи’)

 

   3. Реализация программы экспорта данных

Проект создан, как библиотека DLL MFC, в среде разработки Microsoft Visual Studio Community, которая может использоваться бесплатно в учебных целях. Как создать в Microsoft Visual Studio новый проект DLL, и настроить внешние зависимости, вы можете посмотреть здесь.

Структуру проекта вы можете видеть на рис. 3.

Рисунок 3 - Структура проекта DLL экспорта объектов

Работа с БД PostgreSQL осуществляется с помощью набора специальных dll-библиотек (архив libpqdll), которые нужно добавить в папку с утановленной ГИС "Карта". Для доступа к функциям dll-библиотек PostgreSQL необходимо добавить во внешние зависимости указание на папку libpq с h-файлами PostgreSQL.

Также необходимо добавить во внешние зависимости также указание на папку include, содержащую объявление функций интерфейса "MAPAPI". Ссылки на архивы со всеми необходимыми библиотеками приведены в конце страницы.

Функции работы с PostgreSQL:

1) подключение к базе данных, PGconnection - структура подключения к БД:

 //выполняем подключение к PostgreSQL
  PGconnection = PQconnectdb(conn);
  //проверяем статус подключения
  if (PQstatus(PGconnection) == CONNECTION_BAD) {
     AfxMessageBox(TEXT("Не удается подключиться к базе данных!"));
  return;

2) отправка запроса на сервер и ожидание результата PGresult:

 //формируем запрос для получения имён таблиц базы данных
  PGresultMain = PQexec(PGconnection, "SELECT table_name FROM information_schema.tables 
  WHERE   table_schema = 'public' AND table_name NOT IN('spatial_ref_sys') 
  AND table_type = 'BASE TABLE'");

  if (PQresultStatus(PGresultMain) != PGRES_TUPLES_OK) {
   AfxMessageBox(TEXT("Данные о таблицах базы данных не были получены!"));
	 return;
	}

3) определение количества строк и столбцов, получение значения результата запроса:

 //определяем количество строк в результате запроса
  row_count = PQntuples(PGresultMain);
  //определяем количество столбцов в результате запроса
  col_count = PQnfields(PGresultMain);

  for (int i = 0; i < row_count; i++) {
    for (int j = 0; j < col_count; j++)
     {//получем значение,соответствующее i-ой строке, j-му столбцу результата запроса
	  CString tName(PQgetvalue(PGresultMain, i, j));
	  cbTableName.AddString(tName);
	 }
	 }

4) установка пользовательской кодировки:

 PQsetClientEncoding(PGconnection, "WIN1251");

Функции MAPAPI используемые в программе:

 // Запрос и установка кода EPSG системы координат
  mapGetEPSGCode  
  // Запросить количество семантик в классификаторе
  mapGetRscSemanticCount
  // Запросить код семантики по порядковому номеру
  mapGetRscSemanticCodeByNumber
  // Запросить название семантики по порядковому номеру в кодировке UNICODE
  mapGetRscSemanticNameByNumberUn
  // Запросить тип семантики по её внешнему коду
  mapGetRscSemanticTypeByCode
  // Подсчитать сколько объектов удовлетворяет условиям
  // обобщенного поиска
  mapTotalSeekObjectCount
  // Запросить признак выделения объектов по обобщённым
  // условиям поиска
  mapGetTotalSelectFlag
  // Cоздать пустой объект векторной карты
  mapCreateObject
  // Обобщенный поиск объектов по заданным условиям
  mapTotalSeekObject
  // Запросить характер локализации объекта
  mapObjectLocal
  // Запрос числа точек метрики объекта/подобъекта
  mapPointCount
  // Запросить число семантических характеристик у объекта
  mapSemanticAmount
  // Запросить код семантической характеристики объекта
  mapSemanticCode
  // Запросить значение семантической характеристики объекта
  mapSemanticValue  

 

  4. Алгоритм работы пользователя

1) выбрать на карте объекты для экспорта, с одинаковым типом локализации;

2) выбрать меню «Задачи»-> «Запуск приложений»-> «Экспорт объектов карты в таблицу БД PostgreSQL»;

3) ввести параметры подключения к базе данных, и нажать кнопку «Подключиться» ;

4) выбрать таблицу базы данных для экспорта;

5) если таблица содержит поле первичного ключа, то оно автоматически отобразится в «Поле идентификатора», в другом случае поле будет не заполнено;

6) установить поле метрики;

7) при выборе условия «Экспортировать ключ объекта», выбрать поле в которое будет записываться ключ объекта(поле может иметь только тип character);

8) если это необходимо, то установить в соответствие оставшимся полям таблицы семантики: выбрать поле из первого списка, и сделать двойной щелчок мыши на семантике из второго списка. Если объект, который экспортируется, не содержит соответствующую семантику, то в таблицу записывается пустая строка;

9) нажать кнопку «Выполнить», в таблицу экспортируются только те объекты, число точек которых не превышает 100 000.

 

  5. Импорт демонстрационной базы данных PostgreSQL в pgAdmin 4

Для импорта базы данных необходимо:

1) запустить pgAdmin4, перейти в меню «File»->«Preferences»-> «Binary Paths», и установить в соответствующие поля путь к папке bin, расположенной в каталоге установки PostgreSQL;

2) создать новую базу данных, выбрав «Databases»-> «Create»-> «Database»;

3) выбрать базу данных и нажать правой кнопкой мыши, в открывшемся меню, выбрать «Restore», в диалоге указать формат и путь к файлу импорта, нажать кнопку «Restore».

 

Данные для загрузки:

1) Задача экспорта данных в PostgreSQL (только для ГИС "Карта" 12-й версии): PostgreSqlExportDll.zip

2) dll-библиотеки PostgreSQL (должны быть скопированы в папку установки ГИС "Карта"): libpqdll.zip

3) Исходные файлы примера: codex001.zip

4) h-файлы интерфейса Mapapi для VC++: include.zip

5) h-файлы PostgreSQL: libpq.zip

6) Пример карты для импорта/экспорта: map001.zip

7) Пример базы данных PostgreSQL: db001.zip

Задача экспорта данных в PostgreSQL позволяет использовать любые карты и базы. Добавленные выше архивы с картой и базой приведены только для примера, если у вас нет собственных подходящих данных.

 
 

Касьянов О.В.
info@panorama.kharkov.ua

bigmir)net TOP 100