PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ rt_raster_gdal_contour()

int rt_raster_gdal_contour ( rt_raster  src_raster,
int  src_band,
int  src_srid,
const char *  src_srs,
double  contour_interval,
double  contour_base,
int  fixed_level_count,
double *  fixed_levels,
int  polygonize,
size_t *  ncontours,
struct rt_contour_t **  contours 
)

Return palloc'ed list of contours.

Parameters
src_raster: raster to generate contour from
options: CSList of OPTION=VALUE strings for the contour routine, see https://gdal.org/api/gdal_alg.html?highlight=contour#_CPPv419GDALContourGenerate15GDALRasterBandHddiPdidPvii16GDALProgressFuncPv
src_srs: Coordinate reference system string for raster
ncontours: Output parameter for length of contour list
contours: palloc'ed list of contours, caller to free
src_raster: raster to generate contour from
options: CSList of OPTION=VALUE strings for the contour routine, see https://gdal.org/api/gdal_alg.html?highlight=contour#_CPPv419GDALContourGenerate15GDALRasterBandHddiPdidPvii16GDALProgressFuncPv
src_srs: Coordinate reference system string for raster
ncontours: Output parameter for length of contour list
contours: Output palloc'ed list of contours, caller to free

Definition at line 89 of file rt_gdal.c.

104 {
105  CPLErr cplerr;
106  OGRErr ogrerr;
107  GDALRasterBandH hBand;
108  int nfeatures = 0, i = 0;
109  OGRFeatureH hFeat;
110 
111  _rti_contour_arg arg;
112  _rti_contour_arg_init(&arg);
113 
114  /* Load raster into GDAL memory */
115  arg.src.ds = rt_raster_to_gdal_mem(src_raster, src_srs, NULL, NULL, 0, &(arg.src.drv), &(arg.src.destroy_drv));
116  /* Extract the desired band */
117  hBand = GDALGetRasterBand(arg.src.ds, src_band);
118 
119  /* Set up the OGR destination data store */
120  arg.dst.srid = src_srid;
121  arg.dst.drv = OGRGetDriverByName("Memory");
122  if (!arg.dst.drv)
123  return _rti_contour_arg_destroy(&arg);
124 
125  arg.dst.ds = OGR_Dr_CreateDataSource(arg.dst.drv, "contour_ds", NULL);
126  if (!arg.dst.ds)
127  return _rti_contour_arg_destroy(&arg);
128 
129  /* Polygonize is 2.4+ only */
130 #if POSTGIS_GDAL_VERSION >= 24
131  arg.dst.gtype = polygonize ? wkbPolygon : wkbLineString;
132 #else
133  arg.dst.gtype = wkbLineString;
134 #endif
135 
136  /* Layer has geometry, elevation, id */
137  arg.dst.lyr = OGR_DS_CreateLayer(arg.dst.ds, "contours", NULL, arg.dst.gtype, NULL);
138  if (!arg.dst.lyr)
139  return _rti_contour_arg_destroy(&arg);
140 
141  /* ID field */
142  OGRFieldDefnH hFldId = OGR_Fld_Create("id", OFTInteger);
143  ogrerr = OGR_L_CreateField(arg.dst.lyr, hFldId, TRUE);
144  if (ogrerr != OGRERR_NONE)
145  return _rti_contour_arg_destroy(&arg);
146 
147  /* ELEVATION field */
148  OGRFieldDefnH hFldElevation = OGR_Fld_Create("elevation", OFTReal);
149  ogrerr = OGR_L_CreateField(arg.dst.lyr, hFldElevation, TRUE);
150  if (ogrerr != OGRERR_NONE)
151  return _rti_contour_arg_destroy(&arg);
152 
153  // GDALContourGenerate( GDALRasterBandH hBand,
154  // double dfContourInterval, double dfContourBase,
155  // int nFixedLevelCount, double *padfFixedLevels,
156  // int bUseNoData, double dfNoDataValue,
157  // void *hLayer, int iIDField, int iElevField,
158  // GDALProgressFunc pfnProgress, void *pProgressArg );
159 
160  int use_no_data = 0;
161  double no_data_value = GDALGetRasterNoDataValue(hBand, &use_no_data);;
162 
163  /* Run the contouring routine, filling up the OGR layer */
164  cplerr = GDALContourGenerate(
165  hBand,
166  contour_interval, contour_base,
167  fixed_level_count, fixed_levels,
168  use_no_data, no_data_value,
169  arg.dst.lyr, 0, 1, // OGRLayer, idFieldNum, elevFieldNum
170  NULL, // GDALProgressFunc pfnProgress
171  NULL // void *pProgressArg
172  );
173 
174  if (cplerr != CE_None)
175  return _rti_contour_arg_destroy(&arg);
176 
177  /* Convert the OGR layer into PostGIS geometries */
178  nfeatures = OGR_L_GetFeatureCount(arg.dst.lyr, TRUE);
179  if (nfeatures < 0)
180  return _rti_contour_arg_destroy(&arg);
181 
182  *contours = rtalloc(sizeof(struct rt_contour_t) * nfeatures);
183  OGR_L_ResetReading(arg.dst.lyr);
184  while ((hFeat = OGR_L_GetNextFeature(arg.dst.lyr))) {
185  size_t szWkb;
186  unsigned char *bufWkb;
187  struct rt_contour_t contour;
188  OGRGeometryH hGeom;
189  LWGEOM *geom;
190 
191  /* Somehow we're still iterating, should not happen. */
192  if(i >= nfeatures) break;
193 
194  /* Store elevation/id */
195  contour.id = OGR_F_GetFieldAsInteger(hFeat, 0);
196  contour.elevation = OGR_F_GetFieldAsDouble(hFeat, 1);
197  /* Convert OGR geometry to LWGEOM via WKB */
198  if (!(hGeom = OGR_F_GetGeometryRef(hFeat))) continue;
199  szWkb = OGR_G_WkbSize(hGeom);
200  bufWkb = rtalloc(szWkb);
201  if (OGR_G_ExportToWkb(hGeom, wkbNDR, bufWkb) != OGRERR_NONE) continue;
202  /* Reclaim feature and associated geometry memory */
203  OGR_F_Destroy(hFeat);
204  geom = lwgeom_from_wkb(bufWkb, szWkb, LW_PARSER_CHECK_NONE);
205  if (!geom) rterror("%s: invalid wkb", __func__);
207  contour.geom = gserialized_from_lwgeom(geom, NULL);
208  lwgeom_free(geom);
209  rtdealloc(bufWkb);
210  (*contours)[i++] = contour;
211  }
212 
213  /* Return total number of contours saved */
214  *ncontours = i;
215 
216  /* Free all the non-database allocated structures */
218 
219  /* Done */
220  return TRUE;
221 }
#define TRUE
Definition: dbfopen.c:73
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Definition: gserialized.c:222
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
Definition: lwgeom.c:1547
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2096
LWGEOM * lwgeom_from_wkb(const uint8_t *wkb, const size_t wkb_size, const char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
Definition: lwin_wkb.c:834
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:219
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:191
void rtdealloc(void *mem)
Definition: rt_context.c:206
GDALDatasetH rt_raster_to_gdal_mem(rt_raster raster, const char *srs, uint32_t *bandNums, int *excludeNodataValues, int count, GDALDriverH *rtn_drv, int *destroy_rtn_drv)
Return GDAL dataset using GDAL MEM driver from raster.
Definition: rt_raster.c:1935
src_band
Definition: pixval.py:76
static int _rti_contour_arg_destroy(_rti_contour_arg *arg)
Definition: rt_gdal.c:62
static void _rti_contour_arg_init(_rti_contour_arg *arg)
Definition: rt_gdal.c:54
struct _rti_contour_arg::@12 dst
GDALDatasetH ds
Definition: rt_gdal.c:37
GDALDriverH drv
Definition: rt_gdal.c:38
OGRLayerH lyr
Definition: rt_gdal.c:45
OGRwkbGeometryType gtype
Definition: rt_gdal.c:47
struct _rti_contour_arg::@11 src
GSERIALIZED * geom
Definition: librtcore.h:1749

References _rti_contour_arg_destroy(), _rti_contour_arg_init(), _rti_contour_arg::destroy_drv, _rti_contour_arg::drv, _rti_contour_arg::ds, _rti_contour_arg::dst, rt_contour_t::elevation, rt_contour_t::geom, gserialized_from_lwgeom(), _rti_contour_arg::gtype, rt_contour_t::id, LW_PARSER_CHECK_NONE, lwgeom_free(), lwgeom_from_wkb(), lwgeom_set_srid(), _rti_contour_arg::lyr, rt_raster_to_gdal_mem(), rtalloc(), rtdealloc(), rterror(), _rti_contour_arg::src, pixval::src_band, _rti_contour_arg::srid, and TRUE.

Referenced by RASTER_Contour().

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