static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g) { int i; int numPoints; GEOSCoordSeq coords; GEOSGeom point; shapeObj *shape=NULL; if(!g) return NULL; numPoints = GEOSGetNumGeometries(g); /* each geometry has 1 point */ shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POINT; shape->line = (lineObj *) malloc(sizeof(lineObj)); shape->numlines = 1; shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints); shape->line[0].numpoints = numPoints; shape->geometry = (GEOSGeom) g; for(i=0; i<numPoints; i++) { point = (GEOSGeom) GEOSGetGeometryN(g, i); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(point); GEOSCoordSeq_getX(coords, 0, &(shape->line[0].point[i].x)); GEOSCoordSeq_getY(coords, 0, &(shape->line[0].point[i].y)); /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[i].z)); */ } msComputeBounds(shape); return shape; }
static size_t asgeojson_multiline_buf(GEOSGeom mline, char *srs, char *output, bbox3D *bbox, int precision) { GEOSGeom line; int i, ngeoms = GEOSGetNumGeometries(mline); char *ptr=output; ptr += sprintf(ptr, "{\"type\":\"MultiLineString\","); if (srs) ptr += asgeojson_srs_buf(ptr, srs); if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, GEOS_getWKBOutputDims(mline) == 3, precision); ptr += sprintf(ptr, "\"coordinates\":["); for (i=0; i<ngeoms; i++) { if (i) ptr += sprintf(ptr, ","); ptr += sprintf(ptr, "["); line = (GEOSGeom ) GEOSGetGeometryN(mline, i); ptr += points_to_geojson(line, ptr, precision); ptr += sprintf(ptr, "]"); } ptr += sprintf(ptr, "]}"); return (ptr - output); }
void object::test<2>() { const int size = 6; GEOSGeometry* geoms[size] = { 0 }; // Example from JTS Developer's Guide, Chapter 6 - Polygonization geoms[0] = GEOSGeomFromWKT("LINESTRING(0 0, 10 10)"); // isolated edge geoms[1] = GEOSGeomFromWKT("LINESTRING(185 221, 100 100)"); // dangling edge geoms[2] = GEOSGeomFromWKT("LINESTRING(185 221, 88 275, 180 316)"); geoms[3] = GEOSGeomFromWKT("LINESTRING(185 221, 292 281, 180 316)"); geoms[4] = GEOSGeomFromWKT("LINESTRING(189 98, 83 187, 185 221)"); geoms[5] = GEOSGeomFromWKT("LINESTRING(189 98, 325 168, 185 221)"); GEOSGeometry* g = GEOSPolygonizer_getCutEdges(geoms, size); ensure(0 != g); ensure_equals(GEOSGetNumGeometries(g), 0); GEOSGeom_destroy(g); for (int i = 0; i < size; ++i) { if (0 != geoms[i]) GEOSGeom_destroy(geoms[i]); } }
static size_t asgeojson_multipolygon_size(GEOSGeom mpoly, char *srs, bbox3D *bbox, int precision) { GEOSGeom poly; int size; int i, j, ngeoms = GEOSGetNumGeometries(mpoly); size = sizeof("{'type':'MultiPolygon',"); if (srs) size += asgeojson_srs_size(srs); if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(mpoly) == 3, precision); size += sizeof("'coordinates':[]}"); for (i=0; i < ngeoms; i++) { int nrings; poly = (GEOSGeom ) GEOSGetGeometryN(mpoly, i); nrings = GEOSGetNumInteriorRings(poly); for (j=0 ; j <nrings ; j++) { size += points_geojson_size(*(GEOSGeom*)GEOSGetInteriorRingN(poly, j), precision); size += sizeof("[]"); } size += sizeof("[]"); } size += sizeof(",") * i; size += sizeof("]}"); return size; }
static size_t asgeojson_multipolygon_buf(GEOSGeom mpoly, char *srs, char *output, bbox3D *bbox, int precision) { GEOSGeom poly; int i, j, ngeoms = GEOSGetNumGeometries(mpoly); char *ptr=output; ptr += sprintf(ptr, "{\"type\":\"MultiPolygon\","); if (srs) ptr += asgeojson_srs_buf(ptr, srs); if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, GEOS_getWKBOutputDims(mpoly) == 3, precision); ptr += sprintf(ptr, "\"coordinates\":["); for (i=0; i<ngeoms; i++) { int nrings; if (i) ptr += sprintf(ptr, ","); ptr += sprintf(ptr, "["); poly = (GEOSGeom ) GEOSGetGeometryN(mpoly, i); nrings = GEOSGetNumInteriorRings(poly); for (j=0 ; j < nrings ; j++) { if (j) ptr += sprintf(ptr, ","); ptr += sprintf(ptr, "["); ptr += points_to_geojson(*(GEOSGeom*)GEOSGetInteriorRingN(poly, j), ptr, precision); ptr += sprintf(ptr, "]"); } ptr += sprintf(ptr, "]"); } ptr += sprintf(ptr, "]}"); return (ptr - output); }
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 make_multi_to_term (geometry_t geometry, procedure_to_term_t procedure, const char * functor_name, YAP_Term *term) { int n; geometry_t geometry_n; YAP_Functor functor; unsigned int size; YAP_Term list, head; assert (term != NULL); list = YAP_MkAtomTerm (YAP_LookupAtom ("[]")); size = GEOSGetNumGeometries (geometry); for (n = size - 1; n >= 0; n --) { geometry_n = (geometry_t) GEOSGetGeometryN (geometry, n); if (procedure (geometry_n, NULL, &head) == FALSE) return (FALSE); list = YAP_MkPairTerm (head, list); } functor = YAP_MkFunctor (YAP_LookupAtom (functor_name), 1); *term = YAP_MkApplTerm (functor, 1, &list); return (TRUE); }
LWGEOM* lwgeom_buildarea(const LWGEOM *geom) { GEOSGeometry* geos_in; GEOSGeometry* geos_out; LWGEOM* geom_out; int SRID = (int)(geom->srid); int is3d = FLAGS_GET_Z(geom->flags); /* Can't build an area from an empty! */ if ( lwgeom_is_empty(geom) ) { return (LWGEOM*)lwpoly_construct_empty(SRID, is3d, 0); } LWDEBUG(3, "buildarea called"); LWDEBUGF(3, "ST_BuildArea got geom @ %p", geom); initGEOS(lwnotice, lwgeom_geos_error); geos_in = LWGEOM2GEOS(geom); if ( 0 == geos_in ) /* exception thrown at construction */ { lwerror("First argument geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); return NULL; } geos_out = LWGEOM_GEOS_buildArea(geos_in); GEOSGeom_destroy(geos_in); if ( ! geos_out ) /* exception thrown.. */ { lwerror("LWGEOM_GEOS_buildArea: %s", lwgeom_geos_errmsg); return NULL; } /* If no geometries are in result collection, return NULL */ if ( GEOSGetNumGeometries(geos_out) == 0 ) { GEOSGeom_destroy(geos_out); return NULL; } geom_out = GEOS2LWGEOM(geos_out, is3d); GEOSGeom_destroy(geos_out); #if PARANOIA_LEVEL > 0 if ( geom_out == NULL ) { lwerror("serialization error"); return NULL; } #endif return geom_out; }
//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; }
void object::test<1>() { const int size = 2; GEOSGeometry* geoms[size] = { 0 }; geoms[0] = GEOSGeomFromWKT("LINESTRING(1 3, 3 3, 3 1, 1 1, 1 3)"); geoms[1] = GEOSGeomFromWKT("LINESTRING(1 3, 3 3, 3 1, 1 1, 1 3)"); GEOSGeometry* g = GEOSPolygonizer_getCutEdges(geoms, size); ensure(0 != g); ensure_equals(GEOSGetNumGeometries(g), size); GEOSGeom_destroy(g); GEOSGeom_destroy(geoms[0]); GEOSGeom_destroy(geoms[1]); }
void geo_subgeos(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) { int sub_geos = GEOSGetNumGeometries(geometry); sqlite3_result_int(context,sub_geos); } GEOSGeom_destroy(geometry); finishGEOS(); } }
// Creates the coordinates for a multi-geometry. static ERL_NIF_TERM geom_to_eterm_multi_coords(ErlNifEnv *env, const GEOSGeometry *multi_geom, ERL_NIF_TERM(*geom_to_eterm_coords)(ErlNifEnv *env, const GEOSGeometry *geom)) { int geom_num, i; const GEOSGeometry *geom; ERL_NIF_TERM coords; ERL_NIF_TERM *coords_multi; geom_num = GEOSGetNumGeometries(multi_geom); coords_multi = malloc(sizeof(ERL_NIF_TERM)*geom_num); for (i=0; i<geom_num; i++) { geom = GEOSGetGeometryN(multi_geom, i); coords_multi[i] = (*geom_to_eterm_coords)(env, geom); } coords = enif_make_list_from_array(env, coords_multi, geom_num); free(coords_multi); return coords; }
static size_t asgeojson_multipoint_size(GEOSGeom mpoint, char *srs, bbox3D *bbox, int precision) { GEOSGeom point; int size; int i, ngeoms = GEOSGetNumGeometries(mpoint); size = sizeof("{'type':'MultiPoint',"); if (srs) size += asgeojson_srs_size(srs); if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(mpoint) == 3, precision); size += sizeof("'coordinates':[]}"); for (i=0; i<ngeoms; i++) { point = (GEOSGeom ) GEOSGetGeometryN(mpoint, i); size += points_geojson_size(point, precision); } size += sizeof(",") * i; return size; }
static shapeObj *msGEOSGeometry2Shape_multiline(GEOSGeom g) { int i, j; int numPoints, numLines; GEOSCoordSeq coords; GEOSGeom lineString; shapeObj *shape=NULL; lineObj line; if(!g) return NULL; numLines = GEOSGetNumGeometries(g); shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_LINE; shape->geometry = (GEOSGeom) g; for(j=0; j<numLines; j++) { lineString = (GEOSGeom) GEOSGetGeometryN(g, j); numPoints = GEOSGetNumCoordinates(lineString); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(lineString); 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; }
YAP_Bool geometrycollection_to_term (geometry_t geometry, YAP_Term *term) { int n; geometry_t geometry_n; YAP_Functor functor; unsigned int size; YAP_Term head; assert (term != NULL); *term = YAP_MkAtomTerm (YAP_LookupAtom ("[]")); size = GEOSGetNumGeometries (geometry); for (n = size - 1; n >= 0; n --) { geometry_n = (geometry_t) GEOSGetGeometryN (geometry, n); if (geometry_to_term (geometry_n, &head) == FALSE) return (FALSE); *term = YAP_MkPairTerm (head, *term); } functor = YAP_MkFunctor (YAP_LookupAtom (NAME_GEOMETRYCOLLECTION), 1); *term = YAP_MkApplTerm (functor, 1, term); return (TRUE); }
static size_t asgeojson_multiline_size(GEOSGeom mline, char *srs, bbox3D *bbox, int precision) { GEOSGeom line; int size; int i, ngeoms = GEOSGetNumGeometries(mline); size = sizeof("{'type':'MultiLineString',"); if (srs) size += asgeojson_srs_size(srs); if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(mline) == 3, precision); size += sizeof("'coordinates':[]}"); for (i=0 ; i<ngeoms; i++) { line = (GEOSGeom ) GEOSGetGeometryN(mline, i); size += points_geojson_size(line, precision); size += sizeof("[]"); } size += sizeof(",") * i; return size; }
static size_t asgeojson_collection_size(GEOSGeom col, char *srs, bbox3D *bbox, int precision) { int i,ngeoms = GEOSGetNumGeometries(col); int size; GEOSGeom subgeom; size = sizeof("{'type':'GeometryCollection',"); if (srs) size += asgeojson_srs_size(srs); if (bbox) size += asgeojson_bbox_size(GEOS_getWKBOutputDims(col) == 3, precision); size += sizeof("'geometries':"); for (i=0; i<ngeoms; i++) { subgeom = (GEOSGeom ) GEOSGetGeometryN(col, i); size += asgeojson_geom_size(subgeom, NULL, precision); } size += sizeof(",") * i; size += sizeof("]}"); return size; }
static size_t asgeojson_collection_buf(GEOSGeom col, char *srs, char *output, bbox3D *bbox, int precision) { int i, ngeoms = GEOSGetNumGeometries(col); char *ptr=output; GEOSGeom subgeom; ptr += sprintf(ptr, "{\"type\":\"GeometryCollection\","); if (srs) ptr += asgeojson_srs_buf(ptr, srs); if (ngeoms && bbox) ptr += asgeojson_bbox_buf(ptr, bbox, GEOS_getWKBOutputDims(col) == 3, precision); ptr += sprintf(ptr, "\"geometries\":["); for (i=0; i<ngeoms; i++) { if (i) ptr += sprintf(ptr, ","); subgeom = (GEOSGeom ) GEOSGetGeometryN(col, i); ptr += asgeojson_geom_buf(subgeom, ptr, NULL, precision); } ptr += sprintf(ptr, "]}"); return (ptr - output); }
/* 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; } }
/* 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; }
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 ); }
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; }
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); Face ** geoms; vgeoms[0] = geom_in; #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Polygonizing"); #endif 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); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Num geometries from polygonizer: %d", ngeoms); #endif 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; } LWDEBUGF(2, "Polygonize returned %d geoms", ngeoms); /* * Polygonizer returns a polygon for each face in the built topology. * * This means that for any face with holes we'll have other faces * representing each hole. We can imagine a parent-child relationship * between these faces. * * In order to maximize the number of visible rings in output we * only use those faces which have an even number of parents. * * Example: * * +---------------+ * | L0 | L0 has no parents * | +---------+ | * | | L1 | | L1 is an hole of L0 * | | +---+ | | * | | |L2 | | | L2 is an hole of L1 (which is an hole of L0) * | | | | | | * | | +---+ | | * | +---------+ | * | | * +---------------+ * * See http://trac.osgeo.org/postgis/ticket/1806 * */ #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Preparing face structures"); #endif /* Prepare face structures for later analysis */ geoms = lwalloc(sizeof(Face**)*ngeoms); for (i=0; i<ngeoms; ++i) geoms[i] = newFace(GEOSGetGeometryN(geos_result, i)); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Finding face holes"); #endif /* Find faces representing other faces holes */ findFaceHoles(geoms, ngeoms); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Colletting even ancestor faces"); #endif /* Build a MultiPolygon composed only by faces with an * even number of ancestors */ tmp = collectFacesWithEvenAncestors(geoms, ngeoms); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Cleaning up"); #endif /* Cleanup face structures */ for (i=0; i<ngeoms; ++i) delFace(geoms[i]); lwfree(geoms); /* Faces referenced memory owned by geos_result. * It is safe to destroy geos_result after deleting them. */ GEOSGeom_destroy(geos_result); #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Self-unioning"); #endif /* Run a single overlay operation to dissolve shared edges */ shp = GEOSUnionCascaded(tmp); if ( ! shp ) { GEOSGeom_destroy(tmp); return 0; /* exception */ } #ifdef LWGEOM_PROFILE_BUILDAREA lwnotice("Final cleanup"); #endif GEOSGeom_destroy(tmp); GEOSSetSRID(shp, srid); return shp; }
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; }
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; }
static shapeObj *msGEOSGeometry2Shape_multipolygon(GEOSGeom g) { int i, j, k; shapeObj *shape=NULL; lineObj line; int numPoints, numRings, numPolygons; GEOSCoordSeq coords; GEOSGeom polygon, ring; if(!g) return NULL; numPolygons = GEOSGetNumGeometries(g); shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POLYGON; shape->geometry = (GEOSGeom) g; for(k=0; k<numPolygons; k++) { /* for each polygon */ polygon = (GEOSGeom) GEOSGetGeometryN(g, k); /* exterior ring */ ring = (GEOSGeom) GEOSGetExteriorRing(polygon); 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(polygon); for(j=0; j<numRings; j++) { ring = (GEOSGeom) GEOSGetInteriorRingN(polygon, 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); } } /* next polygon */ msComputeBounds(shape); return shape; }
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; }