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

Владимир Егоров (Все сообщения пользователя)

Поиск  Пользователи  Правила  Войти
Форум » Пользователи » Владимир Егоров
Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 12 ... 21 След.
[MAPAPI] Рамка отображаемого знака объекта, [MAPAPI] Рамка отображаемого знака объекта не пересчитывается при изменении масштаба
 
Или вот ещё.

Функция [B]mapGetObjectContour [/B]- что она вообще считает ?

[CODE] // Определяет габариты объектов (точечных, векторных и подписей) с учетом текущих // 17/11/17
// условий отображения (см. функции mapGetRealShowScale/mapSetRealShowScale и
// mapGetScaleMethod/mapSetScaleMethod)
// Для каждого подобъекта подписи создается прямоугольный подобъект,
// ограничивающий текст подписи
// info    - исходный объект
// contour - объект, в который заносятся габариты исходного объекта
// hPaint  - идентификатор контекста отображения для многопоточного вызова функции
//           отображения (может быть ноль)
// При ошибке возвращает 0

_MAPIMP long int _MAPAPI mapGetObjectContour(HOBJ info, HOBJ contour, HPAINT hPaint);
[/CODE]
В том же примере вызвал эту функцию для объекта squad, потом распечатал метрику из объекта [B]contour [/B] (куда должны были записаться габариты объектов):
[CODE] rc = panorama::mapGetObjectContour(squadObj, contourObj,0);
   if (rc == 0){
       std::cerr << "can not get contour of squad" << std::endl;
   }else{
       long pc = mapPointCount(contourObj, 0);
       std::cout << "point count of contour:" << pc << std::endl;
       for (long i = 0; i< pc; i++){
           DOUBLEPOINT p;
           mapGetPlanePoint(contourObj, &p, i+1, 0);
           std::cout << "point[" << i+1 << "]= X:" << p.X << " Y:" << p.Y << std::endl;
       }
       mapCommitObject(contourObj);

   }

Вывод:
point count of contour:5
point[1]= X:3.68714e+07 Y:4.44749e+07
point[2]= X:3.68709e+07 Y:4.44758e+07
point[3]= X:3.68743e+07 Y:4.44778e+07
point[4]= X:3.68748e+07 Y:4.44769e+07
point[5]= X:3.68714e+07 Y:4.44749e+07
[/CODE]
А [B]mapObjectViewFrameEx [/B]вернул мне следующее (скопировал из дебаггера):
[CODE] viewFrame @0x7fffffffe320 DFRAME
X1 6152256.5999999996 double
X2 6155156.5999999996 double
Y1 7419153.5 double
Y2 7422053.5 double
[/CODE]
[MAPAPI] Рамка отображаемого знака объекта, [MAPAPI] Рамка отображаемого знака объекта не пересчитывается при изменении масштаба
 
[QUOTE]с 1:100000 до 1:50000 знаменатель масштаба уменьшился, а масштаб увеличился.[/QUOTE]
Ок, понял =)

[QUOTE]Даже если бы рамка и соответствовала размерам знака на экране, то Вам пришлось бы перемещать подписи при каждом изменении масштаба[B].[/B][/QUOTE]
Я именно этим и занимаюсь. У меня подписи входят в набор объектов, где родительский (GROUPLEADER) объект - это объект к которому относится подпись, а сама подпись - подчинённая (GROUPSLAVE). И при изменении масштаба я для всех групп объектов, у которых дочерние объекты привязаны к рамке объекта ( а не к точке из метрики) собирался в дочерних объектах редактировать метрику. Но посмотрев на то что рамка постоянная, написал сюда.


А каким-либо другим образом приделать подпись у Вас получилось? Поделитесь ?
[MAPAPI] Рамка отображаемого знака объекта, [MAPAPI] Рамка отображаемого знака объекта не пересчитывается при изменении масштаба
 
[QUOTE]Павел Матвеев написал:
(поэтому получается, что знак увеличиваться в размере при увеличении масштаба перестал, а рамка полученная при помощи mapObjectViewFrameEx  продолжает расти )[/QUOTE]
При уменьшении масштаба отображения  видимо Вы имели в виду ?

Рамка, полученная при помощи [B]mapObjectViewFrameEx [/B]не увеличивается и не уменьшается - она не меняется. [B]mapObjectViewFrameEx [/B]возвращает рамку в метрах в системе карты (плоские прямоугольные СК-42, например).
Визуальный эффект её увеличения связан с тем, что масштаб уменьшился (с 1:100000 до 1:50000, к примеру), и теперь рамка с размером 1494 x1494 метров (в СК-42) в пиксельных координатах занимает больше места.

Мне не нужны [QUOTE]реальные размеры знака[/QUOTE]
Мне нужно чтобы функции с таким описанием
[CODE] // Запрос/Пересчет габаритов изображения знака объекта (в метрах)
// info   - идентификатор объекта карты в памяти
// dframe - габариты изображения объекта в метрах
// force  - признак принудительного пересчета габаритов (необходимо установить,
//          если объект редактировался, но не записан на карту)
// При ошибке возвращает ноль

_MAPIMP long int _MAPAPI mapObjectViewFrameEx(HOBJ info, DFRAME *dframe,
                                             long int force);
_MAPIMP long int _MAPAPI mapObjectViewFrame(HOBJ info, DFRAME *dframe);[/CODE]действительно возвращали (пересчитывали) габариты изображения знака объекта (в метрах).

А так пока получается что я ни текстовую подпись вообще никаким способом к объекту не смогу приделать,
ни отрисовку объектов эффективно реализовать не смогу. Меня сейчас отрисовка даже больше волнует. Ведь на маленьких масштабах все мои потуги по обработке перемещений (редактирования) объектов вообще никакого смысла не имеют, вместо того чтобы перерисовать два небольших участка карты я получается перерисовываю почти всю карту (ту её часть, что отображается в нашем в приложении в текущий момент).
[MAPAPI] Рамка отображаемого знака объекта, [MAPAPI] Рамка отображаемого знака объекта не пересчитывается при изменении масштаба
 
Здравствуйте.

Делал подписи для объектов на пользовательских слоях, и чтобы подписи не наезжали на объекты решил
привязывать подпись к рамке знака объекта, а не к точке метрики.
Пока речь идёт только о подписях к точечным и векторным объектам.

Реализовал, результат меня не удовлетворил, потому-что рамка объекта после его создания не меняется.
Как я понял, рамка объекта (ObjectViewFrame) вычисляет один раз и таким образом , чтобы при любом масштабе

и любом повороте векторного объекта знак векторного объекта гаранитрованно вместился в рассчитанную рамку.

Пример.
Создаю векторный объект,  и линейный объект для отображения рамки, меняю масштаб карты.
(Местами используются namespace panorama:: - можно удалить, gis::coord::GisCoord::init()/deinit() - для указания путей к epsg файлам, а так почти на чистом mapapi пример получился).

[CODE]//карта из пакета gisdesigner с сайта
#define MAP_PATH "/home/vegorov/testsMaps/map/Podolsk/Podolsk.map"


//классификатор из пакета gisdesigner с сайта
#define RSC_PATH "/usr/share/gisdesigner/examples/Data/RSC/operator.rsc"


#define SQUAD_OBJ_KEY "312614004007" //векторный объект
#define BORDER_OBJ_KEY "111045000331" //красная жирная линия


void drawToFile(HMAP hmap, const char* filePath, int w, int h){
   XIMAGEDESC ximage;
   ximage.Depth = 16;
   ximage.CellSize = 2;
   //подбираем размеры как степени двойки
   ximage.Width = w;
   ximage.Height = h;
   ximage.RowSize = ximage.Width * ximage.CellSize;
   size_t bytesCount = ximage.Width * ximage.Height *
                    ximage.CellSize;
   ximage.Point = new char[bytesCount];
   ximage.Point = static_cast<char*>(
              memset(static_cast<void*>(ximage.Point), 0, bytesCount));
   DFRAME mapFrame;
   long rc = mapGetTotalBorder(hmap, &mapFrame, panorama::PP_PICTURE);
   if (rc == 0){
       std::cerr << "can not get border of map" << std::endl;
       delete []ximage.Point;
       std::exit(1);
   }
   int centerX = static_cast<int>((mapFrame.X1 + mapFrame.X2)/2.0);
   int centerY = static_cast<int>((mapFrame.Y1 + mapFrame.Y2)/2.0);
   QRect drawRect(QPoint(), QSize(w, h));
   drawRect.moveCenter(QPoint(centerX, centerY));
   RECT rect;
   rect.top = drawRect.top();
   rect.bottom = drawRect.top() + h;
   rect.left = drawRect.left();
   rect.right = drawRect.right() + w;
   rc = mapPaintToXImage(hmap, &ximage, 0, 0, &rect);
   if (rc == 0){
       std::cerr << "can not paint map to ximage" << std::endl;
       delete []ximage.Point;
       std::exit(1);
   }
   const uchar* buf = reinterpret_cast<const uchar*>(ximage.Point);

   QImage img(buf, static_cast<int>(w),
                   static_cast<int>(h),
                   static_cast<int>(ximage.RowSize),
              QImage::Format_RGB16);
   if (!img.save(QString(filePath), "PNG")){
       std::cerr << "can not save image to file" << std::endl;
       delete []ximage.Point;
       std::exit(1);
   };
   delete []ximage.Point;
   return;
}

bool appendBorder(HOBJ borderObj, DFRAME* viewFrame){
   long rc =mapAppendPointPlane(borderObj,viewFrame->X1, viewFrame->Y1, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapAppendPointPlane(borderObj,viewFrame->X2, viewFrame->Y1, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapAppendPointPlane(borderObj,viewFrame->X2, viewFrame->Y2, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapAppendPointPlane(borderObj,viewFrame->X1, viewFrame->Y2, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapAppendPointPlane(borderObj,viewFrame->X1, viewFrame->Y1, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   mapCommitObject(borderObj);
   return true;
}

bool updateBorder(HOBJ borderObj, DFRAME* viewFrame){
   long rc =mapUpdatePointPlane(borderObj,viewFrame->X1, viewFrame->Y1, 1, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapUpdatePointPlane(borderObj,viewFrame->X2, viewFrame->Y1, 2, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapUpdatePointPlane(borderObj,viewFrame->X2, viewFrame->Y2, 3, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapUpdatePointPlane(borderObj,viewFrame->X1, viewFrame->Y2, 4, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   rc =mapUpdatePointPlane(borderObj,viewFrame->X1, viewFrame->Y1, 5, 0);
   if (rc == 0){
    std::cerr << "can not append point to object Border" << std::endl;
    return false;
   }
   mapCommitObject(borderObj);
   return true;
}


int main(){

   if (!gis::coord::GisCoord::init()){
       std::cout << "can not init giscoord" << std::endl;
       return 1;
   }
   HMAP hmap = panorama::mapOpenData(MAP_PATH);
   if (hmap == 0){
       std::cerr << "can not open map" << MAP_PATH;
       return 1;
   }
   HSITE site = panorama::mapCreateAndAppendTempSite(hmap, RSC_PATH);
    if (site == 0){
        std::cerr << "can not create temp sit" << std::endl;
        return 1;
    }

   HOBJ squadObj = mapCreateSiteObject(hmap, site);
   if (squadObj == 0){
    std::cerr << "can not create object on temp site" << std::endl;
    return 1;
   }
   long rc = mapRegisterObjectByKey(squadObj, SQUAD_OBJ_KEY);
   if (rc == 0){
    std::cerr << "can not register object by key" << std::endl;
    return 1;
   }
   DFRAME mapFrame;
   rc = panorama::mapGetTotalBorder(hmap, &mapFrame, panorama::PP_GEO);
   if (rc == 0){
    std::cerr << "can not get frame of map" << std::endl;
    return 1;
   }
   double centerB = (mapFrame.X1 + mapFrame.X2)/2.0;
   double centerL = (mapFrame.Y1 + mapFrame.Y2)/2.0;
   double centerL2 = centerL + 0.00001;
   double centerB2 = centerB + 0.00001;
   rc = mapAppendPointGeo(squadObj, centerB, centerL);
   if (rc == 0){
    std::cerr << "can not append point to object Point" << std::endl;
    return 1;
   }
   rc = mapAppendPointGeo(squadObj, centerB2, centerL2);
   if (rc == 0){
    std::cerr << "can not append point to object Point" << std::endl;
    return 1;
   }
   mapCommitObject(squadObj);
   DFRAME viewFrame;
   rc = panorama::mapObjectViewFrameEx(squadObj, &viewFrame, 1);
   if (rc == 0){
       std::cerr << "can get object view frame" << std::endl;
   }
   HOBJ borderObj = mapCreateSiteObject(hmap, site);
   if (borderObj == 0){
    std::cerr << "can not create object text on temp site" << std::endl;
    return 1;
   }
   rc = panorama::mapRegisterObjectByKey(borderObj, BORDER_OBJ_KEY);
   if (rc == 0){
    std::cerr << "can not register text object by key" << std::endl;
    return 1;
   }
   if (!appendBorder(borderObj, &viewFrame)){
       return 1;
   }
   drawToFile(hmap, "map.png", 900, 600);
   double scale = mapGetRealShowScale(hmap);
   panorama::mapSetSiteScale(hmap, site, static_cast<long>(scale));
   scale *= 2.0;
   scale = mapSetRealShowScale(hmap, scale);
   rc = panorama::mapObjectViewFrameEx(squadObj, &viewFrame, 1);
   if (rc == 0){
       std::cerr << "can get object view frame" << std::endl;
   }
   if (!updateBorder(borderObj, &viewFrame)){
       return 1;
   }
   drawToFile(hmap, "map_scaled_up.png", 900, 600);
   scale /= 4.0;
   scale = mapSetRealShowScale(hmap, scale);
   rc = panorama::mapObjectViewFrameEx(squadObj, &viewFrame, 1);
   if (rc == 0){
       std::cerr << "can get object view frame" << std::endl;
   }
   if (!updateBorder(borderObj, &viewFrame)){
       return 1;
   }

   drawToFile(hmap, "map_scaled_down.png", 1500, 600);
   mapFreeObject(borderObj);
   mapFreeObject(squadObj);
   mapCloseData(hmap);
   gis::coord::GisCoord::deinit();
   return 0;
}
[/CODE]При приближении карты знак векторного объекта уменьшается, а рамка отображения нет - она значительно больше знака объекта (из-за чего кстати я при работе с объектами делаю много лишней работы по перерисовке обновлённых участков карты).

Изображения:
[URL=https://drive.google.com/open?id=1OTlWIxnGjyIUCCmOXNUaQEJWzahQzZ1F]map.png[/URL]
[URL=https://drive.google.com/open?id=1fcOZ7ws-HSbCSwdVioxc6IQ4MLonzACl]map_scaled_down.png[/URL]
[URL=https://drive.google.com/open?id=1GwHg4zPuEct90kfVvSf81BL1fzNrL1O5]map_scaled_up.png[/URL]

Каким способом можно обновить рамку знака объекта или вычислить актуальную ?
Изменено: Владимир Егоров - 21.11.2018 17:59:10
Убрать полосы прокрутки и отобразить карту целиком
 
[CODE]// -----------------------------------------------------------------------------
//  Переместить карту в заданную точку
// -----------------------------------------------------------------------------
int QDMapViewWindow::MoveMap(long int wparam, long int lparam)
{
 POINT PicturePoint;
 RECT rect = {0, 0};
 POINT * point = (POINT *)lparam;

 if (point == 0)
 {
   return 0;
 }

 MessageHandler(0, MT_MAPWINPORT, MWP_GETCLIENTRECT, (long int)&rect, 0);

 PicturePoint.X = point->x - (rect.RT + rect.LT)/2;
 PicturePoint.Y = point->y - (rect.DN + rect.UP)/2;

 SetPicturePoint(PicturePoint);

 return WM_MOVEDOC;
}
[/CODE]

В самом конце вызывается





[CODE] case MWP_SETPICTUREPOINT :

     // Установить координаты верхнего левого окна карты
     // Если окно только создано
     if (param == 0) return 0;
     point = (POINT *) param;
     if (point->x < 0)    x = 0;
     else                 x = point->x;
     if (point->y < 0)    y = 0;
     else                 y = point->y;
     HScrollBar->setValue(x);
     VScrollBar->setValue(y);

     // нужно ли перемещать карту?
     break;
[/CODE]
указатели на скроллбары разыменовываются без проверки (уже плохо)
а вы с ними как раз что-то делали (скрывали вроде, да ?). Возможно из-за этого и вылетает.
Изменено: Владимир Егоров - 16.11.2018 11:47:46
Как отобразить растры между картой и объектами на временной карте?
 
Мы сейчас используем mapPaintToXImage, соответственно придётся переписывать всё на вызов mapPaintByFrameToXImagePro (так как у него есть параметр erase), который требует рамку в метрах вместо пиксельных координат.

Вопрос только какими функциями отключать/включать отображение дополнительных слоёв и основной карты ?
К примеру - главная карта (векторная), на ней растровая карта (растровый слой) и некоторое количество пользовательских слоёв (с целями и другими пользовательскими объектами).

Чтобы программно добиться отображения целей над растром потребуется:
1) включить отображение всех данных.
2) отключить отображение всех пользоваельских слоёв.
3) отрисовать данные (можно даже обычным mapPaintToXImage ?? )
4) включить отображение всех данных.
5) отключить отображение главной карты (подложки) и всех слоёв не являющихся пользовательскими
6) отрисовать данные в тот же XImage что и в пункте 3

Так вот - какими функциями включать/отключать отображение слоёв/главной карты?

Как правильно вызвать mapPaintByFrameToXImagePro :

* можно ли не указывать рамку (ведь mapPaintToXImage достаточно заполненного XIMAGEDESC)?
* можно ли отдавать hpaint == 0 ?
* что означает параметр alpha ? (точнее - что означает использование/не использование альфа канала)


P.S. Я правильно понял и что тогда, в 15-ом году (три года назад), описанную моим предшественником в первом сообщении проблему можно было решить указанным сейчас способом с отрисовкой? (я тогда смогу исправить предыдущую версию нашего продукта, написанную на старой версии пакета gisdesigner).
Изменено: Владимир Егоров - 16.11.2018 11:52:09
Как отобразить растры между картой и объектами на временной карте?
 
Таки дошли.

Не совсем понятно - что за классификатор такой testshape.rsc? В примере Data/Shape/shape.sitx.

В классификаторе operator.rsc я не смог найти объект врезка карты с семантикой Графический файл или карта (просто врезка карты там есть)
В классификаторе service.rsc есть объект врезка карты с семантикой Графический файл или карта но отсутствует семантика масштаб карты.

Я правильно понял что для использования врезки карты как в примере Data/Shape/shape.sitx подойдёт только классификатор из этого же примера (testshapre.rsc) ??
Нарисовать сложные составной объект на карте
 
[QUOTE]И нужно ли удалять объект, который нам вернёт mapObjectSetFindGeneral(...) ???[/QUOTE]
Не нужно, я так понял что возвращается один из созданных внутри HOBJSET объектов, и при вызове mapFreeObjectSet все данные внутренние объекты будут удалены.

И судя по всему вызов mapBuildObjectSet добавляет в внутренний список тот объект который передаётся параметром, а для оставшихся объектов группы создаёт новые HOBJ, считывает в них объекты с карты и возвращает при вызове mapObjectSetObject
Нарисовать сложные составной объект на карте
 
Вообще, как я понял, группы объектов (HOBJSET) позволяют (с помощью использования служебных семантик) сохранять в карте (на пользовательских слоях, к примеру)   информацию о том, что объекты связаны.
Как вы их обрабатывать будете - уже ваши проблемы.

Ну то есть например - я хочу связать некоторый точечный объект и подпись (объект). Я могу создать группу и записать её в пользовательский слой (точечный объект - главный, подпись объект - подчинённый).

Затем, при очередном открытии пользовательского слоя я найду эту группу (в процессе загрузки объектов слоя) и где-то помечу для точечного объекта - что он главный. И при изменении метрики главного объекта я заодно изменю метрику подчинённого - подписи.
Причём для пользователя (который пользуется моим сервисом работы со слоями) будет виден только главный (точечный) объект, а подпись будет просто задаваться текстом при создании объекта. И редактировать (двигать) пользователь будет только точечный объект (главный). О реализации подписи в виде объекта с локализацией "подпись", входящего в состав группы, пользователь ничего знать не будет.


Поправьте меня если я не прав.
Нарисовать сложные составной объект на карте
 
И ещё мне не совсем понятны некоторые описания функций, например:

[CODE] // Найти главный объект в группе
// hobjset - указатель на набор объектов
// group - номер группы
//         при group = 0 - номер группы устанавливается из набора hobjset
// Объект HOBJ не нужно создавать !!!

_MAPIMP HOBJ _MAPAPI mapObjectSetFindGeneral(HOBJSET hobjset, long int group);
[/CODE]
В комментарии сказано  - "Объект HOBJ не нужно создавать !!!"

А как бы мы могли его создать если HOBJ нам возвращается ?
Мы же не передаём его внутрь.

И нужно ли удалять объект, который нам вернёт mapObjectSetFindGeneral(...) ???

То же самое в другой функции:

[CODE] // Запросить объект из набора по номеру (начиная с 1)
// Объект HOBJ не нужно создавать !!!
// hobjset - указатель на набора объектов
// number  - номер объекта из набора
// При ошибке возвращает 0

_MAPIMP HOBJ _MAPAPI mapObjectSetObject(HOBJSET hobjset, long int number);
[/CODE]
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 12 ... 21 След.



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

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