Пример #1
0
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;
	}
}
Пример #2
0
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;
}
Пример #3
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();
	}
}
Пример #4
0
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;
}
Пример #5
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 )