Source code for localmaxfilter.interfaces

# -*- coding: utf-8 -*-
"""
| ----------------------------------------------------------------------------------------------------------------------
| Date                : March 2019
| Copyright           : © 2019 - 2020 by Tinne Cahy (Geo Solutions) and Ann Crabbé (KU Leuven)
| Email               : acrabbe.foss@gmail.com
| Acknowledgements    : Translated from Local Maximum Filter [C++ software]
|                       Ghent University, Laboratory of Forest Management and Spatial Information Techniques
|                       Lieven P.C. Verbeke
|
| This file is part of the QGIS Tree Density Calculator plugin and treedensitycalculator python package.
|
| This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
| License as published by the Free Software Foundation, either version 3 of the License, or any later version.
|
| This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
| warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License (COPYING.txt). If not see www.gnu.org/licenses.
| ----------------------------------------------------------------------------------------------------------------------
"""
import os
import tempfile

from localmaxfilter.interfaces.imports import import_image, import_vector_as_image
from localmaxfilter.interfaces.exports import write_mask_layer, write_point_layer, write_voronoi_layer
from localmaxfilter.core.local_max_filter import LocalMaxFilter


[docs]def run_algorithm_local_max_filter(image_path, window, log_function=print, update_progress_bar=None, mask_path=None, output_base_path=None, snap_distance=None, voronoi=None, feedback=None, context=None): """ General interface between the GUI/CLI and script. :param image_path: the absolute path to the raster file :param window: window size in meters :param update_progress_bar: function to update the progress bar :param log_function: function to log :param mask_path: absolute path to the vector file (optional) :param output_base_path: base path for output files (optional) :param snap_distance: snap distance for output points (optional) :param voronoi: set to True if you want voronoi polygons as output (optional) :param feedback: necessary for the processing tool :param context: necessary for the processing tool :return: """ if image_path is None: raise Exception("Choose a correct image file.") # get raster (clipped by mask) and its metadata img, img_srs, img_gt = import_image(image_path=image_path, mask_path=mask_path, window_size=window, feedback=feedback, context=context) # get area of interest as raster area_raster = import_vector_as_image(path=mask_path, geo_transform=img_gt, image_size=img.shape, image_srs=img_srs, window_size=window, feedback=feedback, context=None) if mask_path else None # convert the window size from meters to number of pixels (odd number) pixel_size = img_gt[1] window_px = int((window / pixel_size) // 2 * 2 + 1) if window_px == 1: window_px = 3 # Print in the log the size of the window in pixels log_function('The window is built out of {0} by {0} pixels'.format(window_px)) if snap_distance: if snap_distance > window / 2: raise Exception('Snap distance should be max half of the window size') snap_distance = int(snap_distance / pixel_size) # Print in the log the snap distance in pixels log_function('The snap distance is {0} pixels'.format(snap_distance)) # Run LMF lmf_result = LocalMaxFilter(window_px).execute(img, area_of_interest=area_raster, snap=snap_distance, geo_transform=img_gt, set_progress=update_progress_bar) if update_progress_bar: update_progress_bar(100) else: print('progress: 100 %') # base name for output files if not output_base_path: output_base_path = os.path.join(tempfile.gettempdir(), os.path.basename(os.path.splitext(image_path)[0])) else: output_base_path, _ = os.path.splitext(output_base_path) output_base_path = '{0}_window_{1}'.format(output_base_path, window_px) # point layer output_point_path = output_base_path + '_point.shp' write_point_layer(output_path=output_point_path, points_dict=lmf_result, geo_transform=img_gt, srs=img_srs, mask_path=mask_path, feedback=feedback, context=context) # Output mask in case it was given: if mask_path: output_mask_path = output_base_path + '_mask.shp' write_mask_layer(output_mask_path, mask_path, output_point_path, log=log_function) else: output_mask_path = None # write point layer to Voronoi polygon layer if voronoi: output_voronoi_path = output_base_path + '_voronoi.shp' write_voronoi_layer(output_path=output_voronoi_path, point_path=output_point_path, mask_path=mask_path, feedback=feedback, context=context) else: output_voronoi_path = None return output_point_path, output_mask_path, output_voronoi_path