На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Переоткрыть основную карту

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
Переоткрыть основную карту, И подключить к ней существующую пользовательскую
 
Стоит задача работать c основной картой в режиме "только чтение". Карта располагается на NFS сервере. Пользовательская карта создаётся локально и нужна только на время работы приложения.
Однако, соединение c NFS сервером может быть нарушено, поэтому необходимо переоткрыть карту (при появлении соединения c сервером) и подключить к ней уже существующую пользовательскую карту. Таким образом функция mapCreateAndAppendTempSite не подходит.
Попробовал следующий код (пере)открытия основной карты:
Код
//основная карта
if(hMap != 0) {
   mapCloseData(hMap);
   hMap = 0;
}

hMap = mapOpenDataUn(name.utf16(), GENERIC_READ);

if(hMap == 0) {
   //ошибка
   return;
}
//пользовательская карта
//userMap = mapCreateAndAppendTempSite(hMap, "./operator.rsc");
if(userMap == 0) {
   MAPREGISTEREX map;
   DATUMPARAM datum;
   ELLIPSOIDPARAM ellips;
   mapGetDocProjection(hMap, &map, &datum, &ellips);
   userMap = mapCreateTempSiteExUn(QString("./operator.rsc").utf16(), &map, &datum, &ellips);
}

if(userMap == 0) {
   //ошибка
   return;
}
но в данном случае объекты не отображаются.
Каким образом лучше всего решить данную задачу?
Код
// Версия библиотеки MapAccess// (если применяется "mapacces.h" и т.п.)
#define MAPACCESSVERSION  20160418


// Версия интерфейса MAPAPI и ядра библиотеки
#define MAPAPIVERSION  0x0111302
 
Не хватает функции типа:
Код
_MAPIMP long int _MAPAPI mapAppendSite(HMAP hMap, HSITE hSite, long int mode = 0, long int transform = -1);
чтобы можно было добавить уже существующую пользовательскую карту hSite к векторной карте hMap.
 
Для сохранения текущего состояния локальной карты на диск Вам поможет функция:
Код
  // Сохранить текущее состояние карты на диск
  // hMap - идентификатор основной векторной карты
  // hSite - идентификатор открытой пользовательской карты
  // force - сохранять всегда, если не 0, или только при редактировании
  // При выполнении редактирования карты с отключенным
  // журналом транзакций состояние карты в памяти и
  // на диске может отличаться, в этом случае можно
  // вызвать mapSaveSite

_MAPIMP void _MAPAPI mapSaveSite(HMAP hMap, HSITE hSite, long int force); 
Далее при следующем сеансе работы с hMap Вы сможете добавить карту к базовой функциями:
Код
  // Открыть пользовательскую карту в заданном районе работ
  // (добавить в цепочку пользовательских карт (в обстановку))
  // Возвращает идентификатор открытой пользовательской карты
  // hMap     - идентификатор открытой карты
  // sitename - имя открываемого файла пользовательской карты
  // mode     - режим чтения/записи (GENERIC_READ, GENERIC_WRITE
  //            или 0) GENERIC_READ - все данные только на чтение
  // transform - признак трансформирования пользовательской карты
  //             к ранее открытым данным (если проекции разные):
  //             0 - не трансформировать данные (преобразовывать "на лету"),
  //             1 - трансформировать данные при открытии и сохранить карту
  //                 в новой проекции,
  //            -1 - задать вопрос пользователю.
  // В серверной версии (-1) обрабатывается, как 0.
  // password - пароль доступа к данным из которого формируется 256-битный код
  //            для шифрования данных (при утрате данные не восстанавливаются)
  // size     - длина пароля в байтах !!!
  // Передача пароля необходима, если при создании карты он был указан.
  // Если пароль не передан, а он был указан при создании,
  // то автоматически вызывается диалог scnGetMapPassword из mapscena.dll (gisdlgs.dll)
  // Если выдача сообщений запрещена (mapIsMessageEnable()), то диалог
  // не вызывается, а при отсутствии пароля происходит отказ открытия данных
  // При ошибке возвращает ноль

_MAPIMP HSITE _MAPAPI mapOpenSiteForMapPro(HMAP hMap,
                                           const WCHAR *sitename,
                                           long int mode,
                                           long int transform,
                                           const WCHAR *password, long int size);

_MAPIMP HSITE _MAPAPI mapOpenSiteForMap(HMAP hMap, const char *sitename,
                                  long int mode);

_MAPIMP HSITE _MAPAPI mapOpenSiteForMapEx(HMAP hMap, const char *sitename,
                                          long int mode, long int transform);

_MAPIMP HSITE _MAPAPI mapOpenSiteForMapUn(HMAP hMap, const WCHAR *sitename,
                                          long int mode);

_MAPIMP HSITE _MAPAPI mapOpenSiteForMapExUn(HMAP hMap, const WCHAR *sitename,
                                            long int mode, long int transform); 
Удалить карту и все данные Вы сможете функцией:
Код
  // Удалить пользовательскую карту (все файлы данных)
  // hMap - идентификатор открытой карты
  // number - номер пользовательской карты в цепочке от 1 до числа карт
  // При ошибке возвращает ноль

_MAPIMP long int _MAPAPI mapDeleteSite(HMAP hMap, long int number); 
 
Спасибо, я уже рассматривал эти функции. Но проблема в том, что на пользовательской карте у меня есть собственные объекты и ссылки на них (HOBJ). И хотелось бы после всех этих манипуляций c переоткрытием карт чтобы эти ссылки оставались действительными - мне c ними ещё дальше работать. А при использовании функций mapOpenSiteForMap* появляется новый HSITE и ссылки на объекты становятся недействительными...
Я подозреваю, что в таком случае мне пригодится функция mapSetObjectMap. То есть, при переоткрытии карты я создаю новый HSITE на основе переоткрытой HMAP, переношу туда свои объекты c помощью mapSetObjectMap и закрываю старый HSITE. Таким образом, можно каждый раз создавать пользовательскую карты c помощью mapCreateAndAppendTempSiteUn и не заморачиваться c сохранением её на диск. Верен ли такой подход?
 
Набросал следующий код:
   
Код
//функция (пере)открытия основой и пользовательской карт

if(hMap != 0) {
   //закрываем основную карту
   mapCloseData(hMap);
   hMap = 0;
}

//(пере)открываем основную карту (по сути всегда одна и та же карта Подольска)
hMap = mapOpenDataUn(name.utf16(), GENERIC_READ);

if(hMap == 0) {
   //ошибка
   return;
}
//(пере)открываем пользовательскую
if(userMap == 0) {
   //похоже пользовательская карта открывается впервые
   userMap = mapCreateAndAppendTempSiteUn(hMap, class_name.utf16());
} else {
   //пользовательская карта уже была открыта
   //Создаём новую и переносим в неё уже существующие объекты
   HSITE hSite = mapCreateAndAppendTempSiteUn(hMap, class_name.utf16());
   if(hSite != 0) {
      for(HOBJ obj : map_objects) {
         long rc = mapSetObjectMap(obj, hSite);
         if(rc == 0) {
            //ошибка
         }
         mapCommitObject(obj);
      }
   }
   //закрываем старую пользовательскую карту
   mapCloseData(userMap);

   userMap = hSite;
}

if(userMap == 0) {
   //ошибка
}
Он отрабатывает без ошибок, mapSetObjectMap всегда возвращает 1. Но объекты на карте не перерисовываются, то есть отрисовывается только основная карта без пользовательских объектов на ней. Хотя сами объекты похоже валидные, например mapObjectPlane возвращает те же самые координаты объектов что и до переоткрытия.
 
Замена mapSetObjectMap на mapChangeObjectMap ничего не изменила. Единственно в обоих случаях иногда после переоткрытия карт mapObjectPlane возвращает нулевые координаты объектов.
 
Нашёл ошибку: надо вначале создать новую ссылку на основную карту, перенести объекты на новую пользовательскую и только потом удалить старую ссылку на основную. Теперь всё работает.  
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности