Пример #1
0
SEXP rgeos_miscfunc(SEXP env, SEXP obj, SEXP byid, p_miscfunc miscfunc) {

    SEXP ans;
    
    GEOSContextHandle_t GEOShandle = getContextHandle(env);

    GEOSGeom geom = rgeos_convert_R2geos(env, obj);
    int type = GEOSGeomTypeId_r(GEOShandle, geom);
    
    int n = (LOGICAL_POINTER(byid)[0] && type == GEOS_GEOMETRYCOLLECTION) ? 
                GEOSGetNumGeometries_r(GEOShandle, geom) : 1;
    
    int pc=0;
    PROTECT(ans = NEW_NUMERIC(n)); pc++;

    GEOSGeom curgeom = geom;
    for(int i=0; i<n; i++) {
        if ( n > 1) {
            curgeom = (GEOSGeom) GEOSGetGeometryN_r(GEOShandle, geom, i);
            if (curgeom == NULL) error("rgeos_miscfunc: unable to get subgeometries");
        }
        
        double val;
        if (!miscfunc(GEOShandle, curgeom, &val))
            error("rgeos_miscfunc: unable to calculate");
            
        NUMERIC_POINTER(ans)[i] = val;
    }

    GEOSGeom_destroy_r(GEOShandle, geom);

    UNPROTECT(pc);
    return(ans);
}
Пример #2
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);

}
Пример #3
0
// Return closest point to given distance within geometry.
// 'spgeom' must be a LineString
SEXP rgeos_interpolate(SEXP env, SEXP spgeom, SEXP d, SEXP normalized) {

    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    GEOSGeom geom = rgeos_convert_R2geos(env, spgeom);

    GEOSGeom res_geos;
    double dist;

    int nlines = length(GET_SLOT(spgeom, install("lines")));
    if (nlines < 1) {
        error("rgeos_project: invalid number of lines");
    }

    int n = LENGTH(d);
    if (n < 1) {
        error("rgeos_interpolate: invalid number of requested points");
    }

    int pc = 0;
    SEXP crd;
    PROTECT(crd = NEW_NUMERIC(n*2)); pc++;

    double x;
    double y;
    SEXP ans;

    // select interpolation function (normalized/unnormalized)
    GEOSGeometry GEOS_DLL *(*interp_fun)(GEOSContextHandle_t,
                                         const GEOSGeometry*,
                                         double);

    if (LOGICAL_POINTER(normalized)[0]) {
        interp_fun = &GEOSInterpolateNormalized_r;
    } else {
        interp_fun = &GEOSInterpolate_r;
    }

    // interpolate points and store result in coord matrix
    for (int i = 0; i < n; i++) {

        dist = NUMERIC_POINTER(d)[i];

        res_geos = (*interp_fun)(GEOShandle, geom, dist);

        rgeos_Pt2xy(env, res_geos, &x, &y);

        NUMERIC_POINTER(crd)[i] = x;
        NUMERIC_POINTER(crd)[n+i] = y;
    }

    GEOSGeom_destroy_r(GEOShandle, geom);
    GEOSGeom_destroy_r(GEOShandle, res_geos);

    // return coordinates as matrix
    PROTECT(ans = rgeos_formatcrdMat(crd, n)); pc++;

    UNPROTECT(pc);
    return(ans);
}
Пример #4
0
// Return distance of points 'spppoints' projected on 'spgeom' from origin
// of 'spgeom'. Geometry 'spgeom' must be a lineal geometry
SEXP rgeos_project(SEXP env, SEXP spgeom, SEXP sppoint, SEXP normalized) {

    GEOSContextHandle_t GEOShandle = getContextHandle(env);
    GEOSGeom geom = rgeos_convert_R2geos(env, spgeom);

    SEXP crds = GET_SLOT(sppoint, install("coords"));
    SEXP dim = getAttrib(crds, install("dim"));

    int nlines = length(GET_SLOT(spgeom, install("lines")));
    if (nlines < 1) {
        error("rgeos_project: invalid number of lines");
    }

    int n = INTEGER_POINTER(dim)[0];
    if (n < 1) {
        error("rgeos_project: invalid number of points");
    }

    int pc = 0;
    SEXP ans;
    PROTECT(ans = NEW_NUMERIC(n)); pc++;

    GEOSGeom p;

    // select projection function (normalized/unnormalized)
    double GEOS_DLL (*proj_fun)(GEOSContextHandle_t,
                                const GEOSGeometry*,
                                const GEOSGeometry*);

    if (LOGICAL_POINTER(normalized)[0]) {
        proj_fun = &GEOSProjectNormalized_r;
    } else {
        proj_fun = &GEOSProject_r;
    }

    // project points to line geometry
    for (int i = 0; i < n; i++) {

        p = rgeos_xy2Pt(env,
                        NUMERIC_POINTER(crds)[i],
                        NUMERIC_POINTER(crds)[i+n]);

        NUMERIC_POINTER(ans)[i] = (*proj_fun)(GEOShandle, geom, p);
    }

    GEOSGeom_destroy_r(GEOShandle, geom);
    GEOSGeom_destroy_r(GEOShandle, p);

    UNPROTECT(pc);

    return(ans);
}
Пример #5
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) );
}
Пример #6
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);

}
Пример #7
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
}
Пример #8
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) );
}
Пример #9
0
SEXP rgeos_distancefunc(SEXP env, SEXP spgeom1, SEXP spgeom2, SEXP byid, p_distfunc distfunc) {

    GEOSContextHandle_t GEOShandle = getContextHandle(env);

    GEOSGeom geom1 = rgeos_convert_R2geos(env, spgeom1);
    int type1 = GEOSGeomTypeId_r(GEOShandle, geom1);
    GEOSGeom geom2;
    int type2;
    
    int sym_ans = FALSE;
    if (spgeom2 == R_NilValue) {
        sym_ans = TRUE;
        geom2 = geom1;
        type2 = GEOSGeomTypeId_r(GEOShandle, geom2);
    } else {
        geom2 = rgeos_convert_R2geos(env, spgeom2);
        type2 = GEOSGeomTypeId_r(GEOShandle, geom2);
    }

    int m = (LOGICAL_POINTER(byid)[0] && type1 == GEOS_GEOMETRYCOLLECTION) ?
                GEOSGetNumGeometries_r(GEOShandle, geom1) : 1;
    int n = (LOGICAL_POINTER(byid)[1] && type2 == GEOS_GEOMETRYCOLLECTION) ?
                GEOSGetNumGeometries_r(GEOShandle, geom2) : 1;
                
    if (m == -1) error("rgeos_distancefunc: invalid number of subgeometries in geometry 1");
    if (n == -1) error("rgeos_distancefunc: invalid number of subgeometries in geometry 2");

    int pc=0;
    SEXP ans;
    PROTECT(ans = NEW_NUMERIC(m*n)); pc++;

    GEOSGeom curgeom1 = geom1;
    GEOSGeom curgeom2 = geom2;
    for(int i=0; i<m; i++) {
        
        if ( m > 1) {
            curgeom1 = (GEOSGeom) GEOSGetGeometryN_r(GEOShandle, geom1, i);
            if (curgeom1 == NULL) 
                error("rgeos_binpredfunc: unable to get subgeometries from geometry 1");
        }
        for(int j=0; j<n; j++) {
            if(sym_ans && j > i)
                break;
            
            if ( n > 1) {
                curgeom2 = (GEOSGeom) GEOSGetGeometryN_r(GEOShandle, geom2, j);
                if (curgeom2 == NULL) 
                    error("rgeos_binpredfunc: unable to get subgeometries from geometry 2");
            }
            
            double dist;
            if (!distfunc(GEOShandle, curgeom1, curgeom2, &dist))
                error("rgeos_distancefunc: unable to calculate distance");

            NUMERIC_POINTER(ans)[n*i+j] = dist;
            if (sym_ans) NUMERIC_POINTER(ans)[n*j+i] = dist;
        }
    }
    
	if (LOGICAL_POINTER(byid)[0] || LOGICAL_POINTER(byid)[1]) {
        SEXP dims;
        PROTECT(dims = NEW_INTEGER(2)); pc++;
        INTEGER_POINTER(dims)[0] = n;
        INTEGER_POINTER(dims)[1] = m;
        setAttrib(ans, R_DimSymbol, dims);
    }
    
    GEOSGeom_destroy_r(GEOShandle, geom1);
    if (!sym_ans)
        GEOSGeom_destroy_r(GEOShandle, geom2);
    
    UNPROTECT(pc);
    return(ans);
}