static GEOSGeom msGEOSShape2Geometry_polygon(shapeObj *shape) { int i, j; GEOSGeom *polygons; int *outerList, numOuterRings=0, lastOuterRing=0; GEOSGeom g; outerList = msGetOuterList(shape); for(i=0; i<shape->numlines; i++) { if(outerList[i] == MS_TRUE) { numOuterRings++; lastOuterRing = i; /* save for the simple case */ } } if(numOuterRings == 1) { g = msGEOSShape2Geometry_simplepolygon(shape, lastOuterRing, outerList); } else { /* a true multipolygon */ polygons = malloc(numOuterRings*sizeof(GEOSGeom)); if(!polygons) return NULL; j = 0; /* part counter */ for(i=0; i<shape->numlines; i++) { if(outerList[i] == MS_FALSE) continue; polygons[j] = msGEOSShape2Geometry_simplepolygon(shape, i, outerList); /* TODO: account for NULL return values */ j++; } g = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, polygons, numOuterRings); } free(outerList); return g; }
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; } }
static YAP_Bool list_to_geometry (YAP_Term term, unsigned int minimum, procedure_to_geometry_t procedure, geometry_type_t geometry_type, geometry_t *geometry) { geometry_t *p; unsigned int size; unsigned int v, n; YAP_Term head; assert (geometry != NULL); term = YAP_ArgOfTerm (1, term); if ((is_list_get_size (term, &size) == FALSE) || (size < minimum)) return (FALSE); p = (geometry_t *) malloc (sizeof (geometry_t) * size); if (p == NULL) { warning ("%s: list_to_geometry: not enough memory", __FILE__); return (FALSE); } memset (p, 0, sizeof (geometry_t) * size); for (n = 0; YAP_IsPairTerm (term) != FALSE; n ++) { assert (n < size); head = YAP_HeadOfTerm (term); if (procedure (head, &p[n]) == FALSE) { for (v = 0; v < n; v ++) GEOSGeom_destroy (p[v]); free (p); return (FALSE); } term = YAP_TailOfTerm (term); } assert (n == size); assert (YAP_IsAtomTerm (term) != FALSE); assert (strcmp (YAP_AtomName (YAP_AtomOfTerm (term)), "[]") == 0); if (geometry_type == GEOS_POLYGON) *geometry = GEOSGeom_createPolygon (p[0], p + 1, size - 1); else *geometry = GEOSGeom_createCollection (geometry_type, p, size); memset (p, 0, sizeof (geometry_t) * size); free (p); if (*geometry == NULL) return (FALSE); return (TRUE); }
static GEOSGeometry* collectFacesWithEvenAncestors(Face** faces, int nfaces) { GEOSGeometry **geoms = lwalloc(sizeof(GEOSGeometry*)*nfaces); GEOSGeometry *ret; unsigned int ngeoms = 0; int i; for (i=0; i<nfaces; ++i) { Face *f = faces[i]; if ( countParens(f) % 2 ) continue; /* we skip odd parents geoms */ geoms[ngeoms++] = GEOSGeom_clone(f->geom); } ret = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, geoms, ngeoms); lwfree(geoms); return ret; }
GEOSGeometry* eterm_to_geom_multi(ErlNifEnv *env, ERL_NIF_TERM eterm, int type, GEOSGeometry*(*eterm_to_geom)(ErlNifEnv *env, const ERL_NIF_TERM *eterm)) { unsigned int i, geoms_num; GEOSGeometry *geom; GEOSGeometry **geoms; ERL_NIF_TERM tail; enif_get_list_length(env, eterm, &geoms_num); geoms = malloc(sizeof(GEOSGeometry*)*geoms_num); for (i=0; enif_get_list_cell(env, eterm , &eterm, &tail); i++) { geoms[i] = (*eterm_to_geom)(env, &eterm); eterm = tail; } geom = GEOSGeom_createCollection(type, geoms, geoms_num); free(geoms); return geom; }
static GEOSGeom msGEOSShape2Geometry_multipoint(lineObj *multipoint) { int i; GEOSGeom g; GEOSGeom *points; if(!multipoint) return NULL; points = malloc(multipoint->numpoints*sizeof(GEOSGeom)); if(!points) return NULL; for(i=0; i<multipoint->numpoints; i++) points[i] = msGEOSShape2Geometry_point(&(multipoint->point[i])); g = GEOSGeom_createCollection(GEOS_MULTIPOINT, points, multipoint->numpoints); free(points); return g; }
static GEOSGeom msGEOSShape2Geometry_multiline(shapeObj *multiline) { int i; GEOSGeom g; GEOSGeom *lines; if(!multiline) return NULL; lines = malloc(multiline->numlines*sizeof(GEOSGeom)); if(!lines) return NULL; for(i=0; i<multiline->numlines; i++) lines[i] = msGEOSShape2Geometry_line(&(multiline->line[i])); g = GEOSGeom_createCollection(GEOS_MULTILINESTRING, lines, multiline->numlines); free(lines); return g; }
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom) { GEOSCoordSeq sq; GEOSGeom g, shell; GEOSGeom *geoms = NULL; /* LWGEOM *tmp; */ uint32_t ngeoms, i; int geostype; #if LWDEBUG_LEVEL >= 4 char *wkt; #endif LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type)); if (lwgeom_has_arc(lwgeom)) { LWDEBUG(3, "LWGEOM2GEOS: arced geometry found."); lwerror("Exception in LWGEOM2GEOS: curved geometry not supported."); return NULL; } switch (lwgeom->type) { LWPOINT *lwp = NULL; LWPOLY *lwpoly = NULL; LWLINE *lwl = NULL; LWCOLLECTION *lwc = NULL; #if POSTGIS_GEOS_VERSION < 33 POINTARRAY *pa = NULL; #endif case POINTTYPE: lwp = (LWPOINT *)lwgeom; if ( lwgeom_is_empty(lwgeom) ) { #if POSTGIS_GEOS_VERSION < 33 pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2); sq = ptarray_to_GEOSCoordSeq(pa); shell = GEOSGeom_createLinearRing(sq); g = GEOSGeom_createPolygon(shell, NULL, 0); #else g = GEOSGeom_createEmptyPolygon(); #endif } else { sq = ptarray_to_GEOSCoordSeq(lwp->point); g = GEOSGeom_createPoint(sq); } if ( ! g ) { /* lwnotice("Exception in LWGEOM2GEOS"); */ return NULL; } break; case LINETYPE: lwl = (LWLINE *)lwgeom; if ( lwl->points->npoints == 1 ) { /* Duplicate point, to make geos-friendly */ lwl->points = ptarray_addPoint(lwl->points, getPoint_internal(lwl->points, 0), FLAGS_NDIMS(lwl->points->flags), lwl->points->npoints); } sq = ptarray_to_GEOSCoordSeq(lwl->points); g = GEOSGeom_createLineString(sq); if ( ! g ) { /* lwnotice("Exception in LWGEOM2GEOS"); */ return NULL; } break; case POLYGONTYPE: lwpoly = (LWPOLY *)lwgeom; if ( lwgeom_is_empty(lwgeom) ) { #if POSTGIS_GEOS_VERSION < 33 POINTARRAY *pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2); sq = ptarray_to_GEOSCoordSeq(pa); shell = GEOSGeom_createLinearRing(sq); g = GEOSGeom_createPolygon(shell, NULL, 0); #else g = GEOSGeom_createEmptyPolygon(); #endif } else { sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[0]); /* TODO: check ring for being closed and fix if not */ shell = GEOSGeom_createLinearRing(sq); if ( ! shell ) return NULL; /*lwerror("LWGEOM2GEOS: exception during polygon shell conversion"); */ ngeoms = lwpoly->nrings-1; if ( ngeoms > 0 ) geoms = malloc(sizeof(GEOSGeom)*ngeoms); for (i=1; i<lwpoly->nrings; ++i) { sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[i]); geoms[i-1] = GEOSGeom_createLinearRing(sq); if ( ! geoms[i-1] ) { --i; while (i) GEOSGeom_destroy(geoms[--i]); free(geoms); GEOSGeom_destroy(shell); return NULL; } /*lwerror("LWGEOM2GEOS: exception during polygon hole conversion"); */ } g = GEOSGeom_createPolygon(shell, geoms, ngeoms); if (geoms) free(geoms); } if ( ! g ) return NULL; break; case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: case COLLECTIONTYPE: if ( lwgeom->type == MULTIPOINTTYPE ) geostype = GEOS_MULTIPOINT; else if ( lwgeom->type == MULTILINETYPE ) geostype = GEOS_MULTILINESTRING; else if ( lwgeom->type == MULTIPOLYGONTYPE ) geostype = GEOS_MULTIPOLYGON; else geostype = GEOS_GEOMETRYCOLLECTION; lwc = (LWCOLLECTION *)lwgeom; ngeoms = lwc->ngeoms; if ( ngeoms > 0 ) geoms = malloc(sizeof(GEOSGeom)*ngeoms); for (i=0; i<ngeoms; ++i) { GEOSGeometry* g = LWGEOM2GEOS(lwc->geoms[i]); if ( ! g ) { while (i) GEOSGeom_destroy(geoms[--i]); free(geoms); return NULL; } geoms[i] = g; } g = GEOSGeom_createCollection(geostype, geoms, ngeoms); if ( geoms ) free(geoms); if ( ! g ) return NULL; break; default: lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type)); return NULL; } GEOSSetSRID(g, lwgeom->srid); #if LWDEBUG_LEVEL >= 4 wkt = GEOSGeomToWKT(g); LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt); free(wkt); #endif return g; }
void QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset ) { if ( !geom || !lineGeom ) { return; } QList<QgsGeometry*> inputGeomList; if ( geom->isMultipart() ) { inputGeomList = geom->asGeometryCollection(); } else { inputGeomList.push_back( geom ); } QList<GEOSGeometry*> outputGeomList; QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin(); for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt ) { if ( geom->type() == QGis::Line ) { //geos 3.3 needed for line offsets #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) outputGeomList.push_back( GEOSOffsetCurve(( *inputGeomIt )->asGeos(), -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ) ); #else outputGeomList.push_back( GEOSGeom_clone(( *inputGeomIt )->asGeos() ) ); #endif } else if ( geom->type() == QGis::Point ) { QgsPoint p = ( *inputGeomIt )->asPoint(); p = createPointOffset( p.x(), p.y(), offset, lineGeom ); GEOSCoordSequence* ptSeq = GEOSCoordSeq_create( 1, 2 ); GEOSCoordSeq_setX( ptSeq, 0, p.x() ); GEOSCoordSeq_setY( ptSeq, 0, p.y() ); GEOSGeometry* geosPt = GEOSGeom_createPoint( ptSeq ); outputGeomList.push_back( geosPt ); } } if ( !geom->isMultipart() ) { GEOSGeometry* outputGeom = outputGeomList.at( 0 ); if ( outputGeom ) { geom->fromGeos( outputGeom ); } } else { GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()]; for ( int i = 0; i < outputGeomList.size(); ++i ) { geomArray[i] = outputGeomList.at( i ); } GEOSGeometry* collection = 0; if ( geom->type() == QGis::Point ) { collection = GEOSGeom_createCollection( GEOS_MULTIPOINT, geomArray, outputGeomList.size() ); } else if ( geom->type() == QGis::Line ) { collection = GEOSGeom_createCollection( GEOS_MULTILINESTRING, geomArray, outputGeomList.size() ); } geom->fromGeos( collection ); delete[] geomArray; } }
static GEOSGeometry * toGeosGeometry (const gaiaGeomCollPtr gaia) { /* converting a GAIA Geometry into a GEOS Geometry */ int pts = 0; int lns = 0; int pgs = 0; int type; int geos_type; unsigned int dims; int iv; int ib; int nItem; double x; double y; double z; double m; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; GEOSGeometry *geos; GEOSGeometry *geos_ext; GEOSGeometry *geos_int; GEOSGeometry *geos_item; GEOSGeometry **geos_holes; GEOSGeometry **geos_coll; GEOSCoordSequence *cs; if (!gaia) return NULL; pt = gaia->FirstPoint; while (pt) { /* counting how many POINTs are there */ pts++; pt = pt->Next; } ln = gaia->FirstLinestring; while (ln) { /* counting how many LINESTRINGs are there */ lns++; ln = ln->Next; } pg = gaia->FirstPolygon; while (pg) { /* counting how many POLYGONs are there */ pgs++; pg = pg->Next; } if (pts == 0 && lns == 0 && pgs == 0) type = GAIA_UNKNOWN; else if (pts == 1 && lns == 0 && pgs == 0) { if (gaia->DeclaredType == GAIA_MULTIPOINT) type = GAIA_MULTIPOINT; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_POINT; } else if (pts == 0 && lns == 1 && pgs == 0) { if (gaia->DeclaredType == GAIA_MULTILINESTRING) type = GAIA_MULTILINESTRING; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_LINESTRING; } else if (pts == 0 && lns == 0 && pgs == 1) { if (gaia->DeclaredType == GAIA_MULTIPOLYGON) type = GAIA_MULTIPOLYGON; else if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_POLYGON; } else if (pts > 1 && lns == 0 && pgs == 0) { if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTIPOINT; } else if (pts == 0 && lns > 1 && pgs == 0) { if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTILINESTRING; } else if (pts == 0 && lns == 0 && pgs > 1) { if (gaia->DeclaredType == GAIA_GEOMETRYCOLLECTION) type = GAIA_GEOMETRYCOLLECTION; else type = GAIA_MULTIPOLYGON; } else type = GAIA_GEOMETRYCOLLECTION; switch (gaia->DimensionModel) { case GAIA_XY_Z: case GAIA_XY_Z_M: dims = 3; break; default: dims = 2; break; }; switch (type) { case GAIA_POINT: pt = gaia->FirstPoint; cs = GEOSCoordSeq_create (1, dims); switch (gaia->DimensionModel) { case GAIA_XY_Z: case GAIA_XY_Z_M: GEOSCoordSeq_setX (cs, 0, pt->X); GEOSCoordSeq_setY (cs, 0, pt->Y); GEOSCoordSeq_setZ (cs, 0, pt->Z); break; default: GEOSCoordSeq_setX (cs, 0, pt->X); GEOSCoordSeq_setY (cs, 0, pt->Y); break; }; geos = GEOSGeom_createPoint (cs); break; case GAIA_LINESTRING: ln = gaia->FirstLinestring; cs = GEOSCoordSeq_create (ln->Points, dims); for (iv = 0; iv < ln->Points; iv++) { switch (ln->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (ln->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos = GEOSGeom_createLineString (cs); break; case GAIA_POLYGON: pg = gaia->FirstPolygon; rng = pg->Exterior; /* exterior ring */ cs = GEOSCoordSeq_create (rng->Points, dims); for (iv = 0; iv < rng->Points; iv++) { switch (rng->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (rng->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos_ext = GEOSGeom_createLinearRing (cs); geos_holes = NULL; if (pg->NumInteriors > 0) { geos_holes = malloc (sizeof (GEOSGeometry *) * pg->NumInteriors); for (ib = 0; ib < pg->NumInteriors; ib++) { /* interior ring */ rng = pg->Interiors + ib; cs = GEOSCoordSeq_create (rng->Points, dims); for (iv = 0; iv < rng->Points; iv++) { switch (rng->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (rng->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos_int = GEOSGeom_createLinearRing (cs); *(geos_holes + ib) = geos_int; } } geos = GEOSGeom_createPolygon (geos_ext, geos_holes, pg->NumInteriors); if (geos_holes) free (geos_holes); break; case GAIA_MULTIPOINT: case GAIA_MULTILINESTRING: case GAIA_MULTIPOLYGON: case GAIA_GEOMETRYCOLLECTION: nItem = 0; geos_coll = malloc (sizeof (GEOSGeometry *) * (pts + lns + pgs)); pt = gaia->FirstPoint; while (pt) { cs = GEOSCoordSeq_create (1, dims); switch (pt->DimensionModel) { case GAIA_XY_Z: case GAIA_XY_Z_M: GEOSCoordSeq_setX (cs, 0, pt->X); GEOSCoordSeq_setY (cs, 0, pt->Y); GEOSCoordSeq_setZ (cs, 0, pt->Z); break; default: GEOSCoordSeq_setX (cs, 0, pt->X); GEOSCoordSeq_setY (cs, 0, pt->Y); break; }; geos_item = GEOSGeom_createPoint (cs); *(geos_coll + nItem++) = geos_item; pt = pt->Next; } ln = gaia->FirstLinestring; while (ln) { cs = GEOSCoordSeq_create (ln->Points, dims); for (iv = 0; iv < ln->Points; iv++) { switch (ln->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (ln->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos_item = GEOSGeom_createLineString (cs); *(geos_coll + nItem++) = geos_item; ln = ln->Next; } pg = gaia->FirstPolygon; while (pg) { rng = pg->Exterior; /* exterior ring */ cs = GEOSCoordSeq_create (rng->Points, dims); for (iv = 0; iv < rng->Points; iv++) { switch (rng->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (rng->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos_ext = GEOSGeom_createLinearRing (cs); geos_holes = NULL; if (pg->NumInteriors > 0) { geos_holes = malloc (sizeof (GEOSGeometry *) * pg->NumInteriors); for (ib = 0; ib < pg->NumInteriors; ib++) { /* interior ring */ rng = pg->Interiors + ib; cs = GEOSCoordSeq_create (rng->Points, dims); for (iv = 0; iv < rng->Points; iv++) { switch (rng->DimensionModel) { case GAIA_XY_Z: gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; case GAIA_XY_M: gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; case GAIA_XY_Z_M: gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); GEOSCoordSeq_setZ (cs, iv, z); break; default: gaiaGetPoint (rng->Coords, iv, &x, &y); GEOSCoordSeq_setX (cs, iv, x); GEOSCoordSeq_setY (cs, iv, y); break; }; } geos_int = GEOSGeom_createLinearRing (cs); *(geos_holes + ib) = geos_int; } } geos_item = GEOSGeom_createPolygon (geos_ext, geos_holes, pg->NumInteriors); if (geos_holes) free (geos_holes); *(geos_coll + nItem++) = geos_item; pg = pg->Next; } geos_type = GEOS_GEOMETRYCOLLECTION; if (type == GAIA_MULTIPOINT) geos_type = GEOS_MULTIPOINT; if (type == GAIA_MULTILINESTRING) geos_type = GEOS_MULTILINESTRING; if (type == GAIA_MULTIPOLYGON) geos_type = GEOS_MULTIPOLYGON; geos = GEOSGeom_createCollection (geos_type, geos_coll, pts + lns + pgs); if (geos_coll) free (geos_coll); break; default: geos = NULL; }; if (geos) GEOSSetSRID (geos, gaia->Srid); return geos; }