QgsRectangle QgsCoordinateTransform::transform( const QgsRectangle theRect, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return theRect; // transform x double x1 = theRect.xMinimum(); double y1 = theRect.yMinimum(); double x2 = theRect.xMaximum(); double y2 = theRect.yMaximum(); // Number of points to reproject------+ // | // V try { double z = 0.0; transformCoords( 1, &x1, &y1, &z, direction ); transformCoords( 1, &x2, &y2, &z, direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( "Rect projection..." ); QgsDebugMsg( QString( "Xmin : %1 --> %2" ).arg( theRect.xMinimum() ).arg( x1 ) ); QgsDebugMsg( QString( "Ymin : %1 --> %2" ).arg( theRect.yMinimum() ).arg( y1 ) ); QgsDebugMsg( QString( "Xmax : %1 --> %2" ).arg( theRect.xMaximum() ).arg( x2 ) ); QgsDebugMsg( QString( "Ymax : %1 --> %2" ).arg( theRect.yMaximum() ).arg( y2 ) ); #endif return QgsRectangle( x1, y1, x2, y2 ); }
void QgsCoordinateTransform::transformInPlace( float& x, float& y, float& z, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return; #ifdef QGISDEBUG // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__)); #endif // transform x try { double xd = x; double yd = y; double zd = z; transformCoords( 1, &xd, &yd, &zd, direction ); x = xd; y = yd; z = zd; } catch ( QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } }
void QgsCoordinateTransform::transformInPlace( QVector<double>& x, QVector<double>& y, QVector<double>& z, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return; Q_ASSERT( x.size() == y.size() ); // Apparently, if one has a std::vector, it is valid to use the // address of the first element in the vector as a pointer to an // array of the vectors data, and hence easily interface with code // that wants C-style arrays. try { transformCoords( x.size(), &x[0], &y[0], &z[0], direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } }
void QgsCoordinateTransform::transformInPlace( QVector<float> &x, QVector<float> &y, QVector<float> &z, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) return; Q_ASSERT( x.size() == y.size() ); // Apparently, if one has a std::vector, it is valid to use the // address of the first element in the vector as a pointer to an // array of the vectors data, and hence easily interface with code // that wants C-style arrays. try { //copy everything to double vectors since proj needs double int vectorSize = x.size(); QVector<double> xd( x.size() ); QVector<double> yd( y.size() ); QVector<double> zd( z.size() ); double *destX = xd.data(); double *destY = yd.data(); double *destZ = zd.data(); const float *srcX = x.constData(); const float *srcY = y.constData(); const float *srcZ = z.constData(); for ( int i = 0; i < vectorSize; ++i ) { *destX++ = static_cast< double >( *srcX++ ); *destY++ = static_cast< double >( *srcY++ ); *destZ++ = static_cast< double >( *srcZ++ ); } transformCoords( x.size(), &xd[0], &yd[0], &zd[0], direction ); //copy back float *destFX = x.data(); float *destFY = y.data(); float *destFZ = z.data(); const double *srcXD = xd.constData(); const double *srcYD = yd.constData(); const double *srcZD = zd.constData(); for ( int i = 0; i < vectorSize; ++i ) { *destFX++ = static_cast< float >( *srcXD++ ); *destFY++ = static_cast< float >( *srcYD++ ); *destFZ++ = static_cast< float >( *srcZD++ ); } } catch ( QgsCsException & ) { // rethrow the exception QgsDebugMsg( QStringLiteral( "rethrowing exception" ) ); throw; } }
QPointF Panel::transformCoords(QPointF pos) { coord m = pos.x(); coord n = pos.y(); int x, y; transformCoords(m, n, &x, &y); return QPointF(x, y); }
QgsRectangle QgsCoordinateTransform::transform( const QgsRectangle theRect, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return theRect; // transform x double x1 = theRect.xMinimum(); double y1 = theRect.yMinimum(); double x2 = theRect.xMaximum(); double y2 = theRect.yMaximum(); // Number of points to reproject------+ // | // V try { double z = 0.0; transformCoords( 1, &x1, &y1, &z, direction ); transformCoords( 1, &x2, &y2, &z, direction ); } catch ( QgsCsException &cse ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw cse; } #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( "Rect projection..." ); QgsLogger::debug( "Xmin : ", theRect.xMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "-->", x1, 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "Ymin : ", theRect.yMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "-->", y1, 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "Xmax : ", theRect.xMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "-->", x2, 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "Ymax : ", theRect.yMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ ); QgsLogger::debug( "-->", y2, 1, __FILE__, __FUNCTION__, __LINE__ ); #endif return QgsRectangle( x1, y1, x2, y2 ); }
void QgsCoordinateTransform::transformPolygon( QPolygonF &poly, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) { return; } //create x, y arrays int nVertices = poly.size(); QVector<double> x( nVertices ); QVector<double> y( nVertices ); QVector<double> z( nVertices ); double *destX = x.data(); double *destY = y.data(); double *destZ = z.data(); const QPointF *polyData = poly.constData(); for ( int i = 0; i < nVertices; ++i ) { *destX++ = polyData->x(); *destY++ = polyData->y(); *destZ++ = 0; polyData++; } try { transformCoords( nVertices, x.data(), y.data(), z.data(), direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( QStringLiteral( "rethrowing exception" ) ); throw; } QPointF *destPoint = poly.data(); const double *srcX = x.constData(); const double *srcY = y.constData(); for ( int i = 0; i < nVertices; ++i ) { destPoint->rx() = *srcX++; destPoint->ry() = *srcY++; destPoint++; } }
void QgsCoordinateTransform::transformInPlace( QVector<float>& x, QVector<float>& y, QVector<float>& z, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return; Q_ASSERT( x.size() == y.size() ); // Apparently, if one has a std::vector, it is valid to use the // address of the first element in the vector as a pointer to an // array of the vectors data, and hence easily interface with code // that wants C-style arrays. try { //copy everything to double vectors since proj needs double int vectorSize = x.size(); QVector<double> xd( x.size() ); QVector<double> yd( y.size() ); QVector<double> zd( z.size() ); for ( int i = 0; i < vectorSize; ++i ) { xd[i] = x[i]; yd[i] = y[i]; zd[i] = z[i]; } transformCoords( x.size(), &xd[0], &yd[0], &zd[0], direction ); //copy back for ( int i = 0; i < vectorSize; ++i ) { x[i] = xd[i]; y[i] = yd[i]; z[i] = zd[i]; } } catch ( QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } }
void QgsCoordinateTransform::transformInPlace( double& x, double& y, double& z, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return; #ifdef QGISDEBUG // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__)); #endif // transform x try { transformCoords( 1, &x, &y, &z, direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } }
QgsPoint QgsCoordinateTransform::transform( const QgsPoint thePoint, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return thePoint; // transform x double x = thePoint.x(); double y = thePoint.y(); double z = 0.0; try { transformCoords( 1, &x, &y, &z, direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } return QgsPoint( x, y ); }
void QgsCoordinateTransform::transformPolygon( QPolygonF& poly, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) { return; } //create x, y arrays int nVertices = poly.size(); QVector<double> x( nVertices ); QVector<double> y( nVertices ); QVector<double> z( nVertices ); for ( int i = 0; i < nVertices; ++i ) { const QPointF& pt = poly.at( i ); x[i] = pt.x(); y[i] = pt.y(); z[i] = 0; } try { transformCoords( nVertices, x.data(), y.data(), z.data(), direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } for ( int i = 0; i < nVertices; ++i ) { QPointF& pt = poly[i]; pt.rx() = x[i]; pt.ry() = y[i]; } }
QgsPointXY QgsCoordinateTransform::transform( const QgsPointXY &point, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) return point; // transform x double x = point.x(); double y = point.y(); double z = 0.0; try { transformCoords( 1, &x, &y, &z, direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( QStringLiteral( "rethrowing exception" ) ); throw; } return QgsPointXY( x, y ); }
QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle rect, TransformDirection direction, const bool handle180Crossover ) const { // Calculate the bounding box of a QgsRectangle in the source CRS // when projected to the destination CRS (or the inverse). // This is done by looking at a number of points spread evenly // across the rectangle if ( mShortCircuit || !mInitialisedFlag ) return rect; if ( rect.isEmpty() ) { QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction ); return QgsRectangle( p, p ); } static const int numP = 8; QgsRectangle bb_rect; bb_rect.setMinimal(); // We're interfacing with C-style vectors in the // end, so let's do C-style vectors here too. double x[numP * numP]; double y[numP * numP]; double z[numP * numP]; QgsDebugMsg( "Entering transformBoundingBox..." ); // Populate the vectors double dx = rect.width() / ( double )( numP - 1 ); double dy = rect.height() / ( double )( numP - 1 ); double pointY = rect.yMinimum(); for ( int i = 0; i < numP ; i++ ) { // Start at right edge double pointX = rect.xMinimum(); for ( int j = 0; j < numP; j++ ) { x[( i*numP ) + j] = pointX; y[( i*numP ) + j] = pointY; // and the height... z[( i*numP ) + j] = 0.0; // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j])); pointX += dx; } pointY += dy; } // Do transformation. Any exception generated must // be handled in above layers. try { transformCoords( numP * numP, x, y, z, direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } // Calculate the bounding box and use that for the extent for ( int i = 0; i < numP * numP; i++ ) { if ( !qIsFinite( x[i] ) || !qIsFinite( y[i] ) ) { continue; } if ( handle180Crossover ) { //if crossing the date line, temporarily add 360 degrees to -ve longitudes bb_rect.combineExtentWith( x[i] >= 0.0 ? x[i] : x[i] + 360.0, y[i] ); } else { bb_rect.combineExtentWith( x[i], y[i] ); } } if ( handle180Crossover ) { //subtract temporary addition of 360 degrees from longitudes if ( bb_rect.xMinimum() > 180.0 ) bb_rect.setXMinimum( bb_rect.xMinimum() - 360.0 ); if ( bb_rect.xMaximum() > 180.0 ) bb_rect.setXMaximum( bb_rect.xMaximum() - 360.0 ); } QgsDebugMsg( "Projected extent: " + bb_rect.toString() ); if ( bb_rect.isEmpty() ) { QgsDebugMsg( "Original extent: " + rect.toString() ); } return bb_rect; }
QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle &rect, TransformDirection direction, const bool handle180Crossover ) const { // Calculate the bounding box of a QgsRectangle in the source CRS // when projected to the destination CRS (or the inverse). // This is done by looking at a number of points spread evenly // across the rectangle if ( mShortCircuit || !mInitialisedFlag ) return rect; if ( rect.isEmpty() ) { QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction ); return QgsRectangle( p, p ); } // 64 points (<=2.12) is not enough, see #13665, for EPSG:4326 -> EPSG:3574 (say that it is a hard one), // are decent result from about 500 points and more. This method is called quite often, but // even with 1000 points it takes < 1ms // TODO: how to effectively and precisely reproject bounding box? const int nPoints = 1000; double d = sqrt(( rect.width() * rect.height() ) / pow( sqrt( static_cast< double >( nPoints ) ) - 1, 2.0 ) ); int nXPoints = static_cast< int >( ceil( rect.width() / d ) ) + 1; int nYPoints = static_cast< int >( ceil( rect.height() / d ) ) + 1; QgsRectangle bb_rect; bb_rect.setMinimal(); // We're interfacing with C-style vectors in the // end, so let's do C-style vectors here too. QVector<double> x( nXPoints * nYPoints ); QVector<double> y( nXPoints * nYPoints ); QVector<double> z( nXPoints * nYPoints ); QgsDebugMsg( "Entering transformBoundingBox..." ); // Populate the vectors double dx = rect.width() / static_cast< double >( nXPoints - 1 ); double dy = rect.height() / static_cast< double >( nYPoints - 1 ); double pointY = rect.yMinimum(); for ( int i = 0; i < nYPoints ; i++ ) { // Start at right edge double pointX = rect.xMinimum(); for ( int j = 0; j < nXPoints; j++ ) { x[( i*nXPoints ) + j] = pointX; y[( i*nXPoints ) + j] = pointY; // and the height... z[( i*nXPoints ) + j] = 0.0; // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j])); pointX += dx; } pointY += dy; } // Do transformation. Any exception generated must // be handled in above layers. try { transformCoords( nXPoints * nYPoints, x.data(), y.data(), z.data(), direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw; } // Calculate the bounding box and use that for the extent for ( int i = 0; i < nXPoints * nYPoints; i++ ) { if ( !qIsFinite( x[i] ) || !qIsFinite( y[i] ) ) { continue; } if ( handle180Crossover ) { //if crossing the date line, temporarily add 360 degrees to -ve longitudes bb_rect.combineExtentWith( x[i] >= 0.0 ? x[i] : x[i] + 360.0, y[i] ); } else { bb_rect.combineExtentWith( x[i], y[i] ); } } if ( handle180Crossover ) { //subtract temporary addition of 360 degrees from longitudes if ( bb_rect.xMinimum() > 180.0 ) bb_rect.setXMinimum( bb_rect.xMinimum() - 360.0 ); if ( bb_rect.xMaximum() > 180.0 ) bb_rect.setXMaximum( bb_rect.xMaximum() - 360.0 ); } QgsDebugMsg( "Projected extent: " + bb_rect.toString() ); if ( bb_rect.isEmpty() ) { QgsDebugMsg( "Original extent: " + rect.toString() ); } return bb_rect; }
void init(unsigned w, unsigned h) { ResourceMap resource; resource.addPath("Fonts",""); std::string fontPath = resource.getPath("Fonts")+"monaco11"; font.load(fontPath.c_str()); console.reserve(height/font.lineHeight()); width=w;height=h; objs.clear(); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 2000.0); glEnable(GL_DEPTH_TEST); glutIdleFunc (idle); glutDisplayFunc (draw); glutKeyboardFunc (keyboard); //adding here the mouse processing callbacks glutMotionFunc(processMouseActiveMotion); glutPassiveMotionFunc(processMousePassiveMotion); GLfloat mat_specular[] = { .5, .5, .5, 1.0 }; GLfloat mat_shininess[] = { 5.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); Color3 colors [] = { Color3(255,0,0), Color3(0,255,0), Color3(0,0,255), Color3(255,255,0), Color3(0,255,255), Color3(255,0,255), Color3(255,255,255), }; int n = 1; for (unsigned i=0;i<n;i++) { size_t size; // size = objs.size(); // objs.push_back(Object()); // objs[size].p_ = DReal3(randnorm<dreal>(),randnorm<dreal>(),randnorm<dreal>()); // initModel(objs[objs.size()-1], icosa_vertex, icosa_indices,icosa_vertex_size,icosa_indices_size, colors[(i+5)%7],(7./n)); size = objs.size(); objs.push_back(Object()); // objs[size].p_ =0.8*DReal3(0.1+randnorm<dreal>(),0.1+randnorm<dreal>(),randnorm<dreal>()); //objs[size].p_ =0.5*DReal3(randnorm<dreal>(),randnorm<dreal>(),randnorm<dreal>()); objs[size].p_=Real3(0.5,0.,0.5)+0.1*Real3(randnorm<real>(),randnorm<real>(),randnorm<real>()); initModel(objs[objs.size()-1], bunny_vertex, bunny_indices,bunny_vertex_size,bunny_indices_size, colors[(i)%7],5/*(1./n)*/); // initModel(objs[objs.size()-1], bunnyh_vertex, bunnyh_indices,bunnyh_vertex_size,bunnyh_indices_size, colors[(i)%7],5/*(1./n)*/); } gettimeofday(&idleold, 0); transformCoords(); buildTree(objs,coltrees); colres.resize(coltrees.size()); for (unsigned i=0;i<coltrees.size();i++) { coltrees[i]->collideWithSegment(seg[0], seg[1], colres[i]); } }
QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle rect, TransformDirection direction ) const { // Calculate the bounding box of a QgsRectangle in the source CRS // when projected to the destination CRS (or the inverse). // This is done by looking at a number of points spread evenly // across the rectangle if ( mShortCircuit || !mInitialisedFlag || rect.isEmpty() ) return rect; static const int numP = 8; QgsRectangle bb_rect; bb_rect.setMinimal(); // We're interfacing with C-style vectors in the // end, so let's do C-style vectors here too. double x[numP * numP]; double y[numP * numP]; double z[numP * numP]; QgsDebugMsg( "Entering transformBoundingBox..." ); // Populate the vectors double dx = rect.width() / ( double )( numP - 1 ); double dy = rect.height() / ( double )( numP - 1 ); double pointY = rect.yMinimum(); for ( int i = 0; i < numP ; i++ ) { // Start at right edge double pointX = rect.xMinimum(); for ( int j = 0; j < numP; j++ ) { x[( i*numP ) + j] = pointX; y[( i*numP ) + j] = pointY; // and the height... z[( i*numP ) + j] = 0.0; // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j])); pointX += dx; } pointY += dy; } // Do transformation. Any exception generated must // be handled in above layers. try { transformCoords( numP * numP, x, y, z, direction ); } catch ( QgsCsException &cse ) { // rethrow the exception QgsDebugMsg( "rethrowing exception" ); throw cse; } // Calculate the bounding box and use that for the extent for ( int i = 0; i < numP * numP; i++ ) { if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) ) bb_rect.combineExtentWith( x[i], y[i] ); } QgsDebugMsg( "Projected extent: " + QString(( bb_rect.toString() ).toLocal8Bit().data() ) ); return bb_rect; }