2020-09-23 18:41:12 +08:00
|
|
|
/**
|
|
|
|
|
******************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* @file mapgraphicitem.cpp
|
|
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
|
|
|
|
* @brief The main graphicsItem used on the widget, contains the map and map logic
|
|
|
|
|
* @see The GNU Public License (GPL) Version 3
|
|
|
|
|
* @defgroup OPMapWidget
|
|
|
|
|
* @{
|
|
|
|
|
*
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
/*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
|
* for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
|
|
|
|
#include "uavitem.h"
|
|
|
|
|
#include "gpsitem.h"
|
|
|
|
|
#include "homeitem.h"
|
|
|
|
|
#include "mapgraphicitem.h"
|
|
|
|
|
#include <QGraphicsSceneMouseEvent>
|
|
|
|
|
|
|
|
|
|
namespace mapcontrol {
|
|
|
|
|
MapGraphicItem::MapGraphicItem(internals::Core *core, Configuration *configuration) : core(core), config(configuration), MapRenderTransform(1),
|
|
|
|
|
maxZoom(17), minZoom(2), zoomReal(0), zoomDigi(0), isSelected(false), rotation(0)
|
|
|
|
|
{
|
|
|
|
|
dragons.load(QString::fromUtf8(":/markers/images/dragons2.jpg"));
|
|
|
|
|
showTileGridLines = false;
|
|
|
|
|
isMouseOverMarker = false;
|
|
|
|
|
maprect = QRectF(0, 0, 1022, 680);
|
|
|
|
|
core->SetCurrentRegion(internals::Rectangle(0, 0, maprect.width(), maprect.height()));
|
|
|
|
|
core->SetMapType(MapType::GoogleHybrid);
|
|
|
|
|
this->SetZoom(2);
|
|
|
|
|
this->setFlag(ItemIsFocusable);
|
|
|
|
|
connect(core, SIGNAL(OnNeedInvalidation()), this, SLOT(Core_OnNeedInvalidation()));
|
|
|
|
|
connect(core, SIGNAL(OnMapDrag()), this, SLOT(childPosRefresh()));
|
|
|
|
|
connect(core, SIGNAL(OnMapZoomChanged()), this, SLOT(childPosRefresh()));
|
|
|
|
|
setCacheMode(QGraphicsItem::ItemCoordinateCache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapGraphicItem::start()
|
|
|
|
|
{
|
|
|
|
|
core->StartSystem();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapGraphicItem::resize(const QRectF &rect)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(rect);
|
|
|
|
|
{
|
|
|
|
|
this->prepareGeometryChange();
|
|
|
|
|
maprect = boundingBox(scene()->sceneRect(), rotation);
|
|
|
|
|
this->setTransform(QTransform().translate(-(maprect.width() - scene()->width()) / 2, -(maprect.height() - scene()->height()) / 2));
|
|
|
|
|
this->setTransformOriginPoint(maprect.center().x(), maprect.center().y());
|
|
|
|
|
this->setRotation(rotation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core->OnMapSizeChanged(maprect.width(), maprect.height());
|
|
|
|
|
core->SetCurrentRegion(internals::Rectangle(0, 0, maprect.width(), maprect.height()));
|
|
|
|
|
if (isVisible()) {
|
|
|
|
|
core->GoToCurrentPosition();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QRectF MapGraphicItem::boundingRect() const
|
|
|
|
|
{
|
|
|
|
|
const int Margin = 1;
|
|
|
|
|
|
|
|
|
|
return maprect.adjusted(-Margin, -Margin, +Margin, +Margin);
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::Core_OnNeedInvalidation()
|
|
|
|
|
{
|
|
|
|
|
this->update();
|
|
|
|
|
emit childRefreshPosition();
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::childPosRefresh()
|
|
|
|
|
{
|
|
|
|
|
emit childRefreshPosition();
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::setOverlayOpacity(qreal value)
|
|
|
|
|
{
|
|
|
|
|
emit childSetOpacity(value);
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::ConstructLastImage(int const & zoomdiff)
|
|
|
|
|
{
|
|
|
|
|
QImage temp;
|
|
|
|
|
QSize size = boundingRect().size().toSize();
|
|
|
|
|
|
|
|
|
|
size.setWidth(size.width() * 2 * zoomdiff);
|
|
|
|
|
size.setHeight(size.height() * 2 * zoomdiff);
|
|
|
|
|
temp = QImage(size, QImage::Format_ARGB32_Premultiplied);
|
|
|
|
|
temp.fill(0);
|
|
|
|
|
QPainter imagePainter(&temp);
|
|
|
|
|
imagePainter.translate(-boundingRect().topLeft());
|
|
|
|
|
imagePainter.scale(2 * zoomdiff, 2 * zoomdiff);
|
|
|
|
|
paintImage(&imagePainter);
|
|
|
|
|
imagePainter.end();
|
|
|
|
|
lastimagepoint = Point(core->GetrenderOffset().X() * 2 * zoomdiff, core->GetrenderOffset().Y() * 2 * zoomdiff);
|
|
|
|
|
lastimage = temp;
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::paintImage(QPainter *painter)
|
|
|
|
|
{
|
|
|
|
|
if (MapRenderTransform != 1) {
|
|
|
|
|
QTransform transform;
|
|
|
|
|
transform.translate(-((boundingRect().width() * MapRenderTransform) - (boundingRect().width())) / 2, -((boundingRect().height() * MapRenderTransform) - (boundingRect().height())) / 2);
|
|
|
|
|
transform.scale(MapRenderTransform, MapRenderTransform);
|
|
|
|
|
painter->setWorldTransform(transform);
|
|
|
|
|
{
|
|
|
|
|
DrawMap2D(painter);
|
|
|
|
|
}
|
|
|
|
|
painter->resetTransform();
|
|
|
|
|
} else {
|
|
|
|
|
DrawMap2D(painter);
|
|
|
|
|
}
|
|
|
|
|
// painter->drawRect(maprect);
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(option);
|
|
|
|
|
Q_UNUSED(widget);
|
|
|
|
|
|
|
|
|
|
if (MapRenderTransform != 1) {
|
|
|
|
|
QTransform transform;
|
|
|
|
|
transform.translate(-((boundingRect().width() * MapRenderTransform) - (boundingRect().width())) / 2, -((boundingRect().height() * MapRenderTransform) - (boundingRect().height())) / 2);
|
|
|
|
|
transform.scale(MapRenderTransform, MapRenderTransform);
|
|
|
|
|
|
|
|
|
|
painter->setWorldTransform(transform);
|
|
|
|
|
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
|
|
|
painter->setRenderHint(QPainter::HighQualityAntialiasing, true);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
DrawMap2D(painter);
|
|
|
|
|
}
|
|
|
|
|
painter->resetTransform();
|
|
|
|
|
} else {
|
|
|
|
|
DrawMap2D(painter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (core->IsDragging()) {
|
|
|
|
|
if (MapRenderTransform != 1) {
|
|
|
|
|
qreal dx = (event->pos().x() - core->mouseDown.X()) / (MapRenderTransform);
|
|
|
|
|
qreal dy = (event->pos().y() - core->mouseDown.Y()) / (MapRenderTransform);
|
|
|
|
|
qreal nx = core->mouseDown.X() + dx;
|
|
|
|
|
qreal ny = core->mouseDown.Y() + dy;
|
|
|
|
|
core->mouseCurrent.SetX(nx);
|
|
|
|
|
core->mouseCurrent.SetY(ny);
|
|
|
|
|
} else {
|
|
|
|
|
core->mouseCurrent.SetX(event->pos().x());
|
|
|
|
|
core->mouseCurrent.SetY(event->pos().y());
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
core->Drag(core->mouseCurrent);
|
|
|
|
|
}
|
|
|
|
|
} else if (isSelected && !selectionStart.IsEmpty() && (event->modifiers() == Qt::ControlModifier || event->modifiers() == Qt::ShiftModifier)) {
|
|
|
|
|
selectionEnd = FromLocalToLatLng(event->pos().x(), event->pos().y());
|
|
|
|
|
{
|
|
|
|
|
internals::PointLatLng p1 = selectionStart;
|
|
|
|
|
internals::PointLatLng p2 = selectionEnd;
|
|
|
|
|
|
|
|
|
|
double x1 = qMin(p1.Lng(), p2.Lng());
|
|
|
|
|
double y1 = qMax(p1.Lat(), p2.Lat());
|
|
|
|
|
double x2 = qMax(p1.Lng(), p2.Lng());
|
|
|
|
|
double y2 = qMin(p1.Lat(), p2.Lat());
|
|
|
|
|
|
|
|
|
|
SetSelectedArea(internals::RectLatLng(y1, x1, x2 - x1, y1 - y2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
QGraphicsItem::mouseMoveEvent(event);
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
qDebug() << "MapGraphicItem" << "press";
|
|
|
|
|
|
|
|
|
|
if (!IsMouseOverMarker()) {
|
|
|
|
|
if (event->button() == config->DragButton && CanDragMap() && !((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier))) {
|
|
|
|
|
core->mouseDown.SetX(event->pos().x());
|
|
|
|
|
core->mouseDown.SetY(event->pos().y());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this->setCursor(Qt::ClosedHandCursor);
|
|
|
|
|
|
|
|
|
|
core->BeginDrag(core->mouseDown);
|
|
|
|
|
this->update();
|
|
|
|
|
} else if (!isSelected && ((event->modifiers() == Qt::ControlModifier) || (event->modifiers() == Qt::ShiftModifier))) {
|
|
|
|
|
isSelected = true;
|
|
|
|
|
SetSelectedArea(internals::RectLatLng::Empty);
|
|
|
|
|
selectionEnd = internals::PointLatLng::Empty;
|
|
|
|
|
selectionStart = FromLocalToLatLng(event->pos().x(), event->pos().y());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (isSelected) {
|
|
|
|
|
isSelected = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (core->IsDragging()) {
|
|
|
|
|
core->EndDrag();
|
|
|
|
|
|
|
|
|
|
this->setCursor(Qt::ArrowCursor);
|
|
|
|
|
if (!BoundsOfMap.IsEmpty() && !BoundsOfMap.Contains(core->CurrentPosition())) {
|
|
|
|
|
if (!core->LastLocationInBounds.IsEmpty()) {
|
|
|
|
|
core->SetCurrentPosition(core->LastLocationInBounds);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!selectionEnd.IsEmpty() && !selectionStart.IsEmpty()) {
|
|
|
|
|
if (!selectedArea.IsEmpty() && event->modifiers() == Qt::ShiftModifier) {
|
|
|
|
|
SetZoomToFitRect(SelectedArea());
|
|
|
|
|
selectedArea = internals::RectLatLng::Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::keyPressEvent(QKeyEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier)) {
|
|
|
|
|
this->setCursor(Qt::CrossCursor);
|
|
|
|
|
}
|
|
|
|
|
if (event->key() == Qt::Key_Escape) {
|
|
|
|
|
selectedArea = internals::RectLatLng::Empty;
|
|
|
|
|
}
|
|
|
|
|
QGraphicsItem::keyPressEvent(event);
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::keyReleaseEvent(QKeyEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if ((event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier)) == 0) {
|
|
|
|
|
this->setCursor(Qt::ArrowCursor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool MapGraphicItem::SetZoomToFitRect(internals::RectLatLng const & rect)
|
|
|
|
|
{
|
|
|
|
|
int maxZoom = core->GetMaxZoomToFitRect(rect);
|
|
|
|
|
|
|
|
|
|
if (maxZoom > 0) {
|
|
|
|
|
internals::PointLatLng center = internals::PointLatLng(rect.Lat() - (rect.HeightLat() / 2), rect.Lng() + (rect.WidthLng() / 2));
|
|
|
|
|
core->SetCurrentPosition(center);
|
|
|
|
|
|
|
|
|
|
if (maxZoom > MaxZoom()) {
|
|
|
|
|
maxZoom = MaxZoom();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((int)Zoom() != maxZoom) {
|
|
|
|
|
SetZoom(maxZoom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapGraphicItem::wheelEvent(QGraphicsSceneWheelEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (!IsMouseOverMarker() && !IsDragging()) {
|
|
|
|
|
if (core->GetmouseLastZoom().X() != event->pos().x() && core->mouseLastZoom.Y() != event->pos().y()) {
|
|
|
|
|
if (GetMouseWheelZoomType() == internals::MouseWheelZoomType::MousePositionAndCenter) {
|
|
|
|
|
core->SetCurrentPosition(FromLocalToLatLng(event->pos().x(), event->pos().y()));
|
|
|
|
|
} else if (GetMouseWheelZoomType() == internals::MouseWheelZoomType::ViewCenter) {
|
|
|
|
|
core->SetCurrentPosition(FromLocalToLatLng((int)maprect.width() / 2, (int)maprect.height() / 2));
|
|
|
|
|
} else if (GetMouseWheelZoomType() == internals::MouseWheelZoomType::MousePositionWithoutCenter) {
|
|
|
|
|
core->SetCurrentPosition(FromLocalToLatLng(event->pos().x(), event->pos().y()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core->mouseLastZoom.SetX((event->pos().x()));
|
|
|
|
|
core->mouseLastZoom.SetY((event->pos().y()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set mouse position to map center
|
|
|
|
|
if (GetMouseWheelZoomType() != internals::MouseWheelZoomType::MousePositionWithoutCenter) {
|
|
|
|
|
{
|
|
|
|
|
// System.Drawing.Point p = PointToScreen(new System.Drawing.Point(Width/2, Height/2));
|
|
|
|
|
// Stuff.SetCursorPos((int) p.X, (int) p.Y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core->MouseWheelZooming = true;
|
|
|
|
|
|
|
|
|
|
if (event->delta() > 0) {
|
|
|
|
|
SetZoom(ZoomTotal() + 1);
|
|
|
|
|
} else if (event->delta() < 0) {
|
|
|
|
|
SetZoom(ZoomTotal() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core->MouseWheelZooming = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::DrawMap2D(QPainter *painter)
|
|
|
|
|
{
|
|
|
|
|
painter->drawImage(this->boundingRect(), dragons.toImage());
|
|
|
|
|
if (!lastimage.isNull()) {
|
|
|
|
|
painter->drawImage(core->GetrenderOffset().X() - lastimagepoint.X(), core->GetrenderOffset().Y() - lastimagepoint.Y(), lastimage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = -core->GetsizeOfMapArea().Width(); i <= core->GetsizeOfMapArea().Width(); i++) {
|
|
|
|
|
for (int j = -core->GetsizeOfMapArea().Height(); j <= core->GetsizeOfMapArea().Height(); j++) {
|
|
|
|
|
core->SettilePoint(core->GetcenterTileXYLocation());
|
|
|
|
|
core->SettilePoint(Point(core->GettilePoint().X() + i, core->GettilePoint().Y() + j));
|
|
|
|
|
{
|
|
|
|
|
internals::Tile *t = core->Matrix.TileAt(core->GettilePoint());
|
|
|
|
|
if (true) {
|
|
|
|
|
core->tileRect.SetX(core->GettilePoint().X() * core->tileRect.Width());
|
|
|
|
|
core->tileRect.SetY(core->GettilePoint().Y() * core->tileRect.Height());
|
|
|
|
|
core->tileRect.Offset(core->GetrenderOffset());
|
|
|
|
|
if (core->GetCurrentRegion().IntersectsWith(core->tileRect)) {
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
// render tile
|
|
|
|
|
// lock(t.Overlays)
|
|
|
|
|
if (t != 0) {
|
|
|
|
|
foreach(QByteArray img, t->Overlays) {
|
|
|
|
|
if (img.count() != 0) {
|
|
|
|
|
if (!found) {
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
painter->drawPixmap(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height(), PureImageProxy::FromStream(img));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (showTileGridLines) {
|
|
|
|
|
painter->setPen(config->EmptyTileBorders);
|
|
|
|
|
painter->drawRect(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height());
|
|
|
|
|
{
|
|
|
|
|
painter->setFont(config->MissingDataFont);
|
|
|
|
|
painter->setPen(Qt::red);
|
|
|
|
|
painter->drawText(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()), Qt::AlignCenter, (core->GettilePoint() == core->GetcenterTileXYLocation() ? "CENTER: " : "TILE: ") + core->GettilePoint().ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add text if tile is missing
|
|
|
|
|
if (false) {
|
|
|
|
|
painter->fillRect(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()), config->EmptytileBrush);
|
|
|
|
|
painter->setFont(config->MissingDataFont);
|
|
|
|
|
painter->drawText(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()), config->EmptyTileText);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
painter->setPen(config->EmptyTileBorders);
|
|
|
|
|
painter->drawRect(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height());
|
|
|
|
|
|
|
|
|
|
// raise error
|
|
|
|
|
}
|
|
|
|
|
if (!SelectedArea().IsEmpty()) {
|
|
|
|
|
core::Point p1 = FromLatLngToLocal(SelectedArea().LocationTopLeft());
|
|
|
|
|
core::Point p2 = FromLatLngToLocal(SelectedArea().LocationRightBottom());
|
|
|
|
|
int x1 = p1.X();
|
|
|
|
|
int y1 = p1.Y();
|
|
|
|
|
int x2 = p2.X();
|
|
|
|
|
int y2 = p2.Y();
|
|
|
|
|
painter->setPen(Qt::black);
|
|
|
|
|
painter->setBrush(QBrush(QColor(50, 50, 100, 20)));
|
|
|
|
|
painter->drawRect(x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
core::Point MapGraphicItem::FromLatLngToLocal(internals::PointLatLng const & point)
|
|
|
|
|
{
|
|
|
|
|
core::Point ret = core->FromLatLngToLocal(point);
|
|
|
|
|
|
|
|
|
|
if (MapRenderTransform != 1) {
|
|
|
|
|
ret.SetX((int)(ret.X() * MapRenderTransform));
|
|
|
|
|
ret.SetY((int)(ret.Y() * MapRenderTransform));
|
|
|
|
|
ret.SetX(ret.X() - ((boundingRect().width() * MapRenderTransform) - (boundingRect().width())) / 2);
|
|
|
|
|
ret.SetY(ret.Y() - ((boundingRect().height() * MapRenderTransform) - (boundingRect().height())) / 2);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
internals::PointLatLng MapGraphicItem::FromLocalToLatLng(int x, int y)
|
|
|
|
|
{
|
|
|
|
|
if (MapRenderTransform != 1) {
|
|
|
|
|
x = x + ((boundingRect().width() * MapRenderTransform) - (boundingRect().width())) / 2;
|
|
|
|
|
y = y + ((boundingRect().height() * MapRenderTransform) - (boundingRect().height())) / 2;
|
|
|
|
|
|
|
|
|
|
x = (int)(x / MapRenderTransform);
|
|
|
|
|
y = (int)(y / MapRenderTransform);
|
|
|
|
|
}
|
|
|
|
|
return core->FromLocalToLatLng(x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double MapGraphicItem::Zoom()
|
|
|
|
|
{
|
|
|
|
|
return zoomReal;
|
|
|
|
|
}
|
|
|
|
|
double MapGraphicItem::ZoomDigi()
|
|
|
|
|
{
|
|
|
|
|
return zoomDigi;
|
|
|
|
|
}
|
|
|
|
|
double MapGraphicItem::ZoomTotal()
|
|
|
|
|
{
|
|
|
|
|
return zoomDigi + zoomReal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapGraphicItem::SetZoom(double const & value)
|
|
|
|
|
{
|
|
|
|
|
if (ZoomTotal() != value) {
|
|
|
|
|
if (value > MaxZoom()) {
|
|
|
|
|
zoomReal = MaxZoom();
|
|
|
|
|
zoomDigi = value - MaxZoom();
|
|
|
|
|
} else if (value < MinZoom()) {
|
|
|
|
|
zoomDigi = 0;
|
|
|
|
|
zoomReal = MinZoom();
|
|
|
|
|
} else {
|
|
|
|
|
zoomDigi = 0;
|
|
|
|
|
zoomReal = value;
|
|
|
|
|
}
|
|
|
|
|
double integer;
|
|
|
|
|
double remainder = modf(value, &integer);
|
|
|
|
|
if (zoomDigi != 0 || remainder != 0) {
|
|
|
|
|
float scaleValue = zoomDigi + remainder + 1;
|
|
|
|
|
{
|
|
|
|
|
MapRenderTransform = scaleValue;
|
|
|
|
|
}
|
|
|
|
|
if (integer > MaxZoom()) {
|
|
|
|
|
integer = MaxZoom();
|
|
|
|
|
}
|
|
|
|
|
SetZoomStep((qint32)(integer));
|
|
|
|
|
// core->GoToCurrentPositionOnZoom();
|
|
|
|
|
this->update();
|
|
|
|
|
} else {
|
|
|
|
|
MapRenderTransform = 1;
|
|
|
|
|
|
|
|
|
|
SetZoomStep((qint32)(value));
|
|
|
|
|
zoomReal = ZoomStep();
|
|
|
|
|
this->update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int MapGraphicItem::ZoomStep() const
|
|
|
|
|
{
|
|
|
|
|
return core->Zoom();
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::SetZoomStep(int const & value)
|
|
|
|
|
{
|
|
|
|
|
if (value - core->Zoom() > 0 && value <= MaxZoom()) {
|
|
|
|
|
ConstructLastImage(value - core->Zoom());
|
|
|
|
|
} else if (value != MaxZoom()) {
|
|
|
|
|
lastimage = QImage();
|
|
|
|
|
}
|
|
|
|
|
if (value > MaxZoom()) {
|
|
|
|
|
core->SetZoom(MaxZoom());
|
|
|
|
|
emit zoomChanged(MaxZoom() + ZoomDigi(), Zoom(), ZoomDigi());
|
|
|
|
|
} else if (value < MinZoom()) {
|
|
|
|
|
core->SetZoom(MinZoom());
|
|
|
|
|
emit zoomChanged(MinZoom() + ZoomDigi(), Zoom(), ZoomDigi());
|
|
|
|
|
} else {
|
|
|
|
|
core->SetZoom(value);
|
|
|
|
|
emit zoomChanged(value + ZoomDigi(), Zoom(), ZoomDigi());;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapGraphicItem::Offset(int const & x, int const & y)
|
|
|
|
|
{
|
|
|
|
|
core->DragOffset(Point(x, y));
|
|
|
|
|
}
|
|
|
|
|
void MapGraphicItem::mapRotate(qreal angle)
|
|
|
|
|
{
|
|
|
|
|
if (rotation != angle) {
|
|
|
|
|
rotation = angle;
|
|
|
|
|
resize(scene()->sceneRect());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
QRectF MapGraphicItem::boundingBox(const QRectF &rect, const qreal &angle)
|
|
|
|
|
{
|
|
|
|
|
QRectF ret(rect);
|
|
|
|
|
float c = cos(angle * 2 * M_PI / 360);
|
|
|
|
|
float s = sin(angle * 2 * M_PI / 360);
|
|
|
|
|
|
|
|
|
|
ret.setHeight(rect.height() * fabs(c) + rect.width() * fabs(s));
|
|
|
|
|
ret.setWidth(rect.width() * fabs(c) + rect.height() * fabs(s));
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
QSize MapGraphicItem::sizeHint() const
|
|
|
|
|
{
|
|
|
|
|
core::Size size = core->projection->GetTileMatrixMaxXY(MinZoom());
|
|
|
|
|
core::Size tilesize = core->projection->TileSize();
|
|
|
|
|
QSize rsize((size.Width() + 1) * tilesize.Width(), (size.Height() + 1) * tilesize.Height());
|
|
|
|
|
|
|
|
|
|
return rsize;
|
|
|
|
|
}
|
|
|
|
|
}
|