Esempio n. 1
0
QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer, const QgsPoint& layerPoint )
{
  // Calculate derived attributes and insert:
  // measure distance or area depending on geometry type
  QMap< QString, QString > derivedAttributes;

  // init distance/area calculator
  QString ellipsoid = QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE );
  QgsDistanceArea calc;
  calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() );
  calc.setEllipsoid( ellipsoid );
  calc.setSourceCrs( layer->crs().srsid() );

  QgsWKBTypes::Type wkbType = QgsWKBTypes::NoGeometry;
  QGis::GeometryType geometryType = QGis::NoGeometry;

  QgsVertexId vId;
  QgsPointV2 closestPoint;
  if ( feature->constGeometry() )
  {
    geometryType = feature->constGeometry()->type();
    wkbType = feature->constGeometry()->geometry()->wkbType();
    //find closest vertex to clicked point
    closestPoint = QgsGeometryUtils::closestVertex( *feature->constGeometry()->geometry(), QgsPointV2( layerPoint.x(), layerPoint.y() ), vId );
  }

  if ( QgsWKBTypes::isMultiType( wkbType ) )
  {
    QString str = QLocale::system().toString( static_cast<QgsGeometryCollectionV2*>( feature->constGeometry()->geometry() )->numGeometries() );
    derivedAttributes.insert( tr( "Parts" ), str );
    str = QLocale::system().toString( vId.part + 1 );
    derivedAttributes.insert( tr( "Part number" ), str );
  }

  if ( geometryType == QGis::Line )
  {
    const QgsPolyline &pline = feature->constGeometry()->asPolyline();
    double dist = calc.measureLength( feature->constGeometry() );
    QGis::UnitType myDisplayUnits;
    convertMeasurement( calc, dist, myDisplayUnits, false );
    QString str = calc.textUnit( dist, 3, myDisplayUnits, false );  // dist and myDisplayUnits are out params
    derivedAttributes.insert( tr( "Length" ), str );
    str = QLocale::system().toString( pline.size() );
    derivedAttributes.insert( tr( "Vertices" ), str );

    //add details of closest vertex to identify point
    closestVertexAttributes( *feature->constGeometry()->geometry(), vId, layer, derivedAttributes );

    if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString )
    {
      // Add the start and end points in as derived attributes
      QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, pline.first() );
      str = QLocale::system().toString( pnt.x(), 'g', 10 );
      derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str );
      str = QLocale::system().toString( pnt.y(), 'g', 10 );
      derivedAttributes.insert( tr( "firstY" ), str );
      pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, pline.last() );
      str = QLocale::system().toString( pnt.x(), 'g', 10 );
      derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str );
      str = QLocale::system().toString( pnt.y(), 'g', 10 );
      derivedAttributes.insert( tr( "lastY" ), str );
    }
  }
  else if ( geometryType == QGis::Polygon )
  {
    double area = calc.measureArea( feature->constGeometry() );
    double perimeter = calc.measurePerimeter( feature->constGeometry() );
    QGis::UnitType myDisplayUnits;
    convertMeasurement( calc, area, myDisplayUnits, true );  // area and myDisplayUnits are out params
    QString str = calc.textUnit( area, 3, myDisplayUnits, true );
    derivedAttributes.insert( tr( "Area" ), str );
    convertMeasurement( calc, perimeter, myDisplayUnits, false );  // perimeter and myDisplayUnits are out params
    str = calc.textUnit( perimeter, 3, myDisplayUnits, false );
    derivedAttributes.insert( tr( "Perimeter" ), str );

    str = QLocale::system().toString( feature->constGeometry()->geometry()->nCoordinates() );
    derivedAttributes.insert( tr( "Vertices" ), str );

    //add details of closest vertex to identify point
    closestVertexAttributes( *feature->constGeometry()->geometry(), vId, layer, derivedAttributes );
  }
  else if ( geometryType == QGis::Point &&
            QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::Point )
  {
    // Include the x and y coordinates of the point as a derived attribute
    QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->constGeometry()->asPoint() );
    QString str = QLocale::system().toString( pnt.x(), 'g', 10 );
    derivedAttributes.insert( "X", str );
    str = QLocale::system().toString( pnt.y(), 'g', 10 );
    derivedAttributes.insert( "Y", str );

    if ( QgsWKBTypes::hasZ( wkbType ) )
    {
      str = QLocale::system().toString( static_cast<QgsPointV2*>( feature->constGeometry()->geometry() )->z(), 'g', 10 );
      derivedAttributes.insert( "Z", str );
    }
    if ( QgsWKBTypes::hasM( wkbType ) )
    {
      str = QLocale::system().toString( static_cast<QgsPointV2*>( feature->constGeometry()->geometry() )->m(), 'g', 10 );
      derivedAttributes.insert( "M", str );
    }
  }

  return derivedAttributes;
}
Esempio n. 2
0
QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer, const QgsPoint& layerPoint )
{
  // Calculate derived attributes and insert:
  // measure distance or area depending on geometry type
  QMap< QString, QString > derivedAttributes;

  // init distance/area calculator
  QString ellipsoid = QgsProject::instance()->ellipsoid();
  QgsDistanceArea calc;
  calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() );
  calc.setEllipsoid( ellipsoid );
  calc.setSourceCrs( layer->crs().srsid() );

  QgsWkbTypes::Type wkbType = QgsWkbTypes::NoGeometry;
  QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::NullGeometry;

  QgsVertexId vId;
  QgsPointV2 closestPoint;
  if ( feature->hasGeometry() )
  {
    geometryType = feature->geometry().type();
    wkbType = feature->geometry().geometry()->wkbType();
    //find closest vertex to clicked point
    closestPoint = QgsGeometryUtils::closestVertex( *feature->geometry().geometry(), QgsPointV2( layerPoint.x(), layerPoint.y() ), vId );
  }

  if ( QgsWkbTypes::isMultiType( wkbType ) )
  {
    QString str = QLocale::system().toString( static_cast<const QgsGeometryCollection*>( feature->geometry().geometry() )->numGeometries() );
    derivedAttributes.insert( tr( "Parts" ), str );
    str = QLocale::system().toString( vId.part + 1 );
    derivedAttributes.insert( tr( "Part number" ), str );
  }

  if ( geometryType == QgsWkbTypes::LineGeometry )
  {
    double dist = calc.measureLength( feature->geometry() );
    dist = calc.convertLengthMeasurement( dist, displayDistanceUnits() );
    QString str = formatDistance( dist );
    derivedAttributes.insert( tr( "Length" ), str );

    const QgsCurve* curve = dynamic_cast< const QgsCurve* >( feature->geometry().geometry() );
    if ( curve )
    {
      str = QLocale::system().toString( curve->nCoordinates() );
      derivedAttributes.insert( tr( "Vertices" ), str );

      //add details of closest vertex to identify point
      closestVertexAttributes( *curve, vId, layer, derivedAttributes );

      // Add the start and end points in as derived attributes
      QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( curve->startPoint().x(), curve->startPoint().y() ) );
      str = formatXCoordinate( pnt );
      derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str );
      str = formatYCoordinate( pnt );
      derivedAttributes.insert( tr( "firstY" ), str );
      pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( curve->endPoint().x(), curve->endPoint().y() ) );
      str = formatXCoordinate( pnt );
      derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str );
      str = formatYCoordinate( pnt );
      derivedAttributes.insert( tr( "lastY" ), str );
    }
  }
  else if ( geometryType == QgsWkbTypes::PolygonGeometry )
  {
    double area = calc.measureArea( feature->geometry() );
    area = calc.convertAreaMeasurement( area, displayAreaUnits() );
    QString str = formatArea( area );
    derivedAttributes.insert( tr( "Area" ), str );

    double perimeter = calc.measurePerimeter( feature->geometry() );
    perimeter = calc.convertLengthMeasurement( perimeter, displayDistanceUnits() );
    str = formatDistance( perimeter );
    derivedAttributes.insert( tr( "Perimeter" ), str );

    str = QLocale::system().toString( feature->geometry().geometry()->nCoordinates() );
    derivedAttributes.insert( tr( "Vertices" ), str );

    //add details of closest vertex to identify point
    closestVertexAttributes( *feature->geometry().geometry(), vId, layer, derivedAttributes );
  }
  else if ( geometryType == QgsWkbTypes::PointGeometry &&
            QgsWkbTypes::flatType( wkbType ) == QgsWkbTypes::Point )
  {
    // Include the x and y coordinates of the point as a derived attribute
    QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->geometry().asPoint() );
    QString str = formatXCoordinate( pnt );
    derivedAttributes.insert( "X", str );
    str = formatYCoordinate( pnt );
    derivedAttributes.insert( "Y", str );

    if ( QgsWkbTypes::hasZ( wkbType ) )
    {
      str = QLocale::system().toString( static_cast<const QgsPointV2*>( feature->geometry().geometry() )->z(), 'g', 10 );
      derivedAttributes.insert( "Z", str );
    }
    if ( QgsWkbTypes::hasM( wkbType ) )
    {
      str = QLocale::system().toString( static_cast<const QgsPointV2*>( feature->geometry().geometry() )->m(), 'g', 10 );
      derivedAttributes.insert( "M", str );
    }
  }

  return derivedAttributes;
}