/* Find holes of each face */ static void findFaceHoles(Face** faces, int nfaces) { int i, j, h; /* We sort by envelope area so that we know holes are only * after their shells */ qsort(faces, nfaces, sizeof(Face*), compare_by_envarea); for (i=0; i<nfaces; ++i) { Face* f = faces[i]; int nholes = GEOSGetNumInteriorRings(f->geom); LWDEBUGF(2, "Scanning face %d with env area %g and %d holes", i, f->envarea, nholes); for (h=0; h<nholes; ++h) { const GEOSGeometry *hole = GEOSGetInteriorRingN(f->geom, h); LWDEBUGF(2, "Looking for hole %d/%d of face %d among %d other faces", h+1, nholes, i, nfaces-i-1); for (j=i+1; j<nfaces; ++j) { Face* f2 = faces[j]; if ( f2->parent ) continue; /* hole already assigned */ const GEOSGeometry *f2er = GEOSGetExteriorRing(f2->geom); /* TODO: can be optimized as the ring would have the * same vertices, possibly in different order. * maybe comparing number of points could already be * useful. */ if ( GEOSEquals(f2er, hole) ) { LWDEBUGF(2, "Hole %d/%d of face %d is face %d", h+1, nholes, i, j); f2->parent = f; break; } } } } }
ERL_NIF_TERM geom_to_eterm_polygon_coords(ErlNifEnv *env, const GEOSGeometry *geom) { unsigned int inner_num, i; const GEOSGeometry *outer, *inner; const GEOSCoordSequence *coords_seq; ERL_NIF_TERM coords; ERL_NIF_TERM *rings; inner_num = GEOSGetNumInteriorRings(geom); // all rings, outer + inner rings = malloc(sizeof(ERL_NIF_TERM)*inner_num+1); outer = GEOSGetExteriorRing(geom); coords_seq = GEOSGeom_getCoordSeq(outer); rings[0] = GEOSCoordSequence_to_eterm_list(env, coords_seq, GEOSGetNumCoordinates(outer)); for (i=0; i<inner_num; i++) { inner = GEOSGetInteriorRingN(geom, i); coords_seq = GEOSGeom_getCoordSeq(inner); rings[i+1] = GEOSCoordSequence_to_eterm_list(env, coords_seq, GEOSGetNumCoordinates(inner)); } coords = enif_make_list_from_array(env, rings, inner_num+1); free(rings); return coords; }
static shapeObj *msGEOSGeometry2Shape_polygon(GEOSGeom g) { shapeObj *shape=NULL; lineObj line; int numPoints, numRings; int i, j; GEOSCoordSeq coords; GEOSGeom ring; if(!g) return NULL; shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POLYGON; shape->geometry = (GEOSGeom) g; /* exterior ring */ ring = (GEOSGeom) GEOSGetExteriorRing(g); numPoints = GEOSGetNumCoordinates(ring); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring); line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); line.numpoints = numPoints; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(line.point[i].x)); GEOSCoordSeq_getY(coords, i, &(line.point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */ } msAddLineDirectly(shape, &line); /* interior rings */ numRings = GEOSGetNumInteriorRings(g); for(j=0; j<numRings; j++) { ring = (GEOSGeom) GEOSGetInteriorRingN(g, j); if(GEOSisRing(ring) != 1) continue; /* skip it */ numPoints = GEOSGetNumCoordinates(ring); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring); line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); line.numpoints = numPoints; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(line.point[i].x)); GEOSCoordSeq_getY(coords, i, &(line.point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */ } msAddLineDirectly(shape, &line); } msComputeBounds(shape); return shape; }
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); }
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 YAP_Bool make_polygon_to_term (geometry_t geometry, const char * functor_name, YAP_Term *term) { int n; geometry_t ring; sequence_t sequence; YAP_Functor functor; unsigned int size; YAP_Term head; assert (term != NULL); *term = YAP_MkAtomTerm (YAP_LookupAtom ("[]")); size = GEOSGetNumInteriorRings (geometry); for (n = size - 1; n >= 0; n --) { ring = (geometry_t) GEOSGetInteriorRingN (geometry, n); sequence = (sequence_t) GEOSGeom_getCoordSeq (ring); if ((sequence == NULL) || (point_list_to_term (sequence, &head) == FALSE)) return (FALSE); *term = YAP_MkPairTerm (head, *term); } /* Exterior ring always exists. */ ring = (geometry_t) GEOSGetExteriorRing (geometry); if (ring == NULL) return (FALSE); sequence = (sequence_t) GEOSGeom_getCoordSeq (ring); if ((sequence == NULL) || (point_list_to_term (sequence, &head) == FALSE)) return (FALSE); *term = YAP_MkPairTerm (head, *term); if (functor_name != NULL) { functor = YAP_MkFunctor (YAP_LookupAtom (NAME_POLYGON), 1); *term = YAP_MkApplTerm (functor, 1, term); } return (TRUE); }
/* 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; } }
GEOSGeometry* LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) { GEOSGeometry *tmp; GEOSGeometry *geos_result, *shp; GEOSGeometry const *vgeoms[1]; uint32_t i, ngeoms; int srid = GEOSGetSRID(geom_in); vgeoms[0] = geom_in; geos_result = GEOSPolygonize(vgeoms, 1); LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result); /* Null return from GEOSpolygonize (an exception) */ if ( ! geos_result ) return 0; /* * We should now have a collection */ #if PARANOIA_LEVEL > 0 if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE ) { GEOSGeom_destroy(geos_result); lwerror("Unexpected return from GEOSpolygonize"); return 0; } #endif ngeoms = GEOSGetNumGeometries(geos_result); LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms); LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0))); /* * No geometries in collection, early out */ if ( ngeoms == 0 ) { GEOSSetSRID(geos_result, srid); return geos_result; } /* * Return first geometry if we only have one in collection, * to avoid the unnecessary Geometry clone below. */ if ( ngeoms == 1 ) { tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0); if ( ! tmp ) { GEOSGeom_destroy(geos_result); return 0; /* exception */ } shp = GEOSGeom_clone(tmp); GEOSGeom_destroy(geos_result); /* only safe after the clone above */ GEOSSetSRID(shp, srid); return shp; } /* * Iteratively invoke symdifference on outer rings * as suggested by Carl Anderson: * postgis-devel/2005-December/001805.html */ shp = NULL; for (i=0; i<ngeoms; ++i) { GEOSGeom extring; GEOSCoordSeq sq; /* * Construct a Polygon from geometry i exterior ring * We don't use GEOSGeom_clone on the ExteriorRing * due to a bug in CAPI contained in GEOS 2.2 branch * failing to properly return a LinearRing from * a LinearRing clone. */ sq=GEOSCoordSeq_clone(GEOSGeom_getCoordSeq( GEOSGetExteriorRing(GEOSGetGeometryN( geos_result, i)) )); extring = GEOSGeom_createPolygon( GEOSGeom_createLinearRing(sq), NULL, 0 ); if ( extring == NULL ) /* exception */ { lwerror("GEOSCreatePolygon threw an exception"); return 0; } if ( shp == NULL ) { shp = extring; LWDEBUGF(3, "GEOSpolygonize: shp:%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0))); } else { tmp = GEOSSymDifference(shp, extring); LWDEBUGF(3, "GEOSpolygonize: SymDifference(%s, %s):%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(extring, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(tmp, 0)) ); GEOSGeom_destroy(shp); GEOSGeom_destroy(extring); shp = tmp; } } GEOSGeom_destroy(geos_result); GEOSSetSRID(shp, srid); return shp; }
PolygonReader::BoundingBox PolygonReader::getBounds( const GEOSGeom polygons ) { BoundingBox ret; int geomNumber = GEOSGetNumGeometries(polygons); for (int n=0; n<geomNumber; n++) { GEOSGeom outerRing; if (geomNumber > 1) { GEOSGeom polygon = const_cast<GEOSGeom>(GEOSGetGeometryN( polygons, n )); if (polygon == NULL) throw std::runtime_error( "Multigeometry returned is NULL" ); outerRing = const_cast<GEOSGeom>(GEOSGetExteriorRing( polygon )); } else { outerRing = const_cast<GEOSGeom>(GEOSGetExteriorRing( polygons )); } if ( outerRing == NULL ) throw std::runtime_error( "Outer ring of polygon/shape is NULL." ); GEOSCoordSeq coordSeq = const_cast<GEOSCoordSeq>(GEOSGeom_getCoordSeq( outerRing )); if ( coordSeq == NULL ) throw std::runtime_error( "Coordinate sequence of polygon/shape returned NULL" ); unsigned int size; if ( GEOSCoordSeq_getSize( coordSeq, &size ) == 0 ) throw std::runtime_error( "Error when getting size of outer ring of polygon/shape" ); // Calculate Bounds WdbProjection prj( reader_.placeSpecification().projDefinition_ ); lonlat coord; // Initialize GEOSCoordSeq_getX( coordSeq, 0, &coord.lon ); GEOSCoordSeq_getY( coordSeq, 0, &coord.lat ); if ( ! isMetric( DEFAULT_PROJECTION ) ) { coord.lon *= DEG_TO_RAD; coord.lat *= DEG_TO_RAD; } prj.transformFromDefault( 1, &coord.lon, &coord.lat ); if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) { coord.lon *= RAD_TO_DEG; coord.lat *= RAD_TO_DEG; } if (n == 0) { ret.left_ = coord.lon; ret.top_ = coord.lat; ret.right_ = coord.lon; ret.bottom_ = coord.lat; } for ( unsigned int i = 1; i < size; i++ ) { GEOSCoordSeq_getX( coordSeq, i, &coord.lon ); GEOSCoordSeq_getY( coordSeq, i, &coord.lat ); if ( ! isMetric( DEFAULT_PROJECTION ) ) { coord.lon *= DEG_TO_RAD; coord.lat *= DEG_TO_RAD; } prj.transformFromDefault( 1, &coord.lon, &coord.lat ); if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) { coord.lon *= RAD_TO_DEG; coord.lat *= RAD_TO_DEG; } if (coord.lon < ret.left_) ret.left_ = coord.lon; else if (coord.lon > ret.right_) ret.right_ = coord.lon; if (coord.lat < ret.bottom_) ret.bottom_ = coord.lat; else if (coord.lat > ret.top_ ) ret.top_ = coord.lat; } } return ret; }
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; }
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; }