コード例 #1
0
QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *parent, Qt::WFlags fl )
    : QDialog( parent, fl )
    , mMapCanvas( mapCanvas )
{
  setupUi( this );
  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
  connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
  connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
  connect( this, SIGNAL( accepted() ), this, SLOT( apply() ) );
  connect( projectionSelector, SIGNAL( sridSelected( QString ) ), this, SLOT( setMapUnitsToCurrentProjection() ) );

  ///////////////////////////////////////////////////////////
  // Properties stored in map canvas's QgsMapRenderer
  // these ones are propagated to QgsProject by a signal

  QgsMapRenderer* myRenderer = mMapCanvas->mapRenderer();
  QGis::UnitType myUnit = myRenderer->mapUnits();
  setMapUnits( myUnit );

  //see if the user wants on the fly projection enabled
  bool myProjectionEnabled = myRenderer->hasCrsTransformEnabled();
  cbxProjectionEnabled->setChecked( myProjectionEnabled );
  btnGrpMapUnits->setEnabled( !myProjectionEnabled );

  mProjectSrsId = myRenderer->destinationCrs().srsid();
  QgsDebugMsg( "Read project CRSID: " + QString::number( mProjectSrsId ) );
  projectionSelector->setSelectedCrsId( mProjectSrsId );

  ///////////////////////////////////////////////////////////
  // Properties stored in QgsProject

  title( QgsProject::instance()->title() );

  // get the manner in which the number of decimal places in the mouse
  // position display is set (manual or automatic)
  bool automaticPrecision = QgsProject::instance()->readBoolEntry( "PositionPrecision", "/Automatic" );
  if ( automaticPrecision )
  {
    radAutomatic->setChecked( true );
    spinBoxDP->setDisabled( true );
    labelDP->setDisabled( true );
  }
  else
  {
    radManual->setChecked( true );
  }

  cbxAbsolutePath->setCurrentIndex( QgsProject::instance()->readBoolEntry( "Paths", "/Absolute", true ) ? 0 : 1 );

  int dp = QgsProject::instance()->readNumEntry( "PositionPrecision", "/DecimalPlaces" );
  spinBoxDP->setValue( dp );

  //get the color selections and set the button color accordingly
  int myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
  int myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
  int myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
  int myAlphaInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 );
  QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt, myAlphaInt );
  pbnSelectionColor->setColor( myColor );

  //get the color for map canvas background and set button color accordingly (default white)
  myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorRedPart", 255 );
  myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorGreenPart", 255 );
  myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
  myColor = QColor( myRedInt, myGreenInt, myBlueInt );
  pbnCanvasColor->setColor( myColor );

  QgsMapLayer* currentLayer = 0;

  QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( "Identify", "/disabledLayers" );

  const QMap<QString, QgsMapLayer*> &mapLayers = QgsMapLayerRegistry::instance()->mapLayers();

  if ( mMapCanvas->currentLayer() )
  {
    mLayerSrsId = mMapCanvas->currentLayer()->crs().srsid();
  }
  else if ( mapLayers.size() > 0 )
  {
    mLayerSrsId = mapLayers.begin().value()->crs().srsid();
  }
  else
  {
    mLayerSrsId = mProjectSrsId;
  }

  twIdentifyLayers->setColumnCount( 3 );
  twIdentifyLayers->horizontalHeader()->setVisible( true );
  twIdentifyLayers->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "Layer" ) ) );
  twIdentifyLayers->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "Type" ) ) );
  twIdentifyLayers->setHorizontalHeaderItem( 2, new QTableWidgetItem( tr( "Identifiable" ) ) );
  twIdentifyLayers->setRowCount( mapLayers.size() );
  twIdentifyLayers->verticalHeader()->setResizeMode( QHeaderView::ResizeToContents );

  int i = 0;
  for ( QMap<QString, QgsMapLayer*>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); it++, i++ )
  {
    currentLayer = it.value();

    QTableWidgetItem *twi = new QTableWidgetItem( QString::number( i ) );
    twIdentifyLayers->setVerticalHeaderItem( i, twi );

    twi = new QTableWidgetItem( currentLayer->name() );
    twi->setData( Qt::UserRole, it.key() );
    twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
    twIdentifyLayers->setItem( i, 0, twi );

    QString type;
    if ( currentLayer->type() == QgsMapLayer::VectorLayer )
    {
      type = tr( "Vector" );
    }
    else if ( currentLayer->type() == QgsMapLayer::RasterLayer )
    {
      QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( currentLayer );

      if ( rl && rl->providerType() == "wms" )
      {
        type = tr( "WMS" );
      }
      else
      {
        type = tr( "Raster" );
      }
    }

    twi = new QTableWidgetItem( type );
    twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
    twIdentifyLayers->setItem( i, 1, twi );

    QCheckBox *cb = new QCheckBox();
    cb->setChecked( !noIdentifyLayerIdList.contains( currentLayer->id() ) );
    twIdentifyLayers->setCellWidget( i, 2, cb );
  }

  grpWMSServiceCapabilities->setChecked( QgsProject::instance()->readBoolEntry( "WMSServiceCapabilities", "/", false ) );
  mWMSTitle->setText( QgsProject::instance()->readEntry( "WMSServiceTitle", "/" ) );
  mWMSContactOrganization->setText( QgsProject::instance()->readEntry( "WMSContactOrganization", "/", "" ) );
  mWMSContactPerson->setText( QgsProject::instance()->readEntry( "WMSContactPerson", "/", "" ) );
  mWMSContactMail->setText( QgsProject::instance()->readEntry( "WMSContactMail", "/", "" ) );
  mWMSContactPhone->setText( QgsProject::instance()->readEntry( "WMSContactPhone", "/", "" ) );
  mWMSAbstract->setPlainText( QgsProject::instance()->readEntry( "WMSServiceAbstract", "/", "" ) );
  mWMSOnlineResourceLineEdit->setText( QgsProject::instance()->readEntry( "WMSOnlineResource", "/", "" ) );

  bool ok;
  QStringList values;

  mWMSExtMinX->setValidator( new QDoubleValidator( mWMSExtMinX ) );
  mWMSExtMinY->setValidator( new QDoubleValidator( mWMSExtMinY ) );
  mWMSExtMaxX->setValidator( new QDoubleValidator( mWMSExtMaxX ) );
  mWMSExtMaxY->setValidator( new QDoubleValidator( mWMSExtMaxY ) );

  values = QgsProject::instance()->readListEntry( "WMSExtent", "/", &ok );
  grpWMSExt->setChecked( ok && values.size() == 4 );
  if ( grpWMSExt->isChecked() )
  {
    mWMSExtMinX->setText( values[0] );
    mWMSExtMinY->setText( values[1] );
    mWMSExtMaxX->setText( values[2] );
    mWMSExtMaxY->setText( values[3] );
  }

  values = QgsProject::instance()->readListEntry( "WMSCrsList", "/", &ok );
  grpWMSList->setChecked( ok && values.size() > 0 );
  if ( grpWMSList->isChecked() )
  {
    mWMSList->addItems( values );
  }
  else
  {
    values = QgsProject::instance()->readListEntry( "WMSEpsgList", "/", &ok );
    grpWMSList->setChecked( ok && values.size() > 0 );
    if ( grpWMSList->isChecked() )
    {
      QStringList list;
      foreach( QString value, values )
      {
        list << QString( "EPSG:%1" ).arg( value );
      }

      mWMSList->addItems( list );
    }
コード例 #2
0
QgsGrassRasterProvider::~QgsGrassRasterProvider()
{
  QgsDebugMsg( "QgsGrassRasterProvider: deconstructing." );
}
コード例 #3
0
int QgsMapCanvasSnapper::snapToBackgroundLayers( const QgsPoint& point, QList<QgsSnappingResult>& results, const QList<QgsPoint>& excludePoints )
{
  results.clear();

  if ( !mSnapper )
    return 5;

  //topological editing on?
  int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );

  //snapping on intersection on?
  int intersectionSnapping = QgsProject::instance()->readNumEntry( "Digitizing", "/IntersectionSnapping", 0 );

  if ( topologicalEditing == 0 )
  {
    if ( intersectionSnapping == 0 )
      mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult );
    else
      mSnapper->setSnapMode( QgsSnapper::SnapWithResultsWithinTolerances );
  }
  else if ( intersectionSnapping == 0 )
  {
    mSnapper->setSnapMode( QgsSnapper::SnapWithResultsForSamePosition );
  }
  else
  {
    mSnapper->setSnapMode( QgsSnapper::SnapWithResultsWithinTolerances );
  }

  //read snapping settings from project
  bool snappingDefinedInProject, ok;
  QStringList layerIdList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingList", QStringList(), &snappingDefinedInProject );
  QStringList enabledList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingEnabledList", QStringList(), &ok );
  QStringList toleranceList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceList", QStringList(), &ok );
  QStringList toleranceUnitList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceUnitList", QStringList(), &ok );
  QStringList snapToList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnapToList", QStringList(), &ok );

  if ( !( layerIdList.size() == enabledList.size() &&
          layerIdList.size() == toleranceList.size() &&
          layerIdList.size() == toleranceUnitList.size() &&
          layerIdList.size() == snapToList.size() ) )
  {
    // lists must have the same size, otherwise something is wrong
    return 1;
  }

  QList<QgsSnapper::SnapLayer> snapLayers;
  QgsSnapper::SnapLayer snapLayer;

  // Use snapping information from the project
  if ( snappingDefinedInProject )
  {
    // set layers, tolerances, snap to segment/vertex to QgsSnapper
    QStringList::const_iterator layerIt( layerIdList.constBegin() );
    QStringList::const_iterator tolIt( toleranceList.constBegin() );
    QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
    QStringList::const_iterator snapIt( snapToList.constBegin() );
    QStringList::const_iterator enabledIt( enabledList.constBegin() );
    for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
    {
      if ( *enabledIt != "enabled" )
      {
        // skip layer if snapping is not enabled
        continue;
      }

      //layer
      QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( QgsMapLayerRegistry::instance()->mapLayer( *layerIt ) );
      if ( !vlayer || !vlayer->hasGeometryType() )
        continue;

      snapLayer.mLayer = vlayer;

      //tolerance
      snapLayer.mTolerance = tolIt->toDouble();
      snapLayer.mUnitType = ( QgsTolerance::UnitType ) tolUnitIt->toInt();

      // segment or vertex
      if ( *snapIt == "to_vertex" )
      {
        snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
      }
      else if ( *snapIt == "to_segment" )
      {
        snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
      }
      else
      {
        // to vertex and segment
        snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
      }

      snapLayers.append( snapLayer );
    }
  }
  else
  {
    // nothing in project. Use default snapping tolerance to vertex of current layer
    QgsMapLayer* currentLayer = mMapCanvas->currentLayer();
    if ( !currentLayer )
      return 2;

    QgsVectorLayer* currentVectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
    if ( !currentVectorLayer )
      return 3;

    snapLayer.mLayer = currentVectorLayer;

    //default snap mode
    QSettings settings;
    QString defaultSnapString = settings.value( "/qgis/digitizing/default_snap_mode", "off" ).toString();
    if ( defaultSnapString == "to segment" )
    {
      snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
    }
    else if ( defaultSnapString == "to vertex and segment" )
    {
      snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
    }
    else if ( defaultSnapString == "to vertex" )
    {
      snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
    }
    else
    {
      return 0;
    }

    //default snapping tolerance (returned in map units)
    snapLayer.mTolerance = QgsTolerance::defaultTolerance( currentVectorLayer, mMapCanvas->mapSettings() );
    snapLayer.mUnitType = QgsTolerance::MapUnits;

    snapLayers.append( snapLayer );
  }

  mSnapper->setSnapLayers( snapLayers );

  if ( mSnapper->snapPoint( point, results, excludePoints ) != 0 )
    return 4;

  if ( intersectionSnapping != 1 )
    return 0;

  QList<QgsSnappingResult> segments;
  QList<QgsSnappingResult> points;
  for ( QList<QgsSnappingResult>::const_iterator it = results.constBegin();
        it != results.constEnd();
        ++it )
  {
    if ( it->snappedVertexNr == -1 )
    {
      QgsDebugMsg( "segment" );
      segments.push_back( *it );
    }
    else
    {
      QgsDebugMsg( "no segment" );
      points.push_back( *it );
    }
  }

  if ( segments.length() < 2 )
    return 0;

  QList<QgsSnappingResult> myResults;

  for ( QList<QgsSnappingResult>::const_iterator oSegIt = segments.constBegin();
        oSegIt != segments.constEnd();
        ++oSegIt )
  {
    QgsDebugMsg( QString::number( oSegIt->beforeVertexNr ) );

    QVector<QgsPoint> vertexPoints;
    vertexPoints.append( oSegIt->beforeVertex );
    vertexPoints.append( oSegIt->afterVertex );

    QgsGeometry* lineA = QgsGeometry::fromPolyline( vertexPoints );

    for ( QList<QgsSnappingResult>::iterator iSegIt = segments.begin();
          iSegIt != segments.end();
          ++iSegIt )
    {
      QVector<QgsPoint> vertexPoints;
      vertexPoints.append( iSegIt->beforeVertex );
      vertexPoints.append( iSegIt->afterVertex );
      QgsGeometry* lineB = QgsGeometry::fromPolyline( vertexPoints );

      QgsGeometry* intersectionPoint = lineA->intersection( lineB );
      if ( intersectionPoint->type()  == QGis::Point )
      {
        //We have to check the intersection point is inside the tolerance distance for both layers
        double toleranceA = 0;
        double toleranceB = 0;
        for ( int i = 0 ;i < snapLayers.size();++i )
        {
          if ( snapLayers[i].mLayer == oSegIt->layer )
          {
            toleranceA = QgsTolerance::toleranceInMapUnits( snapLayers[i].mTolerance, snapLayers[i].mLayer, mMapCanvas->mapSettings(), snapLayers[i].mUnitType );
          }
          if ( snapLayers[i].mLayer == iSegIt->layer )
          {
            toleranceB = QgsTolerance::toleranceInMapUnits( snapLayers[i].mTolerance, snapLayers[i].mLayer, mMapCanvas->mapSettings(), snapLayers[i].mUnitType );
          }
        }
        QgsGeometry* cursorPoint = QgsGeometry::fromPoint( point );
        double distance = intersectionPoint->distance( *cursorPoint );
        if ( distance < toleranceA && distance < toleranceB )
        {
          iSegIt->snappedVertex = intersectionPoint->asPoint();
          myResults.append( *iSegIt );
        }
      }
    }
  }

  if ( myResults.length() > 0 )
  {
    results.clear();
    results = myResults;
  }

  return 0;
}
コード例 #4
0
ファイル: qgsdb2geometrycolumns.cpp プロジェクト: ndavid/QGIS
bool QgsDb2GeometryColumns::populateLayerProperty( QgsDb2LayerProperty &layer )
{
  if ( !mQuery.isActive() || !mQuery.next() )
  {
    return false;
  }

  layer.schemaName = mQuery.value( 0 ).toString().trimmed();
  layer.tableName = mQuery.value( 1 ).toString().trimmed();
  layer.geometryColName = mQuery.value( 2 ).toString().trimmed();
  layer.type = mQuery.value( 3 ).toString();
  if ( mQuery.value( 4 ).isNull() )
  {
    layer.srid = QLatin1String( "" );
    layer.srsName = QLatin1String( "" );
  }
  else
  {
    layer.srid = mQuery.value( 4 ).toString();
    layer.srsName = mQuery.value( 5 ).toString();
  }
  layer.extents = QStringLiteral( "0 0 0 0" ); // no extents
  if ( ENV_LUW == mEnvironment )
  {
    if ( !mQuery.value( 6 ).isNull() ) // Don't get values if null
    {
      layer.extents = QString(
                        mQuery.value( 6 ).toString() + ' ' +
                        mQuery.value( 7 ).toString() + ' ' +
                        mQuery.value( 8 ).toString() + ' ' +
                        mQuery.value( 9 ).toString() ).trimmed();
    }
  }
  QgsDebugMsg( QString( "layer: %1.%2(%3) type='%4' srid='%5' srsName='%6'" )
               .arg( layer.schemaName, layer.tableName, layer.geometryColName,
                     layer.type, layer.srid, layer.srsName ) );
  QgsDebugMsg( "Extents: '" + layer.extents + "'" );

  layer.pkCols = QStringList();

  // Use the Qt functionality to get the primary key information
  // to set the FID column.
  // We can only use the primary key if it only has one column and
  // the type is Integer or BigInt.
  QString table = QStringLiteral( "%1.%2" ).arg( layer.schemaName, layer.tableName );
  QSqlIndex pk = mDatabase.primaryIndex( table );
  if ( pk.count() == 1 )
  {
    QSqlField pkFld = pk.field( 0 );
    QVariant::Type pkType = pkFld.type();
    if ( ( pkType == QVariant::Int ||  pkType == QVariant::LongLong ) )
    {
      QString fidColName = pk.fieldName( 0 );
      layer.pkCols.append( fidColName );
      QgsDebugMsg( "pk is: " + fidColName );
    }
  }
  else
  {
    QgsDebugMsg( "Warning: table primary key count is " + QString::number( pk.count() ) );
  }
  layer.pkColumnName = layer.pkCols.size() > 0 ? layer.pkCols.at( 0 ) : QString();
  return true;
}
コード例 #5
0
QgsRasterFormatSaveOptionsWidget::QgsRasterFormatSaveOptionsWidget( QWidget* parent, const QString& format,
    QgsRasterFormatSaveOptionsWidget::Type type, const QString& provider )
    : QWidget( parent )
    , mFormat( format )
    , mProvider( provider )
    , mRasterLayer( nullptr )
    , mRasterFileName( QString() )
    , mPyramids( false )
    , mPyramidsFormat( QgsRaster::PyramidsGTiff )

{
  setupUi( this );

  setType( type );

  if ( mBuiltinProfiles.isEmpty() )
  {
    // key=profileKey values=format,profileName,options
    mBuiltinProfiles[ QStringLiteral( "z_adefault" )] = ( QStringList() << QLatin1String( "" ) << tr( "Default" ) << QLatin1String( "" ) );

    // these GTiff profiles are based on Tim's benchmarks at
    // http://linfiniti.com/2011/05/gdal-efficiency-of-various-compression-algorithms/
    // big: no compression | medium: reasonable size/speed tradeoff | small: smallest size
    mBuiltinProfiles[ QStringLiteral( "z_gtiff_1big" )] =
      ( QStringList() << QStringLiteral( "GTiff" ) << tr( "No compression" )
        << QStringLiteral( "COMPRESS=NONE BIGTIFF=IF_NEEDED" ) );
    mBuiltinProfiles[ QStringLiteral( "z_gtiff_2medium" )] =
      ( QStringList() << QStringLiteral( "GTiff" ) << tr( "Low compression" )
        << QStringLiteral( "COMPRESS=PACKBITS" ) );
    mBuiltinProfiles[ QStringLiteral( "z_gtiff_3small" )] =
      ( QStringList() << QStringLiteral( "GTiff" ) << tr( "High compression" )
        << QStringLiteral( "COMPRESS=DEFLATE PREDICTOR=2 ZLEVEL=9" ) );
    mBuiltinProfiles[ QStringLiteral( "z_gtiff_4jpeg" )] =
      ( QStringList() << QStringLiteral( "GTiff" ) << tr( "JPEG compression" )
        << QStringLiteral( "COMPRESS=JPEG JPEG_QUALITY=75" ) );

    // overview compression schemes for GTiff format, see
    // http://www.gdal.org/gdaladdo.html and http://www.gdal.org/frmt_gtiff.html
    // TODO - should we offer GDAL_TIFF_OVR_BLOCKSIZE option here or in QgsRasterPyramidsOptionsWidget ?
    mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_1big" )] =
      ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "No compression" )
        << QStringLiteral( "COMPRESS_OVERVIEW=NONE BIGTIFF_OVERVIEW=IF_NEEDED" ) );
    mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_2medium" )] =
      ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "Low compression" )
        << QStringLiteral( "COMPRESS_OVERVIEW=PACKBITS" ) );
    mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_3small" )] =
      ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "High compression" )
        << QStringLiteral( "COMPRESS_OVERVIEW=DEFLATE PREDICTOR_OVERVIEW=2 ZLEVEL=9" ) ); // how to set zlevel?
    mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_4jpeg" )] =
      ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "JPEG compression" )
        << PYRAMID_JPEG_YCBCR_COMPRESSION );
  }

  connect( mProfileComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
           this, SLOT( updateOptions() ) );
  connect( mOptionsTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( optionsTableChanged() ) );
  connect( mOptionsHelpButton, SIGNAL( clicked() ), this, SLOT( helpOptions() ) );
  connect( mOptionsValidateButton, SIGNAL( clicked() ), this, SLOT( validateOptions() ) );

  // create eventFilter to map right click to swapOptionsUI()
  // mOptionsLabel->installEventFilter( this );
  mOptionsLineEdit->installEventFilter( this );
  mOptionsStackedWidget->installEventFilter( this );

  updateControls();
  updateProfiles();

  QgsDebugMsg( "done" );
}
コード例 #6
0
void QgsGrassFeatureIterator::setSelectionRect( const QgsRectangle& rect, bool useIntersect )
{
  //apply selection rectangle
  resetSelection( 0 );

  if ( !useIntersect )
  { // select by bounding boxes only
    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 ( P->mLayerType == QgsGrassProvider::POINT || P->mLayerType == QgsGrassProvider::CENTROID ||
         P->mLayerType == QgsGrassProvider::LINE || P->mLayerType == QgsGrassProvider::FACE ||
         P->mLayerType == QgsGrassProvider::BOUNDARY )
    {
      Vect_select_lines_by_box( P->mMap, &box, P->mGrassType, mList );
    }
    else if ( P->mLayerType == QgsGrassProvider::POLYGON )
    {
      Vect_select_areas_by_box( P->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 ( P->mLayerType == QgsGrassProvider::POINT || P->mLayerType == QgsGrassProvider::CENTROID ||
         P->mLayerType == QgsGrassProvider::LINE || P->mLayerType == QgsGrassProvider::FACE ||
         P->mLayerType == QgsGrassProvider::BOUNDARY )
    {
      Vect_select_lines_by_polygon( P->mMap, Polygon, 0, NULL, P->mGrassType, mList );
    }
    else if ( P->mLayerType == QgsGrassProvider::POLYGON )
    {
      Vect_select_areas_by_polygon( P->mMap, Polygon, 0, NULL, 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" );
    }
  }

}
コード例 #7
0
ファイル: qgslabeldialog.cpp プロジェクト: AaronGaim/QGIS
void QgsLabelDialog::apply()
{
  QgsDebugMsg( "entering." );

  //set the label props that are NOT bound to a field in the attributes tbl
  //All of these are set in the labelAttributes member of the layer
  QgsLabelAttributes * myLabelAttributes = mLabel->labelAttributes();
  myLabelAttributes->setText( leDefaultLabel->text() );
  myLabelAttributes->setFamily( mFont.family() );
  int myTypeInt = cboFontSizeUnits->currentIndex() == 0 ? QgsLabelAttributes::PointUnits : QgsLabelAttributes::MapUnits;
  myLabelAttributes->setSize( mFont.pointSizeF(), myTypeInt );
  myLabelAttributes->setBold( mFont.bold() );
  myLabelAttributes->setItalic( mFont.italic() );
  myLabelAttributes->setUnderline( mFont.underline() );
  myLabelAttributes->setStrikeOut( mFont.strikeOut() );
  myLabelAttributes->setColor( mFontColor );
  myTypeInt = cboOffsetUnits->currentIndex() == 0 ?  QgsLabelAttributes::PointUnits : QgsLabelAttributes::MapUnits;
  myLabelAttributes->setOffset( spinXOffset->value(), spinYOffset->value(), myTypeInt );
  myLabelAttributes->setAutoAngle( spinAngle->value() == -1 );
  myLabelAttributes->setAngle( spinAngle->value() );

  //the values here may seem a bit counterintuitive - basically everything
  //is the reverse of the way you think it should be...
  //TODO investigate in QgsLabel why this needs to be the case
  if ( radioAboveLeft->isChecked() )   myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignBottom );
  if ( radioBelowLeft->isChecked() )   myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignTop );
  if ( radioAboveRight->isChecked() )  myLabelAttributes->setAlignment( Qt::AlignLeft  | Qt::AlignBottom );
  if ( radioBelowRight->isChecked() )  myLabelAttributes->setAlignment( Qt::AlignLeft  | Qt::AlignTop );
  if ( radioLeft->isChecked() )        myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
  if ( radioRight->isChecked() )       myLabelAttributes->setAlignment( Qt::AlignLeft  | Qt::AlignVCenter );
  if ( radioAbove->isChecked() )       myLabelAttributes->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
  if ( radioBelow->isChecked() )       myLabelAttributes->setAlignment( Qt::AlignTop   | Qt::AlignHCenter );
  if ( radioOver->isChecked() )        myLabelAttributes->setAlignment( Qt::AlignCenter );

  myLabelAttributes->setMultilineEnabled( chkUseMultiline->isChecked() );
  myLabelAttributes->setSelectedOnly( chkSelectedOnly->isChecked() );
  myLabelAttributes->setBufferEnabled( chkUseBuffer->isChecked() );
  myLabelAttributes->setBufferColor( mBufferColor );
  myTypeInt = cboBufferSizeUnits->currentIndex() == 0 ? QgsLabelAttributes::PointUnits : QgsLabelAttributes::MapUnits;
  myLabelAttributes->setBufferSize( spinBufferSize->value(), myTypeInt );
  //TODO - transparency attributes for buffers

  //set the label props that are data bound to a field in the attributes tbl
  mLabel->setLabelField( QgsLabel::Text,  fieldIndexFromName( cboLabelField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Family, fieldIndexFromName( cboFontField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Bold,  fieldIndexFromName( cboBoldField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Italic,  fieldIndexFromName( cboItalicField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Underline,  fieldIndexFromName( cboUnderlineField->currentText() ) );
  mLabel->setLabelField( QgsLabel::StrikeOut,  fieldIndexFromName( cboStrikeOutField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Size,  fieldIndexFromName( cboFontSizeField->currentText() ) );
  mLabel->setLabelField( QgsLabel::SizeType,  fieldIndexFromName( cboFontSizeTypeField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Color,  fieldIndexFromName( cboFontColorField->currentText() ) );
  mLabel->setLabelField( QgsLabel::BufferSize,  fieldIndexFromName( cboBufferSizeField->currentText() ) );
  //mLabel->setLabelField( QgsLabel::BufferTransparency,  cboBufferTransparencyField->currentText() );
  mLabel->setLabelField( QgsLabel::XCoordinate,  fieldIndexFromName( cboXCoordinateField->currentText() ) );
  mLabel->setLabelField( QgsLabel::YCoordinate,  fieldIndexFromName( cboYCoordinateField->currentText() ) );
  mLabel->setLabelField( QgsLabel::XOffset,  fieldIndexFromName( cboXOffsetField->currentText() ) );
  mLabel->setLabelField( QgsLabel::YOffset,  fieldIndexFromName( cboYOffsetField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Alignment,  fieldIndexFromName( cboAlignmentField->currentText() ) );
  mLabel->setLabelField( QgsLabel::Angle,  fieldIndexFromName( cboAngleField->currentText() ) );

  // set up the scale based layer visibility stuff....
  mLabel->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
  mLabel->setMinScale( leMinimumScale->text().toFloat() );
  mLabel->setMaxScale( leMaximumScale->text().toFloat() );
}
コード例 #8
0
void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
{
  QStringList messages;

  // assume the layer is invalid until proven otherwise

  mLayerValid = false;
  mValid = false;
  mRescanRequired = false;

  clearInvalidLines();

  // Initiallize indexes

  resetIndexes();
  bool buildSpatialIndex = buildIndexes && mSpatialIndex != 0;

  // No point building a subset index if there is no geometry, as all
  // records will be included.

  bool buildSubsetIndex = buildIndexes && mBuildSubsetIndex && mGeomRep != GeomNone;

  if ( ! mFile->isValid() )
  {
    // uri is invalid so the layer must be too...

    messages.append( tr( "File cannot be opened or delimiter parameters are not valid" ) );
    reportErrors( messages );
    QgsDebugMsg( "Delimited text source invalid - filename or delimiter parameters" );
    return;
  }

  // Open the file and get number of rows, etc. We assume that the
  // file has a header row and process accordingly. Caller should make
  // sure that the delimited file is properly formed.

  if ( mGeomRep == GeomAsWkt )
  {
    mWktFieldIndex = mFile->fieldIndex( mWktFieldName );
    if ( mWktFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "Wkt" ).arg( mWktFieldName ) );
    }
  }
  else if ( mGeomRep == GeomAsXy )
  {
    mXFieldIndex = mFile->fieldIndex( mXFieldName );
    mYFieldIndex = mFile->fieldIndex( mYFieldName );
    if ( mXFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "X" ).arg( mWktFieldName ) );
    }
    if ( mYFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "Y" ).arg( mWktFieldName ) );
    }
  }
  if ( messages.size() > 0 )
  {
    reportErrors( messages );
    QgsDebugMsg( "Delimited text source invalid - missing geometry fields" );
    return;
  }

  // Scan the entire file to determine
  // 1) the number of fields (this is handled by QgsDelimitedTextFile mFile
  // 2) the number of valid features.  Note that the selection of valid features
  //    should match the code in QgsDelimitedTextFeatureIterator
  // 3) the geometric extents of the layer
  // 4) the type of each field
  //
  // Also build subset and spatial indexes.

  QStringList parts;
  long nEmptyRecords = 0;
  long nBadFormatRecords = 0;
  long nIncompatibleGeometry = 0;
  long nInvalidGeometry = 0;
  long nEmptyGeometry = 0;
  mNumberFeatures = 0;
  mExtent = QgsRectangle();

  QList<bool> isEmpty;
  QList<bool> couldBeInt;
  QList<bool> couldBeDouble;

  while ( true )
  {
    QgsDelimitedTextFile::Status status = mFile->nextRecord( parts );
    if ( status == QgsDelimitedTextFile::RecordEOF ) break;
    if ( status != QgsDelimitedTextFile::RecordOk )
    {
      nBadFormatRecords++;
      recordInvalidLine( tr( "Invalid record format at line %1" ) );
      continue;
    }
    // Skip over empty records
    if ( recordIsEmpty( parts ) )
    {
      nEmptyRecords++;
      continue;
    }

    // Check geometries are valid
    bool geomValid = true;

    if ( mGeomRep == GeomAsWkt )
    {
      if ( mWktFieldIndex >= parts.size() || parts[mWktFieldIndex].isEmpty() )
      {
        nEmptyGeometry++;
        geomValid = false;
      }
      else
      {
        // Get the wkt - confirm it is valid, get the type, and
        // if compatible with the rest of file, add to the extents

        QString sWkt = parts[mWktFieldIndex];
        QgsGeometry *geom = 0;
        if ( !mWktHasPrefix && sWkt.indexOf( WktPrefixRegexp ) >= 0 )
          mWktHasPrefix = true;
        if ( !mWktHasZM && sWkt.indexOf( WktZMRegexp ) >= 0 )
          mWktHasZM = true;
        geom = geomFromWkt( sWkt, mWktHasPrefix, mWktHasZM );

        if ( geom )
        {
          QGis::WkbType type = geom->wkbType();
          if ( type != QGis::WKBNoGeometry )
          {
            if ( mGeometryType == QGis::UnknownGeometry || geom->type() == mGeometryType )
            {
              mGeometryType = geom->type();
              if ( mNumberFeatures == 0 )
              {
                mNumberFeatures++;
                mWkbType = type;
                mExtent = geom->boundingBox();
              }
              else
              {
                mNumberFeatures++;
                if ( geom->isMultipart() ) mWkbType = type;
                QgsRectangle bbox( geom->boundingBox() );
                mExtent.combineExtentWith( &bbox );
              }
              if ( buildSpatialIndex )
              {
                QgsFeature f;
                f.setFeatureId( mFile->recordId() );
                f.setGeometry( geom );
                mSpatialIndex->insertFeature( f );
                // Feature now has ownership of geometry, so set to null
                // here to avoid deleting twice.
                geom = 0;
              }
            }
            else
            {
              nIncompatibleGeometry++;
              geomValid = false;
            }
          }
          if ( geom ) delete geom;
        }
        else
        {
          geomValid = false;
          nInvalidGeometry++;
          recordInvalidLine( tr( "Invalid WKT at line %1" ) );
        }
      }
    }
    else if ( mGeomRep == GeomAsXy )
    {
      // Get the x and y values, first checking to make sure they
      // aren't null.

      QString sX = mXFieldIndex < parts.size() ? parts[mXFieldIndex] : "";
      QString sY = mYFieldIndex < parts.size() ? parts[mYFieldIndex] : "";
      if ( sX.isEmpty() && sY.isEmpty() )
      {
        geomValid = false;
        nEmptyGeometry++;
      }
      else
      {
        QgsPoint pt;
        bool ok = pointFromXY( sX, sY, pt, mDecimalPoint, mXyDms );

        if ( ok )
        {
          if ( mNumberFeatures > 0 )
          {
            mExtent.combineExtentWith( pt.x(), pt.y() );
          }
          else
          {
            // Extent for the first point is just the first point
            mExtent.set( pt.x(), pt.y(), pt.x(), pt.y() );
            mWkbType = QGis::WKBPoint;
            mGeometryType = QGis::Point;
          }
          mNumberFeatures++;
          if ( buildSpatialIndex && qIsFinite( pt.x() ) && qIsFinite( pt.y() ) )
          {
            QgsFeature f;
            f.setFeatureId( mFile->recordId() );
            f.setGeometry( QgsGeometry::fromPoint( pt ) );
            mSpatialIndex->insertFeature( f );
          }
        }
        else
        {
          geomValid = false;
          nInvalidGeometry++;
          recordInvalidLine( tr( "Invalid X or Y fields at line %1" ) );
        }
      }
    }
    else
    {
      mWkbType = QGis::WKBNoGeometry;
      mNumberFeatures++;
    }

    if ( ! geomValid ) continue;

    if ( buildSubsetIndex ) mSubsetIndex.append( mFile->recordId() );


    // If we are going to use this record, then assess the potential types of each colum

    for ( int i = 0; i < parts.size(); i++ )
    {

      QString &value = parts[i];
      if ( value.isEmpty() )
        continue;

      // try to convert attribute values to integer and double

      while ( couldBeInt.size() <= i )
      {
        isEmpty.append( true );
        couldBeInt.append( false );
        couldBeDouble.append( false );
      }
      if ( isEmpty[i] )
      {
        isEmpty[i] = false;
        couldBeInt[i] = true;
        couldBeDouble[i] = true;
      }
      if ( couldBeInt[i] )
      {
        value.toInt( &couldBeInt[i] );
      }
      if ( couldBeDouble[i] )
      {
        if ( ! mDecimalPoint.isEmpty() )
        {
          value.replace( mDecimalPoint, "." );
        }
        value.toDouble( &couldBeDouble[i] );
      }
    }
  }

  // Now create the attribute fields.  Field types are integer by preference,
  // failing that double, failing that text.

  QStringList fieldNames = mFile->fieldNames();
  mFieldCount = fieldNames.size();
  attributeColumns.clear();
  attributeFields.clear();

  QString csvtMessage;
  QStringList csvtTypes = readCsvtFieldTypes( mFile->fileName(), &csvtMessage );

  for ( int i = 0; i < fieldNames.size(); i++ )
  {
    // Skip over WKT field ... don't want to display in attribute table
    if ( i == mWktFieldIndex ) continue;

    // Add the field index lookup for the column
    attributeColumns.append( i );
    QVariant::Type fieldType = QVariant::String;
    QString typeName = "text";
    if ( i < csvtTypes.size() )
    {
      if ( csvtTypes[i] == "integer" )
      {
        fieldType = QVariant::Int;
        typeName = "integer";
      }
      else if ( csvtTypes[i] == "real" )
      {
        fieldType = QVariant::Double;
        typeName = "double";
      }
    }
    else if ( i < couldBeInt.size() )
    {
      if ( couldBeInt[i] )
      {
        fieldType = QVariant::Int;
        typeName = "integer";
      }
      else if ( couldBeDouble[i] )
      {
        fieldType = QVariant::Double;
        typeName = "double";
      }
    }
    attributeFields.append( QgsField( fieldNames[i], fieldType, typeName ) );
  }


  QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
  QgsDebugMsg( "geometry type is: " + QString::number( mWkbType ) );
  QgsDebugMsg( "feature count is: " + QString::number( mNumberFeatures ) );

  QStringList warnings;
  if ( ! csvtMessage.isEmpty() ) warnings.append( csvtMessage );
  if ( nBadFormatRecords > 0 )
    warnings.append( tr( "%1 records discarded due to invalid format" ).arg( nBadFormatRecords ) );
  if ( nEmptyGeometry > 0 )
    warnings.append( tr( "%1 records discarded due to missing geometry definitions" ).arg( nEmptyGeometry ) );
  if ( nInvalidGeometry > 0 )
    warnings.append( tr( "%1 records discarded due to invalid geometry definitions" ).arg( nInvalidGeometry ) );
  if ( nIncompatibleGeometry > 0 )
    warnings.append( tr( "%1 records discarded due to incompatible geometry types" ).arg( nIncompatibleGeometry ) );

  reportErrors( warnings );

  // Decide whether to use subset ids to index records rather than simple iteration through all
  // If more than 10% of records are being skipped, then use index.  (Not based on any experimentation,
  // could do with some analysis?)

  if ( buildSubsetIndex )
  {
    long recordCount = mFile->recordCount();
    recordCount -= recordCount / SUBSET_ID_THRESHOLD_FACTOR;
    mUseSubsetIndex = mSubsetIndex.size() < recordCount;
    if ( ! mUseSubsetIndex ) mSubsetIndex = QList<quintptr>();
  }

  mUseSpatialIndex = buildSpatialIndex;

  mValid = mGeometryType != QGis::UnknownGeometry;
  mLayerValid = mValid;

  // If it is valid, then watch for changes to the file
  connect( mFile, SIGNAL( fileUpdated() ), this, SLOT( onFileUpdated() ) );


}
コード例 #9
0
QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
    : QgsVectorDataProvider( uri )
    , mLayerValid( false )
    , mValid( false )
    , mFile( 0 )
    , mGeomRep( GeomNone )
    , mFieldCount( 0 )
    , mXFieldIndex( -1 )
    , mYFieldIndex( -1 )
    , mWktFieldIndex( -1 )
    , mWktHasZM( false )
    , mWktHasPrefix( false )
    , mXyDms( false )
    , mSubsetString( "" )
    , mSubsetExpression( 0 )
    , mBuildSubsetIndex( true )
    , mUseSubsetIndex( false )
    , mMaxInvalidLines( 50 )
    , mShowInvalidLines( true )
    , mRescanRequired( false )
    , mCrs()
    , mWkbType( QGis::WKBNoGeometry )
    , mGeometryType( QGis::UnknownGeometry )
    , mBuildSpatialIndex( false )
    , mSpatialIndex( 0 )
{
  mNativeTypes
  << QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), "integer", QVariant::Int, 0, 10 )
  << QgsVectorDataProvider::NativeType( tr( "Decimal number (double)" ), "double precision", QVariant::Double, -1, -1, -1, -1 )
  << QgsVectorDataProvider::NativeType( tr( "Text, unlimited length (text)" ), "text", QVariant::String, -1, -1, -1, -1 )
  ;

 QgsDebugMsg( "Delimited text file uri is " + uri );

  QUrl url = QUrl::fromEncoded( uri.toAscii() );
  mFile = new QgsDelimitedTextFile();
  mFile->setFromUrl( url );

  QString subset;

  if ( url.hasQueryItem( "geomType" ) )
  {
    QString gtype = url.queryItemValue( "geomType" ).toLower();
    if ( gtype == "point" ) mGeometryType = QGis::Point;
    else if ( gtype == "line" ) mGeometryType = QGis::Line;
    else if ( gtype == "polygon" ) mGeometryType = QGis::Polygon;
    else if ( gtype == "none " ) mGeometryType = QGis::NoGeometry;
  }

  if ( mGeometryType != QGis::NoGeometry )
  {
    if ( url.hasQueryItem( "wktField" ) )
    {
      mWktFieldName = url.queryItemValue( "wktField" );
      mGeomRep = GeomAsWkt;
      QgsDebugMsg( "wktField is: " + mWktFieldName );
    }
    else if ( url.hasQueryItem( "xField" ) && url.hasQueryItem( "yField" ) )
    {
      mGeomRep = GeomAsXy;
      mGeometryType = QGis::Point;
      mXFieldName = url.queryItemValue( "xField" );
      mYFieldName = url.queryItemValue( "yField" );
      QgsDebugMsg( "xField is: " + mXFieldName );
      QgsDebugMsg( "yField is: " + mYFieldName );

      if ( url.hasQueryItem( "xyDms" ) )
      {
        mXyDms = ! url.queryItemValue( "xyDms" ).toLower().startsWith( "n" );
      }
    }
    else
    {
      mGeometryType = QGis::NoGeometry;
    }
  }

  if ( url.hasQueryItem( "decimalPoint" ) )
    mDecimalPoint = url.queryItemValue( "decimalPoint" );

  if ( url.hasQueryItem( "crs" ) )
    mCrs.createFromString( url.queryItemValue( "crs" ) );

  if ( url.hasQueryItem( "subsetIndex" ) )
  {
    mBuildSubsetIndex = ! url.queryItemValue( "subsetIndex" ).toLower().startsWith( "n" );
  }

  if ( url.hasQueryItem( "spatialIndex" ) )
  {
    mBuildSpatialIndex = ! url.queryItemValue( "spatialIndex" ).toLower().startsWith( "n" );
  }

  if ( url.hasQueryItem( "subset" ) )
  {
    subset = url.queryItemValue( "subset" );
    QgsDebugMsg( "subset is: " + subset );
  }

  if ( url.hasQueryItem( "quiet" ) ) mShowInvalidLines = false;

  // Do an initial scan of the file to determine field names, types,
  // geometry type (for Wkt), extents, etc.  Parameter value subset.isEmpty()
  // avoid redundant building indexes if we will be building a subset string,
  // in which case indexes will be rebuilt.

  scanFile( subset.isEmpty() );

  if ( ! subset.isEmpty() )
  {
    setSubsetString( subset );
  }
}
コード例 #10
0
int main( int argc, char * argv[] )
{
#ifndef _MSC_VER
  qInstallMsgHandler( dummyMessageHandler );
#endif

  QgsApplication qgsapp( argc, argv, getenv( "DISPLAY" ) );

  //Default prefix path may be altered by environment variable
  char* prefixPath = getenv( "QGIS_PREFIX_PATH" );
  if ( prefixPath )
  {
    QgsApplication::setPrefixPath( prefixPath, TRUE );
  }
#if !defined(Q_OS_WIN)
  else
  {
    // init QGIS's paths - true means that all path will be inited from prefix
    QgsApplication::setPrefixPath( CMAKE_INSTALL_PREFIX, TRUE );
  }
#endif

  // Instantiate the plugin directory so that providers are loaded
  QgsProviderRegistry::instance( QgsApplication::pluginPath() );
  QgsDebugMsg( "Prefix  PATH: " + QgsApplication::prefixPath() );
  QgsDebugMsg( "Plugin  PATH: " + QgsApplication::pluginPath() );
  QgsDebugMsg( "PkgData PATH: " + QgsApplication::pkgDataPath() );
  QgsDebugMsg( "User DB PATH: " + QgsApplication::qgisUserDbFilePath() );

  QgsDebugMsg( qgsapp.applicationDirPath() + "/qgis_wms_server.log" );

  //create config cache and search for config files in the current directory.
  //These configurations are used if no mapfile parameter is present in the request
  QString defaultConfigFilePath;
  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
  if ( projectFileInfo.exists() )
  {
    defaultConfigFilePath = projectFileInfo.absoluteFilePath();
  }
  else
  {
    QFileInfo adminSLDFileInfo = defaultAdminSLD();
    if ( adminSLDFileInfo.exists() )
    {
      defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
    }
  }

  //create cache for capabilities XML
  QgsCapabilitiesCache capabilitiesCache;

  //creating QgsMapRenderer is expensive (access to srs.db), so we do it here before the fcgi loop
  QgsMapRenderer* theMapRenderer = new QgsMapRenderer();

  while ( fcgi_accept() >= 0 )
  {
    printRequestInfos(); //print request infos if in debug mode

    //use QgsGetRequestHandler in case of HTTP GET and QgsSOAPRequestHandler in case of HTTP POST
    QgsRequestHandler* theRequestHandler = 0;
    char* requestMethod = getenv( "REQUEST_METHOD" );
    if ( requestMethod != NULL )
    {
      if ( strcmp( requestMethod, "POST" ) == 0 )
      {
        //QgsDebugMsg( "Creating QgsSOAPRequestHandler" );
        //theRequestHandler = new QgsSOAPRequestHandler();
        theRequestHandler = new QgsPostRequestHandler();
      }
      else
      {
        QgsDebugMsg( "Creating QgsGetRequestHandler" );
        theRequestHandler = new QgsGetRequestHandler();
      }
    }
    else
    {
      QgsDebugMsg( "Creating QgsGetRequestHandler" );
      theRequestHandler = new QgsGetRequestHandler();
    }

    QMap<QString, QString> parameterMap;

    try
    {
      parameterMap = theRequestHandler->parseInput();
    }
    catch ( QgsMapServiceException& e )
    {
      QgsDebugMsg( "An exception was thrown during input parsing" );
      theRequestHandler->sendServiceException( e );
      continue;
    }

    QMap<QString, QString>::const_iterator paramIt;

    //set admin config file to wms server object
    QString configFilePath( defaultConfigFilePath );

    paramIt = parameterMap.find( "MAP" );
    if ( paramIt == parameterMap.constEnd() )
    {
      QgsDebugMsg( QString( "Using default configuration file path: %1" ).arg( defaultConfigFilePath ) );
    }
    else
    {
      configFilePath = paramIt.value();
    }

    QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
    if ( !adminConfigParser )
    {
      QgsDebugMsg( "parse error on config file " + configFilePath );
      theRequestHandler->sendServiceException( QgsMapServiceException( "", "Configuration file problem : perhaps you left off the .qgs extension?" ) );
      continue;
    }

    //sld parser might need information about request parameters
    adminConfigParser->setParameterMap( parameterMap );

    //request to WMS?
    QString serviceString;
    paramIt = parameterMap.find( "SERVICE" );
    if ( paramIt == parameterMap.constEnd() )
    {
#ifndef QGISDEBUG
      serviceString = parameterMap.value( "SERVICE", "WMS" );
#else
      QgsDebugMsg( "unable to find 'SERVICE' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
      delete theRequestHandler;
      continue;
#endif
    }
    else
    {
      serviceString = paramIt.value();
    }

    QgsWMSServer* theServer = 0;
    if ( serviceString == "WFS" )
    {
      delete theServer;
      QgsWFSServer* theServer = 0;
      try
      {
        theServer = new QgsWFSServer( parameterMap );
      }
      catch ( QgsMapServiceException e ) //admin.sld may be invalid
      {
        theRequestHandler->sendServiceException( e );
        continue;
      }

      theServer->setAdminConfigParser( adminConfigParser );


      //request type
      QString request = parameterMap.value( "REQUEST" );
      if ( request.isEmpty() )
      {
        //do some error handling
        QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
        theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( request == "GetCapabilities" )
      {
        QDomDocument capabilitiesDocument;
        try
        {
          capabilitiesDocument = theServer->getCapabilities();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request == "DescribeFeatureType" )
      {
        QDomDocument describeDocument;
        try
        {
          describeDocument = theServer->describeFeatureType();
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        QgsDebugMsg( "sending GetCapabilities response" );
        theRequestHandler->sendGetCapabilitiesResponse( describeDocument );
        delete theRequestHandler;
        delete theServer;
        continue;
      }
      else if ( request == "GetFeature" )
      {
        //output format for GetFeature
        QString outputFormat = parameterMap.value( "OUTPUTFORMAT" );
        try
        {
          if ( theServer->getFeature( *theRequestHandler, outputFormat ) != 0 )
          {
            delete theRequestHandler;
            delete theServer;
            continue;
          }
          else
          {
            delete theRequestHandler;
            delete theServer;
            continue;
          }
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }

      return 0;
    }

    try
    {
      theServer = new QgsWMSServer( parameterMap, theMapRenderer );
    }
    catch ( QgsMapServiceException e ) //admin.sld may be invalid
    {
      theRequestHandler->sendServiceException( e );
      continue;
    }

    theServer->setAdminConfigParser( adminConfigParser );


    //request type
    QString request = parameterMap.value( "REQUEST" );
    if ( request.isEmpty() )
    {
      //do some error handling
      QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
      theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) );
      delete theRequestHandler;
      delete theServer;
      continue;
    }

    QString version = parameterMap.value( "VERSION", "1.3.0" );

    if ( request == "GetCapabilities" )
    {
      const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
      if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
      {
        QgsDebugMsg( "Capabilities document not found in cache" );
        QDomDocument doc;
        try
        {
          doc = theServer->getCapabilities( version );
        }
        catch ( QgsMapServiceException& ex )
        {
          theRequestHandler->sendServiceException( ex );
          delete theRequestHandler;
          delete theServer;
          continue;
        }
        capabilitiesCache.insertCapabilitiesDocument( configFilePath, version, &doc );
        capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
      }
      else
      {
        QgsDebugMsg( "Found capabilities document in cache" );
      }

      if ( capabilitiesDocument )
      {
        theRequestHandler->sendGetCapabilitiesResponse( *capabilitiesDocument );
      }
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request == "GetMap" )
    {
      QImage* result = 0;
      try
      {
        result = theServer->getMap();
      }
      catch ( QgsMapServiceException& ex )
      {
        QgsDebugMsg( "Caught exception during GetMap request" );
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetMap response" );
        theRequestHandler->sendGetMapResponse( serviceString, result );
        QgsDebugMsg( "Response sent" );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request == "GetFeatureInfo" )
    {
      QDomDocument featureInfoDoc;
      try
      {
        if ( theServer->getFeatureInfo( featureInfoDoc, version ) != 0 )
        {
          delete theRequestHandler;
          delete theServer;
          continue;
        }
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
        delete theRequestHandler;
        delete theServer;
        continue;
      }

      //info format for GetFeatureInfo
      theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, parameterMap.value( "INFO_FORMAT" ) );
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request == "GetStyles" || request == "GetStyle" ) // GetStyle for compatibility with earlier QGIS versions
    {
      try
      {
        QDomDocument doc = theServer->getStyle();
        theRequestHandler->sendGetStyleResponse( doc );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else if ( request == "GetLegendGraphic" || request == "GetLegendGraphics" ) // GetLegendGraphics for compatibility with earlier QGIS versions
    {
      QImage* result = 0;
      try
      {
        result = theServer->getLegendGraphics();
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( result )
      {
        QgsDebugMsg( "Sending GetLegendGraphic response" );
        //sending is the same for GetMap and GetLegendGraphic
        theRequestHandler->sendGetMapResponse( serviceString, result );
      }
      else
      {
        //do some error handling
        QgsDebugMsg( "result image is 0" );
      }
      delete result;
      delete theRequestHandler;
      delete theServer;
      continue;

    }
    else if ( request == "GetPrint" )
    {
      QByteArray* printOutput = 0;
      try
      {
        printOutput = theServer->getPrint( theRequestHandler->format() );
      }
      catch ( QgsMapServiceException& ex )
      {
        theRequestHandler->sendServiceException( ex );
      }

      if ( printOutput )
      {
        theRequestHandler->sendGetPrintResponse( printOutput );
      }
      delete printOutput;
      delete theRequestHandler;
      delete theServer;
      continue;
    }
    else//unknown request
    {
      QgsMapServiceException e( "OperationNotSupported", "Operation " + request + " not supported" );
      theRequestHandler->sendServiceException( e );
      delete theRequestHandler;
      delete theServer;
    }
  }

  delete theMapRenderer;
  QgsDebugMsg( "************* all done ***************" );
  return 0;
}
コード例 #11
0
QStringList QgsDelimitedTextProvider::readCsvtFieldTypes( QString filename, QString *message )
{
  // Look for a file with the same name as the data file, but an extra 't' or 'T' at the end
  QStringList types;
  QFileInfo csvtInfo( filename + 't' );
  if ( ! csvtInfo.exists() ) csvtInfo.setFile( filename + 'T' );
  if ( ! csvtInfo.exists() ) return types;
  QFile csvtFile( csvtInfo.filePath() );
  if ( ! csvtFile.open( QIODevice::ReadOnly ) ) return types;


  // If anything goes wrong here, just ignore it, as the file
  // is not valid, so just ignore any exceptions.

  // For it to be valid, there must be just one non blank line at the beginning of the
  // file.

  QString strTypeList;
  try
  {
    QTextStream csvtStream( &csvtFile );
    strTypeList = csvtStream.readLine();
    if ( strTypeList.isEmpty() ) return types;
    QString extra = csvtStream.readLine();
    while ( ! extra.isNull() )
    {
      if ( ! extra.isEmpty() ) return types;
      extra = csvtStream.readLine();
    }
  }
  catch ( ... )
  {
    return types;
  }
  csvtFile.close();

  // Is the type string valid?
  // This is a slightly generous regular expression in that it allows spaces and unquoted field types
  // not allowed in OGR CSVT files.  Also doesn't care if int and string fields have

  strTypeList = strTypeList.toLower();
  QRegExp reTypeList( "^(?:\\s*(\\\"?)(?:integer|real|string|date|datetime|time)(?:\\(\\d+(?:\\.\\d+)?\\))?\\1\\s*(?:,|$))+" );
  if ( ! reTypeList.exactMatch( strTypeList ) )
  {
    // Looks like this was supposed to be a CSVT file, so report bad formatted string
    if ( message ) { *message = tr( "File type string in %1 is not correctly formatted" ).arg( csvtInfo.fileName() ); }
    return types;
  }

  // All good, so pull out the types from the string.  Currently only returning integer, real, and string types

  QgsDebugMsg( QString( "Reading field types from %1" ).arg( csvtInfo.fileName() ) );
  QgsDebugMsg( QString( "Field type string: %1" ).arg( strTypeList ) );

  int pos = 0;
  QRegExp reType( "(integer|real|string|date|datetime|time)" );

  while (( pos = reType.indexIn( strTypeList, pos ) ) != -1 )
  {
    QgsDebugMsg( QString( "Found type: %1" ).arg( reType.cap( 1 ) ) );
    types << reType.cap( 1 );
    pos += reType.matchedLength();
  }

  if ( message )
  {
    // Would be a useful info message, but don't want dialog to pop up every time...
    // *message=tr("Reading field types from %1").arg(csvtInfo.fileName());
  }


  return types;


}
コード例 #12
0
bool QgsSLConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
{
  if ( !QgsMimeDataUtils::isUriList( data ) )
    return false;

  // TODO: probably should show a GUI with settings etc

  QgsDataSourceURI destUri;
  destUri.setDatabase( mDbPath );

  qApp->setOverrideCursor( Qt::WaitCursor );

  QProgressDialog *progress = new QProgressDialog( tr( "Copying features..." ), tr( "Abort" ), 0, 0, nullptr );
  progress->setWindowTitle( tr( "Import layer" ) );
  progress->setWindowModality( Qt::WindowModal );
  progress->show();

  QStringList importResults;
  bool hasError = false;
  bool cancelled = false;

  QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
  Q_FOREACH ( const QgsMimeDataUtils::Uri& u, lst )
  {
    if ( u.layerType != "vector" )
    {
      importResults.append( tr( "%1: Not a vector layer!" ).arg( u.name ) );
      hasError = true; // only vectors can be imported
      continue;
    }

    // open the source layer
    QgsVectorLayer* srcLayer = new QgsVectorLayer( u.uri, u.name, u.providerKey );

    if ( srcLayer->isValid() )
    {
      destUri.setDataSource( QString(), u.name, srcLayer->geometryType() != QGis::NoGeometry ? "geom" : QString() );
      QgsDebugMsg( "URI " + destUri.uri() );
      QgsVectorLayerImport::ImportError err;
      QString importError;
      err = QgsVectorLayerImport::importLayer( srcLayer, destUri.uri(), "spatialite", &srcLayer->crs(), false, &importError, false, nullptr, progress );
      if ( err == QgsVectorLayerImport::NoError )
        importResults.append( tr( "%1: OK!" ).arg( u.name ) );
      else if ( err == QgsVectorLayerImport::ErrUserCancelled )
        cancelled = true;
      else
      {
        importResults.append( QString( "%1: %2" ).arg( u.name, importError ) );
        hasError = true;
      }
    }
    else
    {
      importResults.append( tr( "%1: OK!" ).arg( u.name ) );
      hasError = true;
    }

    delete srcLayer;
  }

  delete progress;

  qApp->restoreOverrideCursor();

  if ( cancelled )
  {
    QMessageBox::information( nullptr, tr( "Import to SpatiaLite database" ), tr( "Import cancelled." ) );
    refresh();
  }
  else if ( hasError )
  {
    QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
    output->setTitle( tr( "Import to SpatiaLite database" ) );
    output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ), QgsMessageOutput::MessageText );
    output->showMessage();
  }
  else
  {
    QMessageBox::information( nullptr, tr( "Import to SpatiaLite database" ), tr( "Import was successful." ) );
    refresh();
  }

  return true;
}
コード例 #13
0
void QgsVectorLayerEditBuffer::undoIndexChanged( int index )
{
  QgsDebugMsg( QString( "undo index changed %1" ).arg( index ) );
  Q_UNUSED( index );
  emit layerModified();
}
コード例 #14
0
void QgsCodeEditorPython::setSciLexerPython()
{
  // current line
  setCaretWidth( 2 );

  setEdgeMode( QsciScintilla::EdgeLine );
  setEdgeColumn( 80 );
  setEdgeColor( QColor( "#FF0000" ) );

  setWhitespaceVisibility( QsciScintilla::WsVisibleAfterIndent );

  QFont font = getMonospaceFont();

  QsciLexerPython* pyLexer = new QsciLexerPython( this );
  pyLexer->setDefaultFont( font );
  pyLexer->setFont( font, 1 ); // comment
  pyLexer->setFont( font, 3 ); // singlequotes
  pyLexer->setFont( font, 4 ); // doublequotes
  pyLexer->setFont( font, 6 ); // triplequotes
  pyLexer->setColor( Qt::red, 1 ); // comment color
  pyLexer->setColor( Qt::darkGreen, 5 ); // keyword color
  pyLexer->setColor( Qt::darkBlue, 15 ); // decorator color

  QsciAPIs* apis = new QsciAPIs( pyLexer );

  // check if the file is a prepared apis file.
  //QString mPapFileName = QFileInfo( mAPISFilesList[0] ).fileName();
  //QString isPapFile = mPapFileName.right( 3 );
  //QgsDebugMsg( QString( "file extension: %1" ).arg( isPapFile ) );

  if ( mAPISFilesList.isEmpty() )
  {
    mPapFile = QgsApplication::pkgDataPath() + "/python/qsci_apis/pyqgis.pap";
    apis->loadPrepared( mPapFile );
  }
  else if ( mAPISFilesList.length() == 1 && mAPISFilesList[0].right( 3 ) == "pap" )
  {
    if ( !QFileInfo( mAPISFilesList[0] ).exists() )
    {
      QgsDebugMsg( QString( "The apis file %1 not found" ).arg( mAPISFilesList[0] ) );
      return;
    }
    mPapFile = mAPISFilesList[0];
    apis->loadPrepared( mPapFile );
  }
  else
  {
    for ( int i = 0; i < mAPISFilesList.size(); i++ )
    {
      if ( !QFileInfo( mAPISFilesList[i] ).exists() )
      {
        QgsDebugMsg( QString( "The apis file %1 was not found" ).arg( mAPISFilesList[i] ) );
        return;
      }
      else
      {
        apis->load( mAPISFilesList[i] );
      }
    }
    apis->prepare();
    pyLexer->setAPIs( apis );
  }
  setLexer( pyLexer );

  setMarginVisible( true );
  setFoldingVisible( true );
}
コード例 #15
0
void QgsGrassFeatureIterator::resetSelection( bool sel )
{
  QgsDebugMsg( "entered." );
  memset( mSelection, ( int ) sel, mSelectionSize );
  mNextCidx = 0;
}
コード例 #16
0
void QgsDelimitedTextProvider::rescanFile()
{
  mRescanRequired = false;
  resetIndexes();

  bool buildSpatialIndex = mSpatialIndex != 0;
  bool buildSubsetIndex = mBuildSubsetIndex && ( mSubsetExpression || mGeomRep != GeomNone );

  // In case file has been rewritten check that it is still valid

  mValid = mLayerValid && mFile->isValid();
  if ( ! mValid ) return;

  // Open the file and get number of rows, etc. We assume that the
  // file has a header row and process accordingly. Caller should make
  // sure that the delimited file is properly formed.

  QStringList messages;

  if ( mGeomRep == GeomAsWkt )
  {
    mWktFieldIndex = mFile->fieldIndex( mWktFieldName );
    if ( mWktFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "Wkt" ).arg( mWktFieldName ) );
    }
  }
  else if ( mGeomRep == GeomAsXy )
  {
    mXFieldIndex = mFile->fieldIndex( mXFieldName );
    mYFieldIndex = mFile->fieldIndex( mYFieldName );
    if ( mXFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "X" ).arg( mWktFieldName ) );
    }
    if ( mYFieldIndex < 0 )
    {
      messages.append( tr( "%0 field %1 is not defined in delimited text file" ).arg( "Y" ).arg( mWktFieldName ) );
    }
  }
  if ( messages.size() > 0 )
  {
    reportErrors( messages, false );
    QgsDebugMsg( "Delimited text source invalid on rescan - missing geometry fields" );
    mValid = false;
    return;
  }

  // Reset the field columns

  for ( int i = 0; i < attributeFields.size(); i++ )
  {
    attributeColumns[i] = mFile->fieldIndex( attributeFields[i].name() );
  }

  // Scan through the features in the file

  mSubsetIndex.clear();
  mUseSubsetIndex = false;
  QgsFeatureIterator fi = getFeatures( QgsFeatureRequest() );
  mNumberFeatures = 0;
  mExtent = QgsRectangle();
  QgsFeature f;
  while ( fi.nextFeature( f ) )
  {
    if ( mGeometryType != QGis::NoGeometry )
    {
      if ( mNumberFeatures == 0 )
      {
        mExtent = f.geometry()->boundingBox();
      }
      else
      {
        QgsRectangle bbox( f.geometry()->boundingBox() );
        mExtent.combineExtentWith( &bbox );
      }
      if ( buildSpatialIndex ) mSpatialIndex->insertFeature( f );
    }
    if ( buildSubsetIndex ) mSubsetIndex.append(( quintptr ) f.id() );
    mNumberFeatures++;
  }
  if ( buildSubsetIndex )
  {
    long recordCount = mFile->recordCount();
    recordCount -= recordCount / SUBSET_ID_THRESHOLD_FACTOR;
    mUseSubsetIndex = recordCount < mSubsetIndex.size();
    if ( ! mUseSubsetIndex ) mSubsetIndex.clear();
  }

  mUseSpatialIndex = buildSpatialIndex;
}
コード例 #17
0
void QgsGrassFeatureIterator::setFeatureGeometry( QgsFeature& feature, int id, int type )
{
  unsigned char *wkb;
  int wkbsize;

  // TODO int may be 64 bits (memcpy)
  if ( type & ( GV_POINTS | GV_LINES | GV_FACE ) ) /* points or lines */
  {
    Vect_read_line( P->mMap, mPoints, mCats, id );
    int npoints = mPoints->n_points;

    if ( type & GV_POINTS )
    {
      wkbsize = 1 + 4 + 2 * 8;
    }
    else if ( type & GV_LINES )
    {
      wkbsize = 1 + 4 + 4 + npoints * 2 * 8;
    }
    else // GV_FACE
    {
      wkbsize = 1 + 4 + 4 + 4 + npoints * 2 * 8;
    }
    wkb = new unsigned char[wkbsize];
    unsigned char *wkbp = wkb;
    wkbp[0] = ( unsigned char ) QgsApplication::endian();
    wkbp += 1;

    /* WKB type */
    memcpy( wkbp, &P->mQgisType, 4 );
    wkbp += 4;

    /* Number of rings */
    if ( type & GV_FACE )
    {
      int nrings = 1;
      memcpy( wkbp, &nrings, 4 );
      wkbp += 4;
    }

    /* number of points */
    if ( type & ( GV_LINES | GV_FACE ) )
    {
      QgsDebugMsg( QString( "set npoints = %1" ).arg( npoints ) );
      memcpy( wkbp, &npoints, 4 );
      wkbp += 4;
    }

    for ( int i = 0; i < npoints; i++ )
    {
      memcpy( wkbp, &( mPoints->x[i] ), 8 );
      memcpy( wkbp + 8, &( mPoints->y[i] ), 8 );
      wkbp += 16;
    }
  }
  else   // GV_AREA
  {
    Vect_get_area_points( P->mMap, id, mPoints );
    int npoints = mPoints->n_points;

    wkbsize = 1 + 4 + 4 + 4 + npoints * 2 * 8; // size without islands
    wkb = new unsigned char[wkbsize];
    wkb[0] = ( unsigned char ) QgsApplication::endian();
    int offset = 1;

    /* WKB type */
    memcpy( wkb + offset, &P->mQgisType, 4 );
    offset += 4;

    /* Number of rings */
    int nisles = Vect_get_area_num_isles( P->mMap, id );
    int nrings = 1 + nisles;
    memcpy( wkb + offset, &nrings, 4 );
    offset += 4;

    /* Outer ring */
    memcpy( wkb + offset, &npoints, 4 );
    offset += 4;
    for ( int i = 0; i < npoints; i++ )
    {
      memcpy( wkb + offset, &( mPoints->x[i] ), 8 );
      memcpy( wkb + offset + 8, &( mPoints->y[i] ), 8 );
      offset += 16;
    }

    /* Isles */
    for ( int i = 0; i < nisles; i++ )
    {
      Vect_get_isle_points( P->mMap, Vect_get_area_isle( P->mMap, id, i ), mPoints );
      npoints = mPoints->n_points;

      // add space
      wkbsize += 4 + npoints * 2 * 8;
      wkb = ( unsigned char * ) realloc( wkb, wkbsize );

      memcpy( wkb + offset, &npoints, 4 );
      offset += 4;
      for ( int i = 0; i < npoints; i++ )
      {
        memcpy( wkb + offset, &( mPoints->x[i] ), 8 );
        memcpy( wkb + offset + 8, &( mPoints->y[i] ), 8 );
        offset += 16;
      }
    }
  }

  feature.setGeometryAndOwnership( wkb, wkbsize );
}
コード例 #18
0
ファイル: qgscustomization.cpp プロジェクト: dionhouston/QGIS
bool QgsCustomizationDialog::switchWidget( QWidget *widget, QMouseEvent *e )
{
  Q_UNUSED( e );
  QgsDebugMsg( "Entered" );
  if ( !actionCatch->isChecked() )
    return false;
  QString path = widgetPath( widget );
  QgsDebugMsg( "path = " + path );

  if ( path.startsWith( "/QgsCustomizationDialogBase" ) )
  {
    // do not allow modification of this dialog
    return false;
  }
  else if ( path.startsWith( "/QgisApp" ) )
  {
    // changes to main window
    // (work with toolbars, tool buttons)
    if ( widget->inherits( "QToolBar" ) )
    {
      path = "/Toolbars/" + widget->objectName();
    }
    else if ( widget->inherits( "QToolButton" ) )
    {
      QToolButton* toolbutton = qobject_cast<QToolButton*>( widget );
      QAction* action = toolbutton->defaultAction();
      if ( !action )
        return false;
      QString toolbarName = widget->parent()->objectName();
      QString actionName = action->objectName();
      path = "/Toolbars/" + toolbarName + "/" + actionName;
    }
    else
    {
      // unsupported widget in main window
      return false;
    }
  }
  else
  {
    // ordinary widget in a dialog
    path = "/Widgets" + path;
  }

  QgsDebugMsg( "path final = " + path );
  bool on = !itemChecked( path );

  QgsDebugMsg( QString( "on = %1" ).arg( on ) );

  setItemChecked( path, on );
  QTreeWidgetItem *myItem = item( path );
  if ( myItem )
  {
    treeWidget->scrollToItem( myItem, QAbstractItemView::PositionAtCenter );
    treeWidget->clearSelection();
    myItem->setSelected( true );

    QString style;
    if ( !on )
    {
      style = "background-color: #FFCCCC;";
    }
    widget->setStyleSheet( style );
  }

  return true;
}
コード例 #19
0
ファイル: qgslabeldialog.cpp プロジェクト: AaronGaim/QGIS
QgsLabelDialog::~QgsLabelDialog()
{
  QgsDebugMsg( "entering." );
}
コード例 #20
0
ファイル: qgscustomization.cpp プロジェクト: dionhouston/QGIS
QgsCustomizationDialog::QgsCustomizationDialog( QWidget *parent, QSettings* settings )
    : QMainWindow( parent, Qt::WindowSystemMenuHint )  // Modeless dialog with close button only
#else
QgsCustomizationDialog::QgsCustomizationDialog( QWidget *parent, QSettings* settings )
    : QMainWindow( parent )
#endif
{
  mSettings = settings;
  setupUi( this );

  QSettings appSettings;
  restoreGeometry( appSettings.value( "/Windows/Customization/geometry" ).toByteArray() );

  init();
  QStringList myHeaders;
  myHeaders << tr( "Object name" ) << tr( "Label" ) << tr( "Description" );
  treeWidget->setHeaderLabels( myHeaders );

  mLastDirSettingsName  = QString( "/UI/lastCustomizationDir" );
  //treeWidget->hideColumn(0)
  connect( buttonBox->button( QDialogButtonBox::Ok ), SIGNAL( clicked() ), this, SLOT( ok() ) );
  connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
  connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL( clicked() ), this, SLOT( cancel() ) );
  connect( buttonBox->button( QDialogButtonBox::Reset ), SIGNAL( clicked() ), this, SLOT( reset() ) );

}

QgsCustomizationDialog::~QgsCustomizationDialog()
{
  QSettings settings;
  settings.setValue( "/Windows/Customization/geometry", saveGeometry() );
}

QTreeWidgetItem * QgsCustomizationDialog::item( QString thePath, QTreeWidgetItem *theItem )
{
  QString path = thePath;
  if ( path.startsWith( "/" ) )
    path = path.mid( 1 ); // remove '/'
  QStringList names = path.split( '/' );
  path = QStringList( names.mid( 1 ) ).join( "/" );

  if ( ! theItem )
  {
    for ( int i = 0; i < treeWidget->topLevelItemCount(); ++i )
    {
      QTreeWidgetItem *myItem = treeWidget->topLevelItem( i );
      QString objectName = myItem->text( 0 );
      if ( objectName == names[0] )
      {
        return item( path, myItem );
      }
    }
  }
  else
  {
    for ( int i = 0; i < theItem->childCount(); ++i )
    {
      QTreeWidgetItem *myItem = theItem->child( i );
      QString objectName = myItem->text( 0 );
      if ( objectName == names[0] )
      {
        if ( names.size() == 1 )
        {
          return myItem;
        }
        else
        {
          return item( path, myItem );
        }
      }
    }
  }
  QgsDebugMsg( "not found" );
  return 0;
}
コード例 #21
0
ファイル: qgslabeldialog.cpp プロジェクト: AaronGaim/QGIS
void QgsLabelDialog::init( )
{
  QgsDebugMsg( "entering." );

  QgsLabelAttributes * myLabelAttributes = mLabel->labelAttributes();
  //populate a string list with all the field names which will be used to set up the
  //data bound combos
  const QgsFields& myFields = mLabel->fields();
  QStringList myFieldStringList;
  myFieldStringList.append( "" );
  for ( int i = 0; i < myFields.count(); ++i )
  {
    myFieldStringList.append( myFields[i].name() );
  }
  //
  //now set all the combos that need field lists using the string list
  //
  cboLabelField->clear();
  cboLabelField->addItems( myFieldStringList );
  cboLabelField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Text ), myFieldStringList ) );

  cboFontField->clear();
  cboFontField->addItems( myFieldStringList );
  cboFontField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Family ), myFieldStringList ) );

  cboBoldField->clear();
  cboBoldField->addItems( myFieldStringList );
  cboBoldField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Bold ), myFieldStringList ) );


  cboItalicField->clear();
  cboItalicField->addItems( myFieldStringList );
  cboItalicField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Italic ), myFieldStringList ) );

  cboUnderlineField->clear();
  cboUnderlineField->addItems( myFieldStringList );
  cboUnderlineField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Underline ), myFieldStringList ) );

  cboStrikeOutField->clear();
  cboStrikeOutField->addItems( myFieldStringList );
  cboStrikeOutField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::StrikeOut ), myFieldStringList ) );

  cboFontSizeField->clear();
  cboFontSizeField->addItems( myFieldStringList );
  cboFontSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Size ), myFieldStringList ) );

  cboFontSizeTypeField->clear();
  cboFontSizeTypeField->addItems( myFieldStringList );
  cboFontSizeTypeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::SizeType ), myFieldStringList ) );

#if 0
  cboFontTransparencyField->clear();
  cboFontTransparencyField->addItems( myFieldStringList );
  cboFontTransparencyField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::FontTransparency ), myFieldStringList ) );
#endif

  cboFontColorField->clear();
  cboFontColorField->addItems( myFieldStringList );
  cboFontColorField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Color ), myFieldStringList ) );


  cboBufferSizeField->clear();
  cboBufferSizeField->addItems( myFieldStringList );
  cboBufferSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::BufferSize ), myFieldStringList ) );

  cboBufferTransparencyField->clear();
  cboBufferTransparencyField->addItems( myFieldStringList );
  //cboBufferTransparencyField->setCurrentIndex(itemNoForField(mLabel->labelField(QgsLabel::BufferTransparency),myFieldStringList));

  cboXCoordinateField->clear();
  cboXCoordinateField->addItems( myFieldStringList );
  cboXCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XCoordinate ), myFieldStringList ) );

  cboYCoordinateField->clear();
  cboYCoordinateField->addItems( myFieldStringList );
  cboYCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YCoordinate ), myFieldStringList ) );

  cboXOffsetField->clear();
  cboXOffsetField->addItems( myFieldStringList );
  cboXOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XOffset ), myFieldStringList ) );

  cboYOffsetField->clear();
  cboYOffsetField->addItems( myFieldStringList );
  cboYOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YOffset ), myFieldStringList ) );

  cboAlignmentField->clear();
  cboAlignmentField->addItems( myFieldStringList );
  cboAlignmentField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Alignment ), myFieldStringList ) );

  cboAngleField->clear();
  cboAngleField->addItems( myFieldStringList );
  cboAngleField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Angle ), myFieldStringList ) );

  // set up the scale based layer visibility stuff....
  chkUseScaleDependentRendering->setChecked( mLabel->scaleBasedVisibility() );
  leMinimumScale->setText( QString::number( mLabel->minScale(), 'f' ) );
  leMinimumScale->setValidator( new QDoubleValidator( 0, std::numeric_limits<float>::max(), 1000, this ) );
  leMaximumScale->setText( QString::number( mLabel->maxScale(), 'f' ) );
  leMaximumScale->setValidator( new QDoubleValidator( 0, std::numeric_limits<float>::max(), 1000, this ) );

  //
  //set the non-databound fields up now
  //
  leDefaultLabel->setText( myLabelAttributes->text() );
  mFont.setFamily( myLabelAttributes->family() );
  if ( myLabelAttributes->sizeIsSet() )
  {
    mFont.setPointSizeF( myLabelAttributes->size() );

    int myTypeInt = myLabelAttributes->sizeType();
    cboFontSizeUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
  }
  else //defaults for when no size has been set
  {
    mFont.setPointSizeF( myLabelAttributes->size() );
    cboFontSizeUnits->setCurrentIndex( 0 );
  }

  spinFontSize->setValue( myLabelAttributes->size() );

  if ( myLabelAttributes->boldIsSet() )
  {
    mFont.setBold( myLabelAttributes->bold() );
  }
  else
  {
    mFont.setBold( false );
  }
  if ( myLabelAttributes->italicIsSet() )
  {
    mFont.setItalic( myLabelAttributes->italic() );
  }
  else
  {
    mFont.setItalic( false );
  }
  if ( myLabelAttributes->underlineIsSet() )
  {
    mFont.setUnderline( myLabelAttributes->underline() );
  }
  else
  {
    mFont.setUnderline( false );
  }
  if ( myLabelAttributes->strikeOutIsSet() )
  {
    mFont.setStrikeOut( myLabelAttributes->strikeOut() );
  }
  else
  {
    mFont.setStrikeOut( false );
  }

  mFontColor = myLabelAttributes->color();

  if ( myLabelAttributes->offsetIsSet() )
  {
    int myTypeInt = myLabelAttributes->offsetType();
    cboOffsetUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
    spinXOffset->setValue( myLabelAttributes->xOffset() );
    spinYOffset->setValue( myLabelAttributes->yOffset() );
  }
  else //defaults for when no offset is defined
  {
    cboOffsetUnits->setCurrentIndex( 0 );
    spinXOffset->setValue( 0 );
    spinYOffset->setValue( 0 );
  }
  spinAngle->setRange( -1, 360 );
  spinAngle->setSpecialValueText( tr( "Auto" ) );
  if ( myLabelAttributes->angleIsAuto() )
  {
    spinAngle->setValue( -1 );
  }
  else
  {
    spinAngle->setValue( static_cast<int>( myLabelAttributes->angle() ) );
  }

  //the values here may seem a bit counterintuitive - basically everything
  //is the reverse of the way you think it should be...
  //TODO investigate in QgsLabel why this needs to be the case
  //TODO add support for corners (e.g. bottom right) to xml serialiser

  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignBottom ) ) radioAboveLeft->setChecked( true )   ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignTop ) ) radioBelowLeft->setChecked( true )   ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignBottom ) ) radioAboveRight->setChecked( true )  ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignTop ) ) radioBelowRight->setChecked( true )  ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignVCenter ) ) radioLeft->setChecked( true )        ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignVCenter ) ) radioRight->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignBottom | Qt::AlignHCenter ) ) radioAbove->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignTop   | Qt::AlignHCenter ) ) radioBelow->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == Qt::AlignCenter ) radioOver->setChecked( true )        ;

  mBufferColor = myLabelAttributes->bufferColor();
  //note that it could be that buffer properties are set, but the bufer is disabled
  if ( myLabelAttributes->bufferSizeIsSet() )
  {
    int myTypeInt = myLabelAttributes->bufferSizeType();
    cboBufferSizeUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
    spinBufferSize->setValue( myLabelAttributes->bufferSize() );
  }
  else //defaults for when no offset is defined
  {
    cboBufferSizeUnits->setCurrentIndex( 0 );
    spinBufferSize->setValue( 1 );
  }
  //set the state of the multiline enabled checkbox
  chkUseMultiline->setChecked( myLabelAttributes->multilineEnabled() );
  //set the state of the selected features only checkbox
  chkSelectedOnly->setChecked( myLabelAttributes->selectedOnly() );
  //set the state of the buffer enabled checkbox
  chkUseBuffer->setChecked( myLabelAttributes->bufferEnabled() );

  //NOTE: do we need this line too? TS
  spinBufferSize->setValue( myLabelAttributes->bufferSize() );
}
コード例 #22
0
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid )
{
  QString radius, parameter2;
  //
  // SQLITE3 stuff - get parameters for selected ellipsoid
  //
  sqlite3      *myDatabase;
  const char   *myTail;
  sqlite3_stmt *myPreparedStatement;
  int           myResult;

  // Shortcut if ellipsoid is none.
  if ( ellipsoid == GEO_NONE )
  {
    mEllipsoid = GEO_NONE;
    return true;
  }

  // Check if we have a custom projection, and set from text string.
  // Format is "PARAMETER:<semi-major axis>:<semi minor axis>
  // Numbers must be with (optional) decimal point and no other separators (C locale)
  // Distances in meters.  Flattening is calculated.
  if ( ellipsoid.startsWith( "PARAMETER" ) )
  {
    QStringList paramList = ellipsoid.split( ":" );
    bool semiMajorOk, semiMinorOk;
    double semiMajor = paramList[1].toDouble( & semiMajorOk );
    double semiMinor = paramList[2].toDouble( & semiMinorOk );
    if ( semiMajorOk && semiMinorOk )
    {
      return setEllipsoid( semiMajor, semiMinor );
    }
    else
    {
      return false;
    }
  }

  // Continue with PROJ.4 list of ellipsoids.

  //check the db is available
  myResult = sqlite3_open_v2( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, NULL );
  if ( myResult )
  {
    QgsMessageLog::logMessage( QObject::tr( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
    // XXX This will likely never happen since on open, sqlite creates the
    //     database if it does not exist.
    return false;
  }
  // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
  QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + "'";
  myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
  // XXX Need to free memory from the error msg if one is set
  if ( myResult == SQLITE_OK )
  {
    if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
    {
      radius = QString(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
      parameter2 = QString(( char * )sqlite3_column_text( myPreparedStatement, 1 ) );
    }
  }
  // close the sqlite3 statement
  sqlite3_finalize( myPreparedStatement );
  sqlite3_close( myDatabase );

  // row for this ellipsoid wasn't found?
  if ( radius.isEmpty() || parameter2.isEmpty() )
  {
    QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) );
    return false;
  }

  // get major semiaxis
  if ( radius.left( 2 ) == "a=" )
    mSemiMajor = radius.mid( 2 ).toDouble();
  else
  {
    QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) );
    return false;
  }

  // get second parameter
  // one of values 'b' or 'f' is in field parameter2
  // second one must be computed using formula: invf = a/(a-b)
  if ( parameter2.left( 2 ) == "b=" )
  {
    mSemiMinor = parameter2.mid( 2 ).toDouble();
    mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor );
  }
  else if ( parameter2.left( 3 ) == "rf=" )
  {
    mInvFlattening = parameter2.mid( 3 ).toDouble();
    mSemiMinor = mSemiMajor - ( mSemiMajor / mInvFlattening );
  }
  else
  {
    QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) );
    return false;
  }

  QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) );


  // get spatial ref system for ellipsoid
  QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs";
  QgsCoordinateReferenceSystem destCRS;
  destCRS.createFromProj4( proj4 );
  //TODO: createFromProj4 used to save to the user database any new CRS
  // this behavior was changed in order to separate creation and saving.
  // Not sure if it necessary to save it here, should be checked by someone
  // familiar with the code (should also give a more descriptive name to the generated CRS)
  if ( destCRS.srsid() == 0 )
  {
    QString myName = QString( " * %1 (%2)" )
                     .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ) )
                     .arg( destCRS.toProj4() );
    destCRS.saveAsUserCRS( myName );
  }
  //

  // set transformation from project CRS to ellipsoid coordinates
  mCoordTransform->setDestCRS( destCRS );

  // precalculate some values for area calculations
  computeAreaInit();

  mEllipsoid = ellipsoid;
  return true;
}
コード例 #23
0
ファイル: qgsdb2geometrycolumns.cpp プロジェクト: ndavid/QGIS
QgsDb2GeometryColumns::QgsDb2GeometryColumns( const QSqlDatabase &db )
  : mDatabase( db )
  , mEnvironment( ENV_LUW )
{
  QgsDebugMsg( "constructing" );
}
コード例 #24
0
double QgsDistanceArea::measure( QgsGeometry* geometry )
{
  if ( !geometry )
    return 0.0;

  const unsigned char* wkb = geometry->asWkb();
  if ( !wkb )
    return 0.0;

  QgsConstWkbPtr wkbPtr( wkb + 1 );

  QGis::WkbType wkbType;
  wkbPtr >> wkbType;

  double res, resTotal = 0;
  int count, i;

  // measure distance or area based on what is the type of geometry
  bool hasZptr = false;

  switch ( wkbType )
  {
    case QGis::WKBLineString25D:
      hasZptr = true;
    case QGis::WKBLineString:
      measureLine( wkb, &res, hasZptr );
      QgsDebugMsg( "returning " + QString::number( res ) );
      return res;

    case QGis::WKBMultiLineString25D:
      hasZptr = true;
    case QGis::WKBMultiLineString:
      wkbPtr >> count;
      for ( i = 0; i < count; i++ )
      {
        wkbPtr = measureLine( wkbPtr, &res, hasZptr );
        resTotal += res;
      }
      QgsDebugMsg( "returning " + QString::number( resTotal ) );
      return resTotal;

    case QGis::WKBPolygon25D:
      hasZptr = true;
    case QGis::WKBPolygon:
      measurePolygon( wkb, &res, 0, hasZptr );
      QgsDebugMsg( "returning " + QString::number( res ) );
      return res;

    case QGis::WKBMultiPolygon25D:
      hasZptr = true;
    case QGis::WKBMultiPolygon:
      wkbPtr >> count;
      for ( i = 0; i < count; i++ )
      {
        wkbPtr = measurePolygon( wkbPtr, &res, 0, hasZptr );
        if ( !wkbPtr )
        {
          QgsDebugMsg( "measurePolygon returned 0" );
          break;
        }
        resTotal += res;
      }
      QgsDebugMsg( "returning " + QString::number( resTotal ) );
      return resTotal;

    default:
      QgsDebugMsg( QString( "measure: unexpected geometry type: %1" ).arg( wkbType ) );
      return 0;
  }
}
コード例 #25
0
ファイル: qgsabout.cpp プロジェクト: ChowZenki/QGIS
QgsAbout::QgsAbout( QWidget *parent )
    : QDialog( parent, Qt::WindowSystemMenuHint )  // Modeless dialog with close button only
#else
QgsAbout::QgsAbout( QWidget *parent )
    : QDialog( parent )  // Normal dialog in non Mac-OS
#endif
{
  setupUi( this );
  init();
}

QgsAbout::~QgsAbout()
{
}

void QgsAbout::init()
{
  setPluginInfo();

  setWindowTitle( QString( "%1 - %2 Bit" ).arg( windowTitle() ).arg( QSysInfo::WordSize ) );

  // set the 60x60 icon pixmap
  QPixmap icon( QgsApplication::iconsPath() + "qgis-icon-60x60.png" );
  qgisIcon->setPixmap( icon );

  //read the authors file to populate the svn committers list
  QStringList lines;

  //
  // Load the authors (svn committers) list
  //
  QFile file( QgsApplication::authorsFilePath() );
  if ( file.open( QIODevice::ReadOnly ) )
  {
    QTextStream stream( &file );
    // Always use UTF-8
    stream.setCodec( "UTF-8" );
    QString line;
    while ( !stream.atEnd() )
    {
      line = stream.readLine(); // line of text excluding '\n'
      //ignore the line if it starts with a hash....
      if ( line.left( 1 ) == "#" )
        continue;
      QStringList myTokens = line.split( "\t", QString::SkipEmptyParts );
      lines << myTokens[0];
    }
    file.close();
    lstDevelopers->clear();
    lstDevelopers->insertItems( 0, lines );

    if ( lstDevelopers->count() > 0 )
    {
      lstDevelopers->setCurrentRow( 0 );
    }
  }

  lines.clear();
  //
  // Now load up the contributors list
  //
  QFile file2( QgsApplication::contributorsFilePath() );
  printf( "Reading contributors file %s.............................................\n",
          file2.fileName().toLocal8Bit().constData() );
  if ( file2.open( QIODevice::ReadOnly ) )
  {
    QTextStream stream( &file2 );
    // Always use UTF-8
    stream.setCodec( "UTF-8" );
    QString line;
    while ( !stream.atEnd() )
    {
      line = stream.readLine(); // line of text excluding '\n'
      //ignore the line if it starts with a hash....
      if ( line.left( 1 ) == "#" )
        continue;
      lines += line;
    }
    file2.close();
    lstContributors->clear();
    lstContributors->insertItems( 0, lines );
    if ( lstContributors->count() > 0 )
    {
      lstContributors->setCurrentRow( 0 );
    }
  }



  // read the DONORS file and populate the text widget
  QFile donorsFile( QgsApplication::donorsFilePath() );
#ifdef QGISDEBUG
  printf( "Reading donors file %s.............................................\n",
          donorsFile.fileName().toLocal8Bit().constData() );
#endif
  if ( donorsFile.open( QIODevice::ReadOnly ) )
  {
    QString donorsHTML = ""
                         + tr( "<p>For a list of individuals and institutions who have contributed "
                               "money to fund QGIS development and other project costs see "
                               "<a href=\"http://qgis.org/en/sponsorship/donors.html\">"
                               "http://qgis.org/en/sponsorship/donors.html</a></p>" );
#if 0
    QString website;
    QTextStream donorsStream( &donorsFile );
    // Always use UTF-8
    donorsStream.setCodec( "UTF-8" );
    QString sline;
    while ( !donorsStream.atEnd() )
    {
      sline = donorsStream.readLine(); // line of text excluding '\n'
      //ignore the line if it starts with a hash....
      if ( sline.left( 1 ) == "#" )
        continue;
      QStringList myTokens = sline.split( "|", QString::SkipEmptyParts );
      if ( myTokens.size() > 1 )
      {
        website = "<a href=\"" + myTokens[1].remove( ' ' ) + "\">" + myTokens[1] + "</a>";
      }
      else
      {
        website = "&nbsp;";
      }
      donorsHTML += "<tr>";
      donorsHTML += "<td>" + myTokens[0] + "</td><td>" + website + "</td>";
      // close the row
      donorsHTML += "</tr>";
    }
    donorsHTML += "</table>";
#endif

    QString myStyle = QgsApplication::reportStyleSheet();
    txtDonors->clear();
    txtDonors->document()->setDefaultStyleSheet( myStyle );
    txtDonors->setHtml( donorsHTML );
    QgsDebugMsg( QString( "donorsHTML:%1" ).arg( donorsHTML.toAscii().constData() ) );
  }

  // read the TRANSLATORS file and populate the text widget
  QFile translatorFile( QgsApplication::translatorsFilePath() );
#ifdef QGISDEBUG
  printf( "Reading translators file %s.............................................\n",
          translatorFile.fileName().toLocal8Bit().constData() );
#endif
  if ( translatorFile.open( QIODevice::ReadOnly ) )
  {
    QString translatorHTML = "";
    QTextStream translatorStream( &translatorFile );
    // Always use UTF-8
    translatorStream.setCodec( "UTF-8" );
    QString myStyle = QgsApplication::reportStyleSheet();
    translatorHTML += "<style>" + myStyle + "</style>";
    while ( !translatorStream.atEnd() )
    {
      translatorHTML += translatorStream.readLine();
    }
    txtTranslators->setHtml( translatorHTML );
    QgsDebugMsg( QString( "translatorHTML:%1" ).arg( translatorHTML.toAscii().constData() ) );
  }
  setWhatsNew();
  setLicence();
}
コード例 #26
0
const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr )
{
  if ( !feature )
  {
    QgsDebugMsg( "no feature to measure" );
    return 0;
  }

  QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );

  // get number of rings in the polygon
  int numRings;
  wkbPtr >> numRings;

  if ( numRings == 0 )
  {
    QgsDebugMsg( "no rings to measure" );
    return 0;
  }

  // Set pointer to the first ring
  QList<QgsPoint> points;
  QgsPoint pnt;
  double x, y;
  if ( area )
    *area = 0;
  if ( perimeter )
    *perimeter = 0;

  try
  {
    for ( int idx = 0; idx < numRings; idx++ )
    {
      int nPoints;
      wkbPtr >> nPoints;

      // Extract the points from the WKB and store in a pair of
      // vectors.
      for ( int jdx = 0; jdx < nPoints; jdx++ )
      {
        wkbPtr >> x >> y;
        if ( hasZptr )
        {
          // totally ignore Z value
          wkbPtr += sizeof( double );
        }

        pnt = QgsPoint( x, y );

        if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
        {
          pnt = mCoordTransform->transform( pnt );
        }
        points.append( pnt );
      }

      if ( points.size() > 2 )
      {
        if ( area )
        {
          double areaTmp = computePolygonArea( points );
          if ( idx == 0 )
          {
            // exterior ring
            *area += areaTmp;
          }
          else
          {
            *area -= areaTmp; // interior rings
          }
        }

        if ( perimeter )
        {
          if ( idx == 0 )
          {
            // exterior ring
            *perimeter += measureLine( points );
          }
        }
      }

      points.clear();
    }
  }
  catch ( QgsCsException &cse )
  {
    Q_UNUSED( cse );
    QgsMessageLog::logMessage( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate polygon area or perimeter." ) );
  }

  return wkbPtr;
}
コード例 #27
0
QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
    : QgsRasterDataProvider( uri )
    , mValid( false )
    , mGrassDataType( 0 )
    , mCols( 0 )
    , mRows( 0 )
    , mYBlockSize( 0 )
    , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
{
  QgsDebugMsg( "QgsGrassRasterProvider: constructing with uri '" + uri + "'." );

  if ( !QgsGrass::init() )
  {
    return;
  }

  // Parse URI, it is the same like using GDAL, i.e. path to raster cellhd, i.e.
  // /path/to/gisdbase/location/mapset/cellhd/map
  QFileInfo fileInfo( uri );
  if ( !fileInfo.exists() ) // then we keep it valid forever
  {
    appendError( ERR( tr( "cellhd file %1 does not exist" ).arg( uri ) ) );
    return;
  }

  mMapName = fileInfo.fileName();
  QDir dir = fileInfo.dir();
  QString element = dir.dirName();
  if ( element != QLatin1String( "cellhd" ) )
  {
    appendError( ERR( tr( "Groups not yet supported" ) ) );
    return;
  }
  dir.cdUp(); // skip cellhd
  mMapset = dir.dirName();
  dir.cdUp();
  mLocation = dir.dirName();
  dir.cdUp();
  mGisdbase = dir.path();

  QgsDebugMsg( QString( "gisdbase: %1" ).arg( mGisdbase ) );
  QgsDebugMsg( QString( "location: %1" ).arg( mLocation ) );
  QgsDebugMsg( QString( "mapset: %1" ).arg( mMapset ) );
  QgsDebugMsg( QString( "mapName: %1" ).arg( mMapName ) );

  mTimestamp = dataTimestamp();

  mRasterValue.set( mGisdbase, mLocation, mMapset, mMapName );
  //mValidNoDataValue = true;

  QString error;
  mCrs = QgsGrass::crs( mGisdbase, mLocation, error );
  appendIfError( error );
  QgsDebugMsg( "mCrs: " + mCrs.toWkt() );

  // the block size can change of course when the raster is overridden
  // ibut it is only called once when statistics are calculated
  error.clear();
  QgsGrass::size( mGisdbase, mLocation, mMapset, mMapName, &mCols, &mRows, error );
  appendIfError( error );

  error.clear();
  mInfo = QgsGrass::info( mGisdbase, mLocation, mMapset, mMapName, QgsGrassObject::Raster,
                          QStringLiteral( "info" ), QgsRectangle(), 0, 0, 3000, error );
  appendIfError( error );

  mGrassDataType = mInfo[QStringLiteral( "TYPE" )].toInt();
  QgsDebugMsg( "mGrassDataType = " + QString::number( mGrassDataType ) );

  // TODO: avoid showing these strange numbers in GUI
  // TODO: don't save no data values in project file, add a flag if value was defined by user

  double myInternalNoDataValue;
  if ( mGrassDataType == CELL_TYPE )
  {
    myInternalNoDataValue = INT_MIN;
  }
  else if ( mGrassDataType == DCELL_TYPE )
  {
    // Don't use numeric limits, raster layer is using
    //    qAbs( myValue - mNoDataValue ) <= TINY_VALUE
    // if the mNoDataValue would be a limit, the subtraction could overflow.
    // No data value is shown in GUI, use some nice number.
    // Choose values with small representation error.
    // limit: 1.7976931348623157e+308
    //myInternalNoDataValue = -1e+300;
    myInternalNoDataValue = std::numeric_limits<double>::quiet_NaN();
  }
  else
  {
    if ( mGrassDataType != FCELL_TYPE )
    {
      QgsDebugMsg( "unexpected data type" );
    }

    // limit: 3.40282347e+38
    //myInternalNoDataValue = -1e+30;
    myInternalNoDataValue = std::numeric_limits<float>::quiet_NaN();
  }
  mNoDataValue = myInternalNoDataValue;
  mSrcHasNoDataValue.append( true );
  mSrcNoDataValue.append( mNoDataValue );
  mUseSrcNoDataValue.append( true );
  QgsDebugMsg( QString( "myInternalNoDataValue = %1" ).arg( myInternalNoDataValue ) );

  // TODO: refresh mRows and mCols if raster was rewritten
  // We have to decide some reasonable block size, not to big to occupate too much
  // memory, not too small to result in too many calls to readBlock -> qgis.d.rast
  // for statistics
  int typeSize = dataTypeSize( dataType( 1 ) );
  if ( mCols > 0 && typeSize > 0 )
  {
    const int cache_size = 10000000; // ~ 10 MB
    mYBlockSize = cache_size / typeSize / mCols;
    if ( mYBlockSize > mRows )
    {
      mYBlockSize = mRows;
    }
    QgsDebugMsg( "mYBlockSize = " + QString::number( mYBlockSize ) );
    mValid = true;
  }
}
コード例 #28
0
QString QgsDistanceArea::textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit )
{
  QString unitLabel;

  switch ( u )
  {
    case QGis::Meters:
      if ( isArea )
      {
        if ( keepBaseUnit )
        {
          unitLabel = QObject::trUtf8( " m²" );
        }
        else if ( qAbs( value ) > 1000000.0 )
        {
          unitLabel = QObject::trUtf8( " km²" );
          value = value / 1000000.0;
        }
        else if ( qAbs( value ) > 10000.0 )
        {
          unitLabel = QObject::tr( " ha" );
          value = value / 10000.0;
        }
        else
        {
          unitLabel = QObject::trUtf8( " m²" );
        }
      }
      else
      {
        if ( keepBaseUnit || qAbs( value ) == 0.0 )
        {
          unitLabel = QObject::tr( " m" );
        }
        else if ( qAbs( value ) > 1000.0 )
        {
          unitLabel = QObject::tr( " km" );
          value = value / 1000;
        }
        else if ( qAbs( value ) < 0.01 )
        {
          unitLabel = QObject::tr( " mm" );
          value = value * 1000;
        }
        else if ( qAbs( value ) < 0.1 )
        {
          unitLabel = QObject::tr( " cm" );
          value = value * 100;
        }
        else
        {
          unitLabel = QObject::tr( " m" );
        }
      }
      break;
    case QGis::Feet:
      if ( isArea )
      {
        if ( keepBaseUnit  || qAbs( value ) <= 0.5*43560.0 )
        {
          // < 0.5 acre show sq ft
          unitLabel = QObject::tr( " sq ft" );
        }
        else if ( qAbs( value ) <= 0.5*5280.0*5280.0 )
        {
          // < 0.5 sq mile show acre
          unitLabel = QObject::tr( " acres" );
          value /= 43560.0;
        }
        else
        {
          // above 0.5 acre show sq mi
          unitLabel = QObject::tr( " sq mile" );
          value /= 5280.0 * 5280.0;
        }
      }
      else
      {
        if ( qAbs( value ) <= 528.0 || keepBaseUnit )
        {
          if ( qAbs( value ) == 1.0 )
          {
            unitLabel = QObject::tr( " foot" );
          }
          else
          {
            unitLabel = QObject::tr( " feet" );
          }
        }
        else
        {
          unitLabel = QObject::tr( " mile" );
          value /= 5280.0;
        }
      }
      break;
    case QGis::NauticalMiles:
      if ( isArea )
      {
        unitLabel = QObject::tr( " sq. NM" );
      }
      else
      {
        unitLabel = QObject::tr( " NM" );
      }
      break;
    case QGis::Degrees:
      if ( isArea )
      {
        unitLabel = QObject::tr( " sq.deg." );
      }
      else
      {
        if ( qAbs( value ) == 1.0 )
          unitLabel = QObject::tr( " degree" );
        else
          unitLabel = QObject::tr( " degrees" );
      }
      break;
    case QGis::UnknownUnit:
      unitLabel = QObject::tr( " unknown" );
    default:
      QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( u ) );
  };


  return QLocale::system().toString( value, 'f', decimals ) + unitLabel;
}
コード例 #29
0
void QgsGrassShell::printStdout()
{
  // Debug
#ifdef QGISDEBUG
  QString str;
  for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ )
  {
    int c = mStdoutBuffer[i];
    QString s = "";
    if ( c > '\037' && c != '\177' ) // control characters
    {
      str += c;
    }
    else
    {
      str += "(c=" + QString::number( c, 8 ) + ")";
    }
  }
  QgsDebugMsg( "****** buffer ******" );
  QgsDebugMsg( QString( "-->%1<--" ).arg( str.toLocal8Bit().constData() ) );
#endif

  eraseCursor();
  // To make it faster we want to print maximum lenght blocks from buffer
  while ( mStdoutBuffer.length() > 0 )
  {
    QgsDebugMsg( "------ cycle ------" );

    // Search control character
    int control = -1;
    for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ )
    {
      int c = mStdoutBuffer[i];
      if ( c < '\037' || c == '\177' )
      {
        control = i;
        break;
      }
    }
    QgsDebugMsg( QString( "control = %1" ).arg( control ) );

    // Process control character if found at index 0
    if ( control == 0 )
    {
      int c = mStdoutBuffer[0];
      QgsDebugMsg( QString( "c = %1" ).arg( QString::number( c, 8 ).local8Bit().data() ) );

      // control sequence
      if ( c == '\033' )
      {
// QgsDebugMsg("control sequence");

        bool found = false;

        // It is sequence, so it should be at least one more character
        // wait for more data
        if ( mStdoutBuffer.length() < 2 ) break;
        if ( mStdoutBuffer[1] == ']' && mStdoutBuffer.length() < 3 ) break;

        // ESC ] Ps ; Pt BEL    (xterm title hack)
        QRegExp rx( "\\](\\d+);([^\\a]+)\\a" );
        if ( rx.search( mStdoutBuffer, 1 ) == 1 )
        {
          int mlen = rx.matchedLength();
          QgsDebugMsg( QString( "ESC(set title): %1" ).arg( rx.cap( 2 ).local8Bit().data() ) );
          mStdoutBuffer.remove( 0, mlen + 1 );
          found = true;
        }

        if ( !found )
        {
          //    ESC [ Pn ; Pn FINAL
          // or ESC [ = Pn ; Pn FINAL
          // or ESC [ = Pn ; Pn FINAL
          // TODO: QRegExp captures only last of repeated patterns
          //       ( ; separated nums - (;\\d+)* )
          rx.setPattern( "\\[([?=])*(\\d+)*(;\\d+)*([A-z])" );
          if ( rx.search( mStdoutBuffer, 1 ) == 1 )
          {
            int mlen = rx.matchedLength();
            char final = rx.cap( 4 ).at( 0 ).latin1();

            QgsDebugMsg( QString( "final = %1" ).arg( final ) );
// QgsDebugMsg(QString("ESC: %1").arg(rx.cap(0)));

            switch ( final )
            {
              case 'l' : // RM - Reset Mode
              case 'h' : // SM - Set Mode
              {
                int mode = -1;
                switch ( rx.cap( 2 ).toInt() )
                {
                  case 4 :
                    mode = Insert;
                    break;

                  default:
                    QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
                    break;
                }
                if ( mode >= 0 )
                {
                  if ( final == 'l' )
                    resetMode( mode );
                  else
                    setMode( mode );
                }
                break;
              }

              case 'm' : // SGR - Select Graphic Rendition
                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
                {
                  for ( int i = 0; i < RendetionCount; i++ )
                  {
                    mRendetion[i] = false;
                  }
                }
                else
                {
                  QgsDebugMsg( QString( "ESC SGR ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
                }
                break;

              case 'P' : // DCH - Delete Character
              {
                int n = rx.cap( 2 ).toInt();
                mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + n, 0 );
                mText->removeSelectedText( 0 );
                break;
              }

              case 'K' : // EL - Erase In Line
                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
                {
                  //mText->setSelectionAttributes ( 1, QColor(255,255,255), true );
                  mText->setSelection( mParagraph, mIndex, mParagraph,
                                       mText->paragraphLength( mParagraph ), 0 );
                  mText->removeSelectedText( 0 );
                }
                break;

                // TODO: multiple tab stops
              case 'H' : // Horizontal Tabulation Set (HTS)
                mTabStop[mIndex] = true;
                QgsDebugMsg( QString( "TAB set on %1" ).arg( mIndex ) );
                break;

              case 'g' : // Tabulation Clear (TBC)
                // ESC [ g  Clears tab stop at the cursor
                // ESC [ 2 g  Clears all tab stops in the line
                // ESC [ 3 g  Clears all tab stops in the Page
                QgsDebugMsg( "TAB reset" );
                if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 )
                {
                  mTabStop[mIndex] = false;
                }
                else
                {
                  for ( int i = 0; i < ( int )mTabStop.size(); i++ )
                    mTabStop[mIndex] = false;
                }
                break;

              default:
                QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) );
                break;
            }

            mStdoutBuffer.remove( 0, mlen + 1 );
            found = true;
          }
コード例 #30
0
bool QgsProject::write()
{
  clearError();

  // if we have problems creating or otherwise writing to the project file,
  // let's find out up front before we go through all the hand-waving
  // necessary to create all the Dom objects
  if ( !imp_->file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
  {
    imp_->file.close();         // even though we got an error, let's make
    // sure it's closed anyway

    setError( tr( "Unable to save to file %1" ).arg( imp_->file.fileName() ) );
    return false;
  }
  QFileInfo myFileInfo( imp_->file );
  if ( !myFileInfo.isWritable() )
  {
    // even though we got an error, let's make
    // sure it's closed anyway
    imp_->file.close();
    setError( tr( "%1 is not writable. Please adjust permissions (if possible) and try again." )
              .arg( imp_->file.fileName() ) );
    return false;
  }

  QDomImplementation DomImplementation;

  QDomDocumentType documentType =
    DomImplementation.createDocumentType( "qgis", "http://mrcc.com/qgis.dtd",
                                          "SYSTEM" );
  std::auto_ptr < QDomDocument > doc =
    std::auto_ptr < QDomDocument > ( new QDomDocument( documentType ) );


  QDomElement qgisNode = doc->createElement( "qgis" );
  qgisNode.setAttribute( "projectname", title() );
  qgisNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );

  doc->appendChild( qgisNode );

  // title
  QDomElement titleNode = doc->createElement( "title" );
  qgisNode.appendChild( titleNode );

  QDomText titleText = doc->createTextNode( title() );  // XXX why have title TWICE?
  titleNode.appendChild( titleText );

  // let map canvas and legend write their information
  emit writeProject( *doc );

  // within top level node save list of layers
  QMap<QString, QgsMapLayer*> & layers = QgsMapLayerRegistry::instance()->mapLayers();

  // Iterate over layers in zOrder
  // Call writeXML() on each
  QDomElement projectLayersNode = doc->createElement( "projectlayers" );
  projectLayersNode.setAttribute( "layercount", qulonglong( layers.size() ) );

  QMap<QString, QgsMapLayer*>::iterator li = layers.begin();
  while ( li != layers.end() )
  {
    //QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer(*li);
    QgsMapLayer* ml = li.value();

    if ( ml )
    {
      QString externalProjectFile = layerIsEmbedded( ml->id() );
      QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.find( ml->id() );
      if ( emIt == mEmbeddedLayers.constEnd() )
      {
        ml->writeXML( projectLayersNode, *doc );
      }
      else //layer defined in an external project file
      {
        //only save embedded layer if not managed by a legend group
        if ( emIt.value().second )
        {
          QDomElement mapLayerElem = doc->createElement( "maplayer" );
          mapLayerElem.setAttribute( "embedded", 1 );
          mapLayerElem.setAttribute( "project", writePath( emIt.value().first ) );
          mapLayerElem.setAttribute( "id", ml->id() );
          projectLayersNode.appendChild( mapLayerElem );
        }
      }
    }
    li++;
  }

  qgisNode.appendChild( projectLayersNode );

  // now add the optional extra properties

  dump_( imp_->properties_ );

  QgsDebugMsg( QString( "there are %1 property scopes" ).arg( static_cast<int>( imp_->properties_.count() ) ) );

  if ( !imp_->properties_.isEmpty() ) // only worry about properties if we
    // actually have any properties
  {
    imp_->properties_.writeXML( "properties", qgisNode, *doc );
  }

  // now wrap it up and ship it to the project file
  doc->normalize();             // XXX I'm not entirely sure what this does

  //QString xml = doc->toString(4); // write to string with indentation of four characters
  // (yes, four is arbitrary)

  // const char * xmlString = xml; // debugger probe point
  // qDebug( "project file output:\n\n" + xml );

  QTextStream projectFileStream( &imp_->file );

  //projectFileStream << xml << endl;
  doc->save( projectFileStream, 4 );  // save as utf-8
  imp_->file.close();

  // check if the text stream had no error - if it does
  // the user will get a message so they can try to resolve the
  // situation e.g. by saving project to a volume with more space
  //
  if ( projectFileStream.pos() == -1  || imp_->file.error() != QFile::NoError )
  {
    setError( tr( "Unable to save to file %1. Your project "
                  "may be corrupted on disk. Try clearing some space on the volume and "
                  "check file permissions before pressing save again." )
              .arg( imp_->file.fileName() ) );
    return false;
  }

  dirty( false );               // reset to pristine state

  return true;
} // QgsProject::write