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

Умное масштабирование

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: Пред. 1 2 3 След.
RSS
Умное масштабирование, масштабирование участка над которым курсор мышки
 
Цитата
Andrey Gheleznyakov пишет:
Вообще то вы поставили себе задачу - координаты мыши не менять. Тогда зачем новые координаты мыши?



От координат точки в пикселах в новом масщтабе х,у надо отнять положение мыши, где она была (как в пункте 1) и присвоить полученные значения

mapView->SetMapLeftTop

Попробовал два варианта, вычитание из новых x,y старых x,y(в примере x2,y2) которые взяты как координаты мыши + GetMapLeftTop и второй пример которые взяты только как координаты мыши. Не работают оба варианта?
Код
      long int x=QCursor::pos().x();
      long int y=QCursor::pos().y();

      int valx=0, valy=0;
      mapView->GetMapLeftTop(&valx, &valy);
      x+=valx;
      y+=valy;
      
      int x2 = x;
      int y2 = y;

      mapChangeViewScale(mapView->GetMapHandle(),&x,&y,2);
      int diffX = x - x2;
      int diffY = y - y2;
      mapView->SetMapLeftTop(diffX, diffY);


и

Код
      long int x=QCursor::pos().x();
      long int y=QCursor::pos().y();

      int x2 = x;
      int y2 = y;

      int valx=0, valy=0;
      mapView->GetMapLeftTop(&valx, &valy);
      x+=valx;
      y+=valy;
      

      mapChangeViewScale(mapView->GetMapHandle(),&x,&y,2);
      int diffX = x - x2;
      int diffY = y - y2;
      mapView->SetMapLeftTop(diffX, diffY);


Но я так понимаю что надо как-то учитывать что масштаб поменялся? Помогите:)
 
long int x=QCursor::pos().x();
     long int y=QCursor::pos().y();

     int x2 = x;
     int y2 = y;

     int valx=0, valy=0;
     mapView->GetMapLeftTop(&valx, &valy);
     x+=valx;
     y+=valy;
     

     mapChangeViewScale(mapView->GetMapHandle(),&x,&y,2);
после вызова функции х у имеют новые значения для нового масштаба

     x = x - x2;
     y = y - y2;

     mapView->SetMapLeftTop(x, y);
 
Цитата
Andrey Gheleznyakov пишет:
long int x=QCursor::pos().x();

     long int y=QCursor::pos().y();

     int x2 = x;
     int y2 = y;

     int valx=0, valy=0;

     mapView->GetMapLeftTop(&valx, &valy);

     x+=valx;
     y+=valy;
 

     mapChangeViewScale(mapView->GetMapHandle(),&x,&y,2);

после вызова функции х у имеют новые значения для нового масштаба

     x = x - x2;

     y = y - y2;

     mapView->SetMapLeftTop(x, y);
Не работает этот вариант, Мне кажется проблема в том что нельзя просто из x вычесть x2 так как это координаты в разных масштабах или надо устанавливать leftTop не с помощью SetMapLeftTop а с помощью mapapi. Но вообщем не работает почему-то?
Изменено: Андрей Аксенов - 31.03.2014 13:44:21
 
Что означает "не работает"?
Если координаты x и y (QCursor::pos()) заданы в окне карты (а не в экране)
и Вы хотите, чтобы при масштабировании текущая точка на экране осталась
на месте, то все корректно.

Более универсальный вариант:
1. Пересчитать полученную точку в метры (после сложения) - mapPictureToPlane.
2. Изменить масштаб (как в примере).
3. Пересчитать точку обратно в пикселы - mapPlaneToPicture.
4. Вычесть x2, y2 (как в примере).
5. Установить координат угла (как в примере).
 
Цитата
Oleg Belenkov пишет:
Что означает "не работает"?
Если координаты x и y (QCursor::pos()) заданы в окне карты (а не в экране)
и Вы хотите, чтобы при масштабировании текущая точка на экране осталась
на месте, то все корректно.

Карта смещается. Если изменять масштаб на левом углу карты подольска, где начинается сама карты а не серое обрамление,  то сама карта смещается правее, и курсор мыши после масштабирования указывает на серую часть карты.
Там у меня ошибка, должно быть не:
Код
long int x=QCursor::pos().x();
long int y=QCursor::pos().y();

а
Код
QPoint mousePos = QCursor::pos();
mousePos = mapView->mapFromGlobal(mousePos);
long int x = mousePos.x();
long int y = mousePos.y();

В этом случае x и y такие же как если бы они приходили от сигнала SignalMousePress объекта QDMapView. Я так понимаю Вы это имели ввиду когда написали что координаты должны быть в окне карты.
После исправления карта смещается вправо как я написал выше.

Попробую другой вариант что Вы описали.
 
Без обид, но второй вариант тоже не работает.
Может у меня руки кривоваты, но я взял Ваш пример myfirst и код в функции void MainForm1::GreateScale():
Код
void MainForm1::GreateScale()
{
   int scale =  ui.DMapView1->GetViewScale();

   ui.DMapView1->SetViewScale(scale / 2);
}


заменил на

Код
void MainForm1::GreateScale()
{
    QPoint mousePos = ui.DMapView1->mapFromGlobal(QCursor::pos());

    long int x=mousePos.x();
    long int y=mousePos.y();

    int x2 = x;
    int y2 = y;

    int valx=0, valy=0;
    ui.DMapView1->GetMapLeftTop(&valx, &valy);

    x+=valx;
    y+=valy;

    mapChangeViewScale(ui.DMapView1->GetMapHandle(),&x,&y,2);

    x = x - x2;
    y = y - y2;

    ui.DMapView1->SetMapLeftTop(x, y);
}

Код который как Вы написали должен работать. Эффект такой же как и в разрабатываемом мною приложении.
После трех масштабирований:

И еще такой результат что карта уезжает вправо всегда и ее уже не возможно проскролировать затем обратно, чтобы посмотреть другие участки карты.
 
Для решения вашего вопроса надо после
mapChangeViewScale(ui.DMapView1->GetMapHandle(),&x,&y,2);
DMapView1->UpdatePictureBorder;

Вызов функции необходим потому, что Вы воспользовались АПИ функцией ГИС ядра для изменения масштаба. При изменении масштаба изменяются габариты района отображения, а визуальный компонент об этом не знает (вызов АПИ работает в обход компонента).

На Delphi код следующий

  valx := mvmap.MapLeft;
  valy := mvmap.MapTop;
  valx := valx + x;
  valy := valy + y;
  mvmap.Rendering := false; // чтобы не моргало при перерисовке
  mapChangeViewScale(mvmap.MapHandle,valx,valy,2);
  mvMap.UpdatePictureBorder;
  mvmap.MapLeft := valx - x;
  mvmap.MapTop := valy - y;
  mvmap.Rendering := true;
  mvmap.Repaint;
 
Огромное Вам человеческое спасибо!
Заработало как хотелось.
 
Цитата
KFF написал:
procedure TMainForm.ScreenMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var  fX, fY: Double;
begin
 with Screen.ScreenToClient(MousePos) do Origin.SetPoint(X+Screen.MapLeft,Y+Screen.MapTop);
 case Sign(WheelDelta)of
   -1: Screen.ScaleInPoint(Round(Screen.ViewScale*2), Origin);
   +1: Screen.ScaleInPoint(Round(Screen.ViewScale/2), Origin);
 end;
 Origin.GetPoint(fX, fY);
 Mouse.CursorPos := Screen.ClientToScreen(Point(Round(fX-Screen.MapLeft), Round(fY-Screen.MapTop)));
 Handled:= True;
end;
Здравствуйте!

Мне тоже нужно умное масштабирование,
но к сожалению, я чего-то не понимаю,
прошу помочь.

procedure Tform_main.mvMapMouseWheel(Sender: TObject; Shift: TShiftState;
 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
Var
// tp1 : TPoint;
Origin : TCompMapPoint;
fX,fY : double;
X9,Y9 : double;
begin

ShowMessage ('1');

X9 := mvMap.MapLeft;

ShowMessage ('X9 = '+FloatToStr(X9));  // Здесь значение 3617941

Y9 := mvmap.MapTop;

ShowMessage ('Y9 = '+FloatToStr(Y9));  // Здесь значение 5245537

Origin.SetPoint(X9,Y9); // Вот здесь уже выдает ошибку по адресу памяти. Что я не так делаю?

ShowMessage ('2');

With form_main.mvMap.ScreenToClient(MousePos) do Origin.SetPoint(X9+form_main.mvMap.MapLeft,Y9+form_main.mvMap.MapTop);
 case Sign(WheelDelta)of
   -1:
   form_main.mvMap.ScaleInPoint(Round(form_main.mvMap.ViewScale*2), Origin);
   +1:
   form_main.mvMap.ScaleInPoint(Round(form_main.mvMap.ViewScale/2), Origin);
 end;
 Origin.GetPoint(fX, fY);
 Handled:= True;
 
Origin это экземпляр класса TCompMapPoint и его надо создавать прежде чем использовать.
Положите на форму компонент TMapPoint. В нем уже будет настроенный экземпляр TCompMapPoint .
Страницы: Пред. 1 2 3 След.
Читают тему (гостей: 1)



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

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