From 16c97cfbb93c64f5e358e3a228639834b9d5bbe6 Mon Sep 17 00:00:00 2001 From: gsherman Date: Thu, 25 Jul 2002 05:12:20 +0000 Subject: [PATCH] Change to drawing logic git-svn-id: http://svn.osgeo.org/qgis/trunk@39 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/Makefile | 13 ++- src/qgisapp.cpp | 2 +- src/qgscoordinatetransform.cpp | 38 ++++++ src/qgscoordinatetransform.h | 9 +- src/qgsdatabaselayer.cpp | 207 +++++++++++++++++++++++++++++---- src/qgsdatabaselayer.h | 1 + src/qgsmapcanvas.cpp | 25 +++- src/qgsmaplayer.cpp | 6 +- src/qgsmaplayer.h | 2 + src/qgspoint.cpp | 7 +- src/qgspoint.h | 2 + 11 files changed, 278 insertions(+), 34 deletions(-) diff --git a/src/Makefile b/src/Makefile index 435683b179b..6014b8e3b8a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: qgis -# Generated by qmake (1.03a) on: Wed Jul 24 19:25:43 2002 +# Generated by qmake (1.03a) on: Wed Jul 24 19:50:22 2002 # Project: src.pro # Template: app # Command: $(QMAKE) src.pro @@ -54,7 +54,8 @@ HEADERS = qgsdbsourceselectbase.ui.h \ qgsdbsourceselect.h \ qgsnewconnection.h \ qgsrect.h \ - qgspoint.h + qgspoint.h \ + qgscoordinatetransorm.h SOURCES = main.cpp \ qgisapp.cpp \ qgsdatabaselayer.cpp \ @@ -65,7 +66,8 @@ SOURCES = main.cpp \ qgsdbsourceselect.cpp \ qgsnewconnection.cpp \ qgsrect.cpp \ - qgspoint.cpp + qgspoint.cpp \ + qgscoordinatetransform.cpp OBJECTS = main.o \ qgisapp.o \ qgsdatabaselayer.o \ @@ -77,6 +79,7 @@ OBJECTS = main.o \ qgsnewconnection.o \ qgsrect.o \ qgspoint.o \ + qgscoordinatetransform.o \ qgsdbsourceselectbase.o \ qgisappbase.o \ qgsnewconnectionbase.o @@ -188,6 +191,7 @@ qgsdatasource.o: qgsdatasource.cpp qgsdatasource.h qgsmapcanvas.o: qgsmapcanvas.cpp qgsrect.h \ qgsmaplayer.h \ qgsdatabaselayer.h \ + qgscoordinatetransform.h \ qgsmapcanvas.h \ qgsdatasource.h @@ -215,6 +219,9 @@ qgsrect.o: qgsrect.cpp qgsrect.h qgspoint.o: qgspoint.cpp qgspoint.h +qgscoordinatetransform.o: qgscoordinatetransform.cpp qgspoint.h \ + qgscoordinatetransform.h + qgsdbsourceselectbase.h: qgsdbsourceselectbase.ui $(UIC) qgsdbsourceselectbase.ui -o qgsdbsourceselectbase.h diff --git a/src/qgisapp.cpp b/src/qgisapp.cpp index affdf0705ca..64b3b9f0297 100644 --- a/src/qgisapp.cpp +++ b/src/qgisapp.cpp @@ -101,7 +101,7 @@ QgisApp::addLayer () ++it; } qApp->processEvents(); - mapCanvas->render(); + mapCanvas->render2(); } diff --git a/src/qgscoordinatetransform.cpp b/src/qgscoordinatetransform.cpp index 7e3aa696ad9..73e4f69baf1 100644 --- a/src/qgscoordinatetransform.cpp +++ b/src/qgscoordinatetransform.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "qgspoint.h" #include "qgscoordinatetransform.h" @@ -7,7 +10,42 @@ QgsCoordinateTransform::QgsCoordinateTransform(double mupp=0, double ymax = 0, d QgsCoordinateTransform::~QgsCoordinateTransform(){ } QgsPoint QgsCoordinateTransform::transform(QgsPoint p){ + // transform x + double dx = (p.x() - xMin)/mapUnitsPerPixel; + double dy = (yMax - (p.y() - yMin))/mapUnitsPerPixel; + return QgsPoint(dx,dy); } QgsPoint QgsCoordinateTransform::transform(double x, double y){ + return(transform(QgsPoint(x,y))); +} +void QgsCoordinateTransform::setMapUnitsPerPixel(double mupp){ + mapUnitsPerPixel = mupp; +} + +void QgsCoordinateTransform::setYmax(double ymax){ + yMax = ymax; +} +void QgsCoordinateTransform::setYmin(double ymin){ + yMin = ymin; +} +void QgsCoordinateTransform::setXmin(double xmin){ + xMin = xmin; +} +void QgsCoordinateTransform::setParameters(double mupp, double xmin, + double ymin, double ymax){ + mapUnitsPerPixel = mupp; + xMin = xmin; + yMin = ymin; + yMax = ymax; + +} +QString QgsCoordinateTransform::showParameters(){ + QString rep; + QTextOStream(&rep) << "Map units/pixel: " << mapUnitsPerPixel + << " X minimum: " << xMin + << " Y minimum: " << yMin + << " Y maximum: " << yMax; + return rep; + } diff --git a/src/qgscoordinatetransform.h b/src/qgscoordinatetransform.h index f5914c995d8..05d56fef920 100644 --- a/src/qgscoordinatetransform.h +++ b/src/qgscoordinatetransform.h @@ -4,10 +4,17 @@ class QgsPoint; class QgsCoordinateTransform{ public: - QgsCoordinateTransform(); + QgsCoordinateTransform(double mupp=0, double ymax = 0, double ymin=0, + double xmin = 0); ~QgsCoordinateTransform(); QgsPoint transform(QgsPoint p); QgsPoint transform(double x, double y); + void setMapUnitsPerPixel(double mupp); + void setYmax(double ymax); + void setYmin(double ymin); + void setXmin(double xmin); + void setParameters(double mupp, double xmin, double ymin, double ymax); + QString showParameters(); private: double mapUnitsPerPixel; double yMax; diff --git a/src/qgsdatabaselayer.cpp b/src/qgsdatabaselayer.cpp index 4e7e020209a..76e32b88782 100644 --- a/src/qgsdatabaselayer.cpp +++ b/src/qgsdatabaselayer.cpp @@ -3,6 +3,7 @@ #include #include #include "qgsrect.h" +#include "qgspoint.h" #include #include #include "qgsdatabaselayer.h" @@ -181,30 +182,30 @@ void QgsDatabaseLayer::draw(QPainter *p, QgsRect *viewExtent, int yTransform){ // get the number of polygons ptr = feature + 5; numPolygons = (int *)ptr; - for(kdx = 0; kdx < *numPolygons; kdx++){ - //skip the endian and feature type info and - // get number of rings in the polygon - ptr = feature + 14; - numRings = (int *)ptr; + for(kdx = 0; kdx < *numPolygons; kdx++){ + //skip the endian and feature type info and + // get number of rings in the polygon + ptr = feature + 14; + numRings = (int *)ptr; + ptr += 4; + for(idx = 0; idx < *numRings; idx++){ + // get number of points in the ring + nPoints = (int *)ptr; ptr += 4; - for(idx = 0; idx < *numRings; idx++){ - // get number of points in the ring - nPoints = (int *)ptr; - ptr += 4; - pa = new QPointArray(*nPoints); - for(jdx = 0; jdx < *nPoints; jdx++){ - // add points to a point array for drawing the polygon - x = (double *) ptr; - ptr += sizeof(double); - y = (double *) ptr; - ptr += sizeof(double); - pa->setPoint(jdx,(int)*x, yTransform - (int)*y); - } - // draw the ring - p->drawPolygon(*pa); - delete pa; + pa = new QPointArray(*nPoints); + for(jdx = 0; jdx < *nPoints; jdx++){ + // add points to a point array for drawing the polygon + x = (double *) ptr; + ptr += sizeof(double); + y = (double *) ptr; + ptr += sizeof(double); + pa->setPoint(jdx,(int)*x, yTransform - (int)*y); } + // draw the ring + p->drawPolygon(*pa); + delete pa; } + } break; } @@ -213,6 +214,170 @@ void QgsDatabaseLayer::draw(QPainter *p, QgsRect *viewExtent, int yTransform){ } +void QgsDatabaseLayer::draw(QPainter *p, QgsRect *viewExtent, QgsCoordinateTransform *cXf){ + // painter is active (begin has been called + /* Steps to draw the layer + 1. get the features in the view extent by SQL query + 2. read WKB for a feature + 3. transform + 4. draw + */ + PgCursor pgs(dataSource, "drawCursor"); + QString sql = "select asbinary(" + geometryColumn + ",'" + endianString(); + sql += "') as features from " + tableName; + sql += " where " + geometryColumn; + sql += " && GeometryFromText('BOX3D(" + viewExtent->stringRep(); + sql += ")'::box3d,-1)"; + qWarning(sql); + pgs.Declare((const char *)sql, true); + int res = pgs.Fetch(); + cout << "Number of matching records: " << pgs.Tuples() << endl; + cout << "Using following transform parameters:\n" << cXf->showParameters() + << endl; + for (int idx = 0; idx < pgs.Tuples (); idx++) + { + // allocate memory for the item + char *feature = new char[pgs.GetLength (idx, 0) + 1]; + memset (feature, '\0', pgs.GetLength (idx, 0) + 1); + memcpy (feature, pgs.GetValue (idx, 0), pgs.GetLength (idx, 0)); + wkbType = (int)feature[1]; + //cout << "Feature type: " << wkbType << endl; + // read each feature based on its type + double *x; + double *y; + int *nPoints; + int *numRings; + int *numPolygons; + int numPoints; + int numLineStrings; + int idx,jdx,kdx; + char *ptr; + char lsb; + int ttype; + QgsPoint pt; + QPointArray *pa; + switch(wkbType){ + case WKBPoint: + p->setPen(Qt::red); + x = (double *) (feature + 5); + y = (double *) (feature + 5 + sizeof (double)); + pt = cXf->transform(*x,*y); + p->drawRect (pt.xToInt(), pt.yToInt(), 5, 5); + break; + case WKBLineString: + p->setPen(Qt::blue); + // get number of points in the line + numPoints = (int)(feature + 1 + sizeof(int)); + ptr = feature + 1 + 2 * sizeof(int); + for(idx = 0; idx < numPoints; idx++){ + x = (double *) ptr; + ptr += sizeof(double); + y = (double *) ptr; + ptr += sizeof(double); + // transform the point + pt = cXf->transform(*x, *y); + if(idx == 0) + p->moveTo(pt.xToInt(),pt.yToInt()); + else + p->lineTo(pt.xToInt(),pt.yToInt()); + + } + break; + case WKBMultiLineString: + p->setPen(Qt::blue); + numLineStrings = (int)(feature[5]); + ptr = feature+9; + for(jdx = 0; jdx < numLineStrings; jdx++){ + // each of these is a wbklinestring so must handle as such + lsb = *ptr; + ptr += 5; // skip type since we know its 2 + nPoints = (int *)ptr; + ptr += sizeof(int); + for(idx = 0; idx < *nPoints; idx++){ + x = (double *) ptr; + ptr += sizeof(double); + y = (double *) ptr; + ptr += sizeof(double); + // transform the point + pt = cXf->transform(*x, *y); + if(idx == 0) + p->moveTo(pt.xToInt(),pt.yToInt()); + else + p->lineTo(pt.xToInt(),pt.yToInt()); + + } + } + break; + case WKBPolygon: + p->setPen(Qt::blue); + // get number of rings in the polygon + numRings = (int *)(feature + 1 + sizeof(int)); + ptr = feature + 1 + 2 * sizeof(int); + for(idx = 0; idx < *numRings; idx++){ + // get number of points in the ring + nPoints = (int *)ptr; + ptr += 4; + pa = new QPointArray(*nPoints); + for(jdx = 0; jdx < *nPoints; jdx++){ + // add points to a point array for drawing the polygon + x = (double *) ptr; + ptr += sizeof(double); + y = (double *) ptr; + ptr += sizeof(double); + pt = cXf->transform(*x, *y); + pa->setPoint(jdx,pt.xToInt(), pt.yToInt()); + } + // draw the ring + p->drawPolygon(*pa); + + } + break; + case WKBMultiPolygon: + p->setPen(Qt::darkGreen); + QBrush brush(Qt::green); + p->setBrush(brush); + // get the number of polygons + ptr = feature + 5; + numPolygons = (int *)ptr; + for(kdx = 0; kdx < *numPolygons; kdx++){ + //skip the endian and feature type info and + // get number of rings in the polygon + ptr = feature + 14; + numRings = (int *)ptr; + ptr += 4; + for(idx = 0; idx < *numRings; idx++){ + // get number of points in the ring + nPoints = (int *)ptr; + ptr += 4; + pa = new QPointArray(*nPoints); + for(jdx = 0; jdx < *nPoints; jdx++){ + // add points to a point array for drawing the polygon + x = (double *) ptr; + ptr += sizeof(double); + y = (double *) ptr; + ptr += sizeof(double); + // cout << "Transforming " << *x << "," << *y << " to "; + + pt = cXf->transform(*x, *y); + //cout << pt.xToInt() << "," << pt.yToInt() << endl; + pa->setPoint(jdx,pt.xToInt(), pt.yToInt()); + + } + // draw the ring + p->drawPolygon(*pa); + delete pa; + } + } + break; + } + + } + + + +} + + int QgsDatabaseLayer::endian(){ char *chkEndian = new char[4]; memset (chkEndian, '\0', 4); diff --git a/src/qgsdatabaselayer.h b/src/qgsdatabaselayer.h index c8d943d1108..8869e2f15b9 100644 --- a/src/qgsdatabaselayer.h +++ b/src/qgsdatabaselayer.h @@ -39,6 +39,7 @@ class QgsDatabaseLayer : public QgsMapLayer { //! Destructor ~QgsDatabaseLayer(); virtual void draw(QPainter *, QgsRect *, int ); + virtual void draw(QPainter *, QgsRect *, QgsCoordinateTransform *cFx); private: //! Calculates extent of the layer using SQL and PostGIS functions QgsRect calculateExtent(); diff --git a/src/qgsmapcanvas.cpp b/src/qgsmapcanvas.cpp index 1df8e13c9d5..3816d5aa294 100644 --- a/src/qgsmapcanvas.cpp +++ b/src/qgsmapcanvas.cpp @@ -47,11 +47,24 @@ void QgsMapCanvas::render2(){ currentExtent = fullExtent; QRect v = paint->viewport(); // calculate the translation and scaling parameters - if(currentExtent.height() > currentExtent.width()) - m_mupp = currentExtent.height()/v.height(); - else - m_mupp = currentExtent.width()/v.width(); - coordXForm-> + double muppX, muppY; + muppY = currentExtent.height()/height(); + muppX = currentExtent.width()/width(); + cout << "MuppX is: " << muppX << "\nMuppY is: " << muppY << endl; + m_mupp = muppY > muppX?muppY:muppX; + m_mupp *= 1.20; + coordXForm->setParameters(m_mupp, currentExtent.xMin(), + currentExtent.yMin(), currentExtent.yMax()); + // render all layers in the stack, starting at the base + map::iterator mi = layers.begin(); + while(mi != layers.end()){ + QgsMapLayer *ml = (*mi).second; + // QgsDatabaseLayer *dbl = (QgsDatabaseLayer *)&ml; + ml->draw(paint, ¤tExtent, coordXForm); + mi++; + // mi.draw(p, &fullExtent); + } + paint->end(); } void QgsMapCanvas::render(){ @@ -94,5 +107,5 @@ void QgsMapCanvas::render(){ paint->end(); } void QgsMapCanvas::paintEvent(QPaintEvent *pe){ - render(); + render2(); } diff --git a/src/qgsmaplayer.cpp b/src/qgsmaplayer.cpp index e5d9b4e79c2..0dea75127f8 100644 --- a/src/qgsmaplayer.cpp +++ b/src/qgsmaplayer.cpp @@ -44,7 +44,11 @@ const QgsRect QgsMapLayer::extent(){ QgsRect QgsMapLayer::calculateExtent(){ } -void QgsMapLayer::draw(QPainter *p, QgsRect *viewExtent, int yTransform){ +void QgsMapLayer::draw(QPainter *, QgsRect *viewExtent, int yTransform){ + cout << "In QgsMapLayer::draw" << endl; +} + +void QgsMapLayer::draw(QPainter *, QgsRect *, QgsCoordinateTransform *){ cout << "In QgsMapLayer::draw" << endl; } diff --git a/src/qgsmaplayer.h b/src/qgsmaplayer.h index 9ff81618fee..95dc0176137 100644 --- a/src/qgsmaplayer.h +++ b/src/qgsmaplayer.h @@ -21,6 +21,7 @@ #include #include "qgsdatasource.h" #include "qgsrect.h" +#include "qgscoordinatetransform.h" /** \class QgsMapLayer @@ -56,6 +57,7 @@ class QgsMapLayer : public QgsDataSource { */ virtual QgsRect calculateExtent(); virtual void draw(QPainter *, QgsRect *, int); + virtual void draw(QPainter *, QgsRect *, QgsCoordinateTransform *cXf); /*! Return the extent of the layer as a QRect */ const QgsRect extent(); diff --git a/src/qgspoint.cpp b/src/qgspoint.cpp index bf112e96f04..d37b4f6325b 100644 --- a/src/qgspoint.cpp +++ b/src/qgspoint.cpp @@ -16,7 +16,12 @@ double QgsPoint::x() const { double QgsPoint::y() const { return m_y; } - +int QgsPoint::xToInt() { + return (int)m_x; +} +int QgsPoint::yToInt() { + return (int)m_y; +} bool QgsPoint::operator==(const QgsPoint &other){ if((m_x == other.x()) && (m_y == other.y())) return true; diff --git a/src/qgspoint.h b/src/qgspoint.h index 0743061abcf..d35a5e21efe 100644 --- a/src/qgspoint.h +++ b/src/qgspoint.h @@ -35,10 +35,12 @@ class QgsPoint { * @return x coordinate */ double x() const; + int xToInt(); /*! Get the y value of the point * @return y coordinate */ double y(void) const; + int yToInt(); //! equality operator bool operator==(const QgsPoint &other);