Example #1
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;
}
Example #2
0
static VALUE impl_copy_from(VALUE klass, VALUE factory, VALUE original, char subtype)
{
  VALUE result;
  const GEOSGeometry* original_geom;
  GEOSContextHandle_t context;
  const GEOSCoordSequence* original_coord_seq;
  GEOSCoordSequence* coord_seq;
  GEOSGeometry* geom;

  result = Qnil;
  original_geom = RGEO_GEOMETRY_DATA_PTR(original)->geom;
  if (original_geom) {
    context = RGEO_FACTORY_DATA_PTR(factory)->geos_context;
    if (subtype == 1 && GEOSGetNumCoordinates_r(context, original_geom) != 2) {
      original_geom = NULL;
    }
    if (original_geom) {
      original_coord_seq = GEOSGeom_getCoordSeq_r(context, original_geom);
      if (original_coord_seq) {
        coord_seq = GEOSCoordSeq_clone_r(context, original_coord_seq);
        if (coord_seq) {
          geom = subtype == 2 ? GEOSGeom_createLinearRing_r(context, coord_seq) : GEOSGeom_createLineString_r(context, coord_seq);
          if (geom) {
            result = rgeo_wrap_geos_geometry(factory, geom, klass);
          }
        }
      }
    }
  }
  return result;
}
Example #3
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;
}
Example #4
0
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;
}
Example #5
0
static VALUE method_polygon_geometry_type(VALUE self)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  if (self_data->geom) {
    result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_polygon;
  }
  return result;
}
Example #6
0
static VALUE method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_parser)
{
  RGeo_FactoryData* self_data;

  self_data = RGEO_FACTORY_DATA_PTR(self);
  self_data->wkrep_wkt_parser = wkt_parser;
  self_data->wkrep_wkb_parser = wkb_parser;

  return self;
}
Example #7
0
st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash)
{
  ID hash_method;
  RGeo_Objbase_Hash_Struct hash_struct;

  hash_method = RGEO_FACTORY_DATA_PTR(factory)->globals->id_hash;
  hash_struct.seed_hash = hash;
  hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
  hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
  return rb_memhash(&hash_struct, sizeof(RGeo_Objbase_Hash_Struct));
}
Example #8
0
static VALUE method_geometry_buffer(VALUE self, VALUE distance)
{
  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;
    int resolution = NUM2INT(RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution);
    result = rgeo_wrap_geos_geometry(factory, GEOSBuffer_r(self_data->geos_context, self_geom, rb_num2dbl(distance), resolution), Qnil);
  }
  return result;
}
Example #9
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;
}
Example #10
0
static VALUE cmethod_create_linear_ring(VALUE module, VALUE factory, VALUE array)
{
  VALUE result = Qnil;
  GEOSCoordSequence* coord_seq = coord_seq_from_array(factory, array, 1);
  if (coord_seq) {
    RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
    GEOSGeometry* geom = GEOSGeom_createLinearRing_r(factory_data->geos_context, coord_seq);
    if (geom) {
      result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_linear_ring);
    }
  }
  return result;
}
Example #11
0
VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
{
  VALUE result;
  GEOSGeometry* clone_geom;

  result = Qnil;
  if (geom) {
    clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
    if (clone_geom) {
      result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
    }
  }
  return result;
}
Example #12
0
static VALUE method_line_hash(VALUE self)
{
  st_index_t hash;
  RGeo_GeometryData* self_data;
  VALUE factory;

  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  factory = self_data->factory;
  hash = rb_hash_start(0);
  hash = rgeo_geos_objbase_hash(factory,
    RGEO_FACTORY_DATA_PTR(factory)->globals->feature_line, hash);
  hash = rgeo_geos_coordseq_hash(self_data->geos_context, self_data->geom, hash);
  return LONG2FIX(rb_hash_end(hash));
}
Example #13
0
static VALUE method_geometry_geometry_type(VALUE self)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_geometry;
  }
  return result;
}
Example #14
0
RGEO_BEGIN_C


static VALUE method_line_string_geometry_type(VALUE self)
{
  VALUE result;
  RGeo_GeometryData* self_data;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  if (self_data->geom) {
    result = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->feature_line_string;
  }
  return result;
}
Example #15
0
VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
{
  VALUE result;
  VALUE factory;

  result = Qnil;
  if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
    result = Qfalse;
  }
  else {
    factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
    result = rb_funcall(factory, RGEO_FACTORY_DATA_PTR(factory)->globals->id_eql, 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
  }
  return result;
}
Example #16
0
static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig)
{
  RGeo_GeometryData* self_data;
  const GEOSPreparedGeometry* prep;
  const GEOSGeometry* geom;
  RGeo_GeometryData* orig_data;
  GEOSContextHandle_t orig_context;
  GEOSGeometry* clone_geom;
  RGeo_FactoryData* factory_data;

  // Clear out any existing value
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  if (self_data->geom) {
    GEOSGeom_destroy_r(self_data->geos_context, self_data->geom);
    self_data->geom = NULL;
  }
  prep = self_data->prep;
  if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
    GEOSPreparedGeom_destroy_r(self_data->geos_context, prep);
  }
  self_data->prep = NULL;
  self_data->geos_context = NULL;
  self_data->factory = Qnil;
  self_data->klasses = Qnil;

  // Copy value from orig
  geom = rgeo_get_geos_geometry_safe(orig);
  if (geom) {
    orig_data = RGEO_GEOMETRY_DATA_PTR(orig);
    orig_context = orig_data->geos_context;
    clone_geom = GEOSGeom_clone_r(orig_context, geom);
    if (clone_geom) {
      factory_data = RGEO_FACTORY_DATA_PTR(orig_data->factory);
      GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom));
      self_data->geom = clone_geom;
      self_data->geos_context = orig_context;
      self_data->prep = factory_data && (factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC != 0) ?
        (GEOSPreparedGeometry*)1 : NULL;
      self_data->factory = orig_data->factory;
      self_data->klasses = orig_data->klasses;
    }
  }
  return self;
}
Example #17
0
static VALUE method_polygon_interior_ring_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) {
    int i = NUM2INT(n);
    if (i >= 0) {
      GEOSContextHandle_t self_context = self_data->geos_context;
      int num = GEOSGetNumInteriorRings_r(self_context, self_geom);
      if (i < num) {
        result = rgeo_wrap_geos_geometry_clone(self_data->factory,
          GEOSGetInteriorRingN_r(self_context, self_geom, i),
          RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring);
      }
    }
  }
  return result;
}
Example #18
0
static VALUE get_3d_point(VALUE self, int flag)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    if (RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & flag) {
      GEOSContextHandle_t self_context = self_data->geos_context;
      const GEOSCoordSequence* coord_seq = GEOSGeom_getCoordSeq_r(self_context, self_geom);
      if (coord_seq) {
        double val;
        if (GEOSCoordSeq_getZ_r(self_context, coord_seq, 0, &val)) {
          result = rb_float_new(val);
        }
      }
    }
  }
  return result;
}
Example #19
0
const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
{
  VALUE object;
  const GEOSGeometry* geom;
  RGeo_Globals* globals;

  if (NIL_P(type) && TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
    object = obj;
  }
  else {
    globals = RGEO_FACTORY_DATA_PTR(factory)->globals;
    object = rb_funcall(globals->feature_module, globals->id_cast, 3, obj, factory, type);
  }
  geom = NULL;
  if (!NIL_P(object)) {
    geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
  }
  return geom;
}
Example #20
0
VALUE rgeo_create_geos_point(VALUE factory, double x, double y, double z)
{
  VALUE result = Qnil;
  RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
  GEOSContextHandle_t context = factory_data->geos_context;
  GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, 1, 3);
  if (coord_seq) {
    if (GEOSCoordSeq_setX_r(context, coord_seq, 0, x)) {
      if (GEOSCoordSeq_setY_r(context, coord_seq, 0, y)) {
        if (GEOSCoordSeq_setZ_r(context, coord_seq, 0, z)) {
          GEOSGeometry* geom = GEOSGeom_createPoint_r(context, coord_seq);
          if (geom) {
            result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_point);
          }
        }
      }
    }
  }
  return result;
}
Example #21
0
static VALUE method_polygon_interior_rings(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;
    int count = GEOSGetNumInteriorRings_r(self_context, self_geom);
    if (count >= 0) {
      result = rb_ary_new2(count);
      VALUE factory = self_data->factory;
      VALUE linear_ring_class = RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_linear_ring;
      int i;
      for (i=0; i<count; ++i) {
        rb_ary_store(result, i, rgeo_wrap_geos_geometry_clone(factory, GEOSGetInteriorRingN_r(self_context, self_geom, i), linear_ring_class));
      }
    }
  }
  return result;
}
Example #22
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;
}
Example #23
0
static VALUE method_geometry_buffer_with_style(VALUE self, VALUE distance, VALUE endCapStyle, VALUE joinStyle, VALUE mitreLimit)
{
  VALUE result;
  RGeo_GeometryData* self_data;
  const GEOSGeometry* self_geom;
  VALUE factory;
  int resolution;

  result = Qnil;
  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  self_geom = self_data->geom;
  if (self_geom) {
    factory = self_data->factory;
    result = rgeo_wrap_geos_geometry(factory, 
                                     GEOSBufferWithStyle_r(self_data->geos_context, self_geom,
                                                           rb_num2dbl(distance),
                                                           RGEO_FACTORY_DATA_PTR(factory)->buffer_resolution,
                                                           endCapStyle, joinStyle, mitreLimit),
                                     Qnil);
  }
  return result;
}
Example #24
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;
}
Example #25
0
static VALUE method_get_coord_sys(VALUE self)
{
  return RGEO_FACTORY_DATA_PTR(self)->coord_sys_obj;
}
Example #26
0
static VALUE cmethod_create(VALUE module, VALUE factory, VALUE x, VALUE y, VALUE z)
{
  return rgeo_create_geos_point(factory, rb_num2dbl(x), rb_num2dbl(y),
    RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M ? rb_num2dbl(z) : 0);
}
Example #27
0
static VALUE method_point_eql(VALUE self, VALUE rhs)
{
  VALUE result = rgeo_geos_klasses_and_factories_eql(self, rhs);
  if (RTEST(result)) {
    RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
    result = rgeo_geos_coordseqs_eql(self_data->geos_context, self_data->geom, RGEO_GEOMETRY_DATA_PTR(rhs)->geom, RGEO_FACTORY_DATA_PTR(self_data->factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
  }
  return result;
}
Example #28
0
static VALUE method_get_wkt_generator(VALUE self)
{
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_generator;
}
Example #29
0
static VALUE method_get_wkb_parser(VALUE self)
{
  return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_parser;
}
Example #30
0
VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
{
  VALUE result;
  RGeo_FactoryData* factory_data;
  GEOSContextHandle_t factory_context;
  VALUE klasses;
  RGeo_Globals* globals;
  VALUE inferred_klass;
  char is_collection;
  RGeo_GeometryData* data;

  result = Qnil;
  if (geom || !NIL_P(klass)) {
    factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
    factory_context = factory_data ? factory_data->geos_context : NULL;
    globals = factory_data ? factory_data->globals : NULL;

    // We don't allow "empty" points, so replace such objects with
    // an empty collection.
    if (geom && factory) {
      if (GEOSGeomTypeId_r(factory_context, geom) == GEOS_POINT && GEOSGetNumCoordinates_r(factory_context, geom) == 0) {
        GEOSGeom_destroy_r(factory_context, geom);
        geom = GEOSGeom_createCollection_r(factory_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
        klass = globals->geos_geometry_collection;
      }
    }

    klasses = Qnil;
    if (TYPE(klass) != T_CLASS) {
      inferred_klass = Qnil;
      is_collection = 0;
      switch (GEOSGeomTypeId_r(factory_context, geom)) {
      case GEOS_POINT:
        inferred_klass = globals->geos_point;
        break;
      case GEOS_LINESTRING:
        inferred_klass = globals->geos_line_string;
        break;
      case GEOS_LINEARRING:
        inferred_klass = globals->geos_linear_ring;
        break;
      case GEOS_POLYGON:
        inferred_klass = globals->geos_polygon;
        break;
      case GEOS_MULTIPOINT:
        inferred_klass = globals->geos_multi_point;
        is_collection = 1;
        break;
      case GEOS_MULTILINESTRING:
        inferred_klass = globals->geos_multi_line_string;
        is_collection = 1;
        break;
      case GEOS_MULTIPOLYGON:
        inferred_klass = globals->geos_multi_polygon;
        is_collection = 1;
        break;
      case GEOS_GEOMETRYCOLLECTION:
        inferred_klass = globals->geos_geometry_collection;
        is_collection = 1;
        break;
      default:
        inferred_klass = globals->geos_geometry;
        break;
      }
      if (TYPE(klass) == T_ARRAY && is_collection) {
        klasses = klass;
      }
      klass = inferred_klass;
    }
    data = ALLOC(RGeo_GeometryData);
    if (data) {
      if (geom) {
        GEOSSetSRID_r(factory_context, geom, factory_data->srid);
      }
      data->geos_context = factory_context;
      data->geom = geom;
      data->prep = factory_data && ((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0) ?
        (GEOSPreparedGeometry*)1 : NULL;
      data->factory = factory;
      data->klasses = klasses;
      result = Data_Wrap_Struct(klass, mark_geometry_func, destroy_geometry_func, data);
    }
  }
  return result;
}