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

Проблема с отрисовкой векторного объекта на HDC

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1 2 След.
RSS
Проблема с отрисовкой векторного объекта на HDC
 
Доброго времени суток! Стоит задача нарисовать векторный объект не на карте, а на обычном HDC. С IMG_LINE никаких проблем нет. Перевожу толщину линии в пиксели и рисую по заданным точкам. Не могу понять принцип работы структуры IMG_VECTOREX. Выбираю объект из hRsc по внутреннему коду ( incode). Далее привожу к выбранному типу:  
Код
if(IMG_VECTOREX)
{
     _imgvectpoint = *(IMGVECTOREX*)res;
}
Далее хочу по точкам, которые хранятся в классификаторе нарисовать сам объект.
Код
POINT *points = new POINT[_imgvectpoint.Desc.Count];
for(int i = 0; i < _imgvectpoint.Desc.Count; i++)
{
     points[i].x = MKM2PIX(_imgvectpoint.Desc.Point[i].Hor);
     points[i].y = MKM2PIX(_imgvectpoint.Desc.Point[i].Ver);
}
Иногда получаются в массиве нормальные значения( в пределах 100 пикселей), а иногда выскакивают странные значения типа ~1500000. Пробовал еще сделать следующим образом:
Код
_descPoint = &(_imgvectpoint.Desc);
if(_descPoint->Type == 7)
{
     IMGCIRCLE *_circleParm = (IMGCIRCLE*)(_descPoint->Parm);;
}
int _delta = _descPoint->Length - 4;

_point = (IMGVECTPOINT*)((char*)(&(_descPoint->Point[0])) + _delta);

for (int i = 0; i < _imgvectpoint.Desc.Count; i++)
{
    int x = MKM2PIX(_point[i].Hor);
    int y = MKM2PIX(_point[i].Ver);
}
Но там та же проблема.
Объясните, пожалуйста, что я делаю не так?
 
Добрый день!
Я не вижу текста выше. Векторный знак не всегда имеет параметры типа IMGVECTOREX. Часто параметры лежат в структуре IMGDRAW.

IMGVECTOREX * vectorex;
IMGPOLYDESC *  desc;
IMGVECTPOINT * point;

// if(IMG_VECTOREX)  // Это условие всегда выполнится как "true" (условие ошибочно)
if (function == IMG_VECTOREX)
{
//     _imgvectpoint = *(IMGVECTOREX*)res;  // По отношению к параметрам  IMGVECTOREX, IMGDRAW так делать не рекомендуется - параметры имеют переменную длину
  vectorex = (IMGVECTOREX *)res;
  desc = &(vectorex->Desc);
  point = &(desc->Point);

  // Следующая запись IMGPOLYDESC находится так
  desc = (IMGPOLYDESC *)(point + desc->Count);
  point = &(desc->Point);
}
 
Исправил, но это не помогло, все равно в массиве точек появляются странные значения, намного отличающиеся от экранных координат.
Код
IMGVECTOREX *_vectorex;
IMGPOLYDESC *_desc;
IMGVECTPOINT *_point;
_hRsc = _mapOpenRsc("C:\\Program Files\\Panorama\\Panorama11\\Data\\Seamap\\S57NAVY.RSC");
_incode = _mapGetRscObjectKeyIncode(_hRsc,"HRBFAC_P4");
result = _mapGetRscObjectFunction(_hRsc,_incode);
const char* res = _mapGetRscObjectParameters(_hRsc,_incode);
if(result == IMG_VECTOREX)
            {
                _vectorex = (IMGVECTOREX*)res;
                //Начало первого фрагмента
                _desc = &(_vectorex->Desc);
                _point = _desc->Point;
                //IMGVECTPOINT *_point_arr = (_descPoint->Point);
                for (int i = 0; i < _vectorex->Desc.Count; i++)
                {
                    int x = MKM2PIX(_point[i].Hor);
                    int y = MKM2PIX(_point[i].Ver);
                }
            }
 
Координаты x и y являются относительными.

Если  необходимо отображать карту, то

1. У векторного объекта есть собственные координаты:

DOUBLEPOINT point;
mapGetMapPlanePoint(info, &point, 1, 0);

2. Координаты преобразовать к экранным пискелям

mapPlaneToPicture(map, &point.X, &point.Y);

3. Конечные координаты примитивов векторного знака вычисляются примерно так:

point.X + PosH + x;
point.Y + PosV + y;
 
1. Не подходит, потому что я не работаю с картой, а работаю только с классификатором.
2. По той же причине
3. Если я правильно понял, то point.x и point.y находятся опять же на карте.
Мне нужны точки (правила) построения векторного знака в классификаторе, чтобы я мог нарисовать их winapi функциями (polypolygon или polypolyline) на обычном hDc, а не на карте
 
Тогда возращаемся к началу: координаты x и y являются относительными.

Конечные координаты примитивов векторного знака вычисляются примерно так:
...
x = MKM2PIX(_point[i].Hor);
y = MKM2PIX(_point[i].Ver);

pixelX = centerX + _vectorex->PosH + x;
pixelY = centerY + _vectorex->PosV + y;

где
centerX, centerY - координаты центра окна.
pixelX, pixelY - координаты точек для polyline.
 
Смотрите, есть карта Seamap/ca39995i.sit . Она входит с стандартный пакет поставки Panorama. Есть классификатор s57navy.rsc который тоже входит в стандартный пакет поставки.
1) С помощью функции mapGetRscObjectKeyIncode( hRsc, “boylat_p1) получаем внутренний код объекта в классификаторе. Он равен 165, так?
2) С помощью функции mapGetRscObjectFunction(hRsc, incode) получаем номер функции отображения. Для данного объекта он равен 149, так? То есть то векторный объект imgvectorex, так?
3) С помощью функции res = mapGetRscObjectParameters( hRsc, incode) получаем сами параметры отображения, так?
4) Далее

IMGVECTOREX *vectorex;

IMGPOLYDESC *desc;

IMGVECTPOINT *point;

vectorex = (IMGVECTOREX*)res;// получили заполненную структуру. В поле Count лежит число фрагментов, описывающих знак,так? В данном примере оно равно 5, т.е знак состоит из 5 примитивов.

desc = &(vectorex->desc);// получили  указатель на первый примитив, так?

point = desc->point;// получили указатель на массив точек из которых можно нарисовать Часть объекта,так?

POINT *points = new POINT[vectorex->Desc.count];// count= 600, то есть первый примитив сострит из 600 точек, так?

for(int i = 0; i < vectorex->Desc.count; i ++)

{

        points[i].x = MKM2PIX(point[i].Hor);

        points[i].y = MKM2PIX(point[i].Ver);

}

Так вот ,

при i = 0, (x,y) = (0;25)

При i = 1 , (x,y) = (31;4)

При i = 2 , (x,y) = (4;17989(!!!))

При i = 3 , (x,y) = (-1.07374e+06(!!!); 0)

Почему такие значения получаются?

 
Я немного ошибся. Структура IMGPOLYDESC имеет переменную длину.
Код
typedef struct IMGPOLYDESC       // Для (149) описание цепочки
{                                //      (size = 12 + 8*Count + Length)
  unsigned char  Type    ;       // Тип цепочки (VT_SQUARE, ...)
                                 // для выделения блока VT_OBJECT,
                                 // VT_SUBJECT, VT_END)
  unsigned char  Image   ;       // Тип параметров
                                 // (IMG_SQUARE, IMG_LINE, IMG_DOT,
                                 // IMG_VECTORTEXT)              
  unsigned short Length  ;       // Длина параметров (>= 4)
  unsigned int   Parm    ;       // Параметры цепочки по ее типу
  unsigned int   Count   ;       // Число точек в цепочке
  IMGVECTPOINT   Point[1];       // Координаты до 512 точек
}
  IMGPOLYDESC;
В описании структуры поле "Parm" правильнее было бы написать: Parm[1], чтобы программист видел, что это поле переменной длины. Именно поэтому я ошибся в прежнем описании. Ниже я привожу пример с учетом настоящего поля переменной длины "unsigned int   Parm".
Код
desc = &(vectorex->desc);// получили  указатель на первый примитив

// Число точек
unsigned int * pointCount = (unsigned int*)((char*)&(desc->Parm) + desc->Length; // Пропустить параметры
count = *pointCount;

// Пропустить поле desc->Count
point = (IMGVECTPOINT*)(pointCount+1);

desc->Length зависит от длины параметров:

Если desc->Image = IMG_SQUARE, то desc->Length = 4 = sizeof(IMGSQUARE)
Если desc->Image = IMG_LINE, то desc->Length = 8 = sizeof(IMGLINE)
Изменено: Александр Кружков - 20.12.2017 12:13:12 (Уточнено)
 
У меня получилось нарисовать часть векторного объекта через WinApi. Получилось нарисовать нормально только примитив vt_line. Возникла проблема с vt_circle, но решил ее следующим образом: там дается 2 точки x1,y1 и x2,y2. Если из координат первой точки вычесть координаты второй(правильно ли это?) ,  то получится центр круга, дальше вычисляем радиус и рисуем. Но проблема, которую я не могу решить заключается в vt_arc и в vt_revert_arc. Как нарисовать эти примитивы через WinApi?
 
Приведу описание структуры:
Код
typedef struct IMGVECTPOINT      // Для (149) описание точки объекта
{                                //      ( size = 8 )
  int Hor;                       // Координаты от точки привязки
  int Ver;                       // вправо и вниз в соответствии
                                 // с типом цепочки:
                                 //                Центр  Радиусы  Точки начала и окончания
                                 // Circle, Round  (h,v)  (dh,dh)
                                 // Ellipse, Oval  (h,v)  (dh,dv)
                                 // Arc,      Pie  (h,v)  (dh,dv)        (h1,v1)  (h2,v2)
}
  IMGVECTPOINT;
Примерный текст для получения параметров окружности, эллипса, дуги (продолжение текста от 20.12.2017 11:51:32):
Код
...

// Пропустить поле desc->Count
point = (IMGVECTPOINT*)(pointCount+1);

// Центр окружности (эллипса, дуги)
centerX = point->Hor;
centerY = point->Ver;
point++;

// Радиусы окружности (эллипса, дуги)
radiusH = point->Hor;
radiusV = point->Ver;
point++;

// Точка начала дуги (сектора)
arcX1 = point->Hor;
arcY1 = point->Ver;
point++;

// Точка конца дуги (сектора)
arcX2 = point->Hor;
arcY2 = point->Ver;
Страницы: 1 2 След.
Читают тему (гостей: 1)



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

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