bool QgsGeometryAnalyzer::extent( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures, QProgressDialog * ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } QGis::WkbType outputType = QGis::WKBPolygon; const QgsCoordinateReferenceSystem crs = layer->crs(); QgsFields fields; fields.append( QgsField( QString( "MINX" ), QVariant::Double ) ); fields.append( QgsField( QString( "MINY" ), QVariant::Double ) ); fields.append( QgsField( QString( "MAXX" ), QVariant::Double ) ); fields.append( QgsField( QString( "MAXY" ), QVariant::Double ) ); fields.append( QgsField( QString( "CNTX" ), QVariant::Double ) ); fields.append( QgsField( QString( "CNTY" ), QVariant::Double ) ); fields.append( QgsField( QString( "AREA" ), QVariant::Double ) ); fields.append( QgsField( QString( "PERIM" ), QVariant::Double ) ); fields.append( QgsField( QString( "HEIGHT" ), QVariant::Double ) ); fields.append( QgsField( QString( "WIDTH" ), QVariant::Double ) ); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), fields, outputType, &crs ); QgsRectangle rect; if ( onlySelectedFeatures ) // take only selection { rect = layer->boundingBoxOfSelected(); } else { rect = layer->extent(); } double minx = rect.xMinimum(); double miny = rect.yMinimum(); double maxx = rect.xMaximum(); double maxy = rect.yMaximum(); double height = rect.height(); double width = rect.width(); double cntx = minx + ( width / 2.0 ); double cnty = miny + ( height / 2.0 ); double area = width * height; double perim = ( 2 * width ) + ( 2 * height ); QgsFeature feat; QgsAttributes attrs( 10 ); attrs[0] = QVariant( minx ); attrs[1] = QVariant( miny ); attrs[2] = QVariant( maxx ); attrs[3] = QVariant( maxy ); attrs[4] = QVariant( cntx ); attrs[5] = QVariant( cnty ); attrs[6] = QVariant( area ); attrs[7] = QVariant( perim ); attrs[8] = QVariant( height ); attrs[9] = QVariant( width ); feat.setAttributes( attrs ); feat.setGeometry( QgsGeometry::fromRect( rect ) ); vWriter.addFeature( feat ); return true; }
double QgsComposerScaleBar::mapWidth() const { if ( !mComposerMap ) { return 0.0; } QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() ); if ( mUnits == MapUnits ) { return composerMapRect.width(); } else { QgsDistanceArea da; da.setEllipsoidalMode( mComposerMap->mapRenderer()->hasCrsTransformEnabled() ); da.setSourceCrs( mComposerMap->mapRenderer()->destinationCrs().srsid() ); da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) ); double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) ); if ( mUnits == QgsComposerScaleBar::Feet ) { measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters ); } else if ( mUnits == QgsComposerScaleBar::NauticalMiles ) { measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters ); } return measure; } }
bool QgsVectorLayerRenderer::render() { if ( mGeometryType == QGis::NoGeometry || mGeometryType == QGis::UnknownGeometry ) return true; if ( !mRendererV2 ) { mErrors.append( QObject::tr( "No renderer for drawing." ) ); return false; } bool usingEffect = false; if ( mRendererV2->paintEffect() && mRendererV2->paintEffect()->enabled() ) { usingEffect = true; mRendererV2->paintEffect()->begin( mContext ); } // Per feature blending mode if ( mContext.useAdvancedEffects() && mFeatureBlendMode != QPainter::CompositionMode_SourceOver ) { // set the painter to the feature blend mode, so that features drawn // on this layer will interact and blend with each other mContext.painter()->setCompositionMode( mFeatureBlendMode ); } mRendererV2->startRender( mContext, mFields ); QString rendererFilter = mRendererV2->filter(); QgsRectangle requestExtent = mContext.extent(); mRendererV2->modifyRequestExtent( requestExtent, mContext ); QgsFeatureRequest featureRequest = QgsFeatureRequest() .setFilterRect( requestExtent ) .setSubsetOfAttributes( mAttrNames, mFields ); if ( !rendererFilter.isEmpty() ) { featureRequest.setFilterExpression( rendererFilter ); featureRequest.setExpressionContext( mContext.expressionContext() ); } // enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine. if ( mSimplifyGeometry ) { double map2pixelTol = mSimplifyMethod.threshold(); bool validTransform = true; const QgsMapToPixel& mtp = mContext.mapToPixel(); map2pixelTol *= mtp.mapUnitsPerPixel(); const QgsCoordinateTransform* ct = mContext.coordinateTransform(); // resize the tolerance using the change of size of an 1-BBOX from the source CoordinateSystem to the target CoordinateSystem if ( ct && !(( QgsCoordinateTransform* )ct )->isShortCircuited() ) { try { QgsPoint center = mContext.extent().center(); double rectSize = ct->sourceCrs().geographicFlag() ? 0.0008983 /* ~100/(40075014/360=111319.4833) */ : 100; QgsRectangle sourceRect = QgsRectangle( center.x(), center.y(), center.x() + rectSize, center.y() + rectSize ); QgsRectangle targetRect = ct->transform( sourceRect ); QgsDebugMsg( QString( "Simplify - SourceTransformRect=%1" ).arg( sourceRect.toString( 16 ) ) ); QgsDebugMsg( QString( "Simplify - TargetTransformRect=%1" ).arg( targetRect.toString( 16 ) ) ); if ( !sourceRect.isEmpty() && sourceRect.isFinite() && !targetRect.isEmpty() && targetRect.isFinite() ) { QgsPoint minimumSrcPoint( sourceRect.xMinimum(), sourceRect.yMinimum() ); QgsPoint maximumSrcPoint( sourceRect.xMaximum(), sourceRect.yMaximum() ); QgsPoint minimumDstPoint( targetRect.xMinimum(), targetRect.yMinimum() ); QgsPoint maximumDstPoint( targetRect.xMaximum(), targetRect.yMaximum() ); double sourceHypothenuse = sqrt( minimumSrcPoint.sqrDist( maximumSrcPoint ) ); double targetHypothenuse = sqrt( minimumDstPoint.sqrDist( maximumDstPoint ) ); QgsDebugMsg( QString( "Simplify - SourceHypothenuse=%1" ).arg( sourceHypothenuse ) ); QgsDebugMsg( QString( "Simplify - TargetHypothenuse=%1" ).arg( targetHypothenuse ) ); if ( targetHypothenuse != 0 ) map2pixelTol *= ( sourceHypothenuse / targetHypothenuse ); } } catch ( QgsCsException &cse ) { QgsMessageLog::logMessage( QObject::tr( "Simplify transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) ); validTransform = false; } } if ( validTransform ) { QgsSimplifyMethod simplifyMethod; simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering ); simplifyMethod.setTolerance( map2pixelTol ); simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() ); featureRequest.setSimplifyMethod( simplifyMethod ); QgsVectorSimplifyMethod vectorMethod = mSimplifyMethod; mContext.setVectorSimplifyMethod( vectorMethod ); } else { QgsVectorSimplifyMethod vectorMethod; vectorMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification ); mContext.setVectorSimplifyMethod( vectorMethod ); } } else { QgsVectorSimplifyMethod vectorMethod; vectorMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification ); mContext.setVectorSimplifyMethod( vectorMethod ); } QgsFeatureIterator fit = mSource->getFeatures( featureRequest ); if (( mRendererV2->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && mRendererV2->usingSymbolLevels() ) drawRendererV2Levels( fit ); else drawRendererV2( fit ); if ( usingEffect ) { mRendererV2->paintEffect()->end( mContext ); } //apply layer transparency for vector layers if ( mContext.useAdvancedEffects() && mLayerTransparency != 0 ) { // a layer transparency has been set, so update the alpha for the flattened layer // by combining it with the layer transparency QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * mLayerTransparency / 100 ) ); // use destination in composition mode to merge source's alpha with destination mContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn ); mContext.painter()->fillRect( 0, 0, mContext.painter()->device()->width(), mContext.painter()->device()->height(), transparentFillColor ); } return true; }
QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback ) { QgsDebugMsgLevel( QString( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 ); QgsDebugMsgLevel( QString( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 ); QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height ); if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) ) { block->setNoDataValue( sourceNoDataValue( bandNo ) ); } if ( block->isEmpty() ) { QgsDebugMsg( "Couldn't create raster block" ); return block; } // Read necessary extent only QgsRectangle tmpExtent = extent().intersect( &boundingBox ); if ( tmpExtent.isEmpty() ) { QgsDebugMsg( "Extent outside provider extent" ); block->setIsNoData(); return block; } double xRes = boundingBox.width() / width; double yRes = boundingBox.height() / height; double tmpXRes, tmpYRes; double providerXRes = 0; double providerYRes = 0; if ( capabilities() & Size ) { providerXRes = extent().width() / xSize(); providerYRes = extent().height() / ySize(); tmpXRes = std::max( providerXRes, xRes ); tmpYRes = std::max( providerYRes, yRes ); if ( qgsDoubleNear( tmpXRes, xRes ) ) tmpXRes = xRes; if ( qgsDoubleNear( tmpYRes, yRes ) ) tmpYRes = yRes; } else { tmpXRes = xRes; tmpYRes = yRes; } if ( tmpExtent != boundingBox || tmpXRes > xRes || tmpYRes > yRes ) { // Read smaller extent or lower resolution if ( !extent().contains( boundingBox ) ) { QRect subRect = QgsRasterBlock::subRect( boundingBox, width, height, extent() ); block->setIsNoDataExcept( subRect ); } // Calculate row/col limits (before tmpExtent is aligned) int fromRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMaximum() ) / yRes ); int toRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1; int fromCol = std::round( ( tmpExtent.xMinimum() - boundingBox.xMinimum() ) / xRes ); int toCol = std::round( ( tmpExtent.xMaximum() - boundingBox.xMinimum() ) / xRes ) - 1; QgsDebugMsgLevel( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 ); if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height || fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width ) { // Should not happen QgsDebugMsg( "Row or column limits out of range" ); return block; } // If lower source resolution is used, the extent must beS aligned to original // resolution to avoid possible shift due to resampling if ( tmpXRes > xRes ) { int col = std::floor( ( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes ); tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes ); col = std::ceil( ( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes ); tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes ); } if ( tmpYRes > yRes ) { int row = std::floor( ( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes ); tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes ); row = std::ceil( ( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes ); tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes ); } int tmpWidth = std::round( tmpExtent.width() / tmpXRes ); int tmpHeight = std::round( tmpExtent.height() / tmpYRes ); tmpXRes = tmpExtent.width() / tmpWidth; tmpYRes = tmpExtent.height() / tmpHeight; QgsDebugMsgLevel( QString( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 ); QgsDebugMsgLevel( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 ); QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( bandNo ), tmpWidth, tmpHeight ); if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) ) { tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) ); } readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ); int pixelSize = dataTypeSize( bandNo ); double xMin = boundingBox.xMinimum(); double yMax = boundingBox.yMaximum(); double tmpXMin = tmpExtent.xMinimum(); double tmpYMax = tmpExtent.yMaximum(); for ( int row = fromRow; row <= toRow; row++ ) { double y = yMax - ( row + 0.5 ) * yRes; int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes ); for ( int col = fromCol; col <= toCol; col++ ) { double x = xMin + ( col + 0.5 ) * xRes; int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes ); if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth ) { QgsDebugMsg( "Source row or column limits out of range" ); block->setIsNoData(); // so that the problem becomes obvious and fixed delete tmpBlock; return block; } qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol; qgssize index = row * static_cast< qgssize >( width ) + col; char *tmpBits = tmpBlock->bits( tmpIndex ); char *bits = block->bits( index ); if ( !tmpBits ) { QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) ); continue; } if ( !bits ) { QgsDebugMsg( "Cannot set output block data." ); continue; } memcpy( bits, tmpBits, pixelSize ); } } delete tmpBlock; } else { readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ); } // apply scale and offset block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) ); // apply user no data values block->applyNoDataValues( userNoDataValues( bandNo ) ); return block; }
bool QgsAlignRaster::checkInputParameters() { mErrorMessage.clear(); if ( mCrsWkt == "_error_" ) { mErrorMessage = QObject::tr( "Unable to reproject." ); return false; } if ( mCellSizeX == 0 || mCellSizeY == 0 ) { mErrorMessage = QObject::tr( "Cell size must not be zero." ); return false; } mXSize = mYSize = 0; for ( int i = 0; i < 6; ++i ) mGeoTransform[i] = 0; double finalExtent[4] = { 0, 0, 0, 0 }; // for each raster: determine their extent in projected cfg for ( int i = 0; i < mRasters.count(); ++i ) { Item& r = mRasters[i]; RasterInfo info( r.inputFilename ); QSizeF cs; QgsRectangle extent; if ( !suggestedWarpOutput( info, mCrsWkt, &cs, 0, &extent ) ) { mErrorMessage = QString( "Failed to get suggested warp output.\n\n" "File:\n%1\n\n" "Source WKT:\n%2\n\nDestination WKT:\n%3" ) .arg( r.inputFilename ) .arg( info.mCrsWkt ) .arg( mCrsWkt ); return false; } r.srcCellSizeInDestCRS = cs.width() * cs.height(); if ( finalExtent[0] == 0 && finalExtent[1] == 0 && finalExtent[2] == 0 && finalExtent[3] == 0 ) { // initialize with the first layer finalExtent[0] = extent.xMinimum(); finalExtent[1] = extent.yMinimum(); finalExtent[2] = extent.xMaximum(); finalExtent[3] = extent.yMaximum(); } else { // use intersection of rects if ( extent.xMinimum() > finalExtent[0] ) finalExtent[0] = extent.xMinimum(); if ( extent.yMinimum() > finalExtent[1] ) finalExtent[1] = extent.yMinimum(); if ( extent.xMaximum() < finalExtent[2] ) finalExtent[2] = extent.xMaximum(); if ( extent.yMaximum() < finalExtent[3] ) finalExtent[3] = extent.yMaximum(); } } // count in extra clip extent (if present) // 1. align requested rect to the grid - extend the rect if necessary // 2. intersect with clip extent with final extent if ( !( mClipExtent[0] == 0 && mClipExtent[1] == 0 && mClipExtent[2] == 0 && mClipExtent[3] == 0 ) ) { // extend clip extent to grid double clipX0 = floor_with_tolerance(( mClipExtent[0] - mGridOffsetX ) / mCellSizeX ) * mCellSizeX + mGridOffsetX; double clipY0 = floor_with_tolerance(( mClipExtent[1] - mGridOffsetY ) / mCellSizeY ) * mCellSizeY + mGridOffsetY; double clipX1 = ceil_with_tolerance(( mClipExtent[2] - clipX0 ) / mCellSizeX ) * mCellSizeX + clipX0; double clipY1 = ceil_with_tolerance(( mClipExtent[3] - clipY0 ) / mCellSizeY ) * mCellSizeY + clipY0; if ( clipX0 > finalExtent[0] ) finalExtent[0] = clipX0; if ( clipY0 > finalExtent[1] ) finalExtent[1] = clipY0; if ( clipX1 < finalExtent[2] ) finalExtent[2] = clipX1; if ( clipY1 < finalExtent[3] ) finalExtent[3] = clipY1; } // align to grid - shrink the rect if necessary // output raster grid configuration (with no rotation/shear) // ... and raster width/height double originX = ceil_with_tolerance(( finalExtent[0] - mGridOffsetX ) / mCellSizeX ) * mCellSizeX + mGridOffsetX;; double originY = ceil_with_tolerance(( finalExtent[1] - mGridOffsetY ) / mCellSizeY ) * mCellSizeY + mGridOffsetY; int xSize = floor_with_tolerance(( finalExtent[2] - originX ) / mCellSizeX ); int ySize = floor_with_tolerance(( finalExtent[3] - originY ) / mCellSizeY ); if ( xSize <= 0 || ySize <= 0 ) { mErrorMessage = QObject::tr( "No common intersecting area." ); return false; } mXSize = xSize; mYSize = ySize; // build final geotransform... mGeoTransform[0] = originX; mGeoTransform[1] = mCellSizeX; mGeoTransform[2] = 0; mGeoTransform[3] = originY + ( mCellSizeY * ySize ); mGeoTransform[4] = 0; mGeoTransform[5] = -mCellSizeY; return true; }
void QgsRasterCalculator::readRasterPart( double* targetGeotransform, int xOffset, int yOffset, int nCols, int nRows, double* sourceTransform, GDALRasterBandH sourceBand, float* rasterBuffer ) { //If dataset transform is the same as the requested transform, do a normal GDAL raster io if ( transformationsEqual( targetGeotransform, sourceTransform ) ) { GDALRasterIO( sourceBand, GF_Read, xOffset, yOffset, nCols, nRows, rasterBuffer, nCols, nRows, GDT_Float32, 0, 0 ); return; } //pixel calculation needed because of different raster position / resolution int nodataSuccess; double nodataValue = GDALGetRasterNoDataValue( sourceBand, &nodataSuccess ); QgsRectangle targetRect( targetGeotransform[0] + targetGeotransform[1] * xOffset, targetGeotransform[3] + yOffset * targetGeotransform[5] + nRows * targetGeotransform[5] , targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] * nCols, targetGeotransform[3] + yOffset * targetGeotransform[5] ); QgsRectangle sourceRect( sourceTransform[0], sourceTransform[3] + GDALGetRasterBandYSize( sourceBand ) * sourceTransform[5], sourceTransform[0] + GDALGetRasterBandXSize( sourceBand )* sourceTransform[1], sourceTransform[3] ); QgsRectangle intersection = targetRect.intersect( &sourceRect ); //no intersection, fill all the pixels with nodata values if ( intersection.isEmpty() ) { int nPixels = nCols * nRows; for ( int i = 0; i < nPixels; ++i ) { rasterBuffer[i] = nodataValue; } return; } //do raster io in source resolution int sourcePixelOffsetXMin = floor(( intersection.xMinimum() - sourceTransform[0] ) / sourceTransform[1] ); int sourcePixelOffsetXMax = ceil(( intersection.xMaximum() - sourceTransform[0] ) / sourceTransform[1] ); int nSourcePixelsX = sourcePixelOffsetXMax - sourcePixelOffsetXMin; int sourcePixelOffsetYMax = floor(( intersection.yMaximum() - sourceTransform[3] ) / sourceTransform[5] ); int sourcePixelOffsetYMin = ceil(( intersection.yMinimum() - sourceTransform[3] ) / sourceTransform[5] ); int nSourcePixelsY = sourcePixelOffsetYMin - sourcePixelOffsetYMax; float* sourceRaster = ( float * ) CPLMalloc( sizeof( float ) * nSourcePixelsX * nSourcePixelsY ); double sourceRasterXMin = sourceRect.xMinimum() + sourcePixelOffsetXMin * sourceTransform[1]; double sourceRasterYMax = sourceRect.yMaximum() + sourcePixelOffsetYMax * sourceTransform[5]; GDALRasterIO( sourceBand, GF_Read, sourcePixelOffsetXMin, sourcePixelOffsetYMax, nSourcePixelsX, nSourcePixelsY, sourceRaster, nSourcePixelsX, nSourcePixelsY, GDT_Float32, 0, 0 ); double targetPixelX; double targetPixelXMin = targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] / 2.0; double targetPixelY = targetGeotransform[3] + targetGeotransform[5] * yOffset + targetGeotransform[5] / 2.0; //coordinates of current target pixel int sourceIndexX, sourceIndexY; //current raster index in source pixels double sx, sy; for ( int i = 0; i < nRows; ++i ) { targetPixelX = targetPixelXMin; for ( int j = 0; j < nCols; ++j ) { sx = ( targetPixelX - sourceRasterXMin ) / sourceTransform[1]; sourceIndexX = sx > 0 ? sx : floor( sx ); sy = ( targetPixelY - sourceRasterYMax ) / sourceTransform[5]; sourceIndexY = sy > 0 ? sy : floor( sy ); if ( sourceIndexX >= 0 && sourceIndexX < nSourcePixelsX && sourceIndexY >= 0 && sourceIndexY < nSourcePixelsY ) { rasterBuffer[j + i*nRows] = sourceRaster[ sourceIndexX + nSourcePixelsX * sourceIndexY ]; } else { rasterBuffer[j + i*j] = nodataValue; } targetPixelX += targetGeotransform[1]; } targetPixelY += targetGeotransform[5]; } CPLFree( sourceRaster ); return; }
void QgsComposerMapWidget::updateGuiElements() { if ( mComposerMap ) { blockAllSignals( true ); //width, height, scale QRectF composerMapRect = mComposerMap->rect(); mWidthLineEdit->setText( QString::number( composerMapRect.width() ) ); mHeightLineEdit->setText( QString::number( composerMapRect.height() ) ); mScaleLineEdit->setText( QString::number( mComposerMap->scale(), 'f', 0 ) ); //preview mode QgsComposerMap::PreviewMode previewMode = mComposerMap->previewMode(); int index = -1; if ( previewMode == QgsComposerMap::Cache ) { index = mPreviewModeComboBox->findText( tr( "Cache" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Render ) { index = mPreviewModeComboBox->findText( tr( "Render" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Rectangle ) { index = mPreviewModeComboBox->findText( tr( "Rectangle" ) ); mUpdatePreviewButton->setEnabled( false ); } if ( index != -1 ) { mPreviewModeComboBox->setCurrentIndex( index ); } //composer map extent QgsRectangle composerMapExtent = mComposerMap->extent(); mXMinLineEdit->setText( QString::number( composerMapExtent.xMinimum(), 'f', 3 ) ); mXMaxLineEdit->setText( QString::number( composerMapExtent.xMaximum(), 'f', 3 ) ); mYMinLineEdit->setText( QString::number( composerMapExtent.yMinimum(), 'f', 3 ) ); mYMaxLineEdit->setText( QString::number( composerMapExtent.yMaximum(), 'f', 3 ) ); mRotationSpinBox->setValue( mComposerMap->rotation() ); //keep layer list check box if ( mComposerMap->keepLayerSet() ) { mKeepLayerListCheckBox->setCheckState( Qt::Checked ); } else { mKeepLayerListCheckBox->setCheckState( Qt::Unchecked ); } //draw canvas items if ( mComposerMap->drawCanvasItems() ) { mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked ); } else { mDrawCanvasItemsCheckBox->setCheckState( Qt::Unchecked ); } //grid if ( mComposerMap->gridEnabled() ) { mGridCheckBox->setChecked( true ); } else { mGridCheckBox->setChecked( false ); } mIntervalXSpinBox->setValue( mComposerMap->gridIntervalX() ); mIntervalYSpinBox->setValue( mComposerMap->gridIntervalY() ); mOffsetXSpinBox->setValue( mComposerMap->gridOffsetX() ); mOffsetYSpinBox->setValue( mComposerMap->gridOffsetY() ); QgsComposerMap::GridStyle gridStyle = mComposerMap->gridStyle(); if ( gridStyle == QgsComposerMap::Cross ) { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Cross" ) ) ); } else { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Solid" ) ) ); } mCrossWidthSpinBox->setValue( mComposerMap->crossLength() ); QgsComposerMap::GridAnnotationPosition annotationPos = mComposerMap->gridAnnotationPosition(); if ( annotationPos == QgsComposerMap::InsideMapFrame ) { mAnnotationPositionComboBox->setCurrentIndex( mAnnotationPositionComboBox->findText( tr( "Inside frame" ) ) ); } else { mAnnotationPositionComboBox->setCurrentIndex( mAnnotationPositionComboBox->findText( tr( "Outside frame" ) ) ); } mDistanceToMapFrameSpinBox->setValue( mComposerMap->annotationFrameDistance() ); if ( mComposerMap->showGridAnnotation() ) { mDrawAnnotationCheckBox->setCheckState( Qt::Checked ); } else { mDrawAnnotationCheckBox->setCheckState( Qt::Unchecked ); } QgsComposerMap::GridAnnotationDirection dir = mComposerMap->gridAnnotationDirection(); if ( dir == QgsComposerMap::Horizontal ) { mAnnotationDirectionComboBox->setCurrentIndex( mAnnotationDirectionComboBox->findText( tr( "Horizontal" ) ) ); } else if ( dir == QgsComposerMap::Vertical ) { mAnnotationDirectionComboBox->setCurrentIndex( mAnnotationDirectionComboBox->findText( tr( "Vertical" ) ) ); } else if ( dir == QgsComposerMap::HorizontalAndVertical ) { mAnnotationDirectionComboBox->setCurrentIndex( mAnnotationDirectionComboBox->findText( tr( "Horizontal and Vertical" ) ) ); } else //BoundaryDirection { mAnnotationDirectionComboBox->setCurrentIndex( mAnnotationDirectionComboBox->findText( tr( "Boundary direction" ) ) ); } mCoordinatePrecisionSpinBox->setValue( mComposerMap->gridAnnotationPrecision() ); QPen gridPen = mComposerMap->gridPen(); mLineWidthSpinBox->setValue( gridPen.widthF() ); mLineColorButton->setColor( gridPen.color() ); blockAllSignals( false ); } }
void QgsWFSProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const { const QList<QDomElement>& projectLayerElements = mProjectParser.projectLayerElements(); if ( projectLayerElements.size() < 1 ) { return; } QStringList wfsLayersId = mProjectParser.wfsLayers(); QStringList wfstUpdateLayersId = wfstUpdateLayers(); QStringList wfstInsertLayersId = wfstInsertLayers(); QStringList wfstDeleteLayersId = wfstDeleteLayers(); QMap<QString, QgsMapLayer *> layerMap; foreach ( const QDomElement &elem, projectLayerElements ) { QString type = elem.attribute( "type" ); if ( type == "vector" ) { QgsMapLayer *layer = mProjectParser.createLayerFromElement( elem ); if ( layer && wfsLayersId.contains( layer->id() ) ) { QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) ); layerMap.insert( layer->id(), layer ); QDomElement layerElem = doc.createElement( "FeatureType" ); QDomElement nameElem = doc.createElement( "Name" ); //We use the layer name even though it might not be unique. //Because the id sometimes contains user/pw information and the name is more descriptive QString typeName = layer->name(); typeName = typeName.replace( " ", "_" ); QDomText nameText = doc.createTextNode( typeName ); nameElem.appendChild( nameText ); layerElem.appendChild( nameElem ); QDomElement titleElem = doc.createElement( "Title" ); QString titleName = layer->title(); if ( titleName.isEmpty() ) { titleName = layer->name(); } QDomText titleText = doc.createTextNode( titleName ); titleElem.appendChild( titleText ); layerElem.appendChild( titleElem ); QDomElement abstractElem = doc.createElement( "Abstract" ); QString abstractName = layer->abstract(); if ( abstractName.isEmpty() ) { abstractName = ""; } QDomText abstractText = doc.createTextNode( abstractName ); abstractElem.appendChild( abstractText ); layerElem.appendChild( abstractElem ); //keyword list if ( !layer->keywordList().isEmpty() ) { QDomElement keywordsElem = doc.createElement( "Keywords" ); QDomText keywordsText = doc.createTextNode( layer->keywordList() ); keywordsElem.appendChild( keywordsText ); layerElem.appendChild( keywordsElem ); } //appendExGeographicBoundingBox( layerElem, doc, layer->extent(), layer->crs() ); QDomElement srsElem = doc.createElement( "SRS" ); QDomText srsText = doc.createTextNode( layer->crs().authid() ); srsElem.appendChild( srsText ); layerElem.appendChild( srsElem ); //wfs:Operations element QDomElement operationsElement = doc.createElement( "Operations"/*wfs:Operations*/ ); //wfs:Query element QDomElement queryElement = doc.createElement( "Query"/*wfs:Query*/ ); operationsElement.appendChild( queryElement ); QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( layer ); QgsVectorDataProvider* provider = vlayer->dataProvider(); if (( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) && wfstInsertLayersId.contains( layer->id() ) ) { //wfs:Insert element QDomElement insertElement = doc.createElement( "Insert"/*wfs:Insert*/ ); operationsElement.appendChild( insertElement ); } if (( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) && ( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) && wfstUpdateLayersId.contains( layer->id() ) ) { //wfs:Update element QDomElement updateElement = doc.createElement( "Update"/*wfs:Update*/ ); operationsElement.appendChild( updateElement ); } if (( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) && wfstDeleteLayersId.contains( layer->id() ) ) { //wfs:Delete element QDomElement deleteElement = doc.createElement( "Delete"/*wfs:Delete*/ ); operationsElement.appendChild( deleteElement ); } layerElem.appendChild( operationsElement ); QgsRectangle layerExtent = layer->extent(); QDomElement bBoxElement = doc.createElement( "LatLongBoundingBox" ); bBoxElement.setAttribute( "minx", QString::number( layerExtent.xMinimum() ) ); bBoxElement.setAttribute( "miny", QString::number( layerExtent.yMinimum() ) ); bBoxElement.setAttribute( "maxx", QString::number( layerExtent.xMaximum() ) ); bBoxElement.setAttribute( "maxy", QString::number( layerExtent.yMaximum() ) ); layerElem.appendChild( bBoxElement ); // layer metadata URL QString metadataUrl = layer->metadataUrl(); if ( !metadataUrl.isEmpty() ) { QDomElement metaUrlElem = doc.createElement( "MetadataURL" ); QString metadataUrlType = layer->metadataUrlType(); metaUrlElem.setAttribute( "type", metadataUrlType ); QString metadataUrlFormat = layer->metadataUrlFormat(); if ( metadataUrlFormat == "text/xml" ) { metaUrlElem.setAttribute( "format", "XML" ); } else { metaUrlElem.setAttribute( "format", "TXT" ); } QDomText metaUrlText = doc.createTextNode( metadataUrl ); metaUrlElem.appendChild( metaUrlText ); layerElem.appendChild( metaUrlElem ); } parentElement.appendChild( layerElem ); } } }
bool isSegmentInRect( double x0, double y0, double x1, double y1 ) { // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle OutCode outcode0 = computeOutCode( x0, y0 ); OutCode outcode1 = computeOutCode( x1, y1 ); bool accept = false; while ( true ) { if ( !( outcode0 | outcode1 ) ) { // Bitwise OR is 0. Trivially accept and get out of loop accept = true; break; } else if ( outcode0 & outcode1 ) { // Bitwise AND is not 0. Trivially reject and get out of loop break; } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge double x, y; // At least one endpoint is outside the clip rectangle; pick it. OutCode outcodeOut = outcode0 ? outcode0 : outcode1; // Now find the intersection point; // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0) if ( outcodeOut & TOP ) { // point is above the clip rectangle x = x0 + ( x1 - x0 ) * ( mRect.yMaximum() - y0 ) / ( y1 - y0 ); y = mRect.yMaximum(); } else if ( outcodeOut & BOTTOM ) { // point is below the clip rectangle x = x0 + ( x1 - x0 ) * ( mRect.yMinimum() - y0 ) / ( y1 - y0 ); y = mRect.yMinimum(); } else if ( outcodeOut & RIGHT ) { // point is to the right of clip rectangle y = y0 + ( y1 - y0 ) * ( mRect.xMaximum() - x0 ) / ( x1 - x0 ); x = mRect.xMaximum(); } else if ( outcodeOut & LEFT ) { // point is to the left of clip rectangle y = y0 + ( y1 - y0 ) * ( mRect.xMinimum() - x0 ) / ( x1 - x0 ); x = mRect.xMinimum(); } else break; // Now we move outside point to intersection point to clip // and get ready for next pass. if ( outcodeOut == outcode0 ) { x0 = x; y0 = y; outcode0 = computeOutCode( x0, y0 ); } else { x1 = x; y1 = y; outcode1 = computeOutCode( x1, y1 ); } } } return accept; }
QList< tileMatrixSetDef > getTileMatrixSetList( const QgsProject *project, const QString &tms_ref ) { QList< tileMatrixSetDef > tmsList; bool gridsDefined = false; QStringList wmtsGridList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "CRS" ), QStringList(), &gridsDefined ); if ( gridsDefined ) { if ( !tms_ref.isEmpty() && !wmtsGridList.contains( tms_ref ) ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) ); } QStringList wmtsGridConfigList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "Config" ) ); for ( const QString &c : wmtsGridConfigList ) { QStringList config = c.split( ',' ); QString crsStr = config[0]; if ( !tms_ref.isEmpty() && tms_ref != crsStr ) { continue; } tileMatrixInfo tmi; double fixedTop = 0.0; double fixedLeft = 0.0; double resolution = -1.0; int col = -1; int row = -1; // Does the CRS have fixed tile matrices if ( fixedTileMatrixInfoMap.contains( crsStr ) ) { tmi = fixedTileMatrixInfoMap[crsStr]; // Calculate resolution based on scale denominator resolution = tmi.resolution; // Get fixed corner QgsRectangle extent = tmi.extent; fixedTop = extent.yMaximum(); fixedLeft = extent.xMinimum(); // Get numbers of column and row for the resolution to cover the extent col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) ); row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) ); } else { tmi.ref = crsStr; fixedTop = QVariant( config[1] ).toDouble(); fixedLeft = QVariant( config[2] ).toDouble(); double minScale = QVariant( config[3] ).toDouble(); tmi.scaleDenominator = minScale; QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsStr ); tmi.unit = crs.mapUnits(); tmi.hasAxisInverted = crs.hasAxisInverted(); QgsCoordinateTransform crsTransform( QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ), crs, project ); try { // firstly transform CRS bounds expressed in WGS84 to CRS QgsRectangle extent = crsTransform.transformBoundingBox( crs.bounds() ); // Calculate resolution based on scale denominator resolution = POINTS_TO_M * minScale / QgsUnitTypes::fromUnitToUnitFactor( tmi.unit, QgsUnitTypes::DistanceMeters ); // Get numbers of column and row for the resolution to cover the extent col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) ); row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) ); // Calculate extent double bottom = fixedTop - row * tileSize * resolution; double right = fixedLeft + col * tileSize * resolution; tmi.extent = QgsRectangle( fixedLeft, bottom, right, fixedTop ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ) continue; } } // get lastLevel tmi.lastLevel = QVariant( config[4] ).toInt(); QList< tileMatrixDef > tileMatrixList; for ( int i = 0; i <= tmi.lastLevel; ++i ) { double scale = tmi.scaleDenominator / std::pow( 2, i ); double res = resolution / std::pow( 2, i ); tileMatrixDef tm; tm.resolution = res; tm.scaleDenominator = scale; tm.col = col * std::pow( 2, i ); tm.row = row * std::pow( 2, i ); tm.left = fixedLeft; tm.top = fixedTop; tileMatrixList.append( tm ); } tileMatrixSetDef tms; tms.ref = tmi.ref; tms.extent = tmi.extent; tms.unit = tmi.unit; tms.hasAxisInverted = tmi.hasAxisInverted; tms.tileMatrixList = tileMatrixList; tmsList.append( tms ); } return tmsList; } double minScale = project->readNumEntry( QStringLiteral( "WMTSMinScale" ), QStringLiteral( "/" ), -1.0 ); if ( minScale == -1.0 ) { minScale = getProjectMinScale( project ); } QStringList crsList = QgsServerProjectUtils::wmsOutputCrsList( *project ); if ( !tms_ref.isEmpty() && !crsList.contains( tms_ref ) ) { throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) ); } for ( const QString &crsStr : crsList ) { if ( !tms_ref.isEmpty() && tms_ref != crsStr ) { continue; } tileMatrixInfo tmi = calculateTileMatrixInfo( crsStr, project ); if ( tmi.scaleDenominator > 0.0 ) { tmsList.append( calculateTileMatrixSet( tmi, minScale ) ); } } return tmsList; }
tileMatrixInfo calculateTileMatrixInfo( const QString &crsStr, const QgsProject *project ) { // Does the CRS have fixed tile matrices if ( fixedTileMatrixInfoMap.contains( crsStr ) ) return fixedTileMatrixInfoMap[crsStr]; // Does the CRS have already calculated tile matrices if ( calculatedTileMatrixInfoMap.contains( crsStr ) ) return calculatedTileMatrixInfoMap[crsStr]; tileMatrixInfo tmi; tmi.ref = crsStr; QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsStr ); QgsCoordinateTransform crsTransform( wgs84, crs, project ); try { tmi.extent = crsTransform.transformBoundingBox( crs.bounds() ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ) } tmi.unit = crs.mapUnits(); tmi.hasAxisInverted = crs.hasAxisInverted(); // calculate tile matrix scale denominator double scaleDenominator = 0.0; int colRes = ( tmi.extent.xMaximum() - tmi.extent.xMinimum() ) / tileSize; int rowRes = ( tmi.extent.yMaximum() - tmi.extent.yMinimum() ) / tileSize; double UNIT_TO_M = QgsUnitTypes::fromUnitToUnitFactor( tmi.unit, QgsUnitTypes::DistanceMeters ); if ( colRes > rowRes ) scaleDenominator = std::ceil( colRes * UNIT_TO_M / POINTS_TO_M ); else scaleDenominator = std::ceil( rowRes * UNIT_TO_M / POINTS_TO_M ); // Update extent to get a square one QgsRectangle extent = tmi.extent; double res = POINTS_TO_M * scaleDenominator / UNIT_TO_M; int col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * res ) ); int row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * res ) ); if ( col > 1 || row > 1 ) { // Update scale if ( col > row ) { res = col * res; scaleDenominator = col * scaleDenominator; } else { res = row * res; scaleDenominator = row * scaleDenominator; } // set col and row to 1 for the square col = 1; row = 1; } // Calculate extent double left = ( extent.xMinimum() + ( extent.xMaximum() - extent.xMinimum() ) / 2.0 ) - ( col / 2.0 ) * ( tileSize * res ); double bottom = ( extent.yMinimum() + ( extent.yMaximum() - extent.yMinimum() ) / 2.0 ) - ( row / 2.0 ) * ( tileSize * res ); double right = ( extent.xMinimum() + ( extent.xMaximum() - extent.xMinimum() ) / 2.0 ) + ( col / 2.0 ) * ( tileSize * res ); double top = ( extent.yMinimum() + ( extent.yMaximum() - extent.yMinimum() ) / 2.0 ) + ( row / 2.0 ) * ( tileSize * res ); tmi.extent = QgsRectangle( left, bottom, right, top ); tmi.resolution = res; tmi.scaleDenominator = scaleDenominator; calculatedTileMatrixInfoMap[crsStr] = tmi; return tmi; }
int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing ) { if ( !L->hasGeometryType() ) return 4; QgsFeatureList newFeatures; //store all the newly created features double xMin, yMin, xMax, yMax; QgsRectangle bBox; //bounding box of the split line int returnCode = 0; int splitFunctionReturn; //return code of QgsGeometry::splitGeometry int numberOfSplittedFeatures = 0; QgsFeatureList featureList; const QgsFeatureIds selectedIds = L->selectedFeaturesIds(); if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection { featureList = L->selectedFeatures(); } else //else consider all the feature that intersect the bounding box of the split line { if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 ) { bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin ); bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax ); } else { return 1; } if ( bBox.isEmpty() ) { //if the bbox is a line, try to make a square out of it if ( bBox.width() == 0.0 && bBox.height() > 0 ) { bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 ); bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 ); } else if ( bBox.height() == 0.0 && bBox.width() > 0 ) { bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 ); bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 ); } else { return 2; } } QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; while ( fit.nextFeature( f ) ) featureList << QgsFeature( f ); } QgsFeatureList::iterator select_it = featureList.begin(); for ( ; select_it != featureList.end(); ++select_it ) { if ( !select_it->geometry() ) { continue; } QList<QgsGeometry*> newGeometries; QList<QgsPoint> topologyTestPoints; QgsGeometry* newGeometry = 0; splitFunctionReturn = select_it->geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints ); if ( splitFunctionReturn == 0 ) { //change this geometry L->editBuffer()->changeGeometry( select_it->id(), select_it->geometry() ); //insert new features for ( int i = 0; i < newGeometries.size(); ++i ) { newGeometry = newGeometries.at( i ); QgsFeature newFeature; newFeature.setGeometry( newGeometry ); //use default value where possible (primary key issue), otherwise the value from the original (split) feature QgsAttributes newAttributes = select_it->attributes(); QVariant defaultValue; for ( int j = 0; j < newAttributes.count(); ++j ) { defaultValue = L->dataProvider()->defaultValue( j ); if ( !defaultValue.isNull() ) { newAttributes[ j ] = defaultValue; } } newFeature.setAttributes( newAttributes ); newFeatures.append( newFeature ); } if ( topologicalEditing ) { QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin(); for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it ) { addTopologicalPoints( *topol_it ); } } ++numberOfSplittedFeatures; } else if ( splitFunctionReturn > 1 ) //1 means no split but also no error { returnCode = splitFunctionReturn; } } if ( numberOfSplittedFeatures == 0 && selectedIds.size() > 0 ) { //There is a selection but no feature has been split. //Maybe user forgot that only the selected features are split returnCode = 4; } //now add the new features to this vectorlayer L->editBuffer()->addFeatures( newFeatures ); return returnCode; }
QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr& wkbPtr, const QgsRectangle& clipExtent, QPolygonF& line ) { QgsWKBTypes::Type wkbType = wkbPtr.readHeader(); int nPoints; wkbPtr >> nPoints; int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double ); if ( static_cast<int>( nPoints * ( 2 * sizeof( double ) + skipZM ) ) > wkbPtr.remaining() ) { QgsDebugMsg( QString( "%1 points exceed wkb length (%2>%3)" ).arg( nPoints ).arg( nPoints * ( 2 * sizeof( double ) + skipZM ) ).arg( wkbPtr.remaining() ) ); return QgsConstWkbPtr( nullptr, 0 ); } double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates double p1x_c, p1y_c; //clipped end coordinates double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords QPolygonF pts; wkbPtr -= sizeof( unsigned int ); wkbPtr >> pts; nPoints = pts.size(); line.clear(); line.reserve( nPoints + 1 ); QPointF *ptr = pts.data(); for ( int i = 0; i < nPoints; ++i, ++ptr ) { if ( i == 0 ) { p1x = ptr->rx(); p1y = ptr->ry(); continue; } else { p0x = p1x; p0y = p1y; p1x = ptr->rx(); p1y = ptr->ry(); p1x_c = p1x; p1y_c = p1y; if ( clipLineSegment( clipExtent.xMinimum(), clipExtent.xMaximum(), clipExtent.yMinimum(), clipExtent.yMaximum(), p0x, p0y, p1x_c, p1y_c ) ) { bool newLine = !line.isEmpty() && ( !qgsDoubleNear( p0x, lastClipX ) || !qgsDoubleNear( p0y, lastClipY ) ); if ( newLine ) { //add edge points to connect old and new line connectSeparatedLines( lastClipX, lastClipY, p0x, p0y, clipExtent, line ); } if ( line.size() < 1 || newLine ) { //add first point line << QPointF( p0x, p0y ); } //add second point lastClipX = p1x_c; lastClipY = p1y_c; line << QPointF( p1x_c, p1y_c ); } } } return wkbPtr; }
void QgsClipper::connectSeparatedLines( double x0, double y0, double x1, double y1, const QgsRectangle& clipRect, QPolygonF& pts ) { //test the different edge combinations... if ( qgsDoubleNear( x0, clipRect.xMinimum() ) ) { if ( qgsDoubleNear( x1, clipRect.xMinimum() ) ) { return; } else if ( qgsDoubleNear( y1, clipRect.yMaximum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() ); return; } else if ( qgsDoubleNear( x1, clipRect.xMaximum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() ); pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() ); return; } else if ( qgsDoubleNear( y1, clipRect.yMinimum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() ); return; } } else if ( qgsDoubleNear( y0, clipRect.yMaximum() ) ) { if ( qgsDoubleNear( y1, clipRect.yMaximum() ) ) { return; } else if ( qgsDoubleNear( x1, clipRect.xMaximum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() ); return; } else if ( qgsDoubleNear( y1, clipRect.yMinimum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() ); pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() ); return; } else if ( qgsDoubleNear( x1, clipRect.xMinimum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() ); return; } } else if ( qgsDoubleNear( x0, clipRect.xMaximum() ) ) { if ( qgsDoubleNear( x1, clipRect.xMaximum() ) ) { return; } else if ( qgsDoubleNear( y1, clipRect.yMinimum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() ); return; } else if ( qgsDoubleNear( x1, clipRect.xMinimum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() ); pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() ); return; } else if ( qgsDoubleNear( y1, clipRect.yMaximum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() ); return; } } else if ( qgsDoubleNear( y0, clipRect.yMinimum() ) ) { if ( qgsDoubleNear( y1, clipRect.yMinimum() ) ) { return; } else if ( qgsDoubleNear( x1, clipRect.xMinimum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() ); return; } else if ( qgsDoubleNear( y1, clipRect.yMaximum() ) ) { pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() ); pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() ); return; } else if ( qgsDoubleNear( x1, clipRect.xMaximum() ) ) { pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() ); return; } } }
bool QgsMapRendererJob::reprojectToLayerExtent( const QgsMapLayer *ml, const QgsCoordinateTransform &ct, QgsRectangle &extent, QgsRectangle &r2 ) { bool split = false; try { #ifdef QGISDEBUG // QgsLogger::debug<QgsRectangle>("Getting extent of canvas in layers CS. Canvas is ", extent, __FILE__, __FUNCTION__, __LINE__); #endif // Split the extent into two if the source CRS is // geographic and the extent crosses the split in // geographic coordinates (usually +/- 180 degrees, // and is assumed to be so here), and draw each // extent separately. static const double SPLIT_COORD = 180.0; if ( ml->crs().isGeographic() ) { if ( ml->type() == QgsMapLayer::VectorLayer && !ct.destinationCrs().isGeographic() ) { // if we transform from a projected coordinate system check // check if transforming back roughly returns the input // extend - otherwise render the world. QgsRectangle extent1 = ct.transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform ); QgsRectangle extent2 = ct.transformBoundingBox( extent1, QgsCoordinateTransform::ForwardTransform ); QgsDebugMsgLevel( QString( "\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" ) .arg( extent.toString() ).arg( extent.width() ).arg( extent.height() ) .arg( extent1.toString(), extent2.toString() ).arg( extent2.width() ).arg( extent2.height() ) .arg( std::fabs( 1.0 - extent2.width() / extent.width() ) ) .arg( std::fabs( 1.0 - extent2.height() / extent.height() ) ) , 3 ); if ( std::fabs( 1.0 - extent2.width() / extent.width() ) < 0.5 && std::fabs( 1.0 - extent2.height() / extent.height() ) < 0.5 ) { extent = extent1; } else { extent = QgsRectangle( -180.0, -90.0, 180.0, 90.0 ); } } else { // Note: ll = lower left point QgsPointXY ll = ct.transform( extent.xMinimum(), extent.yMinimum(), QgsCoordinateTransform::ReverseTransform ); // and ur = upper right point QgsPointXY ur = ct.transform( extent.xMaximum(), extent.yMaximum(), QgsCoordinateTransform::ReverseTransform ); QgsDebugMsgLevel( QString( "in:%1 (ll:%2 ur:%3)" ).arg( extent.toString(), ll.toString(), ur.toString() ), 4 ); extent = ct.transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform ); QgsDebugMsgLevel( QString( "out:%1 (w:%2 h:%3)" ).arg( extent.toString() ).arg( extent.width() ).arg( extent.height() ), 4 ); if ( ll.x() > ur.x() ) { // the coordinates projected in reverse order than what one would expect. // we are probably looking at an area that includes longitude of 180 degrees. // we need to take into account coordinates from two intervals: (-180,x1) and (x2,180) // so let's use (-180,180). This hopefully does not add too much overhead. It is // more straightforward than rendering with two separate extents and more consistent // for rendering, labeling and caching as everything is rendered just in one go extent.setXMinimum( -SPLIT_COORD ); extent.setXMaximum( SPLIT_COORD ); } } // TODO: the above rule still does not help if using a projection that covers the whole // world. E.g. with EPSG:3857 the longitude spectrum -180 to +180 is mapped to approx. // -2e7 to +2e7. Converting extent from -5e7 to +5e7 is transformed as -90 to +90, // but in fact the extent should cover the whole world. } else // can't cross 180 { if ( ct.destinationCrs().isGeographic() && ( extent.xMinimum() <= -180 || extent.xMaximum() >= 180 || extent.yMinimum() <= -90 || extent.yMaximum() >= 90 ) ) // Use unlimited rectangle because otherwise we may end up transforming wrong coordinates. // E.g. longitude -200 to +160 would be understood as +40 to +160 due to periodicity. // We could try to clamp coords to (-180,180) for lon resp. (-90,90) for lat, // but this seems like a safer choice. extent = QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX ); else extent = ct.transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform ); } } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); QgsDebugMsg( "Transform error caught" ); extent = QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX ); r2 = QgsRectangle( -DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX ); } return split; }
static SpatialIndex::Region rect2region( const QgsRectangle &rect ) { double pLow[2] = { rect.xMinimum(), rect.yMinimum() }; double pHigh[2] = { rect.xMaximum(), rect.yMaximum() }; return SpatialIndex::Region( pLow, pHigh, 2 ); }
void QgsComposerMapWidget::updateGuiElements() { if ( mComposerMap ) { blockAllSignals( true ); //width, height, scale QRectF composerMapRect = mComposerMap->rect(); mWidthLineEdit->setText( QString::number( composerMapRect.width() ) ); mHeightLineEdit->setText( QString::number( composerMapRect.height() ) ); mScaleLineEdit->setText( QString::number( mComposerMap->scale(), 'f', 0 ) ); //preview mode QgsComposerMap::PreviewMode previewMode = mComposerMap->previewMode(); int index = -1; if ( previewMode == QgsComposerMap::Cache ) { index = mPreviewModeComboBox->findText( tr( "Cache" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Render ) { index = mPreviewModeComboBox->findText( tr( "Render" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Rectangle ) { index = mPreviewModeComboBox->findText( tr( "Rectangle" ) ); mUpdatePreviewButton->setEnabled( false ); } if ( index != -1 ) { mPreviewModeComboBox->setCurrentIndex( index ); } //composer map extent QgsRectangle composerMapExtent = mComposerMap->extent(); mXMinLineEdit->setText( QString::number( composerMapExtent.xMinimum(), 'f', 3 ) ); mXMaxLineEdit->setText( QString::number( composerMapExtent.xMaximum(), 'f', 3 ) ); mYMinLineEdit->setText( QString::number( composerMapExtent.yMinimum(), 'f', 3 ) ); mYMaxLineEdit->setText( QString::number( composerMapExtent.yMaximum(), 'f', 3 ) ); mRotationSpinBox->setValue( mComposerMap->rotation() ); //keep layer list check box if ( mComposerMap->keepLayerSet() ) { mKeepLayerListCheckBox->setCheckState( Qt::Checked ); } else { mKeepLayerListCheckBox->setCheckState( Qt::Unchecked ); } //draw canvas items if ( mComposerMap->drawCanvasItems() ) { mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked ); } else { mDrawCanvasItemsCheckBox->setCheckState( Qt::Unchecked ); } //overview frame int overviewMapFrameId = mComposerMap->overviewFrameMapId(); mOverviewFrameMapComboBox->setCurrentIndex( mOverviewFrameMapComboBox->findData( overviewMapFrameId ) ); //grid if ( mComposerMap->gridEnabled() ) { mGridCheckBox->setChecked( true ); } else { mGridCheckBox->setChecked( false ); } mIntervalXSpinBox->setValue( mComposerMap->gridIntervalX() ); mIntervalYSpinBox->setValue( mComposerMap->gridIntervalY() ); mOffsetXSpinBox->setValue( mComposerMap->gridOffsetX() ); mOffsetYSpinBox->setValue( mComposerMap->gridOffsetY() ); QgsComposerMap::GridStyle gridStyle = mComposerMap->gridStyle(); if ( gridStyle == QgsComposerMap::Cross ) { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Cross" ) ) ); } else { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Solid" ) ) ); } mCrossWidthSpinBox->setValue( mComposerMap->crossLength() ); //grid frame mFrameWidthSpinBox->setValue( mComposerMap->gridFrameWidth() ); QgsComposerMap::GridFrameStyle gridFrameStyle = mComposerMap->gridFrameStyle(); if ( gridFrameStyle == QgsComposerMap::Zebra ) { mFrameStyleComboBox->setCurrentIndex( mFrameStyleComboBox->findText( tr( "Zebra" ) ) ); } else //NoGridFrame { mFrameStyleComboBox->setCurrentIndex( mFrameStyleComboBox->findText( tr( "No frame" ) ) ); } //grid annotation position initAnnotationPositionBox( mAnnotationPositionLeftComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Left ) ); initAnnotationPositionBox( mAnnotationPositionRightComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Right ) ); initAnnotationPositionBox( mAnnotationPositionTopComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Top ) ); initAnnotationPositionBox( mAnnotationPositionBottomComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Bottom ) ); //grid annotation direction initAnnotationDirectionBox( mAnnotationDirectionComboBoxLeft, mComposerMap->gridAnnotationDirection( QgsComposerMap::Left ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxRight, mComposerMap->gridAnnotationDirection( QgsComposerMap::Right ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxTop, mComposerMap->gridAnnotationDirection( QgsComposerMap::Top ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxBottom, mComposerMap->gridAnnotationDirection( QgsComposerMap::Bottom ) ); mDistanceToMapFrameSpinBox->setValue( mComposerMap->annotationFrameDistance() ); if ( mComposerMap->showGridAnnotation() ) { mDrawAnnotationCheckBox->setCheckState( Qt::Checked ); } else { mDrawAnnotationCheckBox->setCheckState( Qt::Unchecked ); } mCoordinatePrecisionSpinBox->setValue( mComposerMap->gridAnnotationPrecision() ); QPen gridPen = mComposerMap->gridPen(); mLineWidthSpinBox->setValue( gridPen.widthF() ); mLineColorButton->setColor( gridPen.color() ); blockAllSignals( false ); } }
SpatialIndex::Region QgsSpatialIndex::rectToRegion( const QgsRectangle &rect ) { double pt1[2] = { rect.xMinimum(), rect.yMinimum() }, pt2[2] = { rect.xMaximum(), rect.yMaximum() }; return SpatialIndex::Region( pt1, pt2, 2 ); }
QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer* layer, QgsRenderContext& rendererContext ) : QgsMapLayerRenderer( layer->id() ) , mRasterViewPort( nullptr ) , mPipe( nullptr ) { mPainter = rendererContext.painter(); const QgsMapToPixel& theQgsMapToPixel = rendererContext.mapToPixel(); mMapToPixel = &theQgsMapToPixel; QgsMapToPixel mapToPixel = theQgsMapToPixel; if ( mapToPixel.mapRotation() ) { // unset rotation for the sake of local computations. // Rotation will be handled by QPainter later // TODO: provide a method of QgsMapToPixel to fetch map center // in geographical units QgsPoint center = mapToPixel.toMapCoordinates( mapToPixel.mapWidth() / 2.0, mapToPixel.mapHeight() / 2.0 ); mapToPixel.setMapRotation( 0, center.x(), center.y() ); } QgsRectangle myProjectedViewExtent; QgsRectangle myProjectedLayerExtent; if ( rendererContext.coordinateTransform() ) { QgsDebugMsg( "coordinateTransform set -> project extents." ); try { myProjectedViewExtent = rendererContext.coordinateTransform()->transformBoundingBox( rendererContext.extent() ); } catch ( QgsCsException &cs ) { QgsMessageLog::logMessage( QObject::tr( "Could not reproject view extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) ); myProjectedViewExtent.setMinimal(); } try { myProjectedLayerExtent = rendererContext.coordinateTransform()->transformBoundingBox( layer->extent() ); } catch ( QgsCsException &cs ) { QgsMessageLog::logMessage( QObject::tr( "Could not reproject layer extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) ); myProjectedLayerExtent.setMinimal(); } } else { QgsDebugMsg( "coordinateTransform not set" ); myProjectedViewExtent = rendererContext.extent(); myProjectedLayerExtent = layer->extent(); } // clip raster extent to view extent QgsRectangle myRasterExtent = myProjectedViewExtent.intersect( &myProjectedLayerExtent ); if ( myRasterExtent.isEmpty() ) { QgsDebugMsg( "draw request outside view extent." ); // nothing to do return; } QgsDebugMsg( "theViewExtent is " + rendererContext.extent().toString() ); QgsDebugMsg( "myProjectedViewExtent is " + myProjectedViewExtent.toString() ); QgsDebugMsg( "myProjectedLayerExtent is " + myProjectedLayerExtent.toString() ); QgsDebugMsg( "myRasterExtent is " + myRasterExtent.toString() ); // // The first thing we do is set up the QgsRasterViewPort. This struct stores all the settings // relating to the size (in pixels and coordinate system units) of the raster part that is // in view in the map window. It also stores the origin. // //this is not a class level member because every time the user pans or zooms //the contents of the rasterViewPort will change mRasterViewPort = new QgsRasterViewPort(); mRasterViewPort->mDrawnExtent = myRasterExtent; if ( rendererContext.coordinateTransform() ) { mRasterViewPort->mSrcCRS = layer->crs(); mRasterViewPort->mDestCRS = rendererContext.coordinateTransform()->destCRS(); mRasterViewPort->mSrcDatumTransform = rendererContext.coordinateTransform()->sourceDatumTransform(); mRasterViewPort->mDestDatumTransform = rendererContext.coordinateTransform()->destinationDatumTransform(); } else { mRasterViewPort->mSrcCRS = QgsCoordinateReferenceSystem(); // will be invalid mRasterViewPort->mDestCRS = QgsCoordinateReferenceSystem(); // will be invalid mRasterViewPort->mSrcDatumTransform = -1; mRasterViewPort->mDestDatumTransform = -1; } // get dimensions of clipped raster image in device coordinate space (this is the size of the viewport) mRasterViewPort->mTopLeftPoint = mapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() ); mRasterViewPort->mBottomRightPoint = mapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() ); // align to output device grid, i.e. floor/ceil to integers // TODO: this should only be done if paint device is raster - screen, image // for other devices (pdf) it can have floating point origin // we could use floating point for raster devices as well, but respecting the // output device grid should make it more effective as the resampling is done in // the provider anyway mRasterViewPort->mTopLeftPoint.setX( floor( mRasterViewPort->mTopLeftPoint.x() ) ); mRasterViewPort->mTopLeftPoint.setY( floor( mRasterViewPort->mTopLeftPoint.y() ) ); mRasterViewPort->mBottomRightPoint.setX( ceil( mRasterViewPort->mBottomRightPoint.x() ) ); mRasterViewPort->mBottomRightPoint.setY( ceil( mRasterViewPort->mBottomRightPoint.y() ) ); // recalc myRasterExtent to aligned values myRasterExtent.set( mapToPixel.toMapCoordinatesF( mRasterViewPort->mTopLeftPoint.x(), mRasterViewPort->mBottomRightPoint.y() ), mapToPixel.toMapCoordinatesF( mRasterViewPort->mBottomRightPoint.x(), mRasterViewPort->mTopLeftPoint.y() ) ); //raster viewport top left / bottom right are already rounded to int mRasterViewPort->mWidth = static_cast<int>( mRasterViewPort->mBottomRightPoint.x() - mRasterViewPort->mTopLeftPoint.x() ); mRasterViewPort->mHeight = static_cast<int>( mRasterViewPort->mBottomRightPoint.y() - mRasterViewPort->mTopLeftPoint.y() ); //the drawable area can start to get very very large when you get down displaying 2x2 or smaller, this is becasue //mapToPixel.mapUnitsPerPixel() is less then 1, //so we will just get the pixel data and then render these special cases differently in paintImageToCanvas() QgsDebugMsgLevel( QString( "mapUnitsPerPixel = %1" ).arg( mapToPixel.mapUnitsPerPixel() ), 3 ); QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( layer->width() ), 3 ); QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( layer->height() ), 3 ); QgsDebugMsgLevel( QString( "myRasterExtent.xMinimum() = %1" ).arg( myRasterExtent.xMinimum() ), 3 ); QgsDebugMsgLevel( QString( "myRasterExtent.xMaximum() = %1" ).arg( myRasterExtent.xMaximum() ), 3 ); QgsDebugMsgLevel( QString( "myRasterExtent.yMinimum() = %1" ).arg( myRasterExtent.yMinimum() ), 3 ); QgsDebugMsgLevel( QString( "myRasterExtent.yMaximum() = %1" ).arg( myRasterExtent.yMaximum() ), 3 ); QgsDebugMsgLevel( QString( "mTopLeftPoint.x() = %1" ).arg( mRasterViewPort->mTopLeftPoint.x() ), 3 ); QgsDebugMsgLevel( QString( "mBottomRightPoint.x() = %1" ).arg( mRasterViewPort->mBottomRightPoint.x() ), 3 ); QgsDebugMsgLevel( QString( "mTopLeftPoint.y() = %1" ).arg( mRasterViewPort->mTopLeftPoint.y() ), 3 ); QgsDebugMsgLevel( QString( "mBottomRightPoint.y() = %1" ).arg( mRasterViewPort->mBottomRightPoint.y() ), 3 ); QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( mRasterViewPort->mWidth ), 3 ); QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( mRasterViewPort->mHeight ), 3 ); // /\/\/\ - added to handle zoomed-in rasters // TODO R->mLastViewPort = *mRasterViewPort; // TODO: is it necessary? Probably WMS only? layer->dataProvider()->setDpi( rendererContext.rasterScaleFactor() * 25.4 * rendererContext.scaleFactor() ); // copy the whole raster pipe! mPipe = new QgsRasterPipe( *layer->pipe() ); }
QString QgsOSMDownload::queryFromRect( const QgsRectangle& rect ) { return QStringLiteral( "(node(%1,%2,%3,%4);<;);out;" ).arg( rect.yMinimum() ).arg( rect.xMinimum() ) .arg( rect.yMaximum() ).arg( rect.xMaximum() ); }
int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing ) { if ( !L->hasGeometryType() ) return 4; QgsFeatureList newFeatures; //store all the newly created features double xMin, yMin, xMax, yMax; QgsRectangle bBox; //bounding box of the split line int returnCode = 0; int splitFunctionReturn; //return code of QgsGeometry::splitGeometry int numberOfSplittedFeatures = 0; QgsFeatureIterator features; const QgsFeatureIds selectedIds = L->selectedFeaturesIds(); if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection { features = L->selectedFeaturesIterator(); } else //else consider all the feature that intersect the bounding box of the split line { if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 ) { bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin ); bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax ); } else { return 1; } if ( bBox.isEmpty() ) { //if the bbox is a line, try to make a square out of it if ( bBox.width() == 0.0 && bBox.height() > 0 ) { bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 ); bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 ); } else if ( bBox.height() == 0.0 && bBox.width() > 0 ) { bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 ); bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 ); } else { //If we have a single point, we still create a non-null box double bufferDistance = 0.000001; if ( L->crs().geographicFlag() ) bufferDistance = 0.00000001; bBox.setXMinimum( bBox.xMinimum() - bufferDistance ); bBox.setXMaximum( bBox.xMaximum() + bufferDistance ); bBox.setYMinimum( bBox.yMinimum() - bufferDistance ); bBox.setYMaximum( bBox.yMaximum() + bufferDistance ); } } features = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); } QgsFeature feat; while ( features.nextFeature( feat ) ) { if ( !feat.constGeometry() ) { continue; } QList<QgsGeometry*> newGeometries; QList<QgsPoint> topologyTestPoints; QgsGeometry* newGeometry = 0; splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints ); if ( splitFunctionReturn == 0 ) { //change this geometry L->editBuffer()->changeGeometry( feat.id(), feat.geometry() ); //insert new features for ( int i = 0; i < newGeometries.size(); ++i ) { newGeometry = newGeometries.at( i ); QgsFeature newFeature; newFeature.setGeometry( newGeometry ); //use default value where possible for primary key (e.g. autoincrement), //and use the value from the original (split) feature if not primary key QgsAttributes newAttributes = feat.attributes(); Q_FOREACH ( int pkIdx, L->dataProvider()->pkAttributeIndexes() ) { const QVariant defaultValue = L->dataProvider()->defaultValue( pkIdx ); if ( !defaultValue.isNull() ) { newAttributes[ pkIdx ] = defaultValue; } else //try with NULL { newAttributes[ pkIdx ] = QVariant(); } } newFeature.setAttributes( newAttributes ); newFeatures.append( newFeature ); } if ( topologicalEditing ) { QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin(); for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it ) { addTopologicalPoints( *topol_it ); } } ++numberOfSplittedFeatures; } else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
bool QgsVectorLayerRenderer::render() { if ( mGeometryType == QgsWkbTypes::NullGeometry || mGeometryType == QgsWkbTypes::UnknownGeometry ) return true; if ( !mRenderer ) { mErrors.append( QObject::tr( "No renderer for drawing." ) ); return false; } bool usingEffect = false; if ( mRenderer->paintEffect() && mRenderer->paintEffect()->enabled() ) { usingEffect = true; mRenderer->paintEffect()->begin( mContext ); } // Per feature blending mode if ( mContext.useAdvancedEffects() && mFeatureBlendMode != QPainter::CompositionMode_SourceOver ) { // set the painter to the feature blend mode, so that features drawn // on this layer will interact and blend with each other mContext.painter()->setCompositionMode( mFeatureBlendMode ); } mRenderer->startRender( mContext, mFields ); QString rendererFilter = mRenderer->filter( mFields ); QgsRectangle requestExtent = mContext.extent(); mRenderer->modifyRequestExtent( requestExtent, mContext ); QgsFeatureRequest featureRequest = QgsFeatureRequest() .setFilterRect( requestExtent ) .setSubsetOfAttributes( mAttrNames, mFields ) .setExpressionContext( mContext.expressionContext() ); if ( mRenderer->orderByEnabled() ) { featureRequest.setOrderBy( mRenderer->orderBy() ); } const QgsFeatureFilterProvider* featureFilterProvider = mContext.featureFilterProvider(); if ( featureFilterProvider ) { featureFilterProvider->filterFeatures( mLayer, featureRequest ); } if ( !rendererFilter.isEmpty() && rendererFilter != "TRUE" ) { featureRequest.combineFilterExpression( rendererFilter ); } // enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine. if ( mSimplifyGeometry ) { double map2pixelTol = mSimplifyMethod.threshold(); bool validTransform = true; const QgsMapToPixel& mtp = mContext.mapToPixel(); map2pixelTol *= mtp.mapUnitsPerPixel(); QgsCoordinateTransform ct = mContext.coordinateTransform(); // resize the tolerance using the change of size of an 1-BBOX from the source CoordinateSystem to the target CoordinateSystem if ( ct.isValid() && !ct.isShortCircuited() ) { try { QgsPoint center = mContext.extent().center(); double rectSize = ct.sourceCrs().isGeographic() ? 0.0008983 /* ~100/(40075014/360=111319.4833) */ : 100; QgsRectangle sourceRect = QgsRectangle( center.x(), center.y(), center.x() + rectSize, center.y() + rectSize ); QgsRectangle targetRect = ct.transform( sourceRect ); QgsDebugMsgLevel( QString( "Simplify - SourceTransformRect=%1" ).arg( sourceRect.toString( 16 ) ), 4 ); QgsDebugMsgLevel( QString( "Simplify - TargetTransformRect=%1" ).arg( targetRect.toString( 16 ) ), 4 ); if ( !sourceRect.isEmpty() && sourceRect.isFinite() && !targetRect.isEmpty() && targetRect.isFinite() ) { QgsPoint minimumSrcPoint( sourceRect.xMinimum(), sourceRect.yMinimum() ); QgsPoint maximumSrcPoint( sourceRect.xMaximum(), sourceRect.yMaximum() ); QgsPoint minimumDstPoint( targetRect.xMinimum(), targetRect.yMinimum() ); QgsPoint maximumDstPoint( targetRect.xMaximum(), targetRect.yMaximum() ); double sourceHypothenuse = sqrt( minimumSrcPoint.sqrDist( maximumSrcPoint ) ); double targetHypothenuse = sqrt( minimumDstPoint.sqrDist( maximumDstPoint ) ); QgsDebugMsgLevel( QString( "Simplify - SourceHypothenuse=%1" ).arg( sourceHypothenuse ), 4 ); QgsDebugMsgLevel( QString( "Simplify - TargetHypothenuse=%1" ).arg( targetHypothenuse ), 4 ); if ( !qgsDoubleNear( targetHypothenuse, 0.0 ) ) map2pixelTol *= ( sourceHypothenuse / targetHypothenuse ); } } catch ( QgsCsException &cse ) { QgsMessageLog::logMessage( QObject::tr( "Simplify transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) ); validTransform = false; } } if ( validTransform ) { QgsSimplifyMethod simplifyMethod; simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering ); simplifyMethod.setTolerance( map2pixelTol ); simplifyMethod.setThreshold( mSimplifyMethod.threshold() ); simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() ); featureRequest.setSimplifyMethod( simplifyMethod ); QgsVectorSimplifyMethod vectorMethod = mSimplifyMethod; vectorMethod.setTolerance( map2pixelTol ); mContext.setVectorSimplifyMethod( vectorMethod ); } else { QgsVectorSimplifyMethod vectorMethod; vectorMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification ); mContext.setVectorSimplifyMethod( vectorMethod ); } } else { QgsVectorSimplifyMethod vectorMethod; vectorMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification ); mContext.setVectorSimplifyMethod( vectorMethod ); } QgsFeatureIterator fit = mSource->getFeatures( featureRequest ); // Attach an interruption checker so that iterators that have potentially // slow fetchFeature() implementations, such as in the WFS provider, can // check it, instead of relying on just the mContext.renderingStopped() check // in drawRenderer() fit.setInterruptionChecker( &mInterruptionChecker ); if (( mRenderer->capabilities() & QgsFeatureRenderer::SymbolLevels ) && mRenderer->usingSymbolLevels() ) drawRendererLevels( fit ); else drawRenderer( fit ); if ( usingEffect ) { mRenderer->paintEffect()->end( mContext ); } return true; }
void QgsAlignRaster::setClipExtent( const QgsRectangle& extent ) { setClipExtent( extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum() ); }
// Slot called when the menu item is triggered // If you created more menu items / toolbar buttons in initiGui, you should // create a separate handler for each action - this single run() method will // not be enough void Heatmap::run() { HeatmapGui d( mQGisIface->mainWindow(), QgisGui::ModalDialogFlags, &mSessionSettings ); if ( d.exec() == QDialog::Accepted ) { // everything runs here // Get the required data from the dialog QgsRectangle myBBox = d.bbox(); int columns = d.columns(); int rows = d.rows(); double cellsize = d.cellSizeX(); // or d.cellSizeY(); both have the same value mDecay = d.decayRatio(); int kernelShape = d.kernelShape(); // Start working on the input vector QgsVectorLayer* inputLayer = d.inputVectorLayer(); // Getting the rasterdataset in place GDALAllRegister(); GDALDataset *emptyDataset; GDALDriver *myDriver; myDriver = GetGDALDriverManager()->GetDriverByName( d.outputFormat().toUtf8() ); if ( myDriver == NULL ) { QMessageBox::information( 0, tr( "GDAL driver error" ), tr( "Cannot open the driver for the specified format" ) ); return; } double geoTransform[6] = { myBBox.xMinimum(), cellsize, 0, myBBox.yMinimum(), 0, cellsize }; emptyDataset = myDriver->Create( d.outputFilename().toUtf8(), columns, rows, 1, GDT_Float32, NULL ); emptyDataset->SetGeoTransform( geoTransform ); // Set the projection on the raster destination to match the input layer emptyDataset->SetProjection( inputLayer->crs().toWkt().toLocal8Bit().data() ); GDALRasterBand *poBand; poBand = emptyDataset->GetRasterBand( 1 ); poBand->SetNoDataValue( NO_DATA ); float* line = ( float * ) CPLMalloc( sizeof( float ) * columns ); for ( int i = 0; i < columns ; i++ ) { line[i] = NO_DATA; } // Write the empty raster for ( int i = 0; i < rows ; i++ ) { poBand->RasterIO( GF_Write, 0, i, columns, 1, line, columns, 1, GDT_Float32, 0, 0 ); } CPLFree( line ); //close the dataset GDALClose(( GDALDatasetH ) emptyDataset ); // open the raster in GA_Update mode GDALDataset *heatmapDS; heatmapDS = ( GDALDataset * ) GDALOpen( d.outputFilename().toUtf8(), GA_Update ); if ( !heatmapDS ) { QMessageBox::information( 0, tr( "Raster update error" ), tr( "Could not open the created raster for updating. The heatmap was not generated." ) ); return; } poBand = heatmapDS->GetRasterBand( 1 ); QgsAttributeList myAttrList; int rField = 0; int wField = 0; // Handle different radius options double radius; double radiusToMapUnits = 1; int myBuffer = 0; if ( d.variableRadius() ) { rField = d.radiusField(); myAttrList.append( rField ); QgsDebugMsg( QString( "Radius Field index received: %1" ).arg( rField ) ); // If not using map units, then calculate a conversion factor to convert the radii to map units if ( d.radiusUnit() == HeatmapGui::Meters ) { radiusToMapUnits = mapUnitsOf( 1, inputLayer->crs() ); } } else { radius = d.radius(); // radius returned by d.radius() is already in map units myBuffer = bufferSize( radius, cellsize ); } if ( d.weighted() ) { wField = d.weightField(); myAttrList.append( wField ); } // This might have attributes or mightnot have attibutes at all // based on the variableRadius() and weighted() QgsFeatureIterator fit = inputLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( myAttrList ) ); int totalFeatures = inputLayer->featureCount(); int counter = 0; QProgressDialog p( tr( "Creating heatmap" ), tr( "Abort" ), 0, totalFeatures, mQGisIface->mainWindow() ); p.setWindowModality( Qt::ApplicationModal ); p.show(); QgsFeature myFeature; while ( fit.nextFeature( myFeature ) ) { counter++; p.setValue( counter ); QApplication::processEvents(); if ( p.wasCanceled() ) { QMessageBox::information( 0, tr( "Heatmap generation aborted" ), tr( "QGIS will now load the partially-computed raster." ) ); break; } QgsGeometry* myPointGeometry; myPointGeometry = myFeature.geometry(); // convert the geometry to point QgsPoint myPoint; myPoint = myPointGeometry->asPoint(); // avoiding any empty points or out of extent points if (( myPoint.x() < myBBox.xMinimum() ) || ( myPoint.y() < myBBox.yMinimum() ) || ( myPoint.x() > myBBox.xMaximum() ) || ( myPoint.y() > myBBox.yMaximum() ) ) { continue; } // If radius is variable then fetch it and calculate new pixel buffer size if ( d.variableRadius() ) { radius = myFeature.attribute( rField ).toDouble() * radiusToMapUnits; myBuffer = bufferSize( radius, cellsize ); } int blockSize = 2 * myBuffer + 1; //Block SIDE would be more appropriate // calculate the pixel position unsigned int xPosition, yPosition; xPosition = (( myPoint.x() - myBBox.xMinimum() ) / cellsize ) - myBuffer; yPosition = (( myPoint.y() - myBBox.yMinimum() ) / cellsize ) - myBuffer; // get the data float *dataBuffer = ( float * ) CPLMalloc( sizeof( float ) * blockSize * blockSize ); poBand->RasterIO( GF_Read, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); double weight = 1.0; if ( d.weighted() ) { weight = myFeature.attribute( wField ).toDouble(); } for ( int xp = 0; xp <= myBuffer; xp++ ) { for ( int yp = 0; yp <= myBuffer; yp++ ) { double distance = sqrt( pow( xp, 2.0 ) + pow( yp, 2.0 ) ); // is pixel outside search bandwidth of feature? if ( distance > myBuffer ) { continue; } double pixelValue = weight * calculateKernelValue( distance, myBuffer, kernelShape ); // clearing anamolies along the axes if ( xp == 0 && yp == 0 ) { pixelValue /= 4; } else if ( xp == 0 || yp == 0 ) { pixelValue /= 2; } int pos[4]; pos[0] = ( myBuffer + xp ) * blockSize + ( myBuffer + yp ); pos[1] = ( myBuffer + xp ) * blockSize + ( myBuffer - yp ); pos[2] = ( myBuffer - xp ) * blockSize + ( myBuffer + yp ); pos[3] = ( myBuffer - xp ) * blockSize + ( myBuffer - yp ); for ( int p = 0; p < 4; p++ ) { if ( dataBuffer[ pos[p] ] == NO_DATA ) { dataBuffer[ pos[p] ] = 0; } dataBuffer[ pos[p] ] += pixelValue; } } } poBand->RasterIO( GF_Write, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); CPLFree( dataBuffer ); } // Finally close the dataset GDALClose(( GDALDatasetH ) heatmapDS ); // Open the file in QGIS window mQGisIface->addRasterLayer( d.outputFilename(), QFileInfo( d.outputFilename() ).baseName() ); } }
void QgsGrassFeatureIterator::setSelectionRect( const QgsRectangle& rect, bool useIntersect ) { //apply selection rectangle resetSelection( 0 ); BOUND_BOX box; box.N = rect.yMaximum(); box.S = rect.yMinimum(); box.E = rect.xMaximum(); box.W = rect.xMinimum(); box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; if ( !useIntersect ) { // select by bounding boxes only if ( mSource->mLayerType == QgsGrassProvider::POINT || mSource->mLayerType == QgsGrassProvider::CENTROID || mSource->mLayerType == QgsGrassProvider::LINE || mSource->mLayerType == QgsGrassProvider::FACE || mSource->mLayerType == QgsGrassProvider::BOUNDARY || mSource->mLayerType == QgsGrassProvider::TOPO_POINT || mSource->mLayerType == QgsGrassProvider::TOPO_LINE ) { Vect_select_lines_by_box( mSource->mMap, &box, mSource->mGrassType, mList ); } else if ( mSource->mLayerType == QgsGrassProvider::POLYGON ) { Vect_select_areas_by_box( mSource->mMap, &box, mList ); } else if ( mSource->mLayerType == QgsGrassProvider::TOPO_NODE ) { Vect_select_nodes_by_box( mSource->mMap, &box, mList ); } } else { // check intersection struct line_pnts *Polygon; Polygon = Vect_new_line_struct(); // Using z coor -PORT_DOUBLE_MAX/PORT_DOUBLE_MAX we cover 3D, Vect_select_lines_by_polygon is // using dig_line_box to get the box, it is not perfect, Vect_select_lines_by_polygon // should clarify better how 2D/3D is treated Vect_append_point( Polygon, rect.xMinimum(), rect.yMinimum(), -PORT_DOUBLE_MAX ); Vect_append_point( Polygon, rect.xMaximum(), rect.yMinimum(), PORT_DOUBLE_MAX ); Vect_append_point( Polygon, rect.xMaximum(), rect.yMaximum(), 0 ); Vect_append_point( Polygon, rect.xMinimum(), rect.yMaximum(), 0 ); Vect_append_point( Polygon, rect.xMinimum(), rect.yMinimum(), 0 ); if ( mSource->mLayerType == QgsGrassProvider::POINT || mSource->mLayerType == QgsGrassProvider::CENTROID || mSource->mLayerType == QgsGrassProvider::LINE || mSource->mLayerType == QgsGrassProvider::FACE || mSource->mLayerType == QgsGrassProvider::BOUNDARY || mSource->mLayerType == QgsGrassProvider::TOPO_POINT || mSource->mLayerType == QgsGrassProvider::TOPO_LINE ) { Vect_select_lines_by_polygon( mSource->mMap, Polygon, 0, NULL, mSource->mGrassType, mList ); } else if ( mSource->mLayerType == QgsGrassProvider::POLYGON ) { Vect_select_areas_by_polygon( mSource->mMap, Polygon, 0, NULL, mList ); } else if ( mSource->mLayerType == QgsGrassProvider::TOPO_NODE ) { // There is no Vect_select_nodes_by_polygon but for nodes it is the same as by box Vect_select_nodes_by_box( mSource->mMap, &box, mList ); } Vect_destroy_line_struct( Polygon ); } for ( int i = 0; i < mList->n_values; i++ ) { if ( mList->value[i] <= mSelectionSize ) { mSelection[mList->value[i]] = 1; } else { QgsDebugMsg( "Selected element out of range" ); } } }
/**************************** REGION ********************************/ void QgsGrassNewMapset::setRegionPage() { QgsDebugMsg( "entered" ); // Set defaults if ( !mRegionModified ) { setGrassRegionDefaults(); } // Create new projection QgsCoordinateReferenceSystem newCrs; if ( mProjRadioButton->isChecked() ) { QgsDebugMsg( QString( "selectedCrsId() = %1" ).arg( mProjectionSelector->selectedCrsId() ) ); if ( mProjectionSelector->selectedCrsId() > 0 ) { newCrs.createFromSrsId( mProjectionSelector->selectedCrsId() ); if ( ! newCrs.isValid() ) { QgsGrass::warning( tr( "Cannot create projection." ) ); } } } // Reproject previous region if it was modified // and if previous and current projection is valid if ( mRegionModified && newCrs.isValid() && mCrs.isValid() && newCrs.srsid() != mCrs.srsid() ) { QgsCoordinateTransform trans( mCrs, newCrs ); double n = mNorthLineEdit->text().toDouble(); double s = mSouthLineEdit->text().toDouble(); double e = mEastLineEdit->text().toDouble(); double w = mWestLineEdit->text().toDouble(); std::vector<QgsPoint> points; // TODO: this is not perfect points.push_back( QgsPoint( w, s ) ); points.push_back( QgsPoint( e, n ) ); bool ok = true; for ( int i = 0; i < 2; i++ ) { try { points[i] = trans.transform( points[i] ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); QgsDebugMsg( "Cannot transform point" ); ok = false; break; } } if ( ok ) { int precision = newCrs.mapUnits() == QGis::Degrees ? 6 : 1; mNorthLineEdit->setText( qgsDoubleToString( points[1].y(), precision ) ); mSouthLineEdit->setText( qgsDoubleToString( points[0].y(), precision ) ); mEastLineEdit->setText( qgsDoubleToString( points[1].x(), precision ) ); mWestLineEdit->setText( qgsDoubleToString( points[0].x(), precision ) ); } else { QgsGrass::warning( tr( "Cannot reproject previously set region, default region set." ) ); setGrassRegionDefaults(); } } // Set current region projection mCrs = newCrs; // Enable / disable region selection widgets if ( mNoProjRadioButton->isChecked() ) { mRegionMap->hide(); mCurrentRegionButton->hide(); mRegionsComboBox->hide(); mRegionButton->hide(); mSetRegionFrame->hide(); } else { mRegionMap->show(); mCurrentRegionButton->show(); mRegionsComboBox->show(); mRegionButton->show(); mSetRegionFrame->show(); QgsRectangle ext = mIface->mapCanvas()->extent(); if ( ext.xMinimum() >= ext.xMaximum() || ext.yMinimum() >= ext.yMaximum() ) { mCurrentRegionButton->setEnabled( false ); } } checkRegion(); if ( !mNoProjRadioButton->isChecked() ) { drawRegion(); } }
void QgsComposerMapWidget::updateGuiElements() { if ( mComposerMap ) { blockAllSignals( true ); //width, height, scale // QRectF composerMapRect = mComposerMap->rect(); mScaleLineEdit->setText( QString::number( mComposerMap->scale(), 'f', 0 ) ); //preview mode QgsComposerMap::PreviewMode previewMode = mComposerMap->previewMode(); int index = -1; if ( previewMode == QgsComposerMap::Cache ) { index = mPreviewModeComboBox->findText( tr( "Cache" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Render ) { index = mPreviewModeComboBox->findText( tr( "Render" ) ); mUpdatePreviewButton->setEnabled( true ); } else if ( previewMode == QgsComposerMap::Rectangle ) { index = mPreviewModeComboBox->findText( tr( "Rectangle" ) ); mUpdatePreviewButton->setEnabled( false ); } if ( index != -1 ) { mPreviewModeComboBox->setCurrentIndex( index ); } //composer map extent QgsRectangle composerMapExtent = *( mComposerMap->currentMapExtent() ); mXMinLineEdit->setText( QString::number( composerMapExtent.xMinimum(), 'f', 3 ) ); mXMaxLineEdit->setText( QString::number( composerMapExtent.xMaximum(), 'f', 3 ) ); mYMinLineEdit->setText( QString::number( composerMapExtent.yMinimum(), 'f', 3 ) ); mYMaxLineEdit->setText( QString::number( composerMapExtent.yMaximum(), 'f', 3 ) ); mMapRotationSpinBox->setValue( mComposerMap->mapRotation() ); //keep layer list check box if ( mComposerMap->keepLayerSet() ) { mKeepLayerListCheckBox->setCheckState( Qt::Checked ); } else { mKeepLayerListCheckBox->setCheckState( Qt::Unchecked ); } //draw canvas items if ( mComposerMap->drawCanvasItems() ) { mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked ); } else { mDrawCanvasItemsCheckBox->setCheckState( Qt::Unchecked ); } //overview frame int overviewMapFrameId = mComposerMap->overviewFrameMapId(); mOverviewFrameMapComboBox->setCurrentIndex( mOverviewFrameMapComboBox->findData( overviewMapFrameId ) ); //overview frame blending mode mOverviewBlendModeComboBox->setBlendMode( mComposerMap->overviewBlendMode() ); //overview inverted mOverviewInvertCheckbox->setChecked( mComposerMap->overviewInverted() ); //center overview mOverviewCenterCheckbox->setChecked( mComposerMap->overviewCentered() ); //grid if ( mComposerMap->gridEnabled() ) { mGridCheckBox->setChecked( true ); } else { mGridCheckBox->setChecked( false ); } mIntervalXSpinBox->setValue( mComposerMap->gridIntervalX() ); mIntervalYSpinBox->setValue( mComposerMap->gridIntervalY() ); mOffsetXSpinBox->setValue( mComposerMap->gridOffsetX() ); mOffsetYSpinBox->setValue( mComposerMap->gridOffsetY() ); QgsComposerMap::GridStyle gridStyle = mComposerMap->gridStyle(); if ( gridStyle == QgsComposerMap::Cross ) { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Cross" ) ) ); } else { mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findText( tr( "Solid" ) ) ); } mCrossWidthSpinBox->setValue( mComposerMap->crossLength() ); //grid frame mFrameWidthSpinBox->setValue( mComposerMap->gridFrameWidth() ); mGridFramePenSizeSpinBox->setValue( mComposerMap->gridFramePenSize() ); mGridFramePenColorButton->setColor( mComposerMap->gridFramePenColor() ); mGridFrameFill1ColorButton->setColor( mComposerMap->gridFrameFillColor1() ); mGridFrameFill2ColorButton->setColor( mComposerMap->gridFrameFillColor2() ); QgsComposerMap::GridFrameStyle gridFrameStyle = mComposerMap->gridFrameStyle(); if ( gridFrameStyle == QgsComposerMap::Zebra ) { mFrameStyleComboBox->setCurrentIndex( mFrameStyleComboBox->findText( tr( "Zebra" ) ) ); toggleFrameControls( true ); } else //NoGridFrame { mFrameStyleComboBox->setCurrentIndex( mFrameStyleComboBox->findText( tr( "No frame" ) ) ); toggleFrameControls( false ); } //grid blend mode mGridBlendComboBox->setBlendMode( mComposerMap->gridBlendMode() ); //grid annotation format QgsComposerMap::GridAnnotationFormat gf = mComposerMap->gridAnnotationFormat(); mAnnotationFormatComboBox->setCurrentIndex(( int )gf ); //grid annotation position initAnnotationPositionBox( mAnnotationPositionLeftComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Left ) ); initAnnotationPositionBox( mAnnotationPositionRightComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Right ) ); initAnnotationPositionBox( mAnnotationPositionTopComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Top ) ); initAnnotationPositionBox( mAnnotationPositionBottomComboBox, mComposerMap->gridAnnotationPosition( QgsComposerMap::Bottom ) ); //grid annotation direction initAnnotationDirectionBox( mAnnotationDirectionComboBoxLeft, mComposerMap->gridAnnotationDirection( QgsComposerMap::Left ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxRight, mComposerMap->gridAnnotationDirection( QgsComposerMap::Right ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxTop, mComposerMap->gridAnnotationDirection( QgsComposerMap::Top ) ); initAnnotationDirectionBox( mAnnotationDirectionComboBoxBottom, mComposerMap->gridAnnotationDirection( QgsComposerMap::Bottom ) ); mAnnotationFontColorButton->setColor( mComposerMap->annotationFontColor() ); mDistanceToMapFrameSpinBox->setValue( mComposerMap->annotationFrameDistance() ); if ( mComposerMap->showGridAnnotation() ) { mDrawAnnotationCheckableGroupBox->setChecked( true ); } else { mDrawAnnotationCheckableGroupBox->setChecked( false ); } mCoordinatePrecisionSpinBox->setValue( mComposerMap->gridAnnotationPrecision() ); //atlas controls mAtlasCheckBox->setChecked( mComposerMap->atlasDriven() ); mAtlasMarginSpinBox->setValue( static_cast<int>( mComposerMap->atlasMargin() * 100 ) ); if ( mComposerMap->atlasFixedScale() ) { mAtlasFixedScaleRadio->setChecked( true ); mAtlasMarginSpinBox->setEnabled( false ); } else { mAtlasMarginRadio->setChecked( true ); mAtlasMarginSpinBox->setEnabled( true ); } if ( !mComposerMap->atlasDriven() ) { mAtlasMarginSpinBox->setEnabled( false ); mAtlasMarginRadio->setEnabled( false ); mAtlasFixedScaleRadio->setEnabled( false ); } else { mAtlasFixedScaleRadio->setEnabled( true ); toggleAtlasMarginByLayerType(); } blockAllSignals( false ); } }
void QgsGrassFeatureIterator::setSelectionRect( const QgsRectangle& rect, bool useIntersect ) { QgsDebugMsg( QString( "useIntersect = %1 rect = %2" ).arg( useIntersect ).arg( rect.toString() ) ); // TODO: selection of edited lines // Lock because functions using static/global variables are used // (e.g. static LocList in Vect_select_lines_by_box, global BranchBuf in RTreeGetBranches) QgsGrass::lock(); mSelection.fill( false ); BOUND_BOX box; box.N = rect.yMaximum(); box.S = rect.yMinimum(); box.E = rect.xMaximum(); box.W = rect.xMinimum(); box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; // Init structures struct ilist * list = Vect_new_list(); if ( !useIntersect ) { // select by bounding boxes only if ( mSource->mLayerType == QgsGrassProvider::POINT || mSource->mLayerType == QgsGrassProvider::CENTROID || mSource->mLayerType == QgsGrassProvider::LINE || mSource->mLayerType == QgsGrassProvider::FACE || mSource->mLayerType == QgsGrassProvider::BOUNDARY || mSource->mLayerType == QgsGrassProvider::TOPO_POINT || mSource->mLayerType == QgsGrassProvider::TOPO_LINE || mSource->mEditing ) { QgsDebugMsg( "Vect_select_lines_by_box" ); int type = mSource->mGrassType; if ( mSource->mEditing ) { type = GV_POINTS | GV_LINES; } QgsDebugMsg( QString( "type = %1" ).arg( type ) ); Vect_select_lines_by_box( mSource->map(), &box, type, list ); } else if ( mSource->mLayerType == QgsGrassProvider::POLYGON ) { Vect_select_areas_by_box( mSource->map(), &box, list ); } else if ( mSource->mLayerType == QgsGrassProvider::TOPO_NODE ) { Vect_select_nodes_by_box( mSource->map(), &box, list ); } } else { // check intersection struct line_pnts *polygon = Vect_new_line_struct(); // Using z coor -PORT_DOUBLE_MAX/PORT_DOUBLE_MAX we cover 3D, Vect_select_lines_by_polygon is // using dig_line_box to get the box, it is not perfect, Vect_select_lines_by_polygon // should clarify better how 2D/3D is treated Vect_append_point( polygon, rect.xMinimum(), rect.yMinimum(), -PORT_DOUBLE_MAX ); Vect_append_point( polygon, rect.xMaximum(), rect.yMinimum(), PORT_DOUBLE_MAX ); Vect_append_point( polygon, rect.xMaximum(), rect.yMaximum(), 0 ); Vect_append_point( polygon, rect.xMinimum(), rect.yMaximum(), 0 ); Vect_append_point( polygon, rect.xMinimum(), rect.yMinimum(), 0 ); if ( mSource->mLayerType == QgsGrassProvider::POINT || mSource->mLayerType == QgsGrassProvider::CENTROID || mSource->mLayerType == QgsGrassProvider::LINE || mSource->mLayerType == QgsGrassProvider::FACE || mSource->mLayerType == QgsGrassProvider::BOUNDARY || mSource->mLayerType == QgsGrassProvider::TOPO_POINT || mSource->mLayerType == QgsGrassProvider::TOPO_LINE || mSource->mEditing ) { QgsDebugMsg( "Vect_select_lines_by_polygon" ); int type = mSource->mGrassType; if ( mSource->mEditing ) { type = GV_POINTS | GV_LINES; } QgsDebugMsg( QString( "type = %1" ).arg( type ) ); Vect_select_lines_by_polygon( mSource->map(), polygon, 0, NULL, type, list ); } else if ( mSource->mLayerType == QgsGrassProvider::POLYGON ) { Vect_select_areas_by_polygon( mSource->map(), polygon, 0, NULL, list ); } else if ( mSource->mLayerType == QgsGrassProvider::TOPO_NODE ) { // There is no Vect_select_nodes_by_polygon but for nodes it is the same as by box Vect_select_nodes_by_box( mSource->map(), &box, list ); } Vect_destroy_line_struct( polygon ); } for ( int i = 0; i < list->n_values; i++ ) { int lid = list->value[i]; if ( lid < 1 || lid >= mSelection.size() ) // should not happen { QgsDebugMsg( QString( "lid %1 out of range <1,%2>" ).arg( lid ).arg( mSelection.size() ) ); continue; } mSelection.setBit( lid ); } Vect_destroy_list( list ); QgsDebugMsg( QString( " %1 features selected" ).arg( list->n_values ) ); QgsGrass::unlock(); }
QgsPoint surfacePoleOfInaccessibility( const QgsSurface *surface, double precision, double &distanceFromBoundary ) { std::unique_ptr< QgsPolygon > segmentizedPoly; const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( surface ); if ( !polygon ) { segmentizedPoly.reset( static_cast< QgsPolygon *>( surface->segmentize() ) ); polygon = segmentizedPoly.get(); } // start with the bounding box QgsRectangle bounds = polygon->boundingBox(); // initial parameters double cellSize = std::min( bounds.width(), bounds.height() ); if ( qgsDoubleNear( cellSize, 0.0 ) ) return QgsPoint( bounds.xMinimum(), bounds.yMinimum() ); double h = cellSize / 2.0; std::priority_queue< Cell *, std::vector<Cell *>, GreaterThanByMax > cellQueue; // cover polygon with initial cells for ( double x = bounds.xMinimum(); x < bounds.xMaximum(); x += cellSize ) { for ( double y = bounds.yMinimum(); y < bounds.yMaximum(); y += cellSize ) { cellQueue.push( new Cell( x + h, y + h, h, polygon ) ); } } // take centroid as the first best guess std::unique_ptr< Cell > bestCell( getCentroidCell( polygon ) ); // special case for rectangular polygons std::unique_ptr< Cell > bboxCell( new Cell( bounds.xMinimum() + bounds.width() / 2.0, bounds.yMinimum() + bounds.height() / 2.0, 0, polygon ) ); if ( bboxCell->d > bestCell->d ) { bestCell = std::move( bboxCell ); } while ( !cellQueue.empty() ) { // pick the most promising cell from the queue std::unique_ptr< Cell > cell( cellQueue.top() ); cellQueue.pop(); Cell *currentCell = cell.get(); // update the best cell if we found a better one if ( currentCell->d > bestCell->d ) { bestCell = std::move( cell ); } // do not drill down further if there's no chance of a better solution if ( currentCell->max - bestCell->d <= precision ) continue; // split the cell into four cells h = currentCell->h / 2.0; cellQueue.push( new Cell( currentCell->x - h, currentCell->y - h, h, polygon ) ); cellQueue.push( new Cell( currentCell->x + h, currentCell->y - h, h, polygon ) ); cellQueue.push( new Cell( currentCell->x - h, currentCell->y + h, h, polygon ) ); cellQueue.push( new Cell( currentCell->x + h, currentCell->y + h, h, polygon ) ); } distanceFromBoundary = bestCell->d; return QgsPoint( bestCell->x, bestCell->y ); }
QString QgsPostgresFeatureIterator::whereClauseRect() { QgsRectangle rect = mRequest.filterRect(); if ( mSource->mSpatialColType == sctGeography ) { rect = QgsRectangle( -180.0, -90.0, 180.0, 90.0 ).intersect( &rect ); } if ( !rect.isFinite() ) { QgsMessageLog::logMessage( QObject::tr( "Infinite filter rectangle specified" ), QObject::tr( "PostGIS" ) ); return "false"; } QString qBox; if ( mConn->majorVersion() < 2 ) { qBox = QString( "setsrid('BOX3D(%1)'::box3d,%2)" ) .arg( rect.asWktCoordinates(), mSource->mRequestedSrid.isEmpty() ? mSource->mDetectedSrid : mSource->mRequestedSrid ); } else { qBox = QString( "st_makeenvelope(%1,%2,%3,%4,%5)" ) .arg( qgsDoubleToString( rect.xMinimum() ), qgsDoubleToString( rect.yMinimum() ), qgsDoubleToString( rect.xMaximum() ), qgsDoubleToString( rect.yMaximum() ), mSource->mRequestedSrid.isEmpty() ? mSource->mDetectedSrid : mSource->mRequestedSrid ); } bool castToGeometry = mSource->mSpatialColType == sctGeography || mSource->mSpatialColType == sctPcPatch; QString whereClause = QString( "%1%2 && %3" ) .arg( QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ), castToGeometry ? "::geometry" : "", qBox ); if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) { QString curveToLineFn; // in postgis < 1.5 the st_curvetoline function does not exist if ( mConn->majorVersion() >= 2 || ( mConn->majorVersion() == 1 && mConn->minorVersion() >= 5 ) ) curveToLineFn = "st_curvetoline"; // st_ prefix is always used whereClause += QString( " AND %1(%2(%3%4),%5)" ) .arg( mConn->majorVersion() < 2 ? "intersects" : "st_intersects", curveToLineFn, QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ), castToGeometry ? "::geometry" : "", qBox ); } if ( !mSource->mRequestedSrid.isEmpty() && ( mSource->mRequestedSrid != mSource->mDetectedSrid || mSource->mRequestedSrid.toInt() == 0 ) ) { whereClause += QString( " AND %1(%2%3)=%4" ) .arg( mConn->majorVersion() < 2 ? "srid" : "st_srid", QgsPostgresConn::quotedIdentifier( mSource->mGeometryColumn ), castToGeometry ? "::geometry" : "", mSource->mRequestedSrid ); } if ( mSource->mRequestedGeomType != QGis::WKBUnknown && mSource->mRequestedGeomType != mSource->mDetectedGeomType ) { whereClause += QString( " AND %1" ).arg( QgsPostgresConn::postgisTypeFilter( mSource->mGeometryColumn, ( QgsWKBTypes::Type )mSource->mRequestedGeomType, castToGeometry ) ); } return whereClause; }