# -*- coding: utf-8 -*-

"""
/***************************************************************************
 Fractalidad
                                 A QGIS plugin
 Estu pligin optiene las capas de fractalidad
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2021-05-27
        copyright            : (C) 2021 by Jair Arriaga, Tonatiuh Suarez
        email                : jair.arriaga@outlook.com, tonatiuhsmeaney@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

__author__ = 'Jair Arriaga, Tonatiuh Suarez'
__date__ = '2021-05-27'
__copyright__ = '(C) 2021 by Jair Arriaga, Tonatiuh Suarez'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
                       QgsFeatureSink,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterFeatureSource,
                       QgsProcessingParameterFeatureSink,
                       QgsProcessingParameterFileDestination,
                       QgsProcessingParameterVectorDestination,
                       QgsProcessingParameterRasterDestination,
                       QgsProcessingParameterDistance,
                       QgsProcessingOutputNumber,
                       QgsProcessingParameterVectorLayer,
                       QgsProcessingMultiStepFeedback)
import processing


class FractalidadAlgorithm(QgsProcessingAlgorithm):

    """
    This is an example algorithm that takes a vector layer and
    creates a new identical one.

    It is meant to be used as an example of how to create your own
    algorithms and explain methods and variables used to do it. An
    algorithm like this will be available in all elements, and there
    is not need for additional work.

    All Processing algorithms should extend the QgsProcessingAlgorithm
    class.
    """

    # Constants used to refer to parameters and outputs. They will be
    # used when calling the algorithm from another algorithm, or when
    # calling from the QGIS console.



    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterVectorLayer('capaentrada', 'Capa entrada', types=[QgsProcessing.TypeVector], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel1', 'Nivel 1', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel2', 'Nivel 2', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel3', 'Nivel 3', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel4', 'Nivel 4', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel5', 'Nivel 5', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel6', 'Nivel 6', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Fractal', 'Fractal', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Nivel0', 'Nivel 0', type=QgsProcessing.TypeVectorPolygon, createByDefault=True, defaultValue=None))

    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(52, model_feedback)
        results = {}
        outputs = {}

        # Recuadro delimitador
        alg_params = {
            'INPUT': parameters['capaentrada'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RecuadroDelimitador'] = processing.run('native:boundingboxes', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # Calcular nivel 0
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Escala',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/2\r\nelse height/2\r\n\r\nend',
            'INPUT': outputs['RecuadroDelimitador']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['CalcularNivel0'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(2)
        if feedback.isCanceled():
            return {}

        # Centroides calculado
        alg_params = {
            'ALL_PARTS': False,
            'INPUT': outputs['CalcularNivel0']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['CentroidesCalculado'] = processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(3)
        if feedback.isCanceled():
            return {}

        # Buffer de distancia variable
        alg_params = {
            'DISSOLVE': False,
            'END_CAP_STYLE': 2,
            'FIELD': 'Escala',
            'INPUT': outputs['CentroidesCalculado']['OUTPUT'],
            'JOIN_STYLE': 1,
            'MITER_LIMIT': 0,
            'SEGMENTS': 99,
            'OUTPUT': parameters['Nivel0']
        }
        outputs['BufferDeDistanciaVariable'] = processing.run('qgis:variabledistancebuffer', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel0'] = outputs['BufferDeDistanciaVariable']['OUTPUT']

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}

        # Nivel 6
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel6',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/64\r\nelse height/64\r\n\r\nend',
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel6'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(5)
        if feedback.isCanceled():
            return {}

        # localizacion_nivel_0
        alg_params = {
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacion_nivel_0'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(6)
        if feedback.isCanceled():
            return {}

        # Nivel 4
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel4',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/16\r\nelse height/16\r\n\r\nend',
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel4'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(7)
        if feedback.isCanceled():
            return {}

        # Longitud_cuadro
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': parameters['capaentrada'],
            'JOIN': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'JOIN_FIELDS': 'width',
            'PREDICATE': [0],
            'SUMMARIES': [2],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Longitud_cuadro'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(8)
        if feedback.isCanceled():
            return {}

        # Nivel 2
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel2',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/4\r\nelse height/4\r\n\r\nend',
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel2'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(9)
        if feedback.isCanceled():
            return {}

        # valor nivel 1
        alg_params = {
            'FIELD_NAME': 'Escala',
            'INPUT_LAYER': outputs['BufferDeDistanciaVariable']['OUTPUT']
        }
        outputs['ValorNivel1'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(10)
        if feedback.isCanceled():
            return {}

        # grid nivel 1
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel1']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel1']['MIN'],
            'OUTPUT': parameters['Nivel1']
        }
        outputs['GridNivel1'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel1'] = outputs['GridNivel1']['OUTPUT']

        feedback.setCurrentStep(11)
        if feedback.isCanceled():
            return {}

        # localización_nivel_1
        alg_params = {
            'INPUT': outputs['GridNivel1']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_1'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(12)
        if feedback.isCanceled():
            return {}

        # valor nivel 6
        alg_params = {
            'FIELD_NAME': 'Nivel6',
            'INPUT_LAYER': outputs['Nivel6']['OUTPUT']
        }
        outputs['ValorNivel6'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(13)
        if feedback.isCanceled():
            return {}

        # Valor nivel 4
        alg_params = {
            'FIELD_NAME': 'Nivel4',
            'INPUT_LAYER': outputs['Nivel4']['OUTPUT']
        }
        outputs['ValorNivel4'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(14)
        if feedback.isCanceled():
            return {}

        # Nivel 3
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel3',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/8\r\nelse height/8\r\n\r\nend',
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel3'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(15)
        if feedback.isCanceled():
            return {}

        # valor nivel 3
        alg_params = {
            'FIELD_NAME': 'Nivel3',
            'INPUT_LAYER': outputs['Nivel3']['OUTPUT']
        }
        outputs['ValorNivel3'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(16)
        if feedback.isCanceled():
            return {}

        # Nivel 5
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel5',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'case \r\n\r\nwhen width > height then width/32\r\nelse height/32\r\n\r\nend',
            'INPUT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel5'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(17)
        if feedback.isCanceled():
            return {}

        # grid nivel 6
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel6']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel6']['MIN'],
            'OUTPUT': parameters['Nivel6']
        }
        outputs['GridNivel6'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel6'] = outputs['GridNivel6']['OUTPUT']

        feedback.setCurrentStep(18)
        if feedback.isCanceled():
            return {}

        # valor nivel 2
        alg_params = {
            'FIELD_NAME': 'Nivel2',
            'INPUT_LAYER': outputs['Nivel2']['OUTPUT']
        }
        outputs['ValorNivel2'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(19)
        if feedback.isCanceled():
            return {}

        # grid nivel 2
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel2']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel2']['MIN'],
            'OUTPUT': parameters['Nivel2']
        }
        outputs['GridNivel2'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel2'] = outputs['GridNivel2']['OUTPUT']

        feedback.setCurrentStep(20)
        if feedback.isCanceled():
            return {}

        # Nombre Tamaño
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Tamaño',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': 'width_min',
            'INPUT': outputs['Longitud_cuadro']['OUTPUT'],
            'NEW_FIELD': False,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['NombreTamao'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(21)
        if feedback.isCanceled():
            return {}

        # grid nivel 3
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel3']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel3']['MIN'],
            'OUTPUT': parameters['Nivel3']
        }
        outputs['GridNivel3'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel3'] = outputs['GridNivel3']['OUTPUT']

        feedback.setCurrentStep(22)
        if feedback.isCanceled():
            return {}

        # join nivel 0
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['NombreTamao']['OUTPUT'],
            'JOIN': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'JOIN_FIELDS': 'area',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel0'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(23)
        if feedback.isCanceled():
            return {}

        # localización_nivel_3
        alg_params = {
            'INPUT': outputs['GridNivel3']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_3'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(24)
        if feedback.isCanceled():
            return {}

        # valor nivel 5
        alg_params = {
            'FIELD_NAME': 'Nivel5',
            'INPUT_LAYER': outputs['Nivel5']['OUTPUT']
        }
        outputs['ValorNivel5'] = processing.run('qgis:basicstatisticsforfields', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(25)
        if feedback.isCanceled():
            return {}

        # grid nivel 4
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel4']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel4']['MIN'],
            'OUTPUT': parameters['Nivel4']
        }
        outputs['GridNivel4'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel4'] = outputs['GridNivel4']['OUTPUT']

        feedback.setCurrentStep(26)
        if feedback.isCanceled():
            return {}

        # localización_nivel_6
        alg_params = {
            'INPUT': outputs['GridNivel6']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_6'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(27)
        if feedback.isCanceled():
            return {}

        #  localización_nivel_2
        alg_params = {
            'INPUT': outputs['GridNivel2']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_2'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(28)
        if feedback.isCanceled():
            return {}

        # grid nivel 5
        alg_params = {
            'CRS': 'ProjectCrs',
            'EXTENT': outputs['BufferDeDistanciaVariable']['OUTPUT'],
            'HOVERLAY': 0,
            'HSPACING': outputs['ValorNivel5']['MIN'],
            'TYPE': 2,
            'VOVERLAY': 0,
            'VSPACING': outputs['ValorNivel5']['MIN'],
            'OUTPUT': parameters['Nivel5']
        }
        outputs['GridNivel5'] = processing.run('native:creategrid', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Nivel5'] = outputs['GridNivel5']['OUTPUT']

        feedback.setCurrentStep(29)
        if feedback.isCanceled():
            return {}

        # Nombre_0
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_0',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'area_count',
            'INPUT': outputs['JoinNivel0']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_0'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(30)
        if feedback.isCanceled():
            return {}

        # localización_nivel_4
        alg_params = {
            'INPUT': outputs['GridNivel4']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_4'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(31)
        if feedback.isCanceled():
            return {}

        # join nivel 1
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_0']['OUTPUT'],
            'JOIN': outputs['GridNivel1']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel1'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(32)
        if feedback.isCanceled():
            return {}

        # localización_nivel_5
        alg_params = {
            'INPUT': outputs['GridNivel5']['OUTPUT'],
            'INTERSECT': parameters['capaentrada'],
            'METHOD': 0,
            'PREDICATE': [0]
        }
        outputs['Localizacin_nivel_5'] = processing.run('native:selectbylocation', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(33)
        if feedback.isCanceled():
            return {}

        # nombre_1
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_1',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count',
            'INPUT': outputs['JoinNivel1']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_1'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(34)
        if feedback.isCanceled():
            return {}

        # join nivel 2
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_1']['OUTPUT'],
            'JOIN': outputs['GridNivel2']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel2'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(35)
        if feedback.isCanceled():
            return {}

        # Nombre_2
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_2',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count_2',
            'INPUT': outputs['JoinNivel2']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_2'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(36)
        if feedback.isCanceled():
            return {}

        # join nivel 3
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_2']['OUTPUT'],
            'JOIN': outputs['GridNivel3']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel3'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(37)
        if feedback.isCanceled():
            return {}

        # Nombre_3
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_3',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count_3',
            'INPUT': outputs['JoinNivel3']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_3'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(38)
        if feedback.isCanceled():
            return {}

        # join nivel 4
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_3']['OUTPUT'],
            'JOIN': outputs['GridNivel4']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel4'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(39)
        if feedback.isCanceled():
            return {}

        # Nombre_4
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_4',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count_4',
            'INPUT': outputs['JoinNivel4']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_4'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(40)
        if feedback.isCanceled():
            return {}

        # join nivel 5
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_4']['OUTPUT'],
            'JOIN': outputs['GridNivel5']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel5'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(41)
        if feedback.isCanceled():
            return {}

        # Nombre_5
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_5',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count_5',
            'INPUT': outputs['JoinNivel5']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_5'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(42)
        if feedback.isCanceled():
            return {}

        # join nivel 6
        alg_params = {
            'DISCARD_NONMATCHING': False,
            'INPUT': outputs['Nombre_5']['OUTPUT'],
            'JOIN': outputs['GridNivel6']['OUTPUT'],
            'JOIN_FIELDS': 'top',
            'PREDICATE': [0],
            'SUMMARIES': [0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['JoinNivel6'] = processing.run('qgis:joinbylocationsummary', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(43)
        if feedback.isCanceled():
            return {}

        # Nombre_6
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Nivel_6',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 1,
            'FORMULA': 'top_count_6',
            'INPUT': outputs['JoinNivel6']['OUTPUT'],
            'NEW_FIELD': True,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nombre_6'] = processing.run('qgis:fieldcalculator', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(44)
        if feedback.isCanceled():
            return {}

        # nivel_0
        alg_params = {
            'COLUMN': 'area_count',
            'INPUT': outputs['Nombre_6']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_0'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(45)
        if feedback.isCanceled():
            return {}

        # tamaño
        alg_params = {
            'COLUMN': 'width_min',
            'INPUT': outputs['Nivel_0']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Tamao'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(46)
        if feedback.isCanceled():
            return {}

        # Nivel_1
        alg_params = {
            'COLUMN': 'top_count',
            'INPUT': outputs['Tamao']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_1'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(47)
        if feedback.isCanceled():
            return {}

        # Nivel_2
        alg_params = {
            'COLUMN': 'top_count_2',
            'INPUT': outputs['Nivel_1']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_2'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(48)
        if feedback.isCanceled():
            return {}

        # Nivel_3
        alg_params = {
            'COLUMN': 'top_count_3',
            'INPUT': outputs['Nivel_2']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_3'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(49)
        if feedback.isCanceled():
            return {}

        # Nivel_4
        alg_params = {
            'COLUMN': 'top_count_4',
            'INPUT': outputs['Nivel_3']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_4'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(50)
        if feedback.isCanceled():
            return {}

        # Nivel_5
        alg_params = {
            'COLUMN': 'top_count_5',
            'INPUT': outputs['Nivel_4']['OUTPUT'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Nivel_5'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(51)
        if feedback.isCanceled():
            return {}

        # Nivel_6
        alg_params = {
            'COLUMN': 'top_count_6',
            'INPUT': outputs['Nivel_5']['OUTPUT'],
            'OUTPUT': parameters['Fractal']
        }
        outputs['Nivel_6'] = processing.run('qgis:deletecolumn', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Fractal'] = outputs['Nivel_6']['OUTPUT']
        return results

    def name(self):
        """
        Returns the algorithm name, used for identifying the algorithm. This
        string should be fixed for the algorithm, and must not be localised.
        The name should be unique within each provider. Names should contain
        lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        """
        return 'Fractalidad'

    def displayName(self):
        """
        Returns the translated algorithm name, which should be used for any
        user-visible display of the algorithm name.
        """
        return self.tr(self.name())

    def group(self):
        """
        Returns the name of the group this algorithm belongs to. This string
        should be localised.
        """
        return self.tr(self.groupId())

    def groupId(self):
        """
        Returns the unique ID of the group this algorithm belongs to. This
        string should be fixed for the algorithm, and must not be localised.
        The group id should be unique within each provider. Group id should
        contain lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        """
        return ''

    def tr(self, string):
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        return FractalidadAlgorithm()
