Ticket #413: postgis-offsetCurve-RafalMagda.patch

File postgis-offsetCurve-RafalMagda.patch, 6.4 KB (added by rafalmag, 2 years ago)

usage: svn co  http://svn.osgeo.org/postgis/trunk/ -r 5389 && patch -p0 < postgis-offsetCurve-RafalMagda?.patch

  • postgis/lwgeom_geos.c

    diff -uNr trunk/postgis/lwgeom_geos.c trunk-patched/postgis/lwgeom_geos.c
    old new  
    4545Datum isvalidreason(PG_FUNCTION_ARGS); 
    4646Datum isvaliddetail(PG_FUNCTION_ARGS); 
    4747Datum buffer(PG_FUNCTION_ARGS); 
     48Datum offsetcurve(PG_FUNCTION_ARGS); 
    4849Datum intersection(PG_FUNCTION_ARGS); 
    4950Datum convexhull(PG_FUNCTION_ARGS); 
    5051Datum topologypreservesimplify(PG_FUNCTION_ARGS); 
     
    12771278        PG_RETURN_POINTER(result); 
    12781279} 
    12791280 
     1281PG_FUNCTION_INFO_V1(offsetcurve); 
     1282Datum offsetcurve(PG_FUNCTION_ARGS) 
     1283{ 
     1284#if POSTGIS_GEOS_VERSION >= 32 
     1285        PG_LWGEOM       *geom1; 
     1286        double  size; 
     1287        GEOSGeometry *g1, *g3; 
     1288        PG_LWGEOM *result; 
     1289        int quadsegs = 8; /* the default */ 
     1290        int nargs; 
     1291 
     1292        enum 
     1293        { 
     1294                JOIN_ROUND = 1, 
     1295                JOIN_MITRE = 2, 
     1296                JOIN_BEVEL = 3 
     1297        }; 
     1298        static const double DEFAULT_MITRE_LIMIT = 5.0; 
     1299        static const int DEFAULT_JOIN_STYLE = JOIN_ROUND; 
     1300 
     1301        double mitreLimit = DEFAULT_MITRE_LIMIT; 
     1302        int joinStyle  = DEFAULT_JOIN_STYLE; 
     1303        int leftSide = 0; 
     1304        char *param; 
     1305        char *params = NULL; 
     1306 
     1307 
     1308        PROFSTART(PROF_QRUN); 
     1309        // geom arg 
     1310        geom1 = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 
     1311        // distance/size arg 
     1312        size = PG_GETARG_FLOAT8(1); 
     1313         
     1314 
     1315        nargs = PG_NARGS(); 
     1316 
     1317        initGEOS(lwnotice, lwnotice); 
     1318 
     1319        PROFSTART(PROF_P2G1); 
     1320        g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1); 
     1321        PROFSTOP(PROF_P2G1); 
     1322 
     1323        // side arg 
     1324        param = pstrdup(PG_GETARG_CSTRING(2)); 
     1325        POSTGIS_DEBUGF(3, "Param side: %s", param); 
     1326        if ( !strcmp(param, "left") ) 
     1327                leftSide = 1; 
     1328        else if( !strcmp(param, "right") ) 
     1329                leftSide = 0; 
     1330        else 
     1331        { 
     1332                lwerror("Invalid side string, " 
     1333                        "accept: " 
     1334                        "'left' or 'right' "); 
     1335        } 
     1336         
     1337        // options arg (optional) 
     1338        if (nargs > 3) 
     1339        { 
     1340                /* We strdup `cause we're going to modify it */ 
     1341                params = pstrdup(PG_GETARG_CSTRING(3)); 
     1342 
     1343                POSTGIS_DEBUGF(3, "Params: %s", params); 
     1344 
     1345                for (param=params; ; param=NULL) 
     1346                { 
     1347                        char *key, *val; 
     1348                        param = strtok(param, " "); 
     1349                        if ( param == NULL ) break; 
     1350                        POSTGIS_DEBUGF(3, "Param: %s", param); 
     1351 
     1352                        key = param; 
     1353                        val = strchr(key, '='); 
     1354                        if ( val == NULL || *(val+1) == '\0' ) 
     1355                        { 
     1356                                lwerror("Missing value for buffer " 
     1357                                        "parameter %s", key); 
     1358                                break; 
     1359                        } 
     1360                        *val = '\0'; 
     1361                        ++val; 
     1362 
     1363                        POSTGIS_DEBUGF(3, "Param: %s : %s", key, val); 
     1364 
     1365                        if ( !strcmp(key, "join") ) 
     1366                        { 
     1367                                if ( !strcmp(val, "round") ) 
     1368                                { 
     1369                                        joinStyle = JOIN_ROUND; 
     1370                                } 
     1371                                else if ( !strcmp(val, "mitre") || 
     1372                                          !strcmp(val, "miter")    ) 
     1373                                { 
     1374                                        joinStyle = JOIN_MITRE; 
     1375                                } 
     1376                                else if ( !strcmp(val, "bevel") ) 
     1377                                { 
     1378                                        joinStyle = JOIN_BEVEL; 
     1379                                } 
     1380                                else 
     1381                                { 
     1382                                        lwerror("Invalid buffer end cap " 
     1383                                                "style: %s (accept: " 
     1384                                                "'round', 'mitre', 'miter' " 
     1385                                                " or 'bevel'" 
     1386                                                ")", val); 
     1387                                        break; 
     1388                                } 
     1389                        } 
     1390                        else if ( !strcmp(key, "mitre_limit") || 
     1391                                  !strcmp(key, "miter_limit")    ) 
     1392                        { 
     1393                                /* mitreLimit is a float */ 
     1394                                mitreLimit = atof(val); 
     1395                        } 
     1396                        else if ( !strcmp(key, "quad_segs") ) 
     1397                        { 
     1398                                /* quadrant segments is an int */ 
     1399                                quadsegs = atoi(val); 
     1400                        } 
     1401                        else 
     1402                        { 
     1403                                lwerror("Invalid buffer parameter: %s (accept: " 
     1404                                        "'join', 'mitre_limit', " 
     1405                                        "'miter_limit and " 
     1406                                        "'quad_segs')", key); 
     1407                                break; 
     1408                        } 
     1409                } 
     1410 
     1411                pfree(params); /* was pstrduped */ 
     1412 
     1413                POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", 
     1414                               joinStyle, mitreLimit); 
     1415 
     1416        } 
     1417 
     1418        PROFSTART(PROF_GRUN); 
     1419        g3 = GEOSSingleSidedBuffer(g1, size, quadsegs, 
     1420                                 joinStyle, mitreLimit, leftSide); 
     1421        PROFSTOP(PROF_GRUN); 
     1422 
     1423        if (g3 == NULL) 
     1424        { 
     1425                elog(ERROR,"GEOS singleSidedBuffer() threw an error!"); 
     1426                GEOSGeom_destroy(g1); 
     1427                PG_RETURN_NULL(); /* never get here */ 
     1428        } 
     1429 
     1430        POSTGIS_DEBUGF(3, "result: %s", GEOSGeomToWKT(g3)); 
     1431 
     1432        GEOSSetSRID(g3, pglwgeom_getSRID(geom1)); 
     1433 
     1434        PROFSTART(PROF_G2P); 
     1435        result = GEOS2POSTGIS(g3, TYPE_HASZ(geom1->type)); 
     1436        PROFSTOP(PROF_G2P); 
     1437 
     1438        if (result == NULL) 
     1439        { 
     1440                GEOSGeom_destroy(g1); 
     1441                GEOSGeom_destroy(g3); 
     1442                elog(ERROR,"GEOS singleSidedBuffer() threw an error (result postgis geometry formation)!"); 
     1443                PG_RETURN_NULL(); /* never get here */ 
     1444        } 
     1445        GEOSGeom_destroy(g1); 
     1446        GEOSGeom_destroy(g3); 
     1447 
     1448 
     1449        /* compressType(result); */ 
     1450 
     1451        PROFSTOP(PROF_QRUN); 
     1452        PROFREPORT("geos",geom1, NULL, result); 
     1453 
     1454        PG_FREE_IF_COPY(geom1, 0); 
     1455 
     1456        PG_RETURN_POINTER(result); 
     1457#else /* POSTGIS_GEOS_VERSION < 32 */ 
     1458        lwerror("The GEOS version this postgis binary " 
     1459        "was compiled against (%d) doesn't support " 
     1460        "offsetcurve function " 
     1461        "(needs 3.2 or higher)", 
     1462        POSTGIS_GEOS_VERSION); 
     1463                         
     1464        elog(ERROR,"offsetcurve() only in GEOS version >= 3.2 ! Please recompile PostGIS using GEOS version >= 3.2"); 
     1465        PG_RETURN_NULL(); /* never get here */ 
     1466#endif /* POSTGIS_GEOS_VERSION < 32 */   
     1467} 
     1468 
     1469 
    12801470PG_FUNCTION_INFO_V1(intersection); 
    12811471Datum intersection(PG_FUNCTION_ARGS) 
    12821472{ 
  • postgis/postgis.sql.in.c

    diff -uNr trunk/postgis/postgis.sql.in.c trunk-patched/postgis/postgis.sql.in.c
    old new  
    38863886        AS 'SELECT ST_Buffer($1, $2, $3)' 
    38873887        LANGUAGE 'SQL' IMMUTABLE STRICT; 
    38883888 
     3889-- Availability: 2.0.0 - requires GEOS-3.2 or higher 
     3890CREATE OR REPLACE FUNCTION _ST_OffsetCurve(geometry,float8,cstring,cstring) 
     3891        RETURNS geometry 
     3892        AS 'MODULE_PATHNAME','offsetcurve' 
     3893        LANGUAGE 'C' IMMUTABLE STRICT 
     3894        COST 100; 
     3895 
     3896-- Availability: 2.0.0 - requires GEOS-3.2 or higher 
     3897CREATE OR REPLACE FUNCTION ST_OffsetCurve(geometry,float8,text,text) 
     3898        RETURNS geometry 
     3899        AS $$ SELECT _ST_OffsetCurve($1, $2, 
     3900                CAST( regexp_replace($3, '^[0123456789]+$', 
     3901                        'quad_segs='||$3) AS cstring), 
     3902                CAST( $4 AS cstring) 
     3903                ) 
     3904           $$ 
     3905        LANGUAGE 'SQL' IMMUTABLE STRICT; 
     3906 
     3907-- Availability: 2.0.0 - requires GEOS-3.2 or higher 
     3908CREATE OR REPLACE FUNCTION _ST_OffsetCurve(geometry,float8,cstring) 
     3909        RETURNS geometry 
     3910        AS 'MODULE_PATHNAME','offsetcurve' 
     3911        LANGUAGE 'C' IMMUTABLE STRICT 
     3912        COST 100; 
     3913 
     3914-- Availability: 2.0.0 - requires GEOS-3.2 or higher 
     3915CREATE OR REPLACE FUNCTION ST_OffsetCurve(geometry,float8,text) 
     3916        RETURNS geometry 
     3917        AS $$ SELECT _ST_OffsetCurve($1, $2, 
     3918                CAST( regexp_replace($3, '^[0123456789]+$', 
     3919                        'quad_segs='||$3) AS cstring) 
     3920                ) 
     3921           $$ 
     3922        LANGUAGE 'SQL' IMMUTABLE STRICT; 
     3923 
    38893924-- Deprecation in 1.2.3 
    38903925CREATE OR REPLACE FUNCTION convexhull(geometry) 
    38913926        RETURNS geometry