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

Рисование эллипса на карте

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
Рисование эллипса на карте
 
Доброе утро.
Подскажите пожалуйста, как нарисовать эллипс на карте?
В одной беседе (http://gisweb.ru/forum/forum7/topic8230/messages/?PAGEN_1=2) товарищ упоминал об эллипсе как о части векторного знака IMG_VECTOREX.
Как рисовать векторные знаки IMG_VECTOREX, не нашёл ни на форуме, ни в примерах.
Буду рад примерам в виде кода.
Использую ГИС конструктор для QT Designer, ОС Ubuntu.
 
Здравствуйте!

Про рисование графических объектов можно посмотреть в разделе "3.6.7 Отображение и печать объектов карты и графических объектов" документа "Руководство программиста" ГИС Конструктор для Qt Designer, доступного на нашем сайте: http://gistoolkit.ru/download/doc/gisdesigner_prog.pdf
 
Ознакомился с выше упомянутым разделом.
Попытался нарисовать пунктирную линию.
За основу взял пример myfirst, в качестве карты использовал карту Подольска.
В итоге получился следующий код:
Код
    PAINTPARM Form;         // Вид объекта на экране
    IMGDOT Image;              // Описание пунктирной линии
    PLACEDATA Place;        // Описание координат объекта (double)

    MyMap  =  this->ui.DMapView1->GetMapHandle();

    Form.Image = IMG_DOT;
    Form.Parm  = (char *)&Image;
    Form.Mode  = R2_XORPEN;

    Image.Color = RGB(255,0,0);
    Image.Thick = PIX2MKM(2);    //
    Image.Dash  = PIX2MKM(7);    //
    Image.Blank = PIX2MKM(3);    //

    int PointCount = 2;        //
    DOUBLEPOINT * Points = new DOUBLEPOINT[PointCount];
    Points[0].x = 6166368;
    Points[0].y = 7416920;
    Points[1].x = 6170679;
    Points[1].y = 7424867;

    Place.Count = 1;           // Объект состоит из одной части
    Place.PolyCounts = &PointCount;
    Place.Points = Points;

    RECT* rectDraw = new RECT();
    rectDraw->left = ( long int ) this->ui.DMapView1->geometry().left();
    rectDraw->top  = ( long int ) this->ui.DMapView1->geometry().top();
    rectDraw->right  = ( long int ) this->ui.DMapView1->geometry().right();
    rectDraw->bottom = ( long int ) this->ui.DMapView1->geometry().bottom();
    long int width = abs(rectDraw->right - rectDraw->left);
    long int height = abs(rectDraw->top - rectDraw->bottom);

    int MAPDEPTH = 32;
    int BMCELLSIZE = MAPDEPTH / 8;
    size_t size = width * BMCELLSIZE * height;

    char* BitMap = AllocateTheMemory(size);

    XIMAGEDESC ximagedesc;
    ximagedesc.Point     = BitMap;
    ximagedesc.Width     = ( long int ) ( rectDraw->right - rectDraw->left );
    ximagedesc.Height    = ( long int ) ( rectDraw->top - rectDraw->bottom);
    ximagedesc.Depth     = 32;
    ximagedesc.CellSize  = 4;
    ximagedesc.RowSize   = ( long int ) ( width * ximagedesc.CellSize );

    mapPaintUserObjectToXImage(MyMap, &ximagedesc, 0,
                               0, rectDraw, &Form,
                               &Place, PP_PLANE);

    this->ui.DMapView1->UpdatePictureBorderForAll();
    this->ui.DMapView1->repaint();
К сожалению, на текущий момент ничего не отрисовывается.
Возникли следующие вопросы:
1. Как данный код превратить в отрисовку эллипса?
2. Откуда на самом деле надо брать параметры MAPDEPTH, BMCELLSIZE, BitMap, CellSize?
3. В каком слое производится отрисовка?
4. Как потом обращаться к нарисованному объекту, чтобы можно было его изменить\удалить?
 
Здравствуйте!

По поводу отображения пунктирной линии:
- в функцию mapPaintUserObjectToXImage координаты отображаемого прямоугольника должны подаваться в пикселах (дополнили описание функции). Пересчет можно выполнить следующим образом:
Код
  // Сформировать прямоугольник отрисовки в пикселах
  DOUBLEPOINT leftTop;
  leftTop.x = 6168000;
  leftTop.y = 7416000;
  mapPlaneToPicture(mapHandle, &leftTop.x, &leftTop.y);

  DOUBLEPOINT rightBottom;
  rightBottom.x = 6166000;
  rightBottom.y = 7425000;
  mapPlaneToPicture(mapHandle, &rightBottom.x, &rightBottom.y);

  RECT* rectDraw = new RECT;
  rectDraw->left = leftTop.x;
  rectDraw->top  = leftTop.y;
  rectDraw->right  = rightBottom.x;
  rectDraw->bottom = rightBottom.y;
- небольшая опечатка в примере при заполнении XIMAGEDESC:
Код
ximagedesc.Width     = width;
ximagedesc.Height    = height;
 
Доброе утро.
Александр, благодарю Вас за ответы.
На текущий момент научился рисовать эллипс "в лоб":
Код
 this->MyMap = this->ui.DMapView1->GetMapHandle();
 this->hMapper = mapCreateAndAppendTempSite(MyMap, "./map/Topo100t.rsc");

 HOBJ ellipseObj = mapCreateSiteObject(this->MyMap, this->hMapper, IDDOUBLE2, 0);
 mapRegisterDrawObject(ellipseObj, 21, LOCAL_LINE);
 
 IMGSQUARE square;
 square.Color = RGB( _redValue, _greenValue, _blueValue );
 mapAppendDraw( ellipseObj, IMG_SQUARE, reinterpret_cast<const char*>(&square) );
 
 double A, dA;
 dA = M_PI / 180.0;
 A = 0.0;
 double buferX, buferY, newX, newY;
double radAngle = degreeAngle / 180.0 * M_PI;
while (A <= 2 * M_PI)
{
    // Вычисление координат точки эллипса.
    buferX = _rb * cos(A) + _centerX;
    buferY = -_ra * sin(A) + _centerY;

    // Поворот точки эллипса на заданный угол.
    newX = ( buferX - _centerX ) * cos(radAngle) - ( buferY - _centerY ) * sin(radAngle) + _centerX;
    newY = ( buferX - _centerX ) * sin(radAngle) + ( buferY - _centerY ) * cos(radAngle) + _centerY;

    // Добавление точки.
    mapAppendPointPlane(ellipseObj, newX, newY);

    A = A + dA;
}

mapCommitObject(ellipseObj);

ui.DMapView1->UpdatePictureBorderForAll();
ui.DMapView1->repaint();

Возникли следующие вопросы:
1. В какой слой добавляется эллипс на самом деле? В методе mapRegisterDrawObject я
   указываю слой 21 (В моём случае это заполняющие знаки). При этом если с помощью QDMapSelectDialog убрать какой-нибудь другой слой,
   а слой 21 оставить, то эллипс всё равно пропадает.
2. Начиная с определённого масштаба эллипс перестаёт рисоваться в силу своей малости. Как определить программно, что эллипс перестал рисоваться?
3. При закрытии карты эллипс не сохраняется. Как его сохранить на карте?
P.S. Теоретический вопрос - чем пользовательские карты (*.sit) отличаются от не пользовательских (*.map).
P.P.S. Существует ли учебник или методическое пособие по ГИС конструктору?
          Или кроме того, что выложено на сайте, больше ничего нет?
 
Здравствуйте!

1. Сам графический объект добавляется в тот слой, который Вы ему указали в параметрах функции. В данном случае диалог состава отображения (который вызывается с помощью компонента QDMapSelectDialog) выставляет флаг, указывающий на то, чтобы при выборе объектов для отображения, пропускать графические объекты.
Данное поведение можно модифицировать, если после вызова диалога "Состав отображения" выполнить следующий код:
Код
HMAP mapHandle = ui.DMapView1->GetMapHandle();
  HSELECT viewSelect = mapCreateSiteSelectContext(mapHandle, mapHandle);
  mapGetViewSelect(mapHandle, viewSelect);
  mapSetDrawObjectsFlag(viewSelect, 0);
  mapDeleteSelectContext(viewSelect);
Описание функций можно посмотреть в заголовочном файле seekapi.h.
Соответственно создание и удаление контекста поиска можно выполнять единоразово, чтобы не перевыделять память.

2. Запросить/установить диапазон масштабов отображения знака можно с помощью следующих функций (mapapi.h):
Код
 // Запросить/Установить диапазон масштабов видимости объекта
 // scale - масштаб отображения от 1:1 до 1:40 млн.
 // info - идентификатор объекта карты в памяти


_MAPIMP long int _MAPAPI mapObjectTopScale(HOBJ info);
_MAPIMP long int _MAPAPI mapSetObjectTopScale(HOBJ info, long int scale);
_MAPIMP long int _MAPAPI mapObjectBotScale(HOBJ info);
_MAPIMP long int _MAPAPI mapSetObjectBotScale(HOBJ info, long int scale);

3. Исходя из исходного кода, объект наносится на временную карту, а специфика временной карты состоит в том, что ее файлы удаляются после закрытия карты.
В качестве вспомогательного материала можно посмотреть 3.6.17 "Создание графических объектов на карте" Руководства программиста (http://gistoolkit.ru/download/doc/gisdesigner_prog.pdf)

У карты формата MAP есть ограничивающая рамка, у SIT - нет рамки (карта безразмерная).

Перечень материалов для изучения ГИС Конструктор:
- Руководство программиста, Руководство системного программиста, Типовая программа и методика испытаний (доступны на нашем сайте: https://gisinfo.ru/download/doc.htm#28);
- тестовые примеры, входящие в инсталляцию;
- Руководство по применению и перечень функций MAPAPI (доступны на нашем сайте: https://gisinfo.ru/download/doc.htm#18);
- описание функций в заголовочных файлах;
- поиск решений типовых задач на форуме.
 
Добрый день, Александр.
Благодарю за ответы.
 
Добрый день! Подскажите пожалуйста, есть ли все-таки метод, который позволяет рисовать элипс с заданием большой полуоси, малой полуоси в метрах и угла наклона)?
 
Цитата
Александр Савелов написал:
Здравствуйте!

Графический вид "эллипс" с указанными Вами параметрами добавим и оповестим Вас о выходе новой версии.
Спасибо!
Т.е на текущий момент такого функционала у вас нет, как понимаю?
 
В новую версию добавлена функция:
Код
 // Построить эллипс по двум точкам и параметрам полуосей
 // Координаты точек в метрах в системе документа
 // centre - координаты центра эллипсоид в метрах на местности
 // bigaxis - большая полуось в метрах на местности
 // littleaxis - малая полуось в метрах на местности
 // angle - угол поворота большой полуоси в радианах против часовой стрелки
 //         от направления на восток
 // count - число точек метрики (от 16 до 128)
 // Создаваемому объекту присваивается признак отображения сплайном,
 // что позволяет минимизировать число точек метрики
 // При ошибке возвращает ноль

_MAPIMP long int _MAPAPI mapBuildEllpse(HOBJ info, DOUBLEPOINT * center, double bigaxis, double littleaxis,
                                        double angle, long int count);

Кроме того, отображение эллипса встроено элементом в векторные знаки.
Страницы: 1
Читают тему (гостей: 2)



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

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