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_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; }
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; }
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_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; }
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; }
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; }
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; }