}
static int
-build_overviews(int idx, RTLOADERCFG *config, RASTERINFO *info, STRINGBUFFER *ovset) {
- GDALDatasetH hdsSrc;
- VRTDatasetH hdsOv;
- VRTSourcedRasterBandH hbandOv;
- double gtOv[6] = {0.};
- int dimOv[2] = {0};
- int factor = 0;
+append_sql_to_buffer(STRINGBUFFER *buffer, const char *str) {
+ if (buffer->length > 9)
+ flush_stringbuffer(buffer);
- int i = 0;
- int j = 0;
+ return append_stringbuffer(buffer, str);
+}
- VRTDatasetH hdsDst;
- VRTSourcedRasterBandH hbandDst;
- int tile_size[2] = {0};
- int ntiles[2] = {1, 1};
- int xtile = 0;
- int ytile = 0;
- double gt[6] = {0.};
+static int
+insert_records(
+ const char *schema, const char *table, const char *column,
+ const char *filename, int copy_statements,
+ STRINGBUFFER *tileset, STRINGBUFFER *buffer
+) {
+ char *fn = NULL;
+ uint32_t len = 0;
+ char *sql = NULL;
+ uint32_t x = 0;
- rt_raster rast = NULL;
- char *hex;
- uint32_t hexlen = 0;
+ assert(table != NULL);
+ assert(column != NULL);
- hdsSrc = GDALOpenShared(config->rt_file[idx], GA_ReadOnly);
- if (hdsSrc == NULL) {
- fprintf(stderr, _("Cannot open raster: %s\n"), config->rt_file[idx]);
- return 0;
- }
+ /* COPY statements */
+ if (copy_statements) {
- /* working copy of geotransform matrix */
- memcpy(gtOv, info->gt, sizeof(double) * 6);
+ /* escape tabs in filename */
+ if (filename != NULL)
+ fn = strreplace(filename, "\t", "\\t", NULL);
- /* loop over each overview factor */
- for (i = 0; i < config->overview_count; i++) {
- factor = config->overview[i];
- if (factor < 2) continue;
-
- dimOv[0] = (int) (info->dim[0] + (factor / 2)) / factor;
- dimOv[1] = (int) (info->dim[1] + (factor / 2)) / factor;
-
- /* create VRT dataset */
- hdsOv = VRTCreate(dimOv[0], dimOv[1]);
- /*
- GDALSetDescription(hdsOv, "/tmp/ov.vrt");
- */
- GDALSetProjection(hdsOv, info->srs);
-
- /* adjust scale */
- gtOv[1] *= factor;
- gtOv[5] *= factor;
-
- GDALSetGeoTransform(hdsOv, gtOv);
-
- /* add bands as simple sources */
- for (j = 0; j < info->nband_count; j++) {
- GDALAddBand(hdsOv, info->gdalbandtype[j], NULL);
- hbandOv = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsOv, j + 1);
-
- if (info->hasnodata[j])
- GDALSetRasterNoDataValue(hbandOv, info->nodataval[j]);
-
- VRTAddSimpleSource(
- hbandOv, GDALGetRasterBand(hdsSrc, info->nband[j]),
- 0, 0,
- info->dim[0], info->dim[1],
- 0, 0,
- dimOv[0], dimOv[1],
- "near", VRT_NODATA_UNSET
- );
- }
+ /* rows */
+ for (x = 0; x < tileset->length; x++) {
+ len = strlen(tileset->line[x]) + 1;
- /* make sure VRT reflects all changes */
- VRTFlushCache(hdsOv);
+ if (filename != NULL)
+ len += strlen(fn) + 1;
- /* decide on tile size */
- if (!config->tile_size[0])
- tile_size[0] = dimOv[0];
- else
- tile_size[0] = config->tile_size[0];
- if (!config->tile_size[1])
- tile_size[1] = dimOv[1];
- else
- tile_size[1] = config->tile_size[1];
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for COPY statement\n"));
+ return 0;
+ }
+ sprintf(sql, "%s%s%s",
+ tileset->line[x],
+ (filename != NULL ? "\t" : ""),
+ (filename != NULL ? fn : "")
+ );
- /* number of tiles */
- if (
- tile_size[0] != dimOv[0] &&
- tile_size[1] != dimOv[1]
- ) {
- ntiles[0] = (dimOv[0] + tile_size[0] - 1) / tile_size[0];
- ntiles[1] = (dimOv[1] + tile_size[1] - 1) / tile_size[1];
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
+ sql = NULL;
}
- /* working copy of geotransform matrix */
- memcpy(gt, gtOv, sizeof(double) * 6);
+ }
+ /* INSERT statements */
+ else {
+ len = strlen("INSERT INTO () VALUES (''::raster);") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
+ len += strlen(column);
+ if (filename != NULL)
+ len += strlen(",\"filename\"");
- /* tile overview */
- /* each tile is a VRT with constraints set for just the data required for the tile */
- for (ytile = 0; ytile < ntiles[1]; ytile++) {
- for (xtile = 0; xtile < ntiles[0]; xtile++) {
- /*
- char fn[100];
- sprintf(fn, "/tmp/tile%d.vrt", (ytile * ntiles[0]) + xtile);
- */
+ /* escape single-quotes in filename */
+ if (filename != NULL)
+ fn = strreplace(filename, "'", "''", NULL);
- /* compute tile's upper-left corner */
- GDALApplyGeoTransform(
- gtOv,
- xtile * tile_size[0], ytile * tile_size[1],
- &(gt[0]), &(gt[3])
- );
+ for (x = 0; x < tileset->length; x++) {
+ int sqllen = len;
- /* create VRT dataset */
- hdsDst = VRTCreate(tile_size[0], tile_size[1]);
- /*
- GDALSetDescription(hdsDst, fn);
- */
- GDALSetProjection(hdsDst, info->srs);
- GDALSetGeoTransform(hdsDst, gt);
+ sqllen += strlen(tileset->line[x]);
+ if (filename != NULL)
+ sqllen += strlen(",''") + strlen(fn);
- /* add bands as simple sources */
- for (j = 0; j < info->nband_count; j++) {
- GDALAddBand(hdsDst, info->gdalbandtype[j], NULL);
- hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, j + 1);
+ sql = rtalloc(sizeof(char) * sqllen);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for INSERT statement\n"));
+ return 0;
+ }
+ sprintf(sql, "INSERT INTO %s%s (%s%s) VALUES ('%s'::raster%s%s%s);",
+ (schema != NULL ? schema : ""),
+ table,
+ column,
+ (filename != NULL ? ",\"filename\"" : ""),
+ tileset->line[x],
+ (filename != NULL ? ",'" : ""),
+ (filename != NULL ? fn : ""),
+ (filename != NULL ? "'" : "")
+ );
- if (info->hasnodata[j])
- GDALSetRasterNoDataValue(hbandDst, info->nodataval[j]);
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
+ sql = NULL;
+ }
+ }
- VRTAddSimpleSource(
- hbandDst, GDALGetRasterBand(hdsOv, j + 1),
- xtile * tile_size[0], ytile * tile_size[1],
- tile_size[0], tile_size[1],
- 0, 0,
- tile_size[0], tile_size[1],
- "near", VRT_NODATA_UNSET
- );
- }
+ if (fn != NULL) rtdealloc(fn);
+ return 1;
+}
- /* make sure VRT reflects all changes */
- VRTFlushCache(hdsDst);
+static int
+drop_table(const char *schema, const char *table, STRINGBUFFER *buffer) {
+ char *sql = NULL;
+ uint32_t len = 0;
- /* convert VRT dataset to rt_raster */
- rast = rt_raster_from_gdal_dataset(hdsDst);
+ len = strlen("DROP TABLE IF EXISTS ;") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
- /* set srid if provided */
- rt_raster_set_srid(rast, config->srid);
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for DROP TABLE statement\n"));
+ return 0;
+ }
+ sprintf(sql, "DROP TABLE IF EXISTS %s%s;",
+ (schema != NULL ? schema : ""),
+ table
+ );
- /* convert rt_raster to hexwkb */
- hex = rt_raster_to_hexwkb(rast, &hexlen);
- raster_destroy(rast);
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- /* add hexwkb to tileset */
- append_stringbuffer(&(ovset[i]), hex);
+ return 1;
+}
- rtdealloc(hex);
- GDALClose(hdsDst);
- }
- }
+static int
+create_table(
+ const char *schema, const char *table, const char *column,
+ const int file_column,
+ const char *tablespace, const char *idx_tablespace,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
+
+ assert(table != NULL);
+ assert(column != NULL);
+
+ len = strlen("CREATE TABLE (\"rid\" serial PRIMARY KEY, raster);") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
+ len += strlen(column);
+ if (file_column)
+ len += strlen(",\"filename\" text");
+ if (tablespace != NULL)
+ len += strlen(" TABLESPACE ") + strlen(tablespace);
+ if (idx_tablespace != NULL)
+ len += strlen(" USING INDEX TABLESPACE ") + strlen(idx_tablespace);
- GDALClose(hdsOv);
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for CREATE TABLE statement\n"));
+ return 0;
}
+ sprintf(sql, "CREATE TABLE %s%s (\"rid\" serial PRIMARY KEY,%s raster%s)%s%s%s%s;",
+ (schema != NULL ? schema : ""),
+ table,
+ column,
+ (file_column ? ",\"filename\" text" : ""),
+ (tablespace != NULL ? " TABLESPACE " : ""),
+ (tablespace != NULL ? tablespace : ""),
+ (idx_tablespace != NULL ? " USING INDEX TABLESPACE " : ""),
+ (idx_tablespace != NULL ? idx_tablespace : "")
+ );
+
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- GDALClose(hdsSrc);
return 1;
}
static int
-convert_raster(int idx, RTLOADERCFG *config, RASTERINFO *info, STRINGBUFFER *tileset) {
- GDALDatasetH hdsSrc;
- GDALRasterBandH hbandSrc;
- int nband = 0;
- int i = 0;
- int ntiles[2] = {1, 1};
- int xtile = 0;
- int ytile = 0;
- double gt[6] = {0.};
+copy_from(
+ const char *schema, const char *table, const char *column,
+ const char *filename,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- rt_raster rast = NULL;
- char *hex;
- uint32_t hexlen = 0;
+ assert(table != NULL);
+ assert(column != NULL);
- hdsSrc = GDALOpenShared(config->rt_file[idx], GA_ReadOnly);
- if (hdsSrc == NULL) {
- fprintf(stderr, _("Cannot open raster: %s\n"), config->rt_file[idx]);
- return 0;
- }
+ len = strlen("COPY () FROM stdin;") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
+ len += strlen(column);
+ if (filename != NULL)
+ len += strlen(",\"filename\"");
- nband = GDALGetRasterCount(hdsSrc);
- if (!nband) {
- fprintf(stderr, _("No bands found in raster: %s\n"), config->rt_file[idx]);
- GDALClose(hdsSrc);
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for COPY statement\n"));
return 0;
}
+ sprintf(sql, "COPY %s%s (%s%s) FROM stdin;",
+ (schema != NULL ? schema : ""),
+ table,
+ column,
+ (filename != NULL ? ",\"filename\"" : "")
+ );
- /* check that bands specified are available */
- for (i = 0; i < config->nband_count; i++) {
- if (config->nband[i] > nband) {
- fprintf(stderr, _("Band %d not found in raster: %s\n"), config->nband[i], config->rt_file[idx]);
- GDALClose(hdsSrc);
- return 0;
- }
- }
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
+ sql = NULL;
- /* record srs */
- if (GDALGetProjectionRef(hdsSrc) != NULL) {
- info->srs = rtalloc(sizeof(char) * (strlen(GDALGetProjectionRef(hdsSrc)) + 1));
- if (info->srs == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing SRS\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- strcpy(info->srs, GDALGetProjectionRef(hdsSrc));
- }
+ return 1;
+}
- /* record geotransform matrix */
- if (GDALGetGeoTransform(hdsSrc, info->gt) != CE_None) {
- fprintf(stderr, _("Cannot get geotransform matrix from raster: %s\n"), config->rt_file[idx]);
- GDALClose(hdsSrc);
- return 0;
- }
- memcpy(gt, info->gt, sizeof(double) * 6);
+static int
+copy_from_end(STRINGBUFFER *buffer) {
+ /* end of data */
+ append_sql_to_buffer(buffer, "\\.");
- /* record # of bands */
- /* user-specified bands */
- if (config->nband_count > 0) {
- info->nband_count = config->nband_count;
- info->nband = rtalloc(sizeof(int) * info->nband_count);
- if (info->nband == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- memcpy(info->nband, config->nband, sizeof(int) * info->nband_count);
- }
- /* all bands */
- else {
- info->nband_count = nband;
- info->nband = rtalloc(sizeof(int) * info->nband_count);
- if (info->nband == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- for (i = 0; i < info->nband_count; i++)
- info->nband[i] = i + 1;
- }
+ return 1;
+}
- /* initialize parameters dependent on nband */
- info->gdalbandtype = rtalloc(sizeof(GDALDataType) * info->nband_count);
- if (info->gdalbandtype == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing GDAL data type\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- info->bandtype = rtalloc(sizeof(rt_pixtype) * info->nband_count);
- if (info->bandtype == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing pixel type\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- info->hasnodata = rtalloc(sizeof(int) * info->nband_count);
- if (info->hasnodata == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing hasnodata flag\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- info->nodataval = rtalloc(sizeof(double) * info->nband_count);
- if (info->nodataval == NULL) {
- fprintf(stderr, _("Could not allocate memory for storing nodata value\n"));
- GDALClose(hdsSrc);
- return 0;
- }
- memset(info->gdalbandtype, GDT_Unknown, sizeof(GDALDataType) * info->nband_count);
- memset(info->bandtype, PT_END, sizeof(rt_pixtype) * info->nband_count);
- memset(info->hasnodata, 0, sizeof(int) * info->nband_count);
- memset(info->nodataval, 0, sizeof(double) * info->nband_count);
+static int
+create_index(
+ const char *schema, const char *table, const char *column,
+ const char *tablespace,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- /* dimensions of raster */
- info->dim[0] = GDALGetRasterXSize(hdsSrc);
- info->dim[1] = GDALGetRasterYSize(hdsSrc);
+ assert(table != NULL);
+ assert(column != NULL);
- /* decide on tile size */
- if (!config->tile_size[0])
- info->tile_size[0] = info->dim[0];
- else
- info->tile_size[0] = config->tile_size[0];
- if (!config->tile_size[1])
- info->tile_size[1] = info->dim[1];
- else
- info->tile_size[1] = config->tile_size[1];
+ /* create index */
+ len = strlen("CREATE INDEX ON USING gist (st_convexhull());") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
+ len += strlen(column);
+ if (tablespace != NULL)
+ len += strlen(" TABLESPACE ") + strlen(tablespace);
- /* number of tiles */
- if (
- info->tile_size[0] != info->dim[0] &&
- info->tile_size[1] != info->dim[1]
- ) {
- ntiles[0] = (info->dim[0] + info->tile_size[0] - 1) / info->tile_size[0];
- ntiles[1] = (info->dim[1] + info->tile_size[1] - 1) / info->tile_size[1];
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for CREATE INDEX statement\n"));
+ return 0;
}
+ sprintf(sql, "CREATE INDEX ON %s%s USING gist (st_convexhull(%s))%s%s;",
+ (schema != NULL ? schema : ""),
+ table,
+ column,
+ (tablespace != NULL ? " TABLESPACE " : ""),
+ (tablespace != NULL ? tablespace : "")
+ );
- /* go through bands for attributes */
- for (i = 0; i < info->nband_count; i++) {
- hbandSrc = GDALGetRasterBand(hdsSrc, info->nband[i]);
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- /* datatype */
- info->gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
+ return 1;
+}
- /* complex data type? */
- if (GDALDataTypeIsComplex(info->gdalbandtype[i])) {
- fprintf(stderr, _("The pixel type of band %d is a complex data type. PostGIS Raster does not support complex data types\n"), i + 1);
- GDALClose(hdsSrc);
- return 0;
- }
+static int
+analyze_table(
+ const char *schema, const char *table,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- /* convert data type to that of postgis raster */
- info->bandtype[i] = rt_util_gdal_datatype_to_pixtype(info->gdalbandtype[i]);
+ assert(table != NULL);
- /* hasnodata and nodataval */
- info->nodataval[i] = GDALGetRasterNoDataValue(hbandSrc, &(info->hasnodata[i]));
- if (!info->hasnodata[i]) {
- /* does NOT have nodata value, but user-specified */
- if (config->hasnodata) {
- info->hasnodata[i] = 1;
- info->nodataval[i] = config->nodataval;
- }
- else
- info->nodataval[i] = 0;
- }
+ len = strlen("ANALYZE ;") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
+
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for ANALYZE TABLE statement\n"));
+ return 0;
}
+ sprintf(sql, "ANALYZE %s%s;",
+ (schema != NULL ? schema : ""),
+ table
+ );
- /* out-db raster */
- if (config->outdb) {
- rt_band band = NULL;
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- GDALClose(hdsSrc);
+ return 1;
+}
- /* each tile is a raster */
- for (ytile = 0; ytile < ntiles[1]; ytile++) {
- for (xtile = 0; xtile < ntiles[0]; xtile++) {
-
- /* compute tile's upper-left corner */
- GDALApplyGeoTransform(
- info->gt,
- xtile * info->tile_size[0], ytile * info->tile_size[1],
- &(gt[0]), &(gt[3])
- );
+static int
+vacuum_table(
+ const char *schema, const char *table,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- /* create raster object */
- rast = rt_raster_new(info->tile_size[0], info->tile_size[1]);
- if (rast == NULL) {
- fprintf(stderr, _("Could not create raster\n"));
- return 0;
- }
+ assert(table != NULL);
- /* set raster attributes */
- rt_raster_set_srid(rast, config->srid);
- rt_raster_set_geotransform_matrix(rast, gt);
+ len = strlen("VACUUM ANALYZE ;") + 1;
+ if (schema != NULL)
+ len += strlen(schema);
+ len += strlen(table);
- /* add bands */
- for (i = 0; i < info->nband_count; i++) {
- band = rt_band_new_offline(
- info->tile_size[0], info->tile_size[1],
- info->bandtype[i],
- info->hasnodata[i], info->nodataval[i],
- info->nband[i] - 1,
- config->rt_file[idx]
- );
- if (band == NULL) {
- fprintf(stderr, _("Could not create offline band\n"));
- raster_destroy(rast);
- return 0;
- }
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for VACUUM statement\n"));
+ return 0;
+ }
+ sprintf(sql, "VACUUM ANALYZE %s%s;",
+ (schema != NULL ? schema : ""),
+ table
+ );
- /* add band to raster */
- if (rt_raster_add_band(rast, band, rt_raster_get_num_bands(rast)) == -1) {
- fprintf(stderr, _("Could not add offlineband to raster\n"));
- rt_band_destroy(band);
- raster_destroy(rast);
- return 0;
- }
- }
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- /* convert rt_raster to hexwkb */
- hex = rt_raster_to_hexwkb(rast, &hexlen);
- raster_destroy(rast);
+ return 1;
+}
- /* add hexwkb to tileset */
- append_stringbuffer(tileset, hex);
+static int
+add_raster_constraints(
+ const char *schema, const char *table, const char *column,
+ int regular_blocking, int max_extent,
+ STRINGBUFFER *buffer
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- rtdealloc(hex);
- }
- }
- }
- /* in-db raster */
- else {
- VRTDatasetH hdsDst;
- VRTSourcedRasterBandH hbandDst;
+ char *_schema = NULL;
+ char *_table = NULL;
+ char *_column = NULL;
- /* each tile is a VRT with constraints set for just the data required for the tile */
- for (ytile = 0; ytile < ntiles[1]; ytile++) {
- for (xtile = 0; xtile < ntiles[0]; xtile++) {
+ assert(table != NULL);
+ assert(column != NULL);
- /* compute tile's upper-left corner */
- GDALApplyGeoTransform(
- info->gt,
- xtile * info->tile_size[0], ytile * info->tile_size[1],
- &(gt[0]), &(gt[3])
- );
+ if (schema != NULL) {
+ char *tmp = chartrim(schema, ".");
+ _schema = chartrim(tmp, "\"");
+ rtdealloc(tmp);
+ }
+ _table = chartrim(table, "\"");
+ _column = chartrim(column, "\"");
- /* create VRT dataset */
- hdsDst = VRTCreate(info->tile_size[0], info->tile_size[1]);
- GDALSetProjection(hdsDst, info->srs);
- GDALSetGeoTransform(hdsDst, gt);
+ len = strlen("SELECT AddRasterConstraints('','','',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,FALSE);") + 1;
+ if (_schema != NULL)
+ len += strlen(_schema);
+ len += strlen(_table);
+ len += strlen(_column);
- /* add bands as simple sources */
- for (i = 0; i < info->nband_count; i++) {
- GDALAddBand(hdsDst, info->gdalbandtype[i], NULL);
- hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for AddRasterConstraints statement\n"));
+ return 0;
+ }
+ sprintf(sql, "SELECT AddRasterConstraints('%s','%s','%s',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,%s,TRUE,TRUE,TRUE,%s);",
+ (_schema != NULL ? _schema : ""),
+ _table,
+ _column,
+ (regular_blocking ? "TRUE" : "FALSE"),
+ (max_extent ? "TRUE" : "FALSE")
+ );
+
+ if (_schema != NULL)
+ rtdealloc(_schema);
+ rtdealloc(_table);
+ rtdealloc(_column);
- if (info->hasnodata[i])
- GDALSetRasterNoDataValue(hbandDst, info->nodataval[i]);
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
- VRTAddSimpleSource(
- hbandDst, GDALGetRasterBand(hdsSrc, info->nband[i]),
- xtile * info->tile_size[0], ytile * info->tile_size[1],
- info->tile_size[0], info->tile_size[1],
- 0, 0,
- info->tile_size[0], info->tile_size[1],
- "near", VRT_NODATA_UNSET
- );
- }
+ return 1;
+}
- /* make sure VRT reflects all changes */
- VRTFlushCache(hdsDst);
+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
+) {
+ char *sql = NULL;
+ uint32_t len = 0;
- /* convert VRT dataset to rt_raster */
- rast = rt_raster_from_gdal_dataset(hdsDst);
+ char *_ovschema = NULL;
+ char *_ovtable = NULL;
+ char *_ovcolumn = NULL;
- /* set srid if provided */
- rt_raster_set_srid(rast, config->srid);
+ char *_schema = NULL;
+ char *_table = NULL;
+ char *_column = NULL;
- /* convert rt_raster to hexwkb */
- hex = rt_raster_to_hexwkb(rast, &hexlen);
- raster_destroy(rast);
+ assert(ovtable != NULL);
+ assert(ovcolumn != NULL);
+ assert(table != NULL);
+ assert(column != NULL);
+ assert(factor >= MINOVFACTOR && factor <= MAXOVFACTOR);
- /* add hexwkb to tileset */
- append_stringbuffer(tileset, hex);
+ if (ovschema != NULL) {
+ char *tmp = chartrim(ovschema, ".");
+ _ovschema = chartrim(tmp, "\"");
+ rtdealloc(tmp);
+ }
+ _ovtable = chartrim(ovtable, "\"");
+ _ovcolumn = chartrim(ovcolumn, "\"");
- rtdealloc(hex);
- GDALClose(hdsDst);
- }
- }
+ if (schema != NULL) {
+ char *tmp = chartrim(schema, ".");
+ _schema = chartrim(tmp, "\"");
+ rtdealloc(tmp);
+ }
+ _table = chartrim(table, "\"");
+ _column = chartrim(column, "\"");
- GDALClose(hdsSrc);
+ len = strlen("SELECT AddOverviewConstraints('','','','','','',);") + 5;
+ if (_ovschema != NULL)
+ len += strlen(_ovschema);
+ len += strlen(_ovtable);
+ len += strlen(_ovcolumn);
+ if (_schema != NULL)
+ len += strlen(_schema);
+ len += strlen(_table);
+ len += strlen(_column);
+
+ sql = rtalloc(sizeof(char) * len);
+ if (sql == NULL) {
+ fprintf(stderr, _("Could not allocate memory for AddOverviewConstraints statement\n"));
+ return 0;
}
+ sprintf(sql, "SELECT AddOverviewConstraints('%s','%s','%s','%s','%s','%s',%d);",
+ (_ovschema != NULL ? _ovschema : ""),
+ _ovtable,
+ _ovcolumn,
+ (_schema != NULL ? _schema : ""),
+ _table,
+ _column,
+ factor
+ );
+
+ if (_ovschema != NULL)
+ rtdealloc(_ovschema);
+ rtdealloc(_ovtable);
+ rtdealloc(_ovcolumn);
+
+ if (_schema != NULL)
+ rtdealloc(_schema);
+ rtdealloc(_table);
+ rtdealloc(_column);
+
+ append_sql_to_buffer(buffer, sql);
+ rtdealloc(sql);
return 1;
}
static int
-insert_records(
- const char *schema, const char *table, const char *column,
- const char *filename, int copy_statements,
- STRINGBUFFER *tileset, STRINGBUFFER *buffer
-) {
- char *fn = NULL;
- uint32_t len = 0;
- char *sql = NULL;
- uint32_t x = 0;
+build_overview(int idx, RTLOADERCFG *config, RASTERINFO *info, int factor, STRINGBUFFER *tileset, STRINGBUFFER *buffer) {
+ GDALDatasetH hdsSrc;
+ VRTDatasetH hdsOv;
+ VRTSourcedRasterBandH hbandOv;
+ double gtOv[6] = {0.};
+ int dimOv[2] = {0};
- assert(table != NULL);
- assert(column != NULL);
+ int j = 0;
- append_stringbuffer(buffer, "");
+ VRTDatasetH hdsDst;
+ VRTSourcedRasterBandH hbandDst;
+ int tile_size[2] = {0};
+ int ntiles[2] = {1, 1};
+ int xtile = 0;
+ int ytile = 0;
+ double gt[6] = {0.};
- /* COPY statements */
- if (copy_statements) {
+ rt_raster rast = NULL;
+ char *hex;
+ uint32_t hexlen = 0;
- /* COPY */
- len = strlen("COPY () FROM stdin;") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
- len += strlen(column);
- if (filename != NULL)
- len += strlen(",\"filename\"");
+ hdsSrc = GDALOpenShared(config->rt_file[idx], GA_ReadOnly);
+ if (hdsSrc == NULL) {
+ fprintf(stderr, _("Cannot open raster: %s\n"), config->rt_file[idx]);
+ return 0;
+ }
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for COPY statement\n"));
- return 0;
- }
- sprintf(sql, "COPY %s%s (%s%s) FROM stdin;",
- (schema != NULL ? schema : ""),
- table,
- column,
- (filename != NULL ? ",\"filename\"" : "")
- );
+ /* working copy of geotransform matrix */
+ memcpy(gtOv, info->gt, sizeof(double) * 6);
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
- sql = NULL;
+ /* loop over each overview factor */
+ if (factor < MINOVFACTOR || factor > MAXOVFACTOR) {
+ fprintf(stderr, _("Overview factor %d is not between %d and %d\n"), factor, MINOVFACTOR, MAXOVFACTOR);
+ return 0;
+ }
- /* escape tabs in filename */
- if (filename != NULL)
- fn = strreplace(filename, "\t", "\\t", NULL);
+ dimOv[0] = (int) (info->dim[0] + (factor / 2)) / factor;
+ dimOv[1] = (int) (info->dim[1] + (factor / 2)) / factor;
- /* rows */
- for (x = 0; x < tileset->length; x++) {
- len = strlen(tileset->line[x]) + 1;
+ /* create VRT dataset */
+ hdsOv = VRTCreate(dimOv[0], dimOv[1]);
+ /*
+ GDALSetDescription(hdsOv, "/tmp/ov.vrt");
+ */
+ GDALSetProjection(hdsOv, info->srs);
- if (filename != NULL)
- len += strlen(fn) + 1;
+ /* adjust scale */
+ gtOv[1] *= factor;
+ gtOv[5] *= factor;
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for COPY statement\n"));
- return 0;
- }
- sprintf(sql, "%s%s%s",
- tileset->line[x],
- (filename != NULL ? "\t" : ""),
- (filename != NULL ? fn : "")
- );
+ GDALSetGeoTransform(hdsOv, gtOv);
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
- sql = NULL;
- }
+ /* add bands as simple sources */
+ for (j = 0; j < info->nband_count; j++) {
+ GDALAddBand(hdsOv, info->gdalbandtype[j], NULL);
+ hbandOv = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsOv, j + 1);
+
+ if (info->hasnodata[j])
+ GDALSetRasterNoDataValue(hbandOv, info->nodataval[j]);
- /* end of data */
- append_stringbuffer(buffer, "\\.");
+ VRTAddSimpleSource(
+ hbandOv, GDALGetRasterBand(hdsSrc, info->nband[j]),
+ 0, 0,
+ info->dim[0], info->dim[1],
+ 0, 0,
+ dimOv[0], dimOv[1],
+ "near", VRT_NODATA_UNSET
+ );
}
- /* INSERT statements */
- else {
- len = strlen("INSERT INTO () VALUES (''::raster);") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
- len += strlen(column);
- if (filename != NULL)
- len += strlen(",\"filename\"");
- /* escape single-quotes in filename */
- if (filename != NULL)
- fn = strreplace(filename, "'", "''", NULL);
+ /* make sure VRT reflects all changes */
+ VRTFlushCache(hdsOv);
- for (x = 0; x < tileset->length; x++) {
- int sqllen = len;
+ /* decide on tile size */
+ if (!config->tile_size[0])
+ tile_size[0] = dimOv[0];
+ else
+ tile_size[0] = config->tile_size[0];
+ if (!config->tile_size[1])
+ tile_size[1] = dimOv[1];
+ else
+ tile_size[1] = config->tile_size[1];
- sqllen += strlen(tileset->line[x]);
- if (filename != NULL)
- sqllen += strlen(",''") + strlen(fn);
+ /* number of tiles */
+ if (
+ tile_size[0] != dimOv[0] &&
+ tile_size[1] != dimOv[1]
+ ) {
+ ntiles[0] = (dimOv[0] + tile_size[0] - 1) / tile_size[0];
+ ntiles[1] = (dimOv[1] + tile_size[1] - 1) / tile_size[1];
+ }
- sql = rtalloc(sizeof(char) * sqllen);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for INSERT statement\n"));
- return 0;
- }
- sprintf(sql, "INSERT INTO %s%s (%s%s) VALUES ('%s'::raster%s%s%s);",
- (schema != NULL ? schema : ""),
- table,
- column,
- (filename != NULL ? ",\"filename\"" : ""),
- tileset->line[x],
- (filename != NULL ? ",'" : ""),
- (filename != NULL ? fn : ""),
- (filename != NULL ? "'" : "")
+ /* working copy of geotransform matrix */
+ memcpy(gt, gtOv, sizeof(double) * 6);
+
+ /* tile overview */
+ /* each tile is a VRT with constraints set for just the data required for the tile */
+ for (ytile = 0; ytile < ntiles[1]; ytile++) {
+ for (xtile = 0; xtile < ntiles[0]; xtile++) {
+ /*
+ char fn[100];
+ sprintf(fn, "/tmp/tile%d.vrt", (ytile * ntiles[0]) + xtile);
+ */
+
+ /* compute tile's upper-left corner */
+ GDALApplyGeoTransform(
+ gtOv,
+ xtile * tile_size[0], ytile * tile_size[1],
+ &(gt[0]), &(gt[3])
);
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
- sql = NULL;
- }
- }
+ /* create VRT dataset */
+ hdsDst = VRTCreate(tile_size[0], tile_size[1]);
+ /*
+ GDALSetDescription(hdsDst, fn);
+ */
+ GDALSetProjection(hdsDst, info->srs);
+ GDALSetGeoTransform(hdsDst, gt);
- append_stringbuffer(buffer, "");
+ /* add bands as simple sources */
+ for (j = 0; j < info->nband_count; j++) {
+ GDALAddBand(hdsDst, info->gdalbandtype[j], NULL);
+ hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, j + 1);
- if (fn != NULL) rtdealloc(fn);
- return 1;
-}
+ if (info->hasnodata[j])
+ GDALSetRasterNoDataValue(hbandDst, info->nodataval[j]);
-static int
-drop_table(const char *schema, const char *table, STRINGBUFFER *buffer) {
- char *sql = NULL;
- uint32_t len = 0;
+ VRTAddSimpleSource(
+ hbandDst, GDALGetRasterBand(hdsOv, j + 1),
+ xtile * tile_size[0], ytile * tile_size[1],
+ tile_size[0], tile_size[1],
+ 0, 0,
+ tile_size[0], tile_size[1],
+ "near", VRT_NODATA_UNSET
+ );
+ }
- len = strlen("DROP TABLE IF EXISTS ;") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
+ /* make sure VRT reflects all changes */
+ VRTFlushCache(hdsDst);
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for DROP TABLE statement\n"));
- return 0;
- }
- sprintf(sql, "DROP TABLE IF EXISTS %s%s;",
- (schema != NULL ? schema : ""),
- table
- );
+ /* convert VRT dataset to rt_raster */
+ rast = rt_raster_from_gdal_dataset(hdsDst);
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ /* set srid if provided */
+ rt_raster_set_srid(rast, config->srid);
- return 1;
-}
+ /* convert rt_raster to hexwkb */
+ hex = rt_raster_to_hexwkb(rast, &hexlen);
+ raster_destroy(rast);
-static int
-create_table(
- const char *schema, const char *table, const char *column,
- const int file_column,
- const char *tablespace, const char *idx_tablespace,
- STRINGBUFFER *buffer
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ /* add hexwkb to tileset */
+ append_stringbuffer(tileset, hex);
+
+ rtdealloc(hex);
+ GDALClose(hdsDst);
+
+ /* flush if tileset gets too big */
+ if (tileset->length > 10) {
+ if (!insert_records(
+ config->schema, config->table, config->raster_column,
+ (config->file_column ? config->rt_filename[idx] : NULL), config->copy_statements,
+ tileset, buffer
+ )) {
+ fprintf(stderr, _("Cannot convert raster tiles into INSERT or COPY statements\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+
+ rtdealloc_stringbuffer(tileset, 0);
+ }
+ }
+ }
- assert(table != NULL);
- assert(column != NULL);
+ GDALClose(hdsOv);
+ GDALClose(hdsSrc);
+ return 1;
+}
- len = strlen("CREATE TABLE (\"rid\" serial PRIMARY KEY, raster);") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
- len += strlen(column);
- if (file_column)
- len += strlen(",\"filename\" text");
- if (tablespace != NULL)
- len += strlen(" TABLESPACE ") + strlen(tablespace);
- if (idx_tablespace != NULL)
- len += strlen(" USING INDEX TABLESPACE ") + strlen(idx_tablespace);
+static int
+convert_raster(int idx, RTLOADERCFG *config, RASTERINFO *info, STRINGBUFFER *tileset, STRINGBUFFER *buffer) {
+ GDALDatasetH hdsSrc;
+ GDALRasterBandH hbandSrc;
+ int nband = 0;
+ int i = 0;
+ int ntiles[2] = {1, 1};
+ int xtile = 0;
+ int ytile = 0;
+ double gt[6] = {0.};
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for CREATE TABLE statement\n"));
+ rt_raster rast = NULL;
+ char *hex;
+ uint32_t hexlen = 0;
+
+ hdsSrc = GDALOpenShared(config->rt_file[idx], GA_ReadOnly);
+ if (hdsSrc == NULL) {
+ fprintf(stderr, _("Cannot open raster: %s\n"), config->rt_file[idx]);
return 0;
}
- sprintf(sql, "CREATE TABLE %s%s (\"rid\" serial PRIMARY KEY,%s raster%s)%s%s%s%s;",
- (schema != NULL ? schema : ""),
- table,
- column,
- (file_column ? ",\"filename\" text" : ""),
- (tablespace != NULL ? " TABLESPACE " : ""),
- (tablespace != NULL ? tablespace : ""),
- (idx_tablespace != NULL ? " USING INDEX TABLESPACE " : ""),
- (idx_tablespace != NULL ? idx_tablespace : "")
- );
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ nband = GDALGetRasterCount(hdsSrc);
+ if (!nband) {
+ fprintf(stderr, _("No bands found in raster: %s\n"), config->rt_file[idx]);
+ GDALClose(hdsSrc);
+ return 0;
+ }
- return 1;
-}
+ /* check that bands specified are available */
+ for (i = 0; i < config->nband_count; i++) {
+ if (config->nband[i] > nband) {
+ fprintf(stderr, _("Band %d not found in raster: %s\n"), config->nband[i], config->rt_file[idx]);
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ }
-static int
-create_index(
- const char *schema, const char *table, const char *column,
- const char *tablespace,
- STRINGBUFFER *buffer
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ /* record srs */
+ if (GDALGetProjectionRef(hdsSrc) != NULL) {
+ info->srs = rtalloc(sizeof(char) * (strlen(GDALGetProjectionRef(hdsSrc)) + 1));
+ if (info->srs == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing SRS\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ strcpy(info->srs, GDALGetProjectionRef(hdsSrc));
+ }
- assert(table != NULL);
- assert(column != NULL);
+ /* record geotransform matrix */
+ if (GDALGetGeoTransform(hdsSrc, info->gt) != CE_None) {
+ fprintf(stderr, _("Cannot get geotransform matrix from raster: %s\n"), config->rt_file[idx]);
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ memcpy(gt, info->gt, sizeof(double) * 6);
- /* create index */
- len = strlen("CREATE INDEX ON USING gist (st_convexhull());") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
- len += strlen(column);
- if (tablespace != NULL)
- len += strlen(" TABLESPACE ") + strlen(tablespace);
+ /* record # of bands */
+ /* user-specified bands */
+ if (config->nband_count > 0) {
+ info->nband_count = config->nband_count;
+ info->nband = rtalloc(sizeof(int) * info->nband_count);
+ if (info->nband == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ memcpy(info->nband, config->nband, sizeof(int) * info->nband_count);
+ }
+ /* all bands */
+ else {
+ info->nband_count = nband;
+ info->nband = rtalloc(sizeof(int) * info->nband_count);
+ if (info->nband == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing band indices\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ for (i = 0; i < info->nband_count; i++)
+ info->nband[i] = i + 1;
+ }
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for CREATE INDEX statement\n"));
+ /* initialize parameters dependent on nband */
+ info->gdalbandtype = rtalloc(sizeof(GDALDataType) * info->nband_count);
+ if (info->gdalbandtype == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing GDAL data type\n"));
+ GDALClose(hdsSrc);
return 0;
}
- sprintf(sql, "CREATE INDEX ON %s%s USING gist (st_convexhull(%s))%s%s;",
- (schema != NULL ? schema : ""),
- table,
- column,
- (tablespace != NULL ? " TABLESPACE " : ""),
- (tablespace != NULL ? tablespace : "")
- );
+ info->bandtype = rtalloc(sizeof(rt_pixtype) * info->nband_count);
+ if (info->bandtype == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing pixel type\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ info->hasnodata = rtalloc(sizeof(int) * info->nband_count);
+ if (info->hasnodata == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing hasnodata flag\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ info->nodataval = rtalloc(sizeof(double) * info->nband_count);
+ if (info->nodataval == NULL) {
+ fprintf(stderr, _("Could not allocate memory for storing nodata value\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
+ memset(info->gdalbandtype, GDT_Unknown, sizeof(GDALDataType) * info->nband_count);
+ memset(info->bandtype, PT_END, sizeof(rt_pixtype) * info->nband_count);
+ memset(info->hasnodata, 0, sizeof(int) * info->nband_count);
+ memset(info->nodataval, 0, sizeof(double) * info->nband_count);
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ /* dimensions of raster */
+ info->dim[0] = GDALGetRasterXSize(hdsSrc);
+ info->dim[1] = GDALGetRasterYSize(hdsSrc);
- return 1;
-}
+ /* decide on tile size */
+ if (!config->tile_size[0])
+ info->tile_size[0] = info->dim[0];
+ else
+ info->tile_size[0] = config->tile_size[0];
+ if (!config->tile_size[1])
+ info->tile_size[1] = info->dim[1];
+ else
+ info->tile_size[1] = config->tile_size[1];
-static int
-analyze_table(
- const char *schema, const char *table,
- STRINGBUFFER *buffer
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ /* number of tiles */
+ if (
+ info->tile_size[0] != info->dim[0] &&
+ info->tile_size[1] != info->dim[1]
+ ) {
+ ntiles[0] = (info->dim[0] + info->tile_size[0] - 1) / info->tile_size[0];
+ ntiles[1] = (info->dim[1] + info->tile_size[1] - 1) / info->tile_size[1];
+ }
- assert(table != NULL);
+ /* go through bands for attributes */
+ for (i = 0; i < info->nband_count; i++) {
+ hbandSrc = GDALGetRasterBand(hdsSrc, info->nband[i]);
- len = strlen("ANALYZE ;") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
+ /* datatype */
+ info->gdalbandtype[i] = GDALGetRasterDataType(hbandSrc);
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for ANALYZE TABLE statement\n"));
- return 0;
+ /* complex data type? */
+ if (GDALDataTypeIsComplex(info->gdalbandtype[i])) {
+ fprintf(stderr, _("The pixel type of band %d is a complex data type. PostGIS Raster does not support complex data types\n"), i + 1);
+ GDALClose(hdsSrc);
+ return 0;
+ }
+
+ /* convert data type to that of postgis raster */
+ info->bandtype[i] = rt_util_gdal_datatype_to_pixtype(info->gdalbandtype[i]);
+
+ /* hasnodata and nodataval */
+ info->nodataval[i] = GDALGetRasterNoDataValue(hbandSrc, &(info->hasnodata[i]));
+ if (!info->hasnodata[i]) {
+ /* does NOT have nodata value, but user-specified */
+ if (config->hasnodata) {
+ info->hasnodata[i] = 1;
+ info->nodataval[i] = config->nodataval;
+ }
+ else
+ info->nodataval[i] = 0;
+ }
}
- sprintf(sql, "ANALYZE %s%s;",
- (schema != NULL ? schema : ""),
- table
- );
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ /* out-db raster */
+ if (config->outdb) {
+ rt_band band = NULL;
- return 1;
-}
+ GDALClose(hdsSrc);
-static int
-vacuum_table(
- const char *schema, const char *table,
- STRINGBUFFER *buffer
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ /* each tile is a raster */
+ for (ytile = 0; ytile < ntiles[1]; ytile++) {
+ for (xtile = 0; xtile < ntiles[0]; xtile++) {
+
+ /* compute tile's upper-left corner */
+ GDALApplyGeoTransform(
+ info->gt,
+ xtile * info->tile_size[0], ytile * info->tile_size[1],
+ &(gt[0]), &(gt[3])
+ );
- assert(table != NULL);
+ /* create raster object */
+ rast = rt_raster_new(info->tile_size[0], info->tile_size[1]);
+ if (rast == NULL) {
+ fprintf(stderr, _("Could not create raster\n"));
+ return 0;
+ }
- len = strlen("VACUUM ANALYZE ;") + 1;
- if (schema != NULL)
- len += strlen(schema);
- len += strlen(table);
+ /* set raster attributes */
+ rt_raster_set_srid(rast, config->srid);
+ rt_raster_set_geotransform_matrix(rast, gt);
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for VACUUM statement\n"));
- return 0;
- }
- sprintf(sql, "VACUUM ANALYZE %s%s;",
- (schema != NULL ? schema : ""),
- table
- );
+ /* add bands */
+ for (i = 0; i < info->nband_count; i++) {
+ band = rt_band_new_offline(
+ info->tile_size[0], info->tile_size[1],
+ info->bandtype[i],
+ info->hasnodata[i], info->nodataval[i],
+ info->nband[i] - 1,
+ config->rt_file[idx]
+ );
+ if (band == NULL) {
+ fprintf(stderr, _("Could not create offline band\n"));
+ raster_destroy(rast);
+ return 0;
+ }
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ /* add band to raster */
+ if (rt_raster_add_band(rast, band, rt_raster_get_num_bands(rast)) == -1) {
+ fprintf(stderr, _("Could not add offlineband to raster\n"));
+ rt_band_destroy(band);
+ raster_destroy(rast);
+ return 0;
+ }
+ }
- return 1;
-}
+ /* convert rt_raster to hexwkb */
+ hex = rt_raster_to_hexwkb(rast, &hexlen);
+ raster_destroy(rast);
-static int
-add_raster_constraints(
- const char *schema, const char *table, const char *column,
- int regular_blocking, int max_extent,
- STRINGBUFFER *buffer
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ /* add hexwkb to tileset */
+ append_stringbuffer(tileset, hex);
- char *_schema = NULL;
- char *_table = NULL;
- char *_column = NULL;
+ rtdealloc(hex);
- assert(table != NULL);
- assert(column != NULL);
+ /* flush if tileset gets too big */
+ if (tileset->length > 10) {
+ if (!insert_records(
+ config->schema, config->table, config->raster_column,
+ (config->file_column ? config->rt_filename[idx] : NULL), config->copy_statements,
+ tileset, buffer
+ )) {
+ fprintf(stderr, _("Cannot convert raster tiles into INSERT or COPY statements\n"));
+ return 0;
+ }
- if (schema != NULL) {
- char *tmp = chartrim(schema, ".");
- _schema = chartrim(tmp, "\"");
- rtdealloc(tmp);
+ rtdealloc_stringbuffer(tileset, 0);
+ }
+ }
+ }
}
- _table = chartrim(table, "\"");
- _column = chartrim(column, "\"");
+ /* in-db raster */
+ else {
+ VRTDatasetH hdsDst;
+ VRTSourcedRasterBandH hbandDst;
- len = strlen("SELECT AddRasterConstraints('','','',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE,FALSE);") + 1;
- if (_schema != NULL)
- len += strlen(_schema);
- len += strlen(_table);
- len += strlen(_column);
+ /* each tile is a VRT with constraints set for just the data required for the tile */
+ for (ytile = 0; ytile < ntiles[1]; ytile++) {
+ for (xtile = 0; xtile < ntiles[0]; xtile++) {
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for AddRasterConstraints statement\n"));
- return 0;
- }
- sprintf(sql, "SELECT AddRasterConstraints('%s','%s','%s',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,%s,TRUE,TRUE,TRUE,%s);",
- (_schema != NULL ? _schema : ""),
- _table,
- _column,
- (regular_blocking ? "TRUE" : "FALSE"),
- (max_extent ? "TRUE" : "FALSE")
- );
-
- if (_schema != NULL)
- rtdealloc(_schema);
- rtdealloc(_table);
- rtdealloc(_column);
+ /* compute tile's upper-left corner */
+ GDALApplyGeoTransform(
+ info->gt,
+ xtile * info->tile_size[0], ytile * info->tile_size[1],
+ &(gt[0]), &(gt[3])
+ );
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ /* create VRT dataset */
+ hdsDst = VRTCreate(info->tile_size[0], info->tile_size[1]);
+ GDALSetProjection(hdsDst, info->srs);
+ GDALSetGeoTransform(hdsDst, gt);
- return 1;
-}
+ /* add bands as simple sources */
+ for (i = 0; i < info->nband_count; i++) {
+ GDALAddBand(hdsDst, info->gdalbandtype[i], NULL);
+ hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, i + 1);
-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
-) {
- char *sql = NULL;
- uint32_t len = 0;
+ if (info->hasnodata[i])
+ GDALSetRasterNoDataValue(hbandDst, info->nodataval[i]);
- char *_ovschema = NULL;
- char *_ovtable = NULL;
- char *_ovcolumn = NULL;
+ VRTAddSimpleSource(
+ hbandDst, GDALGetRasterBand(hdsSrc, info->nband[i]),
+ xtile * info->tile_size[0], ytile * info->tile_size[1],
+ info->tile_size[0], info->tile_size[1],
+ 0, 0,
+ info->tile_size[0], info->tile_size[1],
+ "near", VRT_NODATA_UNSET
+ );
+ }
- char *_schema = NULL;
- char *_table = NULL;
- char *_column = NULL;
+ /* make sure VRT reflects all changes */
+ VRTFlushCache(hdsDst);
- assert(ovtable != NULL);
- assert(ovcolumn != NULL);
- assert(table != NULL);
- assert(column != NULL);
- assert(factor >= MINOVFACTOR && factor <= MAXOVFACTOR);
+ /* convert VRT dataset to rt_raster */
+ rast = rt_raster_from_gdal_dataset(hdsDst);
- if (ovschema != NULL) {
- char *tmp = chartrim(ovschema, ".");
- _ovschema = chartrim(tmp, "\"");
- rtdealloc(tmp);
- }
- _ovtable = chartrim(ovtable, "\"");
- _ovcolumn = chartrim(ovcolumn, "\"");
+ /* set srid if provided */
+ rt_raster_set_srid(rast, config->srid);
- if (schema != NULL) {
- char *tmp = chartrim(schema, ".");
- _schema = chartrim(tmp, "\"");
- rtdealloc(tmp);
- }
- _table = chartrim(table, "\"");
- _column = chartrim(column, "\"");
+ /* convert rt_raster to hexwkb */
+ hex = rt_raster_to_hexwkb(rast, &hexlen);
+ raster_destroy(rast);
- len = strlen("SELECT AddOverviewConstraints('','','','','','',);") + 5;
- if (_ovschema != NULL)
- len += strlen(_ovschema);
- len += strlen(_ovtable);
- len += strlen(_ovcolumn);
- if (_schema != NULL)
- len += strlen(_schema);
- len += strlen(_table);
- len += strlen(_column);
+ /* add hexwkb to tileset */
+ append_stringbuffer(tileset, hex);
- sql = rtalloc(sizeof(char) * len);
- if (sql == NULL) {
- fprintf(stderr, _("Could not allocate memory for AddOverviewConstraints statement\n"));
- return 0;
- }
- sprintf(sql, "SELECT AddOverviewConstraints('%s','%s','%s','%s','%s','%s',%d);",
- (_ovschema != NULL ? _ovschema : ""),
- _ovtable,
- _ovcolumn,
- (_schema != NULL ? _schema : ""),
- _table,
- _column,
- factor
- );
-
- if (_ovschema != NULL)
- rtdealloc(_ovschema);
- rtdealloc(_ovtable);
- rtdealloc(_ovcolumn);
+ rtdealloc(hex);
+ GDALClose(hdsDst);
- if (_schema != NULL)
- rtdealloc(_schema);
- rtdealloc(_table);
- rtdealloc(_column);
+ /* flush if tileset gets too big */
+ if (tileset->length > 10) {
+ if (!insert_records(
+ config->schema, config->table, config->raster_column,
+ (config->file_column ? config->rt_filename[idx] : NULL), config->copy_statements,
+ tileset, buffer
+ )) {
+ fprintf(stderr, _("Cannot convert raster tiles into INSERT or COPY statements\n"));
+ GDALClose(hdsSrc);
+ return 0;
+ }
- append_stringbuffer(buffer, sql);
- rtdealloc(sql);
+ rtdealloc_stringbuffer(tileset, 0);
+ }
+ }
+ }
+
+ GDALClose(hdsSrc);
+ }
return 1;
}
assert(config->raster_column != NULL);
if (config->transaction) {
- if (!append_stringbuffer(buffer, "BEGIN;")) {
+ if (!append_sql_to_buffer(buffer, "BEGIN;")) {
fprintf(stderr, _("Cannot add BEGIN statement to string buffer\n"));
return 0;
}
init_rastinfo(&rastinfo);
init_stringbuffer(&tileset);
+ if (config->copy_statements && !copy_from(
+ config->schema, config->table, config->raster_column,
+ (config->file_column ? config->rt_filename[i] : NULL),
+ buffer
+ )) {
+ fprintf(stderr, _("Cannot add COPY statement to string buffer\n"));
+ rtdealloc_rastinfo(&rastinfo);
+ rtdealloc_stringbuffer(&tileset, 0);
+ return 0;
+ }
+
/* convert raster */
- if (!convert_raster(i, config, &rastinfo, &tileset)) {
+ if (!convert_raster(i, config, &rastinfo, &tileset, buffer)) {
fprintf(stderr, _("Cannot process raster %s\n"), config->rt_file[i]);
rtdealloc_rastinfo(&rastinfo);
rtdealloc_stringbuffer(&tileset, 0);
}
/* process raster tiles into COPY or INSERT statements */
- if (!insert_records(
+ if (tileset.length && !insert_records(
config->schema, config->table, config->raster_column,
(config->file_column ? config->rt_filename[i] : NULL), config->copy_statements,
&tileset, buffer
rtdealloc_stringbuffer(&tileset, 0);
+ if (config->copy_statements && !copy_from_end(buffer)) {
+ fprintf(stderr, _("Cannot add COPY end statement to string buffer\n"));
+ rtdealloc_rastinfo(&rastinfo);
+ return 0;
+ }
+
/* flush buffer after every raster */
flush_stringbuffer(buffer);
/* overviews */
if (config->overview_count) {
int j = 0;
- STRINGBUFFER *ovset = NULL;
-
- /* build appropriate # of ovset */
- ovset = (STRINGBUFFER *) rtalloc(sizeof(struct stringbuffer_t) * config->overview_count);
- if (ovset == NULL) {
- fprintf(stderr, _("Cannot allocate memory for overview tiles\n"));
- rtdealloc_rastinfo(&rastinfo);
- return 0;
- }
- for (j = 0; j < config->overview_count; j++)
- init_stringbuffer(&(ovset[j]));
- if (!build_overviews(i, config, &rastinfo, ovset)) {
- fprintf(stderr, _("Cannot create overviews for raster %s\n"), config->rt_file[i]);
+ for (j = 0; j < config->overview_count; j++) {
- for (j = 0; j < config->overview_count; j++)
- rtdealloc_stringbuffer(&(ovset[j]), 0);
- rtdealloc(ovset);
+ if (config->copy_statements && !copy_from(
+ config->schema, config->overview_table[j], config->raster_column,
+ NULL,
+ buffer
+ )) {
+ fprintf(stderr, _("Cannot add COPY statement to string buffer\n"));
+ rtdealloc_rastinfo(&rastinfo);
+ rtdealloc_stringbuffer(&tileset, 0);
+ return 0;
+ }
- rtdealloc_rastinfo(&rastinfo);
- return 0;
- }
+ if (!build_overview(i, config, &rastinfo, config->overview[j], &tileset, buffer)) {
+ fprintf(stderr, _("Cannot create overview of factor %d for raster %s\n"), config->overview[j], config->rt_file[i]);
+ rtdealloc_rastinfo(&rastinfo);
+ rtdealloc_stringbuffer(&tileset, 0);
+ return 0;
+ }
- /* process overview tiles */
- for (j = 0; j < config->overview_count; j++) {
- if (!insert_records(
+ if (tileset.length && !insert_records(
config->schema, config->overview_table[j], config->raster_column,
NULL, config->copy_statements,
- &(ovset[j]), buffer
+ &tileset, buffer
)) {
fprintf(stderr, _("Cannot convert overview tiles into INSERT or COPY statements\n"));
-
- for (j = 0; j < config->overview_count; j++)
- rtdealloc_stringbuffer(&(ovset[j]), 0);
- rtdealloc(ovset);
-
rtdealloc_rastinfo(&rastinfo);
+ rtdealloc_stringbuffer(&tileset, 0);
return 0;
}
+ rtdealloc_stringbuffer(&tileset, 0);
+
/* flush buffer after every raster */
flush_stringbuffer(buffer);
- }
- /* free ovset */
- for (j = 0; j < config->overview_count; j++)
- rtdealloc_stringbuffer(&(ovset[j]), 0);
- rtdealloc(ovset);
+ if (config->copy_statements) {
+ if (!copy_from_end(buffer)) {
+ fprintf(stderr, _("Cannot add COPY end statement to string buffer\n"));
+ rtdealloc_rastinfo(&rastinfo);
+ return 0;
+ }
+ }
+ }
}
rtdealloc_rastinfo(&rastinfo);
}
if (config->transaction) {
- if (!append_stringbuffer(buffer, "END;")) {
+ if (!append_sql_to_buffer(buffer, "END;")) {
fprintf(stderr, _("Cannot add END statement to string buffer\n"));
return 0;
}