Beispiel #1
0
    void object::test<1>()
    {
        cs_ = GEOSCoordSeq_create(5, 3);
        
        unsigned int size;
        unsigned int dims;

        ensure ( 0 != GEOSCoordSeq_getSize(cs_, &size) );
        ensure_equals( size, 5u );

        ensure ( 0 != GEOSCoordSeq_getDimensions(cs_, &dims) );
        ensure_equals( dims, 3u );

        for (unsigned int i=0; i<5; ++i)
        {
            double x = i*10;
            double y = i*10+1;
            double z = i*10+2;

            GEOSCoordSeq_setX(cs_, i, x);
            GEOSCoordSeq_setY(cs_, i, y);
            GEOSCoordSeq_setZ(cs_, i, z);

            double xcheck, ycheck, zcheck;
            ensure( 0 != GEOSCoordSeq_getX(cs_, i, &xcheck) );
            ensure( 0 != GEOSCoordSeq_getY(cs_, i, &ycheck) );
            ensure( 0 != GEOSCoordSeq_getZ(cs_, i, &zcheck) );

            ensure_equals( xcheck, x );
            ensure_equals( ycheck, y );
            ensure_equals( zcheck, z );
        }
    }   
Beispiel #2
0
    void object::test<4>()
    {
        cs_ = GEOSCoordSeq_create(1, 3);
        
        unsigned int size;
        unsigned int dims;

        ensure ( 0 != GEOSCoordSeq_getSize(cs_, &size) );
        ensure_equals( size, 1u );

        ensure ( 0 != GEOSCoordSeq_getDimensions(cs_, &dims) );
        ensure_equals( dims, 3u );

        double x = 10;
        double y = 11;
        double z = 12;

        // Y, X, Z
        GEOSCoordSeq_setY(cs_, 0, y);
        GEOSCoordSeq_setX(cs_, 0, x);
        GEOSCoordSeq_setZ(cs_, 0, z);

        double xcheck, ycheck, zcheck;
        ensure( 0 != GEOSCoordSeq_getY(cs_, 0, &ycheck) );
        ensure( 0 != GEOSCoordSeq_getX(cs_, 0, &xcheck) );
        ensure( 0 != GEOSCoordSeq_getZ(cs_, 0, &zcheck) );

        ensure_equals( xcheck, x );
        ensure_equals( ycheck, y );
        ensure_equals( zcheck, z );
    }   
    void object::test<8>() {
        // cw orientation
        cs_ = GEOSCoordSeq_create(4, 2);
        char ccw;

        GEOSCoordSeq_setX(cs_, 0, 0);
        GEOSCoordSeq_setY(cs_, 0, 0);

        GEOSCoordSeq_setX(cs_, 1, 1);
        GEOSCoordSeq_setY(cs_, 1, 1);

        GEOSCoordSeq_setX(cs_, 2, 1);
        GEOSCoordSeq_setY(cs_, 2, 0);

        GEOSCoordSeq_setX(cs_, 3, 0);
        GEOSCoordSeq_setY(cs_, 3, 0);

        ensure_equals(GEOSCoordSeq_isCCW(cs_, &ccw), 1);
        ensure(!ccw );
    }
    void object::test<4>()
    {
        GEOSCoordSequence* cs = GEOSCoordSeq_create(5, 2);

        double nan = std::numeric_limits<double>::quiet_NaN();        
        GEOSCoordSeq_setX(cs, 0, 1); GEOSCoordSeq_setY(cs, 0, 1);
        for (unsigned int i=1; i<4; ++i) {
            GEOSCoordSeq_setX(cs, i, nan);
            GEOSCoordSeq_setY(cs, i, nan);
        }
        GEOSCoordSeq_setX(cs, 4, 1); GEOSCoordSeq_setY(cs, 4, 1);

        geom1_ = GEOSGeom_createPolygon(GEOSGeom_createLinearRing(cs),
                                        NULL, 0);

        char const r1 = GEOSIntersects(geom1_, geom1_);

        ensure_equals(int(r1), 2);
        
    }
Beispiel #5
0
/*
** Translation functions
*/
static GEOSGeom msGEOSShape2Geometry_point(pointObj *point)
{
  GEOSCoordSeq coords;
  GEOSGeom g;
  
  if(!point) return NULL;
  
  coords = GEOSCoordSeq_create(1, 2); /* todo handle z's */
  if(!coords) return NULL;
  
  GEOSCoordSeq_setX(coords, 0, point->x);
  GEOSCoordSeq_setY(coords, 0, point->y);
  /* GEOSCoordSeq_setY(coords, 0, point->z); */

  g = GEOSGeom_createPoint(coords); /* g owns the coordinate in coords */
  
  return g;
}
Beispiel #6
0
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;
}
Beispiel #7
0
GEOSCoordSequence *Geometry::ApplyPointTransformationToCoordSequence(PointTransformer *t, const GEOSCoordSequence *seq)
{
    GEOSCoordSequence   *ret = GEOSCoordSeq_clone(seq);
    unsigned int        sz;
    
    GEOSCoordSeq_getSize(ret, &sz);

    for (unsigned int i = 0; i < sz; i++) {
        double x, y;

        GEOSCoordSeq_getX(ret, i, &x);
        GEOSCoordSeq_getY(ret, i, &y);

        t->Transform(&x, &y, NULL);

        GEOSCoordSeq_setX(ret, i, x);
        GEOSCoordSeq_setY(ret, i, y);
    }    
    
    return ret;
}
Beispiel #8
0
YAP_Bool point_to_geometry (YAP_Term term, geometry_t *geometry)
{
  sequence_t sequence;
  YAP_Float x, y;
  YAP_Functor functor;
  const char * functor_name;
  unsigned int arity;

  assert (geometry != NULL);
  if (YAP_IsApplTerm (term) == FALSE)
    return (FALSE);

  functor = YAP_FunctorOfTerm (term);
  functor_name = YAP_AtomName (YAP_NameOfFunctor (functor));
  arity = YAP_ArityOfFunctor (functor);
  if ((strcmp (functor_name, NAME_POINT) != 0) || (arity != 2))
    return (FALSE);

  if ((Yap_IsNumberTerm (YAP_ArgOfTerm (1, term), &x) == FALSE)
      || (Yap_IsNumberTerm (YAP_ArgOfTerm (2, term), &y) == FALSE))
    return (FALSE);

  sequence = GEOSCoordSeq_create (1, 2);
  if (sequence == NULL)
    return (FALSE);
  if ((GEOSCoordSeq_setX (sequence, 0, x) == 0)
      || (GEOSCoordSeq_setY (sequence, 0, y) == 0))
    {
      GEOSCoordSeq_destroy (sequence);
      return (FALSE);
    }
  *geometry = GEOSGeom_createPoint (sequence);
  if (*geometry == NULL)
    return (FALSE);

  return (TRUE);
}
Beispiel #9
0
    GEOSGeometry* random_polygon(double x, double y, double r, size_t num_points)
    {
        std::vector<double> angle(num_points);
        std::vector<double> radius(num_points);


        for (size_t i = 0; i < num_points; i++) {
            angle[i] = 2 * M_PI * std::rand() / RAND_MAX;
            radius[i] = r*std::rand() / RAND_MAX;
        }

        std::sort(angle.begin(), angle.end());

        GEOSCoordSequence* seq_1 = GEOSCoordSeq_create(static_cast<unsigned int>(num_points), 2);
        for (unsigned int i = 0; i < num_points; i++)
        {
            auto idx = i == (num_points - 1) ? 0 : i;

            GEOSCoordSeq_setX(seq_1, i, x + radius[idx] * cos(angle[idx]));
            GEOSCoordSeq_setY(seq_1, i, y + radius[idx] * sin(angle[idx]));
        }

        return GEOSGeom_createPolygon(GEOSGeom_createLinearRing(seq_1), nullptr, 0);
    }
Beispiel #10
0
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, &currentValue );
        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 );
}
Beispiel #11
0
bool
PolygonReader::gridPointsInPolygon( std::vector<GridPointData> & pointsInPolygon, const GEOSGeom polygon )
{
	/*
	WdbProjectionPtr getWdbProjection(const std::string & def)
	{
		typedef std::map<std::string, WdbProjectionPtr> ProjectionMap;
		static ProjectionMap projections;

		ProjectionMap::iterator ret = projections.find(def);
		if ( ret == projections.end() ) // not found
		{
			// ensure that cache does not grow to ridiculous size
			if ( projections.size() > 512 )
				projections.clear();

			std::pair<ProjectionMap::iterator, bool> result =
					projections.insert(std::make_pair(def, WdbProjectionPtr(new WdbProjection(def))));
			ret = result.first;
		}
		return ret->second;
	}
	*/


	BoundingBox bounds = getBounds( polygon );
	//elog(DEBUG1, GEOSGeomToWKT(polygon) );
	int startI = (bounds.left_ - reader_.placeSpecification().startX_) / reader_.placeSpecification().xIncrement_;
	if (startI < 0) startI = 0;
	int endI = ((bounds.right_ - reader_.placeSpecification().startX_) / reader_.placeSpecification().xIncrement_) + 1;
	if (endI > reader_.placeSpecification().xNumber_) endI = reader_.placeSpecification().xNumber_;
	int startJ = (bounds.bottom_ - reader_.placeSpecification().startY_) / reader_.placeSpecification().yIncrement_;
	if (startJ < 0) startJ = 0;
	int endJ = ((bounds.top_ - reader_.placeSpecification().startY_) / reader_.placeSpecification().yIncrement_) + 1;
	if (endJ > reader_.placeSpecification().yNumber_) endJ = reader_.placeSpecification().yNumber_;
	char res = 0;
	GEOSCoordSequence * seq;
	GEOSGeom point;
	double x;
	double y;
	for (int j = startJ; j < endJ; j++ ) {
		for (int i = startI; i < endI; i++) {
			x = reader_.placeSpecification().startX_ + (i * reader_.placeSpecification().xIncrement_);
			y = reader_.placeSpecification().startY_ + (j * reader_.placeSpecification().yIncrement_);
			WdbProjection prj( reader_.placeSpecification().projDefinition_ );
			if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) {
				x *= DEG_TO_RAD;
				y *= DEG_TO_RAD;
			}
			prj.transformToDefault( 1, &x, &y );
			if ( ! isMetric( DEFAULT_PROJECTION ) ) {
				x *= RAD_TO_DEG;
				y *= RAD_TO_DEG;
			}
			// Intersects
			seq = GEOSCoordSeq_create(1, 2);
			GEOSCoordSeq_setX(seq, 0, x);
			GEOSCoordSeq_setY(seq, 0, y);
			point = GEOSGeom_createPoint(seq);
			//elog(DEBUG1, GEOSGeomToWKT(point) );
			res = GEOS_DLL GEOSIntersects(polygon, point);
			if (res == 1) {
				GridPointData posPt;
				posPt.x = i;
				posPt.y = j;
				pointsInPolygon.push_back(posPt);
			}
			GEOSGeom_destroy(point);
		}
	}
	// Return
	return ( pointsInPolygon.size() > 0 );
}
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;
  }
}
void VertexSnapper::snap()
{

    qDebug("VertexSnapper::snap: ENTERING SNAP");

    for ( unsigned int i = 0; i < subGeometry.size(); i++ )
    {
        // find close features from the reference layer

        // vectors of coordinates of close Geometries
        std::vector<double> closeCoordX;
        std::vector<double> closeCoordY;

        qDebug("VertexSnapper::snap: Vectors with coordinates created");

        for ( unsigned int j = 0; j < refGeometry.size(); j++)
        {

            bool close = isClose( subGeometry[i].getGEOSGeom(), refGeometry[j].getGEOSGeom() );
            qDebug("VertexSnapper::snap: isClose checked.");

            if (close)
            {
                // add close coordinates
                //closeCoord->add( refGeometry[j].getGEOSGeom()->getCoordinates(), false, true );//(*ref_it).getGEOSGeom()->getCoordinates(), false, true );

                // get points from geometry
                //GEOSGeometry* points = GEOSGeom_extractUniquePoints( refGeometry[j].getGEOSGeom() );
                const GEOSCoordSequence *coords = GEOSGeom_getCoordSeq( refGeometry[j].getGEOSGeom() ); // NOTE: Only linestring or points is possible
                //GEOSCoordSequence *coords = GEOSCoordSeq_clone( s );

                qDebug("VertexSnapper::snap: GEOSCoordSequence cloned from refGeometry");

                // get number of points
                unsigned int cSize;
                GEOSCoordSeq_getSize( coords, &cSize );

                // add x and y coordinates to the vectors
                for ( unsigned int k = 0; k < cSize; k++ )
                {
                    double x, y;
                    GEOSCoordSeq_getX( coords, k, &x );
                    GEOSCoordSeq_getY( coords, k, &y );

                    closeCoordX.push_back(x);
                    closeCoordY.push_back(y);
                    qDebug("VertexSnapper::snap: Close coordinates x, y added to vector");
                }

                //GEOSCoordSeq_destroy(coords);

            }

        }

        // create sequence with close points
        int dim = GEOSGeom_getDimensions( refGeometry[0].getGEOSGeom() );
        GEOSCoordSequence *closeCoord = GEOSCoordSeq_create( closeCoordX.size(), dim );
        qDebug("VertexSnapper::snap: GEOSCoordSequence closeCoord created");

        for( unsigned int l = 0; l < closeCoordX.size(); l++)
        {
            GEOSCoordSeq_setX(closeCoord, l, closeCoordX[l]);
            GEOSCoordSeq_setY(closeCoord, l, closeCoordY[l]);
        }

        // snap vertex
        snapVertices( &subGeometry[i], closeCoord);
        newGeometry.push_back( subGeometry[i] );

        GEOSCoordSeq_destroy(closeCoord);

    }

} // void VertexSnapper::snap()
void VertexSnapper::snapVertices(MyGEOSGeom *geom, GEOSCoordSequence *closeCoord)
{
    qDebug("VertexSnapper::snapVertices: ENTERING SNAP VERTICES");

    // tested geometry as coordination sequence
    //GEOSGeometry* points = GEOSGeom_extractUniquePoints( geom->getGEOSGeom() );
    const GEOSCoordSequence *s = GEOSGeom_getCoordSeq( geom->getGEOSGeom() );
    GEOSCoordSequence *coord =  GEOSCoordSeq_clone( s );

    qDebug("VertexSnapper::snapVertices: GEOSCoordSequence cloned from geom Geometry");

    // get dimension of geometry
    int dim = GEOSGeom_getDimensions( geom->getGEOSGeom() );

    // get number of points
    unsigned int cSize;
    GEOSCoordSeq_getSize( coord, &cSize );

    unsigned int ccSize;
    GEOSCoordSeq_getSize( closeCoord, &ccSize );

    // find closest point from closeCoord
    for ( unsigned int i = 0; i < cSize; i++)
    {
        // get point from coordinate sequence
        double x, y;
        GEOSCoordSeq_getX( coord, i, &x);
        GEOSCoordSeq_getY( coord, i, &y);
        GEOSCoordSequence *point = GEOSCoordSeq_create( 1, dim );
        GEOSCoordSeq_setX( point, 0, x);
        GEOSCoordSeq_setY( point, 0, y);
        GEOSGeometry * pointGeom = GEOSGeom_createPoint( point );

        // minimal distance
        double minDist = tolDistance;// = coord->getAt(i).distance( closeCoord.getAt(0) );

        unsigned int indMin = 0;
        bool isMin = false;

        for ( unsigned int j = 0; j < ccSize; j++ )
        {
            // get point from coordinate sequence
            double xx, yy;
            GEOSCoordSeq_getX( closeCoord, j, &xx);
            GEOSCoordSeq_getY( closeCoord, j, &yy);
            GEOSCoordSequence *pointj = GEOSCoordSeq_create( 1, dim );
            GEOSCoordSeq_setX( pointj, 0, xx);
            GEOSCoordSeq_setY( pointj, 0, yy);
            GEOSGeometry * pointGeomj = GEOSGeom_createPoint( pointj );

            // compute distance between two tested points
            double dist =  GEOSDistance( pointGeomj, pointGeom, &minDist ); //coord->getAt(i).distance( closeCoord.getAt(j) );

            if( dist <= minDist )
            {
                minDist = dist;
                indMin = j;
                isMin = true;
            }

            GEOSGeom_destroy(pointGeomj);
        }

        // set new coordinate to the closest point if there is some
        if ( isMin )
        {
            double newX, newY;
            GEOSCoordSeq_getX( closeCoord, indMin, &newX);
            GEOSCoordSeq_getY( closeCoord, indMin, &newY);
            GEOSCoordSeq_setX( coord, i, newX);
            GEOSCoordSeq_setY( coord, i, newY);
            //coord->setAt( closeCoord.getAt(indMin), i );
        }

        //GEOSCoordSeq_destroy(point);
        GEOSGeom_destroy(pointGeom);

    }

    // edit geometry
    editGeometry( geom, coord);

    //GEOSCoordSeq_destroy(coord);
    //GEOSCoordSeq_destroy(point0);
    //GEOSGeom_destroy(pointGeom0);

} // MyGEOSGeom& VertexSnapper::snapVertices(MyGEOSGeom &geom, CoordinateSequence &closeCoord)
Beispiel #15
0
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;
}