Example #1
0
bool GEOSGeomCmp::operator () (const GEOSGeom ga, const GEOSGeom gb) const
{
	if ( ga == 0 or gb == 0 )
		return ga < gb; // true only if wa is NULL, but not wb

	const GEOSCoordSeq a = const_cast<GEOSCoordSeq>(GEOSGeom_getCoordSeq(ga));
	const GEOSCoordSeq b = const_cast<GEOSCoordSeq>(GEOSGeom_getCoordSeq(gb));

	unsigned sizeA;
	GEOSCoordSeq_getSize(a, & sizeA);
	unsigned sizeB;
	GEOSCoordSeq_getSize(a, & sizeB);
	if (sizeA != sizeB) return sizeA < sizeB;

	for ( unsigned i = 0; i < sizeA; ++ i)
	{
		double valA, valB;
		GEOSCoordSeq_getX(a, i, & valA);
		GEOSCoordSeq_getX(b, i, & valB);
		if ( valA != valB ) return valA < valB;
	}
	for ( unsigned i = 0; i < sizeA; ++ i)
	{
		double valA, valB;
		GEOSCoordSeq_getY(a, i, & valA);
		GEOSCoordSeq_getY(b, i, & valB);
		if ( valA != valB ) return valA < valB;
	}
	return false;
}
Example #2
0
ERL_NIF_TERM
geom_to_eterm_polygon_coords(ErlNifEnv *env, const GEOSGeometry *geom)
{
    unsigned int inner_num, i;
    const GEOSGeometry *outer, *inner;
    const GEOSCoordSequence *coords_seq;
    ERL_NIF_TERM coords;
    ERL_NIF_TERM *rings;

    inner_num = GEOSGetNumInteriorRings(geom);
    // all rings, outer + inner
    rings = malloc(sizeof(ERL_NIF_TERM)*inner_num+1);

    outer = GEOSGetExteriorRing(geom);
    coords_seq = GEOSGeom_getCoordSeq(outer);
    rings[0] = GEOSCoordSequence_to_eterm_list(env, coords_seq,
        GEOSGetNumCoordinates(outer));

    for (i=0; i<inner_num; i++) {
        inner = GEOSGetInteriorRingN(geom, i);
        coords_seq = GEOSGeom_getCoordSeq(inner);
        rings[i+1] = GEOSCoordSequence_to_eterm_list(env,
            coords_seq, GEOSGetNumCoordinates(inner));
    }
    coords = enif_make_list_from_array(env, rings, inner_num+1);
    free(rings);
    return coords;
}
Example #3
0
static shapeObj *msGEOSGeometry2Shape_polygon(GEOSGeom g)
{
  shapeObj *shape=NULL;
  lineObj line;
  int numPoints, numRings;
  int i, j;

  GEOSCoordSeq coords;
  GEOSGeom ring;

  if(!g) return NULL;

  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);
  shape->type = MS_SHAPE_POLYGON;
  shape->geometry = (GEOSGeom) g;

  /* exterior ring */
  ring = (GEOSGeom) GEOSGetExteriorRing(g);
  numPoints = GEOSGetNumCoordinates(ring);
  coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring);
  
  line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
  line.numpoints = numPoints;

  for(i=0; i<numPoints; i++) {
    GEOSCoordSeq_getX(coords, i, &(line.point[i].x));
    GEOSCoordSeq_getY(coords, i, &(line.point[i].y));
    /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */    
  }
  msAddLineDirectly(shape, &line);

  /* interior rings */
  numRings = GEOSGetNumInteriorRings(g);
  for(j=0; j<numRings; j++) {
    ring = (GEOSGeom) GEOSGetInteriorRingN(g, j);
    if(GEOSisRing(ring) != 1) continue; /* skip it */

    numPoints = GEOSGetNumCoordinates(ring);
    coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring);

    line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
    line.numpoints = numPoints;

    for(i=0; i<numPoints; i++) {
      GEOSCoordSeq_getX(coords, i, &(line.point[i].x));
      GEOSCoordSeq_getY(coords, i, &(line.point[i].y));
      /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */
    }
    msAddLineDirectly(shape, &line);
  }

  msComputeBounds(shape); 

  return shape;
}
Example #4
0
static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g)
{
  int i;
  int numPoints;
  GEOSCoordSeq coords;
  GEOSGeom point;
  
  shapeObj *shape=NULL;

  if(!g) return NULL;
  numPoints = GEOSGetNumGeometries(g); /* each geometry has 1 point */

  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);

  shape->type = MS_SHAPE_POINT;
  shape->line = (lineObj *) malloc(sizeof(lineObj));
  shape->numlines = 1;
  shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
  shape->line[0].numpoints = numPoints;
  shape->geometry = (GEOSGeom) g;

  for(i=0; i<numPoints; i++) {
    point = (GEOSGeom) GEOSGetGeometryN(g, i);
    coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(point);

    GEOSCoordSeq_getX(coords, 0, &(shape->line[0].point[i].x));
    GEOSCoordSeq_getY(coords, 0, &(shape->line[0].point[i].y));
    /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[i].z)); */
  }
 
  msComputeBounds(shape); 

  return shape;
}
Example #5
0
static shapeObj *msGEOSGeometry2Shape_point(GEOSGeom g)
{
  GEOSCoordSeq coords;
  shapeObj *shape=NULL;
  
  if(!g) return NULL;
    
  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);
    
  shape->type = MS_SHAPE_POINT;
  shape->line = (lineObj *) malloc(sizeof(lineObj));
  shape->numlines = 1;
  shape->line[0].point = (pointObj *) malloc(sizeof(pointObj));
  shape->line[0].numpoints = 1;
  shape->geometry = (GEOSGeom) g;

  coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(g);

  GEOSCoordSeq_getX(coords, 0, &(shape->line[0].point[0].x));
  GEOSCoordSeq_getY(coords, 0, &(shape->line[0].point[0].y));
  /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[0].z)); */

  shape->bounds.minx = shape->bounds.maxx = shape->line[0].point[0].x;
  shape->bounds.miny = shape->bounds.maxy = shape->line[0].point[0].y;
 
  return shape;
}
Example #6
0
pointObj *msGEOSGetCentroid(shapeObj *shape)
{
#ifdef USE_GEOS
  GEOSGeom g1, g2;
  GEOSCoordSeq coords;
  pointObj *point;

  if(!shape) return NULL;

  if(!shape->geometry) /* if no geometry for the shape then build one */
    shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape);
  g1 = (GEOSGeom) shape->geometry;
  if(!g1) return NULL;

  g2 = GEOSGetCentroid(g1);

  point = (pointObj *) malloc(sizeof(pointObj));

  coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(g2);

  GEOSCoordSeq_getX(coords, 0, &(point->x));
  GEOSCoordSeq_getY(coords, 0, &(point->y));
  /* GEOSCoordSeq_getZ(coords, 0, &(point->z)); */

  GEOSCoordSeq_destroy(coords);

  return point;
#else
  msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSGetCentroid()");
  return NULL;
#endif
}
Example #7
0
static int ring2pts(const GEOSGeometry *geom, struct line_pnts *Points)
{
    int i, ncoords;
    double x, y, z;
    const GEOSCoordSequence *seq = NULL;

    G_debug(3, "ring2pts()");

    Vect_reset_line(Points);
    if (!geom) {
	G_warning(_("Invalid GEOS geometry!"));
	return 0;
    }
    z = 0.0;
    ncoords = GEOSGetNumCoordinates(geom);
    if (!ncoords) {
	G_warning(_("No coordinates in GEOS geometry (can be ok for negative distance)!"));
	return 0;
    }
    seq = GEOSGeom_getCoordSeq(geom);
    for (i = 0; i < ncoords; i++) {
	GEOSCoordSeq_getX(seq, i, &x);
	GEOSCoordSeq_getY(seq, i, &y);
	if (x != x || x > DBL_MAX || x < -DBL_MAX)
	    G_fatal_error(_("Invalid x coordinate %f"), x);
	if (y != y || y > DBL_MAX || y < -DBL_MAX)
	    G_fatal_error(_("Invalid y coordinate %f"), y);
	Vect_append_point(Points, x, y, z);
    }

    return 1;
}
Example #8
0
static shapeObj *msGEOSGeometry2Shape_line(GEOSGeom g)
{
  shapeObj *shape=NULL;

  int i;
  int numPoints;
  GEOSCoordSeq coords;

  if(!g) return NULL;
  numPoints = GEOSGetNumCoordinates(g);
  coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(g);

  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);

  shape->type = MS_SHAPE_LINE; 
  shape->line = (lineObj *) malloc(sizeof(lineObj));
  shape->numlines = 1;
  shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
  shape->line[0].numpoints = numPoints;
  shape->geometry = (GEOSGeom) g;

  for(i=0; i<numPoints; i++) {
    GEOSCoordSeq_getX(coords, i, &(shape->line[0].point[i].x));
    GEOSCoordSeq_getY(coords, i, &(shape->line[0].point[i].y));
    /* GEOSCoordSeq_getZ(coords, i, &(shape->line[0].point[i].z)); */
  }

  msComputeBounds(shape); 

  return shape;
}
Example #9
0
ERL_NIF_TERM
geom_to_eterm_linestring_coords(ErlNifEnv *env, const GEOSGeometry *geom)
{
    const GEOSCoordSequence *coords_seq;

    coords_seq = GEOSGeom_getCoordSeq(geom);
    return GEOSCoordSequence_to_eterm_list(env, coords_seq,
        GEOSGetNumCoordinates(geom));
}
Example #10
0
ERL_NIF_TERM
geom_to_eterm_point_coords(ErlNifEnv *env, const GEOSGeometry *geom)
{
    const GEOSCoordSequence *coords_seq;
    double coordx, coordy;

    coords_seq = GEOSGeom_getCoordSeq(geom);
    GEOSCoordSeq_getX(coords_seq, 0, &coordx);
    GEOSCoordSeq_getY(coords_seq, 0, &coordy);
    return enif_make_list2(env, enif_make_double(env, coordx),
        enif_make_double(env, coordy));
}
Example #11
0
static YAP_Bool make_polygon_to_term (geometry_t geometry,
                                        const char * functor_name,
                                        YAP_Term *term)
{
  int n;
  geometry_t ring;
  sequence_t sequence;
  YAP_Functor functor;
  unsigned int size;
  YAP_Term head;

  assert (term != NULL);
  *term = YAP_MkAtomTerm (YAP_LookupAtom ("[]"));
  size = GEOSGetNumInteriorRings (geometry);
  for (n = size - 1; n >= 0; n --)
    {
      ring = (geometry_t) GEOSGetInteriorRingN (geometry, n);
      sequence = (sequence_t) GEOSGeom_getCoordSeq (ring);
      if ((sequence == NULL)
          || (point_list_to_term (sequence, &head) == FALSE))
        return (FALSE);
      *term = YAP_MkPairTerm (head, *term);
    }
  /* Exterior ring always exists. */
  ring = (geometry_t) GEOSGetExteriorRing (geometry);
  if (ring == NULL)
    return (FALSE);
  sequence = (sequence_t) GEOSGeom_getCoordSeq (ring);
  if ((sequence == NULL)
      || (point_list_to_term (sequence, &head) == FALSE))
    return (FALSE);
  *term = YAP_MkPairTerm (head, *term);

  if (functor_name != NULL)
    {
      functor = YAP_MkFunctor (YAP_LookupAtom (NAME_POLYGON), 1);
      *term = YAP_MkApplTerm (functor, 1, term);
    }
  return (TRUE);
}
Example #12
0
static void _get_envelope(GEOSGeometry* geometry,Rect* rect)
{
	unsigned int num_pnt;
	GEOSGeometry* env;
	const GEOSGeometry* ring;
	const GEOSCoordSequence* seq;
	double x,y;
	unsigned int loop=0;
	assert(rect != 0);
	assert(geometry != 0);
	rect->minX = rect->minY = rect->maxX = rect->maxY = 0;

	if(GEOSGeomTypeId(geometry) == GEOS_POINT)
	{
		GEOSGeomGetX(geometry,&x);
		GEOSGeomGetY(geometry,&y);
		rect->minX = rect->maxX = x;
		rect->minY = rect->maxY = y;
		return;
	}

	env = GEOSEnvelope(geometry);
	ring = GEOSGetExteriorRing(env);
	seq	 =	GEOSGeom_getCoordSeq(ring);
	GEOSCoordSeq_getSize(seq,&num_pnt);

	if(num_pnt == 0 || num_pnt > 5)return;

	GEOSCoordSeq_getX(seq,0,&x);
	GEOSCoordSeq_getY(seq,0,&y);

	rect->minX = rect->maxX = x;
	rect->minY = rect->maxY = y;

	for(loop=1;loop<num_pnt;loop++)
	{
		GEOSCoordSeq_getX(seq,loop,&x);
		GEOSCoordSeq_getY(seq,loop,&y);
		
		if(x > rect->maxX) rect->maxX = x;
		if(x < rect->minX) rect->minX = x;

		if(y > rect->maxY) rect->maxY = y;
		if(y < rect->minY) rect->minY = y;
	}

	GEOSGeom_destroy(env);
}
Example #13
0
static YAP_Bool make_point_to_term (geometry_t geometry,
                                      const char * functor_name,
                                      YAP_Term *term)
{
  double x, y;
  sequence_t sequence;

  assert (term != NULL);
  sequence = (sequence_t) GEOSGeom_getCoordSeq (geometry);
  if ((sequence == NULL)
      || (GEOSCoordSeq_getX (sequence, 0, &x) == 0)
      || (GEOSCoordSeq_getY (sequence, 0, &y) == 0))
    return (FALSE);
  if (make_point (x, y, functor_name, term) == FALSE)
    return (FALSE);
  return (TRUE);
}
Example #14
0
GEOSGeometry *Geometry::ApplyPointTransformationToSingleGeometry(PointTransformer *t, const GEOSGeometry *g)
{
    int             gtype   = GEOSGeomTypeId(g);
    GEOSGeometry    *ng     = NULL;
    
    if (gtype == GEOS_POINT || gtype == GEOS_LINESTRING || gtype == GEOS_LINEARRING) {
        const GEOSCoordSequence *seq =  GEOSGeom_getCoordSeq(g);
        GEOSCoordSequence       *nseq = ApplyPointTransformationToCoordSequence(t, seq);
        
        // this is silly -- GEOS really needs a shortcut for this
        if (gtype == GEOS_POINT) {
            ng = GEOSGeom_createPoint(nseq);
        }
        if (gtype == GEOS_LINESTRING) {
            ng = GEOSGeom_createLineString(nseq);
        }
        if (gtype == GEOS_LINEARRING) {
            ng = GEOSGeom_createLinearRing(nseq);
        }
    }
    else if (gtype == GEOS_POLYGON) {
        int                 ircnt   = GEOSGetNumInteriorRings(g);
        const GEOSGeometry  *ext    = GEOSGetExteriorRing(g);
        GEOSGeometry        *next   = ApplyPointTransformationToSingleGeometry(t, ext);
        GEOSGeometry        **rings = NULL;
        
        if (ircnt > 0) {
            // This shares a lot in common with the code below in ApplyPointTransformation,
            // refactor into a single method?
            rings = new GEOSGeometry *[ircnt];
            
            for (int i = 0; i < ircnt; i++) {
                rings[i] = ApplyPointTransformationToSingleGeometry(t, GEOSGetInteriorRingN(g, i));
            }
        }
        
        ng = GEOSGeom_createPolygon(next, rings, ircnt);
        
        if (rings) {
            delete rings;
        }
    }
    
    return ng;
}
Example #15
0
static YAP_Bool make_linestring_to_term (geometry_t geometry,
                                           const char * functor_name,
                                           YAP_Term *term)
{
  sequence_t sequence;
  YAP_Functor functor;

  assert (term != NULL);
  sequence = (sequence_t) GEOSGeom_getCoordSeq (geometry);
  if ((sequence == NULL)
      || (point_list_to_term (sequence, term) == FALSE))
    return (FALSE);
  if (functor_name != NULL)
    {
      functor = YAP_MkFunctor (YAP_LookupAtom (functor_name), 1);
      *term = YAP_MkApplTerm (functor, 1, term);
    }
  return (TRUE);
}
Example #16
0
static shapeObj *msGEOSGeometry2Shape_multiline(GEOSGeom g)
{
  int i, j;
  int numPoints, numLines;
  GEOSCoordSeq coords;
  GEOSGeom lineString;

  shapeObj *shape=NULL;
  lineObj line;

  if(!g) return NULL;
  numLines = GEOSGetNumGeometries(g);

  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);

  shape->type = MS_SHAPE_LINE;
  shape->geometry = (GEOSGeom) g;

  for(j=0; j<numLines; j++) {
    lineString = (GEOSGeom) GEOSGetGeometryN(g, j);
    numPoints = GEOSGetNumCoordinates(lineString);
    coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(lineString);

    line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
    line.numpoints = numPoints;

    for(i=0; i<numPoints; i++) {
      GEOSCoordSeq_getX(coords, i, &(line.point[i].x));
      GEOSCoordSeq_getY(coords, i, &(line.point[i].y));
      /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */  	
    }

    msAddLineDirectly(shape, &line);
  }

  msComputeBounds(shape); 

  return shape;
}
Example #17
0
/* Return an LWGEOM from a Geometry */
LWGEOM *
GEOS2LWGEOM(const GEOSGeometry *geom, char want3d)
{
	int type = GEOSGeomTypeId(geom) ;
	int hasZ;
	int SRID = GEOSGetSRID(geom);

	/* GEOS's 0 is equivalent to our unknown as for SRID values */
	if ( SRID == 0 ) SRID = SRID_UNKNOWN;

	if ( want3d )
	{
		hasZ = GEOSHasZ(geom);
		if ( ! hasZ )
		{
			LWDEBUG(3, "Geometry has no Z, won't provide one");

			want3d = 0;
		}
	}

/*
	if ( GEOSisEmpty(geom) )
	{
		return (LWGEOM*)lwcollection_construct_empty(COLLECTIONTYPE, SRID, want3d, 0);
	}
*/

	switch (type)
	{
		const GEOSCoordSequence *cs;
		POINTARRAY *pa, **ppaa;
		const GEOSGeometry *g;
		LWGEOM **geoms;
		uint32_t i, ngeoms;

	case GEOS_POINT:
		LWDEBUG(4, "lwgeom_from_geometry: it's a Point");
		cs = GEOSGeom_getCoordSeq(geom);
		if ( GEOSisEmpty(geom) )
		  return (LWGEOM*)lwpoint_construct_empty(SRID, want3d, 0);
		pa = ptarray_from_GEOSCoordSeq(cs, want3d);
		return (LWGEOM *)lwpoint_construct(SRID, NULL, pa);

	case GEOS_LINESTRING:
	case GEOS_LINEARRING:
		LWDEBUG(4, "lwgeom_from_geometry: it's a LineString or LinearRing");
		if ( GEOSisEmpty(geom) )
		  return (LWGEOM*)lwline_construct_empty(SRID, want3d, 0);

		cs = GEOSGeom_getCoordSeq(geom);
		pa = ptarray_from_GEOSCoordSeq(cs, want3d);
		return (LWGEOM *)lwline_construct(SRID, NULL, pa);

	case GEOS_POLYGON:
		LWDEBUG(4, "lwgeom_from_geometry: it's a Polygon");
		if ( GEOSisEmpty(geom) )
		  return (LWGEOM*)lwpoly_construct_empty(SRID, want3d, 0);
		ngeoms = GEOSGetNumInteriorRings(geom);
		ppaa = lwalloc(sizeof(POINTARRAY *)*(ngeoms+1));
		g = GEOSGetExteriorRing(geom);
		cs = GEOSGeom_getCoordSeq(g);
		ppaa[0] = ptarray_from_GEOSCoordSeq(cs, want3d);
		for (i=0; i<ngeoms; i++)
		{
			g = GEOSGetInteriorRingN(geom, i);
			cs = GEOSGeom_getCoordSeq(g);
			ppaa[i+1] = ptarray_from_GEOSCoordSeq(cs,
			                                      want3d);
		}
		return (LWGEOM *)lwpoly_construct(SRID, NULL,
		                                  ngeoms+1, ppaa);

	case GEOS_MULTIPOINT:
	case GEOS_MULTILINESTRING:
	case GEOS_MULTIPOLYGON:
	case GEOS_GEOMETRYCOLLECTION:
		LWDEBUG(4, "lwgeom_from_geometry: it's a Collection or Multi");

		ngeoms = GEOSGetNumGeometries(geom);
		geoms = NULL;
		if ( ngeoms )
		{
			geoms = lwalloc(sizeof(LWGEOM *)*ngeoms);
			for (i=0; i<ngeoms; i++)
			{
				g = GEOSGetGeometryN(geom, i);
				geoms[i] = GEOS2LWGEOM(g, want3d);
			}
		}
		return (LWGEOM *)lwcollection_construct(type,
		                                        SRID, NULL, ngeoms, geoms);

	default:
		lwerror("GEOS2LWGEOM: unknown geometry type: %d", type);
		return NULL;

	}

}
Example #18
0
static gaiaGeomCollPtr
fromGeosGeometry (const GEOSGeometry * geos, const int dimension_model)
{
/* converting a GEOS Geometry into a GAIA Geometry */
    int type;
    int itemType;
    unsigned int dims;
    int iv;
    int ib;
    int it;
    int sub_it;
    int nItems;
    int nSubItems;
    int holes;
    unsigned int points;
    double x;
    double y;
    double z;
    const GEOSCoordSequence *cs;
    const GEOSGeometry *geos_ring;
    const GEOSGeometry *geos_item;
    const GEOSGeometry *geos_sub_item;
    gaiaGeomCollPtr gaia = NULL;
    gaiaLinestringPtr ln;
    gaiaPolygonPtr pg;
    gaiaRingPtr rng;
    if (!geos)
	return NULL;
    type = GEOSGeomTypeId (geos);
    switch (type)
      {
      case GEOS_POINT:
	  if (dimension_model == GAIA_XY_Z)
	      gaia = gaiaAllocGeomCollXYZ ();
	  else if (dimension_model == GAIA_XY_M)
	      gaia = gaiaAllocGeomCollXYM ();
	  else if (dimension_model == GAIA_XY_Z_M)
	      gaia = gaiaAllocGeomCollXYZM ();
	  else
	      gaia = gaiaAllocGeomColl ();
	  gaia->DeclaredType = GAIA_POINT;
	  gaia->Srid = GEOSGetSRID (geos);
	  cs = GEOSGeom_getCoordSeq (geos);
	  GEOSCoordSeq_getDimensions (cs, &dims);
	  if (dims == 3)
	    {
		GEOSCoordSeq_getX (cs, 0, &x);
		GEOSCoordSeq_getY (cs, 0, &y);
		GEOSCoordSeq_getZ (cs, 0, &z);
	    }
	  else
	    {
		GEOSCoordSeq_getX (cs, 0, &x);
		GEOSCoordSeq_getY (cs, 0, &y);
		z = 0.0;
	    }
	  if (dimension_model == GAIA_XY_Z)
	      gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
	  else if (dimension_model == GAIA_XY_M)
	      gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
	  else if (dimension_model == GAIA_XY_Z_M)
	      gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
	  else
	      gaiaAddPointToGeomColl (gaia, x, y);
	  break;
      case GEOS_LINESTRING:
	  if (dimension_model == GAIA_XY_Z)
	      gaia = gaiaAllocGeomCollXYZ ();
	  else if (dimension_model == GAIA_XY_M)
	      gaia = gaiaAllocGeomCollXYM ();
	  else if (dimension_model == GAIA_XY_Z_M)
	      gaia = gaiaAllocGeomCollXYZM ();
	  else
	      gaia = gaiaAllocGeomColl ();
	  gaia->DeclaredType = GAIA_LINESTRING;
	  gaia->Srid = GEOSGetSRID (geos);
	  cs = GEOSGeom_getCoordSeq (geos);
	  GEOSCoordSeq_getDimensions (cs, &dims);
	  GEOSCoordSeq_getSize (cs, &points);
	  ln = gaiaAddLinestringToGeomColl (gaia, points);
	  for (iv = 0; iv < (int) points; iv++)
	    {
		if (dims == 3)
		  {
		      GEOSCoordSeq_getX (cs, iv, &x);
		      GEOSCoordSeq_getY (cs, iv, &y);
		      GEOSCoordSeq_getZ (cs, iv, &z);
		  }
		else
		  {
		      GEOSCoordSeq_getX (cs, iv, &x);
		      GEOSCoordSeq_getY (cs, iv, &y);
		      z = 0.0;
		  }
		if (dimension_model == GAIA_XY_Z)
		  {
		      gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
		  }
		else if (dimension_model == GAIA_XY_M)
		  {
		      gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
		  }
		else if (dimension_model == GAIA_XY_Z_M)
		  {
		      gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0);
		  }
		else
		  {
		      gaiaSetPoint (ln->Coords, iv, x, y);
		  }
	    }
	  break;
      case GEOS_POLYGON:
	  if (dimension_model == GAIA_XY_Z)
	      gaia = gaiaAllocGeomCollXYZ ();
	  else if (dimension_model == GAIA_XY_M)
	      gaia = gaiaAllocGeomCollXYM ();
	  else if (dimension_model == GAIA_XY_Z_M)
	      gaia = gaiaAllocGeomCollXYZM ();
	  else
	      gaia = gaiaAllocGeomColl ();
	  gaia->DeclaredType = GAIA_POLYGON;
	  gaia->Srid = GEOSGetSRID (geos);
	  /* exterior ring */
	  holes = GEOSGetNumInteriorRings (geos);
	  geos_ring = GEOSGetExteriorRing (geos);
	  cs = GEOSGeom_getCoordSeq (geos_ring);
	  GEOSCoordSeq_getDimensions (cs, &dims);
	  GEOSCoordSeq_getSize (cs, &points);
	  pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
	  rng = pg->Exterior;
	  for (iv = 0; iv < (int) points; iv++)
	    {
		if (dims == 3)
		  {
		      GEOSCoordSeq_getX (cs, iv, &x);
		      GEOSCoordSeq_getY (cs, iv, &y);
		      GEOSCoordSeq_getZ (cs, iv, &z);
		  }
		else
		  {
		      GEOSCoordSeq_getX (cs, iv, &x);
		      GEOSCoordSeq_getY (cs, iv, &y);
		      z = 0.0;
		  }
		if (dimension_model == GAIA_XY_Z)
		  {
		      gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
		  }
		else if (dimension_model == GAIA_XY_M)
		  {
		      gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
		  }
		else if (dimension_model == GAIA_XY_Z_M)
		  {
		      gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
		  }
		else
		  {
		      gaiaSetPoint (rng->Coords, iv, x, y);
		  }
	    }
	  for (ib = 0; ib < holes; ib++)
	    {
		/* interior rings */
		geos_ring = GEOSGetInteriorRingN (geos, ib);
		cs = GEOSGeom_getCoordSeq (geos_ring);
		GEOSCoordSeq_getDimensions (cs, &dims);
		GEOSCoordSeq_getSize (cs, &points);
		rng = gaiaAddInteriorRing (pg, ib, points);
		for (iv = 0; iv < (int) points; iv++)
		  {
		      if (dims == 3)
			{
			    GEOSCoordSeq_getX (cs, iv, &x);
			    GEOSCoordSeq_getY (cs, iv, &y);
			    GEOSCoordSeq_getZ (cs, iv, &z);
			}
		      else
			{
			    GEOSCoordSeq_getX (cs, iv, &x);
			    GEOSCoordSeq_getY (cs, iv, &y);
			    z = 0.0;
			}
		      if (dimension_model == GAIA_XY_Z)
			{
			    gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
			}
		      else if (dimension_model == GAIA_XY_M)
			{
			    gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
			}
		      else if (dimension_model == GAIA_XY_Z_M)
			{
			    gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0);
			}
		      else
			{
			    gaiaSetPoint (rng->Coords, iv, x, y);
			}
		  }
	    }
	  break;
      case GEOS_MULTIPOINT:
      case GEOS_MULTILINESTRING:
      case GEOS_MULTIPOLYGON:
      case GEOS_GEOMETRYCOLLECTION:
	  if (dimension_model == GAIA_XY_Z)
	      gaia = gaiaAllocGeomCollXYZ ();
	  else if (dimension_model == GAIA_XY_M)
	      gaia = gaiaAllocGeomCollXYM ();
	  else if (dimension_model == GAIA_XY_Z_M)
	      gaia = gaiaAllocGeomCollXYZM ();
	  else
	      gaia = gaiaAllocGeomColl ();
	  if (type == GEOS_MULTIPOINT)
	      gaia->DeclaredType = GAIA_MULTIPOINT;
	  else if (type == GEOS_MULTILINESTRING)
	      gaia->DeclaredType = GAIA_MULTILINESTRING;
	  else if (type == GEOS_MULTIPOLYGON)
	      gaia->DeclaredType = GAIA_MULTIPOLYGON;
	  else
	      gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION;
	  gaia->Srid = GEOSGetSRID (geos);
	  nItems = GEOSGetNumGeometries (geos);
	  for (it = 0; it < nItems; it++)
	    {
		/* looping on elementaty geometries */
		geos_item = GEOSGetGeometryN (geos, it);
		itemType = GEOSGeomTypeId (geos_item);
		switch (itemType)
		  {
		  case GEOS_POINT:
		      cs = GEOSGeom_getCoordSeq (geos_item);
		      GEOSCoordSeq_getDimensions (cs, &dims);
		      if (dims == 3)
			{
			    GEOSCoordSeq_getX (cs, 0, &x);
			    GEOSCoordSeq_getY (cs, 0, &y);
			    GEOSCoordSeq_getZ (cs, 0, &z);
			}
		      else
			{
			    GEOSCoordSeq_getX (cs, 0, &x);
			    GEOSCoordSeq_getY (cs, 0, &y);
			    z = 0.0;
			}
		      if (dimension_model == GAIA_XY_Z)
			  gaiaAddPointToGeomCollXYZ (gaia, x, y, z);
		      else if (dimension_model == GAIA_XY_M)
			  gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0);
		      else if (dimension_model == GAIA_XY_Z_M)
			  gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0);
		      else
			  gaiaAddPointToGeomColl (gaia, x, y);
		      break;
		  case GEOS_LINESTRING:
		      cs = GEOSGeom_getCoordSeq (geos_item);
		      GEOSCoordSeq_getDimensions (cs, &dims);
		      GEOSCoordSeq_getSize (cs, &points);
		      ln = gaiaAddLinestringToGeomColl (gaia, points);
		      for (iv = 0; iv < (int) points; iv++)
			{
			    if (dims == 3)
			      {
				  GEOSCoordSeq_getX (cs, iv, &x);
				  GEOSCoordSeq_getY (cs, iv, &y);
				  GEOSCoordSeq_getZ (cs, iv, &z);
			      }
			    else
			      {
				  GEOSCoordSeq_getX (cs, iv, &x);
				  GEOSCoordSeq_getY (cs, iv, &y);
				  z = 0.0;
			      }
			    if (dimension_model == GAIA_XY_Z)
			      {
				  gaiaSetPointXYZ (ln->Coords, iv, x, y, z);
			      }
			    else if (dimension_model == GAIA_XY_M)
			      {
				  gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0);
			      }
			    else if (dimension_model == GAIA_XY_Z_M)
			      {
				  gaiaSetPointXYZM (ln->Coords, iv, x, y, z,
						    0.0);
			      }
			    else
			      {
				  gaiaSetPoint (ln->Coords, iv, x, y);
			      }
			}
		      break;
		  case GEOS_MULTILINESTRING:
		      nSubItems = GEOSGetNumGeometries (geos_item);
		      for (sub_it = 0; sub_it < nSubItems; sub_it++)
			{
			    /* looping on elementaty geometries */
			    geos_sub_item =
				GEOSGetGeometryN (geos_item, sub_it);
			    cs = GEOSGeom_getCoordSeq (geos_sub_item);
			    GEOSCoordSeq_getDimensions (cs, &dims);
			    GEOSCoordSeq_getSize (cs, &points);
			    ln = gaiaAddLinestringToGeomColl (gaia, points);
			    for (iv = 0; iv < (int) points; iv++)
			      {
				  if (dims == 3)
				    {
					GEOSCoordSeq_getX (cs, iv, &x);
					GEOSCoordSeq_getY (cs, iv, &y);
					GEOSCoordSeq_getZ (cs, iv, &z);
				    }
				  else
				    {
					GEOSCoordSeq_getX (cs, iv, &x);
					GEOSCoordSeq_getY (cs, iv, &y);
					z = 0.0;
				    }
				  if (dimension_model == GAIA_XY_Z)
				    {
					gaiaSetPointXYZ (ln->Coords, iv, x, y,
							 z);
				    }
				  else if (dimension_model == GAIA_XY_M)
				    {
					gaiaSetPointXYM (ln->Coords, iv, x, y,
							 0.0);
				    }
				  else if (dimension_model == GAIA_XY_Z_M)
				    {
					gaiaSetPointXYZM (ln->Coords, iv, x, y,
							  z, 0.0);
				    }
				  else
				    {
					gaiaSetPoint (ln->Coords, iv, x, y);
				    }
			      }
			}
		      break;
		  case GEOS_POLYGON:
		      /* exterior ring */
		      holes = GEOSGetNumInteriorRings (geos_item);
		      geos_ring = GEOSGetExteriorRing (geos_item);
		      cs = GEOSGeom_getCoordSeq (geos_ring);
		      GEOSCoordSeq_getDimensions (cs, &dims);
		      GEOSCoordSeq_getSize (cs, &points);
		      pg = gaiaAddPolygonToGeomColl (gaia, points, holes);
		      rng = pg->Exterior;
		      for (iv = 0; iv < (int) points; iv++)
			{
			    if (dims == 3)
			      {
				  GEOSCoordSeq_getX (cs, iv, &x);
				  GEOSCoordSeq_getY (cs, iv, &y);
				  GEOSCoordSeq_getZ (cs, iv, &z);
			      }
			    else
			      {
				  GEOSCoordSeq_getX (cs, iv, &x);
				  GEOSCoordSeq_getY (cs, iv, &y);
				  z = 0.0;
			      }
			    if (dimension_model == GAIA_XY_Z)
			      {
				  gaiaSetPointXYZ (rng->Coords, iv, x, y, z);
			      }
			    else if (dimension_model == GAIA_XY_M)
			      {
				  gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0);
			      }
			    else if (dimension_model == GAIA_XY_Z_M)
			      {
				  gaiaSetPointXYZM (rng->Coords, iv, x, y, z,
						    0.0);
			      }
			    else
			      {
				  gaiaSetPoint (rng->Coords, iv, x, y);
			      }
			}
		      for (ib = 0; ib < holes; ib++)
			{
			    /* interior rings */
			    geos_ring = GEOSGetInteriorRingN (geos_item, ib);
			    cs = GEOSGeom_getCoordSeq (geos_ring);
			    GEOSCoordSeq_getDimensions (cs, &dims);
			    GEOSCoordSeq_getSize (cs, &points);
			    rng = gaiaAddInteriorRing (pg, ib, points);
			    for (iv = 0; iv < (int) points; iv++)
			      {
				  if (dims == 3)
				    {
					GEOSCoordSeq_getX (cs, iv, &x);
					GEOSCoordSeq_getY (cs, iv, &y);
					GEOSCoordSeq_getZ (cs, iv, &z);
				    }
				  else
				    {
					GEOSCoordSeq_getX (cs, iv, &x);
					GEOSCoordSeq_getY (cs, iv, &y);
					z = 0.0;
				    }
				  if (dimension_model == GAIA_XY_Z)
				    {
					gaiaSetPointXYZ (rng->Coords, iv, x, y,
							 z);
				    }
				  else if (dimension_model == GAIA_XY_M)
				    {
					gaiaSetPointXYM (rng->Coords, iv, x, y,
							 0.0);
				    }
				  else if (dimension_model == GAIA_XY_Z_M)
				    {
					gaiaSetPointXYZM (rng->Coords, iv, x, y,
							  z, 0.0);
				    }
				  else
				    {
					gaiaSetPoint (rng->Coords, iv, x, y);
				    }
			      }
			}
		      break;
		  };
	    }
	  break;
      };
    return gaia;
}
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)
Example #20
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::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()
Example #22
0
PolygonReader::BoundingBox
PolygonReader::getBounds( const GEOSGeom polygons )
{
	BoundingBox ret;
	int geomNumber = GEOSGetNumGeometries(polygons);
	for (int n=0; n<geomNumber; n++) {
		GEOSGeom outerRing;
		if (geomNumber > 1) {
			GEOSGeom polygon = const_cast<GEOSGeom>(GEOSGetGeometryN( polygons, n ));
			if (polygon == NULL)
				throw std::runtime_error( "Multigeometry returned is NULL" );
			outerRing = const_cast<GEOSGeom>(GEOSGetExteriorRing( polygon ));
		}
		else {
			outerRing = const_cast<GEOSGeom>(GEOSGetExteriorRing( polygons ));
		}
		if ( outerRing == NULL )
			throw std::runtime_error( "Outer ring of polygon/shape is NULL." );
		GEOSCoordSeq coordSeq = const_cast<GEOSCoordSeq>(GEOSGeom_getCoordSeq( outerRing ));
		if ( coordSeq == NULL )
			throw std::runtime_error( "Coordinate sequence of polygon/shape returned NULL" );
		unsigned int size;
		if ( GEOSCoordSeq_getSize( coordSeq, &size ) == 0 )
			throw std::runtime_error( "Error when getting size of outer ring of polygon/shape" );
		// Calculate Bounds
		WdbProjection prj( reader_.placeSpecification().projDefinition_ );
		lonlat coord;
		// Initialize
		GEOSCoordSeq_getX( coordSeq, 0, &coord.lon );
		GEOSCoordSeq_getY( coordSeq, 0, &coord.lat );
		if ( ! isMetric( DEFAULT_PROJECTION ) ) {
			coord.lon *=  DEG_TO_RAD;
			coord.lat *= DEG_TO_RAD;
		}
		prj.transformFromDefault( 1, &coord.lon, &coord.lat );
		if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) {
			coord.lon *= RAD_TO_DEG;
			coord.lat *= RAD_TO_DEG;
		}
		if (n == 0) {
			ret.left_ = coord.lon;
			ret.top_ = coord.lat;
			ret.right_ = coord.lon;
			ret.bottom_ = coord.lat;
		}
		for ( unsigned int i = 1; i < size; i++ ) {
			GEOSCoordSeq_getX( coordSeq, i, &coord.lon );
			GEOSCoordSeq_getY( coordSeq, i, &coord.lat );
			if ( ! isMetric( DEFAULT_PROJECTION ) ) {
				coord.lon *=  DEG_TO_RAD;
				coord.lat *= DEG_TO_RAD;
			}
			prj.transformFromDefault( 1, &coord.lon, &coord.lat );
			if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) {
				coord.lon *= RAD_TO_DEG;
				coord.lat *= RAD_TO_DEG;
			}
			if (coord.lon < ret.left_)
				ret.left_ = coord.lon;
			else
			if (coord.lon > ret.right_)
				ret.right_ = coord.lon;
			if (coord.lat < ret.bottom_)
				ret.bottom_ = coord.lat;
			else
			if (coord.lat > ret.top_ )
				ret.top_ = coord.lat;
		}
	}
	return ret;
}
Example #23
0
GEOSGeometry*
LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in)
{
	GEOSGeometry *tmp;
	GEOSGeometry *geos_result, *shp;
	GEOSGeometry const *vgeoms[1];
	uint32_t i, ngeoms;
	int srid = GEOSGetSRID(geom_in);

	vgeoms[0] = geom_in;
	geos_result = GEOSPolygonize(vgeoms, 1);

	LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result);

	/* Null return from GEOSpolygonize (an exception) */
	if ( ! geos_result ) return 0;

	/*
	 * We should now have a collection
	 */
#if PARANOIA_LEVEL > 0
	if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE )
	{
		GEOSGeom_destroy(geos_result);
		lwerror("Unexpected return from GEOSpolygonize");
		return 0;
	}
#endif

	ngeoms = GEOSGetNumGeometries(geos_result);

	LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms);
	LWDEBUGF(3, "GEOSpolygonize: polygonized:%s",
	               lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0)));

	/*
	 * No geometries in collection, early out
	 */
	if ( ngeoms == 0 )
	{
		GEOSSetSRID(geos_result, srid);
		return geos_result;
	}

	/*
	 * Return first geometry if we only have one in collection,
	 * to avoid the unnecessary Geometry clone below.
	 */
	if ( ngeoms == 1 )
	{
		tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0);
		if ( ! tmp )
		{
			GEOSGeom_destroy(geos_result);
			return 0; /* exception */
		}
		shp = GEOSGeom_clone(tmp);
		GEOSGeom_destroy(geos_result); /* only safe after the clone above */
		GEOSSetSRID(shp, srid);
		return shp;
	}

	/*
	 * Iteratively invoke symdifference on outer rings
	 * as suggested by Carl Anderson:
	 * postgis-devel/2005-December/001805.html
	 */
	shp = NULL;
	for (i=0; i<ngeoms; ++i)
	{
		GEOSGeom extring;
		GEOSCoordSeq sq;

		/*
		 * Construct a Polygon from geometry i exterior ring
		 * We don't use GEOSGeom_clone on the ExteriorRing
		 * due to a bug in CAPI contained in GEOS 2.2 branch
		 * failing to properly return a LinearRing from
		 * a LinearRing clone.
		 */
		sq=GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(
		                          GEOSGetExteriorRing(GEOSGetGeometryN( geos_result, i))
		                      ));
		extring = GEOSGeom_createPolygon(
		              GEOSGeom_createLinearRing(sq),
		              NULL, 0
		          );

		if ( extring == NULL ) /* exception */
		{
			lwerror("GEOSCreatePolygon threw an exception");
			return 0;
		}

		if ( shp == NULL )
		{
			shp = extring;
			LWDEBUGF(3, "GEOSpolygonize: shp:%s",
			               lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0)));
		}
		else
		{
			tmp = GEOSSymDifference(shp, extring);
			LWDEBUGF(3, "GEOSpolygonize: SymDifference(%s, %s):%s",
			               lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0)),
			               lwgeom_to_ewkt(GEOS2LWGEOM(extring, 0)),
			               lwgeom_to_ewkt(GEOS2LWGEOM(tmp, 0))
			              );
			GEOSGeom_destroy(shp);
			GEOSGeom_destroy(extring);
			shp = tmp;
		}
	}

	GEOSGeom_destroy(geos_result);

	GEOSSetSRID(shp, srid);

	return shp;
}