Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from Tkinter import *
- from Queue import Queue, Empty
- from subprocess import Popen, PIPE
- from threading import Thread
- from osgeo import gdal, ogr, osr
- import tkFileDialog
- import ttk
- from ttk import Treeview, Scrollbar, Style
- import os, datetime, time
- from time import gmtime, strftime
- import subprocess,shlex
- import psycopg2 as psycopg
- from psycopg2 import sql
- import platform
- def iter_except(function, exception):
- try:
- while True:
- yield function()
- except exception:
- return
- #TODO Napraviti scrollbar
- #TODO Kopiranje u mozaik
- #TODO Konfiguracija - zavrsiti
- class Main_Importer_GUI:
- def __init__(self, master):
- self.mod_py = False
- self.source_dir = '/home/dboto/Documents/python/raster'
- self.mosaic_dir = '/home/dboto/Documents/python/raster'
- self.mosaic_srs = '3765'
- self.pg_host = 'localhost'
- self.pg_db = 'gis'
- self.pg_table = 'drone_mosaic'
- self.pg_uname = 'postgres'
- self.pg_pass = 'postgres'
- # --------------------------------------------------------------------------
- master = master
- master.minsize(400, 700)
- master.resizable(0, 0)
- master.title("KING ICT Drone images importer")
- # --------------------------------------------------------------------------
- menubar = Menu(root)
- filemenu = Menu(menubar)
- filemenu.add_command(label='New Project')
- filemenu.add_command(label='Configuration', command=self.config_window)
- filemenu.add_command(label='Load Files...', command=self.select_file)
- filemenu.add_command(label='Exit', command=root.quit)
- menubar.add_cascade(label="File", menu=filemenu)
- datamenu = Menu(menubar)
- datamenu.add_command(label='Show data', command=self.data_window)
- menubar.add_cascade(label="Data", menu=datamenu)
- master.config(menu=menubar)
- # --------------------------------------------------------------------------
- label_1 = Label(master, text="Odaberite TIF datoteku za import")
- label_1.grid(sticky="W", column=0, row=0, padx=(10, 50))
- self.tiff_filepath = StringVar()
- self.selected_TIFF = Entry(master, width=60, textvariable=self.tiff_filepath)
- self.selected_TIFF.grid(sticky="W", column=0, row=1, padx=(10, 10))
- select_TIF_file = Button(master, text="Odaberi", command=self.select_file)
- select_TIF_file.grid(sticky="E", column=0, row=1, padx=(10, 10))
- selected_label = Label(master, text="Odabrane TIFF datoteke:")
- selected_label.grid(sticky="W", column=0, row=2, padx=(10, 50))
- self.file_box = Listbox(master, width=70, height=8)
- self.file_box.grid(sticky="W", column=0, row=3, padx=(10, 10))
- site_label = Label(root, text="Unesite lokaciju snimanja", font=(None, 8))
- site_label.grid(sticky="W", column=0, row=4, padx=(10, 50))
- self.entry_site = StringVar()
- self.site_text = Entry(master, width=40, textvariable=self.entry_site)
- self.site_text.grid(sticky="W", column=0, row=4, padx=(170, 10))
- date_label = Label(root, text="Unesite datum snimanja", font=(None, 8))
- date_label.grid(sticky="W", column=0, row=5, padx=(10, 50))
- self.entry_day = StringVar()
- self.date_day = Entry(master, width=3, textvariable=self.entry_day)
- self.date_day.grid(sticky="W", column=0, row=5, padx=(170, 200))
- self.entry_month = StringVar()
- self.date_month = Entry(master, width=3, textvariable=self.entry_month)
- self.date_month.grid(sticky="W", column=0, row=5, padx=(195, 10))
- self.entry_year = StringVar()
- self.date_year = Entry(master, width=4, textvariable=self.entry_year)
- self.date_year.grid(sticky="W", column=0, row=5, padx=(220, 10))
- output_label = Label(root, text="Output", font=(None, 8))
- output_label.grid(sticky="W", column=0, row=6, padx=(10, 50))
- self.output = Listbox(root, width=70, height=30, bg="black", fg="#00ff00")
- self.output.grid(sticky="W", column=0, row=7, padx=(10, 10))
- self.progress = ttk.Progressbar(root, orient='horizontal', maximum=100, length=560, mode='determinate')
- self.progress.grid(sticky="W", column=0, row=8, padx=(10, 10))
- self.start = Button(master, text="Pokreni import", command=self.start_process, state=DISABLED)
- self.start.grid(column=0, row=9, padx=(10, 10))
- # --------------------------------------------------------------------------
- def select_file(self):
- self.selected_tif_paths = tkFileDialog.askopenfilenames(initialdir=self.source_dir, title="Odaberi", filetypes=(("tiff files", "*.tif"), ("all files", "*.*")))
- self.tiff_filepath.set(self.selected_tif_paths)
- self.file_box.delete(0, 'end')
- for fileName in self.selected_tif_paths:
- self.file_box.insert(END, fileName)
- # --------------------------------------------------------------------------
- self.tiff_path = gdal.Open(fileName)
- tiff_srs = osr.SpatialReference(wkt=self.tiff_path.GetProjection())
- tiff_gt = self.tiff_path.GetGeoTransform()
- tif_band = self.tiff_path.GetRasterBand(1)
- self.tiff_bands = self.tiff_path.RasterCount
- self.tiff_srid = tiff_srs.GetAttrValue("AUTHORITY", 1)
- self.tiff_ctime = time.ctime(os.path.getctime(fileName))
- self.tiff_pixel = tiff_gt[1]
- self.tiff_nodata = tif_band.GetNoDataValue()
- # -----------------------------------------------------------------------
- c_time_in_seconds = os.path.getctime(os.path.join(fileName))
- c_time_array = str(time.gmtime(c_time_in_seconds)[:3])
- c_date_str = ''.join(c_time_array)
- c_datetime_obj = datetime.datetime.strptime(c_date_str, '(%Y, %d, %m)')
- self.created_date = c_datetime_obj.date()
- self.current_date = strftime('(%Y, %d, %m)', gmtime())
- self.file_box.insert(END, ' FILE NAME_= %s' % os.path.basename(fileName))
- self.file_box.insert(END, ' BANDS NUM_= %s' % self.tiff_bands)
- self.file_box.insert(END, ' PIXEL SIZE = %s' % tiff_gt[1])
- self.file_box.insert(END, ' SRID_= %s' % self.tiff_srid)
- self.file_box.insert(END, ' CREATE DATE = %s' % self.created_date)
- self.file_box.insert(END, ' CURRENT DATE = %s' % self.current_date)
- self.file_box.insert(END, ' NO DATA = %s' % self.tiff_nodata)
- self.file_box.insert(END, ' # ----------------------------------------------------------')
- self.entry_site.set(os.path.basename(fileName[:-4]))
- self.entry_year.set(c_date_str.split(",")[0][1:])
- self.entry_month.set(c_date_str.split(",")[1][1:])
- self.entry_day.set(c_date_str.split(",")[2][:-1])
- if self.tiff_bands < 4:
- self.output.insert(1, '*** ERROR: Odabrana TIFF datoteka nema ALPHA kanal! ***')
- self.output.itemconfig(0, {'bg':'black'})
- self.output.itemconfig(0, {'fg': 'red'})
- self.start.configure(state='disable')
- else:
- self.output.delete(0)
- self.start.configure(state='normal')
- # --------------------------------------------------------------------------
- def start_process(self):
- self.start.configure(state='disable')
- self.progress.start(100)
- for tiff_path in self.selected_tif_paths:
- self.output.insert(END, "**************************GDAL PROCESSING - TIFF OPTIMIZACIJA***************************")
- self.output.insert(END, "INPUT FILE NAME IS: ---- %s ----" % (os.path.basename(tiff_path)))
- # ----------------------------------------------------------------------
- # ----------------------------------------------------------------------
- tmp_vrt = tiff_path[:-4] + '_OPT.vrt'
- if self.mod_py:
- output_vrt = gdal.BuildVRT(tmp_vrt, tiff_path, bandList = [1,2,3], callback=gdal.TermProgress)
- else:
- buildvrt_opt = '-b 1 -b 2 -b 3'
- buildvrt_sys = '-overwrite'
- buildvrt_cmd = 'gdalbuildvrt %s %s %s %s' % (os.path.basename(tmp_vrt), buildvrt_opt, buildvrt_sys, os.path.basename(tiff_path))
- self.process_output(buildvrt_cmd)
- # ---------------------------------------------------------------------
- output_tiff = tiff_path[:-4] + '_OPT.tif'
- if self.mod_py:
- gdal.Warp(output_tiff,
- tmp_vrt,
- dstSRS = 'EPSG:{}'.format(self.mosaic_srs),
- srcSRS = 'EPSG:{}'.format(self.tiff_srid),
- srcNodata = self.tiff_nodata,
- dstNodata = 255,
- format = 'GTiff',
- creationOptions=['PHOTOMETRIC=YCBCR', 'COMPRESS=JPEG', 'TILED=YES'], callback=gdal.TermProgress)
- else:
- gdalwarp_opt = '-srcnodata {} -dstnodata 255 -co "PHOTOMETRIC=YCBCR" -co "COMPRESS=JPEG" -co "TILED=YES"'.format(self.tiff_nodata)
- gdalwarp_sys = '-overwrite -wo NUM_THREADS=ALL_CPUS -multi'
- gdalwarp_srs = '-s_srs EPSG:{} -t_srs EPSG:{}'.format(self.tiff_srid, self.mosaic_srs)
- gdalwarp_cmd = 'gdalwarp %s %s %s %s %s' % (gdalwarp_opt, gdalwarp_srs, gdalwarp_sys, os.path.basename(tmp_vrt), os.path.basename(output_tiff))
- self.process_output(gdalwarp_cmd)
- # ---------------------------------------------------------------------
- tiff_opt = gdal.Open(output_tiff, 0)
- if self.mod_py:
- gdal.SetConfigOption('COMPRESS_OVERVIEW', 'JPEG')
- gdal.SetConfigOption('PHOTOMETRIC_OVERVIEW', 'YCBCR')
- gdal.SetConfigOption('INTERLEAVE_OVERVIEW', 'PIXEL')
- self.process = tiff_opt.BuildOverviews("NEAREST", [2, 4, 8, 16, 32, 64, 128, 256, 512], callback=gdal.TermProgress)
- else:
- gdaladdo_opt = '-ro -r nearest --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR --config INTERLEAVE_OVERVIEW PIXEL'
- gdaladdo_sys = '2 4 8 16 32 64 128 256 512'
- gdaladdo_cmd = 'gdaladdo %s %s %s' % (gdaladdo_opt, os.path.basename(output_tiff), gdaladdo_sys)
- print gdaladdo_cmd
- self.process_output(gdaladdo_cmd)
- # ---------------------------------------------------------------------
- # ---------------------------------------------------------------------
- gt = self.tiff_path.GetGeoTransform()
- tiff_up_L = gdal.ApplyGeoTransform(gt, 0, 0) # koordinate gornjeg lijevog kuta
- tiff_up_R = gdal.ApplyGeoTransform(gt, self.tiff_path.RasterXSize, 0) # koordinate gornjeg desnog kuta
- tiff_dw_L = gdal.ApplyGeoTransform(gt, 0, self.tiff_path.RasterYSize) # koordinate donjeg lijevog kuta
- tiff_dw_R = gdal.ApplyGeoTransform(gt, self.tiff_path.RasterXSize, self.tiff_path.RasterYSize) # koordinate donjeg desnod kuta
- gdaladdo_opt = '-ro -r nearest --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR --config INTERLEAVE_OVERVIEW PIXEL'
- gdaladdo_sys = '2 4 8 16 32 64 128 256 512'
- gdaladdo_cmd = 'gdaladdo %s %s %s' % (gdaladdo_opt, os.path.basename(output_tiff), gdaladdo_sys)
- self.process_output(gdaladdo_cmd)
- # ---------------------------------------------------------------------
- # ---------------------------------------------------------------------
- tiff_bounds_wkt = 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))")' % (
- tiff_up_L[0], tiff_up_L[1],
- tiff_dw_L[0], tiff_dw_L[1],
- tiff_dw_R[0], tiff_dw_R[1],
- tiff_up_R[0], tiff_up_R[1],
- tiff_up_L[0], tiff_up_L[1])
- footprint = self.mask_footprint()
- if self.tiff_srid != int(self.mosaic_srs):
- tiff_bounds = ogr.CreateGeometryFromWkt(tiff_bounds_wkt)
- tiff_bounds = self.coordinate_transform(tiff_bounds)
- footprint = str(self.coordinate_transform(footprint))
- # ---------------------------------------------------------------------
- mask_shp_name = tiff_path[:-4] + '_OPT.shp'
- shp_outDriver = ogr.GetDriverByName('ESRI Shapefile')
- mosaic_srs = osr.SpatialReference()
- mosaic_srs.ImportFromEPSG(int(self.mosaic_srs))
- shp_outDataSource = shp_outDriver.CreateDataSource(mask_shp_name)
- shp_outLayer = shp_outDataSource.CreateLayer("mask", mosaic_srs, geom_type=ogr.wkbPolygon)
- shp_idField = ogr.FieldDefn("id", ogr.OFTInteger)
- shp_outLayer.CreateField(shp_idField)
- shp_idField = ogr.FieldDefn("ND", ogr.OFTString)
- shp_outLayer.CreateField(shp_idField)
- featureDefn = shp_outLayer.GetLayerDefn()
- feature = ogr.Feature(featureDefn)
- feature.SetGeometry(ogr.CreateGeometryFromWkt(footprint))
- feature.SetField("id", 1)
- feature.SetField("ND", os.path.basename(tiff_path)[:-4])
- shp_outLayer.CreateFeature(feature)
- feature = None
- # Save and close DataSource
- shp_outDataSource = None
- # ---------------------------------------------------------------------
- self.recording_date = datetime.datetime(int(self.entry_year.get()), int(self.entry_month.get()),
- int(self.entry_day.get()))
- # ---------------------------------------------------------------------
- pg_connect = psycopg.connect('dbname=%s user=%s' % (self.pg_db, self.pg_uname))
- cur = pg_connect.cursor()
- mosaic_insert = cur.mogrify("INSERT INTO drone_mosaic_new (ingestion, location, srid, resolution, bands, nodata, geom, site, footprint,created_on)"
- "VALUES( %s, %s, %s, %s, %s, %s, ST_GeomFromText(%s, {}), %s, ST_GeomFromText(%s, {}), %s)".format(self.mosaic_srs, self.mosaic_srs),
- (self.recording_date,
- tiff_path,
- self.tiff_srid,
- self.tiff_pixel,
- self.tiff_bands,
- self.tiff_nodata,
- tiff_bounds,
- self.entry_site.get(),
- footprint,
- datetime.datetime.now()))
- cur.execute(mosaic_insert)
- pg_connect.commit()
- cur.close()
- pg_connect.close()
- # ---------------------------------------------------------------------
- print 'KRAJ'
- self.progress.configure(value=100)
- def mask_footprint(self):
- if self.tiff_bands > 3:
- alfa_band = self.tiff_path.GetRasterBand(4)
- tmp_vector_mem = ogr.GetDriverByName('MEMORY').CreateDataSource('mask.shp')
- tmp_vector_layer = tmp_vector_mem.CreateLayer('polygonized', srs=None)
- tmp_vector_field = ogr.FieldDefn('mask', ogr.OFTInteger)
- tmp_vector_layer.CreateField(tmp_vector_field)
- gdal.Polygonize(alfa_band, None, tmp_vector_layer, 0, [], callback=gdal.TermProgress)
- for feature in tmp_vector_layer:
- if feature.GetField("mask") == 255:
- geometry = feature.GetGeometryRef()
- symplifyed_footprint = geometry.Simplify(2.0)
- return symplifyed_footprint
- def coordinate_transform(self, geometry_trans):
- source_srs = osr.SpatialReference()
- source_srs.ImportFromEPSG(int(self.tiff_srid))
- self.target_srs = osr.SpatialReference()
- self.target_srs.ImportFromEPSG(int(self.mosaic_srs))
- transform = osr.CoordinateTransformation(source_srs, self.target_srs)
- geometry_trans.Transform(transform)
- return str(geometry_trans)
- def process_output(self, process_cmd):
- self.process = Popen(shlex.split(process_cmd), stdout=PIPE, stderr=PIPE, cwd=self.source_dir)
- q = Queue(maxsize=1024)
- t = Thread(target=self.reader_thread, args=[q])
- t.daemon = True
- t.start()
- self.update(q)
- def reader_thread(self, q):
- try:
- with self.process.stdout as pipe:
- for line in iter(pipe.readline, b''):
- q.put(line)
- finally:
- q.put(None)
- def update(self, q):
- # TODO di staviti wait govno?
- self.process.wait()
- for line in iter_except(q.get_nowait, Empty):
- if line is None:
- self.progress.stop()
- self.progress.configure(value=100)
- #self.quit()
- return
- else:
- self.output.insert(END, line[:-1])
- break
- self.file_box.after(50, self.update, q)
- def quit(self):
- self.process.kill()
- # ---------------------------------------------------------------------
- # ---------------------------------------------------------------------
- def config_window(self):
- config_win = Toplevel(root)
- config_win = config_win
- config_win.minsize(400, 700)
- config_win.resizable(0, 0)
- config_win.title("KING ICT Importer Config")
- # ---------------------------------------------------------------------
- config_warrning = Label(config_win, text="Upozorenje: Promjena parametara moze dovesti do neispravnog\n rada programa", fg="red")
- config_warrning.grid(columnspan=2, column=0, row=0, padx=(10, 50))
- self.config_active = IntVar()
- config_activ = Checkbutton(config_win, text='Izmjena parametara konfiguracije', variable=self.config_active, command=self.config_activate)
- config_activ.grid(sticky="W", columnspan=2, column=0, row=1, padx=(10, 10))
- config_source_lab = Label(config_win, text="TIFF direktorij")
- config_source_lab.grid(sticky="W", column=0, row=2, padx=(10, 50))
- self.config_source_dir_text = StringVar()
- self.config_source_dir = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_source_dir_text)
- self.config_source_dir.grid(sticky="W", column=1, row=2, padx=(10, 10))
- self.config_source_dir_text.set(self.source_dir)
- config_mosaic_lab = Label(config_win, text="Mozaik direktorij")
- config_mosaic_lab.grid(sticky="W", column=0, row=3, padx=(10, 50))
- self.config_mosaic_dir_text = StringVar()
- self.config_mosaic_dir = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_mosaic_dir_text)
- self.config_mosaic_dir.grid(sticky="W", column=1, row=3, padx=(10, 10))
- self.config_mosaic_dir_text.set(self.mosaic_dir)
- config_pg_host_label = Label(config_win, text="PG Host")
- config_pg_host_label.grid(sticky="W", column=0, row=4, padx=(10, 50))
- self.config_pg_host_text = StringVar()
- self.config_pg_host = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_pg_host_text)
- self.config_pg_host.grid(sticky="W", column=1, row=4, padx=(10, 10))
- self.config_pg_host_text.set(self.pg_host)
- config_pg_db_label = Label(config_win, text="PG Baza")
- config_pg_db_label.grid(sticky="W", column=0, row=5, padx=(10, 50))
- self.config_pg_db_text = StringVar()
- self.config_pg_db = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_pg_db_text)
- self.config_pg_db.grid(sticky="W", column=1, row=5, padx=(10, 10))
- self.config_pg_db_text.set(self.pg_db)
- config_pg_uname_label = Label(config_win, text="PG Ime")
- config_pg_uname_label.grid(sticky="W", column=0, row=6, padx=(10, 50))
- self.config_pg_uname_text = StringVar()
- self.config_pg_uname = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_pg_uname_text)
- self.config_pg_uname.grid(sticky="W", column=1, row=6, padx=(10, 10))
- self.config_pg_uname_text.set(self.pg_uname)
- config_pg_pass_label = Label(config_win, text="TIFF Zaporka")
- config_pg_pass_label.grid(sticky="W", column=0, row=7, padx=(10, 50))
- self.config_pg_pass_text = StringVar()
- self.config_pg_pass = Entry(config_win, width=30, state=DISABLED, textvariable=self.config_pg_pass_text)
- self.config_pg_pass.grid(sticky="W", column=1, row=7, padx=(10, 10))
- self.config_pg_pass_text.set(self.pg_pass)
- def config_activate(self):
- if self.config_active.get() == 0:
- self.config_source_dir.configure(state='disabled')
- self.config_mosaic_dir.configure(state='disabled')
- self.config_pg_host.configure(state='disabled')
- self.config_pg_db.configure(state='disabled')
- self.config_pg_uname.configure(state='disabled')
- self.config_pg_pass.configure(state='disabled')
- else:
- self.config_source_dir.configure(state='normal')
- self.config_mosaic_dir.configure(state='normal')
- self.config_pg_host.configure(state='normal')
- self.config_pg_db.configure(state='normal')
- self.config_pg_uname.configure(state='normal')
- self.config_pg_pass.configure(state='normal')
- # ---------------------------------------------------------------------
- # ---------------------------------------------------------------------
- def data_window(self):
- data_win = Toplevel(root)
- data_win.title("KING ICT Importer Mosaic Data")
- data_win.resizable(0, 0)
- # ---------------------------------------------------------------------
- table_frame = ttk.Treeview(data_win, selectmode="browse", column=("column1", "column2", "column3", "column4", "column5", "column6", "column7", "column8", "column9"), show='headings')
- scrollbar = Scrollbar(data_win, orient="vertical", command=table_frame.yview)
- scrollbar.grid(sticky='nse', column=1, row=0)
- table_frame.configure(yscrollcommand=scrollbar.set)
- # ---------------------------------------------------------------------
- table_frame.heading("#1", text="ID")
- table_frame.heading("#2", text="URI")
- table_frame.heading("#3", text="Datum snimanja")
- table_frame.heading("#4", text="Datum importa")
- table_frame.heading("#5", text="SRID")
- table_frame.heading("#6", text="Lokacija")
- table_frame.heading("#7", text="Bendova")
- table_frame.heading("#8", text="NoData")
- table_frame.heading("#9", text="Rezolucija")
- table_frame.column("#1", minwidth=0, width=30)
- table_frame.column("#2", minwidth=0, width=400)
- table_frame.column("#3", minwidth=0, width=150)
- table_frame.column("#4", minwidth=0, width=150)
- table_frame.column("#5", minwidth=0, width=70)
- table_frame.column("#6", minwidth=0, width=150)
- table_frame.column("#7", minwidth=0, width=60)
- table_frame.column("#8", minwidth=0, width=60)
- table_frame.column("#9", minwidth=0, width=60)
- table_frame.grid(sticky="W", column=0, row=0, padx=(0, 0))
- # ---------------------------------------------------------------------
- pg_connect = psycopg.connect('dbname=%s user=%s' % (self.pg_db, self.pg_uname))
- cur = pg_connect.cursor()
- select_data = "SELECT fid, location, ingestion, created_on, srid, site, bands, nodata, resolution FROM drone_mosaic_new"
- cur.execute(select_data)
- mosaic_data = cur.fetchall()
- for row in mosaic_data:
- table_frame.insert('', END, values=row)
- cur.close()
- pg_connect.close()
- # ---------------------------------------------------------------------
- root = Tk()
- my_gui = Main_Importer_GUI(root)
- root.mainloop()
Add Comment
Please, Sign In to add comment