static VALUE get_point_from_coordseq(VALUE self, const GEOSCoordSequence* coord_seq, unsigned int i, char has_z) { VALUE result; RGeo_GeometryData* self_data; GEOSContextHandle_t self_context; double x, y, z; result = Qnil; self_data = RGEO_GEOMETRY_DATA_PTR(self); self_context = self_data->geos_context; if (GEOSCoordSeq_getX_r(self_context, coord_seq, i, &x)) { if (GEOSCoordSeq_getY_r(self_context, coord_seq, i, &y)) { if (has_z) { if (!GEOSCoordSeq_getZ_r(self_context, coord_seq, i, &z)) { z = 0.0; } } else { z = 0.0; } result = rgeo_create_geos_point(self_data->factory, x, y, z); } } return result; }
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; }
static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOSGeometry* geom, GEOSCoordSequence* coord_seq, unsigned int i, char has_z) { const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r(context, geom); double x = 0; if (cs) { GEOSCoordSeq_getX_r(context, cs, 0, &x); } GEOSCoordSeq_setX_r(context, coord_seq, i, x); x = 0; if (cs) { GEOSCoordSeq_getY_r(context, cs, 0, &x); } GEOSCoordSeq_setY_r(context, coord_seq, i, x); x = 0; if (has_z && cs) { GEOSCoordSeq_getZ_r(context, cs, 0, &x); } GEOSCoordSeq_setZ_r(context, coord_seq, i, x); }
VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z) { VALUE result; const GEOSCoordSequence* cs1; const GEOSCoordSequence* cs2; unsigned int len1; unsigned int len2; unsigned int i; double val1, val2; result = Qnil; if (geom1 && geom2) { cs1 = GEOSGeom_getCoordSeq_r(context, geom1); cs2 = GEOSGeom_getCoordSeq_r(context, geom2); if (cs1 && cs2) { len1 = 0; len2 = 0; if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) { if (len1 == len2) { result = Qtrue; for (i=0; i<len1; ++i) { if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) { if (val1 == val2) { if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) { if (val1 == val2) { if (check_z) { val1 = 0; if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) { result = Qnil; break; } val2 = 0; if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) { result = Qnil; break; } if (val1 != val2) { result = Qfalse; break; } } } else { // Y coords are different result = Qfalse; break; } } else { // Failed to get Y coords result = Qnil; break; } } else { // X coords are different result = Qfalse; break; } } else { // Failed to get X coords result = Qnil; break; } } // Iteration over coords } else { // Lengths are different result = Qfalse; } } } } return result; }
Q_NOWARN_UNREACHABLE_POP // Return Nth vertex in GEOSGeometry as a POINT. // May return NULL if the geometry has NO vertexex. static GEOSGeometry *LWGEOM_GEOS_getPointN( const GEOSGeometry *g_in, uint32_t n ) { GEOSContextHandle_t handle = QgsGeos::getGEOSHandler(); uint32_t dims; const GEOSCoordSequence *seq_in = nullptr; GEOSCoordSeq seq_out; double val; uint32_t sz; int gn; GEOSGeometry *ret = nullptr; switch ( GEOSGeomTypeId_r( handle, g_in ) ) { case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: case GEOS_GEOMETRYCOLLECTION: { for ( gn = 0; gn < GEOSGetNumGeometries_r( handle, g_in ); ++gn ) { const GEOSGeometry *g = GEOSGetGeometryN_r( handle, g_in, gn ); ret = LWGEOM_GEOS_getPointN( g, n ); if ( ret ) return ret; } break; } case GEOS_POLYGON: { ret = LWGEOM_GEOS_getPointN( GEOSGetExteriorRing_r( handle, g_in ), n ); if ( ret ) return ret; for ( gn = 0; gn < GEOSGetNumInteriorRings_r( handle, g_in ); ++gn ) { const GEOSGeometry *g = GEOSGetInteriorRingN_r( handle, g_in, gn ); ret = LWGEOM_GEOS_getPointN( g, n ); if ( ret ) return ret; } break; } case GEOS_POINT: case GEOS_LINESTRING: case GEOS_LINEARRING: break; } seq_in = GEOSGeom_getCoordSeq_r( handle, g_in ); if ( ! seq_in ) return nullptr; if ( ! GEOSCoordSeq_getSize_r( handle, seq_in, &sz ) ) return nullptr; if ( ! sz ) return nullptr; if ( ! GEOSCoordSeq_getDimensions_r( handle, seq_in, &dims ) ) return nullptr; seq_out = GEOSCoordSeq_create_r( handle, 1, dims ); if ( ! seq_out ) return nullptr; if ( ! GEOSCoordSeq_getX_r( handle, seq_in, n, &val ) ) return nullptr; if ( ! GEOSCoordSeq_setX_r( handle, seq_out, n, val ) ) return nullptr; if ( ! GEOSCoordSeq_getY_r( handle, seq_in, n, &val ) ) return nullptr; if ( ! GEOSCoordSeq_setY_r( handle, seq_out, n, val ) ) return nullptr; if ( dims > 2 ) { if ( ! GEOSCoordSeq_getZ_r( handle, seq_in, n, &val ) ) return nullptr; if ( ! GEOSCoordSeq_setZ_r( handle, seq_out, n, val ) ) return nullptr; } return GEOSGeom_createPoint_r( handle, seq_out ); }
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; }
void coordseq_to_terms(GEOSCommand *command) { GEOSContextHandle_t handle = command->driver_data->handle; GEOSCoordSequence *coordSeq; unsigned int dims = 2; ERL_READ_PTR_GEOSCOORDSEQUENCE(command, coordSeq); //ERL_READ_INT(command, dims); unsigned int size; if(GEOSCoordSeq_getSize_r(handle, coordSeq, &size)==0) { erl_send_error(command, "invalidcs"); return; } //if(GEOSCoordSeq_getDimensions_r(handle, coordSeq,&dims)==0) { // erl_send_error(command, "invalidcs"); // return; //} always return 3 int allocSize = 7 + (size * (dims * 2 + 2)); //int allocSize = 6 + (dims*2 + 2) * size + 1; double *digits = driver_alloc(sizeof(double) * dims * size); memset(digits, 0, sizeof(double) * dims * size); ErlDrvTermData *terms = driver_alloc(sizeof(ErlDrvTermData) * (allocSize)); terms[0] = ERL_DRV_ATOM; terms[1] = driver_mk_atom("ok"); int pos = 2; int i,d = 0; for(i = 0; i < size; i++) { GEOSCoordSeq_getX_r(handle,coordSeq,i, &digits[d]); terms[pos++] = ERL_DRV_FLOAT; terms[pos++] = (ErlDrvTermData) &digits[d]; d++; if(dims >= 2) { GEOSCoordSeq_getY_r(handle,coordSeq,i, &digits[d]); terms[pos++] = ERL_DRV_FLOAT; terms[pos++] = (ErlDrvTermData) &digits[d]; d++; } if(dims >= 3) { GEOSCoordSeq_getZ_r(handle,coordSeq,i, &digits[d]); terms[pos++] = ERL_DRV_FLOAT; terms[pos++] = (ErlDrvTermData) &digits[d]; d++; } terms[pos++] = ERL_DRV_TUPLE; terms[pos++] = dims; } terms[pos++] = ERL_DRV_NIL; terms[pos++] = ERL_DRV_LIST; terms[pos++] = size+1; terms[pos++] = ERL_DRV_TUPLE; terms[pos] = 2; driver_output_term(command->driver_data->port, terms, pos+1); driver_free(digits); driver_free(terms); }