33 from __future__
import print_function
34 from osgeo
import gdal
36 import osgeo.gdalconst
as gdalc
37 from optparse
import OptionParser, OptionGroup
66 g_rt_schema =
'public'
74 if sys.hexversion < 0x02060000:
75 return str(float(x)).lower() ==
'nan'
80 """Collects, parses and validates command line arguments."""
82 prs = OptionParser(version=
"%prog $Revision$")
85 grp0 = OptionGroup(prs,
"Source and destination",
86 "*** Mandatory parameters always required ***")
87 grp0.add_option(
"-r",
"--raster", dest=
"raster", action=
"append", default=
None,
88 help=
"append raster to list of input files, at least one raster "
89 "file required. You may use wildcards (?,*) for specifying multiple files.")
90 grp0.add_option(
"-t",
"--table", dest=
"table", action=
"store", default=
None,
91 help=
"raster destination in form of [<schema>.]<table> or base raster table for overview level>1, required")
92 prs.add_option_group(grp0);
95 grp_r = OptionGroup(prs,
"Raster processing",
96 "Optional parameters used to manipulate input raster dataset")
97 grp_r.add_option(
"-s",
"--srid", dest=
"srid", action=
"store", type=
"int", default=-1,
98 help=
"assign output raster with specified SRID")
99 grp_r.add_option(
"-b",
"--band", dest=
"band", action=
"store", type=
"int", default=
None,
100 help=
"specify number of the band to be extracted from raster file")
101 grp_r.add_option(
"-k",
"--block-size", dest=
"block_size", action=
"store", default=
None,
102 help=
"cut raster(s) into tiles to be inserted one by table row."
103 "BLOCK_SIZE is expressed as WIDTHxHEIGHT. Incomplete tiles are completed with nodata values")
104 grp_r.add_option(
"-R",
"--register", dest=
"register", action=
"store_true", default=
False,
105 help=
"register the raster as a filesystem (out-db) raster")
106 grp_r.add_option(
"-l",
"--overview-level", dest=
"overview_level", action=
"store", type=
"int", default=1,
107 help=
'create overview tables named as o_<LEVEL>_<RASTER_TABLE> and '
108 'populate with GDAL-provided overviews (regular blocking only)')
109 prs.add_option_group(grp_r);
112 grp_t = OptionGroup(prs,
'Database processing',
113 'Optional parameters used to manipulate database objects')
114 grp_t.add_option(
'-c',
'--create', dest=
'create_table', action=
'store_true', default=
False,
115 help=
'create new table and populate it with raster(s), this is the default mode')
116 grp_t.add_option(
'-a',
'--append', dest=
'append_table', action=
'store_true', default=
False,
117 help=
'append raster(s) to an existing table')
118 grp_t.add_option(
"-d",
"--drop", dest=
"drop_table", action=
"store_true", default=
False,
119 help=
"drop table, create new one and populate it with raster(s)")
120 grp_t.add_option(
"-f",
"--field", dest=
"column", action=
"store", default=g_rt_column,
121 help=
"specify name of destination raster column, default is 'rast'")
122 grp_t.add_option(
"-F",
"--filename", dest=
"filename", action=
"store_true", default=
False,
123 help=
"add a column with the name of the file")
124 grp_t.add_option(
"-I",
"--index", dest=
"index", action=
"store_true", default=
False,
125 help=
"create a GiST index on the raster column")
126 grp_t.add_option(
"-M",
"--vacuum", dest=
"vacuum", action=
"store_true", default=
False,
127 help=
"issue VACUUM command against all generated tables")
128 grp_t.add_option(
'-V',
'--create-raster-overviews', dest=
'create_raster_overviews_table',
129 action=
'store_true', default=
False,
130 help=
'create RASTER_OVERVIEWS table used to store overviews metadata')
131 prs.add_option_group(grp_t);
134 grp_u = OptionGroup(prs,
"Miscellaneous",
"Other optional parameters")
135 grp_u.add_option(
"-e",
"--endian", dest=
"endian", action=
"store", type=
"int", default=g_rt_endian,
136 help=
"control endianness of generated binary output of raster; "
137 "specify 0 for XDR and 1 for NDR (default); "
138 "only NDR output is supported now")
139 grp_u.add_option(
"-w",
"--raster-version", dest=
"version",
140 action=
"store", type=
"int", default=g_rt_version,
141 help=
"specify version of raster protocol, default is 0; "
142 "only value of zero is supported now")
143 grp_u.add_option(
"-o",
"--output", dest=
"output", action=
"store", default=sys.stdout,
144 help=
"specify output file, otherwise send to stdout")
145 grp_u.add_option(
"-v",
"--verbose", dest=
"verbose", action=
"store_true", default=
False,
146 help=
"verbose mode. Useful for debugging")
147 prs.add_option_group(grp_u);
149 (opts, args) = prs.parse_args()
152 if opts.create_table
and opts.drop_table
and opts.append_table:
153 prs.error(
"options -c, -a and -d are mutually exclusive")
154 if opts.create_table
and opts.drop_table:
155 prs.error(
"options -c and -d are mutually exclusive")
156 if opts.create_table
and opts.append_table:
157 prs.error(
"options -c and -a are mutually exclusive")
158 if opts.append_table
and opts.drop_table:
159 prs.error(
"options -a and -d are mutually exclusive")
160 if (
not opts.create_table
and not opts.drop_table
and not opts.append_table)
or opts.drop_table:
161 opts.create_table =
True
163 if opts.raster
is None:
164 prs.error(
"use option -r to specify at least one input raster. Wildcards (?,*) are accepted.")
166 if opts.block_size
is not None and len(opts.raster) != 1:
167 prs.error(
"regular blocking supports single-raster input only")
169 if opts.block_size
is not None:
170 if len(opts.block_size.split(
'x')) != 2
and len(opts.block_size.split(
'X')) != 2:
171 prs.error(
"invalid format of block size, expected WIDTHxHEIGHT")
173 if opts.overview_level > 1
and opts.block_size
is None:
174 prs.error(
"regular blocking mode required to enable overviews support (level > 1)")
176 if opts.create_raster_overviews_table
and opts.overview_level <= 1:
177 prs.error(
'create table for RASTER_OVERVIEWS available only if overviews import requested')
184 if opts.table
is None:
185 prs.error(
"use option -t to specify raster destination table")
186 if len(opts.table.split(
'.')) > 2:
187 prs.error(
"invalid format of table name specified with option -t, expected [<schema>.]table")
189 if opts.output
is None:
190 prs.error(
"failed to initialise output file, try to use option -o explicitly")
192 if opts.version
is not None:
193 if opts.version != g_rt_version:
194 prs.error(
"invalid version of WKT Raster protocol specified, only version 0 is supported")
196 prs.error(
"use option -w to specify version of WKT Raster protocol")
198 if opts.endian
is not None:
199 if opts.endian != NDR
and opts.endian != XDR:
200 prs.error(
"invalid endianness value, valid ones are 0 for NDR or 1 for XDR")
202 prs.error(
"use option -e to specify endianness of binary output")
208 """If verbose mode requested, sends extra progress information to stderr"""
210 sys.stderr.write(msg)
214 """Translate GDAL data type to WKT Raster pixel type."""
216 gdalc.GDT_Byte : {
'name':
'PT_8BUI',
'id': 4 },
217 gdalc.GDT_Int16 : {
'name':
'PT_16BSI',
'id': 5 },
218 gdalc.GDT_UInt16 : {
'name':
'PT_16BUI',
'id': 6 },
219 gdalc.GDT_Int32 : {
'name':
'PT_32BSI',
'id': 7 },
220 gdalc.GDT_UInt32 : {
'name':
'PT_32BUI',
'id': 8 },
221 gdalc.GDT_Float32 : {
'name':
'PT_32BF',
'id': 10 },
222 gdalc.GDT_Float64 : {
'name':
'PT_64BF',
'id': 11 }
229 return pixtypes.get(gdt, 13)
232 """Translate GDAL data type to NumPy data type"""
234 gdalc.GDT_Byte : numpy.uint8,
235 gdalc.GDT_Int16 : numpy.int16,
236 gdalc.GDT_UInt16 : numpy.uint16,
237 gdalc.GDT_Int32 : numpy.int32,
238 gdalc.GDT_UInt32 : numpy.uint32,
239 gdalc.GDT_Float32: numpy.float32,
240 gdalc.GDT_Float64: numpy.float64
242 return ptnumpy.get(pt, numpy.uint8)
245 """Returns binary data type specifier for given pixel type."""
255 return fmttypes.get(pt,
'x')
259 """Returns printf-like formatter for given binary data type sepecifier."""
270 return fmttypes.get(fmt,
'f')
273 assert options
is not None
274 assert options.block_size
is not None
276 wh = options.block_size.split(
'x')
278 wh = options.block_size.split(
'X')
280 assert len(wh) == 2,
"invalid format of specified block size"
281 return ( int(wh[0]), int(wh[1]) )
287 assert value
is not None,
"None value given"
289 if len(value) > 0
and value[0] !=
"'" and value[:-1] !=
"'":
290 sql =
"'" +
str(value) +
"'"
296 assert name
is not None,
"None name given"
298 if name[0] !=
"\"" and name[:-1] !=
"\"":
299 sql =
"\"" +
str(name) +
"\""
307 if isinstance(v, str):
316 st = schema_table.split(
'.')
319 st.insert(0,
"public")
320 assert len(st) == 2,
"Invalid format of table name, expected [<schema>.]table"
321 return (st[0], st[1])
325 table =
"\"%s\".\"%s\"" % (st[0], st[1])
329 st = schema_table.split(
'.')
330 assert len(st) == 1
or len(st) == 2,
"Invalid format of table name, expected [<schema>.]table"
336 sql =
"DROP TABLE IF EXISTS %s CASCADE;\n" \
338 logit(
"SQL: %s" % sql)
345 target =
"'', '%s'" % st[1]
347 target =
"'%s', '%s'" % (st[0], st[1])
348 sql =
"SELECT DropRasterTable(%s);\n" % target
349 logit(
"SQL: %s" % sql)
356 table = options.table
359 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY, \"filename\" text);\n" \
362 if options.overview_level > 1
and is_overview:
363 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY, %s RASTER);\n" \
366 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY);\n" \
369 logit(
"SQL: %s" % sql)
376 logit(
"MSG: Create GiST spatial index on %s\n" % gist_table)
378 sql =
"CREATE INDEX \"%s_%s_gist_idx\" ON %s USING GIST (st_convexhull(%s));\n" % \
379 (gist_table, column, target_table, column)
380 logit(
"SQL: %s" % sql)
385 assert len(pixeltypes) > 0,
"No pixel types given"
390 if nodata
is not None and len(nodata) > 0:
399 bs = (
'null',
'null' )
401 if options.block_size
is not None:
402 assert pixelsize
is not None,
"Pixel size is none, but regular blocking requested"
403 assert blocksize
is not None,
"Block size is none, but regular blocking requested"
404 assert extent
is not None,
"Extent is none, but regular blocking requested"
405 assert len(pixelsize) == 2,
"Invalid pixel size, two values expected"
406 assert len(blocksize) == 2,
"Invalid block size, two values expected"
407 assert len(extent) == 4,
"Invalid extent, four coordinates expected"
408 assert len(extent[0]) == len(extent[3]) == 2,
"Invalid extent, pair of X and Y pair expected"
410 bs = ( blocksize[0], blocksize[1] )
411 extgeom =
"ST_Envelope(ST_SetSRID('POLYGON((%.15f %.15f,%.15f %.15f,%.15f %.15f,%.15f %.15f,%.15f %.15f))'::geometry, %d))" % \
412 (extent[0][0], extent[0][1], extent[1][0], extent[1][1],
413 extent[2][0], extent[2][1], extent[3][0], extent[3][1],
414 extent[0][0], extent[0][1], options.srid)
416 sql =
"SELECT AddRasterColumn('%s','%s','%s',%d, %s, %s, %s, %s, %.15f, %.15f, %s, %s, %s);\n" % \
417 (ts[0], ts[1], options.column, options.srid, pt, odb, rb, nd,
418 pixelsize[0], pixelsize[1], bs[0], bs[1], extgeom)
420 logit(
"SQL: %s" % sql)
425 assert file
is not None,
"Missing filename, but insert_filename requested"
426 sql =
"INSERT INTO %s ( filename, %s ) VALUES ( (\'%s\')::text, (\'%s\')::raster );\n" \
429 sql =
"INSERT INTO %s ( %s ) VALUES ( (\'%s\')::raster );\n" \
439 sql =
'CREATE TABLE ' + table +
' ( ' \
440 'o_table_catalog character varying(256) NOT NULL, ' \
441 'o_table_schema character varying(256) NOT NULL, ' \
442 'o_table_name character varying(256) NOT NULL, ' \
443 'o_column character varying(256) NOT NULL, ' \
444 'r_table_catalog character varying(256) NOT NULL, ' \
445 'r_table_schema character varying(256) NOT NULL, ' \
446 'r_table_name character varying(256) NOT NULL, ' \
447 'r_column character varying(256) NOT NULL, ' \
448 'out_db boolean NOT NULL, ' \
449 'overview_factor integer NOT NULL, ' \
450 'CONSTRAINT raster_overviews_pk ' \
451 'PRIMARY KEY (o_table_catalog, o_table_schema, o_table_name, o_column, overview_factor));\n'
457 assert len(ov_table) > 0
464 sql =
"INSERT INTO public.raster_overviews( " \
465 "o_table_catalog, o_table_schema, o_table_name, o_column, " \
466 "r_table_catalog, r_table_schema, r_table_name, r_column, out_db, overview_factor) " \
467 "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', FALSE, %d);\n" % \
468 (catalog, schema, ov_table, options.column, catalog, schema, r_table, options.column, ov_factor)
480 assert ds
is not None
482 if band_from
is None:
485 band_to = ds.RasterCount
487 assert band_to <= ds.RasterCount,
'Failed checking band_to=%d <= RasterCount=%d' % (band_to,ds.RasterCount)
488 assert band_from <= band_to
491 for i
in range(band_from, band_to + 1):
492 n = ds.GetRasterBand(i).GetOverviewCount()
495 assert n == nov,
'Number of raster overviews is not the same for all bands'
500 assert ds
is not None
504 band = ds.GetRasterBand(1)
505 assert band
is not None
506 assert overview < band.GetOverviewCount()
508 ov_band = band.GetOverview(overview)
509 assert ov_band
is not None
511 ovf = int(0.5 + ds.RasterXSize / float(ov_band.XSize))
512 logit(
'MSG: Overview factor = %d\n' % ovf)
518 """Collect pixel types of bands in requested range.
519 Use names of pixel types in format as returned
520 by rt_core function rt_pixtype_name()"""
523 for i
in range(band_from, band_to):
524 band = ds.GetRasterBand(i)
525 pixel_type =
gdt2pt(band.DataType)[
'name'][3:]
526 pt.append(pixel_type)
531 """Collect nodata values of bands in requested range"""
534 for i
in range(band_from, band_to):
535 band = ds.GetRasterBand(i)
536 nodata = band.GetNoDataValue()
537 if nodata
is not None and not is_nan(nodata):
543 """Size of natural block reported by GDAL for bands of given dataset"""
546 for i
in range(band_from, band_to):
547 band = ds.GetRasterBand(i)
548 assert band
is not None,
"Cannot access raster band %d" % i
549 dims = band.GetBlockSize()
556 if block_dims != dims:
557 logit(
"MSG: Block sizes don't match: %s != %s\n" % (
str(block_dims),
str(dims)))
559 assert block_dims
is not None,
"Failed to calculate block size"
560 return (int(block_dims[0]), int(block_dims[1]))
563 """Dimensions of grid made up with blocks of requested size"""
566 nx = float(raster_size[0]) / float(block_size[0])
567 ny = float(raster_size[1]) / float(block_size[1])
569 return ( int(math.ceil(nx)), int(math.ceil(ny)))
572 """Calculates number of columns [0] and rows [1] of padding"""
573 assert band
is not None
577 block_bound = ( xoff + block_size[0], yoff + block_size[1] )
579 if block_bound[0] > band.XSize:
580 xpad = block_bound[0] - band.XSize
581 if block_bound[1] > band.YSize:
582 ypad = block_bound[1] - band.YSize
587 assert ds
is not None
588 gt = list(ds.GetGeoTransform())
592 """Calculate georeferenced coordinate from given x and y"""
593 assert gt
is not None
594 assert xy
is not None
597 xgeo = gt[0] + gt[1] * xy[0] + gt[2] * xy[1];
598 ygeo = gt[3] + gt[4] * xy[0] + gt[5] * xy[1];
605 newgt = ( gt[0], gt[1] * float(level), gt[2], gt[3], gt[4], gt[5] * float(level) )
610 """Calculate georeferenced coordinates of spatial extent of raster dataset"""
611 assert ds
is not None
614 dim = ( (0,0),(0,ds.RasterYSize),(ds.RasterXSize,0),(ds.RasterXSize,ds.RasterYSize) )
622 assert hex
is not None,
"Error: Missing hex string"
624 assert size > 0,
"Error: hex string is empty"
625 assert size % 2 == 0,
"Error: invalid size of hex string"
626 if bytes_size
is not None:
628 assert n == bytes_size,
"Error: invalid number of bytes %d, expected %d" % (n, bytes_size)
631 assert pixels.ndim == 2
632 print(
'BEGIN BLOCK SCANLINES (numpy): (%d, %d)' %(len(pixels[0]), len(pixels)))
635 for row
in range (0, len(pixels)):
636 s = binascii.hexlify(pixels[row])
637 print(
'%d (%d)\t%s' % (i, (len(s) / 2), s))
640 print(
'END BLOCK SCANLINES')
643 assert band
is not None
646 if band.GetNoDataValue()
is not None:
647 nodata = band.GetNoDataValue()
649 logit(
"WARNING: No nodata flagged in raster_columns metadata. "
650 "In serialized raster, nodata bytes will have value of 0.\n")
654 """Writes raw binary data into HEX-encoded string using binascii module."""
658 fmt_little =
'<' +fmt
659 hexstr = binascii.hexlify(struct.pack(fmt_little, data)).upper()
664 logit(
'HEX (\'fmt=%s\', bytes=%d, val=%s):\t\t%s\n' \
665 % (fmt, len(hexstr) / 2,
str(val), hexstr))
670 """Writes WKT Raster header based on given GDAL into HEX-encoded WKB."""
671 assert ds
is not None,
"Error: Missing GDAL dataset"
673 assert len(ulp) == 2,
"Error: invalid upper-left corner"
675 if xsize
is None or ysize
is None:
676 assert xsize
is None and ysize
is None
677 xsize = ds.RasterXSize
678 ysize = ds.RasterYSize
683 rt_ip = ( ul[0], ul[1] )
684 rt_skew = ( gt[2], gt[4] )
685 rt_scale = ( gt[1] * level, gt[5] * level )
694 hexwkb +=
wkblify(
'B', options.endian)
696 hexwkb +=
wkblify(
'H', options.version)
698 if options.band
is not None and options.band > 0:
701 hexwkb +=
wkblify(
'H', ds.RasterCount)
704 hexwkb +=
wkblify(
'd', rt_scale[0])
705 hexwkb +=
wkblify(
'd', rt_scale[1])
706 hexwkb +=
wkblify(
'd', rt_ip[0])
707 hexwkb +=
wkblify(
'd', rt_ip[1])
708 hexwkb +=
wkblify(
'd', rt_skew[0])
709 hexwkb +=
wkblify(
'd', rt_skew[1])
710 hexwkb +=
wkblify(
'i', options.srid)
717 logit(
"MSG: Georeference: px = %s -> ul = %s \tresolution = %s \trotation = %s\n" \
722 """Writes band header into HEX-encoded WKB"""
723 assert band
is not None,
"Error: Missing GDAL raster band"
733 nodata = band.GetNoDataValue()
735 if nodata
is not None:
741 pixtype =
gdt2pt(band.DataType)[
'id']
742 hexwkb +=
wkblify(
'B', pixtype + first4bits)
750 def wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, bandidx):
751 """Writes band of given GDAL dataset into HEX-encoded WKB for WKT Raster output."""
752 assert band
is not None,
"Error: Missing GDAL raster band"
762 hexwkb +=
wkblify(
'B', bandidx - 1)
763 filepath = os.path.abspath(infile.replace(
'\\',
'\\\\'))
764 logit(
'MSG: Out-db raster path=%s\n' % filepath)
765 hexwkb +=
wkblify(
str(len(filepath)) +
's', filepath)
773 valid_read_block_size = ( read_block_size[0] - read_padding_size[0],
774 read_block_size[1] - read_padding_size[1] )
777 if read_padding_size[0] > 0
or read_padding_size[1] > 0:
778 target_block_size = (valid_read_block_size[0] / level, valid_read_block_size[1] / level)
779 target_padding_size = (read_padding_size[0] / level, read_padding_size[1] / level)
781 target_block_size = block_size
782 target_padding_size = ( 0, 0 )
784 logit(
'MSG: Normalize read_block=%s for level=%d to valid_read_block=%s with padding=%s\n' % \
785 (read_block_size, level, valid_read_block_size, read_padding_size))
786 logit(
'MSG: Normalize target_block=%s for level=%d to valid_target_block=%s with padding=%s\n' % \
787 (block_size, level, target_block_size, target_padding_size))
788 logit(
'MSG: ReadAsArray( %d, %d, %s, %s)\n' % \
789 (xoff, yoff,
str(valid_read_block_size),
str(target_block_size)))
791 assert valid_read_block_size[0] > 0
and valid_read_block_size[1] > 0
792 assert target_block_size[0] > 0
and target_block_size[1] > 0
794 pixels = band.ReadAsArray(xoff, yoff, valid_read_block_size[0], valid_read_block_size[1],
795 target_block_size[0], target_block_size[1])
800 out_pixels = numpy.zeros((block_size[1], block_size[0]),
pt2numpy(band.DataType))
802 logit(
'MSG: Read valid source:\t%d x %d\n' % (len(pixels[0]), len(pixels)))
803 logit(
'MSG: Write into block:\t%d x %d\n' % (len(out_pixels[0]), len(out_pixels)))
805 if target_padding_size[0] > 0
or target_padding_size[1] > 0:
807 ysize_read_pixels = len(pixels)
811 pad_cols = numpy.array([nodata_value] * target_padding_size[0])
812 for row
in range (0, ysize_read_pixels):
813 out_line = numpy.append(pixels[row], pad_cols)
814 out_pixels[row] = out_line
817 for row
in range(ysize_read_pixels, ysize_read_pixels + target_padding_size[1]):
818 out_pixels[row].
fill(nodata_value)
825 hexwkb = binascii.hexlify(out_pixels)
831 assert ds
is not None
833 assert len(band_range) == 2
835 band_from = band_range[0]
836 band_to = band_range[1]
839 raster_size = ( ds.RasterXSize, ds.RasterYSize )
840 if options.block_size
is not None:
842 read_block_size = ( block_size[0] * level, block_size[1] * level)
845 block_size = raster_size
846 read_block_size = block_size
849 logit(
"MSG: Processing raster=%s using read_block_size=%s block_size=%s of grid=%s in level=%d\n" % \
850 (
str(raster_size),
str(read_block_size),
str(block_size),
str(grid_size), level))
854 if i == 0
and options.create_table:
856 pixel_size = ( gt[1], gt[5] )
861 pixel_size, block_size, extent)
862 options.output.write(sql)
863 gen_table = options.table
870 level_table_name =
'o_' +
str(level) +
'_' + schema_table_names[1]
871 level_table = schema_table_names[0] +
'.' + level_table_name
874 options.output.write(sql)
876 options.output.write(sql)
877 gen_table = level_table
883 for ycell
in range(0, grid_size[1]):
884 for xcell
in range(0, grid_size[0]):
886 xoff = xcell * read_block_size[0]
887 yoff = ycell * read_block_size[1]
889 logit(
"MSG: --------- CELL #%04d\tindex = %d x %d\tdim = (%d x %d)\t(%d x %d) \t---------\n" % \
890 (tile_count, xcell, ycell, xoff, yoff, xoff + read_block_size[0], yoff + read_block_size[1]))
892 if options.block_size
is not None:
895 block_size[0], block_size[1])
899 for b
in range(band_from, band_to):
900 band = ds.GetRasterBand(b)
901 assert band
is not None,
"Missing GDAL raster band %d" % b
902 logit(
"MSG: Band %d\n" % b)
905 hexwkb +=
wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, b)
910 options.output.write(sql)
912 tile_count = tile_count + 1
914 return (gen_table, tile_count)
917 """Writes given raster dataset using GDAL features into HEX-encoded of
918 WKB for WKT Raster output."""
920 assert infile
is not None,
"Input file is none, expected file name"
921 assert options.version == g_rt_version,
"Error: invalid WKT Raster protocol version"
922 assert options.endian == NDR,
"Error: invalid endianness, use little-endian (NDR) only"
923 assert options.srid >= -1,
"Error: do you really want to specify SRID = %d" % options.srid
926 ds = gdal.Open(infile, gdalc.GA_ReadOnly);
928 sys.exit(
'Error: Cannot open input file: ' +
str(infile))
933 if options.band
is not None and options.band > 0:
934 band_range = ( options.band, options.band + 1 )
936 band_range = ( 1, ds.RasterCount + 1 )
940 if previous_gt
is not None:
941 if previous_gt[1] != current_gt[1]
or previous_gt[5] != current_gt[5]:
942 sys.exit(
'Error: Cannot load raster with different pixel size in the same raster table')
946 SUMMARY.append( summary )
960 VERBOSE = opts.verbose
965 saved_out = sys.stdout
966 if isinstance(opts.output, str):
967 filename = opts.output
968 opts.output = open(filename,
"w")
971 opts.output.write(
'BEGIN;\n')
974 if opts.create_raster_overviews_table:
976 opts.output.write(sql)
979 if opts.overview_level == 1:
983 opts.output.write(sql)
986 if opts.create_table
and opts.overview_level == 1:
988 opts.output.write(sql)
995 for infile
in opts.raster:
996 filelist = glob.glob(infile)
997 assert len(filelist) > 0,
"No input raster files found for '" +
str(infile) +
"'"
999 for filename
in filelist:
1000 logit(
"MSG: Dataset #%d: %s\n" % (i + 1, filename))
1007 if opts.index
and SUMMARY
is not None:
1009 opts.output.write(sql)
1012 opts.output.write(
'END;\n')
1015 if opts.vacuum
and SUMMARY
is not None:
1017 opts.output.write(sql)
1020 if opts.output != sys.stdout:
1021 sys.stdout = saved_out
1023 print(
"------------------------------------------------------------")
1024 print(
" Summary of GDAL to PostGIS Raster processing:")
1025 print(
"------------------------------------------------------------")
1027 m =
'%d (%s)' % (i, infile)
1030 print(
"Number of processed raster files: " + m)
1031 print(
"List of generated tables (number of tiles):")
1035 print(
"%d\t%s (%d)" % (i, s[0], s[1]))
1039 if __name__ ==
"__main__":
def check_hex(hex, bytes_size=None)
def make_sql_value_array(values)
def make_sql_create_table(options, table=None, is_overview=False)
def make_sql_drop_table(table)
def calculate_overview_factor(ds, overview)
def make_sql_insert_raster(table, rast, hexwkb, insert_filename, file)
def make_sql_full_table_name(schema_table)
def make_sql_vacuum(table)
def wkblify_raster_level(options, ds, level, band_range, infile, i)
def make_sql_drop_raster_table(table)
def wkblify_raster_header(options, ds, level, ulp, xsize=None, ysize=None)
def calculate_block_size(ds, band_from, band_to)
def parse_block_size(options)
def calculate_block_pad_size(band, xoff, yoff, block_size)
def make_sql_create_gist(table, column)
def wkblify_band_header(options, band)
def make_sql_table_name(schema_table)
def calculate_geoxy(gt, xy)
def calculate_geoxy_level(gt, xy, level)
def make_sql_register_overview(options, ov_table, ov_factor)
def get_gdal_geotransform(ds)
def make_sql_addrastercolumn(options, pixeltypes, nodata, pixelsize, blocksize, extent)
def make_sql_schema_table_names(schema_table)
def quote_sql_value(value)
SQL OPERATIONS.
def fetch_band_nodata(band, default=0)
def calculate_overviews(ds, band_from=None, band_to=None)
RASTER OPERATIONS.
def calculate_bounding_box(ds, gt)
def calculate_grid_size(raster_size, block_size)
def collect_nodata_values(ds, band_from, band_to)
def wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, bandidx)
def dump_block_numpy(pixels)
def make_sql_create_raster_overviews(options)
def collect_pixel_types(ds, band_from, band_to)
def wkblify_raster(options, infile, i, previous_gt=None)