Exemplo n.º 1
0
unsigned char* QgsGeometryAnalyzer::locateBetweenWkbString( unsigned char* ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure )
{
  int* nPoints = ( int* ) ptr;
  ptr += sizeof( int );
  double prevx = 0.0, prevy = 0.0, prevz = 0.0;
  double *x, *y, *z;
  QgsPolyline currentLine;

  QgsPoint pt1, pt2;
  bool measureInSegment; //true if measure is contained in the segment
  bool secondPointClipped; //true if second point is != segment endpoint


  for ( int i = 0; i < *nPoints; ++i )
  {
    x = ( double* )ptr;
    ptr += sizeof( double );
    y = ( double* )ptr;
    ptr += sizeof( double );
    z = ( double* ) ptr;
    ptr += sizeof( double );

    if ( i > 0 )
    {
      measureInSegment = clipSegmentByRange( prevx, prevy, prevz, *x, *y, *z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
      if ( measureInSegment )
      {
        if ( currentLine.size() < 1 ) //no points collected yet, so the first point needs to be added to the line
        {
          currentLine.append( pt1 );
        }

        if ( pt1 != pt2 ) //avoid duplicated entry if measure value equals m-value of vertex
        {
          currentLine.append( pt2 );
        }

        if ( secondPointClipped || i == *nPoints - 1 ) //close current segment
        {
          if ( currentLine.size() > 1 )
          {
            result.append( currentLine );
          }
          currentLine.clear();
        }
      }
    }
    prevx = *x; prevy = *y; prevz = *z;
  }
  return ptr;
}
Exemplo n.º 2
0
void TestQgsDistanceArea::measureAreaAndUnits()
{
  QgsDistanceArea da;
  da.setSourceCrs( 3452 );
  da.setEllipsoidalMode( false );
  da.setEllipsoid( "NONE" );
  QgsCoordinateReferenceSystem daCRS;
  daCRS.createFromSrsId( da.sourceCrsId() );
  QgsPolyline ring;
  ring << QgsPoint( 0, 0 )
  << QgsPoint( 1, 0 )
  << QgsPoint( 1, 1 )
  << QgsPoint( 2, 1 )
  << QgsPoint( 2, 2 )
  << QgsPoint( 0, 2 )
  << QgsPoint( 0, 0 );
  QgsPolygon poly;
  poly << ring;

  QgsGeometry polygon( QgsGeometry::fromPolygon( poly ) );

  // We check both the measured area AND the units, in case the logic regarding
  // ellipsoids and units changes in future
  double area = da.measureArea( &polygon );
  QgsUnitTypes::AreaUnit units = da.areaUnits();

  QgsDebugMsg( QString( "measured %1 in %2" ).arg( area ).arg( QgsUnitTypes::toString( units ) ) );

  QVERIFY(( qgsDoubleNear( area, 3.0, 0.00000001 ) && units == QgsUnitTypes::AreaSquareDegrees )
          || ( qgsDoubleNear( area, 37176087091.5, 0.1 ) && units == QgsUnitTypes::AreaSquareMeters ) );

  da.setEllipsoid( "WGS84" );
  area = da.measureArea( &polygon );
  units = da.areaUnits();

  QgsDebugMsg( QString( "measured %1 in %2" ).arg( area ).arg( QgsUnitTypes::toString( units ) ) );
  QVERIFY(( qgsDoubleNear( area, 3.0, 0.00000001 ) && units == QgsUnitTypes::AreaSquareDegrees )
          || ( qgsDoubleNear( area, 37176087091.5, 0.1 ) && units == QgsUnitTypes::AreaSquareMeters ) );

  da.setEllipsoidalMode( true );
  area = da.measureArea( &polygon );
  units = da.areaUnits();

  QgsDebugMsg( QString( "measured %1 in %2" ).arg( area ).arg( QgsUnitTypes::toString( units ) ) );
  // should always be in Meters Squared
  QGSCOMPARENEAR( area, 37416879192.9, 0.1 );
  QCOMPARE( units, QgsUnitTypes::AreaSquareMeters );

  // test converting the resultant area
  area = da.convertAreaMeasurement( area, QgsUnitTypes::AreaSquareMiles );
  QGSCOMPARENEAR( area, 14446.7378, 0.001 );

  // now try with a source CRS which is in feet
  ring.clear();
  ring << QgsPoint( 1850000, 4423000 )
  << QgsPoint( 1851000, 4423000 )
  << QgsPoint( 1851000, 4424000 )
  << QgsPoint( 1852000, 4424000 )
  << QgsPoint( 1852000, 4425000 )
  << QgsPoint( 1851000, 4425000 )
  << QgsPoint( 1850000, 4423000 );
  poly.clear();
  poly << ring;
  polygon = QgsGeometry::fromPolygon( poly );

  da.setSourceCrs( 27469 );
  da.setEllipsoidalMode( false );
  // measurement should be in square feet
  area = da.measureArea( &polygon );
  units = da.areaUnits();
  QgsDebugMsg( QString( "measured %1 in %2" ).arg( area ).arg( QgsUnitTypes::toString( units ) ) );
  QGSCOMPARENEAR( area, 2000000, 0.001 );
  QCOMPARE( units, QgsUnitTypes::AreaSquareFeet );

  // test converting the resultant area
  area = da.convertAreaMeasurement( area, QgsUnitTypes::AreaSquareYards );
  QGSCOMPARENEAR( area, 222222.2222, 0.001 );

  da.setEllipsoidalMode( true );
  // now should be in Square Meters again
  area = da.measureArea( &polygon );
  units = da.areaUnits();
  QgsDebugMsg( QString( "measured %1 in %2" ).arg( area ).arg( QgsUnitTypes::toString( units ) ) );
  QGSCOMPARENEAR( area, 184149.37, 1.0 );
  QCOMPARE( units, QgsUnitTypes::AreaSquareMeters );

  // test converting the resultant area
  area = da.convertAreaMeasurement( area, QgsUnitTypes::AreaSquareYards );
  QgsDebugMsg( QString( "measured %1 in sq yrds" ).arg( area ) );
  QGSCOMPARENEAR( area, 220240.8172549, 0.00001 );
}
Exemplo n.º 3
0
ErrorList topolTest::checkSegmentLength( double tolerance, QgsVectorLayer* layer1, QgsVectorLayer* layer2, bool isExtent )
{
  Q_UNUSED( layer1 );
  Q_UNUSED( layer2 );
  Q_UNUSED( isExtent );

  int i = 0;
  ErrorList errorList;
  QgsFeature f;


  QList<FeatureLayer>::Iterator it;
  QList<FeatureLayer>::ConstIterator FeatureListEnd = mFeatureList1.end();

  QgsPolygon pol;

  QgsMultiPolygon mpol;
  QgsPolyline segm;
  QgsPolyline ls;
  QgsMultiPolyline mls;
  QList<FeatureLayer> fls;
  TopolErrorShort* err;
  double distance;

  for ( it = mFeatureList1.begin(); it != FeatureListEnd; ++it )
  {
    if ( !( ++i % 100 ) )
    {
      emit progress( i );
    }

    if ( testCancelled() )
    {
      break;
    }

    QgsGeometry* g1 = it->feature.geometry();


    // switching by type here, because layer can contain both single and multi version geometries
    switch ( g1->wkbType() )
    {
      case QGis::WKBLineString:
      case QGis::WKBLineString25D:
        ls = g1->asPolyline();


        for ( int i = 1; i < ls.size(); ++i )
        {
          distance = sqrt( ls[i-1].sqrDist( ls[i] ) );
          if ( distance < tolerance )
          {
            fls.clear();
            fls << *it << *it;
            segm.clear();
            segm << ls[i-1] << ls[i];
            QgsGeometry* conflict = QgsGeometry::fromPolyline( segm );
            err = new TopolErrorShort( g1->boundingBox(), conflict, fls );
            //err = new TopolErrorShort(g1->boundingBox(), QgsGeometry::fromPolyline(segm), fls);
            errorList << err;
            //break on getting the first error
            break;
          }
        }
        break;

      case QGis::WKBPolygon:
      case QGis::WKBPolygon25D:
        pol = g1->asPolygon();

        for ( int i = 0; i < pol.size(); ++i )
        {
          for ( int j = 1; j < pol[i].size(); ++j )
          {
            distance =  sqrt( pol[i][j-1].sqrDist( pol[i][j] ) );
            if ( distance < tolerance )
            {
              fls.clear();
              fls << *it << *it;
              segm.clear();
              segm << pol[i][j-1] << pol[i][j];
              QgsGeometry* conflict = QgsGeometry::fromPolyline( segm );
              err = new TopolErrorShort( g1->boundingBox(), conflict, fls );
              errorList << err;
              //break on getting the first error
              break;
            }
          }
        }

        break;

      case QGis::WKBMultiLineString:
      case QGis::WKBMultiLineString25D:
        mls = g1->asMultiPolyline();

        for ( int k = 0; k < mls.size(); ++k )
        {
          QgsPolyline& ls = mls[k];
          for ( int i = 1; i < ls.size(); ++i )
          {
            distance = sqrt( ls[i-1].sqrDist( ls[i] ) );
            if ( distance < tolerance )
            {
              fls.clear();
              fls << *it << *it;
              segm.clear();
              segm << ls[i-1] << ls[i];
              QgsGeometry* conflict = QgsGeometry::fromPolyline( segm );
              err = new TopolErrorShort( g1->boundingBox(), conflict, fls );
              errorList << err;
              //break on getting the first error
              break;
            }
          }
        }
        break;

      case QGis::WKBMultiPolygon:
      case QGis::WKBMultiPolygon25D:
        mpol = g1->asMultiPolygon();

        for ( int k = 0; k < mpol.size(); ++k )
        {
          QgsPolygon& pol = mpol[k];
          for ( int i = 0; i < pol.size(); ++i )
          {
            for ( int j = 1; j < pol[i].size(); ++j )
            {
              distance = pol[i][j-1].sqrDist( pol[i][j] );
              if ( distance < tolerance )
              {
                fls.clear();
                fls << *it << *it;
                segm.clear();
                segm << pol[i][j-1] << pol[i][j];
                QgsGeometry* conflict = QgsGeometry::fromPolyline( segm );
                err = new TopolErrorShort( g1->boundingBox(), conflict, fls );
                errorList << err;
                //break on getting the first error
                break;
              }
            }
          }
        }
        break;

      default:
        continue;
    }
  }

  return errorList;
}