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

После изменения базового масштаба карты не находятся объекты.

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
После изменения базового масштаба карты не находятся объекты.
 
Приветствую!

ГИС Конструктор для Qt Designer x64 (версия 12.6.1), ОС Astra Linux

Столкнулся с проблемой: после изменения базового масштаба карты, некоторые объекты не выделяются на карте (не находятся в области нажатия кнопки мыши). В ходе поиска причины выяснил, что данная проблема как-то связана с запросом габаритов объектов, их сохранением и, собственно, с самим изменением базового масштаба. (похоже, что где-то сохраняются габариты объекта и при повторном поиске, после изменения базового масштаба, объект не находится, хоть и должен)
В результате, в качестве временного решения проблемы, пересохраняю все векторные объекты после изменения базового масштаба.

Пример демонстрирующий проблему:
Код
#include <QString>
#include <QDebug>
#include <QImage>

#include "mapapi.h"
#include "sitapi.h"
#include "rscapi.h"
#include "mapcreat.h"
#include "maptype.h"

HOBJ createPolygonObject(HMAP hmap, RECT* rect, int bgColor, int fgColor) {
   HOBJ hobj = mapCreateObject(hmap, IDDOUBLE2, 0);
   if (hobj != 0) {
      if (mapRegisterDrawObject(hobj, 0, LOCAL_SQUARE) != 0) {
         IMGPOLYGONGLASS fill;
         memset((void*) &fill, 0, sizeof(fill));
         fill.Color = bgColor;
         fill.Transparency = 100;
         mapAppendDraw(hobj, IMG_POLYGONGLASS, (const char*) &fill);
         IMGLINE border;
         memset((void*) &border, 0, sizeof(border));
         border.Color = fgColor;
         border.Thick = PIX2MKM(2);
         mapAppendDraw(hobj, IMG_LINE, (const char*) &border);
         double x1 = rect->left;
         double y1 = rect->top;
         double x2 = rect->right;
         double y2 = rect->bottom;
         mapPictureToPlane(hmap, &x1, &y1);
         mapPictureToPlane(hmap, &x2, &y2);
         mapAppendPointPlane(hobj, x1, y1, 0);
         mapAppendPointPlane(hobj, x2, y1, 0);
         mapAppendPointPlane(hobj, x2, y2, 0);
         mapAppendPointPlane(hobj, x1, y2, 0);
         mapAppendPointPlane(hobj, x1, y1, 0);
         mapCommitObject(hobj);
      } else {
         qDebug() << "mapRegisterDrawObject error";
      }
   } else {
      qDebug() << "mapCreateObject error";
   }
   return hobj;
}

HOBJ createFlag(HMAP hmap, int aX, int aY) {
   HOBJ hobj = mapCreateObject(hmap);
   if (mapRegisterObjectByKey(hobj, "009991001001") != 0) {
      double x = aX;
      double y = aY;
      mapPictureToPlane(hmap, &x, &y);
      mapAppendPointPlane(hobj, x, y, 0);
      mapAppendPointPlane(hobj, x, y, 0);
   }
   return hobj;
}

//Ищет объект в точке (точка в координатах изображения)
bool searchObjInPoint(HMAP hmap, int aX, int aY) {
   DFRAME frame;
   double x = aX - 5;
   double y = aY - 5;
   mapPictureToPlane(hmap, &x, &y);
   frame.X1 = x;
   frame.Y1 = y;
   x = aX + 5;
   y = aY + 5;
   mapPictureToPlane(hmap, &x, &y);
   frame.X2 = x;
   frame.Y2 = y;
   if (frame.X1 > frame.X2) {
      frame.X2 = frame.X1;
      frame.X1 = x;
   }
   if (frame.Y1 > frame.Y2) {
      frame.Y2 = frame.Y1;
      frame.Y1 = y;
   }

   HSELECT select = mapCreateMapSelectContext(hmap);
   HOBJ hobj = mapCreateObject(hmap);

   long res = mapWhatObjectBySelect(hmap, hobj, &frame, select, WO_FIRST | WO_VISUAL | WO_INMAP, PP_PLANE);

   mapFreeObject(hobj);
   mapDeleteSelectContext(select);
   return res != 0;
}

void saveMap(HMAP hmap, QString filename) {
   double scale = mapGetRealShowScale(hmap);
   mapSetRealShowScale(hmap, 10000);
   mapSetRealShowScale(hmap, scale);
    XIMAGEDESC desc;
    DFRAME frame;
    mapGetTotalBorder(hmap, &frame, PP_PICTURE);
    RECT rect;
    rect.left = frame.X1;
    rect.right = frame.X2;
    rect.top = frame.Y1;
    rect.bottom = frame.Y2;

    memset((void*) &desc, 0, sizeof(desc));
    desc.Width = rect.right - rect.left;
    desc.Height = rect.bottom - rect.top;
    desc.Depth = mapGetMapScreenDepth();
    desc.CellSize = desc.Depth / 8;
    desc.RowSize = desc.Width * desc.CellSize;
    desc.Point = (char*) malloc(desc.Height * desc.RowSize);

    mapPaintToXImage(hmap, &desc, 0,0, &rect);
    QImage im2((const uchar*) desc.Point, desc.Width,
               desc.Height, desc.RowSize,
               QImage::Format_RGB32);
    if (!im2.save("/tmp/" + filename, "PNG")) {
        qDebug() << "file save error";
    }
    free(desc.Point);
}

// Тест поиска флага после смены базового масштаба
int main(int argc, char ** argv) {
   QString* siteName = new QString("/home/user/temp/testSearchFlagsAfterBaseScaleChange.sitx");
   QString* rscName = new QString("/home/user/temp/operator.rsc");
   CREATESITEUN cs;
   memset((void*) &cs, 0, sizeof(cs));
   cs.Length = sizeof(CREATESITEUN);
   cs.EllipsoideKind = 9;
   cs.MapType = 16;

   HMAP hmap = mapCreateSiteUn((const WCHAR*) siteName->constData(),
         (const WCHAR*) rscName->constData(), &cs);
   if (hmap != 0) {
      RECT rect;
      rect.left = 0;
      rect.top = 0;
      rect.right = 200;
      rect.bottom = 200;
      HOBJ poly = createPolygonObject(hmap, &rect, 0xFFFFFF, 0xFF0000);
      mapFreeObject(poly);

      mapCloseMap(hmap);
       hmap = mapOpenAnyData((const WCHAR*) siteName->constData());

      HOBJ flag = createFlag(hmap, 200, 250);
      mapSetSiteScale(hmap, 0, 10000);
      mapCommitObject(flag);

      mapSetSiteScale(hmap, 0, 40000);
      saveMap(hmap, "40k.png");

      DFRAME frame;
      mapObjectViewFrameEx(flag, &frame, 1);
      qDebug() << "obj found: " << searchObjInPoint(hmap, 200,180);

      mapCommitObject(flag);
      qDebug() << "obj found: " << searchObjInPoint(hmap, 200,180);

      mapFreeObject(flag);

      mapCloseMap(hmap);
   }
}


В результате, при первом поиске объект не находится, а после повторного сохранения - находится.
Интересно, что результат может быть различным при изменении порядка вызова
mapSetSiteScale, mapCommitObject.

ЗЫ: В общем, какие-то чудеса...

С уважением,
Матвеев П.В.
 
Здравствуйте, Павел!

При изменении базового масштаба карты изменятся и размеры условных знаков, для соответствия установленным размерам в классификаторе. Данное поведение указанно в описании функции mapSetSiteScale.
В предоставленном примере точка поиска берется выше координат условного знака, и поэтому при масштабировании до 10000 размеры знака оказываются вне установленной зоны поиска. Если в примере изменить точку поиска на координаты создаваемого объекта, то знак будет оставаться в рамках установленной зоны поиска.

Код
...
qDebug() << "obj found: " << searchObjInPoint(hmap, 200, 250);
...

 
Приветствую!

То что размеры знаков меняются - это понятно. Вот только есть ощущение, что функция поиска использует габариты знака рассчитанные на ранее установленном базовом масштабе. А после пересохранения объекта все начинает работать как надо.

Обратите внимание на строки:
Код
qDebug() << "obj found: " << searchObjInPoint(hmap, 200,180);

mapCommitObject(flag);
qDebug() << "obj found: " << searchObjInPoint(hmap, 200,180);

В этом фрагменте масштаб не меняется, но первый поиск говорит false (объект на находится), а второй поиск, после пересохранения, успешно находит объект!

То, что в основании флага поиск работает - это тоже понятно, проблема в том, что не находит в точке полотнища! точка (200, 180) как раз попадает в полотнище флага!

С уважением,
Матвеев П.В.
 
1. Свойства карты и объектов в процессе визуализации не должны изменяться. Все настройки нужно делать до начала работы информационной системы.
mapSetSiteScale в обычной программе не должен вызываться.

2. При смене масштаба карты и при смене масштаба отображения координаты в пикселах теряют смысл. Контрольные точки нужно фиксировать в метрах.
Но если меняется проекция/система координат, то контрольные точки фиксируют в геодезических координатах в WGS-84.

3. Пересохранение объекта (mapCommitObject) и перебор объектов не связаны. Скорее помимо сохранения меняются еще какие-то свойства карты, влияющие на отображение/поиск в точке.

4. Последовательность команд
 HSELECT select = mapCreateMapSelectContext(hmap);
 long res = mapWhatObjectBySelect(hmap, hobj, &frame, select, WO_FIRST | WO_VISUAL | WO_INMAP, PP_PLANE);

 избыточна. Поскольку HSELECT не используется. Достаточно одной функции mapWhatObject().
Страницы: 1
Читают тему (гостей: 1)



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

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