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

Мигание объекта из классификатора с помощью подсвечивания/изменения цвета

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: Пред. 1 2 3 4 След.
RSS
Мигание объекта из классификатора с помощью подсвечивания/изменения цвета
 

Здравствуйте!

Подготовили небольшой пример для демонстрации выделения объектов по слоям на стандартной карте Ногинск из состава инсталляции:
https://public.gisinfo.ru/Forum/test_example.zip
Дополнительно приводим код примера:
Код
#include <QApplication>
#include <QImage>

#include "qdmcmp.h"

#include "mapapi.h"
#include "maptype.h"

int main(int argc, char **argv)
{
  QApplication application(argc, argv);
  QDMapView();

  HMAP mapHandle = mapOpenMapUn(WTEXT("Noginsk/Noginsk.sit"));

  // Создать контекст поиска с выделением объектов по слоям из классификатора (topo200t.print.rsc) для открытой карты Ногинск
  HSELECT selectContext = mapCreateMapSelectContext(mapHandle);
  mapSelectLayer(selectContext, -1, 0);
  mapSelectLayer(selectContext, 8, 1);  // Слой 8 - "Дорожная сеть"
  mapSelectLayer(selectContext, 5, 1);  // Слой 5 - "Гидрография"

  double x1 = 6200000;  // в метрах
  double y1 = 7460000;
  double x2 = 6190000;
  double y2 = 7470000;

  // перевод в пиксели
  mapPlaneToPicture(mapHandle, &x1, &y1);
  mapPlaneToPicture(mapHandle, &x2, &y2);
  int paintWidthInPixels = abs(x2 - x1);
  int paintHeightInPixels = abs(y2 - y1);

  RECT drawRectInPixels;
  drawRectInPixels.left = x1;
  drawRectInPixels.top = y1;
  drawRectInPixels.right = x1 + paintWidthInPixels;
  drawRectInPixels.bottom = y1 + paintHeightInPixels;
  int paintDepthInBits = 32;

  char *paintMemory = AllocateTheMemory(paintWidthInPixels * paintHeightInPixels * paintDepthInBits / 8);
  if (paintMemory)
  {
    XIMAGEDESC xImageDesc;
    xImageDesc.Point = paintMemory;
    xImageDesc.Width = paintWidthInPixels;
    xImageDesc.Height = paintHeightInPixels;
    xImageDesc.Depth = paintDepthInBits;
    xImageDesc.CellSize = xImageDesc.Depth / 8;
    xImageDesc.RowSize = paintWidthInPixels * xImageDesc.CellSize;

    if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, selectContext, RGB(255, 0, 0)));
    {
      QImage image((uchar *)paintMemory, paintWidthInPixels, paintHeightInPixels, QImage::Format_RGB32);
      image.save("/tmp/out.png");
    }
  }
  FreeTheMemory(paintMemory);
  mapCloseData(mapHandle);

  return 0;
}
Пожалуйста, проверьте работу данного примера.

 
Здравствуйте!

Проверил работу примера. На устройстве было сгенерировано это изображение:

https://drive.google.com/file/d/1_fYYtXoICoJoLmnP0lZyQOoQY7wKQskc/view?usp=sharing

Перед строкой
Код
if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, selectContext, RGB(255, 0, 0)));
добавил строку
Код
mapSetViewSelect(mapHandle, selectContext);
В результате было сгенерировано это изображение:

https://drive.google.com/file/d/1ycq_WCfwXJcuPYwP4uCxnKn3pnJnhDzD/view?usp=sharing

Похоже, в приведенном вами примере ошибка не воспроизводится. Поэтому несколько изменил ваш пример:
Код
#include <QApplication>
#include <QImage>

#include "qdmcmp.h"

#include "mapapi.h"
#include "maptype.h"

int main(int argc, char **argv)
{
  QApplication application(argc, argv);
  QDMapView();

  //HMAP mapHandle = mapOpenMapUn(WTEXT("Noginsk/Noginsk.sit"));

#ifdef __arm__
  QString myStr("/home/spo-dl/tmp/Noginsk/Noginsk.sit");
#else
  QString myStr("/home/dmitry/experiments_panorama/highlight/from_panorama/Noginsk/Noginsk.sit");
#endif

  std::u16string myU16Str = myStr.toStdU16String();
  auto myU16Pc = myU16Str.c_str();
  const WCHAR* myPWC = (const WCHAR*)myU16Pc;



  HMAP mapHandle = mapOpenMapUn(myPWC);



  CREATESITE createsite;
  MAPREGISTER mapreg;
  LISTREGISTER sheet;

  memset(&createsite, 0, sizeof(CREATESITE));
  memset(&mapreg, 0, sizeof(MAPREGISTER));
  memset(&sheet, 0, sizeof(LISTREGISTER));

  // Получим информацию о базовой карте
  mapGetMapInfo(mapHandle, 1, &mapreg, &sheet);

  // Имя пользовательской карты
  strcpy(createsite.MapName, "Objects");

  // Скопируем в создаваемую пользовательскую карту
  createsite.Length = sizeof(createsite);
  createsite.MapType = mapreg.MapType;
  createsite.MaterialProjection = mapreg.MaterialProjection;
  //createsite.Scale = mapreg.Scale;
  createsite.Scale = 100000;
  createsite.FirstMainParallel = mapreg.FirstMainParallel;
  createsite.SecondMainParallel = mapreg.SecondMainParallel;
  createsite.AxisMeridian = mapreg.AxisMeridian;
  createsite.MainPointParallel = mapreg.MainPointParallel;

  char mapName[MAX_PATH_LONG];
  char rscName[MAX_PATH_LONG];


  // Разместить пользовательскую карту в том же каталоге рядом с базовой
  SplitThePath(mapGetMainMapName(mapHandle), 0, mapName, 0, 0);
  StrCopy(rscName, mapName, MAX_PATH_LONG);
  StrCat(mapName, "objects.sit", MAX_PATH_LONG);
  StrCat(rscName, "operator.rsc", MAX_PATH_LONG);

  // Создать пользовательскую карту и добавить к базовой
  HSITE hSite = mapCreateAndAppendSite(mapHandle, mapName, rscName, &createsite);
  if (hSite  == 0)
    return 0;


  // Создать контекст поиска с выделением объектов по слоям из классификатора (topo200t.print.rsc) для открытой карты Ногинск
  HSELECT selectContext = mapCreateMapSelectContext(mapHandle);
  mapSelectLayer(selectContext, -1, 0);
  mapSelectLayer(selectContext, 8, 1);  // Слой 8 - "Дорожная сеть"
  mapSelectLayer(selectContext, 5, 1);  // Слой 5 - "Гидрография"

  double x1 = 6200000;  // в метрах
  double y1 = 7460000;
  double x2 = 6190000;
  double y2 = 7470000;

  double midX = (x1+x2) / 2;
  double midY = (y1+y2) / 2;

  HOBJ hobj = mapCreateSiteObject(mapHandle, hSite);
  mapRegisterObject(hobj, 112010010, LOCAL_VECTOR);
  mapAppendPointPlane(hobj, midX, midY);
  mapCommitObject(hobj);

  HSELECT selectContext2 = mapCreateSiteSelectContext(mapHandle, hSite);
  mapSelectSampleByNumber(selectContext2, 1, mapGetObjectNumber(hobj));


  // перевод в пиксели
  mapPlaneToPicture(mapHandle, &x1, &y1);
  mapPlaneToPicture(mapHandle, &x2, &y2);

  int paintWidthInPixels = abs(x2 - x1);
  int paintHeightInPixels = abs(y2 - y1);

  RECT drawRectInPixels;
  drawRectInPixels.left = x1;
  drawRectInPixels.top = y1;
  drawRectInPixels.right = x1 + paintWidthInPixels;
  drawRectInPixels.bottom = y1 + paintHeightInPixels;

  int paintDepthInBits = 32;

  char *paintMemory = AllocateTheMemory(paintWidthInPixels * paintHeightInPixels * paintDepthInBits / 8);
  if (paintMemory)
  {
    XIMAGEDESC xImageDesc;
    xImageDesc.Point = paintMemory;
    xImageDesc.Width = paintWidthInPixels;
    xImageDesc.Height = paintHeightInPixels;
    xImageDesc.Depth = paintDepthInBits;
    xImageDesc.CellSize = xImageDesc.Depth / 8;
    xImageDesc.RowSize = paintWidthInPixels * xImageDesc.CellSize;

    mapSetViewSelect(mapHandle, selectContext);

    if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, selectContext2, RGB(0, 255, 255)));
    //if (mapPaintToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels));
    {
      QImage image((uchar *)paintMemory, paintWidthInPixels, paintHeightInPixels, QImage::Format_RGB32);
      image.save("/tmp/out.png");
    }
  }

  FreeTheMemory(paintMemory);

  mapCloseData(mapHandle);

  return 0;
}
Добавил добавление пользовательской карты и символа "Танк (общее обозначение)" из классификатора operator.rsc, цвет подсвечивания изменил на RGB(0, 255, 255). И ошибка воспроизвелась - на устройстве танк не подсветился:

https://drive.google.com/file/d/1ZIW4r3wlAkmh7vVjWGcogx52zlK9MU2h/view?usp=sharing
Изменено: Дмитрий - 09.03.2023 14:32:44
 

Переданный пример (когда в функцию mapPaintAndSelectToXImage передается HSELECT) предназначен для отрисовки выделенных объектов на одной (базовой) карте.
В случае, если открыто несколько карт, на одной из которых будут выделены объекты, необходимо выполнить следующее:
- добавить установку контекста поиска в соответствующую карту с помощью функции mapSetSiteSeekSelect (sitapi.h);
- установить поиск/выделение объектов только на этой карте с помощью функции mapSetTotalSeekMapRule (seekapi.h).

Ниже приводим обновленный пример, на основе описанных выше изменений (дополнительно упростили код примера). Пожалуйста, протестируйте и сообщите нам о результатах.

Код
#include <QApplication>
#include <QImage>

#include <ma th.h>

#include "qdmcmp.h"

#include "mapapi.h"
#include "maptype.h"

int main(int argc, char **argv)
{
  QApplication application(argc, argv);
  QDMapView();

  HMAP mapHandle = mapOpenMapUn(WS("Noginsk/Noginsk.sit"));

  CREATESITE createsite;
  MAPREGISTER mapreg;
  LISTREGISTER sheet;

  memset(&createsite, 0, sizeof(CREATESITE));
  memset(&mapreg, 0, sizeof(MAPREGISTER));
  memset(&sheet, 0, sizeof(LISTREGISTER));

  // Получим информацию о базовой карте
  mapGetMapInfo(mapHandle, 1, &mapreg, &sheet);

  // Имя пользовательской карты
  strcpy(createsite.MapName, "Objects");

  // Скопируем в создаваемую пользовательскую карту
  createsite.Length = sizeof(createsite);
  createsite.MapType = mapreg.MapType;
  createsite.MaterialProjection = mapreg.MaterialProjection;
  createsite.Scale = 100000;
  createsite.FirstMainParallel = mapreg.FirstMainParallel;
  createsite.SecondMainParallel = mapreg.SecondMainParallel;
  createsite.AxisMeridian = mapreg.AxisMeridian;
  createsite.MainPointParallel = mapreg.MainPointParallel;

  char mapName[MAX_PATH_LONG];
  char rscName[MAX_PATH_LONG];

  // Разместить пользовательскую карту в том же каталоге рядом с базовой
  SplitThePath(mapGetMainMapName(mapHandle), 0, mapName, 0, 0);
  StrCopy(rscName, mapName, MAX_PATH_LONG);
  StrCat(mapName, "objects.sit", MAX_PATH_LONG);
  StrCat(rscName, "operator.rsc", MAX_PATH_LONG);

  // Создать пользовательскую карту и добавить к базовой
  HSITE hSite = mapCreateAndAppendSite(mapHandle, mapName, rscName, &createsite);
  if (hSite  == 0)
      return 0;

  double x1 = 6200000;  // в метрах
  double y1 = 7460000;
  double x2 = 6190000;
  double y2 = 7470000;

  double midX = (x1+x2) / 2;
  double midY = (y1+y2) / 2;

  HOBJ hobj = mapCreateSiteObject(mapHandle, hSite);
  mapRegisterObject(hobj, 112010010, LOCAL_VECTOR);
  mapAppendPointPlane(hobj, midX, midY);
  mapCommitObject(hobj);

  HSELECT selectContext = mapCreateSiteSelectContext(mapHandle, hSite);
  // Поиск объекта по порядковому номеру
  mapSelectSampleByNumber(selectContext, 1, mapGetObjectNumber(hobj));
  // Установить контекст поиска пользовательской карты
  mapSetSiteSeekSelect(mapHandle, hSite, selectContext);
  // Ограничить поиск объектов только для первой пользовательской карты
  mapSetTotalSeekMapRule(mapHandle, 1);

  mapSetTotalSelectFlag(mapHandle, 1);

  // перевод в пиксели
  mapPlaneToPicture(mapHandle, &x1, &y1);
  mapPlaneToPicture(mapHandle, &x2, &y2);

  int paintWidthInPixels = abs(x2 - x1);
  int paintHeightInPixels = abs(y2 - y1);

  RECT drawRectInPixels;
  drawRectInPixels.left = x1;
  drawRectInPixels.top = y1;
  drawRectInPixels.right = x1 + paintWidthInPixels;
  drawRectInPixels.bottom = y1 + paintHeightInPixels;

  int paintDepthInBits = 32;

  char *paintMemory = AllocateTheMemory(paintWidthInPixels * paintHeightInPixels * paintDepthInBits / 8);
  if (paintMemory)
  {
    XIMAGEDESC xImageDesc;
    xImageDesc.Point = paintMemory;
    xImageDesc.Width = paintWidthInPixels;
    xImageDesc.Height = paintHeightInPixels;
    xImageDesc.Depth = paintDepthInBits;
    xImageDesc.CellSize = xImageDesc.Depth / 8;
    xImageDesc.RowSize = paintWidthInPixels * xImageDesc.CellSize;

    if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, 0, RGB(0, 0, 255)));
    {
      QImage image((uchar *)paintMemory, paintWidthInPixels, paintHeightInPixels, QImage::Format_RGB32);
      image.save("/tmp/out.png");
    }
  }

  FreeTheMemory(paintMemory);

  mapCloseData(mapHandle);

  return 0;
}

 
На примере ошибка исправилась. Спасибо.
 
Стал пытаться применить ваш совет к проекту, и у меня ничего не получилось. Вернулся к примерам, и обнаружил, что вами были удалены строки
Код
HSELECT selectContext = mapCreateMapSelectContext(mapHandle);
mapSelectLayer(selectContext, -1, 0);
mapSelectLayer(selectContext, 8, 1);  // Слой 8 - "Дорожная сеть"
mapSelectLayer(selectContext, 5, 1);  // Слой 5 - "Гидрография"
а также строка
Код
mapSetViewSelect(mapHandle, selectContext);
Получается, что ошибка перестала воспроизводиться из-за удаления этих строк, а не из-за добавления строк
Код
// Установить контекст поиска пользовательской карты
mapSetSiteSeekSelect(mapHandle, hSite, selectContext2);
// Ограничить поиск объектов только для первой пользовательской карты
mapSetTotalSeekMapRule(mapHandle, 1);
Вернул удаленные вами строки, и ошибка стала вновь воспроизводиться. На всякий случай, получившийся код примера:
Код
#include <QApplication>
#include <QImage>

#include "qdmcmp.h"

#include "mapapi.h"
#include "maptype.h"

int main(int argc, char **argv)
{
  QApplication application(argc, argv);
  QDMapView();

  //HMAP mapHandle = mapOpenMapUn(WTEXT("Noginsk/Noginsk.sit"));

#ifdef __arm__
  QString myStr("/home/spo-dl/tmp/Noginsk/Noginsk.sit");
#else
  QString myStr("/home/dmitry/experiments_panorama/highlight/from_panorama/Noginsk/Noginsk.sit");
#endif

  std::u16string myU16Str = myStr.toStdU16String();
  auto myU16Pc = myU16Str.c_str();
  const WCHAR* myPWC = (const WCHAR*)myU16Pc;



  HMAP mapHandle = mapOpenMapUn(myPWC);



    CREATESITE createsite;
    MAPREGISTER mapreg;
    LISTREGISTER sheet;

    memset(&createsite, 0, sizeof(CREATESITE));
    memset(&mapreg, 0, sizeof(MAPREGISTER));
    memset(&sheet, 0, sizeof(LISTREGISTER));

    // Получим информацию о базовой карте
    mapGetMapInfo(mapHandle, 1, &mapreg, &sheet);

    // Имя пользовательской карты
    strcpy(createsite.MapName, "Objects");

    // Скопируем в создаваемую пользовательскую карту
    createsite.Length = sizeof(createsite);
    createsite.MapType = mapreg.MapType;
    createsite.MaterialProjection = mapreg.MaterialProjection;
    createsite.Scale = 100000;
    createsite.FirstMainParallel = mapreg.FirstMainParallel;
    createsite.SecondMainParallel = mapreg.SecondMainParallel;
    createsite.AxisMeridian = mapreg.AxisMeridian;
    createsite.MainPointParallel = mapreg.MainPointParallel;

    char mapName[MAX_PATH_LONG];
    char rscName[MAX_PATH_LONG];

    // Разместить пользовательскую карту в том же каталоге рядом с базовой
    SplitThePath(mapGetMainMapName(mapHandle), 0, mapName, 0, 0);
    StrCopy(rscName, mapName, MAX_PATH_LONG);
    StrCat(mapName, "objects.sit", MAX_PATH_LONG);
    StrCat(rscName, "operator.rsc", MAX_PATH_LONG);

    // Создать пользовательскую карту и добавить к базовой
    HSITE hSite = mapCreateAndAppendSite(mapHandle, mapName, rscName, &createsite);
    if (hSite  == 0)
        return 0;

    // Создать контекст поиска с выделением объектов по слоям из классификатора (topo200t.print.rsc) для открытой карты Ногинск
    HSELECT selectContext = mapCreateMapSelectContext(mapHandle);
    mapSelectLayer(selectContext, -1, 0);
    mapSelectLayer(selectContext, 8, 1);  // Слой 8 - "Дорожная сеть"
    mapSelectLayer(selectContext, 5, 1);  // Слой 5 - "Гидрография"

    double x1 = 6200000;  // в метрах
    double y1 = 7460000;
    double x2 = 6190000;
    double y2 = 7470000;

    double midX = (x1+x2) / 2;
    double midY = (y1+y2) / 2;

    HOBJ hobj = mapCreateSiteObject(mapHandle, hSite);
    mapRegisterObject(hobj, 112010010, LOCAL_VECTOR);
    mapAppendPointPlane(hobj, midX, midY);
    mapCommitObject(hobj);

    HSELECT selectContext2 = mapCreateSiteSelectContext(mapHandle, hSite);
    // Поиск объекта по порядковому номеру
    mapSelectSampleByNumber(selectContext2, 1, mapGetObjectNumber(hobj));
    // Установить контекст поиска пользовательской карты
    mapSetSiteSeekSelect(mapHandle, hSite, selectContext2);
    // Ограничить поиск объектов только для первой пользовательской карты
    mapSetTotalSeekMapRule(mapHandle, 1);

    // перевод в пиксели
    mapPlaneToPicture(mapHandle, &x1, &y1);
    mapPlaneToPicture(mapHandle, &x2, &y2);

    int paintWidthInPixels = abs(x2 - x1);
    int paintHeightInPixels = abs(y2 - y1);

    RECT drawRectInPixels;
    drawRectInPixels.left = x1;
    drawRectInPixels.top = y1;
    drawRectInPixels.right = x1 + paintWidthInPixels;
    drawRectInPixels.bottom = y1 + paintHeightInPixels;

    int paintDepthInBits = 32;

    char *paintMemory = AllocateTheMemory(paintWidthInPixels * paintHeightInPixels * paintDepthInBits / 8);
    if (paintMemory)
    {
      XIMAGEDESC xImageDesc;
      xImageDesc.Point = paintMemory;
      xImageDesc.Width = paintWidthInPixels;
      xImageDesc.Height = paintHeightInPixels;
      xImageDesc.Depth = paintDepthInBits;
      xImageDesc.CellSize = xImageDesc.Depth / 8;
      xImageDesc.RowSize = paintWidthInPixels * xImageDesc.CellSize;

      mapSetViewSelect(mapHandle, selectContext);

      if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, selectContext2, RGB(0, 255, 255)));
      {
        QImage image((uchar *)paintMemory, paintWidthInPixels, paintHeightInPixels, QImage::Format_RGB32);
        image.save("/tmp/out.png");
      }
    }

    FreeTheMemory(paintMemory);

    mapCloseData(mapHandle);

    return 0;
}
В этом варианте примера танк не подсвечивается. Если закомментировать строку
Код
mapSetViewSelect(mapHandle, selectContext);
то будет подсвечиваться. Хотелось бы добиться того, чтобы все работало корректно в варианте с возвращением удаленных вами строк.
 
Эта же ошибка воспроизводится на десктопе с версией 12.6.2.13.
 
При установке условий поиска непосредственно в карту не нужно передавать контекст в вызываемую функцию:
Код
 if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, selectContext2, RGB(0, 255, 255))); 
Там должен быть ноль:
Код
 if (mapPaintAndSelectToXImage(mapHandle, &xImageDesc, 0, 0, &drawRectInPixels, 0, RGB(0, 255, 255))); 

И нужно включить выделение объектов по условиям поиска карт -
Код
  mapSetTotalSelectFlag(mapHandle, 1); 
 
В нашем проекте используются и другие контексты выделения - для скрытия объектов на пользовательской карте и для скрытия объектов основной карты. Будет ли все это адекватно работать, если применить ваш способ?
Изменено: Дмитрий - 13.03.2023 10:57:26
 
Должен ли работать предложенный вами способ с функцией mapDrawImageSelect? В нашем проекте используется функция mapDrawImageSelect, прямо перед ней написал предложенные вами строки, пятым аргументом установил 0. В результате перестали подсвечиваться объекты, которые до этого подсвечивались, а которые не подсвечивались - подсвечиваться не стали.
 
Цитата
Дмитрий написал:
Должен ли работать предложенный вами способ с функцией mapDrawImageSelect? В нашем проекте используется функция mapDrawImageSelect, прямо перед ней написал предложенные вами строки, пятым аргументом установил 0. В результате перестали подсвечиваться объекты, которые до этого подсвечивались, а которые не подсвечивались - подсвечиваться не стали.
Чтобы ответить на вопросы нужно видеть конкретный текст (фрагмент) программы.

Спасибо!
Страницы: Пред. 1 2 3 4 След.
Читают тему (гостей: 1)



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

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