Пример #1
0
void Crop::ready(PointContext ctx)
{
#ifdef PDAL_HAVE_GEOS
    if (!m_poly.empty())
    {
        m_geosEnvironment = initGEOS_r(pdal::geos::_GEOSWarningHandler,
            pdal::geos::_GEOSErrorHandler);
        m_geosGeometry = GEOSGeomFromWKT_r(m_geosEnvironment, m_poly.c_str());
        if (!m_geosGeometry)
            throw pdal_error("unable to import polygon WKT");

        int gtype = GEOSGeomTypeId_r(m_geosEnvironment, m_geosGeometry);
        if (!(gtype == GEOS_POLYGON || gtype == GEOS_MULTIPOLYGON))
            throw pdal_error("input WKT was not a POLYGON or MULTIPOLYGON");

        char* out_wkt = GEOSGeomToWKT_r(m_geosEnvironment, m_geosGeometry);
        log()->get(LogLevel::Debug2) << "Ingested WKT for filters.crop: " <<
            std::string(out_wkt) <<std::endl;
        GEOSFree_r(m_geosEnvironment, out_wkt);

        if (!GEOSisValid_r(m_geosEnvironment, m_geosGeometry))
        {
            char* reason =
                GEOSisValidReason_r(m_geosEnvironment, m_geosGeometry);
            std::ostringstream oss;
            oss << "WKT is invalid: " << std::string(reason) << std::endl;
            GEOSFree_r(m_geosEnvironment, reason);
            throw pdal_error(oss.str());
        }

        m_geosPreparedGeometry =
            GEOSPrepare_r(m_geosEnvironment, m_geosGeometry);
        if (!m_geosPreparedGeometry)
            throw pdal_error("unable to prepare geometry for "
                "index-accelerated intersection");
        m_bounds = computeBounds(m_geosGeometry);
        log()->get(LogLevel::Debug) << "Computed bounds from given WKT: " <<
            m_bounds <<std::endl;
    }
    else
    {
        log()->get(LogLevel::Debug) << "Using simple bounds for "
            "filters.crop: " << m_bounds << std::endl;
    }

#endif
}
Пример #2
0
std::string Polygon::validReason() const
{
    int gtype = GEOSGeomTypeId_r(m_ctx, m_geom);
    if (gtype != GEOS_POLYGON && gtype != GEOS_MULTIPOLYGON)
        return std::string("Geometry is not Polygon or MultiPolygon");

    char *reason = GEOSisValidReason_r(m_ctx, m_geom);
    std::string output(reason);
    GEOSFree_r(m_ctx, reason);
    return output;
}
Пример #3
0
static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
{
  RGeo_FactoryData* self_data;
  GEOSContextHandle_t self_context;
  GEOSWKTWriter* wkt_writer;
  const GEOSGeometry* geom;
  VALUE result;
  char* str;
  size_t size;
  char has_3d;
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
  RGeo_Globals* globals;
  VALUE wkt_generator;
#endif

  self_data = RGEO_FACTORY_DATA_PTR(self);
  self_context = self_data->geos_context;
  has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
#ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
  if (has_3d) {
    globals = self_data->globals;
    wkt_generator = globals->psych_wkt_generator;
    if (NIL_P(wkt_generator)) {
      wkt_generator = rb_funcall(
        rb_const_get_at(globals->geos_module, rb_intern("Utils")),
        rb_intern("psych_wkt_generator"), 0);
      globals->psych_wkt_generator = wkt_generator;
    }
    return rb_funcall(wkt_generator, globals->id_generate, 1, obj);
  }
#endif
  wkt_writer = self_data->psych_wkt_writer;
  if (!wkt_writer) {
    wkt_writer = GEOSWKTWriter_create_r(self_context);
    if (has_3d) {
      GEOSWKTWriter_setOutputDimension_r(self_context, wkt_writer, 3);
    }
    self_data->psych_wkt_writer = wkt_writer;
  }
  result = Qnil;
  if (wkt_writer) {
    geom = rgeo_get_geos_geometry_safe(obj);
    if (geom) {
      str = GEOSWKTWriter_write_r(self_context, wkt_writer, geom);
      if (str) {
        result = rb_str_new2(str);
        GEOSFree_r(self_context, str);
      }
    }
  }
  return result;
}
Пример #4
0
std::string Polygon::wkt(double precision, bool bOutputZ) const
{
    GEOSWKTWriter *writer = GEOSWKTWriter_create_r(m_ctx);
    GEOSWKTWriter_setRoundingPrecision_r(m_ctx, writer, precision);
    if (bOutputZ)
        GEOSWKTWriter_setOutputDimension_r(m_ctx, writer, 3);

    char *smoothWkt = GEOSWKTWriter_write_r(m_ctx, writer, m_geom);
    std::string output(smoothWkt);
    GEOSFree_r(m_ctx, smoothWkt);
    GEOSWKTWriter_destroy_r(m_ctx, writer);
    return output;
}
Пример #5
0
static VALUE method_geometry_as_text(VALUE self)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
    GEOSWKTWriter* wkt_writer = factory_data->wkt_writer;
    GEOSContextHandle_t geos_context = self_data->geos_context;
    if (!wkt_writer) {
      wkt_writer = GEOSWKTWriter_create_r(geos_context);
      factory_data->wkt_writer = wkt_writer;
    }
    char* str = GEOSWKTWriter_write_r(geos_context, wkt_writer, self_geom);
    if (str) {
      result = rb_str_new2(str);
      GEOSFree_r(geos_context, str);
    }
  }
  return result;
}
Пример #6
0
static VALUE method_geometry_as_binary(VALUE self)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;
  RGeo_FactoryData* factory_data;
  VALUE wkb_generator;
  GEOSWKBWriter* wkb_writer;
  GEOSContextHandle_t geos_context;
  size_t size;
  char* str;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    factory_data = RGEO_FACTORY_DATA_PTR(self_data->factory);
    wkb_generator = factory_data->wkrep_wkb_generator;
    if (!NIL_P(wkb_generator)) {
      result = rb_funcall(wkb_generator, factory_data->globals->id_generate, 1, self);
    }
    else {
      wkb_writer = factory_data->wkb_writer;
      geos_context = self_data->geos_context;
      if (!wkb_writer) {
        wkb_writer = GEOSWKBWriter_create_r(geos_context);
        factory_data->wkb_writer = wkb_writer;
      }
      str = (char*)GEOSWKBWriter_write_r(geos_context, wkb_writer, self_geom, &size);
      if (str) {
        result = rb_str_new(str, size);
        GEOSFree_r(geos_context, str);
      }
    }
  }
  return result;
}
Пример #7
0
void QgsGeometryValidator::run()
{
  mErrorCount = 0;
  QSettings settings;
  if ( settings.value( QStringLiteral( "/qgis/digitizing/validate_geometries" ), 1 ).toInt() == 2 )
  {
    char *r = nullptr;
    const GEOSGeometry *g0 = mG.asGeos();
    GEOSContextHandle_t handle = QgsGeometry::getGEOSHandler();
    if ( !g0 )
    {
      emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error:could not produce geometry for GEOS (check log window)" ) ) );
    }
    else
    {
      GEOSGeometry *g1 = nullptr;
      if ( GEOSisValidDetail_r( handle, g0, GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE, &r, &g1 ) != 1 )
      {
        if ( g1 )
        {
          const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( handle, g1 );

          unsigned int n;
          if ( GEOSCoordSeq_getSize_r( handle, cs, &n ) && n == 1 )
          {
            double x, y;
            GEOSCoordSeq_getX_r( handle, cs, 0, &x );
            GEOSCoordSeq_getY_r( handle, cs, 0, &y );
            emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error:%1" ).arg( r ), QgsPoint( x, y ) ) );
            mErrorCount++;
          }

          GEOSGeom_destroy_r( handle, g1 );
        }
        else
        {
          emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error:%1" ).arg( r ) ) );
          mErrorCount++;
        }

        GEOSFree_r( handle, r );
      }
    }

    return;
  }

  QgsDebugMsg( "validation thread started." );

  QgsWkbTypes::Type flatType = QgsWkbTypes::flatType( mG.wkbType() );
  //if ( flatType == QgsWkbTypes::Point || flatType == QgsWkbTypes::MultiPoint )
  //    break;
  if ( flatType == QgsWkbTypes::LineString )
  {
    validatePolyline( 0, mG.asPolyline() );
  }
  else if ( flatType == QgsWkbTypes::MultiLineString )
  {
    QgsMultiPolyline mp = mG.asMultiPolyline();
    for ( int i = 0; !mStop && i < mp.size(); i++ )
      validatePolyline( i, mp[i] );
  }
  else if ( flatType == QgsWkbTypes::Polygon )
  {
    validatePolygon( 0, mG.asPolygon() );
  }
  else if ( flatType == QgsWkbTypes::MultiPolygon )
  {
    QgsMultiPolygon mp = mG.asMultiPolygon();
    for ( int i = 0; !mStop && i < mp.size(); i++ )
    {
      validatePolygon( i, mp[i] );
    }

    for ( int i = 0; !mStop && i < mp.size(); i++ )
    {
      if ( mp[i].isEmpty() )
      {
        emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 has no rings" ).arg( i ) ) );
        mErrorCount++;
        continue;
      }

      for ( int j = i + 1;  !mStop && j < mp.size(); j++ )
      {
        if ( mp[j].isEmpty() )
          continue;

        if ( ringInRing( mp[i][0], mp[j][0] ) )
        {
          emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 inside polygon %2" ).arg( i ).arg( j ) ) );
          mErrorCount++;
        }
        else if ( ringInRing( mp[j][0], mp[i][0] ) )
        {
          emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 inside polygon %2" ).arg( j ).arg( i ) ) );
          mErrorCount++;
        }
        else
        {
          checkRingIntersections( i, 0, mp[i][0], j, 0, mp[j][0] );
        }
      }
    }
  }

  else if ( flatType == QgsWkbTypes::Unknown )
  {
    QgsDebugMsg( QObject::tr( "Unknown geometry type" ) );
    emit errorFound( QgsGeometry::Error( QObject::tr( "Unknown geometry type %1" ).arg( mG.wkbType() ) ) );
    mErrorCount++;
  }

  QgsDebugMsg( "validation finished." );

  if ( mStop )
  {
    emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry validation was aborted." ) ) );
  }
  else if ( mErrorCount > 0 )
  {
    emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry has %1 errors." ).arg( mErrorCount ) ) );
  }
#if 0
  else
  {
    emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry is valid." ) ) );
  }
#endif
}
Пример #8
0
void QgsGeometryValidator::run()
{
  mErrorCount = 0;
  switch ( mMethod )
  {
    case QgsGeometry::ValidatorGeos:
    {
      char *r = nullptr;
      geos::unique_ptr g0( mGeometry.exportToGeos() );
      GEOSContextHandle_t handle = QgsGeometry::getGEOSHandler();
      if ( !g0 )
      {
        emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error: could not produce geometry for GEOS (check log window)" ) ) );
      }
      else
      {
        GEOSGeometry *g1 = nullptr;
        char res = GEOSisValidDetail_r( handle, g0.get(), GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE, &r, &g1 );
        if ( res != 1 )
        {
          if ( g1 )
          {
            const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( handle, g1 );

            unsigned int n;
            if ( GEOSCoordSeq_getSize_r( handle, cs, &n ) && n == 1 )
            {
              double x, y;
              GEOSCoordSeq_getX_r( handle, cs, 0, &x );
              GEOSCoordSeq_getY_r( handle, cs, 0, &y );
              emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error: %1" ).arg( r ), QgsPointXY( x, y ) ) );
              mErrorCount++;
            }

            GEOSGeom_destroy_r( handle, g1 );
          }
          else
          {
            emit errorFound( QgsGeometry::Error( QObject::tr( "GEOS error: %1" ).arg( r ) ) );
            mErrorCount++;
          }

          GEOSFree_r( handle, r );
        }
      }

      break;
    }

    case QgsGeometry::ValidatorQgisInternal:
    {
      QgsWkbTypes::Type flatType = QgsWkbTypes::flatType( mGeometry.wkbType() );
      //if ( flatType == QgsWkbTypes::Point || flatType == QgsWkbTypes::MultiPoint )
      //    break;
      if ( flatType == QgsWkbTypes::LineString )
      {
        validatePolyline( 0, mGeometry.asPolyline() );
      }
      else if ( flatType == QgsWkbTypes::MultiLineString )
      {
        QgsMultiPolylineXY mp = mGeometry.asMultiPolyline();
        for ( int i = 0; !mStop && i < mp.size(); i++ )
          validatePolyline( i, mp[i] );
      }
      else if ( flatType == QgsWkbTypes::Polygon )
      {
        validatePolygon( 0, mGeometry.asPolygon() );
      }
      else if ( flatType == QgsWkbTypes::MultiPolygon )
      {
        QgsMultiPolygonXY mp = mGeometry.asMultiPolygon();
        for ( int i = 0; !mStop && i < mp.size(); i++ )
        {
          validatePolygon( i, mp[i] );
        }

        for ( int i = 0; !mStop && i < mp.size(); i++ )
        {
          if ( mp[i].isEmpty() )
          {
            emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 has no rings" ).arg( i ) ) );
            mErrorCount++;
            continue;
          }

          for ( int j = i + 1;  !mStop && j < mp.size(); j++ )
          {
            if ( mp[j].isEmpty() )
              continue;

            if ( ringInRing( mp[i][0], mp[j][0] ) )
            {
              emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 inside polygon %2" ).arg( i ).arg( j ) ) );
              mErrorCount++;
            }
            else if ( ringInRing( mp[j][0], mp[i][0] ) )
            {
              emit errorFound( QgsGeometry::Error( QObject::tr( "polygon %1 inside polygon %2" ).arg( j ).arg( i ) ) );
              mErrorCount++;
            }
            else
            {
              checkRingIntersections( i, 0, mp[i][0], j, 0, mp[j][0] );
            }
          }
        }
      }

      else if ( flatType == QgsWkbTypes::Unknown )
      {
        QgsDebugMsg( QObject::tr( "Unknown geometry type" ) );
        emit errorFound( QgsGeometry::Error( QObject::tr( "Unknown geometry type %1" ).arg( mGeometry.wkbType() ) ) );
        mErrorCount++;
      }

      if ( mStop )
      {
        emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry validation was aborted." ) ) );
      }
      else if ( mErrorCount > 0 )
      {
        emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry has %1 errors." ).arg( mErrorCount ) ) );
      }
#if 0
      else
      {
        emit errorFound( QgsGeometry::Error( QObject::tr( "Geometry is valid." ) ) );
      }
#endif
      break;
    }
  }
}