Esempio n. 1
0
static GEOSGeom msGEOSShape2Geometry_simplepolygon(shapeObj *shape, int r, int *outerList)
{
  int i, j, k;
  GEOSCoordSeq coords;
  GEOSGeom g;
  GEOSGeom outerRing;
  GEOSGeom *innerRings=NULL;
  int numInnerRings=0, *innerList;

  if(!shape || !outerList) return NULL;

  /* build the outer shell */
  coords = GEOSCoordSeq_create(shape->line[r].numpoints, 2); /* todo handle z's */
  if(!coords) return NULL;

  for(i=0; i<shape->line[r].numpoints; i++) {
    GEOSCoordSeq_setX(coords, i, shape->line[r].point[i].x);
    GEOSCoordSeq_setY(coords, i, shape->line[r].point[i].y);
    /* GEOSCoordSeq_setZ(coords, i, shape->line[r].point[i].z); */
  }

  outerRing = GEOSGeom_createLinearRing(coords); /* outerRing owns the coordinates in coords */

  /* build the holes */
  innerList = msGetInnerList(shape, r, outerList);
  for(j=0; j<shape->numlines; j++)
    if(innerList[j] == MS_TRUE) numInnerRings++;

  if(numInnerRings > 0) {
    k = 0; /* inner ring counter */

    innerRings = malloc(numInnerRings*sizeof(GEOSGeom));
    if(!innerRings) return NULL; /* todo, this will leak memory (outerRing) */

    for(j=0; j<shape->numlines; j++) {
      if(innerList[j] == MS_FALSE) continue;

      coords = GEOSCoordSeq_create(shape->line[j].numpoints, 2); /* todo handle z's */
      if(!coords) return NULL; /* todo, this will leak memory (shell + allocated holes) */

      for(i=0; i<shape->line[j].numpoints; i++) {
        GEOSCoordSeq_setX(coords, i, shape->line[j].point[i].x);
        GEOSCoordSeq_setY(coords, i, shape->line[j].point[i].y);
        /* GEOSCoordSeq_setZ(coords, i, shape->line[j].point[i].z); */
      }

      innerRings[k] = GEOSGeom_createLinearRing(coords); /* innerRings[k] owns the coordinates in coords */
      k++;
    }
  }

  g = GEOSGeom_createPolygon(outerRing, innerRings, numInnerRings);

  free(innerList); /* clean up */
  free(innerRings); /* clean up */

  return g;
}
    void object::test<5>()
    {
		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_setOrdinate(cs_, 0, 1, y);
		GEOSCoordSeq_setOrdinate(cs_, 0, 0, x);
		GEOSCoordSeq_setOrdinate(cs_, 0, 2, z);

		double xcheck, ycheck, zcheck;
		ensure( 0 != GEOSCoordSeq_getOrdinate(cs_, 0, 1, &ycheck) );
		ensure( 0 != GEOSCoordSeq_getOrdinate(cs_, 0, 0, &xcheck) );
		ensure( 0 != GEOSCoordSeq_getOrdinate(cs_, 0, 2, &zcheck) );

		ensure_equals( xcheck, x );
		ensure_equals( ycheck, y );
		ensure_equals( zcheck, z );
    }	
    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 );
		}
    }	
Esempio n. 4
0
GEOSCoordSeq
ptarray_to_GEOSCoordSeq(const POINTARRAY *pa)
{
	uint32_t dims = 2;
	uint32_t size, i;
	POINT3DZ p;
	GEOSCoordSeq sq;

	if ( FLAGS_GET_Z(pa->flags) ) dims = 3;
	size = pa->npoints;

	sq = GEOSCoordSeq_create(size, dims);
	if ( ! sq ) lwerror("Error creating GEOS Coordinate Sequence");

	for (i=0; i<size; i++)
	{
		getPoint3dz_p(pa, i, &p);

		LWDEBUGF(4, "Point: %g,%g,%g", p.x, p.y, p.z);

#if POSTGIS_GEOS_VERSION < 33
		/* Make sure we don't pass any infinite values down into GEOS */
		/* GEOS 3.3+ is supposed to  handle this stuff OK */
		if ( isinf(p.x) || isinf(p.y) || (dims == 3 && isinf(p.z)) )
			lwerror("Infinite coordinate value found in geometry.");
		if ( isnan(p.x) || isnan(p.y) || (dims == 3 && isnan(p.z)) )
			lwerror("NaN coordinate value found in geometry.");
#endif

		GEOSCoordSeq_setX(sq, i, p.x);
		GEOSCoordSeq_setY(sq, i, p.y);
		if ( dims == 3 ) GEOSCoordSeq_setZ(sq, i, p.z);
	}
	return sq;
}
Esempio n. 5
0
int ogr_features_intersect_tile(mapcache_context *ctx, mapcache_tile *tile) {
   mapcache_metatile *mt = mapcache_tileset_metatile_get(ctx,tile);
   GEOSCoordSequence *mtbboxls = GEOSCoordSeq_create(5,2);
   double *e = mt->map.extent;
   GEOSCoordSeq_setX(mtbboxls,0,e[0]);
   GEOSCoordSeq_setY(mtbboxls,0,e[1]);
   GEOSCoordSeq_setX(mtbboxls,1,e[2]);
   GEOSCoordSeq_setY(mtbboxls,1,e[1]);
   GEOSCoordSeq_setX(mtbboxls,2,e[2]);
   GEOSCoordSeq_setY(mtbboxls,2,e[3]);
   GEOSCoordSeq_setX(mtbboxls,3,e[0]);
   GEOSCoordSeq_setY(mtbboxls,3,e[3]);
   GEOSCoordSeq_setX(mtbboxls,4,e[0]);
   GEOSCoordSeq_setY(mtbboxls,4,e[1]);
   GEOSGeometry *mtbbox = GEOSGeom_createLinearRing(mtbboxls);
   GEOSGeometry *mtbboxg = GEOSGeom_createPolygon(mtbbox,NULL,0);
   int i;
   int intersects = 0;
   for(i=0;i<nClippers;i++) {
      const GEOSPreparedGeometry *clipper = clippers[i];
      if(GEOSPreparedIntersects(clipper,mtbboxg)) {
         intersects = 1;
         break;
      }
   }
   GEOSGeom_destroy(mtbboxg);
   return intersects;
}
Esempio n. 6
0
static YAP_Bool point_list_to_sequence (YAP_Term term,
                                          unsigned int size,
                                          sequence_t *sequence)
{
  YAP_Float x, y;
  unsigned int n;
  YAP_Term head;

  *sequence = GEOSCoordSeq_create (size, 2);
  if (*sequence == NULL)
    return (FALSE);
  for (n = 0; YAP_IsPairTerm (term) != FALSE; n ++)
    {
      assert (n < size);
      head = YAP_HeadOfTerm (term);
      if ((Yap_IsNumberTerm (YAP_ArgOfTerm (1, head), &x) == FALSE)
          || (Yap_IsNumberTerm (YAP_ArgOfTerm (2, head), &y) == FALSE)
          || (GEOSCoordSeq_setX (*sequence, n, x) == 0)
          || (GEOSCoordSeq_setY (*sequence, n, y) == 0))
        {
          GEOSCoordSeq_destroy (*sequence);
          return (FALSE);
        }
      term = YAP_TailOfTerm (term);
    }
  assert (n == size);
  assert (YAP_IsAtomTerm (term) != FALSE);
  assert (strcmp (YAP_AtomName (YAP_AtomOfTerm (term)), "[]") == 0);
  return (TRUE);
}
Esempio n. 7
0
GEOSGeometry*
eterm_to_geom_point(ErlNifEnv *env, const ERL_NIF_TERM *coords_list)
{
    GEOSCoordSequence *coords_seq;

    coords_seq = GEOSCoordSeq_create(1, DIMENSION);
    set_GEOSCoordSeq_from_eterm_list(coords_seq, 0, env, coords_list);
    return GEOSGeom_createPoint(coords_seq);
}
Esempio n. 8
0
void geo_bound(sqlite3_context *context,int argc,sqlite3_value **argv)
{
	if(argc >= 1)
	{
		const unsigned char* ogc;
		unsigned char* ret_geo_buf;
		size_t size;
		double x1,x2,y1,y2;
		GEOSCoordSequence* seq = 0;
		GEOSGeometry* geometry = 0;
		GEOSGeometry* middle_geo = 0;
		
		_init_geos();
		if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_BLOB)
		{
			size = sqlite3_value_bytes(argv[0]);
			ogc = (const unsigned char*)sqlite3_value_blob(argv[0]);
			middle_geo = _geo_from_wkb(ogc,size);
		}
		else if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_TEXT)
		{
			ogc = sqlite3_value_text(argv[0]);
			middle_geo = _geo_from_wkt(ogc);
		}
		else if(argc == 4)
		{
			x1 = sqlite3_value_double(argv[0]);
			y1 = sqlite3_value_double(argv[1]);
			x2 = sqlite3_value_double(argv[2]);
			y2 = sqlite3_value_double(argv[3]);

			seq = GEOSCoordSeq_create(2,2);
			GEOSCoordSeq_setX(seq,0,x1);
			GEOSCoordSeq_setY(seq,0,y1);
			GEOSCoordSeq_setX(seq,1,x2);
			GEOSCoordSeq_setY(seq,1,y2);

			middle_geo = GEOSGeom_createLineString(seq);
		}

		if(middle_geo != 0)
		{
			geometry = GEOSEnvelope(middle_geo);
			if(geometry != 0)
			{
				ret_geo_buf = GEOSGeomToWKB_buf(geometry,&size);
				sqlite3_result_blob(context,ret_geo_buf,size,SQLITE_TRANSIENT);
				GEOSGeom_destroy(geometry);
				GEOSFree(ret_geo_buf);
			}
			GEOSGeom_destroy(middle_geo);
		}

		finishGEOS();
	}
}
    void object::test<9>() {
        // no orientation
        cs_ = GEOSCoordSeq_create(3, 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);

        ensure_equals(GEOSCoordSeq_isCCW(cs_, &ccw), 0);
    }
Esempio n. 10
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;
}
Esempio n. 11
0
    void object::test<6>()
    {
        cs_ = GEOSCoordSeq_create(1, 2);

        unsigned int size;
        unsigned int dims;

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

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

	// The dimension passed to GEOSCoordSeq_create()
	// is a request for a minimum, not a strict mandate
	// for changing actual size.
	//
        ensure ( dims >= 2u );

    }
Esempio n. 12
0
GEOSCoordSeq
eterm_to_geom_linestring_coords(ErlNifEnv *env,
        const ERL_NIF_TERM *coords_list)
{
    unsigned int i=0, len;
    GEOSCoordSequence *coords_seq;
    ERL_NIF_TERM head, tail;

    enif_get_list_length(env, *coords_list, &len);
    coords_seq = GEOSCoordSeq_create(len, DIMENSION);
    while (enif_get_list_cell(env, *coords_list, &head, &tail)) {
        if (!set_GEOSCoordSeq_from_eterm_list(coords_seq, i, env, &head)) {
            return NULL;
        }
        i++;
        coords_list = &tail;
    }
    return coords_seq;
}
Esempio n. 13
0
    void object::test<7>() {
        // ccw 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, 0);

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

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

        ensure_equals(GEOSCoordSeq_isCCW(cs_, &ccw), 1);
        ensure(ccw);
    }
Esempio n. 14
0
    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);
        
    }
Esempio n. 15
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;
}
Esempio n. 16
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);
}
Esempio n. 17
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);
    }
Esempio n. 18
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 );
}
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)
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 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;
  }
}
Esempio n. 22
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 );
}
Esempio n. 23
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;
}