Change to drawing logic

git-svn-id: http://svn.osgeo.org/qgis/trunk@39 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
gsherman 2002-07-25 05:12:20 +00:00
parent 6add40a8b2
commit 16c97cfbb9
11 changed files with 278 additions and 34 deletions

View File

@ -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

View File

@ -101,7 +101,7 @@ QgisApp::addLayer ()
++it;
}
qApp->processEvents();
mapCanvas->render();
mapCanvas->render2();
}

View File

@ -1,3 +1,6 @@
#include <qstring.h>
#include <qtextstream.h>
#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;
}

View File

@ -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;

View File

@ -3,6 +3,7 @@
#include <qpointarray.h>
#include <qbrush.h>
#include "qgsrect.h"
#include "qgspoint.h"
#include <libpq++.h>
#include <qmessagebox.h>
#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);

View File

@ -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();

View File

@ -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<QString,QgsMapLayer *>::iterator mi = layers.begin();
while(mi != layers.end()){
QgsMapLayer *ml = (*mi).second;
// QgsDatabaseLayer *dbl = (QgsDatabaseLayer *)&ml;
ml->draw(paint, &currentExtent, 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();
}

View File

@ -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;
}

View File

@ -21,6 +21,7 @@
#include <qwidget.h>
#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();

View File

@ -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;

View File

@ -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);