QgsRectangle QgsMapSettings::fullExtent() const { // reset the map canvas extent since the extent may now be smaller // We can't use a constructor since QgsRectangle normalizes the rectangle upon construction QgsRectangle fullExtent; fullExtent.setMinimal(); // iterate through the map layers and test each layers extent // against the current min and max values QgsDebugMsgLevel( QStringLiteral( "Layer count: %1" ).arg( mLayers.count() ), 5 ); const auto constMLayers = mLayers; for ( const QgsWeakMapLayerPointer &layerPtr : constMLayers ) { if ( QgsMapLayer *lyr = layerPtr.data() ) { QgsDebugMsgLevel( "Updating extent using " + lyr->name(), 5 ); QgsDebugMsgLevel( "Input extent: " + lyr->extent().toString(), 5 ); if ( lyr->extent().isNull() ) continue; // Layer extents are stored in the coordinate system (CS) of the // layer. The extent must be projected to the canvas CS QgsRectangle extent = layerExtentToOutputExtent( lyr, lyr->extent() ); QgsDebugMsgLevel( "Output extent: " + extent.toString(), 5 ); fullExtent.combineExtentWith( extent ); } } if ( fullExtent.width() == 0.0 || fullExtent.height() == 0.0 ) { // If all of the features are at the one point, buffer the // rectangle a bit. If they are all at zero, do something a bit // more crude. if ( fullExtent.xMinimum() == 0.0 && fullExtent.xMaximum() == 0.0 && fullExtent.yMinimum() == 0.0 && fullExtent.yMaximum() == 0.0 ) { fullExtent.set( -1.0, -1.0, 1.0, 1.0 ); } else { const double padFactor = 1e-8; double widthPad = fullExtent.xMinimum() * padFactor; double heightPad = fullExtent.yMinimum() * padFactor; double xmin = fullExtent.xMinimum() - widthPad; double xmax = fullExtent.xMaximum() + widthPad; double ymin = fullExtent.yMinimum() - heightPad; double ymax = fullExtent.yMaximum() + heightPad; fullExtent.set( xmin, ymin, xmax, ymax ); } } QgsDebugMsgLevel( "Full extent: " + fullExtent.toString(), 5 ); return fullExtent; }
QgsRectangle QgsRasterChangeCoords::getBoundingBox( const QgsRectangle &rect, bool toPixel ) { QgsRectangle rectReturn; QgsPointXY p1( rect.xMinimum(), rect.yMinimum() ); QgsPointXY p2( rect.xMaximum(), rect.yMaximum() ); QgsPointXY( QgsRasterChangeCoords::* func )( const QgsPointXY & ); func = toPixel ? &QgsRasterChangeCoords::toColumnLine : &QgsRasterChangeCoords::toXY; rectReturn.set( ( this->*func )( p1 ), ( this->*func )( p2 ) ); return rectReturn; }
int QgsGml::createBBoxFromCoordinateString( QgsRectangle &r, const QString& coordString ) const { QList<QgsPoint> points; if ( pointsFromCoordinateString( points, coordString ) != 0 ) { return 2; } if ( points.size() < 2 ) { return 3; } r.set( points[0], points[1] ); return 0; }
QgsRectangle QgsMapSettings::fullExtent() const { QgsDebugMsg( "called." ); QgsMapLayerRegistry* registry = QgsMapLayerRegistry::instance(); // reset the map canvas extent since the extent may now be smaller // We can't use a constructor since QgsRectangle normalizes the rectangle upon construction QgsRectangle fullExtent; fullExtent.setMinimal(); // iterate through the map layers and test each layers extent // against the current min and max values QStringList::const_iterator it = mLayers.begin(); QgsDebugMsg( QString( "Layer count: %1" ).arg( mLayers.count() ) ); while ( it != mLayers.end() ) { QgsMapLayer * lyr = registry->mapLayer( *it ); if ( !lyr ) { QgsDebugMsg( QString( "WARNING: layer '%1' not found in map layer registry!" ).arg( *it ) ); } else { QgsDebugMsg( "Updating extent using " + lyr->name() ); QgsDebugMsg( "Input extent: " + lyr->extent().toString() ); if ( lyr->extent().isNull() ) { ++it; continue; } // Layer extents are stored in the coordinate system (CS) of the // layer. The extent must be projected to the canvas CS QgsRectangle extent = layerExtentToOutputExtent( lyr, lyr->extent() ); QgsDebugMsg( "Output extent: " + extent.toString() ); fullExtent.unionRect( extent ); } ++it; } if ( fullExtent.width() == 0.0 || fullExtent.height() == 0.0 ) { // If all of the features are at the one point, buffer the // rectangle a bit. If they are all at zero, do something a bit // more crude. if ( fullExtent.xMinimum() == 0.0 && fullExtent.xMaximum() == 0.0 && fullExtent.yMinimum() == 0.0 && fullExtent.yMaximum() == 0.0 ) { fullExtent.set( -1.0, -1.0, 1.0, 1.0 ); } else { const double padFactor = 1e-8; double widthPad = fullExtent.xMinimum() * padFactor; double heightPad = fullExtent.yMinimum() * padFactor; double xmin = fullExtent.xMinimum() - widthPad; double xmax = fullExtent.xMaximum() + widthPad; double ymin = fullExtent.yMinimum() - heightPad; double ymax = fullExtent.yMaximum() + heightPad; fullExtent.set( xmin, ymin, xmax, ymax ); } } QgsDebugMsg( "Full extent: " + fullExtent.toString() ); return fullExtent; }
bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } // skip features without geometry if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom ) { OGR_F_Destroy( fet ); close(); return false; } readFeature( fet, feature ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; QgsRectangle selectionRect; while (( fet = OGR_L_GetNextFeature( P->ogrLayer ) ) ) { // skip features without geometry if ( !P->mFetchFeaturesWithoutGeom && !OGR_F_GetGeometryRef( fet ) ) { OGR_F_Destroy( fet ); continue; } readFeature( fet, feature ); if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) { //precise test for intersection with search rectangle //first make QgsRectangle from OGRPolygon OGREnvelope env; memset( &env, 0, sizeof( env ) ); if ( mSelectionRectangle ) OGR_G_GetEnvelope( mSelectionRectangle, &env ); if ( env.MinX != 0 || env.MinY != 0 || env.MaxX != 0 || env.MaxY != 0 ) //if envelope is invalid, skip the precise intersection test { selectionRect.set( env.MinX, env.MinY, env.MaxX, env.MaxY ); if ( !feature.geometry() || !feature.geometry()->intersects( selectionRect ) ) { OGR_F_Destroy( fet ); continue; } } } // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }
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() ); }
int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format ) { QgsDebugMsg( "Info format is:" + format ); //read TYPENAME QMap<QString, QString>::const_iterator type_name_it = mParameterMap.find( "TYPENAME" ); if ( type_name_it != mParameterMap.end() ) { mTypeName = type_name_it.value(); } else { return 1; } QStringList wfsLayersId = mConfigParser->wfsLayers(); QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes(); QList<QgsMapLayer*> layerList; QgsMapLayer* currentLayer = 0; layerList = mConfigParser->mapLayerFromStyle( mTypeName, "" ); currentLayer = layerList.at( 0 ); QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer ); if ( layer && wfsLayersId.contains( layer->id() ) ) { //is there alias info for this vector layer? QMap< int, QString > layerAliasInfo; QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); if ( aliasIt != aliasInfo.constEnd() ) { layerAliasInfo = aliasIt.value(); } //hidden attributes for this layer QSet<QString> layerHiddenAttributes; QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); if ( hiddenIt != hiddenAttributes.constEnd() ) { layerHiddenAttributes = hiddenIt.value(); } //do a select with searchRect and go through all the features QgsVectorDataProvider* provider = layer->dataProvider(); if ( !provider ) { return 2; } QgsFeature feature; QgsAttributeMap featureAttributes; const QgsFieldMap& fields = provider->fields(); //map extent QgsRectangle searchRect = layer->extent(); //read FEATUREDID bool fidOk = false; QString fid; QMap<QString, QString>::const_iterator fidIt = mParameterMap.find( "FEATUREID" ); if ( fidIt != mParameterMap.end() ) { fidOk = true; fid = fidIt.value(); } //read FILTER bool filterOk = false; QDomDocument filter; QMap<QString, QString>::const_iterator filterIt = mParameterMap.find( "FILTER" ); if ( filterIt != mParameterMap.end() ) { try { QString errorMsg; if ( !filter.setContent( filterIt.value(), true, &errorMsg ) ) { QgsDebugMsg( "soap request parse error" ); QgsDebugMsg( "error message: " + errorMsg ); QgsDebugMsg( "the xml string was:" ); QgsDebugMsg( filterIt.value() ); } else { filterOk = true; } } catch ( QgsMapServiceException& e ) { Q_UNUSED( e ); filterOk = false; } } bool conversionSuccess; double minx, miny, maxx, maxy; bool bboxOk = false; //read BBOX QMap<QString, QString>::const_iterator bbIt = mParameterMap.find( "BBOX" ); if ( bbIt == mParameterMap.end() ) { minx = 0; miny = 0; maxx = 0; maxy = 0; } else { bboxOk = true; QString bbString = bbIt.value(); minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} } //read MAXFEATURES long maxFeat = layer->featureCount(); long featureCounter = 0; QMap<QString, QString>::const_iterator mfIt = mParameterMap.find( "MAXFEATURES" ); if ( mfIt != mParameterMap.end() ) { QString mfString = mfIt.value(); bool mfOk; maxFeat = mfString.toLong( &mfOk, 10 ); if ( !mfOk ) { maxFeat = layer->featureCount(); } } //read PROPERTYNAME mWithGeom = true; QgsAttributeList attrIndexes = provider->attributeIndexes(); QMap<QString, QString>::const_iterator pnIt = mParameterMap.find( "PROPERTYNAME" ); if ( pnIt != mParameterMap.end() ) { QStringList attrList = pnIt.value().split( "," ); if ( attrList.size() > 0 ) { mWithGeom = false; QStringList::const_iterator alstIt; QList<int> idxList; QMap<QString, int> fieldMap = provider->fieldNameMap(); QMap<QString, int>::const_iterator fieldIt; QString fieldName; for ( alstIt = attrList.begin(); alstIt != attrList.end(); ++alstIt ) { fieldName = *alstIt; fieldIt = fieldMap.find( fieldName ); if ( fieldIt != fieldMap.end() ) { idxList.append( fieldIt.value() ); } else if ( fieldName == "geometry" ) { mWithGeom = true; } } if ( idxList.size() > 0 || mWithGeom ) { attrIndexes = idxList; } else { mWithGeom = true; } } } QgsCoordinateReferenceSystem layerCrs = layer->crs(); startGetFeature( request, format ); if ( fidOk ) { provider->featureAtId( fid.toInt(), feature, mWithGeom, attrIndexes ); sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerHiddenAttributes ); } else if ( filterOk ) { provider->select( attrIndexes, searchRect, mWithGeom, true ); try { QgsFilter* mFilter = QgsFilter::createFilterFromXml( filter.firstChild().toElement().firstChild().toElement(), layer ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { if ( mFilter ) { if ( mFilter->evaluate( feature ) ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } else { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } delete mFilter; } catch ( QgsMapServiceException& e ) { Q_UNUSED( e ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } } else { if ( bboxOk ) searchRect.set( minx, miny, maxx, maxy ); provider->select( attrIndexes, searchRect, mWithGeom, true ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } endGetFeature( request, format ); } else { return 2; } return 0; }