示例#1
0
/*!
    \fn OptVectorLayer::quickGetFeatureAtId_( int featureConstantId, OptFeature& f, bool fetchGeometries, bool fetchAttributes )
 */
int OptVectorLayer::quickGetFeatureAtId_( int featureConstantId, OptFeature& f,  bool fetchGeometries, bool fetchAttributes )
{
  //get the constant feature id of the give feature id
  int featureId = -1;
  featureId = mIdConstantId.key( featureConstantId );
  
//{zhangliye2715:api}
  int result = featureAtId( featureId, f, fetchGeometries, fetchAttributes );
  return result;
}
/**
 * Chooses which image loading method to use and centers the map canvas on the current feature
 */
void eVisGenericEventBrowserGui::displayImage()
{
  //This if statement is a bit of a hack, have to track down where the 0 is comming from on initalization
  if ( "0" != mEventImagePath && 0 == displayArea->currentIndex() )
  {
    if ( mEventImagePath.startsWith( "http://", Qt::CaseInsensitive ) )
    {
      imageDisplayArea->displayUrlImage( mEventImagePath );
    }
    else
    {
      imageDisplayArea->displayImage( mEventImagePath );
    }

    //clear any selection that may be present
    mVectorLayer->removeSelection();
    if ( !mFeatureIds.isEmpty() )
    {
      //select the current feature in the layer
      mVectorLayer->select( mFeatureIds.at( mCurrentFeatureIndex ) );
      //get a copy of the feature
      QgsFeature* myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

      if ( !myFeature )
        return;

      QgsPoint myPoint = myFeature->geometry().asPoint();
      myPoint = mCanvas->mapSettings().layerToMapCoordinates( mVectorLayer, myPoint );
      //keep the extent the same just center the map canvas in the display so our feature is in the middle
      QgsRectangle myRect( myPoint.x() - ( mCanvas->extent().width() / 2 ), myPoint.y() - ( mCanvas->extent().height() / 2 ), myPoint.x() + ( mCanvas->extent().width() / 2 ), myPoint.y() + ( mCanvas->extent().height() / 2 ) );

      // only change the extents if the point is beyond the current extents to minimise repaints
      if ( !mCanvas->extent().contains( myPoint ) )
      {
        mCanvas->setExtent( myRect );
      }
      mCanvas->refresh();
    }
  }
}
/**
 * Slot called when the index changes for the cboxCompassBearingField combo box.
 * @param theIndex - The index of the new selected item
 */
void eVisGenericEventBrowserGui::on_cboxCompassOffsetField_currentIndexChanged( int theIndex )
{
  Q_UNUSED( theIndex );
  if ( !mIgnoreEvent )
  {
    mConfiguration.setCompassOffsetField( cboxCompassOffsetField->currentText() );

    QgsFields myFields = mDataProvider->fields();
    QgsFeature* myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

    if ( !myFeature )
      return;

    QgsAttributes myAttrs = myFeature->attributes();
    for ( int i = 0; i < myAttrs.count(); ++i )
    {
      if ( myFields.at( i ).name() == cboxCompassOffsetField->currentText() )
      {
        mCompassOffset = myAttrs.at( i ).toDouble();
      }
    }
  }
}
/**
 * Slot called when the index changes for the cboxEventImagePathField combo box.
 * \param index - The index of the new selected item
 */
void eVisGenericEventBrowserGui::cboxEventImagePathField_currentIndexChanged( int index )
{
  Q_UNUSED( index );
  if ( !mIgnoreEvent )
  {
    mConfiguration.setEventImagePathField( cboxEventImagePathField->currentText() );

    QgsFields myFields = mVectorLayer->fields();
    QgsFeature *myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

    if ( !myFeature )
      return;

    QgsAttributes myAttrs = myFeature->attributes();
    for ( int i = 0; i < myAttrs.count(); ++i )
    {
      if ( myFields.at( i ).name() == cboxEventImagePathField->currentText() )
      {
        mEventImagePath = myAttrs.at( i ).toString();
      }
    }
  }
}
/**
 * Display the attrbiutes for the current feature and load the image
 */
void eVisGenericEventBrowserGui::loadRecord()
{
  treeEventData->clear();

  //Get a pointer to the current feature
  QgsFeature* myFeature;
  myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

  if ( !myFeature )
    return;

  QString myCompassBearingField = cboxCompassBearingField->currentText();
  QString myCompassOffsetField = cboxCompassOffsetField->currentText();
  QString myEventImagePathField = cboxEventImagePathField->currentText();
  QgsFields myFields = mDataProvider->fields();
  QgsAttributes myAttrs = myFeature->attributes();
  //loop through the attributes and display their contents
  for ( int i = 0; i < myAttrs.count(); ++i )
  {
    QStringList myValues;
    QString fieldName = myFields.at( i ).name();
    myValues << fieldName << myAttrs.at( i ).toString();
    QTreeWidgetItem* myItem = new QTreeWidgetItem( myValues );
    if ( fieldName == myEventImagePathField )
    {
      mEventImagePath = myAttrs.at( i ).toString();
    }

    if ( fieldName == myCompassBearingField )
    {
      mCompassBearing = myAttrs.at( i ).toDouble();
    }

    if ( mConfiguration.isAttributeCompassOffsetSet() )
    {
      if ( fieldName == myCompassOffsetField )
      {
        mCompassOffset = myAttrs.at( i ).toDouble();
      }
    }
    else
    {
      mCompassOffset = 0.0;
    }

    //Check to see if the attribute is a know file type
    int myIterator = 0;
    while ( myIterator < tableFileTypeAssociations->rowCount() )
    {
      if ( tableFileTypeAssociations->item( myIterator, 0 ) && ( myAttrs.at( i ).toString().startsWith( tableFileTypeAssociations->item( myIterator, 0 )->text() + ':', Qt::CaseInsensitive ) || myAttrs.at( i ).toString().endsWith( tableFileTypeAssociations->item( myIterator, 0 )->text(), Qt::CaseInsensitive ) ) )
      {
        myItem->setBackground( 1, QBrush( QColor( 183, 216, 125, 255 ) ) );
        break;
      }
      else
        myIterator++;
    }
    treeEventData->addTopLevelItem( myItem );
  }
  //Modify EventImagePath as needed
  buildEventImagePath();

  //Request the image to be displayed in the browser
  displayImage();
}
/**
 * This method is an extension of the constructor. It was implemented to reduce the amount of code duplicated between the constuctors.
 */
bool eVisGenericEventBrowserGui::initBrowser()
{

  //setup gui
  setWindowTitle( tr( "Generic Event Browser" ) );

  connect( treeEventData, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ), this, SLOT( launchExternalApplication( QTreeWidgetItem *, int ) ) );

  mHighlightSymbol.load( ":/evis/eVisHighlightSymbol.png" );
  mPointerSymbol.load( ":/evis/eVisPointerSymbol.png" );
  mCompassOffset = 0.0;

  //Flag to let us know if the browser fully loaded
  mBrowserInitialized = false;

  //Initialize some class variables
  mDefaultEventImagePathField = 0;
  mDefaultCompassBearingField = 0;
  mDefaultCompassOffsetField = 0;

  //initialize Display tab GUI elements
  pbtnNext->setEnabled( false );
  pbtnPrevious->setEnabled( false );


  //Set up Attribute display
  treeEventData->setColumnCount( 2 );
  QStringList treeHeaders;
  treeHeaders << tr( "Field" ) << tr( "Value" );
  treeEventData->setHeaderLabels( treeHeaders );

  //Initialize Options tab GUI elements
  cboxEventImagePathField->setEnabled( true );
  chkboxEventImagePathRelative->setChecked( false );

  chkboxDisplayCompassBearing->setChecked( false );
  cboxCompassBearingField->setEnabled( true );

  rbtnManualCompassOffset->setChecked( false );
  dsboxCompassOffset->setEnabled( true );
  dsboxCompassOffset->setValue( 0.0 );
  rbtnAttributeCompassOffset->setChecked( false );
  cboxCompassOffsetField->setEnabled( true );


  chkboxUseOnlyFilename->setChecked( false );

  QString myThemePath = QgsApplication::activeThemePath();
  pbtnResetEventImagePathData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );
  pbtnResetCompassBearingData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );
  pbtnResetCompassOffsetData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );
  pbtnResetBasePathData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );
  pbtnResetUseOnlyFilenameData->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );
  pbtnResetApplyPathRulesToDocs->setIcon( QIcon( QPixmap( myThemePath + "/mActionDraw.svg" ) ) );

  chkboxSaveEventImagePathData->setChecked( false );
  chkboxSaveCompassBearingData->setChecked( false );
  chkboxSaveCompassOffsetData->setChecked( false );
  chkboxSaveBasePathData->setChecked( false );
  chkboxSaveUseOnlyFilenameData->setChecked( false );

  //Set up Configure External Application buttons
  pbtnAddFileType->setIcon( QIcon( QPixmap( myThemePath + "/mActionNewAttribute.png" ) ) );
  pbtnDeleteFileType->setIcon( QIcon( QPixmap( myThemePath + "/mActionDeleteAttribute.png" ) ) );

  //Check to for interface, not null when launched from plugin toolbar, otherwise expect map canvas
  if ( mInterface )
  {
    //check for active layer
    if ( mInterface->activeLayer() )
    {
      //verify that the active layer is a vector layer
      if ( QgsMapLayer::VectorLayer == mInterface->activeLayer()->type() )
      {
        mVectorLayer = ( QgsVectorLayer* )mInterface->activeLayer();
        mCanvas = mInterface->mapCanvas();
      }
      else
      {
        QMessageBox::warning( this, tr( "Warning" ), tr( "This tool only supports vector data" ) );
        return false;
      }
    }
    else
    {
      QMessageBox::warning( this, tr( "Warning" ), tr( "No active layers found" ) );
      return false;
    }
  }
  //check for map canvas, if map canvas is null, throw error
  else if ( mCanvas )
  {
    //check for active layer
    if ( mCanvas->currentLayer() )
    {
      //verify that the active layer is a vector layer
      if ( QgsMapLayer::VectorLayer == mCanvas->currentLayer()->type() )
      {
        mVectorLayer = ( QgsVectorLayer* )mCanvas->currentLayer();
      }
      else
      {
        QMessageBox::warning( this, tr( "Warning" ), tr( "This tool only supports vector data" ) );
        return false;
      }
    }
    else
    {
      QMessageBox::warning( this, tr( "Warning" ), tr( "No active layers found" ) );
      return false;
    }
  }
  else
  {
    QMessageBox::warning( this, tr( "Error" ), tr( "Unable to connect to either the map canvas or application interface" ) );
    return false;
  }

  //Connect rendering routine for highlighting symbols and load symbols
  connect( mCanvas, SIGNAL( renderComplete( QPainter * ) ), this, SLOT( renderSymbol( QPainter * ) ) );

  mDataProvider = mVectorLayer->dataProvider();

  /*
   * A list of the selected feature ids is made so that we can move forward and backward through
   * the list. The data providers only have the ability to get one feature at a time or
   * sequentially move forward through the selected features
   */
  if ( 0 == mVectorLayer->selectedFeatureCount() ) //if nothing is selected select everything
  {
    mVectorLayer->invertSelection();
    mFeatureIds = mVectorLayer->selectedFeaturesIds().toList();
  }
  else //use selected features
  {
    mFeatureIds = mVectorLayer->selectedFeaturesIds().toList();
  }

  if ( 0 == mFeatureIds.size() )
    return false;

  //get the first feature in the list so we can set the field in the pulldown menues
  QgsFeature* myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );
  if ( !myFeature )
  {
    QMessageBox::warning( this, tr( "Error" ), tr( "An invalid feature was received during initialization" ) );
    return false;
  }

  QgsFields myFields = mDataProvider->fields();
  mIgnoreEvent = true; //Ignore indexChanged event when adding items to combo boxes
  for ( int x = 0; x < myFields.count(); x++ )
  {
    QString name = myFields.at( x ).name();
    cboxEventImagePathField->addItem( name );
    cboxCompassBearingField->addItem( name );
    cboxCompassOffsetField->addItem( name );
    if ( myFeature->attribute( x ).toString().contains( QRegExp( "(jpg|jpeg|tif|tiff|gif)", Qt::CaseInsensitive ) ) )
    {
      mDefaultEventImagePathField = x;
    }

    if ( name.contains( QRegExp( "(comp|bear)", Qt::CaseInsensitive ) ) )
    {
      mDefaultCompassBearingField = x;
    }

    if ( name.contains( QRegExp( "(offset|declination)", Qt::CaseInsensitive ) ) )
    {
      mDefaultCompassOffsetField = x;
    }
  }
  mIgnoreEvent = false;

  //Set Display tab gui items
  if ( mFeatureIds.size() > 1 )
  {
    pbtnNext->setEnabled( true );
  }

  setWindowTitle( tr( "Event Browser - Displaying records 01 of %1" ).arg( mFeatureIds.size(), 2, 10, QChar( '0' ) ) );

  //Set Options tab gui items
  initOptionsTab();

  //Load file associations into Configure External Applications tab gui items
  QSettings myQSettings;
  myQSettings.beginWriteArray( "/eVis/filetypeassociations" );
  int myTotalAssociations = myQSettings.childGroups().count();
  int myIterator = 0;
  while ( myIterator < myTotalAssociations )
  {
    myQSettings.setArrayIndex( myIterator );
    tableFileTypeAssociations->insertRow( tableFileTypeAssociations->rowCount() );
    tableFileTypeAssociations->setItem( myIterator, 0, new QTableWidgetItem( myQSettings.value( "extension", "" ).toString() ) );
    tableFileTypeAssociations->setItem( myIterator, 1, new QTableWidgetItem( myQSettings.value( "application", "" ).toString() ) );
    myIterator++;
  }
  myQSettings.endArray();

  mBrowserInitialized = true;

  return true;
}
/**
 * This slot is coonnected to the map canvas. When the canvas is done drawing the slot is fired to display thee highlighting symbol
 * @param thePainter - Pointer to the QPainter object
 */
void eVisGenericEventBrowserGui::renderSymbol( QPainter* thePainter )
{

  if ( !mFeatureIds.isEmpty() && mVectorLayer )
  {
    //Get a pointer to the current feature
    QgsFeature* myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

    if ( !myFeature )
      return;

    QgsPoint myPoint = myFeature->geometry().asPoint();
    myPoint = mCanvas->mapSettings().layerToMapCoordinates( mVectorLayer, myPoint );

    mCanvas->getCoordinateTransform()->transform( &myPoint );

    if ( mConfiguration.isDisplayCompassBearingSet() )
    {
      //Make a copy of the pointersymbol and rotate it based on the values in the attribute field
      QPixmap myTempPixmap( mPointerSymbol.height(), mPointerSymbol.height() );
      myTempPixmap.fill( QColor( 255, 255, 255, 0 ) );
      QPainter p( &myTempPixmap );
      QMatrix wm;
      wm.translate( myTempPixmap.width() / 2, myTempPixmap.height() / 2 ); // really center

      double myBearing = mCompassBearing;
      if ( mConfiguration.isManualCompassOffsetSet() )
      {
        myBearing = mCompassBearing + mConfiguration.compassOffset();
      }
      else
      {
        myBearing = mCompassBearing + mCompassOffset;
      }

      if ( myBearing < 0.0 )
      {
        while ( myBearing < 0.0 )
          myBearing = 360.0 + myBearing;
      }
      else if ( myBearing >= 360.0 )
      {
        while ( myBearing >= 360.0 )
          myBearing = myBearing - 360.0;
      }

      wm.rotate( myBearing );

      p.setWorldMatrix( wm );
      p.drawPixmap( -mPointerSymbol.width() / 2, -mPointerSymbol.height() / 2, mPointerSymbol );

      int xShift = ( int )myPoint.x() - ( myTempPixmap.width() / 2 );
      int yShift = ( int )myPoint.y() - ( myTempPixmap.height() / 2 );
      thePainter->drawPixmap( xShift, yShift, myTempPixmap );
    }
    else
    {
      int xShift = ( int )myPoint.x() - ( mHighlightSymbol.width() / 2 );
      int yShift = ( int )myPoint.y() - ( mHighlightSymbol.height() / 2 );
      thePainter->drawPixmap( xShift, yShift, mHighlightSymbol );
    }
  }
}
  mConfiguration.setApplyPathRulesToDocs( chkboxApplyPathRulesToDocs->isChecked() );
}

/**
 * Slot called when the index changes for the cboxEventImagePathField combo box.
 * \param index - The index of the new selected item
 */
void eVisGenericEventBrowserGui::cboxEventImagePathField_currentIndexChanged( int index )
{
  Q_UNUSED( index )
  if ( !mIgnoreEvent )
  {
    mConfiguration.setEventImagePathField( cboxEventImagePathField->currentText() );

    QgsFields myFields = mVectorLayer->fields();
    QgsFeature *myFeature = featureAtId( mFeatureIds.at( mCurrentFeatureIndex ) );

    if ( !myFeature )
      return;

    QgsAttributes myAttrs = myFeature->attributes();
    for ( int i = 0; i < myAttrs.count(); ++i )
    {
      if ( myFields.at( i ).name() == cboxEventImagePathField->currentText() )
      {
        mEventImagePath = myAttrs.at( i ).toString();
      }
    }
  }
}