shapeObj *msGEOSGeometry2Shape(GEOSGeom g) { int type; if(!g) return NULL; /* a NULL geometry generates a NULL shape */ type = GEOSGeomTypeId(g); switch(type) { case GEOS_POINT: return msGEOSGeometry2Shape_point(g); break; case GEOS_MULTIPOINT: return msGEOSGeometry2Shape_multipoint(g); break; case GEOS_LINESTRING: return msGEOSGeometry2Shape_line(g); break; case GEOS_MULTILINESTRING: return msGEOSGeometry2Shape_multiline(g); break; case GEOS_POLYGON: return msGEOSGeometry2Shape_polygon(g); break; case GEOS_MULTIPOLYGON: return msGEOSGeometry2Shape_multipolygon(g); break; default: if (!GEOSisEmpty(g)) msSetError(MS_GEOSERR, "Unsupported GEOS geometry type (%d).", "msGEOSGeometry2Shape()", type); return NULL; } }
void Geometry::ApplyPointTransformation(PointTransformer *t) { GEOSGeometry *g = this->geos_geom_; GEOSGeometry *ng = NULL; int gtype = GEOSGeomTypeId(g); int gcount = GEOSGetNumGeometries(g); if (gcount == 1) { ng = ApplyPointTransformationToSingleGeometry(t, g); } else { GEOSGeometry **coll = new GEOSGeometry *[gcount]; try { for (int i = 0; i < gcount; i++) { coll[i] = ApplyPointTransformationToSingleGeometry(t, GEOSGetGeometryN(g, i)); } } catch (TransformerException ex) { // free up our memory before we pass this up. delete coll; throw ex; } ng = GEOSGeom_createCollection(gtype, coll, gcount); delete coll; } if (ng != NULL) { GEOSGeom_destroy(this->geos_geom_); this->geos_geom_ = ng; } }
struct GridPointDataListIterator * readPoints( const struct PlaceSpecification * ps, GEOSGeom location, enum InterpolationType interpolation, int interpolationParam, FileId dataId) { const BaseDataReader & dataReader = BaseDataReader::getInstance(* ps); GridPointDataListIterator * ret = NULL; try { if ( ! location ) { //AllPointsReader reader(dataReader); //struct GridPointDataList * list = reader.read(dataId); // On NULL geometries we won't return anything struct GridPointDataList * list = GridPointDataListNew(0); ret = GridPointDataListIteratorNew(list); } else { int geometryType = GEOSGeomTypeId(location); if (geometryType == GEOS_POINT) { SinglePointReader reader(dataReader); GridPointDataList * list = reader.read(location, interpolation, interpolationParam, dataId); ret = GridPointDataListIteratorNew(list); } else if ((geometryType == GEOS_POLYGON)|| (geometryType == GEOS_MULTIPOLYGON)) { PolygonReader reader(dataReader); GridPointDataList * list = reader.read(location, interpolation, dataId); ret = GridPointDataListIteratorNew(list); } else throw std::runtime_error("This geometry type is not supported"); } } catch (std::exception & e) { if ( ret ) GridPointDataListDelete(ret->list, false); ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg(e.what()))); } catch (...) { // This should never happen, but just in case... if ( ret ) GridPointDataListDelete(ret->list, false); ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), "Unknown error when fetching point data. Please tell someone about this")); } return ret; }
YAP_Bool geometry_to_term (geometry_t geometry, YAP_Term *term) { geometry_type_t type; unsigned int n, size; assert (term != NULL); type = GEOSGeomTypeId (geometry); size = sizeof (translate) / sizeof (struct type_name_arity); for (n = 0; n < size; n ++) if (translate[n].geos_type == type) return (translate[n].procedure_export (geometry, term)); return (FALSE); }
static void _get_envelope(GEOSGeometry* geometry,Rect* rect) { unsigned int num_pnt; GEOSGeometry* env; const GEOSGeometry* ring; const GEOSCoordSequence* seq; double x,y; unsigned int loop=0; assert(rect != 0); assert(geometry != 0); rect->minX = rect->minY = rect->maxX = rect->maxY = 0; if(GEOSGeomTypeId(geometry) == GEOS_POINT) { GEOSGeomGetX(geometry,&x); GEOSGeomGetY(geometry,&y); rect->minX = rect->maxX = x; rect->minY = rect->maxY = y; return; } env = GEOSEnvelope(geometry); ring = GEOSGetExteriorRing(env); seq = GEOSGeom_getCoordSeq(ring); GEOSCoordSeq_getSize(seq,&num_pnt); if(num_pnt == 0 || num_pnt > 5)return; GEOSCoordSeq_getX(seq,0,&x); GEOSCoordSeq_getY(seq,0,&y); rect->minX = rect->maxX = x; rect->minY = rect->maxY = y; for(loop=1;loop<num_pnt;loop++) { GEOSCoordSeq_getX(seq,loop,&x); GEOSCoordSeq_getY(seq,loop,&y); if(x > rect->maxX) rect->maxX = x; if(x < rect->minX) rect->minX = x; if(y > rect->maxY) rect->maxY = y; if(y < rect->minY) rect->minY = y; } GEOSGeom_destroy(env); }
//LinkedList<const geos::geom::Geometry*> * unmulti (geos::geom::Geometry *the_geom){ LinkedList<const GEOSGeometry*> * unmulti( GEOSGeometry *the_geom ) { //LinkedList<const geos::geom::Geometry*> *queue = new LinkedList<const geos::geom::Geometry*>(ptrGeomEq); //LinkedList<const geos::geom::Geometry*> *final_queue = new LinkedList<const geos::geom::Geometry*>(ptrGeomEq); LinkedList<const GEOSGeometry*> *queue = new LinkedList<const GEOSGeometry*> ( ptrGeomEq ); LinkedList<const GEOSGeometry*> *final_queue = new LinkedList<const GEOSGeometry*> ( ptrGeomEq ); //const geos::geom::Geometry *geom; const GEOSGeometry *geom; queue->push_back( the_geom ); int nGeom; int i; while ( queue->size() > 0 ) { geom = queue->pop_front(); switch ( GEOSGeomTypeId( geom ) ) { //case geos::geom::GEOS_MULTIPOINT: //case geos::geom::GEOS_MULTILINESTRING: //case geos::geom::GEOS_MULTIPOLYGON: case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: nGeom = GEOSGetNumGeometries( geom ); for ( i = 0; i < nGeom; i++ ) { queue->push_back( GEOSGetGeometryN( geom, i ) ); } break; case GEOS_POINT: case GEOS_LINESTRING: case GEOS_POLYGON: final_queue->push_back( geom ); break; default: delete final_queue; final_queue = NULL; } } delete queue; return final_queue; }
GEOSGeometry *Geometry::ApplyPointTransformationToSingleGeometry(PointTransformer *t, const GEOSGeometry *g) { int gtype = GEOSGeomTypeId(g); GEOSGeometry *ng = NULL; if (gtype == GEOS_POINT || gtype == GEOS_LINESTRING || gtype == GEOS_LINEARRING) { const GEOSCoordSequence *seq = GEOSGeom_getCoordSeq(g); GEOSCoordSequence *nseq = ApplyPointTransformationToCoordSequence(t, seq); // this is silly -- GEOS really needs a shortcut for this if (gtype == GEOS_POINT) { ng = GEOSGeom_createPoint(nseq); } if (gtype == GEOS_LINESTRING) { ng = GEOSGeom_createLineString(nseq); } if (gtype == GEOS_LINEARRING) { ng = GEOSGeom_createLinearRing(nseq); } } else if (gtype == GEOS_POLYGON) { int ircnt = GEOSGetNumInteriorRings(g); const GEOSGeometry *ext = GEOSGetExteriorRing(g); GEOSGeometry *next = ApplyPointTransformationToSingleGeometry(t, ext); GEOSGeometry **rings = NULL; if (ircnt > 0) { // This shares a lot in common with the code below in ApplyPointTransformation, // refactor into a single method? rings = new GEOSGeometry *[ircnt]; for (int i = 0; i < ircnt; i++) { rings[i] = ApplyPointTransformationToSingleGeometry(t, GEOSGetInteriorRingN(g, i)); } } ng = GEOSGeom_createPolygon(next, rings, ircnt); if (rings) { delete rings; } } return ng; }
static size_t asgeojson_geom_buf(GEOSGeom geom, char *output, bbox3D *bbox, int precision) { int type = GEOSGeomTypeId(geom)+1; char *ptr=output; switch (type) { case wkbPoint_mdb: ptr += asgeojson_point_buf(geom, NULL, ptr, bbox, precision); break; case wkbLineString_mdb: ptr += asgeojson_line_buf(geom, NULL, ptr, bbox, precision); break; case wkbPolygon_mdb: ptr += asgeojson_poly_buf(geom, NULL, ptr, bbox, precision); break; case wkbMultiPoint_mdb: ptr += asgeojson_multipoint_buf(geom, NULL, ptr, bbox, precision); break; case wkbMultiLineString_mdb: ptr += asgeojson_multiline_buf(geom, NULL, ptr, bbox, precision); break; case wkbMultiPolygon_mdb: ptr += asgeojson_multipolygon_buf(geom, NULL, ptr, bbox, precision); break; default: if (bbox) GDKfree(bbox); assert(0); } return (ptr-output); }
static size_t asgeojson_geom_size(GEOSGeom geom, bbox3D *bbox, int precision) { int type = GEOSGeomTypeId(geom)+1; size_t size = 0; switch (type) { case wkbPoint_mdb: size = asgeojson_point_size(geom, NULL, bbox, precision); break; case wkbLineString_mdb: size = asgeojson_line_size(geom, NULL, bbox, precision); break; case wkbPolygon_mdb: size = asgeojson_poly_size(geom, NULL, bbox, precision); break; case wkbMultiPoint_mdb: size = asgeojson_multipoint_size(geom, NULL, bbox, precision); break; case wkbMultiLineString_mdb: size = asgeojson_multiline_size(geom, NULL, bbox, precision); break; case wkbMultiPolygon_mdb: size = asgeojson_multipolygon_size(geom, NULL, bbox, precision); break; default: assert(0); size = 0; } return size; }
void geo_y(sqlite3_context *context,int argc,sqlite3_value **argv) { if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_BLOB) { GEOSGeometry* geometry; const void* data = sqlite3_value_blob(argv[0]); size_t data_size = sqlite3_value_bytes(argv[0]); _init_geos(); geometry = _geo_from_wkb((const unsigned char*)data,data_size); if(geometry != 0) { if(GEOSGeomTypeId(geometry) == GEOS_POINT) { double y; GEOSGeomGetY(geometry,&y); sqlite3_result_double(context,y); } } GEOSGeom_destroy(geometry); finishGEOS(); } }
char* geom_to_geojson(GEOSGeom geom, char *srs, int precision, int has_bbox) { int type = GEOSGeomTypeId(geom)+1; bbox3D *bbox; if ( precision > OUT_MAX_DOUBLE_PRECISION ) precision = OUT_MAX_DOUBLE_PRECISION; if (has_bbox) { bbox3DFromGeos(&bbox, geom); } switch (type) { case wkbPoint_mdb: return asgeojson_point(geom, srs, bbox, precision); case wkbLineString_mdb: return asgeojson_line(geom, srs, bbox, precision); case wkbPolygon_mdb: return asgeojson_poly(geom, srs, bbox, precision); case wkbMultiPoint_mdb: return asgeojson_multipoint(geom, srs, bbox, precision); case wkbMultiLineString_mdb: return asgeojson_multiline(geom, srs, bbox, precision); case wkbMultiPolygon_mdb: return asgeojson_multipolygon(geom, srs, bbox, precision); case wkbGeometryCollection_mdb: return asgeojson_collection(geom, srs, bbox, precision); default: assert(0); return NULL; } return NULL; }
static ERL_NIF_TERM geom_to_eterm(ErlNifEnv *env, const GEOSGeometry *geom) { ERL_NIF_TERM coords; int type = GEOSGeomTypeId(geom); switch(type) { case GEOS_POINT: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_point_coords(env, geom); } return enif_make_tuple2(env, enif_make_atom(env, "Point"), coords); case GEOS_LINESTRING: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_linestring_coords(env, geom); } return enif_make_tuple2(env, enif_make_atom(env, "LineString"), coords); case GEOS_POLYGON: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_polygon_coords(env, geom); } return enif_make_tuple2(env, enif_make_atom(env, "Polygon"), coords); case GEOS_MULTIPOINT: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_multi_coords(env, geom, geom_to_eterm_point_coords); } return enif_make_tuple2(env, enif_make_atom(env, "MultiPoint"), coords); case GEOS_MULTILINESTRING: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_multi_coords(env, geom, geom_to_eterm_linestring_coords); } return enif_make_tuple2(env, enif_make_atom(env, "MultiLineString"), coords); case GEOS_MULTIPOLYGON: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_multi_coords(env, geom, geom_to_eterm_polygon_coords); } return enif_make_tuple2(env, enif_make_atom(env, "MultiPolygon"), coords); case GEOS_GEOMETRYCOLLECTION: if (GEOSisEmpty(geom)) { coords = enif_make_list(env, 0); } else { coords = geom_to_eterm_multi_coords(env, geom, geom_to_eterm); } return enif_make_tuple2(env, enif_make_atom(env, "GeometryCollection"), coords); } return -1; }
/* Initializes and uses GEOS internally */ static LWGEOM* lwpoly_split_by_line(const LWPOLY* lwpoly_in, const LWLINE* blade_in) { LWCOLLECTION* out; GEOSGeometry* g1; GEOSGeometry* g2; GEOSGeometry* g1_bounds; GEOSGeometry* polygons; const GEOSGeometry *vgeoms[1]; int i,n; int hasZ = FLAGS_GET_Z(lwpoly_in->flags); /* Possible outcomes: * * 1. The line does not split the polygon * -> Return a collection with single element * 2. The line does split the polygon * -> Return a collection of all elements resulting from the split */ initGEOS(lwgeom_geos_error, lwgeom_geos_error); g1 = LWGEOM2GEOS((LWGEOM*)lwpoly_in, 0); if ( NULL == g1 ) { lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg); return NULL; } g1_bounds = GEOSBoundary(g1); if ( NULL == g1_bounds ) { GEOSGeom_destroy(g1); lwerror("GEOSBoundary: %s", lwgeom_geos_errmsg); return NULL; } g2 = LWGEOM2GEOS((LWGEOM*)blade_in, 0); if ( NULL == g2 ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g1_bounds); lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg); return NULL; } vgeoms[0] = GEOSUnion(g1_bounds, g2); if ( NULL == vgeoms[0] ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); lwerror("GEOSUnion: %s", lwgeom_geos_errmsg); return NULL; } polygons = GEOSPolygonize(vgeoms, 1); if ( NULL == polygons ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); lwerror("GEOSPolygonize: %s", lwgeom_geos_errmsg); return NULL; } #if PARANOIA_LEVEL > 0 if ( GEOSGeomTypeId(polygons) != COLLECTIONTYPE ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); lwerror("%s [%s] Unexpected return from GEOSpolygonize", __FILE__, __LINE__); return 0; } #endif /* We should now have all polygons, just skip * the ones which are in holes of the original * geometries and return the rest in a collection */ n = GEOSGetNumGeometries(polygons); out = lwcollection_construct_empty(COLLECTIONTYPE, lwpoly_in->srid, hasZ, 0); /* Allocate space for all polys */ out->geoms = lwrealloc(out->geoms, sizeof(LWGEOM*)*n); assert(0 == out->ngeoms); for (i=0; i<n; ++i) { GEOSGeometry* pos; /* point on surface */ const GEOSGeometry* p = GEOSGetGeometryN(polygons, i); int contains; pos = GEOSPointOnSurface(p); if ( ! pos ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); lwerror("GEOSPointOnSurface: %s", lwgeom_geos_errmsg); return NULL; } contains = GEOSContains(g1, pos); if ( 2 == contains ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); GEOSGeom_destroy(pos); lwerror("GEOSContains: %s", lwgeom_geos_errmsg); return NULL; } GEOSGeom_destroy(pos); if ( 0 == contains ) { /* Original geometry doesn't contain * a point in this ring, must be an hole */ continue; } out->geoms[out->ngeoms++] = GEOS2LWGEOM(p, hasZ); } GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); return (LWGEOM*)out; }
bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText, double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle, int xQuadOffset, int yQuadOffset, double xOffset, double yOffset ) { if ( !geom_id || label_x < 0 || label_y < 0 ) return false; modMutex->lock(); if ( hashtable->find( geom_id ) ) { modMutex->unlock(); //A feature with this id already exists. Don't throw an exception as sometimes, //the same feature is added twice (dateline split with otf-reprojection) return false; } // Split MULTI GEOM and Collection in simple geometries GEOSGeometry *the_geom = userGeom->getGeosGeometry(); Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y ); if ( fixedPos ) { f->setFixedPosition( labelPosX, labelPosY ); } if ( xQuadOffset != 0 || yQuadOffset != 0 ) { f->setQuadOffset( xQuadOffset, yQuadOffset ); } if ( xOffset != 0.0 || yOffset != 0.0 ) { f->setPosOffset( xOffset, yOffset ); } if ( fixedAngle ) { f->setFixedAngle( angle ); } // use layer-level defined rotation, but not if position fixed if ( !fixedPos && angle != 0.0 ) { f->setFixedAngle( angle ); } bool first_feat = true; double geom_size = -1, biggest_size = -1; FeaturePart* biggest_part = NULL; // break the (possibly multi-part) geometry into simple geometries LinkedList <const GEOSGeometry*> *simpleGeometries = unmulti( the_geom ); if ( simpleGeometries == NULL ) // unmulti() failed? { modMutex->unlock(); throw InternalException::UnknownGeometry(); } while ( simpleGeometries->size() > 0 ) { const GEOSGeometry* geom = simpleGeometries->pop_front(); // ignore invalid geometries (e.g. polygons with self-intersecting rings) if ( GEOSisValid( geom ) != 1 ) // 0=invalid, 1=valid, 2=exception { std::cerr << "ignoring invalid feature " << geom_id << std::endl; continue; } int type = GEOSGeomTypeId( geom ); if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON ) { modMutex->unlock(); throw InternalException::UnknownGeometry(); } FeaturePart* fpart = new FeaturePart( f, geom ); // ignore invalid geometries if (( type == GEOS_LINESTRING && fpart->nbPoints < 2 ) || ( type == GEOS_POLYGON && fpart->nbPoints < 3 ) ) { delete fpart; continue; } // polygons: reorder coordinates if ( type == GEOS_POLYGON && reorderPolygon( fpart->nbPoints, fpart->x, fpart->y ) != 0 ) { delete fpart; continue; } if ( mode == LabelPerFeature && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) ) { if ( type == GEOS_LINESTRING ) GEOSLength( geom, &geom_size ); else if ( type == GEOS_POLYGON ) GEOSArea( geom, &geom_size ); if ( geom_size > biggest_size ) { biggest_size = geom_size; delete biggest_part; // safe with NULL part biggest_part = fpart; } continue; // don't add the feature part now, do it later // TODO: we should probably add also other parts to act just as obstacles } // feature part is ready! addFeaturePart( fpart, labelText ); first_feat = false; } delete simpleGeometries; userGeom->releaseGeosGeometry( the_geom ); modMutex->unlock(); // if using only biggest parts... if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL ) { addFeaturePart( biggest_part, labelText ); first_feat = false; } // add feature to layer if we have added something if ( !first_feat ) { features->push_back( f ); hashtable->insertItem( geom_id, f ); } else { delete f; } return !first_feat; // true if we've added something }
static gaiaGeomCollPtr fromGeosGeometry (const GEOSGeometry * geos, const int dimension_model) { /* converting a GEOS Geometry into a GAIA Geometry */ int type; int itemType; unsigned int dims; int iv; int ib; int it; int sub_it; int nItems; int nSubItems; int holes; unsigned int points; double x; double y; double z; const GEOSCoordSequence *cs; const GEOSGeometry *geos_ring; const GEOSGeometry *geos_item; const GEOSGeometry *geos_sub_item; gaiaGeomCollPtr gaia = NULL; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; if (!geos) return NULL; type = GEOSGeomTypeId (geos); switch (type) { case GEOS_POINT: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POINT; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_LINESTRING; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_POLYGON: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POLYGON; gaia->Srid = GEOSGetSRID (geos); /* exterior ring */ holes = GEOSGetNumInteriorRings (geos); geos_ring = GEOSGetExteriorRing (geos); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: case GEOS_GEOMETRYCOLLECTION: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); if (type == GEOS_MULTIPOINT) gaia->DeclaredType = GAIA_MULTIPOINT; else if (type == GEOS_MULTILINESTRING) gaia->DeclaredType = GAIA_MULTILINESTRING; else if (type == GEOS_MULTIPOLYGON) gaia->DeclaredType = GAIA_MULTIPOLYGON; else gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION; gaia->Srid = GEOSGetSRID (geos); nItems = GEOSGetNumGeometries (geos); for (it = 0; it < nItems; it++) { /* looping on elementaty geometries */ geos_item = GEOSGetGeometryN (geos, it); itemType = GEOSGeomTypeId (geos_item); switch (itemType) { case GEOS_POINT: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_MULTILINESTRING: nSubItems = GEOSGetNumGeometries (geos_item); for (sub_it = 0; sub_it < nSubItems; sub_it++) { /* looping on elementaty geometries */ geos_sub_item = GEOSGetGeometryN (geos_item, sub_it); cs = GEOSGeom_getCoordSeq (geos_sub_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } } break; case GEOS_POLYGON: /* exterior ring */ holes = GEOSGetNumInteriorRings (geos_item); geos_ring = GEOSGetExteriorRing (geos_item); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos_item, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; }; } break; }; return gaia; }
static int geom2ring(GEOSGeometry *geom, struct Map_info *Out, struct Map_info *Buf, struct spatial_index *si, struct line_cats *Cats, struct buf_contours **arr_bc, int *buffers_count, int *arr_bc_alloc) { int i, nrings, ngeoms, line_id; const GEOSGeometry *geom2; struct bound_box bbox; static struct line_pnts *Points = NULL; static struct line_cats *BCats = NULL; struct buf_contours *p = *arr_bc; G_debug(3, "geom2ring(): GEOS %s", GEOSGeomType(geom)); if (!Points) Points = Vect_new_line_struct(); if (!BCats) BCats = Vect_new_cats_struct(); if (GEOSGeomTypeId(geom) == GEOS_LINESTRING || GEOSGeomTypeId(geom) == GEOS_LINEARRING) { if (!ring2pts(geom, Points)) return 0; Vect_write_line(Out, GV_BOUNDARY, Points, BCats); line_id = Vect_write_line(Buf, GV_BOUNDARY, Points, Cats); /* add buffer to spatial index */ Vect_get_line_box(Buf, line_id, &bbox); Vect_spatial_index_add_item(si, *buffers_count, &bbox); p[*buffers_count].outer = line_id; p[*buffers_count].inner_count = 0; *buffers_count += 1; if (*buffers_count >= *arr_bc_alloc) { *arr_bc_alloc += 100; p = G_realloc(p, *arr_bc_alloc * sizeof(struct buf_contours)); *arr_bc = p; } } else if (GEOSGeomTypeId(geom) == GEOS_POLYGON) { geom2 = GEOSGetExteriorRing(geom); if (!ring2pts(geom2, Points)) return 0; Vect_write_line(Out, GV_BOUNDARY, Points, BCats); line_id = Vect_write_line(Buf, GV_BOUNDARY, Points, Cats); /* add buffer to spatial index */ Vect_get_line_box(Buf, line_id, &bbox); Vect_spatial_index_add_item(si, *buffers_count, &bbox); p[*buffers_count].outer = line_id; p[*buffers_count].inner_count = 0; nrings = GEOSGetNumInteriorRings(geom); if (nrings > 0) { p[*buffers_count].inner_count = nrings; p[*buffers_count].inner = G_malloc(nrings * sizeof(int)); for (i = 0; i < nrings; i++) { geom2 = GEOSGetInteriorRingN(geom, i); if (!ring2pts(geom2, Points)) { G_fatal_error(_("Corrupt GEOS geometry")); } Vect_write_line(Out, GV_BOUNDARY, Points, BCats); line_id = Vect_write_line(Buf, GV_BOUNDARY, Points, BCats); p[*buffers_count].inner[i] = line_id; } } *buffers_count += 1; if (*buffers_count >= *arr_bc_alloc) { *arr_bc_alloc += 100; p = G_realloc(p, *arr_bc_alloc * sizeof(struct buf_contours)); *arr_bc = p; } } else if (GEOSGeomTypeId(geom) == GEOS_MULTILINESTRING || GEOSGeomTypeId(geom) == GEOS_MULTIPOLYGON || GEOSGeomTypeId(geom) == GEOS_GEOMETRYCOLLECTION) { G_debug(3, "GEOS %s", GEOSGeomType(geom)); ngeoms = GEOSGetNumGeometries(geom); for (i = 0; i < ngeoms; i++) { geom2 = GEOSGetGeometryN(geom, i); geom2ring((GEOSGeometry *)geom2, Out, Buf, si, Cats, arr_bc, buffers_count, arr_bc_alloc); } } else G_fatal_error(_("Unknown GEOS geometry type")); return 1; }
void VertexSnapper::editGeometry( MyGEOSGeom *geom, GEOSCoordSequence *coord ) { // edit geometry according to coord -> GeometryEditor and GeometryEditorOperation/interface classes ?????? qDebug("VertexSnapper::editGeometry: ENTERING EDIT GEOMETRY"); // new geometry GEOSGeometry *newGeom = NULL; GEOSGeometry *ring = NULL; // change geometry according to its type // NOTE: improve this according to http://trac.osgeo.org/geos/browser/trunk/tests/geostest/geostest.c - fineGrainedReconstructionTest int type = GEOSGeomTypeId( geom->getGEOSGeom() ); switch ( type ) { case GEOS_POINT: newGeom = GEOSGeom_createPoint( coord ); break; case GEOS_LINESTRING: newGeom = GEOSGeom_createLineString( coord ); break; case GEOS_LINEARRING: newGeom = GEOSGeom_createLinearRing( coord ); break; case GEOS_POLYGON: ring = GEOSGeom_createLinearRing( coord ); // NOTE: Fails if polygon has holes newGeom = GEOSGeom_createPolygon( ring, NULL, 0 ); break; case GEOS_MULTIPOINT: newGeom = GEOSGeom_createEmptyCollection(4); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_MULTILINESTRING: newGeom = GEOSGeom_createEmptyCollection(5); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_MULTIPOLYGON: newGeom = GEOSGeom_createEmptyCollection(6); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_GEOMETRYCOLLECTION: newGeom = GEOSGeom_createEmptyCollection(7); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; default: qDebug("VertexSnapper::editGeometry: Unknown geometry type."); } // return edited geometry geom->setGEOSGeom( newGeom ); if( GEOSisEmpty( geom->getGEOSGeom() ) ) qDebug("VertexSnapper::editGeometry: Geom is empty."); if( GEOSisValid( geom->getGEOSGeom() ) ) qDebug("VertexSnapper::editGeometry: Geom is valid."); //GEOSGeom_destroy(newGeom); } // void VertexSnapper::editGeometry( MyGEOSGeom &geom, CoordinateSequence &coord )
/* Return an LWGEOM from a Geometry */ LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, char want3d) { int type = GEOSGeomTypeId(geom) ; int hasZ; int SRID = GEOSGetSRID(geom); /* GEOS's 0 is equivalent to our unknown as for SRID values */ if ( SRID == 0 ) SRID = SRID_UNKNOWN; if ( want3d ) { hasZ = GEOSHasZ(geom); if ( ! hasZ ) { LWDEBUG(3, "Geometry has no Z, won't provide one"); want3d = 0; } } /* if ( GEOSisEmpty(geom) ) { return (LWGEOM*)lwcollection_construct_empty(COLLECTIONTYPE, SRID, want3d, 0); } */ switch (type) { const GEOSCoordSequence *cs; POINTARRAY *pa, **ppaa; const GEOSGeometry *g; LWGEOM **geoms; uint32_t i, ngeoms; case GEOS_POINT: LWDEBUG(4, "lwgeom_from_geometry: it's a Point"); cs = GEOSGeom_getCoordSeq(geom); if ( GEOSisEmpty(geom) ) return (LWGEOM*)lwpoint_construct_empty(SRID, want3d, 0); pa = ptarray_from_GEOSCoordSeq(cs, want3d); return (LWGEOM *)lwpoint_construct(SRID, NULL, pa); case GEOS_LINESTRING: case GEOS_LINEARRING: LWDEBUG(4, "lwgeom_from_geometry: it's a LineString or LinearRing"); if ( GEOSisEmpty(geom) ) return (LWGEOM*)lwline_construct_empty(SRID, want3d, 0); cs = GEOSGeom_getCoordSeq(geom); pa = ptarray_from_GEOSCoordSeq(cs, want3d); return (LWGEOM *)lwline_construct(SRID, NULL, pa); case GEOS_POLYGON: LWDEBUG(4, "lwgeom_from_geometry: it's a Polygon"); if ( GEOSisEmpty(geom) ) return (LWGEOM*)lwpoly_construct_empty(SRID, want3d, 0); ngeoms = GEOSGetNumInteriorRings(geom); ppaa = lwalloc(sizeof(POINTARRAY *)*(ngeoms+1)); g = GEOSGetExteriorRing(geom); cs = GEOSGeom_getCoordSeq(g); ppaa[0] = ptarray_from_GEOSCoordSeq(cs, want3d); for (i=0; i<ngeoms; i++) { g = GEOSGetInteriorRingN(geom, i); cs = GEOSGeom_getCoordSeq(g); ppaa[i+1] = ptarray_from_GEOSCoordSeq(cs, want3d); } return (LWGEOM *)lwpoly_construct(SRID, NULL, ngeoms+1, ppaa); case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: case GEOS_GEOMETRYCOLLECTION: LWDEBUG(4, "lwgeom_from_geometry: it's a Collection or Multi"); ngeoms = GEOSGetNumGeometries(geom); geoms = NULL; if ( ngeoms ) { geoms = lwalloc(sizeof(LWGEOM *)*ngeoms); for (i=0; i<ngeoms; i++) { g = GEOSGetGeometryN(geom, i); geoms[i] = GEOS2LWGEOM(g, want3d); } } return (LWGEOM *)lwcollection_construct(type, SRID, NULL, ngeoms, geoms); default: lwerror("GEOS2LWGEOM: unknown geometry type: %d", type); return NULL; } }