void QgsRasterProjector::calcSrcRowsCols() { // Wee need to calculate minimum cell size in the source // TODO: Think it over better, what is the right source resolution? // Taking distances between cell centers projected to source along source // axis would result in very high resolution // TODO: different resolution for rows and cols ? // For now, we take cell sizes projected to source but not to source axes double myDestColsPerMatrixCell = mDestCols / mCPCols; double myDestRowsPerMatrixCell = mDestRows / mCPRows; QgsDebugMsg( QString( "myDestColsPerMatrixCell = %1 myDestRowsPerMatrixCell = %2" ).arg( myDestColsPerMatrixCell ).arg( myDestRowsPerMatrixCell ) ); double myMinSize = DBL_MAX; for ( int i = 0; i < mCPRows - 1; i++ ) { for ( int j = 0; j < mCPCols - 1; j++ ) { QgsPoint myPointA = mCPMatrix[i][j]; QgsPoint myPointB = mCPMatrix[i][j+1]; QgsPoint myPointC = mCPMatrix[i+1][j]; if ( mCPLegalMatrix[i][j] && mCPLegalMatrix[i][j+1] && mCPLegalMatrix[i+1][j] ) { double mySize = sqrt( myPointA.sqrDist( myPointB ) ) / myDestColsPerMatrixCell; if ( mySize < myMinSize ) myMinSize = mySize; mySize = sqrt( myPointA.sqrDist( myPointC ) ) / myDestRowsPerMatrixCell; if ( mySize < myMinSize ) myMinSize = mySize; } } } // Make it a bit higher resolution // TODO: find the best coefficient, attention, increasing resolution for WMS // is changing WMS content myMinSize *= 0.75; QgsDebugMsg( QString( "mMaxSrcXRes = %1 mMaxSrcYRes = %2" ).arg( mMaxSrcXRes ).arg( mMaxSrcYRes ) ); // mMaxSrcXRes, mMaxSrcYRes may be 0 - no limit (WMS) double myMinXSize = mMaxSrcXRes > myMinSize ? mMaxSrcXRes : myMinSize; double myMinYSize = mMaxSrcYRes > myMinSize ? mMaxSrcYRes : myMinSize; QgsDebugMsg( QString( "myMinXSize = %1 myMinYSize = %2" ).arg( myMinXSize ).arg( myMinYSize ) ); QgsDebugMsg( QString( "mSrcExtent.width = %1 mSrcExtent.height = %2" ).arg( mSrcExtent.width() ).arg( mSrcExtent.height() ) ); // we have to round to keep alignment set in calcSrcExtent mSrcRows = ( int ) qRound( mSrcExtent.height() / myMinYSize ); mSrcCols = ( int ) qRound( mSrcExtent.width() / myMinXSize ); QgsDebugMsg( QString( "mSrcRows = %1 mSrcCols = %2" ).arg( mSrcRows ).arg( mSrcCols ) ); }
bool QgsPointSample::checkMinDistance( QgsPoint& pt, QgsSpatialIndex& index, double minDistance, QMap< QgsFeatureId, QgsPoint >& pointMap ) { if ( minDistance <= 0 ) { return true; } QList<QgsFeatureId> neighborList = index.nearestNeighbor( pt, 1 ); if ( neighborList.isEmpty() ) { return true; } QMap< QgsFeatureId, QgsPoint >::const_iterator it = pointMap.find( neighborList[0] ); if ( it == pointMap.constEnd() ) //should not happen { return true; } QgsPoint neighborPt = it.value(); if ( neighborPt.sqrDist( pt ) < ( minDistance * minDistance ) ) { return false; } return true; }
bool QgsRasterProjector::checkRows() { for ( int r = 0; r < mCPRows; r++ ) { for ( int c = 1; c < mCPCols - 1; c += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r][c-1]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r][c+1]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); try { QgsPoint myDestApprox = mCoordinateTransform.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
void QgsAnnotationItem::updateBalloon() { //first test if the point is in the frame. In that case we don't need a balloon. if ( !mMapPositionFixed || ( mOffsetFromReferencePoint.x() < 0 && ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) > 0 && mOffsetFromReferencePoint.y() < 0 && ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) > 0 ) ) { mBalloonSegment = -1; return; } //edge list QList<QLineF> segmentList; segmentList << segment( 0 ); segmentList << segment( 1 ); segmentList << segment( 2 ); segmentList << segment( 3 ); //find closest edge / closest edge point double minEdgeDist = DBL_MAX; int minEdgeIndex = -1; QLineF minEdge; QgsPoint minEdgePoint; QgsPoint origin( 0, 0 ); for ( int i = 0; i < 4; ++i ) { QLineF currentSegment = segmentList.at( i ); QgsPoint currentMinDistPoint; double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint ); if ( currentMinDist < minEdgeDist ) { minEdgeIndex = i; minEdgePoint = currentMinDistPoint; minEdgeDist = currentMinDist; minEdge = currentSegment; } } if ( minEdgeIndex < 0 ) { return; } //make that configurable for the item double segmentPointWidth = 10; mBalloonSegment = minEdgeIndex; QPointF minEdgeEnd = minEdge.p2(); mBalloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() ); if ( sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < segmentPointWidth ) { mBalloonSegmentPoint1 = pointOnLineWithDistance( minEdge.p2(), minEdge.p1(), segmentPointWidth ); } mBalloonSegmentPoint2 = pointOnLineWithDistance( mBalloonSegmentPoint1, minEdge.p2(), 10 ); }
// return ratio [mu/lu] between map units and layer units // this is of course only an approximation double _ratioMU2LU( const QgsMapSettings& mapSettings, QgsMapLayer* layer ) { double distMU = mapSettings.mapUnitsPerPixel(); QgsPoint ptMapCenterMU = mapSettings.visibleExtent().center(); QgsPoint ptMapCenterRightMU( ptMapCenterMU.x() + distMU, ptMapCenterMU.y() ); QgsPoint ptMapCenterLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterMU ); QgsPoint ptMapCenterRightLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterRightMU ); double distLU = sqrt( ptMapCenterLU.sqrDist( ptMapCenterRightLU ) ); double ratio = distMU / distLU; return ratio; }
bool QgsRasterProjector::checkCols( const QgsCoordinateTransform* ct ) { if ( !ct ) { return false; } for ( int c = 0; c < mCPCols; c++ ) { for ( int r = 1; r < mCPRows - 1; r += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r-1][c]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r+1][c]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); if ( !mCPLegalMatrix[r-1][c] || !mCPLegalMatrix[r][c] || !mCPLegalMatrix[r+1][c] ) { // There was an error earlier in transform, just abort return false; } try { QgsPoint myDestApprox = ct->transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
bool QgsRasterProjector::checkCols() { for ( int c = 0; c < mCPCols; c++ ) { for ( int r = 1; r < mCPRows - 1; r += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPoint myDestPoint( myDestX, myDestY ); QgsPoint mySrcPoint1 = mCPMatrix[r-1][c]; QgsPoint mySrcPoint2 = mCPMatrix[r][c]; QgsPoint mySrcPoint3 = mCPMatrix[r+1][c]; QgsPoint mySrcApprox(( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); QgsPoint myDestApprox = mCoordinateTransform.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) return false; } } return true; }
bool QgsTransectSample::closestSegmentPoints( const QgsGeometry& g1, const QgsGeometry& g2, double& dist, QgsPoint& pt1, QgsPoint& pt2 ) { QgsWkbTypes::Type t1 = g1.wkbType(); if ( t1 != QgsWkbTypes::LineString && t1 != QgsWkbTypes::LineString25D ) { return false; } QgsWkbTypes::Type t2 = g2.wkbType(); if ( t2 != QgsWkbTypes::LineString && t2 != QgsWkbTypes::LineString25D ) { return false; } QgsPolyline pl1 = g1.asPolyline(); QgsPolyline pl2 = g2.asPolyline(); if ( pl1.size() < 2 || pl2.size() < 2 ) { return false; } QgsPoint p11 = pl1.at( 0 ); QgsPoint p12 = pl1.at( 1 ); QgsPoint p21 = pl2.at( 0 ); QgsPoint p22 = pl2.at( 1 ); double p1x = p11.x(); double p1y = p11.y(); double v1x = p12.x() - p11.x(); double v1y = p12.y() - p11.y(); double p2x = p21.x(); double p2y = p21.y(); double v2x = p22.x() - p21.x(); double v2y = p22.y() - p21.y(); double denominatorU = v2x * v1y - v2y * v1x; double denominatorT = v1x * v2y - v1y * v2x; if ( qgsDoubleNear( denominatorU, 0 ) || qgsDoubleNear( denominatorT, 0 ) ) { //lines are parallel //project all points on the other segment and take the one with the smallest distance QgsPoint minDistPoint1; double d1 = p11.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint1 ); QgsPoint minDistPoint2; double d2 = p12.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint2 ); QgsPoint minDistPoint3; double d3 = p21.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint3 ); QgsPoint minDistPoint4; double d4 = p22.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint4 ); if ( d1 <= d2 && d1 <= d3 && d1 <= d4 ) { dist = sqrt( d1 ); pt1 = p11; pt2 = minDistPoint1; return true; } else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 ) { dist = sqrt( d2 ); pt1 = p12; pt2 = minDistPoint2; return true; } else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 ) { dist = sqrt( d3 ); pt1 = p21; pt2 = minDistPoint3; return true; } else { dist = sqrt( d4 ); pt1 = p21; pt2 = minDistPoint4; return true; } } double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU; double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT; if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 ) { dist = 0; pt1.setX( p2x + u * v2x ); pt1.setY( p2y + u * v2y ); pt2 = pt1; dist = 0; return true; } if ( t > 1.0 ) { pt1.setX( p12.x() ); pt1.setY( p12.y() ); } else if ( t < 0.0 ) { pt1.setX( p11.x() ); pt1.setY( p11.y() ); } if ( u > 1.0 ) { pt2.setX( p22.x() ); pt2.setY( p22.y() ); } if ( u < 0.0 ) { pt2.setX( p21.x() ); pt2.setY( p21.y() ); } if ( t >= 0.0 && t <= 1.0 ) { //project pt2 onto g1 pt2.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), pt1 ); } if ( u >= 0.0 && u <= 1.0 ) { //project pt1 onto g2 pt1.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), pt2 ); } dist = sqrt( pt1.sqrDist( pt2 ) ); return true; }
void QgsRasterProjector::calcSrcRowsCols() { // Wee need to calculate minimum cell size in the source // TODO: Think it over better, what is the right source resolution? // Taking distances between cell centers projected to source along source // axis would result in very high resolution // TODO: different resolution for rows and cols ? double myMinSize = std::numeric_limits<double>::max(); if ( mApproximate ) { // For now, we take cell sizes projected to source but not to source axes double myDestColsPerMatrixCell = ( double )mDestCols / mCPCols; double myDestRowsPerMatrixCell = ( double )mDestRows / mCPRows; QgsDebugMsg( QString( "myDestColsPerMatrixCell = %1 myDestRowsPerMatrixCell = %2" ).arg( myDestColsPerMatrixCell ).arg( myDestRowsPerMatrixCell ) ); for ( int i = 0; i < mCPRows - 1; i++ ) { for ( int j = 0; j < mCPCols - 1; j++ ) { QgsPoint myPointA = mCPMatrix[i][j]; QgsPoint myPointB = mCPMatrix[i][j+1]; QgsPoint myPointC = mCPMatrix[i+1][j]; if ( mCPLegalMatrix[i][j] && mCPLegalMatrix[i][j+1] && mCPLegalMatrix[i+1][j] ) { double mySize = sqrt( myPointA.sqrDist( myPointB ) ) / myDestColsPerMatrixCell; if ( mySize < myMinSize ) myMinSize = mySize; mySize = sqrt( myPointA.sqrDist( myPointC ) ) / myDestRowsPerMatrixCell; if ( mySize < myMinSize ) myMinSize = mySize; } } } } else { // take highest from corners, points in in the middle of corners and center (3 x 3 ) const QgsCoordinateTransform* inverseCt = QgsCoordinateTransformCache::instance()->transform( mDestCRS.authid(), mSrcCRS.authid(), mDestDatumTransform, mSrcDatumTransform ); //double QgsRectangle srcExtent; int srcXSize, srcYSize; if ( extentSize( inverseCt, mDestExtent, mDestCols, mDestRows, srcExtent, srcXSize, srcYSize ) ) { double srcXRes = srcExtent.width() / srcXSize; double srcYRes = srcExtent.height() / srcYSize; myMinSize = std::min( srcXRes, srcYRes ); } else { QgsDebugMsg( "Cannot get src extent/size" ); } } // Make it a bit higher resolution // TODO: find the best coefficient, attention, increasing resolution for WMS // is changing WMS content myMinSize *= 0.75; QgsDebugMsg( QString( "mMaxSrcXRes = %1 mMaxSrcYRes = %2" ).arg( mMaxSrcXRes ).arg( mMaxSrcYRes ) ); // mMaxSrcXRes, mMaxSrcYRes may be 0 - no limit (WMS) double myMinXSize = mMaxSrcXRes > myMinSize ? mMaxSrcXRes : myMinSize; double myMinYSize = mMaxSrcYRes > myMinSize ? mMaxSrcYRes : myMinSize; QgsDebugMsg( QString( "myMinXSize = %1 myMinYSize = %2" ).arg( myMinXSize ).arg( myMinYSize ) ); QgsDebugMsg( QString( "mSrcExtent.width = %1 mSrcExtent.height = %2" ).arg( mSrcExtent.width() ).arg( mSrcExtent.height() ) ); // we have to round to keep alignment set in calcSrcExtent mSrcRows = ( int ) qRound( mSrcExtent.height() / myMinYSize ); mSrcCols = ( int ) qRound( mSrcExtent.width() / myMinXSize ); QgsDebugMsg( QString( "mSrcRows = %1 mSrcCols = %2" ).arg( mSrcRows ).arg( mSrcCols ) ); }