Skip to content
Snippets Groups Projects
point.cpp 9.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • pixhawk's avatar
    pixhawk committed
    /*
    *
    * This file is part of QMapControl,
    * an open-source cross-platform map widget
    *
    * Copyright (C) 2007 - 2008 Kai Winter
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
    *
    * You should have received a copy of the GNU Lesser General Public License
    * along with QMapControl. If not, see <http://www.gnu.org/licenses/>.
    *
    * Contact e-mail: kaiwinter@gmx.de
    * Program URL   : http://qmapcontrol.sourceforge.net/
    *
    */
    
    #include "point.h"
    namespace qmapcontrol
    {
        Point::Point()
        {}
        Point::Point(const Point& point)
            :Geometry(point.name()), X(point.longitude()), Y(point.latitude())
        {
            visible = point.isVisible();
            mywidget = 0;
            mypixmap = 0;
            mypen = point.mypen;
            homelevel = -1;
            minsize = QSize(-1,-1);
            maxsize = QSize(-1,-1);
        }
    
        Point::Point(qreal x, qreal y, QString name, enum Alignment alignment)
            : Geometry(name), X(x), Y(y), myalignment(alignment)
        {
            GeometryType = "Point";
            mywidget = 0;
            mypixmap = 0;
            visible = true;
            homelevel = -1;
            minsize = QSize(-1,-1);
            maxsize = QSize(-1,-1);
        }
    
        Point::Point(qreal x, qreal y, QWidget* widget, QString name, enum Alignment alignment)
            : Geometry(name), X(x), Y(y), mywidget(widget), myalignment(alignment)
        {
            // Point(x, y, name, alignment);
            GeometryType = "Point";
            mypixmap = 0;
            visible = true;
            size = widget->size();
            homelevel = -1;
            minsize = QSize(-1,-1);
            maxsize = QSize(-1,-1);
            mywidget->show();
        }
        Point::Point(qreal x, qreal y, QPixmap* pixmap, QString name, enum Alignment alignment)
            : Geometry(name), X(x), Y(y), mypixmap(pixmap), myalignment(alignment)
        {
            GeometryType = "Point";
            mywidget = 0;
            visible = true;
            size = pixmap->size();
            homelevel = -1;
            minsize = QSize(-1,-1);
            maxsize = QSize(-1,-1);
        }
        /*
            Point& Point::operator=(const Point& rhs)
            {
            if (this == &rhs)
            return *this;
            else
            {
            X = rhs.X;
            Y = rhs.Y;
            size = rhs.size;
    
            mywidget = rhs.mywidget;
            mypixmap = rhs.mypixmap;
            alignment = rhs.alignment;
            homelevel = rhs.homelevel;
            minsize = rhs.minsize;
            maxsize = rhs.maxsize;
    }
    }
    */
        Point::~Point()
        {
            delete mywidget;
            delete mypixmap;
        }
    
        void Point::setVisible(bool visible)
        {
            this->visible = visible;
            if (mywidget !=0)
            {
                mywidget->setVisible(visible);
            }
        }
    
        QRectF Point::boundingBox()
        {
            //TODO: have to be calculated in relation to alignment...
            return QRectF(QPointF(X, Y), displaysize);
        }
    
        qreal Point::longitude() const
        {
            return X;
        }
        qreal Point::latitude() const
        {
            return Y;
        }
        QPointF Point::coordinate() const
        {
            return QPointF(X, Y);
        }
    
        void Point::draw(QPainter* painter, const MapAdapter* mapadapter, const QRect &viewport, const QPoint offset)
        {
            if (!visible)
                return;
    
            if (homelevel > 0)
            {
    
                int currentzoom = mapadapter->maxZoom() < mapadapter->minZoom() ? mapadapter->minZoom() - mapadapter->currentZoom() : mapadapter->currentZoom();
    
                // int currentzoom = mapadapter->getZoom();
                int diffzoom = homelevel-currentzoom;
                int viewheight = size.height();
                int viewwidth = size.width();
                viewheight = int(viewheight / pow(2, diffzoom));
                viewwidth = int(viewwidth / pow(2, diffzoom));
    
                if (minsize.height()!= -1 && viewheight < minsize.height())
                    viewheight = minsize.height();
                else if (maxsize.height() != -1 && viewheight > maxsize.height())
                    viewheight = maxsize.height();
    
    
                if (minsize.width()!= -1 && viewwidth < minsize.width())
                    viewwidth = minsize.width();
                else if (maxsize.width() != -1 && viewwidth > maxsize.width())
                    viewwidth = maxsize.width();
    
    
                displaysize = QSize(viewwidth, viewheight);
            }
            else
            {
                displaysize = size;
            }
    
    
            if (mypixmap !=0)
            {
                const QPointF c = QPointF(X, Y);
                QPoint point = mapadapter->coordinateToDisplay(c);
    
                if (viewport.contains(point))
                {
                    QPoint alignedtopleft = alignedPoint(point);
                    painter->drawPixmap(alignedtopleft.x(), alignedtopleft.y(), displaysize.width(), displaysize.height(), *mypixmap);
                }
    
            }
            else if (mywidget!=0)
            {
                drawWidget(mapadapter, offset);
            }
    
        }
    
        void Point::drawWidget(const MapAdapter* mapadapter, const QPoint offset)
        {
            const QPointF c = QPointF(X, Y);
            QPoint point = mapadapter->coordinateToDisplay(c);
            point -= offset;
    
            QPoint alignedtopleft = alignedPoint(point);
            mywidget->setGeometry(alignedtopleft.x(), alignedtopleft.y(), displaysize.width(), displaysize.height());
        }
    
        QPoint Point::alignedPoint(const QPoint point) const
        {
            QPoint alignedtopleft;
            if (myalignment == Middle)
            {
                alignedtopleft.setX(point.x()-displaysize.width()/2);
                alignedtopleft.setY(point.y()-displaysize.height()/2);
            }
            else if (myalignment == TopLeft)
            {
                alignedtopleft.setX(point.x());
                alignedtopleft.setY(point.y());
            }
            else if (myalignment == TopRight)
            {
                alignedtopleft.setX(point.x()-displaysize.width());
                alignedtopleft.setY(point.y());
            }
            else if (myalignment == BottomLeft)
            {
                alignedtopleft.setX(point.x());
                alignedtopleft.setY(point.y()-displaysize.height());
            }
            else if (myalignment == BottomRight)
            {
                alignedtopleft.setX(point.x()-displaysize.width());
                alignedtopleft.setY(point.y()-displaysize.height());
            }
            return alignedtopleft;
        }
    
    
        bool Point::Touches(Point* p, const MapAdapter* mapadapter)
        {
            if (this->isVisible() == false)
                return false;
            if (mypixmap == 0)
                return false;
    
            QPointF c = p->coordinate();
            // coordinate to pixel
            QPoint pxOfPoint = mapadapter->coordinateToDisplay(c);
            // size/2 Pixel toleranz aufaddieren
            QPoint p1;
            QPoint p2;
    
            switch (myalignment)
            {
                            case Middle:
                p1 = pxOfPoint - QPoint(displaysize.width()/2,displaysize.height()/2);
                p2 = pxOfPoint + QPoint(displaysize.width()/2,displaysize.height()/2);
                break;
                            case TopLeft:
                p1 = pxOfPoint - QPoint(displaysize.width(),displaysize.height());
                p2 = pxOfPoint;
                break;
                            case TopRight:
                p1 = pxOfPoint - QPoint(0, displaysize.height());
                p2 = pxOfPoint + QPoint(displaysize.width(),0);
                break;
                            case BottomLeft:
                p1 = pxOfPoint - QPoint(displaysize.width(), 0);
                p2 = pxOfPoint + QPoint(0, displaysize.height());
                break;
                            case BottomRight:
                p1 = pxOfPoint;
                p2 = pxOfPoint + QPoint(displaysize.width(), displaysize.height());
                break;
            }
    
            // calculate "Bounding Box" in coordinates
            QPointF c1 = mapadapter->displayToCoordinate(p1);
            QPointF c2 = mapadapter->displayToCoordinate(p2);
    
    
            if(this->longitude()>=c1.x() && this->longitude()<=c2.x())
            {
                if (this->latitude()<=c1.y() && this->latitude()>=c2.y())
                {
                    emit(geometryClicked(this, QPoint(0,0)));
                    return true;
                }
            }
            return false;
        }
    
        void Point::setCoordinate(QPointF point)
        {
            // emit(updateRequest(this));
            // emit(updateRequest(QRectF(X, Y, size.width(), size.height())));
            X = point.x();
            Y = point.y();
            // emit(updateRequest(this));
            emit(updateRequest(QRectF(X, Y, size.width(), size.height())));
    
            emit(positionChanged(this));
        }
        QList<Point*> Point::points()
        {
            //TODO: assigning temp?!
            QList<Point*> points;
            points.append(this);
            return points;
        }
    
        QWidget* Point::widget()
        {
            return mywidget;
        }
    
        QPixmap* Point::pixmap()
        {
            return mypixmap;
        }
    
        void Point::setBaselevel(int zoomlevel)
        {
            homelevel = zoomlevel;
        }
        void Point::setMinsize(QSize minsize)
        {
            this->minsize = minsize;
        }
        void Point::setMaxsize(QSize maxsize)
        {
            this->maxsize = maxsize;
        }
        Point::Alignment Point::alignment() const
        {
            return myalignment;
        }
    }