コード例 #1
0
ファイル: line_string.c プロジェクト: Epictetus/rgeo
static VALUE cmethod_create_line(VALUE module, VALUE factory, VALUE start, VALUE end)
{
  VALUE result = Qnil;
  RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
  char has_z = (char)(factory_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
  VALUE point_type = factory_data->globals->feature_point;
  GEOSContextHandle_t context = factory_data->geos_context;
  
  const GEOSGeometry* start_geom = rgeo_convert_to_geos_geometry(factory, start, point_type);
  if (start_geom) {
    const GEOSGeometry* end_geom = rgeo_convert_to_geos_geometry(factory, end, point_type);
    if (end_geom) {
      GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, 2, 3);
      if (coord_seq) {
        populate_geom_into_coord_seq(context, start_geom, coord_seq, 0, has_z);
        populate_geom_into_coord_seq(context, end_geom, coord_seq, 1, has_z);
        GEOSGeometry* geom = GEOSGeom_createLineString_r(context, coord_seq);
        if (geom) {
          result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_line);
        }
      }
    }
  }
  
  return result;
}
コード例 #2
0
ファイル: geometry.c プロジェクト: Open-Source-GIS/rgeo
static VALUE method_geometry_relate(VALUE self, VALUE rhs, VALUE pattern)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;
  const GEOSGeometry* rhs_geom;
  char val;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
    if (rhs_geom) {
      val = GEOSRelatePattern_r(self_data->geos_context, self_geom, rhs_geom, StringValuePtr(pattern));
      if (val == 0) {
        result = Qfalse;
      }
      else if (val == 1) {
        result = Qtrue;
      }
    }
  }
  return result;
}
コード例 #3
0
ファイル: geometry.c プロジェクト: Open-Source-GIS/rgeo
static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;
  const GEOSGeometry* rhs_geom;
  char val;
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
  const GEOSPreparedGeometry* prep;
#endif

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
    if (rhs_geom) {
#ifdef RGEO_GEOS_SUPPORTS_PREPARED2
      prep = rgeo_request_prepared_geometry(self_data);
      if (prep)
        val = GEOSPreparedOverlaps_r(self_data->geos_context, prep, rhs_geom);
      else
#endif
        val = GEOSOverlaps_r(self_data->geos_context, self_geom, rhs_geom);
      if (val == 0) {
        result = Qfalse;
      }
      else if (val == 1) {
        result = Qtrue;
      }
    }
  }
  return result;
}
コード例 #4
0
ファイル: geometry.c プロジェクト: Epictetus/rgeo
static VALUE method_geometry_sym_difference(VALUE self, VALUE rhs)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    VALUE factory = self_data->factory;
    const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
    if (rhs_geom) {
      result = rgeo_wrap_geos_geometry(factory, GEOSSymDifference_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
    }
  }
  return result;
}
コード例 #5
0
ファイル: geometry.c プロジェクト: Epictetus/rgeo
static VALUE method_geometry_distance(VALUE self, VALUE rhs)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
    if (rhs_geom) {
      double dist;
      if (GEOSDistance_r(self_data->geos_context, self_geom, rhs_geom, &dist)) {
        result = rb_float_new(dist);
      }
    }
  }
  return result;
}
コード例 #6
0
ファイル: geometry.c プロジェクト: Epictetus/rgeo
static VALUE method_geometry_overlaps(VALUE self, VALUE rhs)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    const GEOSGeometry* rhs_geom = rgeo_convert_to_geos_geometry(self_data->factory, rhs, Qnil);
    if (rhs_geom) {
      char val = GEOSOverlaps_r(self_data->geos_context, self_geom, rhs_geom);
      if (val == 0) {
        result = Qfalse;
      }
      else if (val == 1) {
        result = Qtrue;
      }
    }
  }
  return result;
}
コード例 #7
0
ファイル: geometry.c プロジェクト: Open-Source-GIS/rgeo
static VALUE method_geometry_union(VALUE self, VALUE rhs)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;
  VALUE factory;
  const GEOSGeometry* rhs_geom;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    factory = self_data->factory;
    rhs_geom = rgeo_convert_to_geos_geometry(factory, rhs, Qnil);
    if (rhs_geom) {
      result = rgeo_wrap_geos_geometry(factory, GEOSUnion_r(self_data->geos_context, self_geom, rhs_geom), Qnil);
    }
  }
  return result;
}
コード例 #8
0
ファイル: line_string.c プロジェクト: Epictetus/rgeo
static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char close)
{
  Check_Type(array, T_ARRAY);
  RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
  VALUE point_type = factory_data->globals->feature_point;
  unsigned int len = (unsigned int)RARRAY_LEN(array);
  char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
  unsigned int dims = has_z ? 3 : 2;
  double* coords = ALLOC_N(double, len == 0 ? 1 : len * dims);
  if (!coords) {
    return NULL;
  }
  GEOSContextHandle_t context = factory_data->geos_context;
  unsigned int i;
  for (i=0; i<len; ++i) {
    char good = 0;
    const GEOSGeometry* entry_geom = rgeo_convert_to_geos_geometry(factory, rb_ary_entry(array, i), point_type);
    if (entry_geom) {
      const GEOSCoordSequence* entry_cs = GEOSGeom_getCoordSeq_r(context, entry_geom);
      if (entry_cs) {
        double x;
        if (GEOSCoordSeq_getX_r(context, entry_cs, 0, &x)) {
          coords[i*dims] = x;
          if (GEOSCoordSeq_getY_r(context, entry_cs, 0, &x)) {
            coords[i*dims+1] = x;
            good = 1;
            if (has_z) {
              if (GEOSCoordSeq_getZ_r(context, entry_cs, 0, &x)) {
                coords[i*dims+2] = x;
              }
              else {
                good = 0;
              }
            }
          }
        }
      }
    }
    if (!good) {
      free(coords);
      return NULL;
    }
  }
  if (len > 0 && close) {
    if (coords[0] == coords[(len-1)*dims] && coords[1] == coords[(len-1)*dims+1]) {
      close = 0;
    }
  }
  else {
    close = 0;
  }
  GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, len + close, 3);
  if (coord_seq) {
    for (i=0; i<len; ++i) {
      GEOSCoordSeq_setX_r(context, coord_seq, i, coords[i*dims]);
      GEOSCoordSeq_setY_r(context, coord_seq, i, coords[i*dims+1]);
      GEOSCoordSeq_setZ_r(context, coord_seq, i, has_z ? coords[i*dims+2] : 0);
    }
    if (close) {
      GEOSCoordSeq_setX_r(context, coord_seq, len, coords[0]);
      GEOSCoordSeq_setY_r(context, coord_seq, len, coords[1]);
      GEOSCoordSeq_setZ_r(context, coord_seq, len, has_z ? coords[2] : 0);
    }
  }
  free(coords);
  return coord_seq;
}