Exemple #1
0
void TestQgs3DUtils::testTransforms()
{
  QgsVector3D map123( 1, 2, 3 );

  QgsVector3D world123 = Qgs3DUtils::mapToWorldCoordinates( map123, QgsVector3D() );
  QCOMPARE( world123, QgsVector3D( 1, 3, -2 ) );

  QgsVector3D world123map = Qgs3DUtils::worldToMapCoordinates( world123, QgsVector3D() );
  QCOMPARE( world123map, map123 );

  // now with non-zero origin

  QgsVector3D origin( -10, -20, -30 );

  QgsVector3D world123x = Qgs3DUtils::mapToWorldCoordinates( map123, origin );
  QCOMPARE( world123x, QgsVector3D( 11, 33, -22 ) );

  QgsVector3D world123xmap = Qgs3DUtils::worldToMapCoordinates( world123x, origin );
  QCOMPARE( world123xmap, map123 );

  //
  // transform world point from one system to another
  //

  QgsVector3D worldPoint1( 5, 7, -6 );
  QgsVector3D origin1( 10, 20, 30 );
  QgsVector3D origin2( 1, 2, 3 );
  QgsVector3D worldPoint2 = Qgs3DUtils::transformWorldCoordinates( worldPoint1, origin1, QgsCoordinateReferenceSystem(), origin2, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext() );
  QCOMPARE( worldPoint2, QgsVector3D( 14, 34, -24 ) );
  // verify that both are the same map point
  QgsVector3D mapPoint1 = Qgs3DUtils::worldToMapCoordinates( worldPoint1, origin1 );
  QgsVector3D mapPoint2 = Qgs3DUtils::worldToMapCoordinates( worldPoint2, origin2 );
  QCOMPARE( mapPoint1, mapPoint2 );
}
Exemple #2
0
QgsVector3D Qgs3DUtils::mapToWorldCoordinates( const QgsVector3D &mapCoords, const QgsVector3D &origin )
{
  return QgsVector3D( mapCoords.x() - origin.x(),
                      mapCoords.z() - origin.z(),
                      -( mapCoords.y() - origin.y() ) );

}
void Qgs3DMapConfigWidget::apply()
{
  QgsRasterLayer *demLayer = qobject_cast<QgsRasterLayer *>( cboTerrainLayer->currentLayer() );

  bool needsUpdateOrigin = false;

  if ( demLayer )
  {
    bool tGenNeedsUpdate = true;
    if ( mMap->terrainGenerator()->type() == QgsTerrainGenerator::Dem )
    {
      // if we already have a DEM terrain generator, check whether there was actually any change
      QgsDemTerrainGenerator *oldDemTerrainGen = static_cast<QgsDemTerrainGenerator *>( mMap->terrainGenerator() );
      if ( oldDemTerrainGen->layer() == demLayer &&
           oldDemTerrainGen->resolution() == spinTerrainResolution->value() &&
           oldDemTerrainGen->skirtHeight() == spinTerrainSkirtHeight->value() )
        tGenNeedsUpdate = false;
    }

    if ( tGenNeedsUpdate )
    {
      QgsDemTerrainGenerator *demTerrainGen = new QgsDemTerrainGenerator;
      demTerrainGen->setCrs( mMap->crs(), QgsProject::instance()->transformContext() );
      demTerrainGen->setLayer( demLayer );
      demTerrainGen->setResolution( spinTerrainResolution->value() );
      demTerrainGen->setSkirtHeight( spinTerrainSkirtHeight->value() );
      mMap->setTerrainGenerator( demTerrainGen );
      needsUpdateOrigin = true;
    }
  }
  else if ( !demLayer && mMap->terrainGenerator()->type() != QgsTerrainGenerator::Flat )
  {
    QgsFlatTerrainGenerator *flatTerrainGen = new QgsFlatTerrainGenerator;
    flatTerrainGen->setCrs( mMap->crs() );
    flatTerrainGen->setExtent( mMainCanvas->fullExtent() );
    mMap->setTerrainGenerator( flatTerrainGen );
    needsUpdateOrigin = true;
  }

  if ( needsUpdateOrigin )
  {
    // reproject terrain's extent to map CRS
    QgsRectangle te = mMap->terrainGenerator()->extent();
    QgsCoordinateTransform terrainToMapTransform( mMap->terrainGenerator()->crs(), mMap->crs(), QgsProject::instance() );
    te = terrainToMapTransform.transformBoundingBox( te );

    QgsPointXY center = te.center();
    mMap->setOrigin( QgsVector3D( center.x(), center.y(), 0 ) );
  }

  mMap->setTerrainVerticalScale( spinTerrainScale->value() );
  mMap->setMapTileResolution( spinMapResolution->value() );
  mMap->setMaxTerrainScreenError( spinScreenError->value() );
  mMap->setMaxTerrainGroundError( spinGroundError->value() );
  mMap->setShowLabels( chkShowLabels->isChecked() );
  mMap->setShowTerrainTilesInfo( chkShowTileInfo->isChecked() );
  mMap->setShowTerrainBoundingBoxes( chkShowBoundingBoxes->isChecked() );
  mMap->setShowCameraViewCenter( chkShowCameraViewCenter->isChecked() );
}
void QgsCameraController::readXml( const QDomElement &elem )
{
  float x = elem.attribute( QStringLiteral( "x" ) ).toFloat();
  float y = elem.attribute( QStringLiteral( "y" ) ).toFloat();
  float elev = elem.attribute( QStringLiteral( "elev" ) ).toFloat();
  float dist = elem.attribute( QStringLiteral( "dist" ) ).toFloat();
  float pitch = elem.attribute( QStringLiteral( "pitch" ) ).toFloat();
  float yaw = elem.attribute( QStringLiteral( "yaw" ) ).toFloat();
  setLookingAtPoint( QgsVector3D( x, elev, y ), dist, pitch, yaw );
}
void QgsCameraController::setViewFromTop( float worldX, float worldY, float distance, float yaw )
{
  QgsCameraPose camPose;
  camPose.setCenterPoint( QgsVector3D( worldX, 0, worldY ) );
  camPose.setDistanceFromCenterPoint( distance );
  camPose.setHeadingAngle( yaw );

  // a basic setup to make frustum depth range long enough that it does not cull everything
  mCamera->setNearPlane( distance / 2 );
  mCamera->setFarPlane( distance * 2 );

  setCameraPose( camPose );
}
void QgsCameraController::updateCameraFromPose( bool centerPointChanged )
{
  if ( std::isnan( mCameraPose.centerPoint().x() ) || std::isnan( mCameraPose.centerPoint().y() ) || std::isnan( mCameraPose.centerPoint().z() ) )
  {
    // something went horribly wrong but we need to at least try to fix it somehow
    qDebug() << "camera position got NaN!";
    mCameraPose.setCenterPoint( QgsVector3D( 0, 0, 0 ) );
  }

  if ( mCameraPose.pitchAngle() > 180 )
    mCameraPose.setPitchAngle( 180 );  // prevent going over the head
  if ( mCameraPose.pitchAngle() < 0 )
    mCameraPose.setPitchAngle( 0 );   // prevent going over the head
  if ( mCameraPose.distanceFromCenterPoint() < 10 )
    mCameraPose.setDistanceFromCenterPoint( 10 );

  if ( mCamera )
    mCameraPose.updateCamera( mCamera );

  if ( mCamera && mTerrainEntity && centerPointChanged )
  {
    // figure out our distance from terrain and update the camera's view center
    // so that camera tilting and rotation is around a point on terrain, not an point at fixed elevation
    QVector3D intersectionPoint;
    QgsRayCastingUtils::Ray3D ray = QgsRayCastingUtils::rayForCameraCenter( mCamera );
    if ( mTerrainEntity->rayIntersection( ray, intersectionPoint ) )
    {
      float dist = ( intersectionPoint - mCamera->position() ).length();
      mCameraPose.setDistanceFromCenterPoint( dist );
      mCameraPose.setCenterPoint( QgsVector3D( intersectionPoint ) );
      mCameraPose.updateCamera( mCamera );
    }
  }

  emit cameraChanged();
}
Exemple #7
0
QgsVector3D Qgs3DUtils::worldToMapCoordinates( const QgsVector3D &worldCoords, const QgsVector3D &origin )
{
  return QgsVector3D( worldCoords.x() + origin.x(),
                      -worldCoords.z() + origin.y(),
                      worldCoords.y() + origin.z() );
}