2051{
2055 int bandindex = 1;
2056 int num_bands = 0;
2059 int _x = 0;
2060 int _y = 0;
2062 bool exclude_nodata_value =
TRUE;
2064 int isnodata = 0;
2065
2068 double **value2D = NULL;
2069 int **nodata2D = NULL;
2070
2071 int i = 0;
2072 int j = 0;
2073 int k = 0;
2074 Datum *value1D = NULL;
2075 bool *nodata1D = NULL;
2076 int dim[2] = {0};
2077 int lbound[2] = {1, 1};
2078 ArrayType *mdArray = NULL;
2079
2080 int16 typlen;
2081 bool typbyval;
2082 char typalign;
2083
2084
2085 if (PG_ARGISNULL(0))
2086 PG_RETURN_NULL();
2087 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
2088
2090 if (!raster) {
2091 PG_FREE_IF_COPY(pgraster, 0);
2092 elog(ERROR, "RASTER_neighborhood: Could not deserialize raster");
2093 PG_RETURN_NULL();
2094 }
2095
2096
2097 if (!PG_ARGISNULL(1))
2098 bandindex = PG_GETARG_INT32(1);
2100 if (bandindex < 1 || bandindex > num_bands) {
2101 elog(NOTICE, "Invalid band index (must use 1-based). Returning NULL");
2103 PG_FREE_IF_COPY(pgraster, 0);
2104 PG_RETURN_NULL();
2105 }
2106
2107
2108 x = PG_GETARG_INT32(2);
2110
2111
2112 y = PG_GETARG_INT32(3);
2114
2115
2118 elog(NOTICE, "Invalid value for distancex (must be >= zero). Returning NULL");
2120 PG_FREE_IF_COPY(pgraster, 0);
2121 PG_RETURN_NULL();
2122 }
2124
2125
2128 elog(NOTICE, "Invalid value for distancey (must be >= zero). Returning NULL");
2130 PG_FREE_IF_COPY(pgraster, 0);
2131 PG_RETURN_NULL();
2132 }
2134
2135
2136 if (!PG_ARGISNULL(6))
2137 exclude_nodata_value = PG_GETARG_BOOL(6);
2138
2139
2141 if (!band) {
2142 elog(NOTICE, "Could not find band at index %d. Returning NULL", bandindex);
2144 PG_FREE_IF_COPY(pgraster, 0);
2145 PG_RETURN_NULL();
2146 }
2147
2148
2150 npixels = NULL;
2153 band,
2154 _x, _y,
2156 exclude_nodata_value,
2157 &npixels
2158 );
2159
2160 if (count < 0) {
2161 elog(NOTICE, "Could not get the pixel's neighborhood for band at index %d", bandindex);
2162
2165 PG_FREE_IF_COPY(pgraster, 0);
2166
2167 PG_RETURN_NULL();
2168 }
2169 }
2170
2171
2172 if (
2175 ) {
2177 band,
2178 _x, _y,
2180 &isnodata
2182 elog(NOTICE, "Could not get the pixel of band at index %d. Returning NULL", bandindex);
2185 PG_FREE_IF_COPY(pgraster, 0);
2186 PG_RETURN_NULL();
2187 }
2188 }
2189
2190 else {
2191
2194
2195 else
2197 isnodata = 1;
2198 }
2200
2201
2202
2204 if (count > 1)
2206 else
2208 if (npixels == NULL) {
2209
2212 PG_FREE_IF_COPY(pgraster, 0);
2213
2214 elog(ERROR, "RASTER_neighborhood: Could not reallocate memory for neighborhood");
2215 PG_RETURN_NULL();
2216 }
2217 npixels[
count - 1].
x = _x;
2218 npixels[
count - 1].
y = _y;
2221
2222
2223 if (!exclude_nodata_value || !isnodata) {
2225 }
2226
2227
2230 PG_FREE_IF_COPY(pgraster, 0);
2231
2232
2233
2235 npixels, count, NULL,
2236 _x, _y,
2238 &value2D,
2239 &nodata2D,
2240 &(dim[1]), &(dim[0])
2241 );
2242 pfree(npixels);
2244 elog(NOTICE, "Could not create 2D array of neighborhood");
2245 PG_RETURN_NULL();
2246 }
2247
2248
2249 value1D = palloc(sizeof(Datum) * dim[0] * dim[1]);
2250 nodata1D = palloc(sizeof(bool) * dim[0] * dim[1]);
2251
2252 if (value1D == NULL || nodata1D == NULL) {
2253
2254 for (i = 0; i < dim[0]; i++) {
2255 pfree(value2D[i]);
2256 pfree(nodata2D[i]);
2257 }
2258 pfree(value2D);
2259 pfree(nodata2D);
2260
2261 elog(ERROR, "RASTER_neighborhood: Could not allocate memory for return 2D array");
2262 PG_RETURN_NULL();
2263 }
2264
2265
2266 k = 0;
2267
2268 for (i = 0; i < dim[0]; i++) {
2269
2270 for (j = 0; j < dim[1]; j++) {
2271 nodata1D[k] = (bool) nodata2D[i][j];
2272 if (!nodata1D[k])
2273 value1D[k] = Float8GetDatum(value2D[i][j]);
2274 else
2275 value1D[k] = PointerGetDatum(NULL);
2276
2277 k++;
2278 }
2279 }
2280
2281
2282 for (i = 0; i < dim[0]; i++) {
2283 pfree(value2D[i]);
2284 pfree(nodata2D[i]);
2285 }
2286 pfree(value2D);
2287 pfree(nodata2D);
2288
2289
2290 get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
2291
2292 mdArray = construct_md_array(
2293 value1D, nodata1D,
2294 2, dim, lbound,
2295 FLOAT8OID,
2296 typlen, typbyval, typalign
2297 );
2298
2299 pfree(value1D);
2300 pfree(nodata1D);
2301
2302 PG_RETURN_ARRAYTYPE_P(mdArray);
2303}
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
struct rt_pixel_t * rt_pixel
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
void rt_band_destroy(rt_band band)
Destroy a raster band.
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_errorstate rt_pixel_set_to_array(rt_pixel npixel, uint32_t count, rt_mask mask, int x, int y, uint16_t distancex, uint16_t distancey, double ***value, int ***nodata, int *dimx, int *dimy)
uint32_t rt_band_get_nearest_pixel(rt_band band, int x, int y, uint16_t distancex, uint16_t distancey, int exclude_nodata_value, rt_pixel *npixels)
Get nearest pixel(s) with value (not NODATA) to specified pixel.
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
static double distance(double x1, double y1, double x2, double y2)
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
#define POSTGIS_RT_DEBUGF(level, msg,...)