Dane Springmeyer wrote:
Hey, zsj, nice job on this little app!

I tried it out and it works nicely.
I like the smooth zoom - do you think you could get it to match 
http://www.khtml.org/osm/v0.59/index.php whereby the zoom centers upon the 
current mouse position both when zooming in and out?

After struggling with the 0.71 api doc and finding out what coordinate transform mapnik uses, I finally modified the widget to scale upon the current mouse cursor position. Talking about the smooth scale/drag, if the mapnik rendering procedure can be terminated safely, the programm will be more responsive upon complex file. Will it?

Also, I just realized that there may be a few unanswered questions of your 
still on the list - could you resend to me?
Yes, I'll send to the list and you soon. There will be some correction about the questions.


                                     -- Regards, zsj
# -*- coding: utf-8 -*-

import mapnik

from PyQt4.QtCore import *
from PyQt4.QtGui import *


class MapnikWidget(QWidget):

    def __init__(self, parent = None):
        QWidget.__init__(self, parent)

        self.map          = mapnik.Map(256, 256)
        self.qim          = QImage()
        self.startDragPos = QPoint()
        self.endDragPos   = QPoint()
        self.zoomPos      = QPoint()
        self.drag         = False
        self.scale        = False
        self.total_scale  = 1.0
        self.timer        = QTimer()

        self.timer.timeout.connect(self.updateMap)

    def open(self, xml):
        mapnik.load_map(self.map, xml)
        self.map.resize(self.width(), self.height())
        self.zoom_all()

    def close_map(self):
        self.map = mapnik.Map(256, 256)
        self.updateMap()

    def updateMap(self):
        self.timer.stop()

        if self.drag:
            cx = int(0.5 * self.map.width)
            cy = int(0.5 * self.map.height)
            dpos = self.endDragPos - self.startDragPos
            self.map.pan(cx - dpos.x() ,cy - dpos.y())
            self.drag = False
        elif self.scale:
            # scale upon the mouse cursor position
            # build up the transformation matrix
            ma = QMatrix()
            # firstly, translate the cursor position to the origin
            ma.translate(self.zoomPos.x(), self.zoomPos.y())
            # then, do the normal scale upon origin
            ma.scale(self.total_scale, self.total_scale)
            # finnaly, translate back to the cursor position
            ma.translate(-self.zoomPos.x(), -self.zoomPos.y())

            rect = ma.mapRect(QRectF(0, 0, self.map.width, self.map.height))
            env = mapnik.Envelope(rect.left(), rect.bottom(), rect.right(), 
rect.top())
            self.map.zoom_to_box(self.map.view_transform().backward(env))

            self.total_scale = 1.0
            self.scale       = False

        im = mapnik.Image(self.map.width, self.map.height)
        mapnik.render(self.map, im)
        self.qim.loadFromData(QByteArray(im.tostring('png')))
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)

        if self.drag:
            painter.drawImage(self.endDragPos - self.startDragPos, self.qim)
        elif self.scale:
            painter.save()
            scale = 1 / self.total_scale
            painter.translate(self.zoomPos.x(), self.zoomPos.y())
            painter.scale(scale, scale)
            painter.translate(-self.zoomPos.x(), -self.zoomPos.y())
            exposed = 
painter.matrix().inverted()[0].mapRect(self.rect()).adjusted(-1, -1, 1, 1)
            painter.drawImage(exposed, self.qim, exposed)
            painter.restore()
        else:
            painter.drawImage(0, 0, self.qim)

        painter.setPen(QColor(0, 0, 0, 100))
        painter.setBrush(QColor(0, 0, 0, 100))
        painter.drawRect(0, 0, 256, 26)
        painter.setPen(QColor(0, 255 , 0))
        painter.drawText(10, 19, 'Scale Denominator: ' + 
str(self.map.scale_denominator()))

    def zoom_all(self):
        self.map.zoom_all()
        self.updateMap()

    def resizeEvent(self, event):
        self.map.resize(event.size().width(), event.size().height())
        self.updateMap()

    def wheelEvent(self, event):
        self.zoomPos     = event.pos()
        self.total_scale *= 1.0 - event.delta() / (360.0 * 8.0) * 4
        self.scale = True

        self.update()
        self.timer.start(400)


    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.startDragPos = event.pos()
            self.drag         = True

    def mouseMoveEvent(self, event):
        if self.drag:
            self.endDragPos = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.endDragPos = event.pos()
            self.updateMap()
_______________________________________________
Mapnik-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/mapnik-users

Reply via email to