static YAP_Bool line_to_geometry (YAP_Term term, geometry_type_t type, geometry_t *geometry) { sequence_t sequence; unsigned int size; assert ((type == GEOS_LINESTRING) || (type == GEOS_LINEARRING)); assert (geometry != NULL); term = YAP_ArgOfTerm (1, term); if ((is_list_get_size (term, &size) == FALSE) || ((type == GEOS_LINESTRING) && (size < 2)) || ((type == GEOS_LINEARRING) && (size < 4))) return (FALSE); if (point_list_to_sequence (term, size, &sequence) == FALSE) return (FALSE); if (type == GEOS_LINESTRING) *geometry = GEOSGeom_createLineString (sequence); else *geometry = GEOSGeom_createLinearRing (sequence); if (*geometry == NULL) return (FALSE); return (TRUE); }
GEOSGeometry* eterm_to_geom_linestring(ErlNifEnv *env, const ERL_NIF_TERM *eterm) { GEOSCoordSequence *coords_seq = eterm_to_geom_linestring_coords(env, eterm); return GEOSGeom_createLineString(coords_seq); }
void geo_bound(sqlite3_context *context,int argc,sqlite3_value **argv) { if(argc >= 1) { const unsigned char* ogc; unsigned char* ret_geo_buf; size_t size; double x1,x2,y1,y2; GEOSCoordSequence* seq = 0; GEOSGeometry* geometry = 0; GEOSGeometry* middle_geo = 0; _init_geos(); if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_BLOB) { size = sqlite3_value_bytes(argv[0]); ogc = (const unsigned char*)sqlite3_value_blob(argv[0]); middle_geo = _geo_from_wkb(ogc,size); } else if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_TEXT) { ogc = sqlite3_value_text(argv[0]); middle_geo = _geo_from_wkt(ogc); } else if(argc == 4) { x1 = sqlite3_value_double(argv[0]); y1 = sqlite3_value_double(argv[1]); x2 = sqlite3_value_double(argv[2]); y2 = sqlite3_value_double(argv[3]); seq = GEOSCoordSeq_create(2,2); GEOSCoordSeq_setX(seq,0,x1); GEOSCoordSeq_setY(seq,0,y1); GEOSCoordSeq_setX(seq,1,x2); GEOSCoordSeq_setY(seq,1,y2); middle_geo = GEOSGeom_createLineString(seq); } if(middle_geo != 0) { geometry = GEOSEnvelope(middle_geo); if(geometry != 0) { ret_geo_buf = GEOSGeomToWKB_buf(geometry,&size); sqlite3_result_blob(context,ret_geo_buf,size,SQLITE_TRANSIENT); GEOSGeom_destroy(geometry); GEOSFree(ret_geo_buf); } GEOSGeom_destroy(middle_geo); } finishGEOS(); } }
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 GEOSGeom msGEOSShape2Geometry_line(lineObj *line) { int i; GEOSGeom g; GEOSCoordSeq coords; if(!line) return NULL; coords = GEOSCoordSeq_create(line->numpoints, 2); /* todo handle z's */ if(!coords) return NULL; for(i=0; i<line->numpoints; i++) { GEOSCoordSeq_setX(coords, i, line->point[i].x); GEOSCoordSeq_setY(coords, i, line->point[i].y); /* GEOSCoordSeq_setZ(coords, i, line->point[i].z); */ } g = GEOSGeom_createLineString(coords); /* g owns the coordinates in coords */ return g; }
void QgsZonalStatistics::statisticsFromMiddlePointTest_improved( void* band, QgsGeometry* poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, double& sum, double& count ) { double cellCenterX, cellCenterY; QgsPoint currentCellCenter; float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX ); cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; count = 0; sum = 0; for ( int i = 0; i < nCellsY; ++i ) { GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 ); cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2; //do intersection of scanline with geometry GEOSCoordSequence* scanLineSequence = GEOSCoordSeq_create( 2, 2 ); GEOSCoordSeq_setX( scanLineSequence, 0, cellCenterX ); GEOSCoordSeq_setY( scanLineSequence, 0, cellCenterY ); GEOSCoordSeq_setX( scanLineSequence, 1, cellCenterX + nCellsX * cellSizeX ); GEOSCoordSeq_setY( scanLineSequence, 1, cellCenterY ); GEOSGeometry* scanLineGeos = GEOSGeom_createLineString( scanLineSequence ); //todo: delete GEOSGeometry* polyGeos = poly->asGeos(); GEOSGeometry* scanLineIntersection = GEOSIntersection( scanLineGeos, polyGeos ); GEOSGeom_destroy( scanLineGeos ); if ( !scanLineIntersection ) { cellCenterY -= cellSizeY; continue; } //debug //char* scanLineIntersectionType = GEOSGeomType( scanLineIntersection ); int numGeoms = GEOSGetNumGeometries( scanLineIntersection ); if ( numGeoms < 1 ) { GEOSGeom_destroy( scanLineIntersection ); cellCenterY -= cellSizeY; continue; } QList<double> scanLineList; double currentValue; GEOSGeometry* currentGeom = 0; for ( int z = 0; z < numGeoms; ++z ) { if ( numGeoms == 1 ) { currentGeom = scanLineIntersection; } else { currentGeom = GEOSGeom_clone( GEOSGetGeometryN( scanLineIntersection, z ) ); } const GEOSCoordSequence* scanLineCoordSequence = GEOSGeom_getCoordSeq( currentGeom ); if ( !scanLineCoordSequence ) { //error } unsigned int scanLineIntersectionSize; GEOSCoordSeq_getSize( scanLineCoordSequence, &scanLineIntersectionSize ); if ( !scanLineCoordSequence || scanLineIntersectionSize < 2 || ( scanLineIntersectionSize & 1 ) ) { //error } for ( unsigned int k = 0; k < scanLineIntersectionSize; ++k ) { GEOSCoordSeq_getX( scanLineCoordSequence, k, ¤tValue ); scanLineList.push_back( currentValue ); } if ( numGeoms != 1 ) { GEOSGeom_destroy( currentGeom ); } } GEOSGeom_destroy( scanLineIntersection ); qSort( scanLineList ); if ( scanLineList.size() < 1 ) { cellCenterY -= cellSizeY; continue; } int listPlace = -1; for ( int j = 0; j < nCellsX; ++j ) { //currentCellCenter = QgsPoint( cellCenterX, cellCenterY ); //instead of doing a contained test every time, find the place of scanLineList and check if even / odd if ( listPlace >= scanLineList.size() - 1 ) { break; } if ( cellCenterX >= scanLineList.at( listPlace + 1 ) ) { ++listPlace; if ( listPlace >= scanLineList.size() ) { break; } } if ( listPlace >= 0 && listPlace < ( scanLineList.size() - 1 ) && !( listPlace & 1 ) ) { if ( scanLine[j] != mInputNodataValue ) //don't consider nodata values { sum += scanLine[j]; ++count; } } cellCenterX += cellSizeX; } cellCenterY -= cellSizeY; } CPLFree( scanLine ); }
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 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 )
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; }