Exemplo n.º 1
0
GEOSGeometry *_project_line_string(GEOSContextHandle_t handle,
                                   GEOSGeometry *g_line_string,
                                   Interpolator *interpolator,
                                   GEOSGeometry *g_domain, double threshold)
{
    const GEOSCoordSequence *src_coords = GEOSGeom_getCoordSeq_r(handle, g_line_string);
    unsigned int src_size, src_idx;

    
    const GEOSPreparedGeometry *gp_domain = GEOSPrepare_r(handle, g_domain);

    GEOSCoordSeq_getSize_r(handle, src_coords, &src_size); // check exceptions

    LineAccumulator lines;

    for(src_idx = 1; src_idx < src_size; src_idx++)
    {
        _project_segment(handle, src_coords, src_idx - 1, src_idx,
                      interpolator, gp_domain, threshold, lines);
    }

    GEOSPreparedGeom_destroy_r(handle, gp_domain);

    return lines.as_geom(handle);
}
Exemplo n.º 2
0
st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
{
  const GEOSCoordSequence* cs;
  unsigned int len;
  unsigned int i;
  RGeo_Coordseq_Hash_Struct hash_struct;

  if (geom) {
    cs = GEOSGeom_getCoordSeq_r(context, geom);
    if (cs) {
      if (GEOSCoordSeq_getSize_r(context, cs, &len)) {
        for (i=0; i<len; ++i) {
          if (GEOSCoordSeq_getX_r(context, cs, i, &hash_struct.x)) {
            if (GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.y)) {
              if (!GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.z)) {
                hash_struct.z = 0;
              }
              hash_struct.seed_hash = hash;
              hash = rb_memhash(&hash_struct, sizeof(RGeo_Coordseq_Hash_Struct));
            }
          }
        }
      }
    }
  }
  return hash;
}
Exemplo n.º 3
0
BOX3D computeBounds(GEOSContextHandle_t ctx, GEOSGeometry const *geometry)
{
    uint32_t numInputDims;
    BOX3D output;


    GEOSGeometry const* ring = GEOSGetExteriorRing_r(ctx,
        geometry);
    GEOSCoordSequence const* coords = GEOSGeom_getCoordSeq_r(ctx,
        ring);

    GEOSCoordSeq_getDimensions_r(ctx, coords, &numInputDims);

    uint32_t count(0);
    GEOSCoordSeq_getSize_r(ctx, coords, &count);

    double x(0.0);
    double y(0.0);
    double z(0.0);
    for (unsigned i = 0; i < count; ++i)
    {
        GEOSCoordSeq_getOrdinate_r(ctx, coords, i, 0, &x);
        GEOSCoordSeq_getOrdinate_r(ctx, coords, i, 1, &y);
        if (numInputDims > 2)
            GEOSCoordSeq_getOrdinate_r(ctx, coords, i, 2, &z);
        output.grow(x, y, z);
    }
    return output;
}
Exemplo n.º 4
0
BOX3D Polygon::bounds() const
{
    uint32_t numInputDims;
    BOX3D output;

    GEOSGeometry* boundary = GEOSGeom_clone_r(m_ctx, m_geom);

    // Smash out multi*
    if (GEOSGeomTypeId_r(m_ctx, m_geom) > 3)
        boundary = GEOSEnvelope_r(m_ctx, m_geom);

    GEOSGeometry const* ring = GEOSGetExteriorRing_r(m_ctx, boundary);
    GEOSCoordSequence const* coords = GEOSGeom_getCoordSeq_r(m_ctx, ring);

    GEOSCoordSeq_getDimensions_r(m_ctx, coords, &numInputDims);

    uint32_t count(0);
    GEOSCoordSeq_getSize_r(m_ctx, coords, &count);

    double x(0.0);
    double y(0.0);
    double z(0.0);
    for (unsigned i = 0; i < count; ++i)
    {
        GEOSCoordSeq_getOrdinate_r(m_ctx, coords, i, 0, &x);
        GEOSCoordSeq_getOrdinate_r(m_ctx, coords, i, 1, &y);
        if (numInputDims > 2)
            GEOSCoordSeq_getOrdinate_r(m_ctx, coords, i, 2, &z);
        output.grow(x, y, z);
    }
    GEOSGeom_destroy_r(m_ctx, boundary);

    return output;
}
Exemplo n.º 5
0
static VALUE method_line_string_points(VALUE self)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    GEOSContextHandle_t self_context = self_data->geos_context;
    const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
    if (coord_seq) {
      char has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
      unsigned int size;
      if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
        result = rb_ary_new2(size);
        double x, y, z;
        unsigned int i;
        for (i=0; i<size; ++i) {
          VALUE point = get_point_from_coordseq(self, coord_seq, i, has_z);
          if (!NIL_P(point)) {
            rb_ary_store(result, i, point);
          }
        }
      }
    }
  }
  return result;
}
Exemplo n.º 6
0
static VALUE method_line_string_point_n(VALUE self, VALUE n)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    GEOSContextHandle_t self_context = self_data->geos_context;
    const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
    if (coord_seq) {
      char has_z = (char)(RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
      int si = NUM2INT(n);
      if (si >= 0) {
        unsigned int i = si;
        unsigned int size;
        if (GEOSCoordSeq_getSize_r(self_context, coord_seq, &size)) {
          if (i < size) {
            unsigned int dims;
            result = get_point_from_coordseq(self, coord_seq, i, has_z);
          }
        }
      }
    }
  }
  return result;
}
Exemplo n.º 7
0
BOX3D Crop::computeBounds(GEOSGeometry const *geometry)
{
    uint32_t numInputDims;
    BOX3D output;

#ifdef PDAL_HAVE_GEOS

    GEOSGeometry const* ring = GEOSGetExteriorRing_r(m_geosEnvironment,
        geometry);
    GEOSCoordSequence const* coords = GEOSGeom_getCoordSeq_r(m_geosEnvironment,
        ring);

    GEOSCoordSeq_getDimensions_r(m_geosEnvironment, coords, &numInputDims);
    log()->get(LogLevel::Debug) << "Inputted WKT had " << numInputDims <<
        " dimensions" <<std::endl;

    uint32_t count(0);
    GEOSCoordSeq_getSize_r(m_geosEnvironment, coords, &count);

    double x(0.0);
    double y(0.0);
    double z(0.0);
    for (unsigned i = 0; i < count; ++i)
    {
        GEOSCoordSeq_getOrdinate_r(m_geosEnvironment, coords, i, 0, &x);
        GEOSCoordSeq_getOrdinate_r(m_geosEnvironment, coords, i, 1, &y);
        if (numInputDims > 2)
            GEOSCoordSeq_getOrdinate_r(m_geosEnvironment, coords, i, 2, &z);
        output.grow(x, y, z);
    }
#else
    boost::ignore_unused_variable_warning(geometry);
#endif
    return output;
}
Exemplo n.º 8
0
void Point::update(const std::string& wkt_or_json, SpatialReference ref)
{

    Geometry::update(wkt_or_json, ref);

    int t = GEOSGeomTypeId_r(m_geoserr.ctx(), m_geom.get());
    if (t == -1)
        throw pdal_error("Unable to fetch geometry point type");
    if (t > 0)
        throw pdal_error("Geometry type is not point!");

    int nGeometries = GEOSGetNumGeometries_r(m_geoserr.ctx(), m_geom.get());
    if (nGeometries > 1)
        throw pdal_error("Geometry count is > 1!");

    const GEOSGeometry* g = GEOSGetGeometryN_r(m_geoserr.ctx(), m_geom.get(), 0);

    GEOSCoordSequence const* coords = GEOSGeom_getCoordSeq_r(m_geoserr.ctx(),  g);

    uint32_t numInputDims;
    GEOSCoordSeq_getDimensions_r(m_geoserr.ctx(), coords, &numInputDims);

    uint32_t count(0);
    GEOSCoordSeq_getSize_r(m_geoserr.ctx(), coords, &count);
    if (count == 0)
        throw pdal_error("No coordinates in geometry!");

    for (unsigned i = 0; i < count; ++i)
    {
        GEOSCoordSeq_getOrdinate_r(m_geoserr.ctx(), coords, i, 0, &x);
        GEOSCoordSeq_getOrdinate_r(m_geoserr.ctx(), coords, i, 1, &y);
        if (numInputDims > 2)
            GEOSCoordSeq_getOrdinate_r(m_geoserr.ctx(), coords, i, 2, &z);
    }

}
Exemplo n.º 9
0
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
{
  VALUE result;
  const GEOSCoordSequence* cs1;
  const GEOSCoordSequence* cs2;
  unsigned int len1;
  unsigned int len2;
  unsigned int i;
  double val1, val2;

  result = Qnil;
  if (geom1 && geom2) {
    cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
    cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
    if (cs1 && cs2) {
      len1 = 0;
      len2 = 0;
      if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
        if (len1 == len2) {
          result = Qtrue;
          for (i=0; i<len1; ++i) {
            if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
              if (val1 == val2) {
                if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) {
                  if (val1 == val2) {
                    if (check_z) {
                      val1 = 0;
                      if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) {
                        result = Qnil;
                        break;
                      }
                      val2 = 0;
                      if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) {
                        result = Qnil;
                        break;
                      }
                      if (val1 != val2) {
                        result = Qfalse;
                        break;
                      }
                    }
                  }
                  else {  // Y coords are different
                    result = Qfalse;
                    break;
                  }
                }
                else {  // Failed to get Y coords
                  result = Qnil;
                  break;
                }
              }
              else {  // X coords are different
                result = Qfalse;
                break;
              }
            }
            else {  // Failed to get X coords
              result = Qnil;
              break;
            }
          }  // Iteration over coords
        }
        else {  // Lengths are different
          result = Qfalse;
        }
      }
    }
  }
  return result;
}
Exemplo n.º 10
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
}
Exemplo n.º 11
0
void Layer::chopFeaturesAtRepeatDistance()
{
    GEOSContextHandle_t geosctxt = geosContext();
    QLinkedList<FeaturePart*> * newFeatureParts = new QLinkedList<FeaturePart*>;
    while ( !featureParts->isEmpty() )
    {
        FeaturePart* fpart = featureParts->takeFirst();
        const GEOSGeometry* geom = fpart->geos();
        double chopInterval = fpart->getFeature()->repeatDistance();
        if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
        {

            double bmin[2], bmax[2];
            fpart->getBoundingBox( bmin, bmax );
            rtree->Remove( bmin, bmax, fpart );

            const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosctxt, geom );

            // get number of points
            unsigned int n;
            GEOSCoordSeq_getSize_r( geosctxt, cs, &n );

            // Read points
            std::vector<Point> points( n );
            for ( unsigned int i = 0; i < n; ++i )
            {
                GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
                GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
            }

            // Cumulative length vector
            std::vector<double> len( n, 0 );
            for ( unsigned int i = 1; i < n; ++i )
            {
                double dx = points[i].x - points[i - 1].x;
                double dy = points[i].y - points[i - 1].y;
                len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
            }

            // Walk along line
            unsigned int cur = 0;
            double lambda = 0;
            std::vector<Point> part;
            for ( ;; )
            {
                lambda += chopInterval;
                for ( ; cur < n && lambda > len[cur]; ++cur )
                {
                    part.push_back( points[cur] );
                }
                if ( cur >= n )
                {
                    break;
                }
                double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
                Point p;
                p.x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
                p.y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
                part.push_back( p );
                GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
                for ( std::size_t i = 0; i < part.size(); ++i )
                {
                    GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
                    GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
                }

                GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
                FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
                newFeatureParts->append( newfpart );
                newfpart->getBoundingBox( bmin, bmax );
                rtree->Insert( bmin, bmax, newfpart );
                part.clear();
                part.push_back( p );
            }
            // Create final part
            part.push_back( points[n - 1] );
            GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
            for ( std::size_t i = 0; i < part.size(); ++i )
            {
                GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
                GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
            }

            GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
            FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
            newFeatureParts->append( newfpart );
            newfpart->getBoundingBox( bmin, bmax );
            rtree->Insert( bmin, bmax, newfpart );
        }
        else
        {
            newFeatureParts->append( fpart );
        }
    }

    delete featureParts;
    featureParts = newFeatureParts;
}
Exemplo n.º 12
0
Q_NOWARN_UNREACHABLE_POP

// Return Nth vertex in GEOSGeometry as a POINT.
// May return NULL if the geometry has NO vertexex.
static GEOSGeometry *LWGEOM_GEOS_getPointN( const GEOSGeometry *g_in, uint32_t n )
{
  GEOSContextHandle_t handle = QgsGeos::getGEOSHandler();

  uint32_t dims;
  const GEOSCoordSequence *seq_in = nullptr;
  GEOSCoordSeq seq_out;
  double val;
  uint32_t sz;
  int gn;
  GEOSGeometry *ret = nullptr;

  switch ( GEOSGeomTypeId_r( handle, g_in ) )
  {
    case GEOS_MULTIPOINT:
    case GEOS_MULTILINESTRING:
    case GEOS_MULTIPOLYGON:
    case GEOS_GEOMETRYCOLLECTION:
    {
      for ( gn = 0; gn < GEOSGetNumGeometries_r( handle, g_in ); ++gn )
      {
        const GEOSGeometry *g = GEOSGetGeometryN_r( handle, g_in, gn );
        ret = LWGEOM_GEOS_getPointN( g, n );
        if ( ret ) return ret;
      }
      break;
    }

    case GEOS_POLYGON:
    {
      ret = LWGEOM_GEOS_getPointN( GEOSGetExteriorRing_r( handle, g_in ), n );
      if ( ret ) return ret;
      for ( gn = 0; gn < GEOSGetNumInteriorRings_r( handle, g_in ); ++gn )
      {
        const GEOSGeometry *g = GEOSGetInteriorRingN_r( handle, g_in, gn );
        ret = LWGEOM_GEOS_getPointN( g, n );
        if ( ret ) return ret;
      }
      break;
    }

    case GEOS_POINT:
    case GEOS_LINESTRING:
    case GEOS_LINEARRING:
      break;

  }

  seq_in = GEOSGeom_getCoordSeq_r( handle, g_in );
  if ( ! seq_in ) return nullptr;
  if ( ! GEOSCoordSeq_getSize_r( handle, seq_in, &sz ) ) return nullptr;
  if ( ! sz ) return nullptr;

  if ( ! GEOSCoordSeq_getDimensions_r( handle, seq_in, &dims ) ) return nullptr;

  seq_out = GEOSCoordSeq_create_r( handle, 1, dims );
  if ( ! seq_out ) return nullptr;

  if ( ! GEOSCoordSeq_getX_r( handle, seq_in, n, &val ) ) return nullptr;
  if ( ! GEOSCoordSeq_setX_r( handle, seq_out, n, val ) ) return nullptr;
  if ( ! GEOSCoordSeq_getY_r( handle, seq_in, n, &val ) ) return nullptr;
  if ( ! GEOSCoordSeq_setY_r( handle, seq_out, n, val ) ) return nullptr;
  if ( dims > 2 )
  {
    if ( ! GEOSCoordSeq_getZ_r( handle, seq_in, n, &val ) ) return nullptr;
    if ( ! GEOSCoordSeq_setZ_r( handle, seq_out, n, val ) ) return nullptr;
  }

  return GEOSGeom_createPoint_r( handle, seq_out );
}
Exemplo n.º 13
0
void coordseq_to_terms(GEOSCommand *command) {

	GEOSContextHandle_t handle = command->driver_data->handle;
	GEOSCoordSequence *coordSeq;
	unsigned int dims = 2;

	ERL_READ_PTR_GEOSCOORDSEQUENCE(command, coordSeq);
	//ERL_READ_INT(command, dims);
	
	unsigned int size;
	if(GEOSCoordSeq_getSize_r(handle, coordSeq, &size)==0) {
		erl_send_error(command, "invalidcs");
		return;
	}
	//if(GEOSCoordSeq_getDimensions_r(handle, coordSeq,&dims)==0) {
	//	erl_send_error(command, "invalidcs");
	//	return;
	//} always return 3
	
	int allocSize = 7 + (size * (dims * 2 + 2));
	//int allocSize = 6 + (dims*2 + 2) * size + 1;


	double *digits = driver_alloc(sizeof(double) * dims * size);

	memset(digits, 0, sizeof(double) * dims * size);

	ErlDrvTermData *terms = driver_alloc(sizeof(ErlDrvTermData) * (allocSize));

	terms[0] = ERL_DRV_ATOM;
	terms[1] = driver_mk_atom("ok");

	int pos = 2;
	int i,d = 0;

	for(i = 0; i < size; i++) {

		GEOSCoordSeq_getX_r(handle,coordSeq,i, &digits[d]);

		terms[pos++] = ERL_DRV_FLOAT;
		terms[pos++] = (ErlDrvTermData) &digits[d];
		d++;

		if(dims >= 2) {
			GEOSCoordSeq_getY_r(handle,coordSeq,i, &digits[d]);
			terms[pos++] = ERL_DRV_FLOAT;
			terms[pos++] = (ErlDrvTermData) &digits[d];
			d++;
		}
		if(dims >= 3) {
			GEOSCoordSeq_getZ_r(handle,coordSeq,i, &digits[d]);
			terms[pos++] = ERL_DRV_FLOAT;
			terms[pos++] = (ErlDrvTermData) &digits[d];
			d++;
		}
		terms[pos++] = ERL_DRV_TUPLE;
		terms[pos++] = dims;
	
	}

	terms[pos++] = ERL_DRV_NIL;
	terms[pos++] = ERL_DRV_LIST;
	terms[pos++] = size+1;

	terms[pos++] = ERL_DRV_TUPLE;
	terms[pos] = 2;

  	driver_output_term(command->driver_data->port, terms, pos+1);

	driver_free(digits);
	driver_free(terms);
}
Exemplo n.º 14
0
SEXP rgeos_geosring2Polygon(SEXP env, GEOSGeom lr, int hole) {
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    int pc=0;
    
    GEOSCoordSeq s = (GEOSCoordSequence *) GEOSGeom_getCoordSeq_r(GEOShandle, lr);
    if (s == NULL) 
        error("rgeos_geosring2Polygon: CoordSeq failure");
    
    unsigned int n;
    if (GEOSCoordSeq_getSize_r(GEOShandle, s, &n) == 0)
        error("rgeos_geosring2Polygon: CoordSeq failure");
    
    // Get coordinates
    SEXP crd;
    PROTECT(crd = rgeos_crdMatFixDir(PROTECT(rgeos_CoordSeq2crdMat(env, s, FALSE, hole)), hole)); pc += 2;
    
    // Calculate area
    GEOSGeom p = GEOSGeom_createPolygon_r(GEOShandle,GEOSGeom_clone_r(GEOShandle,lr),NULL,0);
    if (p == NULL) 
        error("rgeos_geosring2Polygon: unable to create polygon");
    
    SEXP area;
    PROTECT(area = NEW_NUMERIC(1)); pc++;
    NUMERIC_POINTER(area)[0] = 0.0;
    if (!GEOSArea_r(GEOShandle, p, NUMERIC_POINTER(area)))
        error("rgeos_geosring2Polygon: area calculation failure");
    
    
    // Calculate label position
    SEXP labpt;
    PROTECT(labpt = NEW_NUMERIC(2)); pc++;
    
    GEOSGeom centroid = GEOSGetCentroid_r(GEOShandle, p);
    double xc, yc;
    rgeos_Pt2xy(env, centroid, &xc, &yc);
    
    if (!R_FINITE(xc) || !R_FINITE(yc)) {
        xc = 0.0;
        yc = 0.0;
        for(int i=0; i != n; i++) {
            xc += NUMERIC_POINTER(crd)[i];
            yc += NUMERIC_POINTER(crd)[(int) (n) +i];
        }
        
        xc /= n;
        yc /= n;
    }
    
    NUMERIC_POINTER(labpt)[0] = xc;
    NUMERIC_POINTER(labpt)[1] = yc;
    
    GEOSGeom_destroy_r(GEOShandle, centroid);
    GEOSGeom_destroy_r(GEOShandle, p);
    
    // Get ring direction
    SEXP ringDir;
    PROTECT(ringDir = NEW_INTEGER(1)); pc++;
    INTEGER_POINTER(ringDir)[0] = hole ? -1 : 1;
    
    // Get hole status
    SEXP Hole;
    PROTECT(Hole = NEW_LOGICAL(1)); pc++;
    LOGICAL_POINTER(Hole)[0] = hole;
    
    SEXP ans;
    PROTECT(ans = NEW_OBJECT(MAKE_CLASS("Polygon"))); pc++;    
    SET_SLOT(ans, install("ringDir"), ringDir);
    SET_SLOT(ans, install("labpt"), labpt);
    SET_SLOT(ans, install("area"), area);
    SET_SLOT(ans, install("hole"), Hole);
    SET_SLOT(ans, install("coords"), crd);
    
    SEXP valid;
    PROTECT(valid = SP_PREFIX(Polygon_validate_c)(ans)); pc++;
    if (!isLogical(valid)) {
        UNPROTECT(pc);
        if (isString(valid)) 
            error(CHAR(STRING_ELT(valid, 0)));
        else 
            error("invalid Polygon object");
    }
    
    UNPROTECT(pc);
    return(ans);
}
Exemplo n.º 15
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;
    }
  }
}