Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
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() );
}
Beispiel #7
0
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;
}