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); }
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; }
/* ** 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; }
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); }
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom) { GEOSCoordSeq sq; GEOSGeom g, shell; GEOSGeom *geoms = NULL; /* LWGEOM *tmp; */ uint32_t ngeoms, i; int geostype; #if LWDEBUG_LEVEL >= 4 char *wkt; #endif LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type)); if (lwgeom_has_arc(lwgeom)) { LWDEBUG(3, "LWGEOM2GEOS: arced geometry found."); lwerror("Exception in LWGEOM2GEOS: curved geometry not supported."); return NULL; } switch (lwgeom->type) { LWPOINT *lwp = NULL; LWPOLY *lwpoly = NULL; LWLINE *lwl = NULL; LWCOLLECTION *lwc = NULL; #if POSTGIS_GEOS_VERSION < 33 POINTARRAY *pa = NULL; #endif case POINTTYPE: lwp = (LWPOINT *)lwgeom; if ( lwgeom_is_empty(lwgeom) ) { #if POSTGIS_GEOS_VERSION < 33 pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2); sq = ptarray_to_GEOSCoordSeq(pa); shell = GEOSGeom_createLinearRing(sq); g = GEOSGeom_createPolygon(shell, NULL, 0); #else g = GEOSGeom_createEmptyPolygon(); #endif } else { sq = ptarray_to_GEOSCoordSeq(lwp->point); g = GEOSGeom_createPoint(sq); } if ( ! g ) { /* lwnotice("Exception in LWGEOM2GEOS"); */ return NULL; } break; case LINETYPE: lwl = (LWLINE *)lwgeom; if ( lwl->points->npoints == 1 ) { /* Duplicate point, to make geos-friendly */ lwl->points = ptarray_addPoint(lwl->points, getPoint_internal(lwl->points, 0), FLAGS_NDIMS(lwl->points->flags), lwl->points->npoints); } sq = ptarray_to_GEOSCoordSeq(lwl->points); g = GEOSGeom_createLineString(sq); if ( ! g ) { /* lwnotice("Exception in LWGEOM2GEOS"); */ return NULL; } break; case POLYGONTYPE: lwpoly = (LWPOLY *)lwgeom; if ( lwgeom_is_empty(lwgeom) ) { #if POSTGIS_GEOS_VERSION < 33 POINTARRAY *pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2); sq = ptarray_to_GEOSCoordSeq(pa); shell = GEOSGeom_createLinearRing(sq); g = GEOSGeom_createPolygon(shell, NULL, 0); #else g = GEOSGeom_createEmptyPolygon(); #endif } else { sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[0]); /* TODO: check ring for being closed and fix if not */ shell = GEOSGeom_createLinearRing(sq); if ( ! shell ) return NULL; /*lwerror("LWGEOM2GEOS: exception during polygon shell conversion"); */ ngeoms = lwpoly->nrings-1; if ( ngeoms > 0 ) geoms = malloc(sizeof(GEOSGeom)*ngeoms); for (i=1; i<lwpoly->nrings; ++i) { sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[i]); geoms[i-1] = GEOSGeom_createLinearRing(sq); if ( ! geoms[i-1] ) { --i; while (i) GEOSGeom_destroy(geoms[--i]); free(geoms); GEOSGeom_destroy(shell); return NULL; } /*lwerror("LWGEOM2GEOS: exception during polygon hole conversion"); */ } g = GEOSGeom_createPolygon(shell, geoms, ngeoms); if (geoms) free(geoms); } if ( ! g ) return NULL; break; case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: case COLLECTIONTYPE: if ( lwgeom->type == MULTIPOINTTYPE ) geostype = GEOS_MULTIPOINT; else if ( lwgeom->type == MULTILINETYPE ) geostype = GEOS_MULTILINESTRING; else if ( lwgeom->type == MULTIPOLYGONTYPE ) geostype = GEOS_MULTIPOLYGON; else geostype = GEOS_GEOMETRYCOLLECTION; lwc = (LWCOLLECTION *)lwgeom; ngeoms = lwc->ngeoms; if ( ngeoms > 0 ) geoms = malloc(sizeof(GEOSGeom)*ngeoms); for (i=0; i<ngeoms; ++i) { GEOSGeometry* g = LWGEOM2GEOS(lwc->geoms[i]); if ( ! g ) { while (i) GEOSGeom_destroy(geoms[--i]); free(geoms); return NULL; } geoms[i] = g; } g = GEOSGeom_createCollection(geostype, geoms, ngeoms); if ( geoms ) free(geoms); if ( ! g ) return NULL; break; default: lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type)); return NULL; } GEOSSetSRID(g, lwgeom->srid); #if LWDEBUG_LEVEL >= 4 wkt = GEOSGeomToWKT(g); LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt); free(wkt); #endif return g; }
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::editGeometry( MyGEOSGeom *geom, GEOSCoordSequence *coord ) { // edit geometry according to coord -> GeometryEditor and GeometryEditorOperation/interface classes ?????? qDebug("VertexSnapper::editGeometry: ENTERING EDIT GEOMETRY"); // new geometry GEOSGeometry *newGeom = NULL; GEOSGeometry *ring = NULL; // change geometry according to its type // NOTE: improve this according to http://trac.osgeo.org/geos/browser/trunk/tests/geostest/geostest.c - fineGrainedReconstructionTest int type = GEOSGeomTypeId( geom->getGEOSGeom() ); switch ( type ) { case GEOS_POINT: newGeom = GEOSGeom_createPoint( coord ); break; case GEOS_LINESTRING: newGeom = GEOSGeom_createLineString( coord ); break; case GEOS_LINEARRING: newGeom = GEOSGeom_createLinearRing( coord ); break; case GEOS_POLYGON: ring = GEOSGeom_createLinearRing( coord ); // NOTE: Fails if polygon has holes newGeom = GEOSGeom_createPolygon( ring, NULL, 0 ); break; case GEOS_MULTIPOINT: newGeom = GEOSGeom_createEmptyCollection(4); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_MULTILINESTRING: newGeom = GEOSGeom_createEmptyCollection(5); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_MULTIPOLYGON: newGeom = GEOSGeom_createEmptyCollection(6); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; case GEOS_GEOMETRYCOLLECTION: newGeom = GEOSGeom_createEmptyCollection(7); qDebug("VertexSnapper::editGeometry: Multi geometry is not supported yet."); break; default: qDebug("VertexSnapper::editGeometry: Unknown geometry type."); } // return edited geometry geom->setGEOSGeom( newGeom ); if( GEOSisEmpty( geom->getGEOSGeom() ) ) qDebug("VertexSnapper::editGeometry: Geom is empty."); if( GEOSisValid( geom->getGEOSGeom() ) ) qDebug("VertexSnapper::editGeometry: Geom is valid."); //GEOSGeom_destroy(newGeom); } // void VertexSnapper::editGeometry( MyGEOSGeom &geom, CoordinateSequence &coord )
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)
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; }