Причем такое решение вопроса к сожалению не подходит.
Цитата
Такая возможность имеется - для этого Вам нужно создать в классификаторе объект с видом "Графический знак". Обычно классификатор предварительно подготавливают для работы в настольных продуктах для Windows: ГИС Панорама, ГИС Панорама Мини, Панорама Редактор (доступны для скачивания на нашем сайте: https://gisinfo.ru/download/download.htm) Для этого используется задача "Редактор классификатора".
Все виды графических примитивов описаны в файле mapgdi.h. Например:
Код
#define IMG_GRAPHICMARK 165 // Знак из файла (ВМР, Metafile )
typedef struct IMGGRAPHICMARKEX // (165) ТОЧЕЧНЫЙ ЗНАК - ГРАФИЧЕСКОЕ ИЗОБРАЖЕНИЕ
{ // (size = 312)
int Length; // Полная длина записи описания объекта
int Ident; // Идентификатор считанного изображения = 0
char Name[256]; // Имя файла изображения
int Type; // Тип файла (1 - BMP, 2 - JPEG, 3 - Metafile)
int Height; // Габариты знака (высота, ширина)
int Width; //
int PosH; // Точка привязки знака по горизонтали
int PosV; // и вертикали (от начала габаритов знака)
int Shift; // Смещение тени
IMGLINE Contour; // Параметры контура
char ContourFlag; // Флаг наличия контура
char ShadeFlag; // Флаг наличия тени
char TransparentFlag; // Флаг прозрачности фонового цвета
// (первый пиксел картинки - левый нижний угол BMP)
char Reserve[13]; // Резерв
}
IMGGRAPHICMARKEX;
Для Linux пока реализована поддержка файла BMP, который должен размещаться рядом с файлом RSC.
Изменить параметры отображения в принтерном виде можно функцией:
Код
// Установить принтерный вид объекта
// hRsc - идентификатор классификатора карты
// incode - порядковый номер объекта
// length - длина параметров
// number - номер функции отображения
// param - указатель на параметры функции
// При ошибке возвращает ноль , иначе порядковый номер объекта
_MAPIMP long int _MAPAPI mapSetRscPrintObjectImage(HRSC hRsc,
long int incode,long int length,long int number,char * param);
Для этого нужно объявить структуру IMGGRAPHICMARKEX, заполнить ее и передать ее адрес в функцию:
В поле Name структуры IMGGRAPHICMARKEX указывается имя файла без пути к файлу. Параметр hRsc может быть получен при открытии классификатора. Параметр incode может быть получен по классификационному коду объекта и локализации или по ключу объекта в классификаторе.
Подскажите пожалуйста, какими значениями мне заполнить структуру IMGGRAPHICMARKEX, с именем файла я поняла, а вот дальше не очень понятно и все ли поля являются обязательными в этой структуре?
Цитата
Параметр incode может быть получен по классификационному коду объекта и локализации или по ключу объекта в классификаторе.
Приведите пожалуйста пример, пока не понятно, как получить incode.
У меня же этого объекта еще нет в классификаторе, а как раз таки я его хочу добавить туда. Поясните пожалуйста.
Повторюсь, задача заключается в добавлении собственного изображения в классификатор (для последующего его использования).
Если в структуре есть поле, то в нем всегда будет какое-то значение. После объявления переменной типа структура ее можно обнулить (memset), а затем установить значения в соответствии с назначением поля.
Для создания в классификаторе нового объекта есть функция:
Код
// Создать объект
// RSCOBJECT - структура входных данных (см. maptype.h)
// hRsc - идентификатор классификатора карты
// При ошибке возвращает ноль , иначе порядковый номер объекта (с 1)
_MAPIMP long int _MAPAPI mapAppendRscObject(HRSC hRsc, RSCOBJECT * object);
Возвращаемое функцией mapAppendRscObject значение и будет "incode" объекта.
Но прикладная программа, как правило, не создает и не редактирует классификатор, который должен создаваться заблаговременно средствами Редактора классификатора на основании бумажного документа с кодами и изображениями знаков и описанием их атрибутов, утвержденного Заказчиком. Удобнее это сделать в программе Панорама Мини.
Спасибо за ответ. Относительно Панорамы Мини мы учтем. Но на данный момент есть все же желание разобраться, как добавлять свое изображение в классификатор в программе.
Добавила объект из классификатора, а затем применила метод изменяющий его внешний вид. В результате ничего не изменилось.
Код
HRSC myHrsc = mapGetRscIdent(hmap, hsite);
std::cout<<"myHrsc = "<<myHrsc<<std::endl;
IMGGRAPHICMARKEX parm;
memset((char*)&parm, 0, sizeof(parm));
strcpy(parm.Name, "test.bmp"); // изображение в папке, где собирается проект
parm.Type = 1;
parm.Height = 32;
parm.Width = 32;
parm.Length = sizeof(parm);
parm.PosV = 16;
parm.PosH = 16;
parm.TransparentFlag = 1;
if(listKeyObj.isEmpty()) return;
int answ = mapSetRscPrintObjectImage(myHrsc,listKeyObj.first(),sizeof(IMGGRAPHICMARKEX), IMG_GRAPHICMARK, (char *)&parm);
std::cout<<"answ = "<<answ<<std::endl;
Уточните, пожалуйста, каким способом Вы осуществляете проверку того, что классификатор изменился? В качестве варианта проверки внесенных изменений можно перенести полученный классификатор в Windows и открыть вид измененного объекта в задаче "Редактор классификатор" в одном из настольных продуктов (например, Панорама Мини).
Здравствуйте! Как я поняла, применив метод mapSetRscPrintObjectImage на карте я должна увидеть вместо стандартного значка из классификатора собственное изображение в формате bmp.
Уточните пожалуйста, есть ли возможность, все-таки программно добавить собственное изображение в классификатор (не используя панораму мини).
Александр Савелов написал: В качестве варианта проверки внесенных изменений можно перенести полученный классификатор в Windows и открыть вид измененного объекта в задаче "Редактор классификатор" в одном из настольных продуктов (например, Панорама Мини).
Мы обсуждаем именно программный способ редактирования классификатора. В данном случае Панорама Мини предлагалось использовать в качестве удобного средства для проверки полученного результата.
Возможные причины некорректного поведения в приведенном Вами коде: - исходя из приведенного текста, не очевидно, что в качестве первого параметра в функцию mapSetRscPrintObjectImage передается порядковый номер объекта в классификаторе (incode). Пример получения incode можно посмотреть в примере rscedit из состава ГИС Конструктор. - в конце операций по редактированию классификатора необходимо вызвать функцию mapCloseRsc - иначе внесенные Вами изменения останутся только в памяти программы и не попадут на диск.
Примечание: для того, чтобы можно было полноценно оценить корректность Вашего кода, лучше привести автономный пример, который можно скомпилировать и запустить. В этом случае исчезнут неоднозначности, связанные, например, с переменной listKeyObj.
1) К сожалению в последнем установленном мной пакете ГИС КОНСТРУКТОР для Qt Designer X64 НЕТ примера rsedit. В связи с этим можете пожалуйста привести пример получения incode или ссылку, где можно скачать этот проект. 2) Объясните пожалуйста, что должен выполнять этот метод mapSetRscPrintObjectImage? Как я понимаю он ничего не меняет в самом классификаторе, а просто заменяет его отображения в текущий момент.
Код
- в конце операций по редактированию классификатора необходимо вызвать функцию mapCloseRsc - иначе внесенные Вами изменения останутся только в памяти программы и не попадут на диск.
Ваш совет не помог. Изображения по прежнему свое не вижу. Получение listKeyObj описано ниже:
Код
// Добавление объекта на карту
void MainWindow::on_pushButton_3_clicked()
{
HOBJ hObj = mapCreateSiteObject(hmap, hsite, IDDOUBLE2); // создаём пустой объект на карте (контейнер)
std::cout<<"hObj = "<<hObj<<std::endl;
// Зарегистрировать новый объект, как линейный
mapRegisterObject(hObj, 53160000, LOCAL_POINT);
mapAppendPointPlane(hObj, 6170267, 7411269, 0); // добавляем точку метрики
mapCommitObject(hObj); // записываем на карту
int i = mapObjectKey(hObj); // Получение уникального номра, добавленого объекта
listKeyObj.append(i);
std::cout<<"unique key obj = "<<i<<std::endl;
mapFreeObject(hObj); // освобождаем контейнер
ui->viewMap->Repaint(); // переписовка
}
3) Уточните, как заполнить структуру RSCOBJECT при создании объекта в классификаторе. Пожалуйста приведите пример.
1) Привожу исходный текст rscedit, в котором показан пример программного создания описания объекта в классификаторе (линейного, площадного и точечного) и изменения описания объекта (площадного). 2) Метод mapSetRscPrintObjectImage изменяет именно принтерный вид объекта в классификаторе. В структуре listKeyObj хранится порядковый номер объекта в карте, а не в классификаторе - это две разные сущности. 3) Для разных типов объектов структура RSCOBJECT заполняется в приведенном примере.
Код
HRSC rscHandle = mapOpenRsc(rscPath);
long int totalObjectCount = mapGetRscObjectCount(rscHandle);
printf("Число объектов в классификаторе: %d\n", totalObjectCount);
RSCOBJECT newObject;
memset( &newObject, 0, sizeof(newObject) );
// Создать линейный объект
newObject.Code = 10000;
newObject.Segment = 7;
newObject.Length = sizeof(RSCOBJECT);
newObject.Local = LOCAL_LINE;
StrCopy(newObject.Name, "NewLine", sizeof(newObject.Name));
IMGLINE lineParm;
lineParm.Color = 0xFF;
lineParm.Thick = 512;
long int incode = mapAppendRscObject(rscHandle, &newObject);
long int isImageSet = mapSetRscObjectImage(rscHandle, incode, sizeof(IMGLINE), IMG_LINE, (char*)&lineParm);
if (incode && isImageSet)
printf("Добавлен линейный объект с порядковым номером: %d\n", incode);
else
printf("Не удалось добавить линейный объект\n");
// Создать площадной объект
newObject.Code = 10001;
newObject.Segment = 7;
newObject.Length = sizeof(RSCOBJECT);
newObject.Local = LOCAL_SQUARE;
strcpy(newObject.Name, "NewSquare");
IMGPOLYGONGLASS polyParm;
polyParm.Color = 0xFF0000;
polyParm.Bright = -10;
polyParm.Contrast = +5;
polyParm.Transparency = 100;
incode = mapAppendRscObject(rscHandle, &newObject);
isImageSet = mapSetRscObjectImage(rscHandle, incode, sizeof(IMGPOLYGONGLASS), IMG_POLYGONGLASS, (char*)&polyParm);
if (incode && isImageSet)
printf("Добавлен площадной объект с порядковым номером: %d\n", incode);
else
printf("Не удалось добавить площадной объект\n");
// Создать точечный объект
newObject.Code = 10002;
newObject.Segment = 7;
newObject.Length = sizeof(RSCOBJECT);
newObject.Local = LOCAL_POINT;
strcpy(newObject.Name, "NewPoint");
IMGMULTIMARK multiMarkParm;
multiMarkParm.Count = 1;
multiMarkParm.Length = sizeof(IMGMULTIMARK) + multiMarkParm.Count*sizeof(IMGMARKCHAIN);
multiMarkParm.Size = PIX2MKM(32);
multiMarkParm.PosH = 0;
multiMarkParm.PosV = 0;
IMGMARKCHAIN markChainParm;
markChainParm.Color = 0xFF0000;
memset(markChainParm.Bits, 0, sizeof(markChainParm.Bits));
memset(&markChainParm.Bits[48], 0xFF, 8 * 4); // нарисовать линию толщиной 8п
char *multiMarkParmTotal = new char[multiMarkParm.Length];
memcpy(multiMarkParmTotal, (char*)&multiMarkParm, sizeof(multiMarkParm));
memcpy(multiMarkParmTotal + sizeof(IMGMULTIMARK), (char*)&markChainParm, sizeof(markChainParm));
incode = mapAppendRscObject(rscHandle, &newObject);
isImageSet = mapSetRscObjectImage(rscHandle, incode, multiMarkParm.Length, IMG_MULTIMARK, multiMarkParmTotal);
if (incode && isImageSet)
printf("Добавлен точечный объект с порядковым номером: %d\n", incode);
else
printf("Не удалось добавить точечный объект\n");
delete [] multiMarkParmTotal;
totalObjectCount = mapGetRscObjectCount(rscHandle);
printf("Число объектов в классификаторе: %d\n\n", totalObjectCount);
// Изменить внешний вид объекта
printf("Изменение внешнего вида объекта \"Кварталы плот.застр.круп.гор.\"\n", totalObjectCount);
incode = mapGetRscObjectCodeByKey(rscHandle, "S0045111000");
const char *drawParm = mapGetRscObjectParameters(rscHandle, incode);
IMGSQUARE squareDrawParm = *((IMGSQUARE*)drawParm);
printf("Цвет объекта до изменения: 0x%x\n", squareDrawParm.Color);
squareDrawParm.Color = 0xFF0000;
mapSetRscObjectImage(rscHandle, incode, sizeof(IMGSQUARE), IMG_SQUARE, (char*)&squareDrawParm);
drawParm = mapGetRscObjectParameters(rscHandle, incode);
squareDrawParm = *((IMGSQUARE*)drawParm);
printf("Цвет объекта после изменения: 0x%x\n", squareDrawParm.Color);
mapCloseRsc(rscHandle);