static VALUE method_geometry_equals(VALUE self, VALUE rhs) { VALUE result; RGeo_GeometryData* self_data; const GEOSGeometry* self_geom; const GEOSGeometry* rhs_geom; GEOSContextHandle_t self_context; char val; result = Qnil; self_data = RGEO_GEOMETRY_DATA_PTR(self); self_geom = self_data->geom; if (self_geom) { rhs_geom = rgeo_get_geos_geometry_safe(rhs); if (rhs_geom) { self_context = self_data->geos_context; // GEOS has a bug where empty geometries are not spatially equal // to each other. Work around this case first. if (GEOSisEmpty_r(self_context, self_geom) == 1 && GEOSisEmpty_r(RGEO_GEOMETRY_DATA_PTR(rhs)->geos_context, rhs_geom) == 1) { result = Qtrue; } else { val = GEOSEquals_r(self_context, self_geom, rhs_geom); if (val == 0) { result = Qfalse; } else if (val == 1) { result = Qtrue; } } } } return result; }
static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig) { // Clear out any existing value RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self); GEOSGeometry* self_geom = self_data->geom; if (self_geom) { GEOSGeom_destroy_r(self_data->geos_context, self_geom); self_data->geom = NULL; self_data->geos_context = NULL; self_data->factory = Qnil; self_data->klasses = Qnil; } // Copy value from orig const GEOSGeometry* geom = rgeo_get_geos_geometry_safe(orig); if (geom) { RGeo_GeometryData* orig_data = RGEO_GEOMETRY_DATA_PTR(orig); GEOSContextHandle_t orig_context = orig_data->geos_context; GEOSGeometry* clone_geom = GEOSGeom_clone_r(orig_context, geom); if (clone_geom) { GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom)); self_data->geom = clone_geom; self_data->geos_context = orig_context; self_data->factory = orig_data->factory; self_data->klasses = orig_data->klasses; } } return self; }
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; }
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; }
static VALUE method_geometry_steal(VALUE self, VALUE orig) { RGeo_GeometryData* self_data; const GEOSPreparedGeometry* prep; const GEOSGeometry* geom; RGeo_GeometryData* orig_data; geom = rgeo_get_geos_geometry_safe(orig); if (geom) { // 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); } prep = self_data->prep; if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) { GEOSPreparedGeom_destroy_r(self_data->geos_context, prep); } // Steal value from orig orig_data = RGEO_GEOMETRY_DATA_PTR(orig); self_data->geom = orig_data->geom; self_data->prep = orig_data->prep; self_data->geos_context = orig_data->geos_context; self_data->factory = orig_data->factory; self_data->klasses = orig_data->klasses; // Clear out orig orig_data->geom = NULL; orig_data->prep = NULL; orig_data->geos_context = NULL; orig_data->factory = Qnil; orig_data->klasses = Qnil; } return self; }