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 ); } }
void object::test<4>() { cs_ = GEOSCoordSeq_create(1, 3); unsigned int size; unsigned int dims; ensure ( 0 != GEOSCoordSeq_getSize(cs_, &size) ); ensure_equals( size, 1u ); ensure ( 0 != GEOSCoordSeq_getDimensions(cs_, &dims) ); ensure_equals( dims, 3u ); double x = 10; double y = 11; double z = 12; // Y, X, Z GEOSCoordSeq_setY(cs_, 0, y); GEOSCoordSeq_setX(cs_, 0, x); GEOSCoordSeq_setZ(cs_, 0, z); double xcheck, ycheck, zcheck; ensure( 0 != GEOSCoordSeq_getY(cs_, 0, &ycheck) ); ensure( 0 != GEOSCoordSeq_getX(cs_, 0, &xcheck) ); ensure( 0 != GEOSCoordSeq_getZ(cs_, 0, &zcheck) ); ensure_equals( xcheck, x ); ensure_equals( ycheck, y ); ensure_equals( zcheck, z ); }
void object::test<8>() { // cw orientation cs_ = GEOSCoordSeq_create(4, 2); char ccw; GEOSCoordSeq_setX(cs_, 0, 0); GEOSCoordSeq_setY(cs_, 0, 0); GEOSCoordSeq_setX(cs_, 1, 1); GEOSCoordSeq_setY(cs_, 1, 1); GEOSCoordSeq_setX(cs_, 2, 1); GEOSCoordSeq_setY(cs_, 2, 0); GEOSCoordSeq_setX(cs_, 3, 0); GEOSCoordSeq_setY(cs_, 3, 0); ensure_equals(GEOSCoordSeq_isCCW(cs_, &ccw), 1); ensure(!ccw ); }
void object::test<4>() { GEOSCoordSequence* cs = GEOSCoordSeq_create(5, 2); double nan = std::numeric_limits<double>::quiet_NaN(); GEOSCoordSeq_setX(cs, 0, 1); GEOSCoordSeq_setY(cs, 0, 1); for (unsigned int i=1; i<4; ++i) { GEOSCoordSeq_setX(cs, i, nan); GEOSCoordSeq_setY(cs, i, nan); } GEOSCoordSeq_setX(cs, 4, 1); GEOSCoordSeq_setY(cs, 4, 1); geom1_ = GEOSGeom_createPolygon(GEOSGeom_createLinearRing(cs), NULL, 0); char const r1 = GEOSIntersects(geom1_, geom1_); ensure_equals(int(r1), 2); }
/* ** 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; }
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; }
GEOSCoordSequence *Geometry::ApplyPointTransformationToCoordSequence(PointTransformer *t, const GEOSCoordSequence *seq) { GEOSCoordSequence *ret = GEOSCoordSeq_clone(seq); unsigned int sz; GEOSCoordSeq_getSize(ret, &sz); for (unsigned int i = 0; i < sz; i++) { double x, y; GEOSCoordSeq_getX(ret, i, &x); GEOSCoordSeq_getY(ret, i, &y); t->Transform(&x, &y, NULL); GEOSCoordSeq_setX(ret, i, x); GEOSCoordSeq_setY(ret, i, y); } return ret; }
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* 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); }
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, ¤tValue ); 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 ); }
bool PolygonReader::gridPointsInPolygon( std::vector<GridPointData> & pointsInPolygon, const GEOSGeom polygon ) { /* WdbProjectionPtr getWdbProjection(const std::string & def) { typedef std::map<std::string, WdbProjectionPtr> ProjectionMap; static ProjectionMap projections; ProjectionMap::iterator ret = projections.find(def); if ( ret == projections.end() ) // not found { // ensure that cache does not grow to ridiculous size if ( projections.size() > 512 ) projections.clear(); std::pair<ProjectionMap::iterator, bool> result = projections.insert(std::make_pair(def, WdbProjectionPtr(new WdbProjection(def)))); ret = result.first; } return ret->second; } */ BoundingBox bounds = getBounds( polygon ); //elog(DEBUG1, GEOSGeomToWKT(polygon) ); int startI = (bounds.left_ - reader_.placeSpecification().startX_) / reader_.placeSpecification().xIncrement_; if (startI < 0) startI = 0; int endI = ((bounds.right_ - reader_.placeSpecification().startX_) / reader_.placeSpecification().xIncrement_) + 1; if (endI > reader_.placeSpecification().xNumber_) endI = reader_.placeSpecification().xNumber_; int startJ = (bounds.bottom_ - reader_.placeSpecification().startY_) / reader_.placeSpecification().yIncrement_; if (startJ < 0) startJ = 0; int endJ = ((bounds.top_ - reader_.placeSpecification().startY_) / reader_.placeSpecification().yIncrement_) + 1; if (endJ > reader_.placeSpecification().yNumber_) endJ = reader_.placeSpecification().yNumber_; char res = 0; GEOSCoordSequence * seq; GEOSGeom point; double x; double y; for (int j = startJ; j < endJ; j++ ) { for (int i = startI; i < endI; i++) { x = reader_.placeSpecification().startX_ + (i * reader_.placeSpecification().xIncrement_); y = reader_.placeSpecification().startY_ + (j * reader_.placeSpecification().yIncrement_); WdbProjection prj( reader_.placeSpecification().projDefinition_ ); if ( ! isMetric( reader_.placeSpecification().projDefinition_ ) ) { x *= DEG_TO_RAD; y *= DEG_TO_RAD; } prj.transformToDefault( 1, &x, &y ); if ( ! isMetric( DEFAULT_PROJECTION ) ) { x *= RAD_TO_DEG; y *= RAD_TO_DEG; } // Intersects seq = GEOSCoordSeq_create(1, 2); GEOSCoordSeq_setX(seq, 0, x); GEOSCoordSeq_setY(seq, 0, y); point = GEOSGeom_createPoint(seq); //elog(DEBUG1, GEOSGeomToWKT(point) ); res = GEOS_DLL GEOSIntersects(polygon, point); if (res == 1) { GridPointData posPt; posPt.x = i; posPt.y = j; pointsInPolygon.push_back(posPt); } GEOSGeom_destroy(point); } } // Return return ( pointsInPolygon.size() > 0 ); }
void QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset ) { if ( !geom || !lineGeom ) { return; } QList<QgsGeometry*> inputGeomList; if ( geom->isMultipart() ) { inputGeomList = geom->asGeometryCollection(); } else { inputGeomList.push_back( geom ); } QList<GEOSGeometry*> outputGeomList; QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin(); for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt ) { if ( geom->type() == QGis::Line ) { //geos 3.3 needed for line offsets #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) outputGeomList.push_back( GEOSOffsetCurve(( *inputGeomIt )->asGeos(), -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ) ); #else outputGeomList.push_back( GEOSGeom_clone(( *inputGeomIt )->asGeos() ) ); #endif } else if ( geom->type() == QGis::Point ) { QgsPoint p = ( *inputGeomIt )->asPoint(); p = createPointOffset( p.x(), p.y(), offset, lineGeom ); GEOSCoordSequence* ptSeq = GEOSCoordSeq_create( 1, 2 ); GEOSCoordSeq_setX( ptSeq, 0, p.x() ); GEOSCoordSeq_setY( ptSeq, 0, p.y() ); GEOSGeometry* geosPt = GEOSGeom_createPoint( ptSeq ); outputGeomList.push_back( geosPt ); } } if ( !geom->isMultipart() ) { GEOSGeometry* outputGeom = outputGeomList.at( 0 ); if ( outputGeom ) { geom->fromGeos( outputGeom ); } } else { GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()]; for ( int i = 0; i < outputGeomList.size(); ++i ) { geomArray[i] = outputGeomList.at( i ); } GEOSGeometry* collection = 0; if ( geom->type() == QGis::Point ) { collection = GEOSGeom_createCollection( GEOS_MULTIPOINT, geomArray, outputGeomList.size() ); } else if ( geom->type() == QGis::Line ) { collection = GEOSGeom_createCollection( GEOS_MULTILINESTRING, geomArray, outputGeomList.size() ); } geom->fromGeos( collection ); delete[] geomArray; } }
void VertexSnapper::snap() { qDebug("VertexSnapper::snap: ENTERING SNAP"); for ( unsigned int i = 0; i < subGeometry.size(); i++ ) { // find close features from the reference layer // vectors of coordinates of close Geometries std::vector<double> closeCoordX; std::vector<double> closeCoordY; qDebug("VertexSnapper::snap: Vectors with coordinates created"); for ( unsigned int j = 0; j < refGeometry.size(); j++) { bool close = isClose( subGeometry[i].getGEOSGeom(), refGeometry[j].getGEOSGeom() ); qDebug("VertexSnapper::snap: isClose checked."); if (close) { // add close coordinates //closeCoord->add( refGeometry[j].getGEOSGeom()->getCoordinates(), false, true );//(*ref_it).getGEOSGeom()->getCoordinates(), false, true ); // get points from geometry //GEOSGeometry* points = GEOSGeom_extractUniquePoints( refGeometry[j].getGEOSGeom() ); const GEOSCoordSequence *coords = GEOSGeom_getCoordSeq( refGeometry[j].getGEOSGeom() ); // NOTE: Only linestring or points is possible //GEOSCoordSequence *coords = GEOSCoordSeq_clone( s ); qDebug("VertexSnapper::snap: GEOSCoordSequence cloned from refGeometry"); // get number of points unsigned int cSize; GEOSCoordSeq_getSize( coords, &cSize ); // add x and y coordinates to the vectors for ( unsigned int k = 0; k < cSize; k++ ) { double x, y; GEOSCoordSeq_getX( coords, k, &x ); GEOSCoordSeq_getY( coords, k, &y ); closeCoordX.push_back(x); closeCoordY.push_back(y); qDebug("VertexSnapper::snap: Close coordinates x, y added to vector"); } //GEOSCoordSeq_destroy(coords); } } // create sequence with close points int dim = GEOSGeom_getDimensions( refGeometry[0].getGEOSGeom() ); GEOSCoordSequence *closeCoord = GEOSCoordSeq_create( closeCoordX.size(), dim ); qDebug("VertexSnapper::snap: GEOSCoordSequence closeCoord created"); for( unsigned int l = 0; l < closeCoordX.size(); l++) { GEOSCoordSeq_setX(closeCoord, l, closeCoordX[l]); GEOSCoordSeq_setY(closeCoord, l, closeCoordY[l]); } // snap vertex snapVertices( &subGeometry[i], closeCoord); newGeometry.push_back( subGeometry[i] ); GEOSCoordSeq_destroy(closeCoord); } } // void VertexSnapper::snap()
void VertexSnapper::snapVertices(MyGEOSGeom *geom, GEOSCoordSequence *closeCoord) { qDebug("VertexSnapper::snapVertices: ENTERING SNAP VERTICES"); // tested geometry as coordination sequence //GEOSGeometry* points = GEOSGeom_extractUniquePoints( geom->getGEOSGeom() ); const GEOSCoordSequence *s = GEOSGeom_getCoordSeq( geom->getGEOSGeom() ); GEOSCoordSequence *coord = GEOSCoordSeq_clone( s ); qDebug("VertexSnapper::snapVertices: GEOSCoordSequence cloned from geom Geometry"); // get dimension of geometry int dim = GEOSGeom_getDimensions( geom->getGEOSGeom() ); // get number of points unsigned int cSize; GEOSCoordSeq_getSize( coord, &cSize ); unsigned int ccSize; GEOSCoordSeq_getSize( closeCoord, &ccSize ); // find closest point from closeCoord for ( unsigned int i = 0; i < cSize; i++) { // get point from coordinate sequence double x, y; GEOSCoordSeq_getX( coord, i, &x); GEOSCoordSeq_getY( coord, i, &y); GEOSCoordSequence *point = GEOSCoordSeq_create( 1, dim ); GEOSCoordSeq_setX( point, 0, x); GEOSCoordSeq_setY( point, 0, y); GEOSGeometry * pointGeom = GEOSGeom_createPoint( point ); // minimal distance double minDist = tolDistance;// = coord->getAt(i).distance( closeCoord.getAt(0) ); unsigned int indMin = 0; bool isMin = false; for ( unsigned int j = 0; j < ccSize; j++ ) { // get point from coordinate sequence double xx, yy; GEOSCoordSeq_getX( closeCoord, j, &xx); GEOSCoordSeq_getY( closeCoord, j, &yy); GEOSCoordSequence *pointj = GEOSCoordSeq_create( 1, dim ); GEOSCoordSeq_setX( pointj, 0, xx); GEOSCoordSeq_setY( pointj, 0, yy); GEOSGeometry * pointGeomj = GEOSGeom_createPoint( pointj ); // compute distance between two tested points double dist = GEOSDistance( pointGeomj, pointGeom, &minDist ); //coord->getAt(i).distance( closeCoord.getAt(j) ); if( dist <= minDist ) { minDist = dist; indMin = j; isMin = true; } GEOSGeom_destroy(pointGeomj); } // set new coordinate to the closest point if there is some if ( isMin ) { double newX, newY; GEOSCoordSeq_getX( closeCoord, indMin, &newX); GEOSCoordSeq_getY( closeCoord, indMin, &newY); GEOSCoordSeq_setX( coord, i, newX); GEOSCoordSeq_setY( coord, i, newY); //coord->setAt( closeCoord.getAt(indMin), i ); } //GEOSCoordSeq_destroy(point); GEOSGeom_destroy(pointGeom); } // edit geometry editGeometry( geom, coord); //GEOSCoordSeq_destroy(coord); //GEOSCoordSeq_destroy(point0); //GEOSGeom_destroy(pointGeom0); } // MyGEOSGeom& VertexSnapper::snapVertices(MyGEOSGeom &geom, CoordinateSequence &closeCoord)
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; }