PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ buffer()

Datum buffer ( PG_FUNCTION_ARGS  )

Definition at line 989 of file postgis/lwgeom_geos.c.

990{
991 GEOSBufferParams *bufferparams;
992 GEOSGeometry *g1, *g3 = NULL;
994 LWGEOM *lwg;
995 int quadsegs = 8; /* the default */
996 int singleside = 0; /* the default */
997 enum
998 {
999 ENDCAP_ROUND = 1,
1000 ENDCAP_FLAT = 2,
1001 ENDCAP_SQUARE = 3
1002 };
1003 enum
1004 {
1005 JOIN_ROUND = 1,
1006 JOIN_MITRE = 2,
1007 JOIN_BEVEL = 3
1008 };
1009 const double DEFAULT_MITRE_LIMIT = 5.0;
1010 const int DEFAULT_ENDCAP_STYLE = ENDCAP_ROUND;
1011 const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1012 double mitreLimit = DEFAULT_MITRE_LIMIT;
1013 int endCapStyle = DEFAULT_ENDCAP_STYLE;
1014 int joinStyle = DEFAULT_JOIN_STYLE;
1015
1016 GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(0);
1017 double size = PG_GETARG_FLOAT8(1);
1018 text *params_text;
1019
1020 if (PG_NARGS() > 2)
1021 {
1022 params_text = PG_GETARG_TEXT_P(2);
1023 }
1024 else
1025 {
1026 params_text = cstring_to_text("");
1027 }
1028
1029 /* Empty.Buffer() == Empty[polygon] */
1030 if ( gserialized_is_empty(geom1) )
1031 {
1033 gserialized_get_srid(geom1),
1034 0, 0)); // buffer wouldn't give back z or m anyway
1035 PG_RETURN_POINTER(geometry_serialize(lwg));
1036 }
1037
1038 lwg = lwgeom_from_gserialized(geom1);
1039
1040 if (!lwgeom_isfinite(lwg))
1041 {
1042 lwpgerror("Geometry contains invalid coordinates");
1043 PG_RETURN_NULL();
1044 }
1045 lwgeom_free(lwg);
1046
1047 initGEOS(lwpgnotice, lwgeom_geos_error);
1048
1049 g1 = POSTGIS2GEOS(geom1);
1050 if (!g1)
1051 HANDLE_GEOS_ERROR("First argument geometry could not be converted to GEOS");
1052
1053
1054 if (VARSIZE_ANY_EXHDR(params_text) > 0)
1055 {
1056 char *param;
1057 char *params = text_to_cstring(params_text);
1058
1059 for (param=params; ; param=NULL)
1060 {
1061 char *key, *val;
1062 param = strtok(param, " ");
1063 if (!param) break;
1064 POSTGIS_DEBUGF(3, "Param: %s", param);
1065
1066 key = param;
1067 val = strchr(key, '=');
1068 if (!val || *(val + 1) == '\0')
1069 {
1070 lwpgerror("Missing value for buffer parameter %s", key);
1071 break;
1072 }
1073 *val = '\0';
1074 ++val;
1075
1076 POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1077
1078 if ( !strcmp(key, "endcap") )
1079 {
1080 /* Supported end cap styles:
1081 * "round", "flat", "square"
1082 */
1083 if ( !strcmp(val, "round") )
1084 {
1085 endCapStyle = ENDCAP_ROUND;
1086 }
1087 else if ( !strcmp(val, "flat") ||
1088 !strcmp(val, "butt") )
1089 {
1090 endCapStyle = ENDCAP_FLAT;
1091 }
1092 else if ( !strcmp(val, "square") )
1093 {
1094 endCapStyle = ENDCAP_SQUARE;
1095 }
1096 else
1097 {
1098 lwpgerror("Invalid buffer end cap "
1099 "style: %s (accept: "
1100 "'round', 'flat', 'butt' "
1101 "or 'square'"
1102 ")", val);
1103 break;
1104 }
1105
1106 }
1107 else if ( !strcmp(key, "join") )
1108 {
1109 if ( !strcmp(val, "round") )
1110 {
1111 joinStyle = JOIN_ROUND;
1112 }
1113 else if ( !strcmp(val, "mitre") ||
1114 !strcmp(val, "miter") )
1115 {
1116 joinStyle = JOIN_MITRE;
1117 }
1118 else if ( !strcmp(val, "bevel") )
1119 {
1120 joinStyle = JOIN_BEVEL;
1121 }
1122 else
1123 {
1124 lwpgerror("Invalid buffer end cap "
1125 "style: %s (accept: "
1126 "'round', 'mitre', 'miter' "
1127 " or 'bevel'"
1128 ")", val);
1129 break;
1130 }
1131 }
1132 else if ( !strcmp(key, "mitre_limit") ||
1133 !strcmp(key, "miter_limit") )
1134 {
1135 /* mitreLimit is a float */
1136 mitreLimit = atof(val);
1137 }
1138 else if ( !strcmp(key, "quad_segs") )
1139 {
1140 /* quadrant segments is an int */
1141 quadsegs = atoi(val);
1142 }
1143 else if ( !strcmp(key, "side") )
1144 {
1145 if ( !strcmp(val, "both") )
1146 {
1147 singleside = 0;
1148 }
1149 else if ( !strcmp(val, "left") )
1150 {
1151 singleside = 1;
1152 }
1153 else if ( !strcmp(val, "right") )
1154 {
1155 singleside = 1;
1156 size *= -1;
1157 }
1158 else
1159 {
1160 lwpgerror("Invalid side parameter: %s (accept: 'right', 'left', 'both')", val);
1161 break;
1162 }
1163 }
1164 else
1165 {
1166 lwpgerror(
1167 "Invalid buffer parameter: %s (accept: 'endcap', 'join', 'mitre_limit', 'miter_limit', 'quad_segs' and 'side')",
1168 key);
1169 break;
1170 }
1171 }
1172 pfree(params); /* was pstrduped */
1173 }
1174
1175
1176 POSTGIS_DEBUGF(3, "endCap:%d joinStyle:%d mitreLimit:%g",
1177 endCapStyle, joinStyle, mitreLimit);
1178
1179 bufferparams = GEOSBufferParams_create();
1180 if (bufferparams)
1181 {
1182 if (GEOSBufferParams_setEndCapStyle(bufferparams, endCapStyle) &&
1183 GEOSBufferParams_setJoinStyle(bufferparams, joinStyle) &&
1184 GEOSBufferParams_setMitreLimit(bufferparams, mitreLimit) &&
1185 GEOSBufferParams_setQuadrantSegments(bufferparams, quadsegs) &&
1186 GEOSBufferParams_setSingleSided(bufferparams, singleside))
1187 {
1188 g3 = GEOSBufferWithParams(g1, bufferparams, size);
1189 }
1190 else
1191 {
1192 lwpgerror("Error setting buffer parameters.");
1193 }
1194 GEOSBufferParams_destroy(bufferparams);
1195 }
1196 else
1197 {
1198 lwpgerror("Error setting buffer parameters.");
1199 }
1200
1201 GEOSGeom_destroy(g1);
1202
1203 if (!g3) HANDLE_GEOS_ERROR("GEOSBuffer");
1204
1205 POSTGIS_DEBUGF(3, "result: %s", GEOSGeomToWKT(g3));
1206
1207 GEOSSetSRID(g3, gserialized_get_srid(geom1));
1208
1210 GEOSGeom_destroy(g3);
1211
1212 if (!result)
1213 {
1214 elog(ERROR,"GEOS buffer() threw an error (result postgis geometry formation)!");
1215 PG_RETURN_NULL(); /* never get here */
1216 }
1217
1218 PG_FREE_IF_COPY(geom1, 0);
1219 PG_RETURN_POINTER(result);
1220}
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
int gserialized_has_z(const GSERIALIZED *g)
Check if a GSERIALIZED has a Z ordinate.
void lwgeom_geos_error(const char *fmt,...)
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
int lwgeom_isfinite(const LWGEOM *lwgeom)
Check if a LWGEOM has any non-finite (NaN or Inf) coordinates.
Definition lwgeom.c:2835
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoly.c:161
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition lwgeom.c:357
GSERIALIZED * GEOS2POSTGIS(GEOSGeom geom, char want3d)
GEOSGeometry * POSTGIS2GEOS(const GSERIALIZED *pglwgeom)
#define HANDLE_GEOS_ERROR(label)

References GEOS2POSTGIS(), gserialized_get_srid(), gserialized_has_z(), gserialized_is_empty(), HANDLE_GEOS_ERROR, lwgeom_free(), lwgeom_from_gserialized(), lwgeom_geos_error(), lwgeom_isfinite(), lwpoly_as_lwgeom(), lwpoly_construct_empty(), POSTGIS2GEOS(), and result.

Referenced by add_overview_constraints(), add_raster_constraints(), analyze_table(), append_sql_to_buffer(), append_stringbuffer(), build_overview(), convert_raster(), copy_from(), copy_from_end(), create_index(), create_table(), do_test_s64_roundtrip(), do_test_u64_roundtrip(), drop_table(), dump_stringbuffer(), encode_ptarray(), encode_ptarray_initial(), flush_stringbuffer(), init_homogenizebuffer(), init_stringbuffer(), insert_records(), lwcollection_build_buffer(), lwcollection_homogenize(), lwgeom_to_wkb_buffer(), lwgeom_to_wkb_varlena(), lwgeom_to_wkb_write_buf(), main(), mvt_clip_and_validate(), mvt_clip_and_validate_geos(), mvt_geom(), process_rasters(), rtdealloc_stringbuffer(), spatial_index_read_extent(), ST_AsMVTGeom(), and vacuum_table().

Here is the call graph for this function:
Here is the caller graph for this function: