long long msudf_isValid(UDF_INIT *initid,UDF_ARGS *args,char *is_null, char *error) { GEOSGeom geom; long long result; DEBUG("msudf_isValid"); geom = msudf_getGeometry((unsigned char *)args->args[0],args->lengths[0]); if (geom == NULL) { strcpy(error,"Invalid geometry."); *is_null = 1; return 0; } result = GEOSisValid(geom); if (geom != NULL) GEOSGeom_destroy(geom); if (result >1) { *is_null = 1; return 0; } else { return result; } }
int main(void) { GEOSWKTReader *reader; GEOSGeometry *mp; GEOSGeometry *p; const GEOSPreparedGeometry *prep_mp; unsigned long int i; unsigned long int count = 1e6; initGEOS(NULL, NULL); reader = GEOSWKTReader_create(); mp = GEOSWKTReader_read(reader, "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))"); p = GEOSWKTReader_read(reader, "POLYGON((2 2, 6 2, 6 6, 2 6, 2 2))"); assert(GEOSisValid(mp)); assert(GEOSisValid(p)); prep_mp = GEOSPrepare(mp); for (i=0; i<count; i++) { if ( !(i%100) ) printf("%lu iterations\n", i); /* does not leak */ /* GEOSContains(mp, p); */ /* leaks */ GEOSPreparedContains(prep_mp, p); } printf("%lu iterations (END)\n", i); return 0; }
void geo_valid(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) { char empty = (GEOSisValid(geometry) == 1) ? 1 : 0; sqlite3_result_int(context,empty); } GEOSGeom_destroy(geometry); finishGEOS(); } }
void OGRILI1Layer::PolygonizeAreaLayer() { if (poAreaLineLayer == 0) return; //add all lines from poAreaLineLayer to collection OGRGeometryCollection *gc = new OGRGeometryCollection(); poAreaLineLayer->ResetReading(); while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef()) gc->addGeometry(feature->GetGeometryRef()); //polygonize lines CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries()); OGRMultiPolygon* polys = Polygonize( gc , false); CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); if (polys->getNumGeometries() != poAreaReferenceLayer->GetFeatureCount()) { CPLDebug( "OGR_ILI", "Feature count of layer %s: %d", poAreaReferenceLayer->GetLayerDefn()->GetName(), GetFeatureCount()); CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix"); delete polys; polys = Polygonize( gc, true ); //try again with crossing line fix } delete gc; //associate polygon feature with data row according to centroid #if defined(HAVE_GEOS) int i; OGRPolygon emptyPoly; GEOSGeom *ahInGeoms = NULL; CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName()); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),polys->getNumGeometries()); for( i = 0; i < polys->getNumGeometries(); i++ ) { ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(); if (!GEOSisValid(ahInGeoms[i])) ahInGeoms[i] = NULL; } poAreaReferenceLayer->ResetReading(); while (OGRFeature *feature = poAreaReferenceLayer->GetNextFeatureRef()) { GEOSGeom point = (GEOSGeom)feature->GetGeometryRef()->exportToGEOS(); for (i = 0; i < polys->getNumGeometries(); i++ ) { if (ahInGeoms[i] && GEOSWithin(point, ahInGeoms[i])) { OGRFeature* areaFeature = feature->Clone(); areaFeature->SetGeometry( polys->getGeometryRef(i) ); AddFeature(areaFeature); break; } } if (i == polys->getNumGeometries()) { CPLDebug( "OGR_ILI", "Association between area and point failed."); feature->SetGeometry( &emptyPoly ); } GEOSGeom_destroy( point ); } for( i = 0; i < polys->getNumGeometries(); i++ ) GEOSGeom_destroy( ahInGeoms[i] ); CPLFree( ahInGeoms ); #endif poAreaReferenceLayer = 0; poAreaLineLayer = 0; }
bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText, double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle, int xQuadOffset, int yQuadOffset, double xOffset, double yOffset ) { if ( !geom_id || label_x < 0 || label_y < 0 ) return false; modMutex->lock(); if ( hashtable->find( geom_id ) ) { modMutex->unlock(); //A feature with this id already exists. Don't throw an exception as sometimes, //the same feature is added twice (dateline split with otf-reprojection) return false; } // Split MULTI GEOM and Collection in simple geometries GEOSGeometry *the_geom = userGeom->getGeosGeometry(); Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y ); if ( fixedPos ) { f->setFixedPosition( labelPosX, labelPosY ); } if ( xQuadOffset != 0 || yQuadOffset != 0 ) { f->setQuadOffset( xQuadOffset, yQuadOffset ); } if ( xOffset != 0.0 || yOffset != 0.0 ) { f->setPosOffset( xOffset, yOffset ); } if ( fixedAngle ) { f->setFixedAngle( angle ); } // use layer-level defined rotation, but not if position fixed if ( !fixedPos && angle != 0.0 ) { f->setFixedAngle( angle ); } bool first_feat = true; double geom_size = -1, biggest_size = -1; FeaturePart* biggest_part = NULL; // break the (possibly multi-part) geometry into simple geometries LinkedList <const GEOSGeometry*> *simpleGeometries = unmulti( the_geom ); if ( simpleGeometries == NULL ) // unmulti() failed? { modMutex->unlock(); throw InternalException::UnknownGeometry(); } while ( simpleGeometries->size() > 0 ) { const GEOSGeometry* geom = simpleGeometries->pop_front(); // ignore invalid geometries (e.g. polygons with self-intersecting rings) if ( GEOSisValid( geom ) != 1 ) // 0=invalid, 1=valid, 2=exception { std::cerr << "ignoring invalid feature " << geom_id << std::endl; continue; } int type = GEOSGeomTypeId( geom ); if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON ) { modMutex->unlock(); throw InternalException::UnknownGeometry(); } FeaturePart* fpart = new FeaturePart( f, geom ); // ignore invalid geometries if (( type == GEOS_LINESTRING && fpart->nbPoints < 2 ) || ( type == GEOS_POLYGON && fpart->nbPoints < 3 ) ) { delete fpart; continue; } // polygons: reorder coordinates if ( type == GEOS_POLYGON && reorderPolygon( fpart->nbPoints, fpart->x, fpart->y ) != 0 ) { delete fpart; continue; } if ( mode == LabelPerFeature && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) ) { if ( type == GEOS_LINESTRING ) GEOSLength( geom, &geom_size ); else if ( type == GEOS_POLYGON ) GEOSArea( geom, &geom_size ); if ( geom_size > biggest_size ) { biggest_size = geom_size; delete biggest_part; // safe with NULL part biggest_part = fpart; } continue; // don't add the feature part now, do it later // TODO: we should probably add also other parts to act just as obstacles } // feature part is ready! addFeaturePart( fpart, labelText ); first_feat = false; } delete simpleGeometries; userGeom->releaseGeosGeometry( the_geom ); modMutex->unlock(); // if using only biggest parts... if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL ) { addFeaturePart( biggest_part, labelText ); first_feat = false; } // add feature to layer if we have added something if ( !first_feat ) { features->push_back( f ); hashtable->insertItem( geom_id, f ); } else { delete f; } return !first_feat; // true if we've added something }
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 )