30 #include "ogr_srs_api.h"
33 #define xstr(s) str(s)
38 static const char *label =
"ERROR: ";
39 char newfmt[1024] = {0};
40 snprintf(newfmt, 1024,
"%s%s\n", label,
fmt);
42 vfprintf(stderr, newfmt, ap);
48 static const char *label =
"WARNING: ";
49 char newfmt[1024] = {0};
50 snprintf(newfmt, 1024,
"%s%s\n", label,
fmt);
52 vfprintf(stderr, newfmt, ap);
58 static const char *label =
"INFO: ";
59 char newfmt[1024] = {0};
60 snprintf(newfmt, 1024,
"%s%s\n", label,
fmt);
62 vfprintf(stderr, newfmt, ap);
82 for (i = 0; i < nbands; i++) {
84 if (
band == NULL)
continue;
96 array_range(
int min,
int max,
int step,
int **range, uint32_t *len) {
101 *len = (uint32_t) ((abs(max - min) + 1 + (step / 2)) / step);
102 *range =
rtalloc(
sizeof(
int) * *len);
105 for (i = min, j = 0; i <= max; i += step, j++)
108 else if (max < min) {
109 if (step > 0) step *= -1;
110 for (i = min, j = 0; i >= max; i += step, j++)
113 else if (min == max) {
146 const char *oldstr,
const char *newstr,
149 const char *tmp =
str;
153 int oldlen = strlen(oldstr);
154 int newlen = strlen(newstr);
158 while ((tmp = strstr(tmp, oldstr)) != NULL && found != limit)
159 found++, tmp += oldlen;
161 length = strlen(
str) + found * (newlen - oldlen);
162 if ((result = (
char *)
rtalloc(length + 1)) == NULL) {
163 rterror(
_(
"strreplace: Not enough memory"));
172 while ((limit-- > 0) && (tmp = strstr(tmp, oldstr)) != NULL) {
173 length = (tmp -
str);
174 strncpy(result + reslen,
str, length);
175 strcpy(result + (reslen += length), newstr);
181 strcpy(result + reslen,
str);
192 for (j = strlen(
str) - 1; j >= 0; j--)
210 tmp =
rtalloc(
sizeof(
char) * (strlen(
str) + 1));
212 rterror(
_(
"strsplit: Not enough memory"));
217 if (!strlen(tmp) || !delimiter || !strlen(delimiter)) {
219 rtn = (
char **)
rtalloc(*n *
sizeof(
char *));
221 rterror(
_(
"strsplit: Not enough memory"));
224 rtn[0] = (
char *)
rtalloc(
sizeof(
char) * (strlen(tmp) + 1));
225 if (NULL == rtn[0]) {
226 rterror(
_(
"strsplit: Not enough memory"));
234 token = strtok(tmp, delimiter);
235 while (token != NULL) {
237 rtn = (
char **)
rtalloc(
sizeof(
char *));
240 rtn = (
char **)
rtrealloc(rtn, (*n + 1) *
sizeof(
char *));
243 rterror(
_(
"strsplit: Not enough memory"));
248 rtn[*n] = (
char *)
rtalloc(
sizeof(
char) * (strlen(token) + 1));
249 if (NULL == rtn[*n]) {
250 rterror(
_(
"strsplit: Not enough memory"));
254 strcpy(rtn[*n], token);
257 token = strtok(NULL, delimiter);
274 return (
char *) input;
277 while (isspace(*input))
281 ptr = ((
char *) input) + strlen(input);
282 while (isspace(*--ptr))
285 len = strlen(input) - offset + 1;
286 rtn =
rtalloc(
sizeof(
char) * len);
288 rterror(
_(
"trim: Not enough memory"));
291 strncpy(rtn, input, len);
306 return (
char *) input;
309 while (strchr(remove, *input) != NULL)
313 ptr = ((
char *) input) + strlen(input);
314 while (strchr(remove, *--ptr) != NULL)
317 len = strlen(input) - offset + 1;
318 rtn =
rtalloc(
sizeof(
char) * len);
320 rterror(
_(
"chartrim: Not enough memory"));
323 strncpy(rtn, input, len);
324 rtn[strlen(input) - offset] =
'\0';
333 "USAGE: raster2pgsql [<options>] <raster>[ <raster>[ ...]] [[<schema>.]<table>]\n"
334 " Multiple rasters can also be specified using wildcards (*,?).\n"
347 " -s <srid> Set the SRID field. Defaults to %d. If SRID not\n"
348 " provided or is %d, raster's metadata will be checked to\n"
349 " determine an appropriate SRID.\n"
352 " -b <band> Index (1-based) of band to extract from raster. For more\n"
353 " than one band index, separate with comma (,). Ranges can be\n"
354 " defined by separating with dash (-). If unspecified, all bands\n"
355 " of raster will be extracted.\n"
358 " -t <tile size> Cut raster into tiles to be inserted one per\n"
359 " table row. <tile size> is expressed as WIDTHxHEIGHT.\n"
360 " <tile size> can also be \"auto\" to allow the loader to compute\n"
361 " an appropriate tile size using the first raster and applied to\n"
365 " -P Pad right-most and bottom-most tiles to guarantee that all tiles\n"
366 " have the same width and height.\n"
369 " -R Register the raster as an out-of-db (filesystem) raster. Provided\n"
370 " raster should have absolute path to the file\n"
373 " (-d|a|c|p) These are mutually exclusive options:\n"
374 " -d Drops the table, then recreates it and populates\n"
375 " it with current raster data.\n"
376 " -a Appends raster into current table, must be\n"
377 " exactly the same table schema.\n"
378 " -c Creates a new table and populates it, this is the\n"
379 " default if you do not specify any options.\n"
380 " -p Prepare mode, only creates the table.\n"
383 " -f <column> Specify the name of the raster column\n"
386 " -F Add a column with the filename of the raster.\n"
389 " -n <column> Specify the name of the filename column. Implies -F.\n"
392 " -l <overview factor> Create overview of the raster. For more than\n"
393 " one factor, separate with comma(,). Overview table name follows\n"
394 " the pattern o_<overview factor>_<table>. Created overview is\n"
395 " stored in the database and is not affected by -R.\n"
398 " -q Wrap PostgreSQL identifiers in quotes.\n"
401 " -I Create a GIST spatial index on the raster column. The ANALYZE\n"
402 " command will automatically be issued for the created index.\n"
405 " -M Run VACUUM ANALYZE on the table of the raster column. Most\n"
406 " useful when appending raster to existing table with -a.\n"
409 " -C Set the standard set of constraints on the raster\n"
410 " column after the rasters are loaded. Some constraints may fail\n"
411 " if one or more rasters violate the constraint.\n"
412 " -x Disable setting the max extent constraint. Only applied if\n"
413 " -C flag is also used.\n"
414 " -r Set the constraints (spatially unique and coverage tile) for\n"
415 " regular blocking. Only applied if -C flag is also used.\n"
418 " -T <tablespace> Specify the tablespace for the new table.\n"
419 " Note that indices (including the primary key) will still use\n"
420 " the default tablespace unless the -X flag is also used.\n"
423 " -X <tablespace> Specify the tablespace for the table's new index.\n"
424 " This applies to the primary key and the spatial index if\n"
425 " the -I flag is used.\n"
428 " -N <nodata> NODATA value to use on bands without a NODATA value.\n"
431 " -k Skip NODATA value checks for each raster band.\n"
434 " -E <endian> Control endianness of generated binary output of\n"
435 " raster. Use 0 for XDR and 1 for NDR (default). Only NDR\n"
436 " is supported at this time.\n"
439 " -V <version> Specify version of output WKB format. Default\n"
440 " is 0. Only 0 is supported at this time.\n"
443 " -e Execute each statement individually, do not use a transaction.\n"
446 " -Y Use COPY statements instead of INSERT statements.\n"
449 " -G Print the supported GDAL raster formats.\n"
452 " -? Display this help screen.\n"
457 calc_tile_size(uint32_t dimX, uint32_t dimY,
int *tileX,
int *tileY)
459 uint32_t min_tile_size = 30;
460 uint32_t max_tile_size = 300;
462 for (uint8_t current_dimension = 0; current_dimension <= 1; current_dimension++)
464 uint32_t img_size = (current_dimension == 0) ? dimX : dimY;
465 uint32_t best_gap = max_tile_size;
466 uint32_t best_size = img_size;
468 if (img_size > max_tile_size)
470 for (uint32_t tile_size = max_tile_size; tile_size >= min_tile_size; tile_size--)
472 uint32_t gap = img_size % tile_size;
476 best_size = tile_size;
481 if (current_dimension == 0)
492 memset(info->
dim, 0,
sizeof(uint32_t) * 2);
499 memset(info->
gt, 0,
sizeof(
double) * 6);
500 memset(info->
tile_size, 0,
sizeof(
int) * 2);
505 if (info->
srs != NULL)
521 if (src->
srs != NULL) {
523 if (dst->
srs == NULL) {
524 rterror(
_(
"copy_rastinfo: Not enough memory"));
527 strcpy(dst->
srs, src->
srs);
529 memcpy(dst->
dim, src->
dim,
sizeof(uint32_t) * 2);
533 if (dst->
nband == NULL) {
534 rterror(
_(
"copy_rastinfo: Not enough memory"));
542 rterror(
_(
"copy_rastinfo: Not enough memory"));
550 rterror(
_(
"copy_rastinfo: Not enough memory"));
558 rterror(
_(
"copy_rastinfo: Not enough memory"));
566 rterror(
_(
"copy_rastinfo: Not enough memory"));
571 memcpy(dst->
gt, src->
gt,
sizeof(
double) * 6);
579 static uint8_t msg[6] = {0};
587 rtwarn(
_(
"Different number of bands found in the set of rasters being converted to PostGIS raster"));
594 if (
x->bandtype[i] != ref->
bandtype[i]) {
595 rtwarn(
_(
"Different pixel types found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
605 rtwarn(
_(
"Different hasnodata flags found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
614 if (!
x->hasnodata[i] && !ref->
hasnodata[i])
continue;
616 rtwarn(
_(
"Different NODATA values found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
633 rterror(
_(
"diff_rastinfo: Could not allocate memory for raster alignment test"));
646 rterror(
_(
"diff_rastinfo: Could not run raster alignment test"));
651 rtwarn(
_(
"Raster with different alignment found in the set of rasters being converted to PostGIS raster"));
658 for (i = 0; i < 2; i++) {
660 rtwarn(
_(
"Different tile sizes found in the set of rasters being converted to PostGIS raster"));
674 config->
table = NULL;
683 config->
nband = NULL;
685 memset(config->
tile_size, 0,
sizeof(
int) * 2);
718 if (config->
schema != NULL)
720 if (config->
table != NULL)
755 for (i = 0; i <
buffer->length; i++) {
756 if (
buffer->line[i] != NULL)
772 for (i = 0; i <
buffer->length; i++) {
773 printf(
"%s\n",
buffer->line[i]);
779 dump_stringbuffer(
buffer);
780 rtdealloc_stringbuffer(
buffer, 0);
789 if (
buffer->line == NULL) {
790 rterror(
_(
"append_stringbuffer: Could not allocate memory for appending string to buffer"));
802 flush_stringbuffer(
buffer);
808 copy_from(
const char *schema,
const char *table,
const char *column,
809 const char *filename,
const char *file_column_name,
815 assert(table != NULL);
816 assert(column != NULL);
818 len = strlen(
"COPY () FROM stdin;") + 1;
820 len += strlen(schema);
821 len += strlen(table);
822 len += strlen(column);
823 if (filename != NULL)
824 len += strlen(
",") + strlen(file_column_name);
828 rterror(
_(
"copy_from: Could not allocate memory for COPY statement"));
831 sprintf(
sql,
"COPY %s%s (%s%s%s) FROM stdin;",
832 (schema != NULL ? schema :
""),
835 (filename != NULL ?
"," :
""),
836 (filename != NULL ? file_column_name :
"")
849 append_sql_to_buffer(
buffer, strdup(
"\\."));
856 const char *schema,
const char *table,
const char *column,
857 const char *filename,
const char *file_column_name,
858 int copy_statements,
int out_srid,
866 assert(table != NULL);
867 assert(column != NULL);
870 if (copy_statements) {
873 schema, table, column,
874 (file_column_name ? filename : NULL), file_column_name,
877 rterror(
_(
"insert_records: Could not add COPY statement to string buffer"));
883 if (filename != NULL)
888 len = strlen(tileset->
line[
x]) + 1;
890 if (filename != NULL)
891 len += strlen(fn) + 1;
895 rterror(
_(
"insert_records: Could not allocate memory for COPY statement"));
898 sprintf(
sql,
"%s%s%s",
900 (filename != NULL ?
"\t" :
""),
901 (filename != NULL ? fn :
"")
908 if (!copy_from_end(
buffer)) {
909 rterror(
_(
"process_rasters: Could not add COPY end statement to string buffer"));
916 len = strlen(
"INSERT INTO () VALUES (ST_Transform(''::raster,xxxxxxxxx));") + 1;
918 len += strlen(schema);
919 len += strlen(table);
920 len += strlen(column);
921 if (filename != NULL)
922 len += strlen(
",") + strlen(file_column_name);
925 if (filename != NULL)
932 sqllen += strlen(tileset->
line[
x]);
933 if (filename != NULL)
934 sqllen += strlen(
",''") + strlen(fn);
938 rterror(
_(
"insert_records: Could not allocate memory for INSERT statement"));
942 ptr += sprintf(
sql,
"INSERT INTO %s%s (%s%s%s) VALUES (",
943 (schema != NULL ? schema :
""),
946 (filename != NULL ?
"," :
""),
947 (filename != NULL ? file_column_name :
"")
950 ptr += sprintf(ptr,
"ST_Transform(");
952 ptr += sprintf(ptr,
"'%s'::raster",
956 ptr += sprintf(ptr,
", %d)", out_srid);
958 if (filename != NULL) {
959 ptr += sprintf(ptr,
",'%s'", fn);
961 ptr += sprintf(ptr,
");");
977 len = strlen(
"DROP TABLE IF EXISTS ;") + 1;
979 len += strlen(schema);
980 len += strlen(table);
984 rterror(
_(
"drop_table: Could not allocate memory for DROP TABLE statement"));
987 sprintf(
sql,
"DROP TABLE IF EXISTS %s%s;",
988 (schema != NULL ? schema :
""),
999 const char *schema,
const char *table,
const char *column,
1000 const int file_column,
const char *file_column_name,
1001 const char *tablespace,
const char *idx_tablespace,
1007 assert(table != NULL);
1008 assert(column != NULL);
1010 len = strlen(
"CREATE TABLE (\"rid\" serial PRIMARY KEY, raster);") + 1;
1012 len += strlen(schema);
1013 len += strlen(table);
1014 len += strlen(column);
1016 len += strlen(
", text") + strlen(file_column_name);
1017 if (tablespace != NULL)
1018 len += strlen(
" TABLESPACE ") + strlen(tablespace);
1019 if (idx_tablespace != NULL)
1020 len += strlen(
" USING INDEX TABLESPACE ") + strlen(idx_tablespace);
1024 rterror(
_(
"create_table: Could not allocate memory for CREATE TABLE statement"));
1027 sprintf(
sql,
"CREATE TABLE %s%s (\"rid\" serial PRIMARY KEY%s%s,%s raster%s%s%s)%s%s;",
1028 (schema != NULL ? schema :
""),
1030 (idx_tablespace != NULL ?
" USING INDEX TABLESPACE " :
""),
1031 (idx_tablespace != NULL ? idx_tablespace :
""),
1033 (file_column ?
"," :
""),
1034 (file_column ? file_column_name :
""),
1035 (file_column ?
" text" :
""),
1036 (tablespace != NULL ?
" TABLESPACE " :
""),
1037 (tablespace != NULL ? tablespace :
"")
1047 const char *schema,
const char *table,
const char *column,
1048 const char *tablespace,
1053 char *_table = NULL;
1054 char *_column = NULL;
1056 assert(table != NULL);
1057 assert(column != NULL);
1063 len = strlen(
"CREATE INDEX \"__gist\" ON USING gist (st_convexhull());") + 1;
1065 len += strlen(schema);
1066 len += strlen(_table);
1067 len += strlen(_column);
1068 len += strlen(table);
1069 len += strlen(column);
1070 if (tablespace != NULL)
1071 len += strlen(
" TABLESPACE ") + strlen(tablespace);
1075 rterror(
_(
"create_index: Could not allocate memory for CREATE INDEX statement"));
1080 sprintf(
sql,
"CREATE INDEX ON %s%s USING gist (st_convexhull(%s))%s%s;",
1081 (schema != NULL ? schema :
""),
1084 (tablespace != NULL ?
" TABLESPACE " :
""),
1085 (tablespace != NULL ? tablespace :
"")
1097 const char *schema,
const char *table,
1103 assert(table != NULL);
1105 len = strlen(
"ANALYZE ;") + 1;
1107 len += strlen(schema);
1108 len += strlen(table);
1112 rterror(
_(
"analyze_table: Could not allocate memory for ANALYZE TABLE statement"));
1115 sprintf(
sql,
"ANALYZE %s%s;",
1116 (schema != NULL ? schema :
""),
1127 const char *schema,
const char *table,
1133 assert(table != NULL);
1135 len = strlen(
"VACUUM ANALYZE ;") + 1;
1137 len += strlen(schema);
1138 len += strlen(table);
1142 rterror(
_(
"vacuum_table: Could not allocate memory for VACUUM statement"));
1145 sprintf(
sql,
"VACUUM ANALYZE %s%s;",
1146 (schema != NULL ? schema :
""),
1156 add_raster_constraints(
1157 const char *schema,
const char *table,
const char *column,
1158 int regular_blocking,
int max_extent,
1165 char *_schema = NULL;
1166 char *_table = NULL;
1167 char *_column = NULL;
1169 assert(table != NULL);
1170 assert(column != NULL);
1173 if (schema != NULL) {
1192 len = strlen(
"SELECT AddRasterConstraints('','','',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE);") + 1;
1193 if (_schema != NULL)
1194 len += strlen(_schema);
1195 len += strlen(_table);
1196 len += strlen(_column);
1200 rterror(
_(
"add_raster_constraints: Could not allocate memory for AddRasterConstraints statement"));
1203 sprintf(
sql,
"SELECT AddRasterConstraints('%s','%s','%s',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,%s,TRUE,TRUE,TRUE,TRUE,%s);",
1204 (_schema != NULL ? _schema :
""),
1207 (regular_blocking ?
"TRUE" :
"FALSE"),
1208 (max_extent ?
"TRUE" :
"FALSE")
1211 if (_schema != NULL)
1222 add_overview_constraints(
1223 const char *ovschema,
const char *ovtable,
const char *ovcolumn,
1224 const char *schema,
const char *table,
const char *column,
1233 char *_ovschema = NULL;
1234 char *_ovtable = NULL;
1235 char *_ovcolumn = NULL;
1237 char *_schema = NULL;
1238 char *_table = NULL;
1239 char *_column = NULL;
1241 assert(ovtable != NULL);
1242 assert(ovcolumn != NULL);
1243 assert(table != NULL);
1244 assert(column != NULL);
1248 if (ovschema != NULL) {
1252 _tmp =
strreplace(_ovschema,
"'",
"''", NULL);
1259 _ovtable =
strreplace(_tmp,
"'",
"''", NULL);
1264 _ovcolumn =
strreplace(_tmp,
"'",
"''", NULL);
1268 if (schema != NULL) {
1287 len = strlen(
"SELECT AddOverviewConstraints('','','','','','',);") + 5;
1288 if (_ovschema != NULL)
1289 len += strlen(_ovschema);
1290 len += strlen(_ovtable);
1291 len += strlen(_ovcolumn);
1292 if (_schema != NULL)
1293 len += strlen(_schema);
1294 len += strlen(_table);
1295 len += strlen(_column);
1299 rterror(
_(
"add_overview_constraints: Could not allocate memory for AddOverviewConstraints statement"));
1302 sprintf(
sql,
"SELECT AddOverviewConstraints('%s','%s','%s','%s','%s','%s',%d);",
1303 (_ovschema != NULL ? _ovschema :
""),
1306 (_schema != NULL ? _schema :
""),
1312 if (_ovschema != NULL)
1317 if (_schema != NULL)
1329 GDALDatasetH hdsSrc;
1331 VRTSourcedRasterBandH hbandOv;
1332 double gtOv[6] = {0.};
1337 const char *ovtable = NULL;
1340 VRTSourcedRasterBandH hbandDst;
1341 int tile_size[2] = {0};
1342 int _tile_size[2] = {0};
1343 int ntiles[2] = {1, 1};
1346 double gt[6] = {0.};
1350 uint32_t hexlen = 0;
1352 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1353 if (hdsSrc == NULL) {
1354 rterror(
_(
"build_overview: Could not open raster: %s"), config->
rt_file[idx]);
1359 memcpy(gtOv, info->
gt,
sizeof(
double) * 6);
1362 rterror(
_(
"build_overview: Invalid overview index: %d"), ovx);
1374 dimOv[0] = (int) (info->
dim[0] + (factor / 2)) / factor;
1375 dimOv[1] = (int) (info->
dim[1] + (factor / 2)) / factor;
1378 hdsOv = VRTCreate(dimOv[0], dimOv[1]);
1382 GDALSetProjection(hdsOv, info->
srs);
1388 GDALSetGeoTransform(hdsOv, gtOv);
1393 hbandOv = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsOv, j + 1);
1396 GDALSetRasterNoDataValue(hbandOv, info->
nodataval[j]);
1399 hbandOv, GDALGetRasterBand(hdsSrc, info->
nband[j]),
1401 info->
dim[0], info->
dim[1],
1404 "near", VRT_NODATA_UNSET
1409 VRTFlushCache(hdsOv);
1413 tile_size[0] = dimOv[0];
1417 tile_size[1] = dimOv[1];
1423 tile_size[0] != dimOv[0] &&
1424 tile_size[1] != dimOv[1]
1426 ntiles[0] = (dimOv[0] + tile_size[0] - 1) / tile_size[0];
1427 ntiles[1] = (dimOv[1] + tile_size[1] - 1) / tile_size[1];
1431 memcpy(
gt, gtOv,
sizeof(
double) * 6);
1435 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1438 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1439 _tile_size[1] = dimOv[1] - (ytile * tile_size[1]);
1441 _tile_size[1] = tile_size[1];
1443 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1450 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1451 _tile_size[0] = dimOv[0] - (xtile * tile_size[0]);
1453 _tile_size[0] = tile_size[0];
1456 GDALApplyGeoTransform(
1458 xtile * tile_size[0], ytile * tile_size[1],
1463 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1467 GDALSetProjection(hdsDst, info->
srs);
1468 GDALSetGeoTransform(hdsDst,
gt);
1473 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, j + 1);
1476 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[j]);
1479 hbandDst, GDALGetRasterBand(hdsOv, j + 1),
1480 xtile * tile_size[0], ytile * tile_size[1],
1481 _tile_size[0], _tile_size[1],
1483 _tile_size[0], _tile_size[1],
1484 "near", VRT_NODATA_UNSET
1489 VRTFlushCache(hdsDst);
1494 rterror(
_(
"build_overview: Could not convert VRT dataset to PostGIS raster"));
1507 rterror(
_(
"build_overview: Could not convert PostGIS raster to hex WKB"));
1513 append_stringbuffer(tileset, hex);
1518 if (tileset->
length > 10) {
1519 if (!insert_records(
1525 rterror(
_(
"build_overview: Could not convert raster tiles into INSERT or COPY statements"));
1530 rtdealloc_stringbuffer(tileset, 0);
1542 GDALDatasetH hdsSrc;
1543 GDALRasterBandH hbandSrc;
1546 int ntiles[2] = {1, 1};
1547 int _tile_size[2] = {0, 0};
1552 double gt[6] = {0.};
1553 const char* pszProjectionRef = NULL;
1557 uint32_t numbands = 0;
1560 uint32_t hexlen = 0;
1564 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1565 if (hdsSrc == NULL) {
1566 rterror(
_(
"convert_raster: Could not open raster: %s"), config->
rt_file[idx]);
1570 nband = GDALGetRasterCount(hdsSrc);
1572 rterror(
_(
"convert_raster: No bands found in raster: %s"), config->
rt_file[idx]);
1580 rterror(
_(
"convert_raster: Band %d not found in raster: %s"), config->
nband[i], config->
rt_file[idx]);
1587 pszProjectionRef = GDALGetProjectionRef(hdsSrc);
1588 if (pszProjectionRef != NULL && pszProjectionRef[0] !=
'\0') {
1589 info->
srs =
rtalloc(
sizeof(
char) * (strlen(pszProjectionRef) + 1));
1590 if (info->
srs == NULL) {
1591 rterror(
_(
"convert_raster: Could not allocate memory for storing SRS"));
1595 strcpy(info->
srs, pszProjectionRef);
1598 OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL);
1599 if (OSRSetFromUserInput(hSRS, pszProjectionRef) == OGRERR_NONE) {
1600 const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
1601 const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
1603 pszAuthorityName != NULL &&
1604 strcmp(pszAuthorityName,
"EPSG") == 0 &&
1605 pszAuthorityCode != NULL
1607 info->
srid = atoi(pszAuthorityCode);
1610 OSRDestroySpatialReference(hSRS);
1615 rterror(
_(
"convert_raster: could not determine source srid, cannot transform to target srid %d"), config->
out_srid);
1621 if (GDALGetGeoTransform(hdsSrc, info->
gt) != CE_None) {
1622 rtinfo(
_(
"Using default geotransform matrix (0, 1, 0, 0, 0, -1) for raster: %s"), config->
rt_file[idx]);
1630 memcpy(
gt, info->
gt,
sizeof(
double) * 6);
1637 if (info->
nband == NULL) {
1638 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1648 if (info->
nband == NULL) {
1649 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1654 info->
nband[i] = i + 1;
1660 rterror(
_(
"convert_raster: Could not allocate memory for storing GDAL data type"));
1666 rterror(
_(
"convert_raster: Could not allocate memory for storing pixel type"));
1672 rterror(
_(
"convert_raster: Could not allocate memory for storing hasnodata flag"));
1678 rterror(
_(
"convert_raster: Could not allocate memory for storing nodata value"));
1688 info->
dim[0] = GDALGetRasterXSize(hdsSrc);
1689 info->
dim[1] = GDALGetRasterYSize(hdsSrc);
1695 hbandSrc = GDALGetRasterBand(hdsSrc, info->
nband[i]);
1698 info->
gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
1702 rterror(
_(
"convert_raster: The pixel type of band %d is a complex data type. PostGIS raster does not support complex data types"), i + 1);
1706 GDALGetBlockSize(hbandSrc, &naturalx, &naturaly);
1730 calc_tile_size((naturalx > 1) ? (uint32_t)naturalx : info->
dim[0],
1731 (naturaly > 1) ? (uint32_t)naturaly : info->
dim[1],
1760 rtwarn(
_(
"The size of each output tile may exceed 1 GB. Use -t to specify a reasonable tile size"));
1763 if (config->
outdb) {
1767 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1769 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1770 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1774 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1778 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1779 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1784 GDALApplyGeoTransform(
1793 rterror(
_(
"convert_raster: Could not create raster"));
1804 _tile_size[0], _tile_size[1],
1811 rterror(
_(
"convert_raster: Could not create offline band"));
1818 rterror(
_(
"convert_raster: Could not add offlineband to raster"));
1830 if (!tile_is_nodata)
1834 if (!hex && !tile_is_nodata)
1836 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1841 if (!tile_is_nodata)
1842 append_stringbuffer(tileset, hex);
1845 if (tileset->
length > 10) {
1846 if (!insert_records(
1852 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1856 rtdealloc_stringbuffer(tileset, 0);
1864 VRTSourcedRasterBandH hbandDst;
1867 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1870 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1871 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1875 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1883 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1884 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1889 GDALApplyGeoTransform(
1902 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1906 GDALSetProjection(hdsDst, info->
srs);
1907 GDALSetGeoTransform(hdsDst,
gt);
1912 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
1915 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[i]);
1918 hbandDst, GDALGetRasterBand(hdsSrc, info->
nband[i]),
1920 _tile_size[0], _tile_size[1],
1922 _tile_size[0], _tile_size[1],
1923 "near", VRT_NODATA_UNSET
1928 VRTFlushCache(hdsDst);
1933 rterror(
_(
"convert_raster: Could not convert VRT dataset to PostGIS raster"));
1943 for (i = 0; i < numbands; i++) {
1950 if (!tile_is_nodata)
1954 if (!hex && !tile_is_nodata)
1956 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1962 if (!tile_is_nodata)
1963 append_stringbuffer(tileset, hex);
1968 if (tileset->
length > 10) {
1969 if (!insert_records(
1975 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1980 rtdealloc_stringbuffer(tileset, 0);
1995 assert(config != NULL);
1996 assert(config->
table != NULL);
2000 if (!append_sql_to_buffer(
buffer, strdup(
"BEGIN;"))) {
2001 rterror(
_(
"process_rasters: Could not add BEGIN statement to string buffer"));
2007 if (config->
opt ==
'd') {
2009 rterror(
_(
"process_rasters: Could not add DROP TABLE statement to string buffer"));
2016 rterror(
_(
"process_rasters: Could not add an overview's DROP TABLE statement to string buffer"));
2024 if (config->
opt !=
'a') {
2031 rterror(
_(
"process_rasters: Could not add CREATE TABLE statement to string buffer"));
2043 rterror(
_(
"process_rasters: Could not add an overview's CREATE TABLE statement to string buffer"));
2051 if (config->
opt !=
'p') {
2053 init_rastinfo(&refinfo);
2062 init_rastinfo(&rastinfo);
2063 init_stringbuffer(&tileset);
2066 if (!convert_raster(i, config, &rastinfo, &tileset,
buffer)) {
2067 rterror(
_(
"process_rasters: Could not process raster: %s"), config->
rt_file[i]);
2068 rtdealloc_rastinfo(&rastinfo);
2069 rtdealloc_stringbuffer(&tileset, 0);
2074 if (tileset.
length && !insert_records(
2081 rterror(
_(
"process_rasters: Could not convert raster tiles into INSERT or COPY statements"));
2082 rtdealloc_rastinfo(&rastinfo);
2083 rtdealloc_stringbuffer(&tileset, 0);
2087 rtdealloc_stringbuffer(&tileset, 0);
2090 flush_stringbuffer(
buffer);
2098 if (!build_overview(i, config, &rastinfo, j, &tileset,
buffer)) {
2099 rterror(
_(
"process_rasters: Could not create overview of factor %d for raster %s"), config->
overview[j], config->
rt_file[i]);
2100 rtdealloc_rastinfo(&rastinfo);
2101 rtdealloc_stringbuffer(&tileset, 0);
2105 if (tileset.
length && !insert_records(
2111 rterror(
_(
"process_rasters: Could not convert overview tiles into INSERT or COPY statements"));
2112 rtdealloc_rastinfo(&rastinfo);
2113 rtdealloc_stringbuffer(&tileset, 0);
2117 rtdealloc_stringbuffer(&tileset, 0);
2120 flush_stringbuffer(
buffer);
2126 copy_rastinfo(&refinfo, &rastinfo);
2128 diff_rastinfo(&rastinfo, &refinfo);
2132 rtdealloc_rastinfo(&rastinfo);
2135 rtdealloc_rastinfo(&refinfo);
2146 rterror(
_(
"process_rasters: Could not add CREATE INDEX statement to string buffer"));
2151 if (config->
opt !=
'p') {
2156 rterror(
_(
"process_rasters: Could not add ANALYZE statement to string buffer"));
2169 rterror(
_(
"process_rasters: Could not add an overview's CREATE INDEX statement to string buffer"));
2174 if (config->
opt !=
'p') {
2179 rterror(
_(
"process_rasters: Could not add an overview's ANALYZE statement to string buffer"));
2189 if (!add_raster_constraints(
2194 rterror(
_(
"process:rasters: Could not add AddRasterConstraints statement to string buffer"));
2200 if (!add_raster_constraints(
2205 rterror(
_(
"process_rasters: Could not add an overview's AddRasterConstraints statement to string buffer"));
2215 if (!add_overview_constraints(
2221 rterror(
_(
"process_rasters: Could not add an overview's AddOverviewConstraints statement to string buffer"));
2228 if (!append_sql_to_buffer(
buffer, strdup(
"END;"))) {
2229 rterror(
_(
"process_rasters: Could not add END statement to string buffer"));
2240 rterror(
_(
"process_rasters: Could not add VACUUM statement to string buffer"));
2250 rterror(
_(
"process_rasters: Could not add an overview's VACUUM statement to string buffer"));
2262 main(
int argc,
char **argv) {
2267 char **elements = NULL;
2269 GDALDriverH drv = NULL;
2276 setlocale (LC_ALL,
"");
2277 bindtextdomain (PACKAGE, LOCALEDIR);
2278 textdomain (PACKAGE);
2289 if (config == NULL) {
2290 rterror(
_(
"Could not allocate memory for loader configuration"));
2293 init_config(config);
2299 for (argit = 1; argit < argc; argit++) {
2303 if (
CSEQUAL(argv[argit],
"-s") && argit < argc - 1) {
2304 optarg = argv[++argit];
2305 ptr = strchr(optarg,
':');
2308 sscanf(optarg,
"%d", &config->
srid);
2309 sscanf(ptr,
"%d", &config->
out_srid);
2311 config->
srid = atoi(optarg);
2315 else if (
CSEQUAL(argv[argit],
"-b") && argit < argc - 1) {
2316 elements =
strsplit(argv[++argit],
",", &n);
2318 rterror(
_(
"Could not process -b"));
2319 rtdealloc_config(config);
2324 for (j = 0; j < n; j++) {
2325 char *t =
trim(elements[j]);
2326 char **minmax = NULL;
2336 if (!
array_range(atoi(minmax[0]), atoi(minmax[1]), 1, &range, &p)) {
2337 rterror(
_(
"Could not allocate memory for storing band indices"));
2338 for (l = 0; l < o; l++)
2341 for (j = 0; j < n; j++)
2345 rtdealloc_config(config);
2352 if (range == NULL) {
2353 rterror(
_(
"Could not allocate memory for storing band indices"));
2354 for (l = 0; l < o; l++)
2357 for (j = 0; j < n; j++)
2361 rtdealloc_config(config);
2370 if (config->
nband == NULL) {
2371 rterror(
_(
"Could not allocate memory for storing band indices"));
2373 for (l = 0; l < o; l++)
2376 for (j = 0; j < n; j++)
2380 rtdealloc_config(config);
2384 for (l = 0; l < p; l++, m++)
2385 config->
nband[m] = range[l];
2389 for (l = 0; l < o; l++)
2401 if (config->
nband[j] < 1) {
2402 rterror(
_(
"Band index %d must be greater than 0"), config->
nband[j]);
2403 rtdealloc_config(config);
2409 else if (
CSEQUAL(argv[argit],
"-t") && argit < argc - 1) {
2410 if (
CSEQUAL(argv[++argit],
"auto")) {
2415 elements =
strsplit(argv[argit],
"x", &n);
2417 rterror(
_(
"Could not process -t"));
2418 rtdealloc_config(config);
2422 for (j = 0; j < n; j++) {
2423 char *t =
trim(elements[j]);
2432 for (j = 0; j < 2; j++) {
2434 rterror(
_(
"Tile size must be greater than 0x0"));
2435 rtdealloc_config(config);
2442 else if (
CSEQUAL(argv[argit],
"-P")) {
2446 else if (
CSEQUAL(argv[argit],
"-R")) {
2450 else if (
CSEQUAL(argv[argit],
"-d")) {
2454 else if (
CSEQUAL(argv[argit],
"-a")) {
2458 else if (
CSEQUAL(argv[argit],
"-c")) {
2462 else if (
CSEQUAL(argv[argit],
"-p")) {
2466 else if (
CSEQUAL(argv[argit],
"-f") && argit < argc - 1) {
2467 const size_t len = (strlen(argv[++argit]) + 1);
2470 rterror(
_(
"Could not allocate memory for storing raster column name"));
2471 rtdealloc_config(config);
2477 else if (
CSEQUAL(argv[argit],
"-F")) {
2481 else if (
CSEQUAL(argv[argit],
"-n") && argit < argc - 1) {
2482 const size_t len = (strlen(argv[++argit]) + 1);
2485 rterror(
_(
"Could not allocate memory for storing filename column name"));
2486 rtdealloc_config(config);
2493 else if (
CSEQUAL(argv[argit],
"-l") && argit < argc - 1) {
2494 elements =
strsplit(argv[++argit],
",", &n);
2496 rterror(
_(
"Could not process -l"));
2497 rtdealloc_config(config);
2504 rterror(
_(
"Could not allocate memory for storing overview factors"));
2505 rtdealloc_config(config);
2508 for (j = 0; j < n; j++) {
2509 char *t =
trim(elements[j]);
2521 rtdealloc_config(config);
2527 else if (
CSEQUAL(argv[argit],
"-q")) {
2531 else if (
CSEQUAL(argv[argit],
"-I")) {
2535 else if (
CSEQUAL(argv[argit],
"-M")) {
2539 else if (
CSEQUAL(argv[argit],
"-C")) {
2543 else if (
CSEQUAL(argv[argit],
"-x")) {
2547 else if (
CSEQUAL(argv[argit],
"-r")) {
2551 else if (
CSEQUAL(argv[argit],
"-T") && argit < argc - 1) {
2552 const size_t len = (strlen(argv[++argit]) + 1);
2555 rterror(
_(
"Could not allocate memory for storing tablespace of new table"));
2556 rtdealloc_config(config);
2559 strncpy(config->
tablespace, argv[argit], len);
2562 else if (
CSEQUAL(argv[argit],
"-X") && argit < argc - 1) {
2563 const size_t len = (strlen(argv[++argit]) + 1);
2566 rterror(
_(
"Could not allocate memory for storing tablespace of new indices"));
2567 rtdealloc_config(config);
2573 else if (
CSEQUAL(argv[argit],
"-N") && argit < argc - 1) {
2575 config->
nodataval = atof(argv[++argit]);
2578 else if (
CSEQUAL(argv[argit],
"-k")) {
2582 else if (
CSEQUAL(argv[argit],
"-E") && argit < argc - 1) {
2583 config->
endian = atoi(argv[++argit]);
2587 else if (
CSEQUAL(argv[argit],
"-V") && argit < argc - 1) {
2588 config->
version = atoi(argv[++argit]);
2592 else if (
CSEQUAL(argv[argit],
"-e")) {
2596 else if (
CSEQUAL(argv[argit],
"-Y")) {
2600 else if (
CSEQUAL(argv[argit],
"-G")) {
2601 uint32_t drv_count = 0;
2603 if (drv_set == NULL || !drv_count) {
2604 rterror(
_(
"Could not get list of available GDAL raster formats"));
2607 printf(
_(
"Supported GDAL raster formats:\n"));
2608 for (j = 0; j < drv_count; j++) {
2609 printf(
_(
" %s\n"), drv_set[j].long_name);
2618 rtdealloc_config(config);
2622 else if (
CSEQUAL(argv[argit],
"-?")) {
2624 rtdealloc_config(config);
2631 if (config->
rt_file == NULL) {
2632 rterror(
_(
"Could not allocate memory for storing raster files"));
2633 rtdealloc_config(config);
2637 len = strlen(argv[argit]) + 1;
2640 rterror(
_(
"Could not allocate memory for storing raster filename"));
2641 rtdealloc_config(config);
2650 rterror(
_(
"Invalid argument combination - cannot use -Y with -s FROM_SRID:TO_SRID"));
2661 rtdealloc_config(config);
2678 if (config->
schema == NULL) {
2679 rterror(
_(
"Could not allocate memory for storing schema name"));
2680 rtdealloc_config(config);
2687 if (config->
table == NULL) {
2688 rterror(
_(
"Could not allocate memory for storing table name"));
2689 rtdealloc_config(config);
2699 if (config->
table == NULL) {
2700 rterror(
_(
"Could not allocate memory for storing table name"));
2701 rtdealloc_config(config);
2709 if (config->
rt_file == NULL) {
2710 rterror(
_(
"Could not reallocate the memory holding raster names"));
2711 rtdealloc_config(config);
2723 drv = GDALIdentifyDriver(config->
rt_file[i], NULL);
2727 rtdealloc_config(config);
2735 rterror(
_(
"Could not allocate memory for cleaned raster filenames"));
2736 rtdealloc_config(config);
2745 rterror(
_(
"Could not allocate memory for cleaned raster filename"));
2746 rtdealloc_config(config);
2749 strcpy(file, config->
rt_file[i]);
2751 for (ptr = file + strlen(file); ptr > file; ptr--) {
2752 if (*ptr ==
'/' || *ptr ==
'\\') {
2760 rterror(
_(
"Could not allocate memory for cleaned raster filename"));
2761 rtdealloc_config(config);
2773 if (config->
table == NULL) {
2779 rterror(
_(
"Could not allocate memory for proxy table name"));
2780 rtdealloc_config(config);
2785 for (ptr = file + strlen(file); ptr > file; ptr--) {
2792 config->
table =
rtalloc(
sizeof(
char) * (strlen(file) + 1));
2793 if (config->
table == NULL) {
2794 rterror(
_(
"Could not allocate memory for proxy table name"));
2795 rtdealloc_config(config);
2798 strcpy(config->
table, file);
2806 rterror(
_(
"Could not allocate memory for default raster column name"));
2807 rtdealloc_config(config);
2817 rterror(
_(
"Could not allocate memory for default filename column name"));
2818 rtdealloc_config(config);
2830 if (config->
schema != NULL)
2832 if (config->
table != NULL)
2852 rterror(
_(
"Could not allocate memory for overview table names"));
2853 rtdealloc_config(config);
2858 sprintf(factor,
"%d", config->
overview[i]);
2862 rterror(
_(
"Could not allocate memory for overview table name"));
2863 rtdealloc_config(config);
2875 rtwarn(
_(
"The schema name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2881 rtwarn(
_(
"The table name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2887 rtwarn(
_(
"The column name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2893 rtwarn(
_(
"The column name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2899 rtwarn(
_(
"The tablespace name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2905 rtwarn(
_(
"The index tablespace name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2913 rtwarn(
_(
"The overview table name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2925 if (config->
schema != NULL) {
2928 rterror(
_(
"Could not allocate memory for quoting schema name"));
2929 rtdealloc_config(config);
2933 sprintf(tmp,
"\"%s\".", config->
schema);
2937 if (config->
table != NULL) {
2938 tmp =
rtalloc(
sizeof(
char) * (strlen(config->
table) + 3));
2940 rterror(
_(
"Could not allocate memory for quoting table name"));
2941 rtdealloc_config(config);
2945 sprintf(tmp,
"\"%s\"", config->
table);
2947 config->
table = tmp;
2952 rterror(
_(
"Could not allocate memory for quoting raster column name"));
2953 rtdealloc_config(config);
2964 rterror(
_(
"Could not allocate memory for quoting raster column name"));
2965 rtdealloc_config(config);
2976 rterror(
_(
"Could not allocate memory for quoting tablespace name"));
2977 rtdealloc_config(config);
2988 rterror(
_(
"Could not allocate memory for quoting index tablespace name"));
2989 rtdealloc_config(config);
3001 rterror(
_(
"Could not allocate memory for quoting overview table name"));
3002 rtdealloc_config(config);
3019 rterror(
_(
"Could not allocate memory for output string buffer"));
3020 rtdealloc_config(config);
3023 init_stringbuffer(
buffer);
3026 if (!process_rasters(config,
buffer)) {
3027 rterror(
_(
"Unable to process rasters"));
3028 rtdealloc_stringbuffer(
buffer, 1);
3029 rtdealloc_config(config);
3033 flush_stringbuffer(
buffer);
3035 rtdealloc_stringbuffer(
buffer, 1);
3036 rtdealloc_config(config);
int main(int argc, char *argv[])
#define SRID_UNKNOWN
Unknown SRID value.
void * default_rt_allocator(size_t size)
The default memory/logging handlers installed by lwgeom_install_default_allocators()
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
void rtinfo(const char *fmt,...)
rt_gdaldriver rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc)
Returns a set of available GDAL drivers.
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
char * rt_raster_to_hexwkb(rt_raster raster, int outasin, uint32_t *hexwkbsize)
Return this raster in HEXWKB form (null-terminated hex)
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
void default_rt_deallocator(void *mem)
void rtwarn(const char *fmt,...)
int rt_band_check_is_nodata(rt_band band)
Returns TRUE if the band is only nodata values.
void rt_band_destroy(rt_band band)
Destroy a raster band.
void * rtrealloc(void *mem, size_t size)
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_band rt_band_new_offline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t bandNum, const char *path)
Create an out-db rt_band.
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
void rtdealloc(void *mem)
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
int rt_band_get_ownsdata_flag(rt_band band)
Return 0 (FALSE) or non-zero (TRUE) indicating if rt_band is responsible for managing the memory for ...
int rt_band_is_offline(rt_band band)
Return non-zero if the given band data is on the filesystem.
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
void * default_rt_reallocator(void *mem, size_t size)
void rt_set_handlers(rt_allocator allocator, rt_reallocator reallocator, rt_deallocator deallocator, rt_message_handler error_handler, rt_message_handler info_handler, rt_message_handler warning_handler)
This function is called when the PostgreSQL backend is taking care of the memory and we want to use p...
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Datum buffer(PG_FUNCTION_ARGS)
static void loader_rt_error_handler(const char *fmt, va_list ap)
static char * strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
static char ** strsplit(const char *str, const char *delimiter, uint32_t *n)
static int array_range(int min, int max, int step, int **range, uint32_t *len)
static char * chartrim(const char *input, char *remove)
static char * trim(const char *input)
static void loader_rt_info_handler(const char *fmt, va_list ap)
static void rt_init_allocators(void)
static char * strtolower(char *str)
static void raster_destroy(rt_raster raster)
static void loader_rt_warning_handler(const char *fmt, va_list ap)
#define POSTGIS_LIB_VERSION
GDALDataType * gdalbandtype