Return a raster of the provided geometry.
2512 double _scale[2] = {0};
2513 double _skew[2] = {0};
2516 OGRGeometryH src_geom;
2517 OGREnvelope src_env;
2519 OGRwkbGeometryType wkbtype = wkbUnknown;
2524 double _gt[6] = {0};
2525 GDALDriverH _drv = NULL;
2527 GDALDatasetH _ds = NULL;
2528 GDALRasterBandH _band = NULL;
2530 uint16_t _width = 0;
2531 uint16_t _height = 0;
2535 assert(NULL != wkb);
2536 assert(0 != wkb_len);
2541 rterror(
"rt_raster_gdal_rasterize: Could not initialize internal variables");
2546 if (num_bands < 1) {
2577 if (NULL != srs && strlen(srs)) {
2578 arg->
src_sr = OSRNewSpatialReference(NULL);
2579 if (OSRSetFromUserInput(arg->
src_sr, srs) != OGRERR_NONE) {
2580 rterror(
"rt_raster_gdal_rasterize: Could not create OSR spatial reference using the provided srs: %s", srs);
2587 ogrerr = OGR_G_CreateFromWkb((
unsigned char *) wkb, arg->
src_sr, &src_geom, wkb_len);
2588 if (ogrerr != OGRERR_NONE) {
2589 rterror(
"rt_raster_gdal_rasterize: Could not create OGR Geometry from WKB");
2598 if (OGR_G_IsEmpty(src_geom)) {
2599 rtinfo(
"Geometry provided is empty. Returning empty raster");
2601 OGR_G_DestroyGeometry(src_geom);
2609 OGR_G_GetEnvelope(src_geom, &src_env);
2612 RASTER_DEBUGF(3,
"Suggested raster envelope: %f, %f, %f, %f",
2617 (NULL != scale_x) &&
2618 (NULL != scale_y) &&
2623 _scale[0] = fabs(*scale_x);
2624 _scale[1] = fabs(*scale_y);
2633 _dim[0] = abs(*
width);
2637 _scale[0] = fabs((extent.
MaxX - extent.
MinX) / _dim[0]);
2642 _scale[1] = fabs((extent.
MaxY - extent.
MinY) / _dim[1]);
2647 rterror(
"rt_raster_gdal_rasterize: Values must be provided for width and height or X and Y of scale");
2649 OGR_G_DestroyGeometry(src_geom);
2655 RASTER_DEBUGF(3,
"scale (x, y) = %f, %f", _scale[0], -1 * _scale[1]);
2659 if (NULL != skew_x) {
2673 if (NULL != skew_y) {
2695 wkbtype = wkbFlatten(OGR_G_GetGeometryType(src_geom));
2697 (wkbtype == wkbPoint) ||
2698 (wkbtype == wkbMultiPoint) ||
2699 (wkbtype == wkbLineString) ||
2700 (wkbtype == wkbMultiLineString)
2708 GEOSGeometry *egeom = NULL;
2709 GEOSGeometry *geom = NULL;
2711 RASTER_DEBUG(3,
"Testing geometry is properly contained by extent");
2724 if (epoly == NULL) {
2725 rterror(
"rt_raster_gdal_rasterize: Could not create envelope's geometry to test if geometry is properly contained by extent");
2727 OGR_G_DestroyGeometry(src_geom);
2743 result = GEOSRelatePattern(egeom, geom,
"T**FF*FF*");
2744 GEOSGeom_destroy(geom);
2745 GEOSGeom_destroy(egeom);
2748 rterror(
"rt_raster_gdal_rasterize: Could not test if geometry is properly contained by extent for geometry within extent");
2750 OGR_G_DestroyGeometry(src_geom);
2760 #if POSTGIS_GDAL_VERSION > 18 2764 (NULL == ul_xw && NULL == ul_yw) &&
2765 (NULL != grid_xw && NULL != grid_xw) &&
2769 RASTER_DEBUG(3,
"Skipping extent adjustment on X-axis due to upcoming alignment");
2772 RASTER_DEBUG(3,
"Adjusting extent for GDAL > 1.8 by half the scale on X-axis");
2773 extent.
MinX -= (_scale[0] / 2.);
2774 extent.
MaxX += (_scale[0] / 2.);
2779 (NULL == ul_xw && NULL == ul_yw) &&
2780 (NULL != grid_xw && NULL != grid_xw) &&
2784 RASTER_DEBUG(3,
"Skipping extent adjustment on Y-axis due to upcoming alignment");
2787 RASTER_DEBUG(3,
"Adjusting extent for GDAL > 1.8 by half the scale on Y-axis");
2788 extent.
MinY -= (_scale[1] / 2.);
2789 extent.
MaxY += (_scale[1] / 2.);
2796 (NULL == ul_xw && NULL == ul_yw) &&
2797 (NULL != grid_xw && NULL != grid_xw) &&
2801 RASTER_DEBUG(3,
"Skipping extent adjustment on X-axis due to upcoming alignment");
2804 RASTER_DEBUG(3,
"Adjusting extent for GDAL <= 1.8 by the scale on X-axis");
2805 extent.
MinX -= _scale[0];
2806 extent.
MaxX += _scale[0];
2812 (NULL == ul_xw && NULL == ul_yw) &&
2813 (NULL != grid_xw && NULL != grid_xw) &&
2817 RASTER_DEBUG(3,
"Skipping extent adjustment on Y-axis due to upcoming alignment");
2820 RASTER_DEBUG(3,
"Adjusting extent for GDAL <= 1.8 by the scale on Y-axis");
2821 extent.
MinY -= _scale[1];
2822 extent.
MaxY += _scale[1];
2851 if (skewedrast == NULL) {
2852 rterror(
"rt_raster_gdal_rasterize: Could not compute skewed raster");
2854 OGR_G_DestroyGeometry(src_geom);
2861 _dim[0] = skewedrast->
width;
2862 _dim[1] = skewedrast->
height;
2872 _dim[0] = (int) fmax((fabs(extent.
MaxX - extent.
MinX) + (_scale[0] / 2.)) / _scale[0], 1);
2874 _dim[1] = (int) fmax((fabs(extent.
MaxY - extent.
MinY) + (_scale[1] / 2.)) / _scale[1], 1);
2879 rterror(
"rt_raster_gdal_rasterize: Out of memory allocating temporary raster");
2881 OGR_G_DestroyGeometry(src_geom);
2894 RASTER_DEBUGF(3,
"Temp raster's geotransform: %f, %f, %f, %f, %f, %f",
2895 _gt[0], _gt[1], _gt[2], _gt[3], _gt[4], _gt[5]);
2896 RASTER_DEBUGF(3,
"Temp raster's dimensions (width x height): %d x %d",
2906 RASTER_DEBUGF(4,
"Using user-specified upper-left corner: %f, %f", *ul_xw, *ul_yw);
2914 ((NULL != ul_xw) && (NULL == ul_yw)) ||
2915 ((NULL == ul_xw) && (NULL != ul_yw))
2917 rterror(
"rt_raster_gdal_rasterize: Both X and Y upper-left corner values must be provided");
2920 OGR_G_DestroyGeometry(src_geom);
2930 (NULL != grid_xw) || (NULL != grid_yw)
2935 ((NULL != grid_xw) && (NULL == grid_yw)) ||
2936 ((NULL == grid_xw) && (NULL != grid_yw))
2938 rterror(
"rt_raster_gdal_rasterize: Both X and Y alignment values must be provided");
2941 OGR_G_DestroyGeometry(src_geom);
2948 RASTER_DEBUGF(4,
"Aligning extent to user-specified grid: %f, %f", *grid_xw, *grid_yw);
2956 RASTER_DEBUG(3,
"Skipping raster alignment as it is already aligned to grid");
2971 rterror(
"rt_raster_gdal_rasterize: Could not compute raster pixel for spatial coordinates");
2974 OGR_G_DestroyGeometry(src_geom);
2987 rterror(
"rt_raster_gdal_rasterize: Could not compute spatial coordinates for raster pixel");
2990 OGR_G_DestroyGeometry(src_geom);
3001 else if (NULL == scale_x) {
3013 rterror(
"rt_raster_gdal_rasterize: Could not compute spatial coordinates for raster pixel");
3016 OGR_G_DestroyGeometry(src_geom);
3023 rast->
scaleX = fabs((_c[0] - _w[0]) / ((
double) rast->
width));
3029 else if (NULL == scale_y) {
3041 rterror(
"rt_raster_gdal_rasterize: Could not compute spatial coordinates for raster pixel");
3044 OGR_G_DestroyGeometry(src_geom);
3051 rast->
scaleY = -1 * fabs((_c[1] - _w[1]) / ((
double) rast->
height));
3065 _dim[0] = rast->
width;
3071 (NULL != scale_x) && (*scale_x < 0.)
3073 (NULL != scale_y) && (*scale_y > 0)
3079 (NULL != scale_x) &&
3090 rterror(
"rt_raster_gdal_rasterize: Could not compute spatial coordinates for raster pixel");
3093 OGR_G_DestroyGeometry(src_geom);
3104 if (NULL != skew_x &&
FLT_NEQ(*skew_x, 0))
3109 (NULL != scale_y) &&
3120 rterror(
"rt_raster_gdal_rasterize: Could not compute spatial coordinates for raster pixel");
3123 OGR_G_DestroyGeometry(src_geom);
3134 if (NULL != skew_y &&
FLT_NEQ(*skew_y, 0))
3142 RASTER_DEBUGF(3,
"Applied geotransform: %f, %f, %f, %f, %f, %f",
3143 _gt[0], _gt[1], _gt[2], _gt[3], _gt[4], _gt[5]);
3144 RASTER_DEBUGF(3,
"Raster dimensions (width x height): %d x %d",
3153 _drv = GDALGetDriverByName(
"MEM");
3155 rterror(
"rt_raster_gdal_rasterize: Could not load the MEM GDAL driver");
3157 OGR_G_DestroyGeometry(src_geom);
3167 GDALDeregisterDriver(_drv);
3170 _ds = GDALCreate(_drv,
"", _dim[0], _dim[1], 0, GDT_Byte, NULL);
3172 rterror(
"rt_raster_gdal_rasterize: Could not create a GDALDataset to rasterize the geometry into");
3174 OGR_G_DestroyGeometry(src_geom);
3177 if (unload_drv) GDALDestroyDriver(_drv);
3183 cplerr = GDALSetGeoTransform(_ds, _gt);
3184 if (cplerr != CE_None) {
3185 rterror(
"rt_raster_gdal_rasterize: Could not set geotransform on GDALDataset");
3187 OGR_G_DestroyGeometry(src_geom);
3192 if (unload_drv) GDALDestroyDriver(_drv);
3198 if (NULL != arg->
src_sr) {
3200 OSRExportToWkt(arg->
src_sr, &_srs);
3202 cplerr = GDALSetProjection(_ds, _srs);
3204 if (cplerr != CE_None) {
3205 rterror(
"rt_raster_gdal_rasterize: Could not set projection on GDALDataset");
3207 OGR_G_DestroyGeometry(src_geom);
3212 if (unload_drv) GDALDestroyDriver(_drv);
3219 for (i = 0; i < arg->
numbands; i++) {
3225 if (cplerr != CE_None) {
3226 rterror(
"rt_raster_gdal_rasterize: Could not add band to GDALDataset");
3231 _band = GDALGetRasterBand(_ds, i + 1);
3232 if (NULL == _band) {
3233 rterror(
"rt_raster_gdal_rasterize: Could not get band %d from GDALDataset", i + 1);
3241 cplerr = GDALSetRasterNoDataValue(_band, arg->
nodata[i]);
3242 if (cplerr != CE_None) {
3243 rterror(
"rt_raster_gdal_rasterize: Could not set nodata value");
3247 RASTER_DEBUGF(4,
"NODATA value set to %f", GDALGetRasterNoDataValue(_band, NULL));
3251 cplerr = GDALFillRaster(_band, arg->
init[i], 0);
3252 if (cplerr != CE_None) {
3253 rterror(
"rt_raster_gdal_rasterize: Could not set initial value");
3262 OGR_G_DestroyGeometry(src_geom);
3268 if (unload_drv) GDALDestroyDriver(_drv);
3278 cplerr = GDALRasterizeGeometries(
3287 if (cplerr != CE_None) {
3288 rterror(
"rt_raster_gdal_rasterize: Could not rasterize geometry");
3290 OGR_G_DestroyGeometry(src_geom);
3295 if (unload_drv) GDALDestroyDriver(_drv);
3301 GDALFlushCache(_ds);
3305 OGR_G_DestroyGeometry(src_geom);
3309 if (unload_drv) GDALDestroyDriver(_drv);
3312 rterror(
"rt_raster_gdal_rasterize: Could not rasterize geometry");
3321 for (i = 0; i < arg->
numbands; i++) {
3329 double nodataval = 0;
3334 if (oldband == NULL) {
3335 rterror(
"rt_raster_gdal_rasterize: Could not get band %d of output raster", i);
3353 rterror(
"rt_raster_gdal_rasterize: Could not allocate memory for band data");
3364 hasnodata, nodataval,
3368 rterror(
"rt_raster_gdal_rasterize: Could not create band");
3379 for (x = 0; x < _width; x++) {
3380 for (y = 0; y < _height; y++) {
3383 rterror(
"rt_raster_gdal_rasterize: Could not get pixel value");
3395 rterror(
"rt_raster_gdal_rasterize: Could not set pixel value");
3406 if (oldband == NULL) {
3407 rterror(
"rt_raster_gdal_rasterize: Could not replace band %d of output raster", i);
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
rt_band rt_raster_replace_band(rt_raster raster, rt_band band, int index)
Replace band at provided index with new band.
void lwgeom_free(LWGEOM *geom)
rt_errorstate rt_raster_cell_to_geopoint(rt_raster raster, double xr, double yr, double *xw, double *yw, double *gt)
Convert an xr, yr raster point to an xw, yw point on map.
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
LWPOLY * rt_util_envelope_to_lwpoly(rt_envelope ext)
OGRSpatialReferenceH src_sr
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw,yw map point to a xr,yr raster point.
rt_raster rt_raster_compute_skewed_raster(rt_envelope extent, double *skew, double *scale, double tolerance)
void rt_band_destroy(rt_band band)
Destroy a raster band.
static _rti_rasterize_arg _rti_rasterize_arg_init()
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
#define LW_PARSER_CHECK_NONE
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
static void _rti_rasterize_arg_destroy(_rti_rasterize_arg arg)
void rt_band_set_ownsdata_flag(rt_band band, int flag)
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
int rt_util_gdal_driver_registered(const char *drv)
void lwgeom_geos_error(const char *fmt,...)
void lwpoly_free(LWPOLY *poly)
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
void rtinfo(const char *fmt,...)
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
#define RASTER_DEBUGF(level, msg,...)
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, int autofix)
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
rt_band rt_band_new_inline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t *data)
Create an in-db rt_band with no data.
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
void rtdealloc(void *mem)
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
#define RASTER_DEBUG(level, msg)
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
void rt_util_from_ogr_envelope(OGREnvelope env, rt_envelope *ext)
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
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...
uint16_t rt_raster_get_height(rt_raster raster)
uint16_t rt_raster_get_width(rt_raster raster)
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.