Использую классификатор operator.rsc из ГИС Конструктор 13 в Astra Linux SE 1.6. Получилось сформировать условный знак в виде QImage.
Код
#include <QApplication>
#include <QImage>
#include <QPixmap>
#include <QDialog>
#include <QVBoxLayout>
#include <QLabel>
#include "rscapi.h"
#include "mapapi.h"
#include "maptype.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
const char *rscPath = "./operator.rsc";
HRSC hRsc = mapOpenRsc(rscPath);
HMAP hMap = mapCreateTempSite(rscPath);
int objNum = mapGetRscObjectCodeByKey(hRsc, "009991001015");
RSCOBJECT object;
mapGetRscObject(hRsc, objNum, &object);
COLORREF colorimage[256];
int colorcount = mapGetSiteColorsCount(hMap, hMap);
mapGetSitePalette(hMap, hMap, colorimage, colorcount);
int mapdepth = 32;
int cw=500;
int ch=500;
long allignwidth = cw * (mapdepth / 8 );
long size = allignwidth * ch;
char *bits = ::AllocateTheMemory(size);
XIMAGEDESC Ximagedesc;
Ximagedesc.Point = bits; // Адрес начала области пикселов
Ximagedesc.Width = cw; // Ширина строки в пикселах
Ximagedesc.Height = ch; // Число строк
Ximagedesc.Depth = mapdepth; // Размер элемента в битах (8,15,16,24,32)
Ximagedesc.CellSize = mapdepth / 8; // Размер элемента(пиксела) в байтах
Ximagedesc.RowSize = cw * Ximagedesc.CellSize;// Ширина строки в байтах
RECT Rect;
Rect.bottom = ch;
Rect.left = 0;
Rect.right = cw;
Rect.top = 0;
long func = mapGetRscObjectFunction(hRsc, objNum);
const char *param = mapGetRscObjectParameters(hRsc, objNum);
int val = mapPaintExampleObjectByFuncToXImage(hMap,
&Ximagedesc,
&Rect,
func,
param,
colorcount,
colorimage,
0,
object.Local);
QImage image((uchar *)bits, cw, ch, QImage::Format_RGB32);
QLabel *label = new QLabel;
label->setAutoFillBackground(true);
label->setAlignment(Qt::AlignCenter);
label->setScaledContents(true);
label->setPixmap(QPixmap::fromImage(image));
QDialog dlg;
dlg.setAutoFillBackground(true);
QPalette palette = dlg.palette();
palette.setColor(QPalette::Window, Qt::gray);
dlg.setPalette(palette);
QVBoxLayout layout;
layout.addWidget(label);
dlg.setLayout(&layout);
dlg.show();
int exitCode = app.exec();
mapCloseRsc(hRsc);
return exitCode;
}
Два вопроса:
1. Как задать произвольный размер условного знака ?
2. Как вывести условный знак по центру ? Я так понимаю это зависит от классификатора, точнее функции отрисовки конкретного знака. При просмотре классификатора через ГИС Оператор некоторые знаки смещены относительно центра. Как это изменить ?
Для управления масштабом знаков, рисуемых функциями типа "PaintExample" применяются следующий функции MAPAPI:
Код
// Установка процента масштаба отображения знака в окнах - примерах
// scale - масштаб отображения в % от 10 до 100 уменьшение, более 100 увеличение
_MAPIMP long int _MAPAPI mapSetRscExampleScale(HRSC hRsc, long int scale);
// Запрос процента масштаба отображения знака в окнах - примерах,
// от 10 до 100 уменьшение, более 100 увеличение
// При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGetRscExampleScale(HRSC hRsc);
Для отрисовки произвольных объектов с произвольной метрикой применяются функции типа PaintUserObject и PaintMapObject. Подвинуть растровое изображение в окне можно средствами Qt.
Oleg Belenkov написал: Для управления масштабом знаков, рисуемых функциями типа "PaintExample" применяются следующий функции MAPAPI:
Код
// Установка процента масштаба отображения знака в окнах - примерах
// scale - масштаб отображения в % от 10 до 100 уменьшение, более 100 увеличение
_MAPIMP long int _MAPAPI mapSetRscExampleScale(HRSC hRsc, long int scale);
// Запрос процента масштаба отображения знака в окнах - примерах,
// от 10 до 100 уменьшение, более 100 увеличение
// При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGetRscExampleScale(HRSC hRsc);
Для отрисовки произвольных объектов с произвольной метрикой применяются функции типа PaintUserObject и PaintMapObject. Подвинуть растровое изображение в окне можно средствами Qt.
После получения hRsc, выполняю:
Код
mapSetRscExampleScale(hRsc, 150)
Ничего не меняется, флажек остается прежних размеров.
Не совсем понимаю как использовать PaintUserObject
Код
// Отобразить произвольный объект в пределах фрагмента // в условных знаках пользователя в структуру XImage // imagedesc - структура XIMAGEDESC (см. maptype.h) // x,y - координаты левого верхнего угла внутри // rect - выводимый фрагмент карты в пикселах текущего изображения карты // image - описание вида объекта (см. mapgdi.h), // data - координаты объекта, // place - вид системы координат (в точках экрана - PP_PICTURE, в метрах в // системе координат документа - PP_PLANE, в радианах на эллипсоиде // документа - PP_GEO) // При ошибке в параметрах возвращает ноль _MAPIMP long int _MAPAPI mapPaintUserObjectToXImage(HMAP hMap, XIMAGEDESC * imagedesc, long int x, long int y, RECT * rect, PAINTPARM * image, PLACEDATA * data, long int place);
Как заполнить PAINTPARM и PLACEDATA. И как мне это поможет в задании размера флажка ?
Но на самом деле меняется не размер флажка, а только "область" содержащая его (светло-серый фон). А как задать размер самого флажка ?
И в чем сакральный смысл отрисовки флажка в левом нижнем углу, а не по центру ? Хотя некоторые другие знаки рисуются по центру. В данном случае средствами Qt подвинуть изображение не получится, т.к. нет информации о том какую область занимает знак.
Проверили работу функции mapSetRscExampleScale на последней версии ГИС Конструктор с сайта. Размер знака в данном примере менялся согласно установленному значению процента. Примеры заполнения структур PAINTPARM и PLACEDATA можно посмотреть в исходных текстах библиотеки компонентов (/usr/share/gisdesigner/examples/Source/) в файлах qdmwina.cpp и qdmactpt.cpp.
Константин Ганюшин написал: Проверили работу функции mapSetRscExampleScale на последней версии ГИС Конструктор с сайта. Размер знака в данном примере менялся согласно установленному значению процента.
Запросить базовый размер условного знака можно, например, следующими функциями:
Код
// Запросить размеры в микронах и свойства принтерного вида объекта
// hRsc - идентификатор классификатора карты
// incode - порядковый номер объекта (с 1)
// IMAGESIZE - структура входных данных (см. maptype.h)
// Строка string длиной length задается для
// определения горизонтального размера подписи
// При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGetRscPrnImageSize(HRSC hRsc, long int incode, IMAGESIZE * imagesize, long int length = 0,char * string = 0);
// Запросить габаритную рамку изображения объекта (точечный, векторный)
// с учетом поворота объекта (IMAGEFRAME - см. maptype.h)
// Все размеры в микронах на "бумажном" изображении (в базовом масштабе)
// относительно первой точки метрики объекта в картографической системе
// Для пересчета полученных координат в метры на местности нужно
// их поделить на 1 000 000, умножить на базовый масштаб карты
// и добавить координаты первой точки метрики
// number - номер функции отображения (mapgdi.h)
// param - параметры отображения (mapgdi.h)
// angle - угол поворота объекта в радианах по часовой стрелке
// При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGetRscMarkFrame(HRSC hRsc, long int number, const char * param, double angle, IMAGEFRAME * imageframe);
Если установить процент увеличения знака, равным 200, то размер образца знака (paintExample) будет вдвое больше.
Примерный пересчет из мкм в пикселы экрана в базовом масштабе карты можно выполнить с помощью макросов из mapgdi.h:
Код
// Операции пересчета пикселов в микроны и обратно
#define MKMINPIX 250 // 1000 * 25.4 / 96 = 264.583333
#define PIX2MKM(pixel) ((pixel) * MKMINPIX)
#define MKM2PIX(metric) ((int)((metric) / MKMINPIX))
или с помощью функций MAPAPI (мкм нужно перевести в метры - делить на 1 000 000):
Код
// Пересчет через текущие параметры экрана
// из метров экрана в пикселы и обратно
_MAPIMP long int _MAPAPI mapScreenMeter2Pixel(double metric);
_MAPIMP double _MAPAPI mapScreenPixel2Meter(long int pixel);