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

Перемещение одного и группы объектов

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1
RSS
Перемещение одного и группы объектов, Перемещение одного и группы объектов
 
Добрый день, господа разработчики!

Мой вопрос заключается в следующем, при добавлении объекта из классификатора т.е. после того как я выполнил выбор необходимого объекта
нужно, чтобы он тянулся за курсором мыши прям как в ГИС "Панорама" и аналогично при перемещении группы объектов.

Мои данные: пишу на С# с использованием Gis ToolKit 12

Это код при добавлении объекта из классификатора:
Код
private void ToolStripMenuItem13_Click(object sender, EventArgs e) // Добавление объекта на карту из класификатора
        {
            if (!MapSelectObjectRsc.ExecuteForMapObj(MapObj.C_CONTAINER, true)) return;
            MapSelectObjectRsc.RestoreEnabled = false;
            MapEditMetric.MetEditMode = TxEditMode.emCreate;
            MapSelectObjectRsc.Show();
 
              if (MapObj.Local == TxObjectLocal.OL_VECTOR) // Если был выбран векторный объект
            {
                ObjStyle = 8;
                ObjExCode = MapObj.ExCode;
                MapEditMetric.StartAction();
           }
}
 
private void MapEditMetric_OnExecute(object sender, EventArgs e)
{
          if (ObjStyle == 8)
            {
               MapObj.SetObjectByExcode((int)TxMetricType.IDFLOAT2, ObjExCode, (int)TxObjectLocal.OL_VECTOR);
               MapObj.CommitObjectAsNew();
        MapView.Refresh();
     }
}


Это код при перемещении группы объектов выделенных по области;
Код
ШАГ 1. ВЫПОЛНЯЮ ВЫДЕЛЕНИЕ ОБЪЕКТОВ ПО ОБЛАСТИ
 
private void MapSelectRect_OnDoRect(object sender, EventArgs e)
        {
            ObjCopyFind.Clear();
 
            TxColorRef aColor = new TxColorRef
            {
                Red = 255
            };
            MapFind.cMapSelect.SiteNumber = 0; // основная карта
            MapFind.cMapSelect.UnselectSeekArea(-1); // сбросим область если была
            MapView.ViewSelect.MapSites[1] = false;
            MapView.ViewSelect.MapSites[2] = false;
            MapView.ViewSelect.MapSites[3] = false;
            MapFind.cMapSelect.Layers[47] = false;
            MapFind.cMapSelect.MapSites[1] = false;
           MapFind.cMapSelect.MapSites[2] = false;
            // создать объект ограничивающий область
            MapObj.CreateNullObj(0);
            MapPoint.PlaceInp = TxPPLACE.PP_PLANE;
            // установить метрику объекта (замкнутый объект, последняя точка должна совпадать с первой)
            MapPoint.SetPoint(MapSelectRect.SelectedRect.X1, MapSelectRect.SelectedRect.Y1);
            MapObj.Metric.Append(0, MapPoint.C_CONTAINER);
            MapPoint.SetPoint(MapSelectRect.SelectedRect.X1, MapSelectRect.SelectedRect.Y2);
            MapObj.Metric.Append(0, MapPoint.C_CONTAINER);
            MapPoint.SetPoint(MapSelectRect.SelectedRect.X2, MapSelectRect.SelectedRect.Y2);
            MapObj.Metric.Append(0, MapPoint.C_CONTAINER);
            MapPoint.SetPoint(MapSelectRect.SelectedRect.X2, MapSelectRect.SelectedRect.Y1);
            MapObj.Metric.Append(0, MapPoint.C_CONTAINER);
            MapPoint.SetPoint(MapSelectRect.SelectedRect.X1, MapSelectRect.SelectedRect.Y1);
            MapObj.Metric.Append(0, MapPoint.C_CONTAINER);
            MapFind.Active = false;
            MapFind.FindPoint = false;
            // установить параметры выделения объектов по области
            MapFind.cMapSelect.SelectSeekArea(0, MapFind.cMapObj.C_CONTAINER, 0, 1, 2, 1, 1);
            MapFind.Active = true;
            // выделяем объекты на карте
            MapView.SetObjSelected(MapFind.cMapSelect, aColor, true);
            MapFind.first();
            while (!MapFind.Eof)
            {
                //создаем копию выделенных объектов
                int hobj = Program.Distance.mapCreateCopyObject(MapFind.cMapView.MapHandle, MapObj.ObjHandle);
                ObjCopyFind.Add(hobj);
                MapFind.Next();
            }
        }
 
 
Шаг 2. ВЫБИРАЮ ПЕРЕМЕЩЕНИЕ ОБЪЕКТОВ
 
if (ObjCopyFind.Count != 0)
            {
                _currentWorkState = MapEvents.moveObjectFindArea;
            }
 
 
 
ШАГ 3. ВЫПОЛНЯЮ ПЕРЕМЕЩЕНИЕ ОБЪЕКТОВ ВЫДЕЛЕННЫХ ПО ОБЛАСТИ
 
case MapEvents.moveObjectFindArea: // перемещение объектов выделенных по области
 
                    //получаем координаты точки отжатия в метрах
                    MouseXY.SetPoint(MapView.MapLeft + e.x, MapView.MapTop + e.y);
                    MouseXY.GetPoint(ref x3, ref y3);
                   
                    //вычисляем смещение между точками нажатия мыши
                    delta.X = x3 - alfa.X;
                    delta.Y = y3 - alfa.Y;
 
                    int type = Program.Distance.mapLogReadActionForUndo(MapView.MapHandle, 0, 1); //выполняет запрос на получение номера последней транзакции
                    Program.Distance.mapLogCreateAction(MapView.MapHandle, 0, type++); // открывает журнал транзакций на запись
                    MapView.Rendering = false;
                    for (int k = 0; k <= ObjCopyFind.Count - 1; k++)
                    {
                        //записываем копии выделенных объектов в MapObj1
                        MapObj1.ObjHandle = ObjCopyFind[k];
                        MapObj1.CommitAsNew();
                        //перемещаем копии выделенных объектов на величину delta
                        Program.Distance.mapRelocateObject(MapView.MapHandle, MapObj1.ObjHandle, ref delta, 3);
                        MapObj1.Commit();
                        MapObj1.Repaint();
                    }
                    //удаляем копии выделенных объектов
                    MapFind.first();
                    while (!MapFind.Eof)
                    {
                        MapObj.Delete();
                        MapObj.ObjHandle = 0;
                        MapView.Refresh();
                        MapFind.Next();
                    }
                    Program.Distance.mapLogCommitAction(MapView.MapHandle, 0);
                    MapView.Rendering = true;
                    MapView.Repaint();
                    _currentWorkState = MapEvents.objFree;
                    MapFind.cMapSelect.Clear(); // Сброс всех условий для текущей карты
                    MapView.SetObjSelected(null, new TxColorRef(), true); // Снять выделение с объектов на карте после группового выделения
                    MapView.AdjustData();
                    ObjCopyFind.Clear();
                    break;

Хочу заметить, что код работает отлично, но хотелось бы еще и видеть как добавляемые и перемещаемые мной объекты тянутся за курсором мыши))
Может ВЫ еще и параллельно и по коду что то подскажите поправить)  
 
К сожалению, компонент MapEditMetric работает только с одним объектом, поэтому воспользоваться им для перемещения группы объектов не получится.
Но реализовать придется примерно то, что этот компонент делает.
Исходный код этого компонента есть в составе GIS ToolKit и GIS ToolKit Active (см. mapedmet.pas).

Суть сводится к тому, чтобы:
1. в самом начале перемещения выполнить временную отрисовку всех перемещаемых объектов;
2. на перемещение мыши выполнить (на каждое событие OnMapMouseMoveкомпонента MapView):
2.1. стирание объектов на старом месте
2.2. рисование их на новом
3. по окончании перемещения - стереть временную отрисовку и выполнить сохранение объектов.

В целом это практически то, что Вы реализовали в "Шаге 3", только выполнять это надо на каждое смещение мыши (OnMapMouseMove) не сохраняя объекты.
Выполнить отрисовку объекта, в том числе не сохраненного физически на карте, можно с помощью метода axMapObj.PaintObjectUp.
Со стиранием сложнее.
Компонент MapEditMetric рисует объект графической функцией, используя параметры с инверсным рисованием (R2_NOT, см. axMapObj.Parm), что позволяет стереть объект просто повторно нарисовав его же на том же месте.
При обработке множества объектов такой подход, скорее всего, вызовет артефакты при отрисовке и стирании, поэтому стирать изображение отрисованных поверх карты объектов будет проще путем перерисовки всей карты целиком (или фрагмента, где перемещаемые объекты).
Использование метода Repaint компонента MapView вызовет мерцание, если вызывать его на перемещение мыши.
Поэтому использовать лучше компонент MapScreen, который является наследником MapView, но имеет два буфера - поверх одного Вы рисуете, содержимым второго стираете.
Замена MapView на MapScreen никак не должна повлиять на работу остальных компонентов.
Страницы: 1
Читают тему (гостей: 1)



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

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