Ejemplo n.º 1
0
SEXP rgeos_node(SEXP env, SEXP obj) {

    SEXP ans, id;
    int pc=0;
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    SEXP p4s = GET_SLOT(obj, install("proj4string"));
    GEOSGeom geom = rgeos_convert_R2geos(env, obj);
//    int type = GEOSGeomTypeId_r(GEOShandle, geom);
//Rprintf("type: %d, %s\n", type, GEOSGeomType_r(GEOShandle, geom));
    
    GEOSGeom res = GEOSNode_r(GEOShandle, geom);
    
//    type = GEOSGeomTypeId_r(GEOShandle, res);

    int ng = GEOSGetNumGeometries_r(GEOShandle, res);

//Rprintf("ng: %d, type: %d, %s\n", ng, type, GEOSGeomType_r(GEOShandle, res));

    char buf[BUFSIZ];

    PROTECT(id = NEW_CHARACTER(ng)); pc++;
    for (int i=0; i<ng; i++) {
        sprintf(buf, "%d", i);
        SET_STRING_ELT(id, i, COPY_TO_USER_STRING(buf));
    }

    GEOSGeom_destroy_r(GEOShandle, geom);

    ans = rgeos_convert_geos2R(env, res, p4s, id); 

    UNPROTECT(pc);
    return(ans);

}
Ejemplo n.º 2
0
SEXP rgeos_polygonize(SEXP env, SEXP obj, SEXP id, SEXP p4s, SEXP cutEdges) {
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    
    int getCutEdges = LOGICAL_POINTER(cutEdges)[0];
    int n = length(obj);
    GEOSGeom *geoms = (GEOSGeom *) R_alloc((size_t) n, sizeof(GEOSGeom));
    
    for(int i=0; i<n; i++) {
        geoms[i] = rgeos_convert_R2geos(env, VECTOR_ELT(obj,i));
    }
    
    GEOSGeom res = (getCutEdges)
                     ? GEOSPolygonizer_getCutEdges_r(GEOShandle, (const GEOSGeometry *const *) geoms, (unsigned int) n)
                     : GEOSPolygonize_r(GEOShandle, (const GEOSGeometry *const *) geoms, (unsigned int) n);
    
    return( rgeos_convert_geos2R(env, res, p4s, id) );
}
Ejemplo n.º 3
0
SEXP rgeos_delaunaytriangulation(SEXP env, SEXP obj, SEXP tol,
  SEXP onlyEdges) {

    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    double tolerance = NUMERIC_POINTER(tol)[0];
    int oE = INTEGER_POINTER(onlyEdges)[0];
    int pc=0;

    SEXP ans, id;
    
    SEXP p4s = GET_SLOT(obj, install("proj4string"));

    GEOSGeom geom = rgeos_convert_R2geos(env, obj);

    GEOSGeom resgeom = GEOSDelaunayTriangulation_r(GEOShandle, geom,
        tolerance, oE);
    if (resgeom == NULL)
            error("rgeos_delaunaytriangulation: unable to compute");

    GEOSGeom_destroy_r(GEOShandle, geom);

//    int type = GEOSGeomTypeId_r(GEOShandle, resgeom);

    int ng = GEOSGetNumGeometries_r(GEOShandle, resgeom);

//Rprintf("ng: %d, type: %d, %s\n", ng, type, GEOSGeomType_r(GEOShandle, resgeom));
// FIXME convert type 5 to type 7

    char buf[BUFSIZ];

    PROTECT(id = NEW_CHARACTER(ng)); pc++;
    for (int i=0; i<ng; i++) {
        sprintf(buf, "%d", i);
        SET_STRING_ELT(id, i, COPY_TO_USER_STRING(buf));
    }

    ans = rgeos_convert_geos2R(env, resgeom, p4s, id); 

    UNPROTECT(pc);
    return(ans);

}
Ejemplo n.º 4
0
SEXP rgeos_topologyfunc(SEXP env, SEXP obj, SEXP id, SEXP byid, p_topofunc topofunc) {

    GEOSContextHandle_t GEOShandle = getContextHandle(env);

    SEXP p4s = GET_SLOT(obj, install("proj4string"));
    GEOSGeom geom = rgeos_convert_R2geos(env, obj);
    int type = GEOSGeomTypeId_r(GEOShandle, geom);
    
    int n = 1;
    if (LOGICAL_POINTER(byid)[0] && type == GEOS_GEOMETRYCOLLECTION)
        n = GEOSGetNumGeometries_r(GEOShandle, geom);
    
    if (n < 1) error("rgeos_topologyfunc: invalid number of geometries");
    
    GEOSGeom *resgeoms = (GEOSGeom *) R_alloc((size_t) n, sizeof(GEOSGeom));
    
    for(int i=0; i<n; i++) {
        const GEOSGeometry *curgeom = (n > 1) ? (GEOSGeom) GEOSGetGeometryN_r(GEOShandle, geom, i)
                                       : geom;
        
        if (curgeom == NULL) 
            error("rgeos_topologyfunc: unable to get subgeometries");
        
        if (    topofunc == GEOSUnionCascaded_r
             && GEOSGeomTypeId_r(GEOShandle, curgeom) == GEOS_POLYGON) {
            resgeoms[i] = GEOSGeom_clone_r(GEOShandle, curgeom);
        } else {
            resgeoms[i] = topofunc(GEOShandle, curgeom);
            if (resgeoms[i] == NULL)
                error("rgeos_topologyfunc: unable to calculate");
        }
    }
    
    GEOSGeom_destroy_r(GEOShandle, geom);
    
    GEOSGeom res = (n == 1) ? resgeoms[0]
                    : GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, resgeoms, (unsigned int) n);
    
    return( rgeos_convert_geos2R(env, res, p4s, id) ); // releases res
}
Ejemplo n.º 5
0
SEXP rgeos_simplify(SEXP env, SEXP obj, SEXP tol, SEXP id, SEXP byid, SEXP topPres) {
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    
    SEXP p4s = GET_SLOT(obj, install("proj4string"));
    GEOSGeom geom = rgeos_convert_R2geos(env, obj);
    int type = GEOSGeomTypeId_r(GEOShandle, geom);
    
    int preserve = LOGICAL_POINTER(topPres)[0];
    double tolerance = NUMERIC_POINTER(tol)[0];
    
    int n = 1;
    if (LOGICAL_POINTER(byid)[0] && type == GEOS_GEOMETRYCOLLECTION)
        n = GEOSGetNumGeometries_r(GEOShandle, geom);
    
    if (n < 1) error("rgeos_simplify: invalid number of geometries");
    
    GEOSGeom *resgeoms = (GEOSGeom *) R_alloc((size_t) n, sizeof(GEOSGeom));
    
    for(int i=0; i<n; i++) {
        const GEOSGeometry *curgeom = (n > 1) ? (GEOSGeom) GEOSGetGeometryN_r(GEOShandle, geom, i)
                                       : geom;
        if (curgeom == NULL)
            error("rgeos_topologyfunc: unable to get subgeometries");
        
        resgeoms[i] = (preserve)
                        ? GEOSTopologyPreserveSimplify_r(GEOShandle, curgeom, tolerance)
                        : GEOSSimplify_r(GEOShandle, curgeom, tolerance);
    }
    
    GEOSGeom_destroy_r(GEOShandle, geom);
    
    GEOSGeom res = (n == 1) ? resgeoms[0] :
                    GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, resgeoms, (unsigned int) n);
    
    return( rgeos_convert_geos2R(env, res, p4s, id) );
}
Ejemplo n.º 6
0
SEXP rgeos_convert_geos2R(SEXP env, GEOSGeom geom, SEXP p4s, SEXP id) {
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);

    int type = GEOSGeomTypeId_r(GEOShandle, geom);
    int ng = GEOSGetNumGeometries_r(GEOShandle, geom);
    if (ng == -1) error("rgeos_convert_geos2R: invalid number of subgeometries"); 
    
    if (type == GEOS_GEOMETRYCOLLECTION && ng==0 && GEOSisEmpty_r(GEOShandle,geom)) {
        GEOSGeom_destroy_r(GEOShandle, geom);
        return(R_NilValue);
    }
    
    ng = ng ? ng : 1; // Empty MULTI type geometries return size 0

    int pc=0;

    SEXP ans=NULL;
    switch(type) { // Determine appropriate conversion for the collection
        case -1:
            error("rgeos_convert_geos2R: unknown geometry type");
            break;
            
        case GEOS_POINT:
        case GEOS_MULTIPOINT:
            PROTECT( ans = rgeos_geospoint2SpatialPoints(env, geom, p4s, id, ng) ); pc++;
            break;
    
        case GEOS_LINEARRING:
            PROTECT( ans = rgeos_geosring2SpatialRings(env, geom, p4s, id, ng)); pc++;
            break;
            
        case GEOS_LINESTRING:
        case GEOS_MULTILINESTRING:
            PROTECT( ans = rgeos_geosline2SpatialLines(env, geom, p4s, id, 1) ); pc++;
            break;
    
        case GEOS_POLYGON:
        case GEOS_MULTIPOLYGON:
            PROTECT( ans = rgeos_geospolygon2SpatialPolygons(env, geom,p4s, id, 1) ); pc++;
            break;
        
        case GEOS_GEOMETRYCOLLECTION:
        {    
            
            int gctypes[] = {0,0,0,0,0,0,0,0};
            int gctypen[] = {0,0,0,0,0,0,0,0};
            int n=0;
            
            int *types = (int *) R_alloc((size_t) ng, sizeof(int));
            for (int i=0; i<ng; i++) {
                const GEOSGeometry *subgeom = GEOSGetGeometryN_r(GEOShandle, geom, i);
                if (subgeom == NULL)
                    error("rgeos_convert_geos2R: unable to retrieve subgeometry");
                
                int ns = GEOSGetNumGeometries_r(GEOShandle, subgeom);
                if (ns == -1) error("rgeos_convert_geos2R: invalid number of geometries in subgeometry");
                ns = ns ? ns : 1;
                n += ns;
                
                types[i] = GEOSGeomTypeId_r(GEOShandle, subgeom);
                if (types[i] == GEOS_GEOMETRYCOLLECTION) {
                    Rprintf("output subgeometry %d, row.name: %s\n", i,
                        CHAR(STRING_ELT(id, i)));
                    for (int ii=0; ii<ns; ii++)
                        Rprintf("subsubgeometry %d: %s\n", ii,
                            GEOSGeomType_r(GEOShandle,
                            GEOSGetGeometryN_r(GEOShandle, subgeom, ii)));
                    error("Geometry collections may not contain other geometry collections");
                }
                
                gctypes[ types[i] ] += 1; 
                gctypen[ types[i] ] += ns;
            }
            
            int isPoint = gctypes[GEOS_POINT] + gctypes[GEOS_MULTIPOINT];
            int isLine  = gctypes[GEOS_LINESTRING] + gctypes[GEOS_MULTILINESTRING];
            int isPoly  = gctypes[GEOS_POLYGON] + gctypes[GEOS_MULTIPOLYGON];
            int isRing  = gctypes[GEOS_LINEARRING];
            int isGC    = gctypes[GEOS_GEOMETRYCOLLECTION];
            
            if ( isPoint && !isLine && !isPoly && !isRing && !isGC ) {
                PROTECT( ans = rgeos_geospoint2SpatialPoints(env, geom, p4s, id, n) ); pc++;
            } else if ( isLine && !isPoint && !isPoly && !isRing && !isGC ) {
                PROTECT( ans = rgeos_geosline2SpatialLines(env, geom, p4s, id, ng) ); pc++;
            } else if ( isPoly && !isPoint && !isLine && !isRing && !isGC ) {
                PROTECT( ans = rgeos_geospolygon2SpatialPolygons(env, geom, p4s,id, ng) ); pc++;
            } else if ( isRing && !isPoint && !isLine && !isPoly && !isGC ) {
                PROTECT( ans = rgeos_geosring2SpatialRings(env, geom, p4s, id, ng) ); pc++;    
            } else {
                
                //Rprintf("isPoint: %d  isLine: %d  isPoly: %d  isRing: %d  isGC: %d\n",isPoint, isLine, isPoly, isRing, isGC);
                
                int m = MAX(MAX(MAX(isPoint,isLine),isPoly),isRing);
                if (length(id) < m) {
                    char buf[BUFSIZ];

                    PROTECT(id = NEW_CHARACTER(m)); pc++;
                    for (int i=0;i<m;i++) {
                        sprintf(buf,"%d",i);
                        SET_STRING_ELT(id, i, COPY_TO_USER_STRING(buf));
                    }
                }
                
                GEOSGeom *GCS[4];
                GCS[0] = (GEOSGeom *) R_alloc((size_t) isPoint, sizeof(GEOSGeom));
                GCS[1] = (GEOSGeom *) R_alloc((size_t) isLine,  sizeof(GEOSGeom));
                GCS[2] = (GEOSGeom *) R_alloc((size_t) isRing,  sizeof(GEOSGeom));
                GCS[3] = (GEOSGeom *) R_alloc((size_t) isPoly,  sizeof(GEOSGeom));
                
                SEXP ptID, lID, rID, pID;
                PROTECT(ptID = NEW_CHARACTER(isPoint)); pc++;
                PROTECT(lID  = NEW_CHARACTER(isLine)); pc++;
                PROTECT(rID  = NEW_CHARACTER(isRing)); pc++;
                PROTECT(pID  = NEW_CHARACTER(isPoly)); pc++;
                
                int typei[] = {0,0,0,0};
                for (int i=0; i<ng; i++) {
                    const GEOSGeometry *subgeom = GEOSGetGeometryN_r(GEOShandle, geom, i);
                    if (subgeom == NULL)
                        error("rgeos_convert_geos2R: unable to retrieve subgeometry");
                    
                    int j = -1;
                    SEXP cur_id=NULL;
                    
                    if (types[i]==GEOS_POINT || types[i]==GEOS_MULTIPOINT) {
                        j=0;
                        cur_id=ptID;
                    } else if (types[i]==GEOS_LINESTRING || types[i]==GEOS_MULTILINESTRING) {
                        j=1;
                        cur_id=lID;
                    } else if (types[i]==GEOS_LINEARRING) {
                        j=2;
                        cur_id=rID;
                    } else if (types[i]==GEOS_POLYGON || types[i]==GEOS_MULTIPOLYGON) {
                        j=3;
                        cur_id=pID;
                    }
                    
                    if (GCS[j] == NULL)
                        error("rgeos_convert_geos2R: GCS element is NULL (this should never happen).");
                    
                    GCS[j][ typei[j] ] = GEOSGeom_clone_r(GEOShandle, subgeom);
                    
                    SET_STRING_ELT(cur_id, typei[j], STRING_ELT(id,typei[j]));
                    typei[j]++;
                }         
                
                SEXP points = R_NilValue;
                SEXP lines  = R_NilValue;
                SEXP rings  = R_NilValue;
                SEXP polys  = R_NilValue;
                
                if (isPoint) {
                    GEOSGeom ptGC = GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, GCS[0], (unsigned int) isPoint);
                    PROTECT( points = rgeos_convert_geos2R(env, ptGC, p4s, ptID) ); pc++;
                }
                if (isLine) {
                    GEOSGeom lGC = GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, GCS[1], (unsigned int) isLine);
                    PROTECT( lines = rgeos_convert_geos2R(env, lGC, p4s, lID) ); pc++;
                }
                if (isRing) {
                    GEOSGeom rGC = GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, GCS[2], (unsigned int) isRing);
                    PROTECT( rings = rgeos_convert_geos2R(env, rGC, p4s, rID) ); pc++;
                }
                if (isPoly) {
                    GEOSGeom pGC = GEOSGeom_createCollection_r(GEOShandle, GEOS_GEOMETRYCOLLECTION, GCS[3], (unsigned int) isPoly);
                    PROTECT( polys = rgeos_convert_geos2R(env, pGC, p4s, pID) ); pc++;
                }
                
                PROTECT(ans = NEW_OBJECT(MAKE_CLASS("SpatialCollections"))); pc++;
                SET_SLOT(ans, install("proj4string"), p4s);
                
                SET_SLOT(ans, install("pointobj"), points);
                SET_SLOT(ans, install("lineobj"), lines);
                SET_SLOT(ans, install("ringobj"), rings);
                SET_SLOT(ans, install("polyobj"), polys);
            
                SEXP plotOrder;
                PROTECT(plotOrder = NEW_INTEGER(4)); pc++;
                INTEGER_POINTER(plotOrder)[0] = 4;
                INTEGER_POINTER(plotOrder)[1] = 3;
                INTEGER_POINTER(plotOrder)[2] = 2;
                INTEGER_POINTER(plotOrder)[3] = 1;
                SET_SLOT(ans, install("plotOrder"), plotOrder);
                
                SEXP bbox;
                PROTECT(bbox = rgeos_geom2bbox(env, geom)); pc++;
                SET_SLOT(ans, install("bbox"), bbox);
            }
            
            break;
        }    
        default:
            error("rgeos_convert_geos2R: Unknown geometry type");
    }
    
    GEOSGeom_destroy_r(GEOShandle, geom);
    UNPROTECT(pc);
    return(ans);
}