def get_items(self): """ Populate the Maps Menu with the available products Returns: None """ # Get the subfolders product_folders = list() for x in os.listdir(self.root): if os.path.isdir(x) and (x == "ChangeMaps" or x == "CoverMaps"): product_folders.append(os.path.join(self.root, x)) log.debug("MAPS VIEWER, product_folders: %s" % str(product_folders)) sub_folders = list() for prod_folder in product_folders: for root, folders, files in os.walk(prod_folder): for folder in folders: sub_folders.append(os.path.join(root, folder)) log.debug("MAPS VIEWER, sub_folders: %s" % str(sub_folders))
def highlight_pick(self): """ Change the symbology of the clicked point so that it is visible on the plot Returns: None """ # Remove the highlight from the previously selected point try: self.prev_highlight.set_data([], []) except AttributeError: pass # <class 'matplotlib.lines.Line2D'> This points to the Line2D curve that will contain the highlighted point # Use index '0' because self.artist_map[b] is referencing a list of 1 item highlight = self.artist_map[self.b][0] self.prev_highlight = highlight log.debug("artist_data[0]: {}".format(self.artist_data[0])) log.debug("artist_data[1]: {}".format(self.artist_data[1])) highlight.set_data(self.artist_data[0], self.artist_data[1]) self.canvas.draw()
def update_config(self, item, params): log.debug('PARAMS: {}'.format(params)) _id = LOOKUP[item] if _id is 'highlight_pick': # 's' won't work for plots, only for scatters params['ms'] = params['s'] params['mec'] = params['color'] params.pop('s', None) params.pop('color', None) bg_color = params.pop('background') temp = self.opts['DEFAULTS'][_id] for key, value in params.items(): temp[key] = value self.opts['DEFAULTS'][_id] = temp self.opts['DEFAULTS']['background']['color'] = bg_color temp = self.opts['LEG_DEFAULTS'][_id] for key, value in params.items(): # Don't want to change symbol size on the legend if key is not 's': temp[key] = value self.opts['LEG_DEFAULTS'][_id] = temp
def save_plot_config(self, outfile): """Save the plot configuration settings for use in a different session""" log.debug('plot config outfile: {}'.format(outfile)) with open(outfile, 'w') as f: yaml.dump(self.plotconfig.opts, f) self.symbol_selector.close()
def init_configure(self): log.debug("Selected Legend Label: {}".format(self.artist.get_label())) self.label = self.artist.get_label() if self.label in POINTS or self.label in LINES: # self.symbol_selector = SymbologyWindow() # # self.symbol_selector.selected_marker.connect(self.connect_symbology) self.change_symbology.emit(self.label)
def browse_map(self): """ Load the mapped product Returns: None """ # <str> Represents the currently selected text in the combo box product = self.ui.comboBox_map1.currentText() log.debug("MAPS VIEWER, browse_map-> product: %s" % product) # Grab the current extent of the scene view so that the next image that gets opened is in the same extent self.graphics_view.view_holder = QRectF( self.graphics_view.mapToScene(0, 0), self.graphics_view.mapToScene(self.graphics_view.width(), self.graphics_view.height())) if product is not "": try: self.img_list1 = glob.glob(PRODUCTS[product]["root"] + os.sep + "*.tif") temp = [ img for img in self.img_list1 if str(self.ui.date_slider.value()) in img ][0] self.pixel_map = QPixmap(temp) self.graphics_view.set_image(self.pixel_map) if self.graphics_view.view_holder: view_rect = self.graphics_view.viewport().rect() scene_rect = self.graphics_view.transform().mapRect( self.graphics_view.view_holder) factor = min(view_rect.width() / scene_rect.width(), view_rect.height() / scene_rect.height()) self.graphics_view.scale(factor, factor) except IndexError: pass
def mousePressEvent(self, event: QMouseEvent): # 1 -> Left-click # 2 -> Right-click # 4 -> Wheel-click self._mouse_button = event.button() if event.button() == Qt.RightButton: self.toggle_drag() if self._image.isUnderMouse() and event.button() == Qt.LeftButton \ and self.dragMode() == QGraphicsView.NoDrag: point = self.mapToScene(event.pos()) log.debug("point %s" % str(point)) self.image_clicked.emit(QPointF(point)) super(ImageViewer, self).mousePressEvent(event)
def connect_plot_selection(self, val): """ Display the selected observation in the main control window Args: val (dict): Information describing which observation was selected in a particular axes Returns: """ log.debug("emitted selection: {}".format(val)) output = "Obs. Date: {:%Y-%b-%d}\n{}-Value: {}".format( val['date'], val['b'], val['value']) self.plot_window.b = val['b'] self.ui.ListWidget_selected.addItem(output)
def grid_timeseries_index(self): """ A wrapper to get the index within a timeseries for each grid-location in regards to a target date """ log.debug("coords_snap: %s" % str(self.coords_snap[0])) log.debug("tile_geo pixel_coord_ul: %s" % str(self.tile_geo.pixel_coord_ul)) temp = ARDData.get_sequence( timeseries=self.grid[self.tile_geo.chip_coord_ul]['data'], pixel_coord=self.tile_geo.pixel_coord_ul) ind = self.get_index(temp['dates'], self.date) for loc, item in self.grid.items(): self.grid[loc]['ind'] = ind
def get_product_root_directories(self): """ Construct the full path to the change/cover product subdirectories using the most recent version available. Store the full path in the products dict under keyword "root" Returns: None """ for product in PRODUCTS.keys(): PRODUCTS[product]["root"] = os.path.join( self.root, PRODUCTS[product]["type"], PRODUCTS[product]["alias"]) log.debug("MAPS VIEWER, %s root dir: %s" % (str(product), str(PRODUCTS[product]["root"]))) return None
def __init__(self, tile: str, chip_coord: GeoCoordinate, pixel_coord: GeoCoordinate, json_dir: str): """ Args: tile: The string-formatted H-V tile name chip_coord: The upper left coordinate of the chip in projected meters pixel_coord: The upper left coordinate of the pixel in projected meters json_dir: Absolute path to tile-specific PyCCD results stored in JSON files Returns: """ log.debug(f'SEARCHING - dir - {json_dir}') log.debug( f'SEARCHING - file - {tile}_{chip_coord.x}_{chip_coord.y}.json') try: self.json_file = self.find_file( file_ls=[ os.path.join(json_dir, f) for f in os.listdir(json_dir) ], string="{tile}_{x}_{y}.json".format(tile=tile, x=chip_coord.x, y=chip_coord.y)) except Exception: log.exception("ERROR - retrieving pyccd results failed") self.results = [{}] if self.json_file is not None: self.results = self.check_dates( self.extract_jsoncurve(pixel_info=self.pixel_ccd_info( results_chip=self.json_file, coord=pixel_coord))) else: log.warning("No PyCCD results exist for tile %s" % tile) self.results = [{}]
def redraw_plot(self, val): self.fig_num += 1 log.debug("Received plot config vals: {}".format(val)) if self.label in POINTS: self.plotconfig.update_config( self.label, { 'marker': val['marker'], 's': val['markersize'], 'color': val['color'], 'background': val['background'] }) else: self.plotconfig.update_config( self.label, { 'linestyle': val['marker'], 'linewidth': val['markersize'], 'color': val['color'], 'background': val['background'] }) self.symbol_selector.close() self.fig, self.artist_map, self.lines_map, self.axes = make_plots.draw_figure( data=self.plot_specs, items=self.item_list, fig_num=self.fig_num, config=self.plotconfig.opts) self.plot_window = PlotWindow(fig=self.fig, axes=self.axes, artist_map=self.artist_map, lines_map=self.lines_map) self.plot_window.selected_obs.connect(self.connect_plot_selection) self.plot_window.change_symbology.connect(self.change_symbology)
def show_image(self, key, imgs=None): """ Display the image Args: key: imgs: Returns: """ input_dir = self.action_mapper1[key][1] log.debug("MAPS VIEWER, show_image-> input_dir: %s" % input_dir) if imgs is None: imgs = glob.glob(input_dir + os.sep + "*.tif") log.debug("MAPS VIEWER, show_image-> imgs: %s" % str(imgs)) self.pixel_map = QPixmap(imgs[0]) self.graphics_view.set_image(self.pixel_map)
def save_fig(self): """ Save the current matplotlib figure to a PNG file """ if not os.path.exists(self.ui.LineEdit_outputDir.text()): os.makedirs(self.ui.LineEdit_outputDir.text()) fname = self.fname_generator() # Overwrite the .png if it already exists if os.path.exists(fname): try: os.remove(fname) except (IOError, PermissionError) as _e: log.error('Exception: %s' % _e, exc_info=True) # Make sure the timeseries plot is set as the current figure plt.figure(f'timeseries_figure_{self.fig_num}') plt.savefig(fname, bbox_inches="tight", dpi=150) log.debug("Plot figure saved to file {}".format(fname))
def main(): log.debug('*** System Information ***') log.debug('Platform: %s' % sys.platform) log.debug('Python: %s' % str(sys.version).replace('\n', '')) log.debug('Pip: %s' % ', '.join(freeze.freeze())) log.info("Running lcmap-tap version %s" % __version__) # Create a QApplication object, necessary to manage the GUI control flow and settings app = QApplication(sys.argv) # session_id = "session_{}".format(MainControls.get_time()) control_window = MainControls() if control_window: # Enter the main event loop, begin event handling for application widgets until exit() is called sys.exit(app.exec_())
def update_plot(self): """ Generate a new plot for the clicked point location Returns: None """ # Gather information to retrieve necessary data for the new plot rowcol = RowColumn(row=self.ard.row, column=self.ard.col) coords = GeoInfo.rowcol_to_geo(affine=self.ard.pixel_image_affine, rowcol=rowcol) # Update the x and y so that they are displayed correctly with save_img self.ard.x = coords.x self.ard.y = coords.y log.debug("New point selected: %s" % str(coords)) # Update the X and Y coordinates in the GUI with the new point if UNITS[self.selected_units]["unit"] == "meters": self.ui.LineEdit_x1.setText(str(coords.x)) self.ui.LineEdit_y1.setText(str(coords.y)) # Convert to lat/long before updating the coordinate text on the GUI else: _coords = GeoInfo.unit_conversion(coords) self.ui.LineEdit_x1.setText(str(_coords.x)) self.ui.LineEdit_y1.setText(str(_coords.y)) # Do the plotting and generate a new figure self.check_values() self.plot() """Need to determine the y-axis value for the new time series. Can be done by determining the index within the new time-series of the x-axis (i.e. date) value from the previous time series """ x_look_thru = { "obs_points": self.plot_specs.dates_in[self.plot_specs.qa_mask[ self.plot_specs.date_mask]], "out_points": self.plot_specs.dates_out[self.plot_specs.fill_out], "mask_points": self.plot_specs. dates_in[~self.plot_specs.qa_mask[self.plot_specs.date_mask]] } y_look_thru = { "obs_points": self.plot_specs.all_lookup[self.ard.ax][0][ self.plot_specs.date_mask][self.plot_specs.qa_mask[ self.plot_specs.date_mask]], "out_points": self.plot_specs.all_lookup[self.ard.ax][0] [~self.plot_specs.date_mask][self.plot_specs.fill_out], "mask_points": self.plot_specs.all_lookup[self.ard.ax][0][ self.plot_specs.date_mask] [~self.plot_specs.qa_mask[self.plot_specs.date_mask]] } for key, x in x_look_thru.items(): if self.ard.date_x in x: x_series = x y_series = y_look_thru[key] #: int: the location of the date in the new time series ind = np.where(x_series == self.ard.date_x) #: the reflectance or index value for the new time series data_y = np.take(y_series, ind) # Display the highlighted pixel in the new plot highlight = self.plot_window.artist_map[self.ard.ax][0] # highlight.set_data(self.date_x[0], self.data_y[0]) highlight.set_data(self.ard.date_x, data_y) self.plot_window.canvas.draw() break
def save_img(self): """ Returns: """ date = self.date.strftime('%Y%m%d') r = self.ui.ComboBox_red.currentText().lower() g = self.ui.ComboBox_green.currentText().lower() b = self.ui.ComboBox_blue.currentText().lower() try: outdir = self.working_dir if r == b and r == g: outfile = os.path.join(outdir, f'{r}_{date}_{get_time()}.png') else: outfile = os.path.join(outdir, f'{r}_{g}_{b}_{date}_{get_time()}.png') fig, ax = plt.subplots(figsize=(10, 10), num=f'ard_figure_{self.fig_num}') # Make sure that the ARD figure is active plt.figure(f'ard_figure_{self.fig_num}') plt.axis('off') ax.grid(False) center = self.chips.tile_geo.chip_coord_ul _date = dt.datetime.fromordinal( self.chips.grid[center]['data'][0][1]['dates'][ self.chips.grid[center]['ind']]).strftime('%Y-%m-%d') title = f'Date: {_date}' text = f'X: {self.x}\nY: {self.y}' ax.set_title(title) ax.imshow(self.chips.rgb, interpolation='nearest') ax.scatter(x=self.col, y=self.row, marker='s', facecolor='none', color='yellow', s=15, linewidth=1) ax.text(0, -.01, text, horizontalalignment='left', verticalalignment='top', transform=ax.transAxes) plt.savefig(outfile, bbox_inches='tight', dpi=200) log.debug("Plot figure saved to file {}".format(outfile)) plt.gcf().clear() self.fig_num += 1 except (TypeError, ValueError) as e: log.error('ARD save_img raised exception: %s' % e, exc_info=True)
def __init__(self, tile, root, geo, version, begin_year=1984, end_year=2015): super(MapsViewer, self).__init__() icon = QIcon( QPixmap( pkg_resources.resource_filename( "lcmap_tap", "/".join(("Auxiliary", "icon.PNG"))))) self.setWindowIcon(icon) self.tile = tile self.root = root self.geo_info = geo self.current_pixel = None self.pixel_rowcol = self.geo_info.geo_to_rowcol( affine=self.geo_info.PIXEL_AFFINE, coord=self.geo_info.coord) self.row = self.pixel_rowcol.row self.col = self.pixel_rowcol.column log.debug("MAP VIEWER, tile_pixel_rowcol: %s" % str(self.pixel_rowcol)) if not os.path.exists(os.path.join(self.root, version)): self.version = self.get_version() else: self.version = version self.root = os.path.join(self.root, self.version) log.info("MAP VIEWER using version %s" % self.version) log.debug("MAP VIEWER, root: %s" % self.root) self.get_product_root_directories() self.ui = Ui_MapViewer() self.ui.setupUi(self) self.graphics_view = ImageViewer() self.ui.scrollArea.setWidget(self.graphics_view) self.img_list1 = list() self.pixel_map = None self.ui.date_slider.setMinimum(begin_year) self.ui.date_slider.setMaximum(end_year) self.ui.date_slider.setTickPosition(QSlider.TicksBothSides) self.ui.date_slider.setTickInterval(1) # This show's the left-most value of the time slider initially, 1984 self.ui.show_date.setText(str(self.ui.date_slider.value())) self.ui.move_left.clicked.connect(self.move_left) self.ui.move_right.clicked.connect(self.move_right) self.ui.date_slider.valueChanged.connect(self.date_changed) self.ui.pushButton_zoom.clicked.connect(self.zoom_to_point) self.ui.comboBox_map1.currentIndexChanged.connect(self.browse_map) self.ui.exit_QPush.clicked.connect(self.exit) self.make_rect() self.init_ui()