33 from osgeo
import gdal
35 import osgeo.gdalconst
as gdalc
36 from optparse
import OptionParser, OptionGroup
65 g_rt_schema =
'public'
73 if sys.hexversion < 0x02060000:
74 return str(float(x)).lower() ==
'nan'
79 """Collects, parses and validates command line arguments."""
81 prs = OptionParser(version=
"%prog $Revision$")
84 grp0 = OptionGroup(prs,
"Source and destination",
85 "*** Mandatory parameters always required ***")
86 grp0.add_option(
"-r",
"--raster", dest=
"raster", action=
"append", default=
None,
87 help=
"append raster to list of input files, at least one raster "
88 "file required. You may use wildcards (?,*) for specifying multiple files.")
89 grp0.add_option(
"-t",
"--table", dest=
"table", action=
"store", default=
None,
90 help=
"raster destination in form of [<schema>.]<table> or base raster table for overview level>1, required")
91 prs.add_option_group(grp0);
94 grp_r = OptionGroup(prs,
"Raster processing",
95 "Optional parameters used to manipulate input raster dataset")
96 grp_r.add_option(
"-s",
"--srid", dest=
"srid", action=
"store", type=
"int", default=-1,
97 help=
"assign output raster with specified SRID")
98 grp_r.add_option(
"-b",
"--band", dest=
"band", action=
"store", type=
"int", default=
None,
99 help=
"specify number of the band to be extracted from raster file")
100 grp_r.add_option(
"-k",
"--block-size", dest=
"block_size", action=
"store", default=
None,
101 help=
"cut raster(s) into tiles to be inserted one by table row."
102 "BLOCK_SIZE is expressed as WIDTHxHEIGHT. Incomplete tiles are completed with nodata values")
103 grp_r.add_option(
"-R",
"--register", dest=
"register", action=
"store_true", default=
False,
104 help=
"register the raster as a filesystem (out-db) raster")
105 grp_r.add_option(
"-l",
"--overview-level", dest=
"overview_level", action=
"store", type=
"int", default=1,
106 help=
'create overview tables named as o_<LEVEL>_<RASTER_TABLE> and '
107 'populate with GDAL-provided overviews (regular blocking only)')
108 prs.add_option_group(grp_r);
111 grp_t = OptionGroup(prs,
'Database processing',
112 'Optional parameters used to manipulate database objects')
113 grp_t.add_option(
'-c',
'--create', dest=
'create_table', action=
'store_true', default=
False,
114 help=
'create new table and populate it with raster(s), this is the default mode')
115 grp_t.add_option(
'-a',
'--append', dest=
'append_table', action=
'store_true', default=
False,
116 help=
'append raster(s) to an existing table')
117 grp_t.add_option(
"-d",
"--drop", dest=
"drop_table", action=
"store_true", default=
False,
118 help=
"drop table, create new one and populate it with raster(s)")
119 grp_t.add_option(
"-f",
"--field", dest=
"column", action=
"store", default=g_rt_column,
120 help=
"specify name of destination raster column, default is 'rast'")
121 grp_t.add_option(
"-F",
"--filename", dest=
"filename", action=
"store_true", default=
False,
122 help=
"add a column with the name of the file")
123 grp_t.add_option(
"-I",
"--index", dest=
"index", action=
"store_true", default=
False,
124 help=
"create a GiST index on the raster column")
125 grp_t.add_option(
"-M",
"--vacuum", dest=
"vacuum", action=
"store_true", default=
False,
126 help=
"issue VACUUM command against all generated tables")
127 grp_t.add_option(
'-V',
'--create-raster-overviews', dest=
'create_raster_overviews_table',
128 action=
'store_true', default=
False,
129 help=
'create RASTER_OVERVIEWS table used to store overviews metadata')
130 prs.add_option_group(grp_t);
133 grp_u = OptionGroup(prs,
"Miscellaneous",
"Other optional parameters")
134 grp_u.add_option(
"-e",
"--endian", dest=
"endian", action=
"store", type=
"int", default=g_rt_endian,
135 help=
"control endianness of generated binary output of raster; "
136 "specify 0 for XDR and 1 for NDR (default); "
137 "only NDR output is supported now")
138 grp_u.add_option(
"-w",
"--raster-version", dest=
"version",
139 action=
"store", type=
"int", default=g_rt_version,
140 help=
"specify version of raster protocol, default is 0; "
141 "only value of zero is supported now")
142 grp_u.add_option(
"-o",
"--output", dest=
"output", action=
"store", default=sys.stdout,
143 help=
"specify output file, otherwise send to stdout")
144 grp_u.add_option(
"-v",
"--verbose", dest=
"verbose", action=
"store_true", default=
False,
145 help=
"verbose mode. Useful for debugging")
146 prs.add_option_group(grp_u);
148 (opts, args) = prs.parse_args()
151 if opts.create_table
and opts.drop_table
and opts.append_table:
152 prs.error(
"options -c, -a and -d are mutually exclusive")
153 if opts.create_table
and opts.drop_table:
154 prs.error(
"options -c and -d are mutually exclusive")
155 if opts.create_table
and opts.append_table:
156 prs.error(
"options -c and -a are mutually exclusive")
157 if opts.append_table
and opts.drop_table:
158 prs.error(
"options -a and -d are mutually exclusive")
159 if (
not opts.create_table
and not opts.drop_table
and not opts.append_table)
or opts.drop_table:
160 opts.create_table =
True
162 if opts.raster
is None:
163 prs.error(
"use option -r to specify at least one input raster. Wildcards (?,*) are accepted.")
165 if opts.block_size
is not None and len(opts.raster) != 1:
166 prs.error(
"regular blocking supports single-raster input only")
168 if opts.block_size
is not None:
169 if len(opts.block_size.split(
'x')) != 2
and len(opts.block_size.split(
'X')) != 2:
170 prs.error(
"invalid format of block size, expected WIDTHxHEIGHT")
172 if opts.overview_level > 1
and opts.block_size
is None:
173 prs.error(
"regular blocking mode required to enable overviews support (level > 1)")
175 if opts.create_raster_overviews_table
and opts.overview_level <= 1:
176 prs.error(
'create table for RASTER_OVERVIEWS available only if overviews import requested')
183 if opts.table
is None:
184 prs.error(
"use option -t to specify raster destination table")
185 if len(opts.table.split(
'.')) > 2:
186 prs.error(
"invalid format of table name specified with option -t, expected [<schema>.]table")
188 if opts.output
is None:
189 prs.error(
"failed to initialise output file, try to use option -o explicitly")
191 if opts.version
is not None:
192 if opts.version != g_rt_version:
193 prs.error(
"invalid version of WKT Raster protocol specified, only version 0 is supported")
195 prs.error(
"use option -w to specify version of WKT Raster protocol")
197 if opts.endian
is not None:
198 if opts.endian != NDR
and opts.endian != XDR:
199 prs.error(
"invalid endianness value, valid ones are 0 for NDR or 1 for XDR")
201 prs.error(
"use option -e to specify endianness of binary output")
207 """If verbose mode requested, sends extra progress information to stderr"""
209 sys.stderr.write(msg)
213 """Translate GDAL data type to WKT Raster pixel type."""
215 gdalc.GDT_Byte : {
'name':
'PT_8BUI',
'id': 4 },
216 gdalc.GDT_Int16 : {
'name':
'PT_16BSI',
'id': 5 },
217 gdalc.GDT_UInt16 : {
'name':
'PT_16BUI',
'id': 6 },
218 gdalc.GDT_Int32 : {
'name':
'PT_32BSI',
'id': 7 },
219 gdalc.GDT_UInt32 : {
'name':
'PT_32BUI',
'id': 8 },
220 gdalc.GDT_Float32 : {
'name':
'PT_32BF',
'id': 10 },
221 gdalc.GDT_Float64 : {
'name':
'PT_64BF',
'id': 11 }
228 return pixtypes.get(gdt, 13)
231 """Translate GDAL data type to NumPy data type"""
233 gdalc.GDT_Byte : numpy.uint8,
234 gdalc.GDT_Int16 : numpy.int16,
235 gdalc.GDT_UInt16 : numpy.uint16,
236 gdalc.GDT_Int32 : numpy.int32,
237 gdalc.GDT_UInt32 : numpy.uint32,
238 gdalc.GDT_Float32: numpy.float32,
239 gdalc.GDT_Float64: numpy.float64
241 return ptnumpy.get(pt, numpy.uint8)
244 """Returns binary data type specifier for given pixel type."""
254 return fmttypes.get(pt,
'x')
258 """Returns printf-like formatter for given binary data type sepecifier."""
269 return fmttypes.get(fmt,
'f')
272 assert options
is not None
273 assert options.block_size
is not None
275 wh = options.block_size.split(
'x')
277 wh = options.block_size.split(
'X')
279 assert len(wh) == 2,
"invalid format of specified block size"
280 return ( int(wh[0]), int(wh[1]) )
286 assert value
is not None,
"None value given"
288 if len(value) > 0
and value[0] !=
"'" and value[:-1] !=
"'":
289 sql =
"'" + str(value) +
"'"
295 assert name
is not None,
"None name given"
297 if name[0] !=
"\"" and name[:-1] !=
"\"":
298 sql =
"\"" + str(name) +
"\""
315 st = schema_table.split(
'.')
318 st.insert(0,
"public")
319 assert len(st) == 2,
"Invalid format of table name, expected [<schema>.]table"
320 return (st[0], st[1])
324 table =
"\"%s\".\"%s\"" % (st[0], st[1])
328 st = schema_table.split(
'.')
329 assert len(st) == 1
or len(st) == 2,
"Invalid format of table name, expected [<schema>.]table"
335 sql =
"DROP TABLE IF EXISTS %s CASCADE;\n" \
337 logit(
"SQL: %s" % sql)
344 target =
"'', '%s'" % st[1]
346 target =
"'%s', '%s'" % (st[0], st[1])
347 sql =
"SELECT DropRasterTable(%s);\n" % target
348 logit(
"SQL: %s" % sql)
355 table = options.table
358 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY, \"filename\" text);\n" \
361 if options.overview_level > 1
and is_overview:
362 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY, %s RASTER);\n" \
365 sql =
"CREATE TABLE %s (rid serial PRIMARY KEY);\n" \
368 logit(
"SQL: %s" % sql)
375 logit(
"MSG: Create GiST spatial index on %s\n" % gist_table)
377 sql =
"CREATE INDEX \"%s_%s_gist_idx\" ON %s USING GIST (st_convexhull(%s));\n" % \
378 (gist_table, column, target_table, column)
379 logit(
"SQL: %s" % sql)
384 assert len(pixeltypes) > 0,
"No pixel types given"
389 if nodata
is not None and len(nodata) > 0:
398 bs = (
'null',
'null' )
400 if options.block_size
is not None:
401 assert pixelsize
is not None,
"Pixel size is none, but regular blocking requested"
402 assert blocksize
is not None,
"Block size is none, but regular blocking requested"
403 assert extent
is not None,
"Extent is none, but regular blocking requested"
404 assert len(pixelsize) == 2,
"Invalid pixel size, two values expected"
405 assert len(blocksize) == 2,
"Invalid block size, two values expected"
406 assert len(extent) == 4,
"Invalid extent, four coordinates expected"
407 assert len(extent[0]) == len(extent[3]) == 2,
"Invalid extent, pair of X and Y pair expected"
409 bs = ( blocksize[0], blocksize[1] )
410 extgeom =
"ST_Envelope(ST_SetSRID('POLYGON((%.15f %.15f,%.15f %.15f,%.15f %.15f,%.15f %.15f,%.15f %.15f))'::geometry, %d))" % \
411 (extent[0][0], extent[0][1], extent[1][0], extent[1][1],
412 extent[2][0], extent[2][1], extent[3][0], extent[3][1],
413 extent[0][0], extent[0][1], options.srid)
415 sql =
"SELECT AddRasterColumn('%s','%s','%s',%d, %s, %s, %s, %s, %.15f, %.15f, %s, %s, %s);\n" % \
416 (ts[0], ts[1], options.column, options.srid, pt, odb, rb, nd,
417 pixelsize[0], pixelsize[1], bs[0], bs[1], extgeom)
419 logit(
"SQL: %s" % sql)
424 assert file
is not None,
"Missing filename, but insert_filename requested"
425 sql =
"INSERT INTO %s ( filename, %s ) VALUES ( (\'%s\')::text, (\'%s\')::raster );\n" \
428 sql =
"INSERT INTO %s ( %s ) VALUES ( (\'%s\')::raster );\n" \
438 sql =
'CREATE TABLE ' + table +
' ( ' \
439 'o_table_catalog character varying(256) NOT NULL, ' \
440 'o_table_schema character varying(256) NOT NULL, ' \
441 'o_table_name character varying(256) NOT NULL, ' \
442 'o_column character varying(256) NOT NULL, ' \
443 'r_table_catalog character varying(256) NOT NULL, ' \
444 'r_table_schema character varying(256) NOT NULL, ' \
445 'r_table_name character varying(256) NOT NULL, ' \
446 'r_column character varying(256) NOT NULL, ' \
447 'out_db boolean NOT NULL, ' \
448 'overview_factor integer NOT NULL, ' \
449 'CONSTRAINT raster_overviews_pk ' \
450 'PRIMARY KEY (o_table_catalog, o_table_schema, o_table_name, o_column, overview_factor));\n'
456 assert len(ov_table) > 0
463 sql =
"INSERT INTO public.raster_overviews( " \
464 "o_table_catalog, o_table_schema, o_table_name, o_column, " \
465 "r_table_catalog, r_table_schema, r_table_name, r_column, out_db, overview_factor) " \
466 "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', FALSE, %d);\n" % \
467 (catalog, schema, ov_table, options.column, catalog, schema, r_table, options.column, ov_factor)
479 assert ds
is not None
481 if band_from
is None:
484 band_to = ds.RasterCount
486 assert band_to <= ds.RasterCount,
'Failed checking band_to=%d <= RasterCount=%d' % (band_to,ds.RasterCount)
487 assert band_from <= band_to
490 for i
in range(band_from, band_to + 1):
491 n = ds.GetRasterBand(i).GetOverviewCount()
494 assert n == nov,
'Number of raster overviews is not the same for all bands'
499 assert ds
is not None
503 band = ds.GetRasterBand(1)
504 assert band
is not None
505 assert overview < band.GetOverviewCount()
507 ov_band = band.GetOverview(overview)
508 assert ov_band
is not None
510 ovf = int(0.5 + ds.RasterXSize / float(ov_band.XSize))
511 logit(
'MSG: Overview factor = %d\n' % ovf)
517 """Collect pixel types of bands in requested range.
518 Use names of pixel types in format as returned
519 by rt_core function rt_pixtype_name()"""
522 for i
in range(band_from, band_to):
523 band = ds.GetRasterBand(i)
524 pixel_type =
gdt2pt(band.DataType)[
'name'][3:]
525 pt.append(pixel_type)
530 """Collect nodata values of bands in requested range"""
533 for i
in range(band_from, band_to):
534 band = ds.GetRasterBand(i)
535 nodata = band.GetNoDataValue()
536 if nodata
is not None and not is_nan(nodata):
542 """Size of natural block reported by GDAL for bands of given dataset"""
545 for i
in range(band_from, band_to):
546 band = ds.GetRasterBand(i)
547 assert band
is not None,
"Cannot access raster band %d" % i
548 dims = band.GetBlockSize()
555 if block_dims != dims:
556 logit(
"MSG: Block sizes don't match: %s != %s\n" % (str(block_dims), str(dims)))
558 assert block_dims
is not None,
"Failed to calculate block size"
559 return (int(block_dims[0]), int(block_dims[1]))
562 """Dimensions of grid made up with blocks of requested size"""
565 nx = float(raster_size[0]) / float(block_size[0])
566 ny = float(raster_size[1]) / float(block_size[1])
568 return ( int(math.ceil(nx)), int(math.ceil(ny)))
571 """Calculates number of columns [0] and rows [1] of padding"""
572 assert band
is not None
576 block_bound = ( xoff + block_size[0], yoff + block_size[1] )
578 if block_bound[0] > band.XSize:
579 xpad = block_bound[0] - band.XSize
580 if block_bound[1] > band.YSize:
581 ypad = block_bound[1] - band.YSize
586 assert ds
is not None
587 gt = list(ds.GetGeoTransform())
591 """Calculate georeferenced coordinate from given x and y"""
592 assert gt
is not None
593 assert xy
is not None
596 xgeo = gt[0] + gt[1] * xy[0] + gt[2] * xy[1];
597 ygeo = gt[3] + gt[4] * xy[0] + gt[5] * xy[1];
604 newgt = ( gt[0], gt[1] * float(level), gt[2], gt[3], gt[4], gt[5] * float(level) )
609 """Calculate georeferenced coordinates of spatial extent of raster dataset"""
610 assert ds
is not None
613 dim = ( (0,0),(0,ds.RasterYSize),(ds.RasterXSize,0),(ds.RasterXSize,ds.RasterYSize) )
621 assert hex
is not None,
"Error: Missing hex string"
623 assert size > 0,
"Error: hex string is empty"
624 assert size % 2 == 0,
"Error: invalid size of hex string"
625 if bytes_size
is not None:
627 assert n == bytes_size,
"Error: invalid number of bytes %d, expected %d" % (n, bytes_size)
630 assert pixels.ndim == 2
631 print 'BEGIN BLOCK SCANLINES (numpy): (%d, %d)' %(len(pixels[0]), len(pixels))
634 for row
in range (0, len(pixels)):
635 s = binascii.hexlify(pixels[row])
636 print '%d (%d)\t%s' % (i, (len(s) / 2), s)
639 print 'END BLOCK SCANLINES'
642 assert band
is not None
645 if band.GetNoDataValue()
is not None:
646 nodata = band.GetNoDataValue()
648 logit(
"WARNING: No nodata flagged in raster_columns metadata. "
649 "In serialized raster, nodata bytes will have value of 0.\n")
653 """Writes raw binary data into HEX-encoded string using binascii module."""
657 fmt_little =
'<' +fmt
658 hexstr = binascii.hexlify(struct.pack(fmt_little, data)).upper()
663 logit(
'HEX (\'fmt=%s\', bytes=%d, val=%s):\t\t%s\n' \
664 % (fmt, len(hexstr) / 2, str(val), hexstr))
669 """Writes WKT Raster header based on given GDAL into HEX-encoded WKB."""
670 assert ds
is not None,
"Error: Missing GDAL dataset"
672 assert len(ulp) == 2
is not None,
"Error: invalid upper-left corner"
674 if xsize
is None or ysize
is None:
675 assert xsize
is None and ysize
is None
676 xsize = ds.RasterXSize
677 ysize = ds.RasterYSize
682 rt_ip = ( ul[0], ul[1] )
683 rt_skew = ( gt[2], gt[4] )
684 rt_scale = ( gt[1] * level, gt[5] * level )
693 hexwkb +=
wkblify(
'B', options.endian)
695 hexwkb +=
wkblify(
'H', options.version)
697 if options.band
is not None and options.band > 0:
700 hexwkb +=
wkblify(
'H', ds.RasterCount)
703 hexwkb +=
wkblify(
'd', rt_scale[0])
704 hexwkb +=
wkblify(
'd', rt_scale[1])
705 hexwkb +=
wkblify(
'd', rt_ip[0])
706 hexwkb +=
wkblify(
'd', rt_ip[1])
707 hexwkb +=
wkblify(
'd', rt_skew[0])
708 hexwkb +=
wkblify(
'd', rt_skew[1])
709 hexwkb +=
wkblify(
'i', options.srid)
716 logit(
"MSG: Georeference: px = %s -> ul = %s \tresolution = %s \trotation = %s\n" \
717 % (str(ulp), str(rt_ip), str(rt_scale), str(rt_skew)))
721 """Writes band header into HEX-encoded WKB"""
722 assert band
is not None,
"Error: Missing GDAL raster band"
732 nodata = band.GetNoDataValue()
734 if nodata
is not None:
740 pixtype =
gdt2pt(band.DataType)[
'id']
741 hexwkb +=
wkblify(
'B', pixtype + first4bits)
749 def wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, bandidx):
750 """Writes band of given GDAL dataset into HEX-encoded WKB for WKT Raster output."""
751 assert band
is not None,
"Error: Missing GDAL raster band"
761 hexwkb +=
wkblify(
'B', bandidx - 1)
762 filepath = os.path.abspath(infile.replace(
'\\',
'\\\\'))
763 logit(
'MSG: Out-db raster path=%s\n' % filepath)
764 hexwkb +=
wkblify(str(len(filepath)) +
's', filepath)
772 valid_read_block_size = ( read_block_size[0] - read_padding_size[0],
773 read_block_size[1] - read_padding_size[1] )
776 if read_padding_size[0] > 0
or read_padding_size[1] > 0:
777 target_block_size = (valid_read_block_size[0] / level, valid_read_block_size[1] / level)
778 target_padding_size = (read_padding_size[0] / level, read_padding_size[1] / level)
780 target_block_size = block_size
781 target_padding_size = ( 0, 0 )
783 logit(
'MSG: Normalize read_block=%s for level=%d to valid_read_block=%s with padding=%s\n' % \
784 (read_block_size, level, valid_read_block_size, read_padding_size))
785 logit(
'MSG: Normalize target_block=%s for level=%d to valid_target_block=%s with padding=%s\n' % \
786 (block_size, level, target_block_size, target_padding_size))
787 logit(
'MSG: ReadAsArray( %d, %d, %s, %s)\n' % \
788 (xoff, yoff, str(valid_read_block_size), str(target_block_size)))
790 assert valid_read_block_size[0] > 0
and valid_read_block_size[1] > 0
791 assert target_block_size[0] > 0
and target_block_size[1] > 0
793 pixels = band.ReadAsArray(xoff, yoff, valid_read_block_size[0], valid_read_block_size[1],
794 target_block_size[0], target_block_size[1])
799 out_pixels = numpy.zeros((block_size[1], block_size[0]),
pt2numpy(band.DataType))
801 logit(
'MSG: Read valid source:\t%d x %d\n' % (len(pixels[0]), len(pixels)))
802 logit(
'MSG: Write into block:\t%d x %d\n' % (len(out_pixels[0]), len(out_pixels)))
804 if target_padding_size[0] > 0
or target_padding_size[1] > 0:
806 ysize_read_pixels = len(pixels)
810 pad_cols = numpy.array([nodata_value] * target_padding_size[0])
811 for row
in range (0, ysize_read_pixels):
812 out_line = numpy.append(pixels[row], pad_cols)
813 out_pixels[row] = out_line
816 for row
in range(ysize_read_pixels, ysize_read_pixels + target_padding_size[1]):
817 out_pixels[row].
fill(nodata_value)
824 hexwkb = binascii.hexlify(out_pixels)
830 assert ds
is not None
832 assert len(band_range) == 2
834 band_from = band_range[0]
835 band_to = band_range[1]
838 raster_size = ( ds.RasterXSize, ds.RasterYSize )
839 if options.block_size
is not None:
841 read_block_size = ( block_size[0] * level, block_size[1] * level)
844 block_size = raster_size
845 read_block_size = block_size
848 logit(
"MSG: Processing raster=%s using read_block_size=%s block_size=%s of grid=%s in level=%d\n" % \
849 (str(raster_size), str(read_block_size), str(block_size), str(grid_size), level))
853 if i == 0
and options.create_table:
855 pixel_size = ( gt[1], gt[5] )
860 pixel_size, block_size, extent)
861 options.output.write(sql)
862 gen_table = options.table
869 level_table_name =
'o_' + str(level) +
'_' + schema_table_names[1]
870 level_table = schema_table_names[0] +
'.' + level_table_name
873 options.output.write(sql)
875 options.output.write(sql)
876 gen_table = level_table
882 for ycell
in range(0, grid_size[1]):
883 for xcell
in range(0, grid_size[0]):
885 xoff = xcell * read_block_size[0]
886 yoff = ycell * read_block_size[1]
888 logit(
"MSG: --------- CELL #%04d\tindex = %d x %d\tdim = (%d x %d)\t(%d x %d) \t---------\n" % \
889 (tile_count, xcell, ycell, xoff, yoff, xoff + read_block_size[0], yoff + read_block_size[1]))
891 if options.block_size
is not None:
894 block_size[0], block_size[1])
898 for b
in range(band_from, band_to):
899 band = ds.GetRasterBand(b)
900 assert band
is not None,
"Missing GDAL raster band %d" % b
901 logit(
"MSG: Band %d\n" % b)
904 hexwkb +=
wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, b)
909 options.output.write(sql)
911 tile_count = tile_count + 1
913 return (gen_table, tile_count)
916 """Writes given raster dataset using GDAL features into HEX-encoded of
917 WKB for WKT Raster output."""
919 assert infile
is not None,
"Input file is none, expected file name"
920 assert options.version == g_rt_version,
"Error: invalid WKT Raster protocol version"
921 assert options.endian == NDR,
"Error: invalid endianness, use little-endian (NDR) only"
922 assert options.srid >= -1,
"Error: do you really want to specify SRID = %d" % options.srid
925 ds = gdal.Open(infile, gdalc.GA_ReadOnly);
927 sys.exit(
'Error: Cannot open input file: ' + str(infile))
932 if options.band
is not None and options.band > 0:
933 band_range = ( options.band, options.band + 1 )
935 band_range = ( 1, ds.RasterCount + 1 )
939 if previous_gt
is not None:
940 if previous_gt[1] != current_gt[1]
or previous_gt[5] != current_gt[5]:
941 sys.exit(
'Error: Cannot load raster with different pixel size in the same raster table')
945 SUMMARY.append( summary )
959 VERBOSE = opts.verbose
964 saved_out = sys.stdout
965 if type(opts.output)
is str:
966 filename = opts.output
967 opts.output = open(filename,
"w")
970 opts.output.write(
'BEGIN;\n')
973 if opts.create_raster_overviews_table:
975 opts.output.write(sql)
978 if opts.overview_level == 1:
982 opts.output.write(sql)
985 if opts.create_table
and opts.overview_level == 1:
987 opts.output.write(sql)
994 for infile
in opts.raster:
995 filelist = glob.glob(infile)
996 assert len(filelist) > 0,
"No input raster files found for '" + str(infile) +
"'"
998 for filename
in filelist:
999 logit(
"MSG: Dataset #%d: %s\n" % (i + 1, filename))
1006 if opts.index
and SUMMARY
is not None:
1008 opts.output.write(sql)
1011 opts.output.write(
'END;\n')
1014 if opts.vacuum
and SUMMARY
is not None:
1016 opts.output.write(sql)
1019 if opts.output != sys.stdout:
1020 sys.stdout = saved_out
1022 print "------------------------------------------------------------"
1023 print " Summary of GDAL to PostGIS Raster processing:"
1024 print "------------------------------------------------------------"
1026 m =
'%d (%s)' % (i, infile)
1029 print "Number of processed raster files: " + m
1030 print "List of generated tables (number of tiles):"
1034 print "%d\t%s (%d)" % (i, s[0], s[1])
1038 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)