static VALUE cmethod_create(VALUE module, VALUE factory, VALUE exterior, VALUE interior_array) { Check_Type(interior_array, T_ARRAY); RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory); VALUE linear_ring_type = factory_data->globals->feature_linear_ring; GEOSGeometry* exterior_geom = rgeo_convert_to_detached_geos_geometry(exterior, factory, linear_ring_type, NULL); if (exterior_geom) { GEOSContextHandle_t context = factory_data->geos_context; unsigned int len = (unsigned int)RARRAY_LEN(interior_array); GEOSGeometry** interior_geoms = ALLOC_N(GEOSGeometry*, len == 0 ? 1 : len); if (interior_geoms) { unsigned int actual_len = 0; unsigned int i; for (i=0; i<len; ++i) { GEOSGeometry* interior_geom = rgeo_convert_to_detached_geos_geometry(rb_ary_entry(interior_array, i), factory, linear_ring_type, NULL); if (interior_geom) { interior_geoms[actual_len++] = interior_geom; } } if (len == actual_len) { GEOSGeometry* polygon = GEOSGeom_createPolygon_r(context, exterior_geom, interior_geoms, actual_len); if (polygon) { free(interior_geoms); return rgeo_wrap_geos_geometry(factory, polygon, factory_data->globals->geos_polygon); } } for (i=0; i<actual_len; ++i) { GEOSGeom_destroy_r(context, interior_geoms[i]); } free(interior_geoms); } GEOSGeom_destroy_r(context, exterior_geom); } return Qnil; }
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; }
static VALUE method_factory_read_for_psych(VALUE self, VALUE str) { RGeo_FactoryData* self_data; GEOSContextHandle_t self_context; GEOSWKTReader* wkt_reader; VALUE result; GEOSGeometry* geom; Check_Type(str, T_STRING); self_data = RGEO_FACTORY_DATA_PTR(self); self_context = self_data->geos_context; wkt_reader = self_data->psych_wkt_reader; if (!wkt_reader) { wkt_reader = GEOSWKTReader_create_r(self_context); self_data->psych_wkt_reader = wkt_reader; } result = Qnil; if (wkt_reader) { geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str)); if (geom) { result = rgeo_wrap_geos_geometry(self, geom, Qnil); } } return result; }
static VALUE method_geometry_envelope(VALUE self) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; GEOSContextHandle_t geos_context; GEOSGeometry* envelope; result = Qnil; self_data = RGEO_GEOMETRY_DATA_PTR(self); self_geom = self_data->geom; if (self_geom) { geos_context = self_data->geos_context; envelope = GEOSEnvelope_r(geos_context, self_geom); // GEOS returns an "empty" point for an empty collection's envelope. // We don't allow that type, so we replace it with an empty collection. if (!envelope || GEOSGeomTypeId_r(geos_context, envelope) == GEOS_POINT && GEOSGetNumCoordinates_r(geos_context, envelope) == 0) { if (envelope) { GEOSGeom_destroy_r(geos_context, envelope); } envelope = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0); } result = rgeo_wrap_geos_geometry(self_data->factory, envelope, Qnil); } return result; }
static VALUE method_factory_read_for_marshal(VALUE self, VALUE str) { RGeo_FactoryData* self_data; GEOSContextHandle_t self_context; GEOSWKBReader* wkb_reader; VALUE result; GEOSGeometry* geom; Check_Type(str, T_STRING); self_data = RGEO_FACTORY_DATA_PTR(self); self_context = self_data->geos_context; wkb_reader = self_data->marshal_wkb_reader; if (!wkb_reader) { wkb_reader = GEOSWKBReader_create_r(self_context); self_data->marshal_wkb_reader = wkb_reader; } result = Qnil; if (wkb_reader) { geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str)); if (geom) { result = rgeo_wrap_geos_geometry(self, geom, Qnil); } } return result; }
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; }
static VALUE method_polygon_centroid(VALUE self) { VALUE result = Qnil; RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self); const GEOSGeometry* self_geom = self_data->geom; if (self_geom) { result = rgeo_wrap_geos_geometry(self_data->factory, GEOSGetCentroid_r(self_data->geos_context, self_geom), RGEO_FACTORY_DATA_PTR(self_data->factory)->globals->geos_point); } return result; }
static VALUE method_geometry_convex_hull(VALUE self) { VALUE result = Qnil; RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self); const GEOSGeometry* self_geom = self_data->geom; if (self_geom) { result = rgeo_wrap_geos_geometry(self_data->factory, GEOSConvexHull_r(self_data->geos_context, self_geom), Qnil); } return result; }
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; }
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; }
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; }
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; }
static VALUE method_geometry_simplify(VALUE self, VALUE tolerance) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; VALUE factory; 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, GEOSSimplify_r(self_data->geos_context, self_geom, rb_num2dbl(tolerance)), Qnil); } return result; }
static VALUE method_geometry_boundary(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 geos_context = self_data->geos_context; GEOSGeometry* boundary = GEOSBoundary_r(geos_context, self_geom); // GEOS returns NULL for the boundary of an empty collection. // Replace that with an empty collection. if (!boundary) { boundary = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0); } result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil); } return result; }
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; }
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; }
static VALUE method_geometry_boundary(VALUE self) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; GEOSContextHandle_t geos_context; GEOSGeometry* boundary; result = Qnil; self_data = RGEO_GEOMETRY_DATA_PTR(self); self_geom = self_data->geom; if (self_geom) { geos_context = self_data->geos_context; boundary = GEOSBoundary_r(geos_context, self_geom); if (boundary) { result = rgeo_wrap_geos_geometry(self_data->factory, boundary, Qnil); } } return result; }
static VALUE impl_unary_union(VALUE self) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; result = Qnil; #ifdef RGEO_GEOS_SUPPORTS_UNARYUNION self_data = RGEO_GEOMETRY_DATA_PTR(self); self_geom = self_data->geom; if (self_geom) { GEOSContextHandle_t self_context = self_data->geos_context; result = rgeo_wrap_geos_geometry(self_data->factory, GEOSUnaryUnion_r(self_context, self_geom), Qnil); } #endif return result; }
static VALUE method_geometry_envelope(VALUE self) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; GEOSContextHandle_t geos_context; GEOSGeometry* envelope; result = Qnil; self_data = RGEO_GEOMETRY_DATA_PTR(self); self_geom = self_data->geom; if (self_geom) { geos_context = self_data->geos_context; envelope = GEOSEnvelope_r(geos_context, self_geom); if (!envelope) { envelope = GEOSGeom_createCollection_r(geos_context, GEOS_GEOMETRYCOLLECTION, NULL, 0); } result = rgeo_wrap_geos_geometry(self_data->factory, envelope, Qnil); } return result; }
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; }
static VALUE alloc_geometry(VALUE klass) { return rgeo_wrap_geos_geometry(Qnil, NULL, klass); }