30 #include "ogr_srs_api.h" 35 static const char *label =
"ERROR: ";
36 char newfmt[1024] = {0};
37 snprintf(newfmt, 1024,
"%s%s\n", label, fmt);
39 vfprintf(stderr, newfmt, ap);
45 static const char *label =
"WARNING: ";
46 char newfmt[1024] = {0};
47 snprintf(newfmt, 1024,
"%s%s\n", label, fmt);
49 vfprintf(stderr, newfmt, ap);
55 static const char *label =
"INFO: ";
56 char newfmt[1024] = {0};
57 snprintf(newfmt, 1024,
"%s%s\n", label, fmt);
59 vfprintf(stderr, newfmt, ap);
79 for (i = 0; i < nbands; i++) {
81 if (band == NULL)
continue;
93 array_range(
int min,
int max,
int step,
int **range,
int *len) {
98 *len = (abs(max - min) + 1 + (step / 2)) / step;
99 *range =
rtalloc(
sizeof(
int) * *len);
102 for (i = min, j = 0; i <= max; i += step, j++)
105 else if (max < min) {
106 if (step > 0) step *= -1;
107 for (i = min, j = 0; i >= max; i += step, j++)
110 else if (min == max) {
143 const char *oldstr,
const char *newstr,
146 const char *tmp = str;
150 int oldlen = strlen(oldstr);
151 int newlen = strlen(newstr);
152 int limit = (count != NULL && *count > 0) ? *count : -1;
155 while ((tmp = strstr(tmp, oldstr)) != NULL && found != limit)
156 found++, tmp += oldlen;
158 length = strlen(str) + found * (newlen - oldlen);
159 if ((result = (
char *)
rtalloc(length + 1)) == NULL) {
160 rterror(
_(
"strreplace: Not enough memory"));
169 while ((limit-- > 0) && (tmp = strstr(tmp, oldstr)) != NULL) {
170 length = (tmp - str);
171 strncpy(result + reslen, str, length);
172 strcpy(result + (reslen += length), newstr);
178 strcpy(result + reslen, str);
181 if (count != NULL) *count = found;
189 for (j = strlen(str) - 1; j >= 0; j--)
190 str[j] = tolower(str[j]);
197 strsplit(
const char *str,
const char *delimiter,
int *n) {
207 tmp =
rtalloc(
sizeof(
char) * (strlen(str) + 1));
209 rterror(
_(
"strsplit: Not enough memory"));
214 if (!strlen(tmp) || !delimiter || !strlen(delimiter)) {
216 rtn = (
char **)
rtalloc(*n *
sizeof(
char *));
218 rterror(
_(
"strsplit: Not enough memory"));
221 rtn[0] = (
char *)
rtalloc(
sizeof(
char) * (strlen(tmp) + 1));
222 if (NULL == rtn[0]) {
223 rterror(
_(
"strsplit: Not enough memory"));
231 token = strtok(tmp, delimiter);
232 while (token != NULL) {
234 rtn = (
char **)
rtalloc(
sizeof(
char *));
237 rtn = (
char **)
rtrealloc(rtn, (*n + 1) *
sizeof(
char *));
240 rterror(
_(
"strsplit: Not enough memory"));
245 rtn[*n] = (
char *)
rtalloc(
sizeof(
char) * (strlen(token) + 1));
246 if (NULL == rtn[*n]) {
247 rterror(
_(
"strsplit: Not enough memory"));
251 strcpy(rtn[*n], token);
254 token = strtok(NULL, delimiter);
270 return (
char *) input;
273 while (isspace(*input))
277 ptr = ((
char *) input) + strlen(input);
278 while (isspace(*--ptr))
281 rtn =
rtalloc(
sizeof(
char) * (strlen(input) - offset + 1));
283 rterror(
_(
"trim: Not enough memory"));
286 strncpy(rtn, input, strlen(input) - offset);
287 rtn[strlen(input) - offset] =
'\0';
301 return (
char *) input;
304 while (strchr(
remove, *input) != NULL)
308 ptr = ((
char *) input) + strlen(input);
309 while (strchr(
remove, *--ptr) != NULL)
312 rtn =
rtalloc(
sizeof(
char) * (strlen(input) - offset + 1));
314 rterror(
_(
"chartrim: Not enough memory"));
317 strncpy(rtn, input, strlen(input) - offset);
318 rtn[strlen(input) - offset] =
'\0';
325 printf(
_(
"RELEASE: %s GDAL_VERSION=%d (r%d)\n"),
POSTGIS_LIB_VERSION, POSTGIS_GDAL_VERSION, POSTGIS_SVN_REVISION);
327 "USAGE: raster2pgsql [<options>] <raster>[ <raster>[ ...]] [[<schema>.]<table>]\n" 328 " Multiple rasters can also be specified using wildcards (*,?).\n" 341 " -s <srid> Set the SRID field. Defaults to %d. If SRID not\n" 342 " provided or is %d, raster's metadata will be checked to\n" 343 " determine an appropriate SRID.\n" 346 " -b <band> Index (1-based) of band to extract from raster. For more\n" 347 " than one band index, separate with comma (,). Ranges can be\n" 348 " defined by separating with dash (-). If unspecified, all bands\n" 349 " of raster will be extracted.\n" 352 " -t <tile size> Cut raster into tiles to be inserted one per\n" 353 " table row. <tile size> is expressed as WIDTHxHEIGHT.\n" 354 " <tile size> can also be \"auto\" to allow the loader to compute\n" 355 " an appropriate tile size using the first raster and applied to\n" 359 " -P Pad right-most and bottom-most tiles to guarantee that all tiles\n" 360 " have the same width and height.\n" 363 " -R Register the raster as an out-of-db (filesystem) raster. Provided\n" 364 " raster should have absolute path to the file\n" 367 " (-d|a|c|p) These are mutually exclusive options:\n" 368 " -d Drops the table, then recreates it and populates\n" 369 " it with current raster data.\n" 370 " -a Appends raster into current table, must be\n" 371 " exactly the same table schema.\n" 372 " -c Creates a new table and populates it, this is the\n" 373 " default if you do not specify any options.\n" 374 " -p Prepare mode, only creates the table.\n" 377 " -f <column> Specify the name of the raster column\n" 380 " -F Add a column with the filename of the raster.\n" 383 " -n <column> Specify the name of the filename column. Implies -F.\n" 386 " -l <overview factor> Create overview of the raster. For more than\n" 387 " one factor, separate with comma(,). Overview table name follows\n" 388 " the pattern o_<overview factor>_<table>. Created overview is\n" 389 " stored in the database and is not affected by -R.\n" 392 " -q Wrap PostgreSQL identifiers in quotes.\n" 395 " -I Create a GIST spatial index on the raster column. The ANALYZE\n" 396 " command will automatically be issued for the created index.\n" 399 " -M Run VACUUM ANALYZE on the table of the raster column. Most\n" 400 " useful when appending raster to existing table with -a.\n" 403 " -C Set the standard set of constraints on the raster\n" 404 " column after the rasters are loaded. Some constraints may fail\n" 405 " if one or more rasters violate the constraint.\n" 406 " -x Disable setting the max extent constraint. Only applied if\n" 407 " -C flag is also used.\n" 408 " -r Set the constraints (spatially unique and coverage tile) for\n" 409 " regular blocking. Only applied if -C flag is also used.\n" 412 " -T <tablespace> Specify the tablespace for the new table.\n" 413 " Note that indices (including the primary key) will still use\n" 414 " the default tablespace unless the -X flag is also used.\n" 417 " -X <tablespace> Specify the tablespace for the table's new index.\n" 418 " This applies to the primary key and the spatial index if\n" 419 " the -I flag is used.\n" 422 " -N <nodata> NODATA value to use on bands without a NODATA value.\n" 425 " -k Skip NODATA value checks for each raster band.\n" 428 " -E <endian> Control endianness of generated binary output of\n" 429 " raster. Use 0 for XDR and 1 for NDR (default). Only NDR\n" 430 " is supported at this time.\n" 433 " -V <version> Specify version of output WKB format. Default\n" 434 " is 0. Only 0 is supported at this time.\n" 437 " -e Execute each statement individually, do not use a transaction.\n" 440 " -Y Use COPY statements instead of INSERT statements.\n" 443 " -G Print the supported GDAL raster formats.\n" 446 " -? Display this help screen.\n" 452 int *tileX,
int *tileY
466 for (j = 0; j < 2; j++) {
471 if (j < 1 && dimX <= max) {
475 else if (dimY <= max) {
480 for (i = max; i >= min; i--) {
483 r = (double) dimX / (
double) i;
488 r = (double) dimY / (
double) i;
521 memset(info->
gt, 0,
sizeof(
double) * 6);
522 memset(info->
tile_size, 0,
sizeof(
int) * 2);
527 if (info->
srs != NULL)
543 if (src->
srs != NULL) {
545 if (dst->
srs == NULL) {
546 rterror(
_(
"copy_rastinfo: Not enough memory"));
549 strcpy(dst->
srs, src->
srs);
555 if (dst->
nband == NULL) {
556 rterror(
_(
"copy_rastinfo: Not enough memory"));
564 rterror(
_(
"copy_rastinfo: Not enough memory"));
572 rterror(
_(
"copy_rastinfo: Not enough memory"));
580 rterror(
_(
"copy_rastinfo: Not enough memory"));
588 rterror(
_(
"copy_rastinfo: Not enough memory"));
593 memcpy(dst->
gt, src->
gt,
sizeof(
double) * 6);
609 rtwarn(
_(
"Different number of bands found in the set of rasters being converted to PostGIS raster"));
617 rtwarn(
_(
"Different pixel types found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
627 rtwarn(
_(
"Different hasnodata flags found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
638 rtwarn(
_(
"Different NODATA values found for band %d in the set of rasters being converted to PostGIS raster"), ref->
nband[i]);
655 rterror(
_(
"diff_rastinfo: Could not allocate memory for raster alignment test"));
668 rterror(
_(
"diff_rastinfo: Could not run raster alignment test"));
673 rtwarn(
_(
"Raster with different alignment found in the set of rasters being converted to PostGIS raster"));
680 for (i = 0; i < 2; i++) {
682 rtwarn(
_(
"Different tile sizes found in the set of rasters being converted to PostGIS raster"));
696 config->
table = NULL;
705 config->
nband = NULL;
707 memset(config->
tile_size, 0,
sizeof(
int) * 2);
740 if (config->
schema != NULL)
742 if (config->
table != NULL)
777 for (i = 0; i < buffer->
length; i++) {
778 if (buffer->
line[i] != NULL)
794 for (i = 0; i < buffer->
length; i++) {
795 printf(
"%s\n", buffer->
line[i]);
811 if (buffer->
line == NULL) {
812 rterror(
_(
"append_stringbuffer: Could not allocate memory for appending string to buffer"));
816 buffer->
line[buffer->
length - 1] = (
char *) str;
830 copy_from(
const char *schema,
const char *table,
const char *column,
831 const char *filename,
const char *file_column_name,
837 assert(table != NULL);
838 assert(column != NULL);
840 len = strlen(
"COPY () FROM stdin;") + 1;
842 len += strlen(schema);
843 len += strlen(table);
844 len += strlen(column);
845 if (filename != NULL)
846 len += strlen(
",") + strlen(file_column_name);
848 sql =
rtalloc(
sizeof(
char) * len);
850 rterror(
_(
"copy_from: Could not allocate memory for COPY statement"));
853 sprintf(sql,
"COPY %s%s (%s%s%s) FROM stdin;",
854 (schema != NULL ? schema :
""),
857 (filename != NULL ?
"," :
""),
858 (filename != NULL ? file_column_name :
"")
878 const char *schema,
const char *table,
const char *column,
879 const char *filename,
const char *file_column_name,
880 int copy_statements,
int out_srid,
888 assert(table != NULL);
889 assert(column != NULL);
892 if (copy_statements) {
895 schema, table, column,
896 (file_column_name ? filename : NULL), file_column_name,
899 rterror(
_(
"insert_records: Could not add COPY statement to string buffer"));
905 if (filename != NULL)
909 for (x = 0; x < tileset->
length; x++) {
910 len = strlen(tileset->
line[x]) + 1;
912 if (filename != NULL)
913 len += strlen(fn) + 1;
915 sql =
rtalloc(
sizeof(
char) * len);
917 rterror(
_(
"insert_records: Could not allocate memory for COPY statement"));
920 sprintf(sql,
"%s%s%s",
922 (filename != NULL ?
"\t" :
""),
923 (filename != NULL ? fn :
"")
931 rterror(
_(
"process_rasters: Could not add COPY end statement to string buffer"));
938 len = strlen(
"INSERT INTO () VALUES (ST_Transform(''::raster,xxxxxxxxx));") + 1;
940 len += strlen(schema);
941 len += strlen(table);
942 len += strlen(column);
943 if (filename != NULL)
944 len += strlen(
",") + strlen(file_column_name);
947 if (filename != NULL)
950 for (x = 0; x < tileset->
length; x++) {
954 sqllen += strlen(tileset->
line[x]);
955 if (filename != NULL)
956 sqllen += strlen(
",''") + strlen(fn);
958 sql =
rtalloc(
sizeof(
char) * sqllen);
960 rterror(
_(
"insert_records: Could not allocate memory for INSERT statement"));
964 ptr += sprintf(sql,
"INSERT INTO %s%s (%s%s%s) VALUES (",
965 (schema != NULL ? schema :
""),
968 (filename != NULL ?
"," :
""),
969 (filename != NULL ? file_column_name :
"")
972 ptr += sprintf(ptr,
"ST_Transform(");
974 ptr += sprintf(ptr,
"'%s'::raster",
978 ptr += sprintf(ptr,
", %d)", out_srid);
980 if (filename != NULL) {
981 ptr += sprintf(ptr,
",'%s'", fn);
983 ptr += sprintf(ptr,
");");
999 len = strlen(
"DROP TABLE IF EXISTS ;") + 1;
1001 len += strlen(schema);
1002 len += strlen(table);
1004 sql =
rtalloc(
sizeof(
char) * len);
1006 rterror(
_(
"drop_table: Could not allocate memory for DROP TABLE statement"));
1009 sprintf(sql,
"DROP TABLE IF EXISTS %s%s;",
1010 (schema != NULL ? schema :
""),
1021 const char *schema,
const char *table,
const char *column,
1022 const int file_column,
const char *file_column_name,
1023 const char *tablespace,
const char *idx_tablespace,
1029 assert(table != NULL);
1030 assert(column != NULL);
1032 len = strlen(
"CREATE TABLE (\"rid\" serial PRIMARY KEY, raster);") + 1;
1034 len += strlen(schema);
1035 len += strlen(table);
1036 len += strlen(column);
1038 len += strlen(
", text") + strlen(file_column_name);
1039 if (tablespace != NULL)
1040 len += strlen(
" TABLESPACE ") + strlen(tablespace);
1041 if (idx_tablespace != NULL)
1042 len += strlen(
" USING INDEX TABLESPACE ") + strlen(idx_tablespace);
1044 sql =
rtalloc(
sizeof(
char) * len);
1046 rterror(
_(
"create_table: Could not allocate memory for CREATE TABLE statement"));
1049 sprintf(sql,
"CREATE TABLE %s%s (\"rid\" serial PRIMARY KEY%s%s,%s raster%s%s%s)%s%s;",
1050 (schema != NULL ? schema :
""),
1052 (idx_tablespace != NULL ?
" USING INDEX TABLESPACE " :
""),
1053 (idx_tablespace != NULL ? idx_tablespace :
""),
1055 (file_column ?
"," :
""),
1056 (file_column ? file_column_name :
""),
1057 (file_column ?
" text" :
""),
1058 (tablespace != NULL ?
" TABLESPACE " :
""),
1059 (tablespace != NULL ? tablespace :
"")
1069 const char *schema,
const char *table,
const char *column,
1070 const char *tablespace,
1075 char *_table = NULL;
1076 char *_column = NULL;
1078 assert(table != NULL);
1079 assert(column != NULL);
1085 len = strlen(
"CREATE INDEX \"__gist\" ON USING gist (st_convexhull());") + 1;
1087 len += strlen(schema);
1088 len += strlen(_table);
1089 len += strlen(_column);
1090 len += strlen(table);
1091 len += strlen(column);
1092 if (tablespace != NULL)
1093 len += strlen(
" TABLESPACE ") + strlen(tablespace);
1095 sql =
rtalloc(
sizeof(
char) * len);
1097 rterror(
_(
"create_index: Could not allocate memory for CREATE INDEX statement"));
1102 sprintf(sql,
"CREATE INDEX ON %s%s USING gist (st_convexhull(%s))%s%s;",
1103 (schema != NULL ? schema :
""),
1106 (tablespace != NULL ?
" TABLESPACE " :
""),
1107 (tablespace != NULL ? tablespace :
"")
1119 const char *schema,
const char *table,
1125 assert(table != NULL);
1127 len = strlen(
"ANALYZE ;") + 1;
1129 len += strlen(schema);
1130 len += strlen(table);
1132 sql =
rtalloc(
sizeof(
char) * len);
1134 rterror(
_(
"analyze_table: Could not allocate memory for ANALYZE TABLE statement"));
1137 sprintf(sql,
"ANALYZE %s%s;",
1138 (schema != NULL ? schema :
""),
1149 const char *schema,
const char *table,
1155 assert(table != NULL);
1157 len = strlen(
"VACUUM ANALYZE ;") + 1;
1159 len += strlen(schema);
1160 len += strlen(table);
1162 sql =
rtalloc(
sizeof(
char) * len);
1164 rterror(
_(
"vacuum_table: Could not allocate memory for VACUUM statement"));
1167 sprintf(sql,
"VACUUM ANALYZE %s%s;",
1168 (schema != NULL ? schema :
""),
1179 const char *schema,
const char *table,
const char *column,
1180 int regular_blocking,
int max_extent,
1187 char *_schema = NULL;
1188 char *_table = NULL;
1189 char *_column = NULL;
1191 assert(table != NULL);
1192 assert(column != NULL);
1195 if (schema != NULL) {
1214 len = strlen(
"SELECT AddRasterConstraints('','','',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE);") + 1;
1215 if (_schema != NULL)
1216 len += strlen(_schema);
1217 len += strlen(_table);
1218 len += strlen(_column);
1220 sql =
rtalloc(
sizeof(
char) * len);
1222 rterror(
_(
"add_raster_constraints: Could not allocate memory for AddRasterConstraints statement"));
1225 sprintf(sql,
"SELECT AddRasterConstraints('%s','%s','%s',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,%s,TRUE,TRUE,TRUE,TRUE,%s);",
1226 (_schema != NULL ? _schema :
""),
1229 (regular_blocking ?
"TRUE" :
"FALSE"),
1230 (max_extent ?
"TRUE" :
"FALSE")
1233 if (_schema != NULL)
1245 const char *ovschema,
const char *ovtable,
const char *ovcolumn,
1246 const char *schema,
const char *table,
const char *column,
1255 char *_ovschema = NULL;
1256 char *_ovtable = NULL;
1257 char *_ovcolumn = NULL;
1259 char *_schema = NULL;
1260 char *_table = NULL;
1261 char *_column = NULL;
1263 assert(ovtable != NULL);
1264 assert(ovcolumn != NULL);
1265 assert(table != NULL);
1266 assert(column != NULL);
1270 if (ovschema != NULL) {
1274 _tmp =
strreplace(_ovschema,
"'",
"''", NULL);
1281 _ovtable =
strreplace(_tmp,
"'",
"''", NULL);
1286 _ovcolumn =
strreplace(_tmp,
"'",
"''", NULL);
1290 if (schema != NULL) {
1309 len = strlen(
"SELECT AddOverviewConstraints('','','','','','',);") + 5;
1310 if (_ovschema != NULL)
1311 len += strlen(_ovschema);
1312 len += strlen(_ovtable);
1313 len += strlen(_ovcolumn);
1314 if (_schema != NULL)
1315 len += strlen(_schema);
1316 len += strlen(_table);
1317 len += strlen(_column);
1319 sql =
rtalloc(
sizeof(
char) * len);
1321 rterror(
_(
"add_overview_constraints: Could not allocate memory for AddOverviewConstraints statement"));
1324 sprintf(sql,
"SELECT AddOverviewConstraints('%s','%s','%s','%s','%s','%s',%d);",
1325 (_ovschema != NULL ? _ovschema :
""),
1328 (_schema != NULL ? _schema :
""),
1334 if (_ovschema != NULL)
1339 if (_schema != NULL)
1351 GDALDatasetH hdsSrc;
1353 VRTSourcedRasterBandH hbandOv;
1354 double gtOv[6] = {0.};
1359 const char *ovtable = NULL;
1362 VRTSourcedRasterBandH hbandDst;
1363 int tile_size[2] = {0};
1364 int _tile_size[2] = {0};
1365 int ntiles[2] = {1, 1};
1368 double gt[6] = {0.};
1374 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1375 if (hdsSrc == NULL) {
1376 rterror(
_(
"build_overview: Could not open raster: %s"), config->
rt_file[idx]);
1381 memcpy(gtOv, info->
gt,
sizeof(
double) * 6);
1384 rterror(
_(
"build_overview: Invalid overview index: %d"), ovx);
1392 rterror(
_(
"build_overview: Overview factor %d is not between %d and %d"), factor,
MINOVFACTOR, MAXOVFACTOR);
1396 dimOv[0] = (int) (info->
dim[0] + (factor / 2)) / factor;
1397 dimOv[1] = (int) (info->
dim[1] + (factor / 2)) / factor;
1400 hdsOv = VRTCreate(dimOv[0], dimOv[1]);
1404 GDALSetProjection(hdsOv, info->
srs);
1410 GDALSetGeoTransform(hdsOv, gtOv);
1415 hbandOv = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsOv, j + 1);
1418 GDALSetRasterNoDataValue(hbandOv, info->
nodataval[j]);
1421 hbandOv, GDALGetRasterBand(hdsSrc, info->
nband[j]),
1423 info->
dim[0], info->
dim[1],
1426 "near", VRT_NODATA_UNSET
1431 VRTFlushCache(hdsOv);
1435 tile_size[0] = dimOv[0];
1439 tile_size[1] = dimOv[1];
1445 tile_size[0] != dimOv[0] &&
1446 tile_size[1] != dimOv[1]
1448 ntiles[0] = (dimOv[0] + tile_size[0] - 1) / tile_size[0];
1449 ntiles[1] = (dimOv[1] + tile_size[1] - 1) / tile_size[1];
1453 memcpy(gt, gtOv,
sizeof(
double) * 6);
1457 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1460 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1461 _tile_size[1] = dimOv[1] - (ytile * tile_size[1]);
1463 _tile_size[1] = tile_size[1];
1465 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1472 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1473 _tile_size[0] = dimOv[0] - (xtile * tile_size[0]);
1475 _tile_size[0] = tile_size[0];
1478 GDALApplyGeoTransform(
1480 xtile * tile_size[0], ytile * tile_size[1],
1485 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1489 GDALSetProjection(hdsDst, info->
srs);
1490 GDALSetGeoTransform(hdsDst, gt);
1495 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, j + 1);
1498 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[j]);
1501 hbandDst, GDALGetRasterBand(hdsOv, j + 1),
1502 xtile * tile_size[0], ytile * tile_size[1],
1503 _tile_size[0], _tile_size[1],
1505 _tile_size[0], _tile_size[1],
1506 "near", VRT_NODATA_UNSET
1511 VRTFlushCache(hdsDst);
1516 rterror(
_(
"build_overview: Could not convert VRT dataset to PostGIS raster"));
1529 rterror(
_(
"build_overview: Could not convert PostGIS raster to hex WKB"));
1540 if (tileset->
length > 10) {
1547 rterror(
_(
"build_overview: Could not convert raster tiles into INSERT or COPY statements"));
1564 GDALDatasetH hdsSrc;
1565 GDALRasterBandH hbandSrc;
1568 int ntiles[2] = {1, 1};
1569 int _tile_size[2] = {0, 0};
1572 double gt[6] = {0.};
1573 const char* pszProjectionRef = NULL;
1584 hdsSrc = GDALOpenShared(config->
rt_file[idx], GA_ReadOnly);
1585 if (hdsSrc == NULL) {
1586 rterror(
_(
"convert_raster: Could not open raster: %s"), config->
rt_file[idx]);
1590 nband = GDALGetRasterCount(hdsSrc);
1592 rterror(
_(
"convert_raster: No bands found in raster: %s"), config->
rt_file[idx]);
1599 if (config->
nband[i] > nband) {
1600 rterror(
_(
"convert_raster: Band %d not found in raster: %s"), config->
nband[i], config->
rt_file[idx]);
1607 pszProjectionRef = GDALGetProjectionRef(hdsSrc);
1608 if (pszProjectionRef != NULL && pszProjectionRef[0] !=
'\0') {
1609 info->
srs =
rtalloc(
sizeof(
char) * (strlen(pszProjectionRef) + 1));
1610 if (info->
srs == NULL) {
1611 rterror(
_(
"convert_raster: Could not allocate memory for storing SRS"));
1615 strcpy(info->
srs, pszProjectionRef);
1618 OGRSpatialReferenceH hSRS = OSRNewSpatialReference(NULL);
1619 if (OSRSetFromUserInput(hSRS, pszProjectionRef) == OGRERR_NONE) {
1620 const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL);
1621 const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL);
1623 pszAuthorityName != NULL &&
1624 strcmp(pszAuthorityName,
"EPSG") == 0 &&
1625 pszAuthorityCode != NULL
1627 info->
srid = atoi(pszAuthorityCode);
1630 OSRDestroySpatialReference(hSRS);
1635 rterror(
_(
"convert_raster: could not determine source srid, cannot transform to target srid %d"), config->
out_srid);
1641 if (GDALGetGeoTransform(hdsSrc, info->
gt) != CE_None) {
1642 rtinfo(
_(
"Using default geotransform matrix (0, 1, 0, 0, 0, -1) for raster: %s"), config->
rt_file[idx]);
1650 memcpy(gt, info->
gt,
sizeof(
double) * 6);
1657 if (info->
nband == NULL) {
1658 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1668 if (info->
nband == NULL) {
1669 rterror(
_(
"convert_raster: Could not allocate memory for storing band indices"));
1674 info->
nband[i] = i + 1;
1680 rterror(
_(
"convert_raster: Could not allocate memory for storing GDAL data type"));
1686 rterror(
_(
"convert_raster: Could not allocate memory for storing pixel type"));
1692 rterror(
_(
"convert_raster: Could not allocate memory for storing hasnodata flag"));
1698 rterror(
_(
"convert_raster: Could not allocate memory for storing nodata value"));
1708 info->
dim[0] = GDALGetRasterXSize(hdsSrc);
1709 info->
dim[1] = GDALGetRasterYSize(hdsSrc);
1717 info->
dim[0], info->
dim[1],
1745 hbandSrc = GDALGetRasterBand(hdsSrc, info->
nband[i]);
1748 info->
gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
1752 rterror(
_(
"convert_raster: The pixel type of band %d is a complex data type. PostGIS raster does not support complex data types"), i + 1);
1779 rtwarn(
_(
"The size of each output tile may exceed 1 GB. Use -t to specify a reasonable tile size"));
1782 if (config->
outdb) {
1786 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1788 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1789 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1793 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1796 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1797 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1802 GDALApplyGeoTransform(
1811 rterror(
_(
"convert_raster: Could not create raster"));
1822 _tile_size[0], _tile_size[1],
1829 rterror(
_(
"convert_raster: Could not create offline band"));
1836 rterror(
_(
"convert_raster: Could not add offlineband to raster"));
1852 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1860 if (tileset->
length > 10) {
1867 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
1879 VRTSourcedRasterBandH hbandDst;
1882 for (ytile = 0; ytile < ntiles[1]; ytile++) {
1885 if (!config->
pad_tile && ntiles[1] > 1 && (ytile + 1) == ntiles[1])
1886 _tile_size[1] = info->
dim[1] - (ytile * info->
tile_size[1]);
1890 for (xtile = 0; xtile < ntiles[0]; xtile++) {
1897 if (!config->
pad_tile && ntiles[0] > 1 && (xtile + 1) == ntiles[0])
1898 _tile_size[0] = info->
dim[0] - (xtile * info->
tile_size[0]);
1903 GDALApplyGeoTransform(
1916 hdsDst = VRTCreate(_tile_size[0], _tile_size[1]);
1920 GDALSetProjection(hdsDst, info->
srs);
1921 GDALSetGeoTransform(hdsDst, gt);
1926 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
1929 GDALSetRasterNoDataValue(hbandDst, info->
nodataval[i]);
1932 hbandDst, GDALGetRasterBand(hdsSrc, info->
nband[i]),
1934 _tile_size[0], _tile_size[1],
1936 _tile_size[0], _tile_size[1],
1937 "near", VRT_NODATA_UNSET
1942 VRTFlushCache(hdsDst);
1947 rterror(
_(
"convert_raster: Could not convert VRT dataset to PostGIS raster"));
1957 for (i = 0; i < numbands; i++) {
1968 rterror(
_(
"convert_raster: Could not convert PostGIS raster to hex WKB"));
1979 if (tileset->
length > 10) {
1986 rterror(
_(
"convert_raster: Could not convert raster tiles into INSERT or COPY statements"));
2006 assert(config != NULL);
2007 assert(config->
table != NULL);
2012 rterror(
_(
"process_rasters: Could not add BEGIN statement to string buffer"));
2018 if (config->
opt ==
'd') {
2020 rterror(
_(
"process_rasters: Could not add DROP TABLE statement to string buffer"));
2027 rterror(
_(
"process_rasters: Could not add an overview's DROP TABLE statement to string buffer"));
2035 if (config->
opt !=
'a') {
2042 rterror(
_(
"process_rasters: Could not add CREATE TABLE statement to string buffer"));
2054 rterror(
_(
"process_rasters: Could not add an overview's CREATE TABLE statement to string buffer"));
2062 if (config->
opt !=
'p') {
2078 rterror(
_(
"process_rasters: Could not process raster: %s"), config->
rt_file[i]);
2092 rterror(
_(
"process_rasters: Could not convert raster tiles into INSERT or COPY statements"));
2109 if (!
build_overview(i, config, &rastinfo, j, &tileset, buffer)) {
2110 rterror(
_(
"process_rasters: Could not create overview of factor %d for raster %s"), config->
overview[j], config->
rt_file[i]);
2122 rterror(
_(
"process_rasters: Could not convert overview tiles into INSERT or COPY statements"));
2157 rterror(
_(
"process_rasters: Could not add CREATE INDEX statement to string buffer"));
2162 if (config->
opt !=
'p') {
2167 rterror(
_(
"process_rasters: Could not add ANALYZE statement to string buffer"));
2180 rterror(
_(
"process_rasters: Could not add an overview's CREATE INDEX statement to string buffer"));
2185 if (config->
opt !=
'p') {
2190 rterror(
_(
"process_rasters: Could not add an overview's ANALYZE statement to string buffer"));
2205 rterror(
_(
"process:rasters: Could not add AddRasterConstraints statement to string buffer"));
2216 rterror(
_(
"process_rasters: Could not add an overview's AddRasterConstraints statement to string buffer"));
2232 rterror(
_(
"process_rasters: Could not add an overview's AddOverviewConstraints statement to string buffer"));
2240 rterror(
_(
"process_rasters: Could not add END statement to string buffer"));
2251 rterror(
_(
"process_rasters: Could not add VACUUM statement to string buffer"));
2261 rterror(
_(
"process_rasters: Could not add an overview's VACUUM statement to string buffer"));
2278 char **elements = NULL;
2280 GDALDriverH drv = NULL;
2286 setlocale (LC_ALL,
"");
2287 bindtextdomain (PACKAGE, LOCALEDIR);
2288 textdomain (PACKAGE);
2299 if (config == NULL) {
2300 rterror(
_(
"Could not allocate memory for loader configuration"));
2309 for (i = 1; i < argc; i++) {
2312 if (
CSEQUAL(argv[i],
"-s") && i < argc - 1) {
2314 ptr = strchr(optarg,
':');
2317 sscanf(optarg,
"%d", &config->
srid);
2318 sscanf(ptr,
"%d", &config->
out_srid);
2320 config->
srid = atoi(optarg);
2324 else if (
CSEQUAL(argv[i],
"-b") && i < argc - 1) {
2325 elements =
strsplit(argv[++i],
",", &n);
2327 rterror(
_(
"Could not process -b"));
2333 for (j = 0; j < n; j++) {
2334 char *t =
trim(elements[j]);
2335 char **minmax = NULL;
2345 if (!
array_range(atoi(minmax[0]), atoi(minmax[1]), 1, &range, &p)) {
2346 rterror(
_(
"Could not allocate memory for storing band indices"));
2347 for (l = 0; l < o; l++)
2350 for (j = 0; j < n; j++)
2361 if (range == NULL) {
2362 rterror(
_(
"Could not allocate memory for storing band indices"));
2363 for (l = 0; l < o; l++)
2366 for (j = 0; j < n; j++)
2379 if (config->
nband == NULL) {
2380 rterror(
_(
"Could not allocate memory for storing band indices"));
2382 for (l = 0; l < o; l++)
2385 for (j = 0; j < n; j++)
2393 for (l = 0; l < p; l++, m++)
2394 config->
nband[m] = range[l];
2398 for (l = 0; l < o; l++)
2410 if (config->
nband[j] < 1) {
2411 rterror(
_(
"Band index %d must be greater than 0"), config->
nband[j]);
2418 else if (
CSEQUAL(argv[i],
"-t") && i < argc - 1) {
2419 if (
CSEQUAL(argv[++i],
"auto")) {
2424 elements =
strsplit(argv[i],
"x", &n);
2426 rterror(
_(
"Could not process -t"));
2431 for (j = 0; j < n; j++) {
2432 char *t =
trim(elements[j]);
2441 for (j = 0; j < 2; j++) {
2443 rterror(
_(
"Tile size must be greater than 0x0"));
2451 else if (
CSEQUAL(argv[i],
"-P")) {
2455 else if (
CSEQUAL(argv[i],
"-R")) {
2459 else if (
CSEQUAL(argv[i],
"-d")) {
2463 else if (
CSEQUAL(argv[i],
"-a")) {
2467 else if (
CSEQUAL(argv[i],
"-c")) {
2471 else if (
CSEQUAL(argv[i],
"-p")) {
2475 else if (
CSEQUAL(argv[i],
"-f") && i < argc - 1) {
2478 rterror(
_(
"Could not allocate memory for storing raster column name"));
2482 strncpy(config->
raster_column, argv[i], strlen(argv[i]) + 1);
2485 else if (
CSEQUAL(argv[i],
"-F")) {
2489 else if (
CSEQUAL(argv[i],
"-n") && i < argc - 1) {
2492 rterror(
_(
"Could not allocate memory for storing filename column name"));
2500 else if (
CSEQUAL(argv[i],
"-l") && i < argc - 1) {
2501 elements =
strsplit(argv[++i],
",", &n);
2503 rterror(
_(
"Could not process -l"));
2511 rterror(
_(
"Could not allocate memory for storing overview factors"));
2515 for (j = 0; j < n; j++) {
2516 char *t =
trim(elements[j]);
2534 else if (
CSEQUAL(argv[i],
"-q")) {
2538 else if (
CSEQUAL(argv[i],
"-I")) {
2542 else if (
CSEQUAL(argv[i],
"-M")) {
2546 else if (
CSEQUAL(argv[i],
"-C")) {
2550 else if (
CSEQUAL(argv[i],
"-x")) {
2554 else if (
CSEQUAL(argv[i],
"-r")) {
2558 else if (
CSEQUAL(argv[i],
"-T") && i < argc - 1) {
2561 rterror(
_(
"Could not allocate memory for storing tablespace of new table"));
2565 strncpy(config->
tablespace, argv[i], strlen(argv[i]) + 1);
2568 else if (
CSEQUAL(argv[i],
"-X") && i < argc - 1) {
2571 rterror(
_(
"Could not allocate memory for storing tablespace of new indices"));
2578 else if (
CSEQUAL(argv[i],
"-N") && i < argc - 1) {
2583 else if (
CSEQUAL(argv[i],
"-k")) {
2587 else if (
CSEQUAL(argv[i],
"-E") && i < argc - 1) {
2588 config->
endian = atoi(argv[++i]);
2592 else if (
CSEQUAL(argv[i],
"-V") && i < argc - 1) {
2593 config->
version = atoi(argv[++i]);
2597 else if (
CSEQUAL(argv[i],
"-e")) {
2601 else if (
CSEQUAL(argv[i],
"-Y")) {
2605 else if (
CSEQUAL(argv[i],
"-G")) {
2608 if (drv_set == NULL || !drv_count) {
2609 rterror(
_(
"Could not get list of available GDAL raster formats"));
2612 printf(
_(
"Supported GDAL raster formats:\n"));
2613 for (j = 0; j < drv_count; j++) {
2614 printf(
_(
" %s\n"), drv_set[j].long_name);
2627 else if (
CSEQUAL(argv[i],
"-?")) {
2635 if (config->
rt_file == NULL) {
2636 rterror(
_(
"Could not allocate memory for storing raster files"));
2643 rterror(
_(
"Could not allocate memory for storing raster filename"));
2653 rterror(
_(
"Invalid argument combination - cannot use -Y with -s FROM_SRID:TO_SRID"));
2681 if (config->
schema == NULL) {
2682 rterror(
_(
"Could not allocate memory for storing schema name"));
2690 if (config->
table == NULL) {
2691 rterror(
_(
"Could not allocate memory for storing table name"));
2701 if (config->
table == NULL) {
2702 rterror(
_(
"Could not allocate memory for storing table name"));
2711 if (config->
rt_file == NULL) {
2712 rterror(
_(
"Could not reallocate the memory holding raster names"));
2725 drv = GDALIdentifyDriver(config->
rt_file[i], NULL);
2737 rterror(
_(
"Could not allocate memory for cleaned raster filenames"));
2747 rterror(
_(
"Could not allocate memory for cleaned raster filename"));
2751 strcpy(file, config->
rt_file[i]);
2753 for (ptr = file + strlen(file); ptr > file; ptr--) {
2754 if (*ptr ==
'/' || *ptr ==
'\\') {
2762 rterror(
_(
"Could not allocate memory for cleaned raster filename"));
2775 if (config->
table == NULL) {
2781 rterror(
_(
"Could not allocate memory for proxy table name"));
2787 for (ptr = file + strlen(file); ptr > file; ptr--) {
2794 config->
table =
rtalloc(
sizeof(
char) * (strlen(file) + 1));
2795 if (config->
table == NULL) {
2796 rterror(
_(
"Could not allocate memory for proxy table name"));
2800 strcpy(config->
table, file);
2808 rterror(
_(
"Could not allocate memory for default raster column name"));
2819 rterror(
_(
"Could not allocate memory for default filename column name"));
2832 if (config->
schema != NULL)
2834 if (config->
table != NULL)
2854 rterror(
_(
"Could not allocate memory for overview table names"));
2860 sprintf(factor,
"%d", config->
overview[i]);
2864 rterror(
_(
"Could not allocate memory for overview table name"));
2877 rtwarn(
_(
"The schema name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2883 rtwarn(
_(
"The table name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2889 rtwarn(
_(
"The column name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2895 rtwarn(
_(
"The column name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2901 rtwarn(
_(
"The tablespace name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2907 rtwarn(
_(
"The index tablespace name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2915 rtwarn(
_(
"The overview table name \"%s\" may exceed the maximum string length permitted for PostgreSQL identifiers (%d)"),
2927 if (config->
schema != NULL) {
2930 rterror(
_(
"Could not allocate memory for quoting schema name"));
2935 sprintf(tmp,
"\"%s\".", config->
schema);
2939 if (config->
table != NULL) {
2940 tmp =
rtalloc(
sizeof(
char) * (strlen(config->
table) + 3));
2942 rterror(
_(
"Could not allocate memory for quoting table name"));
2947 sprintf(tmp,
"\"%s\"", config->
table);
2949 config->
table = tmp;
2954 rterror(
_(
"Could not allocate memory for quoting raster column name"));
2966 rterror(
_(
"Could not allocate memory for quoting raster column name"));
2978 rterror(
_(
"Could not allocate memory for quoting tablespace name"));
2990 rterror(
_(
"Could not allocate memory for quoting index tablespace name"));
3003 rterror(
_(
"Could not allocate memory for quoting overview table name"));
3020 if (buffer == NULL) {
3021 rterror(
_(
"Could not allocate memory for output string buffer"));
3029 rterror(
_(
"Unable to process rasters"));
GDALDataType * gdalbandtype
static void loader_rt_info_handler(const char *fmt, va_list ap)
static void flush_stringbuffer(STRINGBUFFER *buffer)
static int add_overview_constraints(const char *ovschema, const char *ovtable, const char *ovcolumn, const char *schema, const char *table, const char *column, const int factor, STRINGBUFFER *buffer)
static int analyze_table(const char *schema, const char *table, STRINGBUFFER *buffer)
int rt_raster_get_num_bands(rt_raster raster)
static void init_rastinfo(RASTERINFO *info)
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
static void rtdealloc_stringbuffer(STRINGBUFFER *buffer, int freebuffer)
static int create_index(const char *schema, const char *table, const char *column, const char *tablespace, STRINGBUFFER *buffer)
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...
static int array_range(int min, int max, int step, int **range, int *len)
static char * chartrim(const char *input, char *remove)
static void diff_rastinfo(RASTERINFO *x, RASTERINFO *ref)
int rt_band_is_offline(rt_band band)
Return non-zero if the given band data is on the filesystem.
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
void * default_rt_reallocator(void *mem, size_t size)
static int add_raster_constraints(const char *schema, const char *table, const char *column, int regular_blocking, int max_extent, STRINGBUFFER *buffer)
#define POSTGIS_LIB_VERSION
void * rtrealloc(void *mem, size_t size)
static int append_stringbuffer(STRINGBUFFER *buffer, const char *str)
void rt_band_destroy(rt_band band)
Destroy a raster band.
static int drop_table(const char *schema, const char *table, STRINGBUFFER *buffer)
static int vacuum_table(const char *schema, const char *table, STRINGBUFFER *buffer)
static char * strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
static int insert_records(const char *schema, const char *table, const char *column, const char *filename, const char *file_column_name, int copy_statements, int out_srid, STRINGBUFFER *tileset, STRINGBUFFER *buffer)
Datum buffer(PG_FUNCTION_ARGS)
int main(int argc, char **argv)
static int append_sql_to_buffer(STRINGBUFFER *buffer, const char *str)
static char * strtolower(char *str)
static int process_rasters(RTLOADERCFG *config, STRINGBUFFER *buffer)
static void rt_init_allocators(void)
void rtwarn(const char *fmt,...)
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 ...
char * rt_raster_to_hexwkb(rt_raster raster, int outasin, uint32_t *hexwkbsize)
Return this raster in HEXWKB form (null-terminated hex)
#define SRID_UNKNOWN
Unknown SRID value.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
rt_pixtype rt_util_gdal_datatype_to_pixtype(GDALDataType gdt)
Convert GDALDataType to rt_pixtype.
void rtinfo(const char *fmt,...)
int rt_band_check_is_nodata(rt_band band)
Returns TRUE if the band is only nodata values.
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
static void rtdealloc_config(RTLOADERCFG *config)
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
static void rtdealloc_rastinfo(RASTERINFO *info)
static void calc_tile_size(int dimX, int dimY, int *tileX, int *tileY)
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
static void init_stringbuffer(STRINGBUFFER *buffer)
static int build_overview(int idx, RTLOADERCFG *config, RASTERINFO *info, int ovx, STRINGBUFFER *tileset, STRINGBUFFER *buffer)
static char ** strsplit(const char *str, const char *delimiter, int *n)
void default_rt_deallocator(void *mem)
void rtdealloc(void *mem)
static int copy_from(const char *schema, const char *table, const char *column, const char *filename, const char *file_column_name, STRINGBUFFER *buffer)
static void raster_destroy(rt_raster raster)
rt_gdaldriver rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc)
Returns a set of available GDAL drivers.
void * default_rt_allocator(size_t size)
The default memory/logging handlers installed by lwgeom_install_default_allocators() ...
static void loader_rt_error_handler(const char *fmt, va_list ap)
static int copy_from_end(STRINGBUFFER *buffer)
static int convert_raster(int idx, RTLOADERCFG *config, RASTERINFO *info, STRINGBUFFER *tileset, STRINGBUFFER *buffer)
static int copy_rastinfo(RASTERINFO *dst, RASTERINFO *src)
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
static char * trim(const char *input)
static void init_config(RTLOADERCFG *config)
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
static void loader_rt_warning_handler(const char *fmt, va_list ap)
static void dump_stringbuffer(STRINGBUFFER *buffer)
static int create_table(const char *schema, const char *table, const char *column, const int file_column, const char *file_column_name, const char *tablespace, const char *idx_tablespace, STRINGBUFFER *buffer)
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.