# -*- coding: utf-8 -*-
"""
/***************************************************************************
 MoPSP
                                 A QGIS plugin
 Plugin s funkcí pro kontrolu platnosti podmínek pro pásové střídaní plodin.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2024-10-23
        git sha              : $Format:%H$
        copyright            : (C) 2024 by tp
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt, QVariant, QTemporaryFile
from qgis.PyQt.QtGui import QColor, QIcon, QFont    #*
from qgis.PyQt.QtWidgets import QAction, QFileDialog, QMessageBox
# Initialize Qt resources from file resources.py
from .resources import *
from qgis.core import QgsProject, QgsWkbTypes, QgsRasterLayer, QgsCoordinateReferenceSystem, QgsVectorLayer, Qgis, \
    QgsProcessingFeatureSourceDefinition, QgsFeatureRequest, QgsFeature, QgsField, QgsGeometry, QgsSymbol, \
    QgsSimpleFillSymbolLayer, QgsRendererCategory, QgsCategorizedSymbolRenderer, QgsPointXY, QgsVectorFileWriter, \
    QgsCoordinateTransform, NULL, QgsPrintLayout, QgsLayoutItemMap, QgsLayoutItemPage, QgsLayoutPoint, QgsUnitTypes, \
    QgsLayoutSize, QgsLayoutItemLegend, QgsLayerTree, QgsLegendStyle, QgsLayoutExporter, QgsLayoutItemLabel, \
    QgsSingleSymbolRenderer, QgsCoordinateTransformContext, QgsPoint, QgsRasterFileWriter, QgsRasterPipe,\
    QgsRandomColorRamp, QgsSpatialIndex, QgsLayoutItemShape, QgsRasterBandStats, QgsColorRampShader, QgsRasterShader, \
    QgsSingleBandPseudoColorRenderer, QgsFillSymbol, QgsLinePatternFillSymbolLayer, QgsExpression, \
    QgsExpressionContext, QgsExpressionContextUtils, QgsLayoutItemTextTable, QgsLayoutTableColumn, QgsTextFormat, QgsLayoutFrame, \
    QgsProcessingException

from .psp.layers_utils import (generate_layer, ulozeni_vektorove_vrstvy, symbology_kategorie,
                               mazani_poli)
from .psp.geometry_utils import (vypocet_uhlu, clip_lyr, rozdel_krivku_na_segmenty)
from .psp.crs_transform import (
    ensure_jtsk_grids, maybe_show_install_info,
    operation_4326_to_5514, reproject_layer_5514_to_4326)

import processing
import os
import os.path

import re
import unicodedata

import numpy as np
import time
from time import strftime, localtime
import math
from scipy.interpolate import griddata
from collections import deque, Counter

from matplotlib import cm

try:
    from PyPDF2 import PdfWriter  # QGIS 3.x
except ImportError:
    from pypdf import PdfWriter  # QGIS 4.x (Qt6)

import zipfile
import webbrowser
import requests
from lxml import html



import shutil
import gc


from .MoPSP_dockwidget import MoPSPDockWidget
from .MoPSP_window import MoPSPWindow


try:
    _RIGHT_DOCK = Qt.DockWidgetArea.RightDockWidgetArea
except AttributeError:
    _RIGHT_DOCK = Qt.RightDockWidgetArea

_IS_QGIS4 = Qgis.QGIS_VERSION_INT >= 40000


def _smaz_docasne_tiff_slozku(docasne_dir, *seznamy_souboru):
    """Smaže dočasné TIF a složku docasne_tiff (Windows drží GDAL zámek — retry + gc)."""
    if not docasne_dir:
        return
    for seznam in seznamy_souboru:
        for cesta in seznam or []:
            try:
                os.remove(cesta)
            except OSError:
                pass
    gc.collect()
    for _ in range(8):
        if not os.path.isdir(docasne_dir):
            return
        for name in os.listdir(docasne_dir):
            fp = os.path.join(docasne_dir, name)
            try:
                if os.path.isfile(fp) or os.path.islink(fp):
                    os.remove(fp)
                elif os.path.isdir(fp):
                    shutil.rmtree(fp, ignore_errors=True)
            except OSError:
                pass
        try:
            os.rmdir(docasne_dir)
            return
        except OSError:
            gc.collect()
            time.sleep(0.25)
    shutil.rmtree(docasne_dir, ignore_errors=True)


def _combo_ma_vrstvu(combobox, nulty_radek):
    """True pokud je v comboboxu vybrána skutečná vrstva (ne nultý řádek)."""
    if _IS_QGIS4:
        return combobox.currentData() is not None
    return combobox.currentText() != nulty_radek


def _pridani_vrstev_predvyplnen(combobox, lyr_typ, nulty_radek):
    current_data = combobox.currentData()
    current_text = combobox.currentText()
    combobox.clear()
    if _IS_QGIS4:
        combobox.addItem(nulty_radek, None)
    else:
        combobox.addItem(nulty_radek)
    for layer in lyr_typ:
        combobox.addItem(layer.name() + " (" + layer.crs().authid() + ")", layer)
    if _IS_QGIS4:
        if current_data is None:
            combobox.setCurrentIndex(0)
        elif current_data in lyr_typ:
            index = combobox.findData(current_data)
            combobox.setCurrentIndex(index if index >= 0 else 0)
        else:
            combobox.setCurrentIndex(0)
    elif current_text == nulty_radek:
        index = combobox.findText(current_text)
        combobox.setCurrentIndex(index)
    elif current_data in lyr_typ:
        index = combobox.findData(current_data)
        combobox.setCurrentIndex(index)


def _run_processing_algs(alg_ids, params, result_key):
    """Spustí první Processing algoritmus, který v dané verzi QGIS existuje."""
    last_err = None
    for alg_id in alg_ids:
        try:
            return processing.run(alg_id, params)[result_key]
        except Exception as e:
            last_err = e
            msg = str(e).lower()
            if 'not found' not in msg and 'does not exist' not in msg and 'nenalezen' not in msg:
                raise
    raise last_err


def _run_checkvalidity(vrstva):
    """qgis:checkvalidity (3.x) nebo native:checkvalidity (novější QGIS)."""
    shared = {
        'METHOD': 2,
        'IGNORE_RING_SELF_INTERSECTION': False,
        'VALID_OUTPUT': 'TEMPORARY_OUTPUT',
        'INVALID_OUTPUT': 'TEMPORARY_OUTPUT',
        'ERROR_OUTPUT': 'TEMPORARY_OUTPUT'}
    try:
        return processing.run("qgis:checkvalidity", dict(shared, INPUT_LAYER=vrstva))["INVALID_COUNT"]
    except Exception as e:
        msg = str(e).lower()
        if 'not found' not in msg and 'does not exist' not in msg and 'nenalezen' not in msg:
            raise
        return processing.run("native:checkvalidity", dict(shared, INPUT=vrstva))["INVALID_COUNT"]


class MoPSP:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'MoPSP_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Návrh pásového střídání plodin (MoPSP)')
        self.toolbar = self.iface.addToolBar(u'Návrh pásového střídání plodin (MoPSP)')
        self.toolbar.setObjectName(u'Návrh pásového střídání plodin (MoPSP)')

        self.pluginIsActive = False
        self.dockwidget = None




    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('MoPSP', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = f'{self.plugin_dir}/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Návrh pásového střídání plodin (MoPSP)'),
            callback=self.run,
            parent=self.iface.mainWindow())

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        # disconnects

        self.dlg.pushButton_nacitani.clicked.disconnect(self.nacitani_vrstev_s_textem)
        self.dlg.pushButton_vypocetsklonu.clicked.disconnect(self.spusteni_vypoctu)
        self.dlg.pushButton_kontrolaprojektu.clicked.disconnect(self.kontrola_projektu_prep)

        self.dlg.pushButton_vykrslenilinii.clicked.disconnect(self.vykresleni_linii)
        self.dlg.pushButton_vyhlazeni.clicked.disconnect(self.vyhlazeni_linii)

        self.dlg.pushButton_vypocetdostupnosti.clicked.disconnect(self.vypocet_dostupnosti)
        self.dlg.pushButton_importkostry.clicked.disconnect(self.import_kostry)
        self.dlg.pushButton_kostraprojektu.clicked.disconnect(self.select_tiskdir)
        self.dlg.pushButton_cestalinie.clicked.disconnect(self.select_cestalinie)
        self.dlg.pushButton_kostraxlsx.clicked.disconnect(self.select_cestakostraxlsx)

        self.dlg.pushButton_downloaddmr.clicked.disconnect(self.download_dmr)
        self.dlg.pushButton_downloadwfs.clicked.disconnect(self.download_wfs)
        self.dlg.pushButton_downloadkp.clicked.disconnect(self.download_kp)

        self.dlg.checkBox_vcetnepasu.stateChanged.disconnect(self.zmena_textu_tlacitko)
        self.dlg.checkBox_ulozeniGPS.stateChanged.disconnect(self.zmena_textu_tlacitko)
        QgsProject.instance().layersRemoved.disconnect(self.odstraneni_vrstvy)

        self.dlg.pushButton_ciselnikplodin.clicked.disconnect(self.webciselnik)

        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        self.pluginIsActive = False


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Návrh pásového střídání plodin (MoPSP)'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    #--------------------------------------------------------------------------

    def nacitani_vrstev_s_textem(self):
        """
        Načte vrstvy do příslušných comboboxů s kontrolou validity geometri
        """
        
        #CRS projektu nastavrno na 5514
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        
        settings = QSettings("MoPSP", "Settings")  # Stejný název jako při ukládání
        saved_width_value = settings.value("width_value", defaultValue=36)  # Defaultní hodnota 36, pokud není uložena žádná
        self.dlg.spinBox_sirkapas.setValue(int(saved_width_value))  # Nastavení hodnoty do QSpinBoxu
        self.dlg.spinBox_sirkapas2.setValue(float(saved_width_value))  # Nastavení hodnoty do QSpinBoxu

        #rozdělení vrstev podle typu geometrie
        layers = QgsProject.instance().layerTreeRoot().children()

        layers_line = []
        layers_polygon = []
        layers_raster = []

        layers_invalid_geometry = []

        #upozornění na vrstvy se shodnými jmény
        jmena0 = [l.name() for l in layers]
        jmena = list(dict.fromkeys(jmena0))
        if jmena != jmena0:
            self.iface.messageBar().pushMessage("Pozor",
                                                "V projektu jsou vrstvy se shodnými jmény",
                                                level=Qgis.MessageLevel.Warning, duration=5)
        for jmeno in jmena:
            vrstvy = QgsProject.instance().mapLayersByName(jmeno)
            for vrstva in vrstvy:
                try:
                    feats = vrstva.getFeatures()
                    for feat in feats:
                        geom = feat.geometry()
                        if geom.type() == QgsWkbTypes.GeometryType.PolygonGeometry:
                            layers_polygon.append(vrstva)
                            pocet_chyb = _run_checkvalidity(vrstva)
                            if pocet_chyb > 0:
                                layers_invalid_geometry.append(vrstva)
                            break

                        elif geom.type() == QgsWkbTypes.GeometryType.LineGeometry:
                            layers_line.append(vrstva)
                            pocet_chyb = _run_checkvalidity(vrstva)
                            if pocet_chyb > 0:
                                layers_invalid_geometry.append(vrstva)
                            break
                except:
                    layers_raster.append(vrstva)


        if len(layers_invalid_geometry) > 0:
            layers_invalid_geometry_neopraveno = []
            layers_invalid_geometry_opraveno = []
            for invalid_lyr in layers_invalid_geometry:
                repair_lyr = processing.run("native:buffer", {'INPUT':invalid_lyr,\
                                            'DISTANCE':0,'SEGMENTS':5,'END_CAP_STYLE':0,'JOIN_STYLE':0,'MITER_LIMIT':2, \
                                            'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                pocet_chyb_opraveneho = _run_checkvalidity(repair_lyr)
                if pocet_chyb_opraveneho == 0:
                    repair_lyr_name = invalid_lyr.name() + "_opraveno"
                    repair_lyr.setName(repair_lyr_name)
                    QgsProject.instance().addMapLayer(repair_lyr)
                    layers_invalid_geometry_opraveno.append(invalid_lyr.name())
                else:
                    layers_invalid_geometry_neopraveno.append(invalid_lyr.name())
                    

            self.okno = MoPSPWindow()
            if len(layers_invalid_geometry_opraveno) > 1:
                textik1 = "\n".join(layers_invalid_geometry_opraveno)
            elif len(layers_invalid_geometry_opraveno) == 1:
                textik1 = layers_invalid_geometry_opraveno[0]
            else:
                textik1 = ""

            if len(layers_invalid_geometry_neopraveno) > 1:
                textik2 = "\n".join(layers_invalid_geometry_neopraveno)
            elif len(layers_invalid_geometry_neopraveno) == 1:
                textik2 = layers_invalid_geometry_neopraveno[0]
            else:
                textik2 = ""
            self.okno.label_opravenevrstvy.setText(textik1)
            self.okno.label_chybnevrstvy.setText(textik2)

            self.okno.exec()

        else:
            pass
        #přidání vrstev do comboboxů

        def pridani_vrstev(combobox, lyr_typ):
            current_data = combobox.currentData()
            combobox.clear()
            for layer in lyr_typ:
                combobox.addItem(layer.name() + " (" + layer.crs().authid() + ")", layer)
            if (current_data in lyr_typ):
                index = combobox.findData(current_data)
                combobox.setCurrentIndex(index)

        pridani_vrstev(self.dlg.comboBox_maska, layers_polygon)
        pridani_vrstev(self.dlg.comboBox_trajektorie, layers_line)
        pridani_vrstev(self.dlg.comboBox_dmt, layers_raster)
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_np, layers_polygon, "bez stabilizačních ploch")
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_pasy, layers_polygon, "bez pásů")
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_agroenvi, layers_polygon, "bez agroenvi")

        # pro vykresleni linii 1
        pridani_vrstev(self.dlg.comboBox_klicovalinie, layers_line)
        pridani_vrstev(self.dlg.comboBox_maskalinie, layers_polygon)

        # pro simplifikaci linie
        pridani_vrstev(self.dlg.comboBox_hlavnilinka, layers_line)

        # pro svahovou dostupnost
        pridani_vrstev(self.dlg.comboBox_trajektorie2, layers_line)
        pridani_vrstev(self.dlg.comboBox_dmt2, layers_raster)
            
            
    def nacitani_vrstev(self):
        """
        Načte vrstvy do příslušných comboboxů
        """
        
        #CRS projektu nastavrno na 5514
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        
        """
        with open(f'{self.plugin_dir}/sirkapasu.txt', "r") as soubor:
            sirkapasu = int(soubor.readline())
            
        self.dlg.spinBox_sirkapas2.setValue(sirkapasu)
        self.dlg.spinBox_sirkapas.setValue(sirkapasu)
        """
        
        settings = QSettings("MoPSP", "Settings")  # Stejný název jako při ukládání
        saved_width_value = settings.value("width_value", defaultValue=36)  # Defaultní hodnota 100, pokud není uložena žádná
        self.dlg.spinBox_sirkapas.setValue(int(saved_width_value))  # Nastavení hodnoty do QSpinBoxu
        self.dlg.spinBox_sirkapas2.setValue(float(saved_width_value))  # Nastavení hodnoty do QSpinBoxu

        #rozdělení vrstev podle typu geometrie
        layers = QgsProject.instance().layerTreeRoot().children()

        layers_line = []
        layers_polygon = []
        layers_raster = []

        #upozornění na vrstvy se shodnými jmény
        jmena0 = [l.name() for l in layers]
        jmena = list(dict.fromkeys(jmena0))
        if jmena != jmena0:
            self.iface.messageBar().pushMessage("Pozor",
                                                "V projektu jsou vrstvy se shodnými jmény",
                                                level=Qgis.MessageLevel.Warning, duration=5)
        for jmeno in jmena:
            vrstvy = QgsProject.instance().mapLayersByName(jmeno)
            for vrstva in vrstvy:
                try:
                    feats = vrstva.getFeatures()
                    for feat in feats:
                        geom = feat.geometry()
                        if geom.type() == QgsWkbTypes.GeometryType.PolygonGeometry:
                            layers_polygon.append(vrstva)
                            break

                        elif geom.type() == QgsWkbTypes.GeometryType.LineGeometry:
                            layers_line.append(vrstva)
                            break
                except:
                    layers_raster.append(vrstva)


        def pridani_vrstev(combobox, lyr_typ):
            current_data = combobox.currentData()
            combobox.clear()
            for layer in lyr_typ:
                combobox.addItem(layer.name() + " (" + layer.crs().authid() + ")", layer)
            if (current_data in lyr_typ):
                index = combobox.findData(current_data)
                combobox.setCurrentIndex(index)

        pridani_vrstev(self.dlg.comboBox_maska, layers_polygon)
        pridani_vrstev(self.dlg.comboBox_trajektorie, layers_line)
        pridani_vrstev(self.dlg.comboBox_dmt, layers_raster)
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_np, layers_polygon, "bez stabilizačních ploch")
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_pasy, layers_polygon, "bez pásů")
        _pridani_vrstev_predvyplnen(self.dlg.comboBox_agroenvi, layers_polygon, "bez agroenvi")

        # pro vykresleni linii 1
        pridani_vrstev(self.dlg.comboBox_klicovalinie, layers_line)
        pridani_vrstev(self.dlg.comboBox_maskalinie, layers_polygon)

        # pro simplifikaci linie
        pridani_vrstev(self.dlg.comboBox_hlavnilinka, layers_line)

        # pro svahovou dostupnost
        pridani_vrstev(self.dlg.comboBox_trajektorie2, layers_line)
        pridani_vrstev(self.dlg.comboBox_dmt2, layers_raster)



    def vypocet_sklonu(self):
        """
        Výpočet podélného sklonu + pár dalších kontrol uskutečnitelných před tvorbou plánu osevu 
        """
        
        # Nastavení CRS projektu na EPSG:5514
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        
        # Inicializace proměnných
        EPSG = "5514"
        dist = self.dlg.spinBox_sirkapas.value()  # Šířka pásů
        kod_uzivatele = self.dlg.lineEdit_koduzivatele.text()  # Kód uživatele
        id_procesu = time.strftime("%y%m%d%H%M%S")  # ID procesu podle aktuálního času
        
        settings = QSettings("MoPSP", "Settings")  # uložení šířky pásu
        settings.setValue("width_value", dist)
        
        # Parametry pro různé limity
        limit_pro_limit30 = 30
        limit_pro_vymeru = 4  # ha
        limit_pro_zeop = 10
        limit_pro_maska3 = 30
        limit_pro_pasy_v_dpb = 99.99  # %
        
        # Nastavení hodnoty progress baru
        self.dlg.progressBar_vypocet.setValue(0)
        self.dlg.progressBar_vypocet.setFormat("Start")
        
        # Vytvoření základní složky a složky pro mezivýstupy
        if os.path.isdir(self.dlg.lineEdit_kostraprojektu.text()) == True:
            TEMPdir_path = self.dlg.lineEdit_kostraprojektu.text()
            
            # Cesta pro mezivýstupy
            if self.dlg.checkBox_neresitUcinnost.isChecked():
                TEMPdir = os.path.join(TEMPdir_path, f"Dokumentace_psp_{dist}m_{kod_uzivatele}_{id_procesu}", f"Test_psp_{dist}m_{kod_uzivatele}_{id_procesu}","mezivystupy")
            else:
                TEMPdir = os.path.join(TEMPdir_path, f"Dokumentace_psp_{dist}m_{kod_uzivatele}_{id_procesu}", f"Navrh_psp_{dist}m_{kod_uzivatele}_{id_procesu}","mezivystupy")
            os.makedirs(TEMPdir)
            
            # Cesta pro exportní složku
            if self.dlg.checkBox_neresitUcinnost.isChecked():
                Exportdir_path = os.path.join(self.dlg.lineEdit_kostraprojektu.text(), f"Dokumentace_psp_{dist}m_{kod_uzivatele}_{id_procesu}", f"Test_psp_{dist}m_{kod_uzivatele}_{id_procesu}")
            else:
                Exportdir_path = os.path.join(self.dlg.lineEdit_kostraprojektu.text(), f"Dokumentace_psp_{dist}m_{kod_uzivatele}_{id_procesu}", f"Navrh_psp_{dist}m_{kod_uzivatele}_{id_procesu}")
        
        # Funkce pro převod CRS na EPSG:5514
        def crs_na_5514(lyr):
            source_crs = QgsCoordinateReferenceSystem(lyr.crs().authid())  # Získání původního CRS vrstvy
            target_crs = QgsCoordinateReferenceSystem("EPSG:5514")  # Cílové CRS (EPSG:5514)
            
            lyr.startEditing()  # Zahájení úpravy vrstvy
            
            for feat in lyr.getFeatures():
                geom = feat.geometry()  # Získání geometrie
                geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))  # Transformace geometrie
                feat.setGeometry(geom)  # Nastavení nové geometrie
                lyr.updateFeature(feat)  # Aktualizace vrstvy
            
            lyr.setCrs(target_crs)  # Nastavení CRS vrstvy na cílové CRS
            lyr.commitChanges()  # Uložení změn
            lyr.setCrs(target_crs)  # Opětovné nastavení CRS pro vrstvu
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Načítání vrstev (------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        # DMT (Digitální model terénu)
        selectedLayerDMT = self.dlg.comboBox_dmt.currentData()
        LayerDMT = selectedLayerDMT.clone()
        
        # Trajektorie
        selectedLayerTrajektorie = self.dlg.comboBox_trajektorie.currentData()
        selectedLayerTrajektorie.selectAll()
        LayerTrajektorie = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerTrajektorie, 'OUTPUT': 'memory:'})['OUTPUT']
        selectedLayerTrajektorie.removeSelection()
        crs_na_5514(LayerTrajektorie)  # Transformace CRS vrstvy Trajektorie
        
        # Stabilizační plochy
        np_bool = False
        if _combo_ma_vrstvu(self.dlg.comboBox_np, "bez stabilizačních ploch"):
            selectedLayerNP = self.dlg.comboBox_np.currentData()
            selectedLayerNP.selectAll()
            LayerNP = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerNP, 'OUTPUT': 'memory:'})['OUTPUT']
            selectedLayerNP.removeSelection()
            crs_na_5514(LayerNP)  # Transformace CRS vrstvy Stabilizační plochy
            LayerNP.setName("Kopie_sp")  # Přejmenování vrstvy
            np_bool = True
        
        # Pásy
        pasy_bool = False
        if _combo_ma_vrstvu(self.dlg.comboBox_pasy, "bez pásů"):
            selectedLayerPasy = self.dlg.comboBox_pasy.currentData()
            selectedLayerPasy.selectAll()
            LayerPasy = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerPasy, 'OUTPUT': 'memory:'})['OUTPUT']
            selectedLayerPasy.removeSelection()
            crs_na_5514(LayerPasy)  # Transformace CRS vrstvy Pásy
            pasy_bool = True
            
        # Agroenvi
        agroenvi_bool = False
        if self.dlg.comboBox_agroenvikod.currentText() != "nevyskytuje se":
            if _combo_ma_vrstvu(self.dlg.comboBox_agroenvi, "bez agroenvi"):
                selectedLayerAgroenvi = self.dlg.comboBox_agroenvi.currentData()
                selectedLayerAgroenvi.selectAll()
                LayerAgroenvi = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerAgroenvi, 'OUTPUT': 'memory:'})['OUTPUT']
                selectedLayerAgroenvi.removeSelection()
                crs_na_5514(LayerAgroenvi)  # Transformace CRS vrstvy 
                LayerAgroenvi.setName("Agroenvi")  # Přejmenování vrstvy
                agroenvi_bool = True
        
        # Maska DPB
        selectedLayerMaska = self.dlg.comboBox_maska.currentData()
        selectedLayerMaska.selectAll()
        LayerMaska = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerMaska, 'OUTPUT': 'memory:'})['OUTPUT']
        selectedLayerMaska.removeSelection()
        crs_na_5514(LayerMaska)  # Transformace CRS vrstvy Maska DPB
        LayerMaska.setName("Maska")  # Přejmenování vrstvy
        # ---------------------------------------------------------------------------------------------------------------

        self.dlg.progressBar_vypocet.setValue(10)
        self.dlg.progressBar_vypocet.setFormat("Zpracovani vstupu")
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Tvorba ořezu DMR a svažitosti (----------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        # Výpočet ořezu DMR a svažitosti
        dx = selectedLayerDMT.rasterUnitsPerPixelX()  # X rozlišení rastru
        dy = selectedLayerDMT.rasterUnitsPerPixelY()  # Y rozlišení rastru
        
        # Tvorba dissolve masky
        LayerMaska_diss = processing.run("native:dissolve",
                                         {'INPUT': LayerMaska, 'FIELD': [], 'SEPARATE_DISJOINT': False,
                                          'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        
        # Zvětšení masky pro ořez o 80 m
        LayerMaska_plus = processing.run("native:buffer",
                                         {'INPUT': LayerMaska_diss, 'DISTANCE': 80, 'SEGMENTS': 5,
                                          'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 42, 'DISSOLVE': False,
                                          'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        # extent rastru jako polygon
        raster_extent = LayerDMT.extent()
        raster_geom = QgsGeometry.fromRect(raster_extent)

        # geometrie masky
        maska_geom = next(LayerMaska_plus.getFeatures()).geometry()

        # část masky mimo raster
        outside = maska_geom.difference(raster_geom)

        if not outside.isEmpty():

            QMessageBox.critical(
                None,
                "Chyba",
                "Polygon zájmového území zasahuje mimo rozsah DMT."
            )

            #raise QgsProcessingException("Polygon zájmového území zasahuje mimo rozsah DMT.")
            return
        
        orez_dmt_prep = processing.run("gdal:cliprasterbymasklayer", {'INPUT': LayerDMT,
                                                                     'MASK': LayerMaska_plus,
                                                                     'SOURCE_CRS': QgsCoordinateReferenceSystem(
                                                                         selectedLayerDMT.crs().authid()),
                                                                     'TARGET_CRS': QgsCoordinateReferenceSystem(
                                                                         'EPSG:' + EPSG),
                                                                     'TARGET_EXTENT': None, 'NODATA': -9999,
                                                                     'ALPHA_BAND': False, 'CROP_TO_CUTLINE': True,
                                                                     'KEEP_RESOLUTION': False, 'SET_RESOLUTION': False,
                                                                     'X_RESOLUTION': dx, 'Y_RESOLUTION': dy,
                                                                     'MULTITHREADING': False, 'OPTIONS': '',
                                                                     'DATA_TYPE': 0, 'EXTRA': '',
                                                                     'OUTPUT':TEMPdir + "//orez_dmt.tif"})
        
        
        orez_dmt = QgsRasterLayer(orez_dmt_prep["OUTPUT"], "orez_dmt", "gdal")
        # QgsProject.instance().addMapLayer(orez_dmt)  # Přidání vrstvy do projektu (volitelné)
        
        # Výpočet svažitosti z oříznutého DMT
        sklon_prep = processing.run("gdal:slope", {'INPUT': orez_dmt, 'BAND': 1, 'SCALE': 1, 'AS_PERCENT': False,
                                                   'COMPUTE_EDGES': True, 'ZEVENBERGEN': False, 'OPTIONS': '',
                                                   'EXTRA': '', 'OUTPUT': TEMPdir + "//slope.tif"})
        
        
        sklon_layer = QgsRasterLayer(sklon_prep["OUTPUT"], "sklon (°)", "gdal")
        target_crs = QgsCoordinateReferenceSystem("EPSG:5514")
        sklon_layer.setCrs(target_crs)
        sklon_layer.setName("Sklon °_" + id_procesu)  # Přejmenování vrstvy podle ID procesu
        
        # ------------------------------------------------------------------------------------------------------------------
        self.dlg.progressBar_vypocet.setValue(25)
        self.dlg.progressBar_vypocet.setFormat("Sklon nad 3 %")
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Tvorba masky, kde je plocha se sklonem nad 3 % (-----------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        # Třídění rastru podle sklonu
        reclass_slope_prep = processing.run("native:reclassifybytable",
                                            {'INPUT_RASTER': sklon_layer, 'RASTER_BAND': 1,
                                             'TABLE': ['1.718', '100', '1'], 'NO_DATA': -9999, 'RANGE_BOUNDARIES': 0,
                                             'NODATA_FOR_MISSING': True, 'DATA_TYPE': 5,
                                             'OUTPUT': TEMPdir + "//reclass_slope.tif"})
        
        reclass_slope_layer = QgsRasterLayer(reclass_slope_prep["OUTPUT"], "reclass sklon", "gdal")
        reclass_slope_layer.setCrs(target_crs)
        # QgsProject.instance().addMapLayer(reclass_slope_layer)  # Přidání vrstvy do projektu (volitelné)
        
        # Převod rastru na polygony
        reclass_slope_polyg_prep = processing.run("gdal:polygonize",
                                                  {'INPUT': reclass_slope_layer, 'BAND': 1, 'FIELD': 'VALUE',
                                                   'EIGHT_CONNECTEDNESS': False, 'EXTRA': '',
                                                   'OUTPUT': TEMPdir + "//reclass_slope_polyg.shp"})
        
        reclass_slope_polyg = QgsVectorLayer(reclass_slope_polyg_prep["OUTPUT"], "reclass sklon polyg", "ogr")
        reclass_slope_polyg.setCrs(target_crs)
        # QgsProject.instance().addMapLayer(reclass_slope_polyg)  # Přidání vrstvy do projektu (volitelné)
        
        # Zvětšení masky, dissolve a zmenšení pro výslednou masku
        buffer1 = processing.run("native:buffer",
                                 {'INPUT': reclass_slope_polyg,
                                  'DISTANCE': 0.5, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                  'MITER_LIMIT': 2,
                                  'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        # QgsProject.instance().addMapLayer(buffer1)  # Přidání vrstvy do projektu (volitelné)
        
        buffer1_diss = processing.run("native:dissolve", {
            'INPUT': buffer1,
            'FIELD': ['VALUE'], 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        
        maska_3pr = processing.run("native:buffer",
                                   {'INPUT': buffer1_diss,
                                    'DISTANCE': -0.5, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                    'MITER_LIMIT': 2,
                                    'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        # QgsProject.instance().addMapLayer(maska_3pr)  # Přidání vrstvy do projektu (volitelné)
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Vytvoření filnálnich vrstev, kde se spojí výsledky jednotlivých DPB (--------------------------
        # ---------------------------------------------------------------------------------------------------------------
        limit30_all_fields = {"CTVEREC": QVariant.String, 
                              "ZKOD": QVariant.String, 
                              "JI": QVariant.String, 
                              "PROJEKT_ID": QVariant.String, 
                              "P_SKL(%)": QVariant.Double, 
                              "P_SKLstav": QVariant.String}
        dpb_fields =    {"CTVEREC": QVariant.String,
                        "ZKOD": QVariant.String,
                        "JI": QVariant.String,
                        "PROJEKT_ID": QVariant.String,
                        "KULTURA": QVariant.String,
                        "UCINNEDPB": QVariant.String,
                        "SKL<3%(%)": QVariant.Double,
                        "P_SKL(%)": QVariant.Double,
                        "ZEOP(%)": QVariant.Double,
                        "ZPvDPB(%)": QVariant.Double,
                        "STPvDPB(%)": QVariant.Double,
                        "AEvDPB(%)": QVariant.Double,
                        "PASDPB(%)": QVariant.Double,
                        "VYMERA": QVariant.String,
                        "KULTURstav": QVariant.String,
                        "SKL<3%stav": QVariant.String,
                        "P_SKLstav": QVariant.String,
                        "ZEOPstav": QVariant.String,
                        "PASDPBstav": QVariant.String,
                        "DSOnaDPB": QVariant.String,
                        "STPnaDSO": QVariant.String,
                        "ZPvDPBstav": QVariant.String,
                        "pocet_chyb": QVariant.Int,
                        "stav_DPB": QVariant.String}
        trajektorie_fields = {"SIRKA_PASU": QVariant.Int}
        maska3_fields = {"CTVEREC": QVariant.String,
                        "ZKOD": QVariant.String,
                        "JI": QVariant.String,
                        "PROJEKT_ID": QVariant.String,
                        "SKL<3%(%)": QVariant.Double,
                        "SKL<3%(ha)": QVariant.Double,
                        "plocha(ha)": QVariant.Double}
        siroke_pasy_fields = {"typ": QVariant.String,
                             "NEO(%)": QVariant.Double}
        dpb_spatne_sirky_fields =   {"Sirka pasu zadana": QVariant.Int,
                                    "Sirka pasu odhadovana": QVariant.Int}
        trajektorie_kontrola_fields = {"stav": QVariant.String}
        polygony_ohrozenost_maska_union_all_fields =    {"CTVEREC": QVariant.String,
                                                        "ZKOD": QVariant.String,
                                                        "result": QVariant.String,
                                                        "result_2": QVariant.String}
        polygony_ohrozenost_maska_union_singleparts_all_fields =    {"CTVEREC": QVariant.String,
                                                                    "ZKOD": QVariant.String,
                                                                    "result": QVariant.String,
                                                                    "podelny_sklon": QVariant.String}

        limit30_all = generate_layer("Polygon?crs=EPSG:5514", "Limit30_all", limit30_all_fields)
        dpb_all = generate_layer("Polygon?crs=EPSG:5514", "DPB_all", dpb_fields)
        trajektorie_all = generate_layer("LineString?crs=EPSG:5514", "trajektorie", trajektorie_fields)
        maska3_all = generate_layer("Polygon?crs=EPSG:5514", "maska3p", maska3_fields)
        dpb_spatne_sirky_all = generate_layer("Polygon?crs=EPSG:5514", "špatná šířka", dpb_spatne_sirky_fields)
        trajektorie_kontrola_all = generate_layer("LineString?crs=EPSG:5514", "trajektorie_kontrola", trajektorie_kontrola_fields)
        polygony_ohrozenost_maska_union_all = generate_layer("Polygon?crs=EPSG:5514", "union_all", polygony_ohrozenost_maska_union_all_fields)
        polygony_ohrozenost_maska_union_singleparts_all = generate_layer("Polygon?crs=EPSG:5514", "union_single_all", polygony_ohrozenost_maska_union_singleparts_all_fields)
        siroke_pasy_all = generate_layer("Polygon?crs=EPSG:5514", "siroke_pasy_all", siroke_pasy_fields)

        dso_all = QgsVectorLayer("Polygon?crs=EPSG:5514", "DSO_all", "memory")

        zeop_all_fields = {"CTVEREC": QVariant.String, 
                              "ZKOD": QVariant.String, 
                              "JI": QVariant.String, 
                              "PROJEKT_ID": QVariant.String, 
                              "ZEOP(%)": QVariant.Double, 
                              "ZEOPstav": QVariant.String}
        zeop_all = generate_layer("Polygon?crs=EPSG:5514", "ZEOP_all", zeop_all_fields)
        zeop_all_provider = zeop_all.dataProvider()
        zeop_fields = [QgsField("VYMZEOP", QVariant.Double, len=10, prec=4)]
        zeop_all_provider.addAttributes(zeop_fields)
        zeop_all.updateFields()

        kostra_fields =     {"CTVEREC": QVariant.String,
                            "ZKOD": QVariant.String,
                            "PLOD_ID": QVariant.String,
                            "PLODINA_AK": QVariant.String,
                            "JI": QVariant.String,
                            "SCHEMA": QVariant.String,
                            "SCELEK_ID": QVariant.String,
                            "ZAKRES_ID": QVariant.String}
        kostra_psp_all = generate_layer("Polygon?crs=EPSG:5514", "kostra_all", kostra_fields)
        kostra_psp_all_provider = kostra_psp_all.dataProvider()
        vymzakres_field = QgsField("VYMZAKRES", QVariant.Double, len=10, prec=4)
        kostra_psp_all_provider.addAttributes([vymzakres_field])
        kostra_psp_all.updateFields()

        # ---------------------------------------------------------------------------------------------------------------
        
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Funkce pro výpočty (---------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------

        # Funkce pro odstraneni Z-souradnic z geometrie
        def odstranit_z_souradnice(geom):
            if geom.isMultipart():
                parts = geom.asMultiPolyline()
                new_parts = []
                for part in parts:
                    new_part = [QgsPoint(p.x(), p.y()) for p in part]  # Odebrání Z-souřadnic
                    new_parts.append(new_part)
                return QgsGeometry.fromMultiPolyline(new_parts)
            else:
                part = geom.asPolyline()
                new_part = [QgsPoint(p.x(), p.y()) for p in part]  # Odebrání Z-souřadnic
                return QgsGeometry.fromPolyline(new_part)

        # pomocné funkce
            
        def morfologicky_opening(lyr, vzdalenost):
            minus = processing.run("native:buffer", {'INPUT':lyr,
                                             'DISTANCE':-vzdalenost,
                                             'SEGMENTS':5,
                                             'END_CAP_STYLE':1,
                                             'JOIN_STYLE':1,
                                             'MITER_LIMIT':2,
                                             'DISSOLVE':False,
                                             'SEPARATE_DISJOINT':False,
                                             'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
            
            plus = processing.run("native:buffer", {'INPUT':minus,
                                             'DISTANCE':vzdalenost,
                                             'SEGMENTS':5,
                                             'END_CAP_STYLE':1,
                                             'JOIN_STYLE':1,
                                             'MITER_LIMIT':2,
                                             'DISSOLVE':False,
                                             'SEPARATE_DISJOINT':False,
                                             'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
            
            return plus
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Stahování WFS (--------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------

        #stažení ploch NEO
        neo_bool = False
        extent = LayerMaska.extent()
        xmin = int(extent.xMinimum()) - 100
        ymin = int(extent.yMinimum()) - 100
        xmax = int(extent.xMaximum()) + 100
        ymax = int(extent.yMaximum()) + 100
        bbox = f"{xmin},{ymin},{xmax},{ymax}"
        print(bbox)
        try:
            uri = "https://iprod.vumop.cz/wfs/neo.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:neo&bbox=" + bbox
            neo_vlayer = QgsVectorLayer(uri, "NEO", "ogr")
            # Nastavení CRS
            crs = neo_vlayer.crs()
            crs.createFromId(5514)
            neo_vlayer.setCrs(crs)
            # Oprava geometrie
            neo_lyr = processing.run("native:fixgeometries",
                           {'INPUT': neo_vlayer, 'METHOD': 1,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            # QgsProject.instance().addMapLayer(dso_vlayer)
            if neo_lyr.isValid():
                neo_bool = True
            else:
                raise ValueError("Po opravě geometrie je vrstva NEO neplatná.")
        except requests.exceptions.RequestException as e:
            self.iface.messageBar().pushMessage("Chyba připojení", f"Nepodařilo se připojit k WFS službě (NEO): {e}", level=Qgis.MessageLevel.Critical)
        except ValueError as e:
            # Chyba při validaci vrstvy
            self.iface.messageBar().pushMessage("Chyba validace (NEO)", str(e), level=Qgis.MessageLevel.Critical)
        except Exception as e:
            # Ostatní chyby
            self.iface.messageBar().pushMessage("Chyba", f"Došlo k neočekávané chybě (NEO): {e}", level=Qgis.MessageLevel.Critical)

            
        if self.dlg.checkBox_neresitUcinnost.isChecked():
            dpb_vlayer = LayerMaska
            dpb_vlayer_bool = True
        else:
            #stažení DPB
            dpb_vlayer_bool = False
            try:
                uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_DPB_UCINNE&bbox=" + bbox
                dpb_vlayer0 = QgsVectorLayer(uri, "DPB_wfs", "ogr")
    
                crs = dpb_vlayer0.crs()
                crs.createFromId(5514)
                dpb_vlayer0.setCrs(crs)
                
                dpb_vlayer0.selectAll()
                dpb_vlayer = processing.run("native:saveselectedfeatures", {'INPUT': dpb_vlayer0, 'OUTPUT': 'memory:'})['OUTPUT']
                dpb_vlayer0.removeSelection()
    
                
                dpb_vlayer.setName("DPB_účinné")
                #QgsProject.instance().addMapLayer(dpb_vlayer0)
                dpb_vlayer_bool = True
    
            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu DPB_UCINNE z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
        
        dso_bool = False
        extent = LayerMaska.extent()
        xmin = int(extent.xMinimum()) - 100
        ymin = int(extent.yMinimum()) - 100
        xmax = int(extent.xMaximum()) + 100
        ymax = int(extent.yMaximum()) + 100
        bbox = f"{xmin},{ymin},{xmax},{ymax}"
        print(bbox)
        try:
            uri = "https://iprod.vumop.cz/wfs/dso.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:dso5&bbox=" + bbox
            DSO_vlayer = QgsVectorLayer(uri, "DSO5ha", "ogr")
            crs = DSO_vlayer.crs()
            crs.createFromId(5514)
            DSO_vlayer.setCrs(crs)
            dso_bool = True
            QgsProject.instance().addMapLayer(DSO_vlayer)
        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu DSO 5 ha z WFS služby",
                                                level=Qgis.MessageLevel.Warning)   
        if dso_bool:
            DSO_pasy = processing.run("native:buffer", {'INPUT':DSO_vlayer,'DISTANCE':7.5,'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            
        #stažení KP i vnitřních
        kp_vlayer_bool = False
        try:
            uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_EVP_UCINNE&bbox=" + bbox
            kp_vlayer0 = QgsVectorLayer(uri, "DPB_wfs", "ogr")
            # WFS/OGR má často neplatné CRS; saveselectedfeatures pak v QGIS 4 vrátí 0 prvků
            kp_vlayer0.setCrs(QgsCoordinateReferenceSystem("EPSG:5514"))
            kp_vlayer = kp_vlayer0.materialize(QgsFeatureRequest())
            
            kp_vlayer.startEditing()
            kp_vlayer_provider = kp_vlayer.dataProvider()
            kp_vlayer_fields = [QgsField("CTVEREC", QVariant.String),
                           QgsField("ZKOD", QVariant.String) ]
            kp_vlayer_provider.addAttributes(kp_vlayer_fields)
            kp_vlayer.updateFields()
            # WFS/OGR může vracet různou velikost písmen v názvech polí
            _kp_flds = {n.lower(): n for n in kp_vlayer.fields().names()}
            _src_ctverec = _kp_flds.get("ctverec")
            _src_zkod = _kp_flds.get("zkracenykod")
            for feat in kp_vlayer.getFeatures():
                if _src_ctverec:
                    feat["CTVEREC"] = feat[_src_ctverec]
                if _src_zkod:
                    feat["ZKOD"] = feat[_src_zkod]
                kp_vlayer.updateFeature(feat)
            kp_vlayer.commitChanges()
            # WFS LPIS_EVP_UCINNE občas vrátí totožné polygony vícekrát → jinak E přes sebe v kostra_psp
            if kp_vlayer.featureCount() > 0:
                kp_vlayer = processing.run("native:deleteduplicategeometries", {
                    'INPUT': kp_vlayer, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            
            kp_vlayer.setName("EVP_účinné")
            #QgsProject.instance().addMapLayer(kp_vlayer)
            kp_vlayer_bool = kp_vlayer.featureCount() > 0

        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu LPIS_EVP_UCINNE z WFS služby",
                                                level=Qgis.MessageLevel.Warning)
        #----------------------------------------------------------------------------------------------------------------
 
    
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Průchod jednotlivými DPB a výpočty v jejich rámci (--------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        pocet_dpb = LayerMaska.featureCount()
        pocitadlo_dpb = 1

        for feat_dpb_base in LayerMaska.getFeatures():

            #převod feature dpb na vrstvu
            """LayerMaska.select(feat_dpb_base.id())
            LayerDPB_i = processing.run("native:saveselectedfeatures", {'INPUT': LayerMaska, 'OUTPUT': 'memory:'})['OUTPUT']
            LayerMaska.removeSelection()"""
            LayerDPB_i = LayerMaska.materialize(QgsFeatureRequest().setFilterFids([feat_dpb_base.id()]))
            #QgsProject.instance().addMapLayer(LayerDPB_i)

            #přiřazení zkodu a ctverce
            if ("ZKOD") in LayerMaska.fields().names():
                zkod = feat_dpb_base["ZKOD"]
            else:
                zkod = NULL
            if ("CTVEREC") in LayerMaska.fields().names():
                ctverec = feat_dpb_base["CTVEREC"]
            else:
                ctverec = NULL    
                            
            zeop_procenta = 0
            limit30_procenta = 0
            plocha_dpb = feat_dpb_base.geometry().area()/10000
            dso_i_bool = False
            plocha_dso_v_dpb = 0
            plocha_dso_v_np = 0
            vyhodnoceni_dpb = "NEŘEŠENO"
            kultury_s = ""
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Oříznutí vrstev podle DPB (--------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            LayerTrajektorie_i, traj_i_bool = clip_lyr(LayerTrajektorie, LayerDPB_i)
            np_i_bool = False
            if np_bool:
                LayerNP_i, np_i_bool = clip_lyr(LayerNP, LayerDPB_i, dissolving=True)
            maska_3pr_i, maska3_i_bool = clip_lyr(maska_3pr, LayerDPB_i) 

            aenvi_i_bool = False
            if agroenvi_bool:
                LayerAenvi_i, aenvi_i_bool = clip_lyr(LayerAgroenvi, LayerDPB_i, dissolving=True)  
                if ((aenvi_i_bool == True) and (np_i_bool==True)):
                    LayerAE_i_rezNP = processing.run("native:difference", {'INPUT':LayerAenvi_i,'OVERLAY':LayerNP_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                    LayerAenvi_i = processing.run("native:multiparttosingleparts", {'INPUT':LayerAE_i_rezNP,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    LayerAenvi_i.startEditing()
                    for feat in LayerAenvi_i.getFeatures():
                        if feat.geometry().area() < 1:
                            LayerAenvi_i.deleteFeature(feat.id())
                    LayerAenvi_i.commitChanges()

            pasy_i_bool = False
            if pasy_bool:
                LayerPasy_i, pasy_i_bool = clip_lyr(LayerPasy, LayerDPB_i)
                if ((pasy_i_bool == True) and (np_i_bool==True)):
                    LayerPasy_i = processing.run("native:difference", {'INPUT':LayerPasy_i,'OVERLAY':LayerNP_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                if ((pasy_i_bool == True) and (aenvi_i_bool==True)):
                    LayerPasy_i = processing.run("native:difference", {'INPUT':LayerPasy_i,'OVERLAY':LayerAenvi_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                if pasy_i_bool:
                    LayerPasy_i = processing.run("native:multiparttosingleparts", {'INPUT':LayerPasy_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    LayerPasy_i.startEditing()
                    for feat in LayerPasy_i.getFeatures():
                        if feat.geometry().area() < 1:
                            LayerPasy_i.deleteFeature(feat.id())
                    LayerPasy_i.commitChanges() 

             
        
            maska3p_area = 0
            maska3p_i_area = 0
            maska3p_procenta = 100.0          
            if maska3_i_bool:
                # maska se sklonem nad 3 %
                #mazani_poli(maska_3pr_i, [])
                maska_3pr_i.startEditing()
                new_fields = [QgsField("SKL<3%(%)", QVariant.Double),
                              QgsField("plocha(ha)", QVariant.Double),
                              QgsField("SKL<3%(ha)", QVariant.Double),
                              QgsField("ZKOD", QVariant.String),
                              QgsField("CTVEREC", QVariant.String)]
                maska_3pr_i.dataProvider().addAttributes(new_fields)
                maska_3pr_i.updateFields()

                maska3p_i_area = 0
                for feat in maska_3pr_i.getFeatures():
                    maska3p_area = feat.geometry().area()/10000
                    maska3p_i_area = maska3p_i_area + maska3p_area

                    feat["SKL<3%(ha)"] = round((plocha_dpb - maska3p_area),4)
                    feat["plocha(ha)"] = round((plocha_dpb),4)
                    maska3p_procenta = round((100 - maska3p_area * 100 / plocha_dpb), 2)
                    feat["SKL<3%(%)"] = maska3p_procenta
                    feat["ZKOD"] = zkod
                    feat["CTVEREC"] = ctverec
                    maska_3pr_i.updateFeature(feat)
                maska_3pr_i.commitChanges()
                maska_3pr_i.setName("sklon nad 3 %")
                #QgsProject.instance().addMapLayer(maska_3pr_i)
                
                """maska3p_i_area = 0
                for feat in maska_3pr_i.getFeatures():
                    maska3p_i_area = maska3p_i_area + feat.geometry().area()/10000"""
                
            zeop_i_bool = False
            limit30_i_bool = False
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------)                           (--------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            
            #DPB bez ďur -> spojení vnitřních dpb a kp do spojených vnitřních prvků (bez ďur)
            #určení minima pro STP (bez DSO) + vnitřní prvky? + ...       
            DPB_i_bez_dur = processing.run("native:deleteholes",{'INPUT': LayerDPB_i, 'MIN_AREA': 0, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            if dpb_vlayer_bool:
                # QGIS 4: při „Neřešit účinnost“ vrací saveselectedfeatures bez výběru celý DPB
                if _IS_QGIS4 and self.dlg.checkBox_neresitUcinnost.isChecked():
                    dpb_vlayer_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "dpb_vlayer_i_empty", "memory")
                else:
                    dpb_vlayer_i0 = processing.run("native:clip",{'INPUT': dpb_vlayer, 'OVERLAY': DPB_i_bez_dur, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    if not self.dlg.checkBox_neresitUcinnost.isChecked():
                        ids = [feat.id() for feat in dpb_vlayer_i0.getFeatures() if feat["kultura"][:20] != "standardní orná půda"]
                        dpb_vlayer_i0.selectByIds(ids)
                    dpb_vlayer_i1 = processing.run("native:saveselectedfeatures",{'INPUT': dpb_vlayer_i0, 'OUTPUT': 'memory:'})["OUTPUT"]
                    dpb_vlayer_i0.removeSelection()
                    #dpb_vlayer_i1 = processing.run("native:extractbyexpression", {'INPUT':dpb_vlayer_i0,'EXPRESSION':' "kultura" = \'úhor\'','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    dpb_vlayer_i = processing.run("native:deleteholes",{'INPUT': dpb_vlayer_i1, 'MIN_AREA': 0, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            if kp_vlayer_bool:
                kp_vlayer_i0 = processing.run("native:clip",{'INPUT': kp_vlayer, 'OVERLAY': DPB_i_bez_dur, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                kp_vlayer_i = processing.run("native:deleteholes",{'INPUT': kp_vlayer_i0, 'MIN_AREA': 0, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]


            vnitrni_prvky_bool = False
            dpb_count = dpb_vlayer_i.featureCount() if dpb_vlayer_bool else 0
            kp_count = kp_vlayer_i.featureCount() if kp_vlayer_bool else 0
            vnitrni_prvky_bool = (dpb_count > 0 or kp_count > 0)
            if vnitrni_prvky_bool:       
                if dpb_count > 0 and kp_count > 0:
                    vnitrni_prvky0 = processing.run("native:mergevectorlayers",{'LAYERS': [dpb_vlayer_i, kp_vlayer_i],'CRS': QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                else:
                    vnitrni_prvky0 = dpb_vlayer_i if dpb_count > 0 else kp_vlayer_i

                vnitrni_prvky = processing.run("native:dissolve", {'INPUT': vnitrni_prvky0,'FIELD': [],'SEPARATE_DISJOINT': False,'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_prvky_bool = True

            #určení minima pro STP (bez DSO)
            if vnitrni_prvky_bool:
                DPB_bez_vnitrnich_prvku = processing.run("native:difference", {'INPUT':DPB_i_bez_dur,'OVERLAY':vnitrni_prvky,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
            else:
                DPB_bez_vnitrnich_prvku = DPB_i_bez_dur

            STP_ringbuffery = processing.run("native:multiringconstantbuffer", {'INPUT':DPB_bez_vnitrnich_prvku,'RINGS':1,'DISTANCE':-15,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_ringbuffer = processing.run("native:extractbyattribute", {'INPUT':STP_ringbuffery,'FIELD':'distance','OPERATOR':0,'VALUE':'-15','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_ringbuffer = processing.run("native:clip", {'INPUT':STP_ringbuffer,'OVERLAY':LayerDPB_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            #přidání DSO
            DSO_pasy_i = processing.run("native:clip", {'INPUT':DSO_pasy,'OVERLAY':LayerDPB_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_zaklad = processing.run("native:mergevectorlayers", {'LAYERS':[STP_ringbuffer, DSO_pasy_i],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_zaklad = processing.run("native:dissolve", {'INPUT':STP_zaklad,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_zaklad.setName("STP povinné minimum")
            #QgsProject.instance().addMapLayer(STP_zaklad)
                    
            #určeni ďur - i pro další práci
            Layer_diry_i = processing.run("native:difference", {'INPUT':DPB_bez_vnitrnich_prvku,'OVERLAY':LayerDPB_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
            Layer_diry_i.startEditing()
            for feat in Layer_diry_i.getFeatures():
                if feat.geometry().area() < 1:
                    Layer_diry_i.deleteFeature(feat.id())
            Layer_diry_i.commitChanges()
            diry_bool = False
            if Layer_diry_i.featureCount() > 0:
                Layer_diry_i.setName("Ďury")
                diry_bool = True
                #QgsProject.instance().addMapLayer(Layer_diry_i)               
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Rozdělení trajektorií v místě s ostrým úhlem (-------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            
            # Overeni platnosti vrstvy a pridani do projektu
            if traj_i_bool:
                if not LayerTrajektorie_i.isValid():
                    print("Vrstva nebyla uspesne nactena!")
                else:
                    # QgsProject.instance().addMapLayer(LayerTrajektorie)
                    print("Vrstva byla uspesne nactena a pridana do projektu.")

                    # Rozpusteni vrstvy (nastroj "Dissolve")
                    rozpkrivka = processing.run("native:dissolve",
                                                {'INPUT': LayerTrajektorie_i,
                                                'FIELD': [],
                                                'SEPARATE_DISJOINT': False,
                                                'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                    # Pridani rozpustene vrstvy do projektu
                    rozpkrivka.setName("rozpkrivka")
                    # QgsProject.instance().addMapLayer(rozpkrivka)
                    print("Vrstva byla rozpustena a pridana jako 'rozpkrivka'.")

                    # Rozdeleni multipartnich geometrii na jednotlivé části (nastroj "Multipart to singleparts")
                    singkrivka = processing.run("native:multiparttosingleparts",
                                                        {'INPUT': rozpkrivka,
                                                        'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    # Pridani singl vrstvy do projektu
                    singkrivka.setName("singkrivka")
                    # QgsProject.instance().addMapLayer(singkrivka)
                    print("Vrstva byla rozdelena na jednotlive casti jako 'singkrivka'.")

                    # Odstraneni Z-souradnic z vrstvy "singkrivka" a vytvoreni nove vrstvy "NOZ"
                    noz_layer = QgsVectorLayer("LineString?crs=EPSG:5514", "NOZ", "memory")
                    noz_provider = noz_layer.dataProvider()
                    noz_provider.addAttributes(singkrivka.fields())
                    noz_layer.updateFields()

                    for feature in singkrivka.getFeatures():
                        geom = feature.geometry()
                        new_geom = odstranit_z_souradnice(geom)  # Odstraneni Z-souřadnic
                        new_feature = QgsFeature(noz_layer.fields())
                        new_feature.setGeometry(new_geom)
                        new_feature.setAttributes(feature.attributes())
                        noz_provider.addFeature(new_feature)

                    noz_layer.updateExtents()
                    # QgsProject.instance().addMapLayer(noz_layer)
                    print("Vrstva 'singkrivka' byla transformovana do vrstvy 'NOZ' bez Z-souřadnic.")

                    LayerTrajektorie_1 = \
                        processing.run("native:deleteduplicategeometries",
                                       {'INPUT': noz_layer, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                            "OUTPUT"]
                    # QgsProject.instance().addMapLayer(LayerTrajektorie_1)

                    noz_layer = processing.run("native:multiparttosingleparts",
                                               {'INPUT': LayerTrajektorie_1,
                                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    # Rozdeleni lomovych bodu v uhlu mensim nez 120 stupnu a vetsim nez 240 stupnu na vrstve "NOZ"
                    ostreuhly_layer = QgsVectorLayer("LineString?crs=EPSG:5514", "ostreuhly", "memory")
                    ostreuhly_provider = ostreuhly_layer.dataProvider()
                    ostreuhly_provider.addAttributes(noz_layer.fields())  # Pouziti vrstvy NOZ
                    ostreuhly_layer.updateFields()

                    for feature in noz_layer.getFeatures():  # Pouziti vrstvy NOZ
                        geom = feature.geometry()
                        line = geom.asPolyline()  # Ziskani linie
                        if len(line) < 3:
                            pass
                        # Rozdelovani podle uhlu
                        segment = [QgsPoint(p) for p in line[:1]]  # Používáme QgsPoint namísto QgsPointXY
                        for i in range(1, len(line) - 1):
                            uhel = vypocet_uhlu(QgsPoint(line[i - 1]), QgsPoint(line[i]),
                                                QgsPoint(line[i + 1]))  # Konverze na QgsPoint
                            if uhel < 140 or uhel > 240:  # Rozdeleni v lomovych bodech
                                segment.append(QgsPoint(line[i]))
                                segment_geom = QgsGeometry.fromPolyline(segment)
                                new_feature = QgsFeature(ostreuhly_layer.fields())
                                new_feature.setGeometry(segment_geom)
                                new_feature.setAttributes(feature.attributes())
                                ostreuhly_provider.addFeature(new_feature)
                                segment = [QgsPoint(line[i])]
                            else:
                                segment.append(QgsPoint(line[i]))
                        segment.append(QgsPoint(line[-1]))
                        segment_geom = QgsGeometry.fromPolyline(segment)
                        new_feature = QgsFeature(ostreuhly_layer.fields())
                        new_feature.setGeometry(segment_geom)
                        new_feature.setAttributes(feature.attributes())
                        ostreuhly_provider.addFeature(new_feature)

                    ostreuhly_layer.updateExtents()
                    # QgsProject.instance().addMapLayer(ostreuhly_layer)
                    print("Vrstva 'ostreuhly' byla vytvorena a pridana do projektu.")

                LayerTrajektorie_i = ostreuhly_layer
                # Zobrazeni vsech vrstev
                print("Vizualizace všech vrstev byla dokončena.")
                # QgsProject.instance().addMapLayer(LayerTrajektorie)
                # ---------------------------------------------------------------------------------------------------------------
                
                
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Vytvoření segmentů po 10 m (-------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------    

            if traj_i_bool:
                kolmice = QgsVectorLayer("LineString?crs=epsg:5514", "kolmice", "memory")
                kolmice_prov = kolmice.dataProvider()

                # Overeni platnosti vrstvy a pridani do projektu
                if not LayerTrajektorie_i.isValid():
                    print("Vrstva nebyla uspesne nactena! ")
                else:
                    # QgsProject.instance().addMapLayer(layer)
                    print("Vrstva byla uspesne nactena a pridana do projektu.")

                    # Nacteni CRS puvodni vrstvy (pokud je treba)
                    crs = LayerTrajektorie_i.crs().authid()
                    print(f"CRS puvodni vrstvy: {crs}")

                    # Delka segmentu
                    delka_segmentu = 10.0

                    # Pruchod jednotlivymi prvky vrstvy a rozdeleni krivek
                    for feature in LayerTrajektorie_i.getFeatures():
                        geom = feature.geometry()
                        if geom.isNull():
                            continue

                        pocet_segmentu = 0
                        # Kontrola, zda je geometrie typu linie

                        if geom.type() != QgsWkbTypes.GeometryType.LineGeometry:
                            print("Prvek neni krivka, preskocen.")
                            continue

                        docasna_linka = QgsVectorLayer("LineString?crs=epsg:5514", "docasna", "memory")
                        linka_prov = docasna_linka.dataProvider()
                        feat_linka = QgsFeature()
                        feat_linka.setGeometry(geom)
                        linka_prov.addFeatures([feat_linka])
                        docasna_linka.updateExtents()

                        docasne_linky = processing.run("native:multiparttosingleparts",
                                                       {'INPUT': docasna_linka, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        # QgsProject.instance().addMapLayer(docasne_linky)

                        # smazat z docasne linky ty linky co maji mensi delku jak 1 m
                        docasne_linky.startEditing()
                        for feat in docasne_linky.getFeatures():
                            if feat.geometry().length() < 1:
                                docasne_linky.deleteFeature(feat.id())
                        docasne_linky.commitChanges()

                        #QgsProject.instance().addMapLayer(docasne_linky)

                        for f in docasne_linky.getFeatures():
                            geom_docasne = f.geometry()

                            segment_layer = QgsVectorLayer("Point?crs=EPSG:5514", "Dělící body", "memory")
                            segment_layer_pr = segment_layer.dataProvider()

                            segments = rozdel_krivku_na_segmenty(geom_docasne, delka_segmentu)

                            for segment_geom in segments:
                                new_feature = QgsFeature(segment_layer.fields())
                                new_feature.setGeometry(segment_geom)
                                new_feature.setAttributes(feature.attributes())
                                segment_layer_pr.addFeature(new_feature)
                                pocet_segmentu += 1

                            # Aktualizace rozsahu nove vrstvy a jeji pridani do projektu
                            segment_layer.updateExtents()
                            QgsProject.instance().addMapLayer(segment_layer)

                            kolmicky = processing.run("native:geometrybyexpression",
                                                      {'INPUT': docasne_linky, 'OUTPUT_GEOMETRY': 1, 'WITH_Z': False,
                                                       'WITH_M': False,
                                                       'EXPRESSION': "collect_geometries (\r\n    array_foreach (\r\n        aggregate( \r\n            'Dělící body', \r\n            'array_agg', \r\n            $geometry\r\n        ),\r\n        extend (\r\n            make_line(\r\n                line_interpolate_point( \r\n                    $geometry,\r\n                    line_locate_point($geometry,@element)\r\n                ),\r\n            project (\r\n                 line_interpolate_point( \r\n                    $geometry,\r\n                    line_locate_point($geometry,@element)\r\n                ),\r\n                10,\r\n                radians(\r\n                    90+line_interpolate_angle( \r\n                        $geometry,\r\n                        line_locate_point($geometry,@element)\r\n            )))),\r\n            10,\r\n            0\r\n)))",
                                                       'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            #QgsProject.instance().addMapLayer(kolmicky)

                            for feat_kolmicky in kolmicky.getFeatures():
                                feat_kolmice = QgsFeature()
                                feat_kolmice.setGeometry(feat_kolmicky.geometry())
                                kolmice_prov.addFeatures([feat_kolmice])

                            # Vypis poctu vytvorenych segmentu
                            print(f"Pocet vytvorenych segmentu: {pocet_segmentu}")
                            QgsProject.instance().removeMapLayer(segment_layer.id())

                kolmice.updateExtents()
                # QgsProject.instance().addMapLayer(kolmice)

                segmenty = processing.run("native:splitwithlines",
                                          {'INPUT': LayerTrajektorie_i, 'LINES': kolmice,
                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(segmenty)

                segmenty.startEditing()
                segmenty_provider = segmenty.dataProvider()
                new_fields = [QgsField("Slope_%", QVariant.Double),
                              QgsField("z_first", QVariant.Double),
                              QgsField("z_last", QVariant.Double),
                              QgsField("delka_seg", QVariant.Double)]
                segmenty_provider.addAttributes(new_fields)
                segmenty.updateFields()
                for feat in segmenty.getFeatures():
                    linka = feat.geometry()
                    body = [v for v in linka.vertices()]
                    kraj1 = body[0]
                    kraj2 = body[-1]
                    delka = linka.length()
                    vyska1, res = orez_dmt.dataProvider().sample(QgsPointXY(kraj1.x(), kraj1.y()), 1)
                    vyska2, res = orez_dmt.dataProvider().sample(QgsPointXY(kraj2.x(), kraj2.y()), 1)
                    sklon = (abs(vyska1 - vyska2)) * 100 / delka
                    sklon = round(sklon, 1)
                    feat["Slope_%"] = sklon
                    feat["z_first"] = vyska1
                    feat["z_last"] = vyska2
                    feat["delka_seg"] = round(linka.length(), 2)
                    segmenty.updateFeature(feat)
                segmenty.commitChanges()
                segmenty.setName("Segmenty")
                #QgsProject.instance().addMapLayer(segmenty)
            # ---------------------------------------------------------------------------------------------------------------

            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Vytvoření bufferů kolem segmentů (-------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------    

            if traj_i_bool:
                plosky = processing.run("native:buffer", {
                    'INPUT': segmenty,
                    'DISTANCE': dist / 2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(plosky)

                #určení sklonu na plošce
                plosky_slope = processing.run("native:zonalstatisticsfb", {
                    'INPUT': plosky,
                    'INPUT_RASTER': sklon_layer, 'RASTER_BAND': 1,
                    'COLUMN_PREFIX': 'slope_', 'STATISTICS': [2, 6], 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # urceni tridy prekroceni sklonu
                plosky_slope.startEditing()
                new_field = QgsField("result", QVariant.Int)
                plosky_slope.addAttribute(new_field)
                plosky_slope.updateFields()
                for feat in plosky_slope.getFeatures():
                    mean_slope_st = feat["slope_mean"]
                    mean_slope_pr = 100 * (math.tan(math.radians(mean_slope_st)))
                    sklon_trajektorie_pr = feat["Slope_%"]
                    if mean_slope_pr > 3:
                        if sklon_trajektorie_pr <= 7:
                            if sklon_trajektorie_pr > mean_slope_pr / 2:
                                feat["result"] = 1
                            else:
                                feat["result"] = 0
                        else:
                            feat["result"] = 2
                    else:
                        feat["result"] = 0
                    plosky_slope.updateFeature(feat)
                plosky_slope.commitChanges()
                #QgsProject.instance().addMapLayer(plosky_slope)

                # pouziti neprodukční plochy ci ne
                """LayerDPB_i.selectAll()
                upravena_maska = processing.run("native:saveselectedfeatures", {'INPUT': LayerDPB_i, 'OUTPUT': 'memory:'})['OUTPUT']
                LayerDPB_i.removeSelection()"""
                upravena_maska = LayerDPB_i.materialize(QgsFeatureRequest())
  
                if np_i_bool:
                    upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                          'OVERLAY': LayerNP_i,
                                                                          'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                          'GRID_SIZE': None})['OUTPUT']
                if aenvi_i_bool:
                    upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                          'OVERLAY': LayerAenvi_i,
                                                                          'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                          'GRID_SIZE': None})['OUTPUT']
                    
                #odstranění odřezků
                upravena_maska.startEditing()
                for feat in upravena_maska.getFeatures():
                    if feat.geometry().area() < 1:
                        upravena_maska.deleteFeature(feat.id())
                upravena_maska.commitChanges()
                upravena_maska.setName("maska upravena")
                # QgsProject.instance().addMapLayer(upravena_maska)

                upravena_maska_minus = processing.run("native:buffer", {
                    'INPUT': upravena_maska,
                    'DISTANCE': -0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                upravena_maska = processing.run("native:buffer", {
                    'INPUT': upravena_maska_minus,
                    'DISTANCE': 0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                plosky_final = plosky_slope

                #buffer +, dissolve a buffer -        
                buffer3 = processing.run("native:buffer", {
                    'INPUT': plosky_final,
                    'DISTANCE': 0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                #QgsProject.instance().addMapLayer(buffer3)

                buffer3_diss = processing.run("native:dissolve", {
                    'INPUT': buffer3,
                    'FIELD': ['result'], 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(buffer3_diss)

                buffer4 = processing.run("native:buffer",
                                         {'INPUT': buffer3_diss,
                                          'DISTANCE': -0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                          'MITER_LIMIT': 2,
                                          'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                buffer4.startEditing()
                for feat in buffer4.getFeatures():
                    if feat.geometry().area() < 1:
                        buffer4.deleteFeature(feat.id())
                buffer4.commitChanges()
                # QgsProject.instance().addMapLayer(buffer4)

                polygony_ohrozenost = processing.run("native:fixgeometries", {
                    'INPUT': buffer4,
                    'METHOD': 1, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                #QgsProject.instance().addMapLayer(buffer4)
                
                try:
                    if polygony_ohrozenost.featureCount() > 0:
                        polygony_ohrozenost_bool = True
                    else:
                        polygony_ohrozenost_bool = False
                except:
                    polygony_ohrozenost_bool = False
                    
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Vytvoření vrstev ZEOP a limit30 (--------------------------------------------------------------
                # ---------------------------------------------------------------------------------------------------------------    
                
                if polygony_ohrozenost_bool:

                    polygony_ohrozenost_maska_union = processing.run("native:union", {
                        'INPUT': polygony_ohrozenost,
                        'OVERLAY': LayerDPB_i, 'OVERLAY_FIELDS_PREFIX': '',
                        'OUTPUT': 'TEMPORARY_OUTPUT', 'GRID_SIZE': None})["OUTPUT"]
    
                    polygony_ohrozenost_maska_union_singleparts = processing.run("native:multiparttosingleparts", {
                        'INPUT': polygony_ohrozenost_maska_union,
                        'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    polygony_ohrozenost_maska_union_singleparts.startEditing()
                    new_field = QgsField("podelny_sklon", QVariant.Int)
                    polygony_ohrozenost_maska_union_singleparts.addAttribute(new_field)
                    polygony_ohrozenost_maska_union_singleparts.updateFields()
                    for feat in polygony_ohrozenost_maska_union_singleparts.getFeatures():
                        if ((feat["result"] == 2) and (feat.geometry().area() > 10000)):
                            zeop_i_bool = True
                            feat["podelny_sklon"] = 2
                        elif (feat["result"] == 1):
                            feat["podelny_sklon"] = 1
                        elif (feat["result"] == 0):
                            feat["podelny_sklon"] = 0
                        elif (feat["result"] == NULL):
                            feat["podelny_sklon"] = NULL
                        else:
                            feat["podelny_sklon"] = 1
                        polygony_ohrozenost_maska_union_singleparts.updateFeature(feat)
                    polygony_ohrozenost_maska_union_singleparts.commitChanges()
                    polygony_ohrozenost_maska_union_singleparts.setName("podelna sklonitost trajektorie uložení")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_singleparts)
                    
                    mazani_poli(polygony_ohrozenost_maska_union_singleparts, ["ZKOD", "CTVEREC", "result", "podelny_sklon"])
                    
                    polygony_ohrozenost_maska_union_singleparts_final = processing.run("native:clip", {
                        'INPUT': polygony_ohrozenost_maska_union_singleparts,
                        'OVERLAY': upravena_maska, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    polygony_ohrozenost_maska_union_singleparts_final.startEditing()
                    for feat in polygony_ohrozenost_maska_union_singleparts_final.getFeatures():
                        if feat.geometry().area() < 1:
                            polygony_ohrozenost_maska_union_singleparts_final.deleteFeature(feat.id())
                    polygony_ohrozenost_maska_union_singleparts_final.commitChanges()
                    polygony_ohrozenost_maska_union_singleparts_final.setName("polygony_ohrozenost_maska_union_singleparts_final_výpočty")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_singleparts_final)
    
                    polygony_ohrozenost_maska_union.startEditing()
                    new_field = QgsField("result_2", QVariant.Int)
                    polygony_ohrozenost_maska_union.addAttribute(new_field)
                    polygony_ohrozenost_maska_union.updateFields()
                    for feat in polygony_ohrozenost_maska_union.getFeatures():
                        if ((feat["result"] == 1) or (feat["result"] == 2)):
                            feat["result_2"] = 1
                        else:
                            feat["result_2"] = 0
                        polygony_ohrozenost_maska_union.updateFeature(feat)
                    polygony_ohrozenost_maska_union.commitChanges()
                    polygony_ohrozenost_maska_union.setName("polygony_ohrozenost_maska_union_uložení")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union)
                    
                    mazani_poli(polygony_ohrozenost_maska_union, ["ZKOD", "CTVEREC", "result", "result_2"])
 
                    polygony_ohrozenost_maska_union_final = processing.run("native:clip", {
                        'INPUT': polygony_ohrozenost_maska_union,
                        'OVERLAY': upravena_maska, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    polygony_ohrozenost_maska_union_final.startEditing()
                    for feat in polygony_ohrozenost_maska_union_final.getFeatures():
                        if feat.geometry().area() < 1:
                            polygony_ohrozenost_maska_union_final.deleteFeature(feat.id())
                    polygony_ohrozenost_maska_union_final.commitChanges()
                    polygony_ohrozenost_maska_union_final.setName("polygony_ohrozenost_maska_union_final_výpočty")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_final)




                    plosky_prekroceno = processing.run("native:extractbyattribute", {
                        'INPUT': polygony_ohrozenost_maska_union_final,
                        'FIELD': 'result_2', 'OPERATOR': 0, 'VALUE': '1', 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(plosky_prekroceno)
    
                    plosky_prekroceno_diss = processing.run("native:dissolve",
                                                            {'INPUT': plosky_prekroceno, 'FIELD': ['result_2'],
                                                             'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                        "OUTPUT"]
                    #QgsProject.instance().addMapLayer(plosky_prekroceno_diss)
    
                    buffer5 = processing.run("native:buffer", {
                        'INPUT': plosky_prekroceno_diss,
                        'DISTANCE': 0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    buffer6 = processing.run("native:buffer", {
                        'INPUT': buffer5,
                        'DISTANCE': -0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    buffer6 = processing.run("native:fixgeometries", {
                        'INPUT': buffer6,
                        'METHOD': 1, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    # QgsProject.instance().addMapLayer(buffer6)

                    limit30 = processing.run("native:multiintersection", {
                        'INPUT': buffer6,
                        'OVERLAYS': [maska_3pr_i],
                        'OVERLAY_FIELDS_PREFIX': '', 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    
                    
                    if limit30.featureCount() > 0:
                        limit30_i_bool = True
                        mazani_poli(limit30, [])
                        limit30.startEditing()
                        new_fields = [QgsField("P_SKL(%)", QVariant.Double)]
                        limit30.dataProvider().addAttributes(new_fields)
                        limit30.updateFields()
                        for feat in limit30.getFeatures():
                            plocha_ha = feat.geometry().area() / 10000
                            limit30_vyhovuje = False
                            if (100 * plocha_ha / maska3p_i_area) < limit_pro_limit30:     
                                limit30_vyhovuje = True
                            limit30_procenta = round(100 * plocha_ha / maska3p_i_area, 2)
                            feat["P_SKL(%)"] = limit30_procenta
                            limit30.updateFeature(feat)
                        limit30.commitChanges()
                        limit30.setName("limit30")
                        #QgsProject.instance().addMapLayer(limit30)

                zeop_all_procenta = 0
                zeop_vyhovuje = True
                
                if zeop_i_bool:
                    zeop_prep = processing.run("native:extractbyattribute", {
                        'INPUT': polygony_ohrozenost_maska_union_singleparts_final, 'FIELD': 'podelny_sklon', 'OPERATOR': 0,
                        'VALUE': '2',
                        'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    
                    
 
                    zeop_prep2 = processing.run("native:dissolve",
                                               {'INPUT': zeop_prep, 'FIELD': [],
                                                'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    
                    zeop = processing.run("native:multiparttosingleparts", {'INPUT':zeop_prep2,   
                                                                            'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    zeop = processing.run("native:fieldcalculator", {'INPUT':zeop,
                                                                     'FIELD_NAME':'plocha',
                                                                     'FIELD_TYPE':0,
                                                                     'FIELD_LENGTH':10,
                                                                     'FIELD_PRECISION':2,
                                                                     'FORMULA':' $area '
                                                                     ,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    zeop = processing.run("native:extractbyattribute", {'INPUT':zeop,
                                                                        'FIELD':'plocha',
                                                                        'OPERATOR':2,
                                                                        'VALUE':'10000',
                                                                        'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    if zeop.featureCount() > 0:
                        zeop_vyhovuje = False
                        zeop_all_area = 0
                        zeop_all_procenta = 0
                        pocet_zeop_nad2ha = 0
                        
                        mazani_poli(zeop, [])
                        zeop.startEditing()
                        new_fields = [QgsField("CTVEREC", QVariant.String),
                                      QgsField("ZKOD", QVariant.String),
                                      QgsField("ZEOP(%)", QVariant.Double),
                                      QgsField("VYMZEOP", QVariant.Double, len=10, prec=4),
                                      QgsField("ZEOPstav", QVariant.String)
                                      ]
                        zeop.dataProvider().addAttributes(new_fields)
                        zeop.updateFields()
                        for feat in zeop.getFeatures():
                            plocha_ha = feat.geometry().area() / 10000
                            zeop_all_area = zeop_all_area + plocha_ha
                            zeop_procenta = 100 * plocha_ha / maska3p_i_area
                            zeop_all_procenta = zeop_all_procenta + zeop_procenta
                            feat["ZEOP(%)"] = round(zeop_procenta,1)
                            feat["CTVEREC"] = ctverec
                            feat["ZKOD"] = zkod
                            feat["VYMZEOP"] = round(plocha_ha, 4)
                            if ((zeop_procenta < 10) and (plocha_ha < 2)):
                                feat["ZEOPstav"] = "OK"
                            else:
                                feat["ZEOPstav"] = "překračuje limity"
                                pocet_zeop_nad2ha = pocet_zeop_nad2ha + 1
                            zeop.updateFeature(feat)
                        zeop.commitChanges()
                        zeop.setName("ZEOP")
                        #QgsProject.instance().addMapLayer(zeop)
                        if (((100 * zeop_all_area / maska3p_i_area) < limit_pro_zeop) and (pocet_zeop_nad2ha == 0)):   
                            zeop_vyhovuje = True            
                # ---------------------------------------------------------------------------------------------------------------           
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola překrytí StP přes DSO (---------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------   

            if dso_bool:
                dso_i_bool = False
                DSO_buffer_dpb0 = processing.run("native:clip", {'INPUT': DSO_pasy, 'OVERLAY': LayerDPB_i,
                                                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                if DSO_buffer_dpb0.featureCount() > 0:
                    dso_i_bool = True
                    DSO_buffer_dpb = processing.run("native:dissolve", {'INPUT':DSO_buffer_dpb0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(DSO_buffer_dpb)
                if np_i_bool:
                    if dso_i_bool:
                        DSO_buffer_np = processing.run("native:clip", {'INPUT': DSO_buffer_dpb, 'OVERLAY': LayerNP_i,
                                                                       'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        #DSO_buffer_np.setName("DSO5ha uvnitř NP")
                        #QgsProject.instance().addMapLayer(DSO_buffer_np)

                #kontrola, že DSO leží ve stabilizované ploše
                #plocha průniku DSO a STP musí být stejná jako plocha DSO
                plocha_dso_v_dpb = 0
                plocha_dso_v_np = 0
                geom_dpb = feat_dpb_base.geometry()

                if dso_i_bool:
                    for feat_dso1 in DSO_buffer_dpb.getFeatures():
                        geom_dso1 = feat_dso1.geometry()
                        geom_prunik1 = geom_dpb.intersection(geom_dso1)
                        plocha_dso_v_dpb = plocha_dso_v_dpb + geom_prunik1.area()
                    if np_i_bool:
                        for feat_dso2 in DSO_buffer_np.getFeatures():
                            geom_dso2 = feat_dso2.geometry()
                            geom_prunik2 = geom_dpb.intersection(geom_dso2)
                            plocha_dso_v_np = plocha_dso_v_np + geom_prunik2.area()

            # ---------------------------------------------------------------------------------------------------------------   
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Převod výsledků uvnitř DPB do vrstev pro celý projekt (kromě DPB a kostry) (-------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            if dso_i_bool:
                for feat in DSO_buffer_dpb.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature()
                    new_feature.setGeometry(geom)
                    dso_all.dataProvider().addFeature(new_feature)
                dso_all.updateExtents()

            if maska3_i_bool:
                maska3_all_provider = maska3_all.dataProvider()
                for feat in maska_3pr_i.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(maska3_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["SKL<3%(ha)"] = feat["SKL<3%(ha)"]
                    new_feature["plocha(ha)"] = feat["plocha(ha)"]
                    new_feature["SKL<3%(%)"] = feat["SKL<3%(%)"]
                    new_feature["ZKOD"] = feat["ZKOD"]
                    new_feature["CTVEREC"] = feat["CTVEREC"]
                    new_feature["JI"] = kod_uzivatele
                    new_feature["PROJEKT_ID"] = id_procesu
                    maska3_all_provider.addFeature(new_feature)
                maska3_all.updateExtents()

            if traj_i_bool:
                for feat in LayerTrajektorie_i.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(trajektorie_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["SIRKA_PASU"] = dist
                    trajektorie_all.dataProvider().addFeature(new_feature)
                trajektorie_all.updateExtents()

            if limit30_i_bool:
                limit30_all_provider = limit30_all.dataProvider()
                for feat in limit30.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(limit30_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["CTVEREC"] = ctverec
                    new_feature["ZKOD"] = zkod
                    new_feature["P_SKL(%)"] = feat["P_SKL(%)"]
                    new_feature["JI"] = kod_uzivatele
                    new_feature["PROJEKT_ID"] = id_procesu
                    if limit30_vyhovuje:
                        new_feature["P_SKLstav"] = "vyhovuje"
                    else:
                        new_feature["P_SKLstav"] = "nevyhovuje"
                    limit30_all_provider.addFeature(new_feature)
                limit30_all.updateExtents()

            if zeop_i_bool:
                zeop_all_provider = zeop_all.dataProvider()
                for feat in zeop.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(zeop_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["CTVEREC"] = ctverec
                    new_feature["ZKOD"] = zkod
                    new_feature["ZEOP(%)"] = feat["ZEOP(%)"]
                    new_feature["JI"] = kod_uzivatele
                    new_feature["PROJEKT_ID"] = id_procesu
                    new_feature["VYMZEOP"] = feat["VYMZEOP"]
                    new_feature["ZEOPstav"] = feat["ZEOPstav"]
                    zeop_all_provider.addFeature(new_feature)
                zeop_all.updateExtents()
            
            
            
            if polygony_ohrozenost.featureCount() > 0:
                polygony_ohrozenost_maska_union_singleparts_all_provider = polygony_ohrozenost_maska_union_singleparts_all.dataProvider()
                for feat in polygony_ohrozenost_maska_union_singleparts.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(polygony_ohrozenost_maska_union_singleparts_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["CTVEREC"] = ctverec
                    new_feature["ZKOD"] = zkod
                    new_feature["result"] = feat["result"]
                    new_feature["podelny_sklon"] = feat["podelny_sklon"]
                    polygony_ohrozenost_maska_union_singleparts_all_provider.addFeature(new_feature)
                polygony_ohrozenost_maska_union_singleparts_all.updateExtents()
                
                polygony_ohrozenost_maska_union_all_provider = polygony_ohrozenost_maska_union_all.dataProvider()
                for feat in polygony_ohrozenost_maska_union.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(polygony_ohrozenost_maska_union_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["CTVEREC"] = ctverec
                    new_feature["ZKOD"] = zkod
                    new_feature["result"] = feat["result"]
                    new_feature["result_2"] = feat["result_2"]
                    polygony_ohrozenost_maska_union_all_provider.addFeature(new_feature)
                polygony_ohrozenost_maska_union_all.updateExtents()
            
            # ---------------------------------------------------------------------------------------------------------------   
              
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Hledání širokých/spojených pásů (--------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            siroke_pasy_bool = False
            if pasy_i_bool:    
                LayerPasy_i_vnitrni_buffer = processing.run("native:buffer",
                               {'INPUT': LayerPasy_i,
                                'DISTANCE': -21.45, 'SEGMENTS': 5, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2,
                                'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                LayerPasy_i_vnitrni_buffer.startEditing()
                for feat in LayerPasy_i_vnitrni_buffer.getFeatures():
                    if feat.geometry().area() < 0.011:
                        LayerPasy_i_vnitrni_buffer.deleteFeature(feat.id())
                LayerPasy_i_vnitrni_buffer.commitChanges()

                if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                    siroke_pasy_bool = True
                    LayerPasy_i_s_vnitrnim_bufferem0 = processing.run("native:extractbylocation",
                                   {'INPUT': LayerPasy_i,
                                    'PREDICATE': [1],
                                    'INTERSECT': LayerPasy_i_vnitrni_buffer,
                                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(LayerPasy_i_vnitrni_buffer)

            if siroke_pasy_bool:          
                if neo_bool:
                    neo_ve_spojene = processing.run("native:clip", {'INPUT':neo_lyr,'OVERLAY':LayerPasy_i_s_vnitrnim_bufferem0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                for feat in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                    geom = feat.geometry()
                    plocha_siroky_pas = geom.area()
                    plocha_neo_pod_pasem = 0
                    for feat_neo in neo_ve_spojene.getFeatures():
                        geom_prunik = geom.intersection(feat_neo.geometry())
                        plocha_neo_pod_pasem = plocha_neo_pod_pasem + geom_prunik.area()
                    
                    new_feature = QgsFeature(siroke_pasy_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["NEO(%)"] = round((100*plocha_neo_pod_pasem/plocha_siroky_pas),1)
                    if 100*plocha_neo_pod_pasem/plocha_siroky_pas < 80:
                        new_feature["typ"] = "Široký pás mimo NEO"
                    else:
                        new_feature["typ"] = "Široký pás na NEO"
                    siroke_pasy_all.dataProvider().addFeature(new_feature)
                siroke_pasy_all.updateExtents()

                for feat in LayerPasy_i_vnitrni_buffer.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(siroke_pasy_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["typ"] = "Poloha překročení šířky"
                    siroke_pasy_all.dataProvider().addFeature(new_feature)
                siroke_pasy_all.updateExtents()
                
            # --------------------------------------------------------------------------------------------------------------- 
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola plochy StP a Aenvi (--------------------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
                
            #určení zda vyhovuje plocha STP podmínce (5-30 %) -> bez vyhodnoceni
            NP_AE_area = 0
            if np_i_bool:      
                for feat in LayerNP_i.getFeatures():
                    NP_AE_area += feat.geometry().area()
            if aenvi_i_bool:      
                for feat in LayerAenvi_i.getFeatures():
                    NP_AE_area += feat.geometry().area()   
                    
            NP_p = 100*NP_AE_area/(feat_dpb_base.geometry().area())
            
            """
            AE_area = 0
            if aenvi_i_bool:      
                for feat in LayerAenvi_i.getFeatures():
                    AE_area += feat.geometry().area()
            AE_p = 100*AE_area/(feat_dpb_base.geometry().area())
            """
            
            # --------------------------------------------------------------------------------------------------------------- 

            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Určení očekáváné šířky pásů pro daný DPB (-----------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
 
            #kolem trajektorií se vytváří stále větší buffer, jsou vytvořeny pásy od 1 do 43 m a je určeno vzájemné překrytí bufferů
            #pro toto vzájemné překrytí je určena druhá derivace, která má nejvyšší hodnotu pří šířce, která je skutečně použita
            if traj_i_bool:
                plochy_prekryvu = []
                LayerTrajektorie_i_dissolve = processing.run("native:dissolve", {'INPUT':LayerTrajektorie_i,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                LayerTrajektorie_i_single = processing.run("native:multiparttosingleparts", {'INPUT':LayerTrajektorie_i_dissolve,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #QgsProject.instance().addMapLayer(LayerTrajektorie_i_single)
                for sirka in range(1, 44):
                    buffery = processing.run("native:buffer",
                                           {'INPUT': LayerTrajektorie_i_single, 'DISTANCE': sirka / 2, 'SEGMENTS': 5,
                                            'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2, 'DISSOLVE': False,
                                            'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(buffery)
                    plocha_prunik = 0
                    for f1 in buffery.getFeatures():
                        for f2 in buffery.getFeatures():
                            if f2 != f1:
                                prunik = f1.geometry().intersection(f2.geometry())
                                plocha_prunik = plocha_prunik + prunik.area()
                    plochy_prekryvu.append(round(plocha_prunik))

                print("sirka, překryv, druhá derivace")
                druhe_derivace = [0 for n in range(1,44)]
                for n in range(1,42):
                    druhe_derivace[n] = (plochy_prekryvu[n-1] - 2*plochy_prekryvu[n] + plochy_prekryvu[n+1])
                    print(n, plochy_prekryvu[n], druhe_derivace[n])
                    
                # použití z_skore pro nalezení výrazných maxim
                z_skore = []
                prumer = sum(druhe_derivace)/len(druhe_derivace)
                odchylka = np.std(druhe_derivace)
                
                print("sirka, z-skore")
                for nk, clen in enumerate(druhe_derivace):
                    n = nk + 1
                    z_skore_i = (clen - prumer)/odchylka
                    z_skore.append(z_skore_i)
                    print(n, z_skore_i)
                
                sirka_odhad = -1
                for index, number in enumerate(z_skore):
                    if number > 2:
                        sirka_odhad = index + 1
                        break
                        
                if sirka_odhad < 0:
                    for index, number in enumerate(z_skore):
                        if number > 1:
                            sirka_odhad = index + 1
                            break
                
                if sirka_odhad < 0:
                    sirka_odhad = z_skore.index(max(z_skore))+1
                    
                print("sirka odhad:", sirka_odhad) 
                    
                print("sirka odhad:", sirka_odhad)

                if sirka_odhad != dist:
                    geom = feat_dpb_base.geometry()
                    new_feature = QgsFeature(dpb_spatne_sirky_all.fields())
                    new_feature.setGeometry(geom)
                    new_feature["Sirka pasu zadana"] = dist
                    new_feature["Sirka pasu odhadovana"] = sirka_odhad
                    dpb_spatne_sirky_all.dataProvider().addFeature(new_feature)
                    dpb_spatne_sirky_all.updateExtents()
                    
            # --------------------------------------------------------------------------------------------------------------- 
            
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola zda jde trajektorie středem pásu (----------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            if ((pasy_i_bool == True) and (traj_i_bool == True) and (np_i_bool == True)):
                #udělá se vnitřní buffer co nejde až do středu, a převede se na linie
                pasy_i = processing.run("native:deleteholes", {'INPUT':LayerPasy_i,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_buffer = processing.run("native:buffer", {'INPUT': pasy_i ,'DISTANCE': (1-dist/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':0,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                vnitrni_buffer_linie = processing.run("native:polygonstolines", {'INPUT':vnitrni_buffer,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #linie se oříznou podle bufferu kolem STP a ďur -> tímto se odstraní "čela" vnitřních bufferů
                #a zůstanou pouze linky kolem trajektorie
                #trajektorie tyto linky nesmí protnout, pokud jsou v ose pásu
                np_buffer = processing.run("native:buffer", {'INPUT': LayerNP_i ,'DISTANCE': (dist/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                diry_buffer = processing.run("native:buffer", {'INPUT': Layer_diry_i ,'DISTANCE': (dist/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                #!!!! je dpb ok?
                dpb_vnitrni_buffer0 = processing.run("native:multiringconstantbuffer", {'INPUT':DPB_i_bez_dur,'RINGS':1,'DISTANCE':-(dist/2),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                dpb_vnitrni_buffer = processing.run("native:extractbyattribute", {'INPUT':dpb_vnitrni_buffer0,'FIELD':'distance','OPERATOR':0,'VALUE':f'{-(dist/2)}','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #!!!! pouzit i konce odřizle
                
                spojeny_buffer = processing.run("native:mergevectorlayers", {'LAYERS':[np_buffer, diry_buffer, dpb_vnitrni_buffer],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                spojeny_buffer = processing.run("native:dissolve", {'INPUT':spojeny_buffer,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"] 
                
                konce = processing.run("native:clip", {'INPUT': vnitrni_buffer_linie, 'OVERLAY': spojeny_buffer,
                                                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                #kontrola, že trajektorie je mezi vnějšíma linkama + 
                vnejsi_linky = processing.run("native:difference", {'INPUT':vnitrni_buffer_linie,'OVERLAY':spojeny_buffer,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                protinajici_linky = processing.run("native:extractbylocation", {'INPUT':LayerTrajektorie_i,'PREDICATE':[0],'INTERSECT': vnejsi_linky,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #kontrola, že linky vubec prochazi středovym bufferem
                """
                LayerTrajektorie_i.removeSelection()
                processing.run("native:selectbylocation", {'INPUT':LayerTrajektorie_i,
                                                           'PREDICATE':[0],
                                                           'INTERSECT':vnitrni_buffer,
                                                           'METHOD':0})["OUTPUT"]
                LayerTrajektorie_i.invertSelection()
                selected_features_traj = LayerTrajektorie_i.selectedFeatures()
                if selected_features_traj:
                    protinajici_linky.startEditing()
                    for feature in selected_features_traj:
                        new_feature = QgsFeature(protinajici_linky.fields())
                        new_feature.setGeometry(feature.geometry())
                        new_feature.setAttributes(feature.attributes())
                        protinajici_linky.addFeature(new_feature)
                    protinajici_linky.commitChanges()
                LayerTrajektorie_i.removeSelection()
                
                
                QgsProject.instance().addMapLayer(vnejsi_linky)     
                QgsProject.instance().addMapLayer(protinajici_linky)  
                QgsProject.instance().addMapLayer(konce)
                QgsProject.instance().addMapLayer(vnitrni_buffer)
                """
                
                #vykreslí se linky mimo osu, pouze pokud existují     
                if protinajici_linky.featureCount() > 0:
                    for feat in protinajici_linky.getFeatures():
                        geom = feat.geometry()
                        new_feature = QgsFeature(trajektorie_kontrola_all.fields())
                        new_feature.setGeometry(geom)
                        new_feature["stav"] = "Trajektorie pravděpodobně mimo osu pásu"
                        trajektorie_kontrola_all.dataProvider().addFeature(new_feature)
                    trajektorie_kontrola_all.updateExtents()
                    
            # --------------------------------------------------------------------------------------------------------------- 
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Tvorba kostry plodin (-------------------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 

            pomer_plodiny_dpb = 0 #poměr zemědělskych parcel v dpb
            pomer_plodiny_dpb_ok = False
            kostra_bool = False
            print("pasy_i_bool np_i_bool", pasy_i_bool, np_i_bool)
            if ((pasy_i_bool==True) and (np_i_bool == True)) :
                # tvorba kostry
                crs_epsg_5514 = QgsCoordinateReferenceSystem("EPSG:5514")

                #Provest geometricky rozdil mezi pasy a np (a aenvi)
                if aenvi_i_bool:
                    difference_layer = processing.run("native:multidifference", {
                        'INPUT':LayerPasy_i,
                        'OVERLAYS':[LayerNP_i,
                                    LayerAenvi_i],
                        'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                else:
                    difference_layer = processing.run("native:difference", {
                        'INPUT': LayerPasy_i,
                        'OVERLAY': LayerNP_i,
                        'OUTPUT': 'TEMPORARY_OUTPUT',
                        'GRID_SIZE': None})['OUTPUT']

                #Rozdelit multipart (difference_layer) na jednotlive casti
                singleparts_layer = processing.run("native:multiparttosingleparts",
                                                   {'INPUT': difference_layer,
                                                       'OUTPUT': 'TEMPORARY_OUTPUT'
                                                   })['OUTPUT']
                
                #QgsProject.instance().addMapLayer(LayerPasy_i)
                #singleparts_layer.setName("1 single part")
                #QgsProject.instance().addMapLayer(singleparts_layer)

                # EVP vyřízne díru ve stabilizační ploše (až tady — po ořezu pásů o NP),
                # aby pásy nezabraly plochu EVP; do kostry se EVP dosadí jako SCHEMA E / 50082
                # při chybě pokračovat bez výřezu — kostra se musí vytvořit
                if kp_vlayer_bool:
                    try:
                        kp_na_np = processing.run("native:clip", {
                            'INPUT': kp_vlayer,
                            'OVERLAY': LayerDPB_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if kp_na_np.featureCount() > 0:
                            LayerNP_i = processing.run("native:difference", {
                                'INPUT': LayerNP_i,
                                'OVERLAY': kp_na_np,
                                'OUTPUT': 'TEMPORARY_OUTPUT',
                                'GRID_SIZE': None})["OUTPUT"]
                            LayerNP_i = processing.run("native:multiparttosingleparts", {
                                'INPUT': LayerNP_i,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            LayerNP_i.startEditing()
                            for feat in LayerNP_i.getFeatures():
                                if feat.geometry().area() < 1:
                                    LayerNP_i.deleteFeature(feat.id())
                            LayerNP_i.commitChanges()
                    except Exception:
                        pass

                # Uprava atributu overlay vrstvy (pouzita overlay_qgs_layer nactena v EPSG:5514)
                overlay_data_provider = LayerNP_i.dataProvider()

                # Odstraneni vsech atributu
                mazani_poli(LayerNP_i, [])

                # Pridani novych atributu SCHEMA a SCELEK_ID
                schema_field = QgsField("SCHEMA", QVariant.String, len=254)
                scelek_id_field = QgsField("SCELEK_ID", QVariant.String, len=254)
                overlay_data_provider.addAttributes([schema_field, scelek_id_field])
                LayerNP_i.updateFields()

                # Nastaveni hodnot atributu
                LayerNP_i.startEditing()
                for feature in LayerNP_i.getFeatures():
                    feature.setAttribute("SCHEMA", "D")
                    feature.setAttribute("SCELEK_ID", None)
                    LayerNP_i.updateFeature(feature)
                LayerNP_i.commitChanges()
                
                
                if aenvi_i_bool:
                    #To stejné pro aenvi
                    overlay_data_provider2 = LayerAenvi_i.dataProvider()

                    # Odstraneni vsech atributu
                    mazani_poli(LayerAenvi_i, [])

                    # Pridani novych atributu SCHEMA a SCELEK_ID
                    schema_field = QgsField("SCHEMA", QVariant.String, len=254)
                    scelek_id_field = QgsField("SCELEK_ID", QVariant.String, len=254)
                    overlay_data_provider2.addAttributes([schema_field, scelek_id_field])
                    LayerAenvi_i.updateFields()

                    # Nastaveni hodnot atributu
                    LayerAenvi_i.startEditing()
                    for feature in LayerAenvi_i.getFeatures():
                        feature.setAttribute("SCHEMA", "F")
                        feature.setAttribute("SCELEK_ID", None)
                        LayerAenvi_i.updateFeature(feature)
                    LayerAenvi_i.commitChanges()

                # Slouceni vrstev
                if aenvi_i_bool:
                    merged_layer = processing.run("native:mergevectorlayers", {'LAYERS': [singleparts_layer, LayerNP_i, LayerAenvi_i],
                        'CRS': crs_epsg_5514,  # Nastaveni EPSG:5514
                        'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                else:
                    merged_layer = processing.run("native:mergevectorlayers", {'LAYERS': [singleparts_layer, LayerNP_i],
                        'CRS': crs_epsg_5514,  # Nastaveni EPSG:5514
                        'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                # Rozdeleni sloucene vrstvy na jednotlive casti
                singleparts_merged_layer = processing.run("native:multiparttosingleparts",
                                                          {'INPUT': merged_layer,
                                                              'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                # Pridani atributu ZAKRES_ID a jeho naplneni
                singleparts_merged_layer.dataProvider().addAttributes([QgsField("ZAKRES_ID", QVariant.String)])
                singleparts_merged_layer.updateFields()
                singleparts_merged_layer

                # Vytvoreni bodu na povrchu
                parameters_point_on_surface = {
                    'INPUT': singleparts_merged_layer,
                    'ALL_PARTS': False,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                }
                result_point_on_surface = processing.run("native:pointonsurface", parameters_point_on_surface)
                point_layer = result_point_on_surface['OUTPUT']

                # Naplneni atributu ZAKRES_ID
                singleparts_merged_layer.startEditing()
                for feature in singleparts_merged_layer.getFeatures():
                    request = QgsFeatureRequest().setFilterFid(feature.id())
                    point_feature = next(point_layer.getFeatures(request))
                    point_geom = point_feature.geometry().asPoint()
                    x_coord = str(int(point_geom.x()))
                    y_coord = str(int(point_geom.y()))
                    x_last5 = re.sub(r'\D', '', x_coord)[-5:]
                    y_last5 = re.sub(r'\D', '', y_coord)[-5:]
                    zakres_id = x_last5 + y_last5
                    feature.setAttribute("ZAKRES_ID", zakres_id)
                    singleparts_merged_layer.updateFeature(feature)
                singleparts_merged_layer.commitChanges()

                # Odstraneni vsech atributu krome SCHEMA, SCELEK_ID a ZAKRES_ID
                # QGIS 4: PLOD_ID z pásů A/B musí zůstat, jinak chybí v atributové tabulce
                _pole_zustavaji = ["SCHEMA", "SCELEK_ID", "ZAKRES_ID"]
                if _IS_QGIS4:
                    _pole_zustavaji.append("PLOD_ID")
                mazani_poli(singleparts_merged_layer, _pole_zustavaji)

                # Pridani novych atributu
                new_fields = [
                    QgsField("CTVEREC", QVariant.String),
                    QgsField("ZKOD", QVariant.String),
                    QgsField("PLODINA_AK", QVariant.String),
                    QgsField("PLOD_ID", QVariant.String),
                    QgsField("VYMZAKRES", QVariant.Double, len=10, prec=4),
                    QgsField("JI", QVariant.String)
                ]
                if _IS_QGIS4:
                    existing_fields = set(singleparts_merged_layer.fields().names())
                    new_fields = [f for f in new_fields if f.name() not in existing_fields]
                if new_fields:
                    singleparts_merged_layer.dataProvider().addAttributes(new_fields)
                    singleparts_merged_layer.updateFields()
                # Vypocitani plochy (v hektarech) pro atribut VYMZAKRES
                singleparts_merged_layer.startEditing()
                for feature in singleparts_merged_layer.getFeatures():
                    geom = feature.geometry()
                    if geom.area() < 1:
                        singleparts_merged_layer.deleteFeature(feature.id())
                    else:
                        area = geom.area() / 10000  # Prevedeni plochy z m² na hektary
                        feature.setAttribute("VYMZAKRES", round(area,4))
                        singleparts_merged_layer.updateFeature(feature)
                singleparts_merged_layer.commitChanges()
                
                #singleparts_merged_layer.setName("jednotlive casti2")
                #QgsProject.instance().addMapLayer(singleparts_merged_layer)

                # Pojmenovani vrstvy jako "jednotlive casti2"
                #singleparts_merged_layer.setName("jednotlive casti2")
                #QgsProject.instance().addMapLayer(singleparts_merged_layer)

                # Vytvoreni vrstvy kostra_psp na zaklade vrstvy "jednotlive casti2"
                kostra_psp = singleparts_merged_layer.clone()
                kostra_psp.setName("kostra_psp")

                kostra_bool = True                

                # pridani JI do kostry
                kostra_psp.startEditing()
                for feature in kostra_psp.getFeatures():
                    feature.setAttribute("JI", kod_uzivatele)
                    kostra_psp.updateFeature(feature)
                kostra_psp.commitChanges()


                # Doplnovani hodnot atributu z vrstvy u_krize_polygon.shp do kostra_psp
                kostra_psp.startEditing()
                for feature in kostra_psp.getFeatures():
                    geom = feature.geometry()
                    # Najit prvky z vrstvy u_krize_polygon.shp, ktere se protinaji
                    request = QgsFeatureRequest().setFilterRect(geom.boundingBox())
                    for krize_feature in LayerDPB_i.getFeatures(request):
                        if geom.intersects(krize_feature.geometry()):
                            # Zkopirovat hodnoty atributu z vrstvy u_krize_polygon.shp
                            for field in LayerDPB_i.fields():
                                field_name = field.name()
                                if field_name in kostra_psp.fields().names() and field_name not in ["SCHEMA",
                                                                                                    "SCELEK_ID",
                                                                                                    "ZAKRES_ID",
                                                                                                    "VYMZAKRES"]:
                                    feature.setAttribute(field_name, krize_feature[field_name])
                            kostra_psp.updateFeature(feature)
                kostra_psp.commitChanges()
                # QgsProject.instance().addMapLayer(kostra_psp)
                kostra_psp.startEditing()
                for feature in kostra_psp.getFeatures():
                    if feature["SCHEMA"] == "D":
                        feature.setAttribute("PLOD_ID", 471)
                    if feature["SCHEMA"] == "F":
                        hodnota_aenvi = int(self.dlg.comboBox_agroenvikod.currentText())
                        feature.setAttribute("PLOD_ID", hodnota_aenvi)
                    if feature["SCHEMA"] not in ["A", "B", "D", "E", "F"]:
                        feature.setAttribute("SCHEMA", "ostatni")
                    kostra_psp.updateFeature(feature)
                kostra_psp.commitChanges()
                #kostra_psp.setName("psp0")
                #QgsProject.instance().addMapLayer(kostra_psp)
                #kostra bez vnitrnich prvku        
                kostra_psp = processing.run("native:clip", {'INPUT':kostra_psp,'OVERLAY':DPB_bez_vnitrnich_prvku,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #krajinný prvek uvnitř dpb_i (EVP) → PLOD_ID 50082 / SCHEMA E; díra v NP je už výše
                # Partice DPB: E vyplní díru EVP (bez překryvu s A/B/D/F, bez prázdné mezery)
                # try/except: chyba EVP nesmí zrušit zápis zbytku kostry
                if kp_vlayer_bool:
                    try:
                        # stejná EVP geometrie jako ve vnitrních prvcích (pokud na DPB je)
                        if kp_count > 0:
                            KP_v_dpb = processing.run("native:multiparttosingleparts", {'INPUT':kp_vlayer_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        else:
                            KP_v_dpb = processing.run("native:clip", {'INPUT':kp_vlayer,'OVERLAY':LayerDPB_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            KP_v_dpb = processing.run("native:multiparttosingleparts", {'INPUT':KP_v_dpb,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if KP_v_dpb.featureCount() > 0:
                            KP_v_dpb = processing.run("native:deleteduplicategeometries", {
                                'INPUT': KP_v_dpb, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        KP_v_dpb.startEditing()
                        for feat in KP_v_dpb.getFeatures():
                            if feat.geometry().area() < 1:
                                KP_v_dpb.deleteFeature(feat.id())
                        KP_v_dpb.commitChanges()

                        # E vyhraje plochu EVP: vyříznout z kostry přesně pod KP, pak dosadit celé E
                        # (ne difference(E, kostra) — to by při zbytkovém překryvu E „sežralo“ a nechalo díru)
                        if KP_v_dpb.featureCount() > 0:
                            kostra_psp = processing.run("native:difference", {
                                'INPUT': kostra_psp,
                                'OVERLAY': KP_v_dpb,
                                'OUTPUT': 'TEMPORARY_OUTPUT',
                                'GRID_SIZE': None})["OUTPUT"]
                            kostra_psp = processing.run("native:multiparttosingleparts", {
                                'INPUT': kostra_psp,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            kostra_psp.startEditing()
                            for feat in kostra_psp.getFeatures():
                                if feat.geometry().area() < 1:
                                    kostra_psp.deleteFeature(feat.id())
                            kostra_psp.commitChanges()

                            mazani_poli(KP_v_dpb, [])
                            KP_v_dpb_provider = KP_v_dpb.dataProvider()
                            KP_v_dpb_provider.addAttributes(
                                [QgsField(name, field_type) for name, field_type in kostra_fields.items()]
                                + [QgsField("VYMZAKRES", QVariant.Double, len=10, prec=4)]
                            )
                            KP_v_dpb.updateFields()
                            KP_v_dpb.startEditing()
                            for feat in KP_v_dpb.getFeatures():
                                feat["PLOD_ID"] = "50082"
                                feat["ZKOD"] = zkod
                                feat["CTVEREC"] = ctverec
                                feat["SCHEMA"] = "E"
                                feat["VYMZAKRES"] = round(feat.geometry().area(),4)
                                feat["JI"] = kod_uzivatele
                                KP_v_dpb.updateFeature(feat)
                            KP_v_dpb.commitChanges()

                            point_layer = processing.run("native:pointonsurface", {'INPUT': KP_v_dpb, 'ALL_PARTS': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                            KP_v_dpb.startEditing()
                            for feature in KP_v_dpb.getFeatures():
                                request = QgsFeatureRequest().setFilterFid(feature.id())
                                point_feature = next(point_layer.getFeatures(request))
                                point_geom = point_feature.geometry().asPoint()
                                x_coord = str(int(point_geom.x()))
                                y_coord = str(int(point_geom.y()))
                                x_last5 = re.sub(r'\D', '', x_coord)[-5:]
                                y_last5 = re.sub(r'\D', '', y_coord)[-5:]
                                zakres_id = x_last5 + y_last5
                                feature.setAttribute("ZAKRES_ID", zakres_id)
                                KP_v_dpb.updateFeature(feature)
                            KP_v_dpb.commitChanges()

                            kostra_psp = processing.run("native:mergevectorlayers", {'LAYERS':[KP_v_dpb, kostra_psp],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            # po merge sjednotit SCHEMA (QGIS někdy atributy při sloučení rozbije)
                            kostra_psp.startEditing()
                            for feat in kostra_psp.getFeatures():
                                if str(feat["PLOD_ID"]) == "50082":
                                    feat["SCHEMA"] = "E"
                                    kostra_psp.updateFeature(feat)
                            kostra_psp.commitChanges()
                    except Exception:
                        pass
                kostra_psp.setName("kostra_psp_jenpracovnivrstva")
                #QgsProject.instance().addMapLayer(kostra_psp)

                kostra_psp_all_provider = kostra_psp_all.dataProvider()
                for feat in kostra_psp.getFeatures():
                    geom = feat.geometry()
                    new_feature = QgsFeature(kostra_psp_all.fields())
                    new_feature.setGeometry(geom)
                    for pole in kostra_psp_all.fields().names():
                        try:
                            new_feature[pole] = feat[pole]
                        except KeyError:
                            continue
                    try:
                        if str(feat["PLOD_ID"]) == "50082":
                            new_feature["SCHEMA"] = "E"
                            new_feature["PLOD_ID"] = "50082"
                    except KeyError:
                        pass
                    kostra_psp_all_provider.addFeature(new_feature)
                kostra_psp_all.updateExtents()
                    
            #kontrola "duplicity pásů"
            #součet ploch v kostře vs výměra DPB
            # Důležité: sčítat plochu po clip+dissolve (ne sumu feature.area) —
            # po propsání EVP (E/50082) i při drobných překryvech pásů/NP by jinak
            # PASDPB lehce přesáhlo 100.01 % (Byčiny ~100.098 %) a kostra se neexportovala.
            plochy_ZP = 0
            pasy_suma_p = 0
            pasy_suma_stav = False
            if kostra_bool:
                try:
                    _pas_clip = processing.run("native:clip", {
                        'INPUT': kostra_psp,
                        'OVERLAY': LayerDPB_i,
                        'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    _pas_diss = processing.run("native:dissolve", {
                        'INPUT': _pas_clip,
                        'FIELD': [],
                        'SEPARATE_DISJOINT': False,
                        'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    for feat in _pas_diss.getFeatures():
                        geom = feat.geometry()
                        if geom and not geom.isEmpty():
                            plochy_ZP = plochy_ZP + geom.area()/10000
                except Exception:
                    plochy_ZP = 0
                    for feat in kostra_psp.getFeatures():
                        geom = feat.geometry()
                        plochy_ZP = plochy_ZP + geom.area()/10000
                if plochy_ZP <= 0:
                    for feat in kostra_psp.getFeatures():
                        geom = feat.geometry()
                        plochy_ZP = plochy_ZP + geom.area()/10000

                pasy_suma_p = 100*plochy_ZP/plocha_dpb
                if ((pasy_suma_p < 100.01 ) and (pasy_suma_p > limit_pro_pasy_v_dpb)):
                    pasy_suma_stav = True
                if pasy_suma_p > limit_pro_pasy_v_dpb:
                    pomer_plodiny_dpb_ok = True

            # --------------------------------------------------------------------------------------------------------------- 
            
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola DPB vs účinný DPB (-------------------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            chyby_v_dpb = 0
            if self.dlg.checkBox_neresitUcinnost.isChecked():
                vyhodnoceni_dpb = "NEŘEŠENO"
                
            else:
                if dpb_vlayer_bool:
                    zkody = []
                    ctverce = []
                    kultury = []
                    uzivatele = []
                    index = QgsSpatialIndex(dpb_vlayer.getFeatures())
                    geometry1 = feat_dpb_base.geometry()
                    # Projdeme všechny polygony v druhé vrstvě a zkontrolujeme, zda se protínají
                    for feature2 in dpb_vlayer.getFeatures():
                        geometry2 = feature2.geometry()
                        # Zkontrolujeme, zda se geometrie kryjí (intersect)
                        if geometry1.intersects(geometry2):
                            #dáme pryč odřezky
                            geom_prunik = geometry1.intersection(geometry2)
                            if geom_prunik.area() > 1: 
                                zkody.append(feature2["zkracenyKod"]) 
                                ctverce.append(feature2["ctverec"])
                                kultury.append(feature2["kultura"])
                                uzivatele.append(str(feature2["JIuzivatele"]))
                                print((abs(geom_prunik.area()-feat_dpb_base.geometry().area())), (abs(geom_prunik.area()-geometry2.area())))
                                if ((abs(geom_prunik.area()-feat_dpb_base.geometry().area()) < 1) and (abs(geom_prunik.area()-geometry2.area()) < 1)):
                                    pass
                                else:  
                                    chyby_v_dpb = chyby_v_dpb + 1
                         
                    # Získání hodnoty atributů 'ZKOD' a 'CTVEREC' pro tuto feature
                    zkod_value = feat_dpb_base['ZKOD'] if 'ZKOD' in feat_dpb_base.fields().names() else None
                    ctverec_value = feat_dpb_base['CTVEREC'] if 'CTVEREC' in feat_dpb_base.fields().names() else None
                    
                    # Kontrola, zda atributy existují a mají hodnoty
                    if zkod_value is not None and ctverec_value is not None:
                        print(f"Feature má atributy 'ZKOD' ({zkod_value}) a 'CTVEREC' ({ctverec_value}).")
                    else:
                        print("Atributy 'ZKOD' a/nebo 'CTVEREC' nejsou v této feature.")
                        chyby_v_dpb = chyby_v_dpb + 1
    
                    if chyby_v_dpb == 0:
                        if len(zkody) == 1:
                            if feat_dpb_base["ZKOD"] != zkody[0]:
                                chyby_v_dpb = chyby_v_dpb + 1
                        else:
                            chyby_v_dpb = chyby_v_dpb + 1
                            
                        if len(ctverce) == 1:
                            if feat_dpb_base["CTVEREC"] != ctverce[0]:
                                chyby_v_dpb = chyby_v_dpb + 1
                        else:
                            chyby_v_dpb = chyby_v_dpb + 1
                            
                        if len(uzivatele) == 1:
                            if kod_uzivatele != uzivatele[0]:
                                chyby_v_dpb = chyby_v_dpb + 1
                        else:
                            chyby_v_dpb = chyby_v_dpb + 1 
                    
                    if chyby_v_dpb > 0:
                        vyhodnoceni_dpb = "NESPLNĚNO"
                    else:
                        vyhodnoceni_dpb = "SPLNĚNO" 
                        
                    kultury_s = list(set(kultury))
                    kultury_s = ", ".join(kultury_s)
            # --------------------------------------------------------------------------------------------------------------- 
            
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Tvorba DPB_all s výsledky vyhodnocení (--------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            #vyplnění dpb_all, všechny podmínky
            pocet_chyb = 0
            dpb_all_provider = dpb_all.dataProvider()
            geom = feat_dpb_base.geometry()
            new_feature = QgsFeature(dpb_all.fields())
            new_feature.setGeometry(geom)
            new_feature["JI"] = kod_uzivatele
            new_feature["PROJEKT_ID"] = id_procesu
            new_feature["ZEOP(%)"] = round(zeop_all_procenta, 1)
            new_feature["P_SKL(%)"] = limit30_procenta
            new_feature["ZPvDPB(%)"] = pomer_plodiny_dpb 
            new_feature["PASDPB(%)"] = round(pasy_suma_p,3)
            
            
            new_feature["UCINNEDPB"] = vyhodnoceni_dpb
            
            if new_feature["UCINNEDPB"] == "NESPLNĚNO":
                pocet_chyb = pocet_chyb + 1
            
            
            if self.dlg.checkBox_neresitUcinnost.isChecked():
                new_feature["KULTURA"] = "NEŘEŠENO"
            else:
                new_feature["KULTURA"] = kultury_s
    
                if ((len(kultury) == 1 ) and (kultury[0][:20] == "standardní orná půda")):
                    new_feature["KULTURstav"] = "SPLNĚNO"
                else:
                    new_feature["KULTURstav"] = "NESPLNĚNO"
                    pocet_chyb = pocet_chyb + 1
            
            if not kostra_bool:
                new_feature["PASDPBstav"] = "NEŘEŠENO (kostra nevytvořena)"
                new_feature["ZPvDPBstav"] = "NEŘEŠENO (kostra nevytvořena)"
            else:
                if pasy_suma_stav:
                    new_feature["PASDPBstav"] = "Byla SPLNĚNA podmínka, že suma výměry pásů se rovná výměře DPB"
                else:
                    new_feature["PASDPBstav"] = "NENÍ splněna podmínka, že suma výměry pásů se rovná výměře DPB"
                    pocet_chyb = pocet_chyb + 1

                if pomer_plodiny_dpb_ok == False:
                    new_feature["ZPvDPBstav"] = "NENÍ splněna podmínka zaplnění plochy DPB zemědělskými parcelami minimálně z 99,99 %"
                    pocet_chyb = pocet_chyb + 1
                else:
                    new_feature["ZPvDPBstav"] = "Byla SPLNĚNA podmínka zaplnění plochy DPB zemědělskými parcelami minimálně z 99,99 %"
                
                
            if self.dlg.checkBox_neresitUcinnost.isChecked():
                new_feature["CTVEREC"] = ctverec
                new_feature["ZKOD"] = zkod
            else:
                if ((ctverec == NULL) or (ctverec == "Doplňte údaj")):
                    new_feature["CTVEREC"] = "Doplňte údaj"
                    pocet_chyb = pocet_chyb + 1
                else:
                    new_feature["CTVEREC"] = ctverec
    
                if ((zkod == NULL) or (zkod == "Doplňte údaj")):
                    new_feature["ZKOD"] = "Doplňte údaj"
                    pocet_chyb = pocet_chyb + 1
                else:
                    new_feature["ZKOD"] = zkod

            if plocha_dpb < limit_pro_vymeru:
                new_feature["VYMERA"] = f"< {limit_pro_vymeru} ha (" + str(round(plocha_dpb, 1)) + " ha)"
                pocet_chyb = pocet_chyb + 1
            else:
                new_feature["VYMERA"] = str(round(plocha_dpb, 2)) + " ha"

            if limit30_i_bool:
                if limit30_vyhovuje:
                    new_feature["P_SKLstav"] = f"Byl SPLNĚN limit {limit_pro_limit30} % plochy s vysokým podélným sklonem"
                else:
                    new_feature["P_SKLstav"] = f"Byl PŘEKROČEN limit {limit_pro_limit30} % plochy s vysokým podélným sklonem"
                    pocet_chyb = pocet_chyb + 1
            else:
                new_feature["P_SKLstav"] = f"Byl SPLNĚN limit {limit_pro_limit30} % plochy s vysokým podélným sklonem"

            if zeop_i_bool:
                if zeop_vyhovuje:
                    new_feature["ZEOPstav"] = f"Byl SPLNĚN limit {limit_pro_zeop} % plochy s podélným sklonem přes 7 % na souvislé ploše alespoň 1 ha"
                else:
                    new_feature["ZEOPstav"] = f"Byl PŘEKROČEN limit {limit_pro_zeop} % plochy s podélným sklonem přes 7 % na souvislé ploše alespoň 1 ha"
                    pocet_chyb = pocet_chyb + 1
            else:
                new_feature["ZEOPstav"] = f"Byl SPLNĚN limit {limit_pro_zeop} % plochy s podélným sklonem přes 7 % na souvislé ploše alespoň 1 ha"

            new_feature["SKL<3%(%)"] = maska3p_procenta
            

            # teď se  nekontroluje, ale později bude
            if maska3_i_bool:
                if maska3p_procenta <= limit_pro_maska3 :
                    new_feature["SKL<3%stav"] = f"Byl SPLNĚN limit {limit_pro_maska3} % plochy kde je svažitost nižší než 3 %"
                else:
                    new_feature["SKL<3%stav"] = f"Byl PŘEKROČEN limit {limit_pro_maska3} % plochy kde je svažitost nižší než 3 %"
                    pocet_chyb = pocet_chyb + 1
            else:
                new_feature["SKL<3%stav"] = f"Byl PŘEKROČEN limit {limit_pro_maska3} % plochy kde je svažitost nižší než 3 %"
                pocet_chyb = pocet_chyb + 1


            if plocha_dso_v_dpb > 0:
                new_feature["DSOnaDPB"] = "Existuje"
            else:
                new_feature["DSOnaDPB"] = "NEexistuje"

            if not np_bool:
                new_feature["STPnaDSO"] = "NEŘEŠENO"
            elif (abs(plocha_dso_v_dpb - plocha_dso_v_np) < 1):
                new_feature["STPnaDSO"] = "SPLNĚNO"
            else:
                new_feature["STPnaDSO"] = "NESPLNĚNO"
                pocet_chyb = pocet_chyb + 1
                
            new_feature["STPvDPB(%)"] = round(NP_p,2)
            #new_feature["AEvDPB(%)"] = round(AE_p,2)
            
                
            new_feature["pocet_chyb"] = pocet_chyb

            if pocet_chyb > 0:
                new_feature["stav_DPB"] = "Není splněna nejméně jedna podmínka"
            else:
                new_feature["stav_DPB"] = "Jsou splněny podmínky pro návrh projektu"
            dpb_all_provider.addFeature(new_feature)
            dpb_all.updateExtents()
            
            #progress bar
            posun = int(25 + (pocitadlo_dpb / pocet_dpb) * 60)
            self.dlg.progressBar_vypocet.setValue(posun)
            self.dlg.progressBar_vypocet.setFormat(f"Bylo vyřešeno {pocitadlo_dpb}/{pocet_dpb} DPB")
            pocitadlo_dpb = pocitadlo_dpb + 1
            
            
        # --------------------------------------------------------------------------------------------------------------- 

        self.dlg.progressBar_vypocet.setValue(90)
        self.dlg.progressBar_vypocet.setFormat("Ukládání")
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Uložení výsledků tam kde DPB vyhovuje (--------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 

        dpb_vyhovuje = processing.run("native:extractbyattribute",
                                      {'INPUT': dpb_all, 'FIELD': 'pocet_chyb', 'OPERATOR': 0,
                                       'VALUE': '0', 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        kostra_vyhovuje_bool = False
        if dpb_vyhovuje.featureCount() > 0:

            Exportdir_vyhovuje = os.path.join(Exportdir_path, f"psp_vyhovuje_{dist}m_{kod_uzivatele}_{id_procesu}")
            os.makedirs(os.path.join(Exportdir_vyhovuje, "dalsi_vrstvy"), exist_ok=True)
            #os.mkdir(Exportdir_vyhovuje)
            #os.mkdir(os.path.join(Exportdir_vyhovuje, "dalsi_vrstvy"))

            dpb_vyhovuje_path = os.path.join(Exportdir_vyhovuje, f"DPB_vyhovuje_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
            ulozeni_vektorove_vrstvy(dpb_vyhovuje, EPSG, dpb_vyhovuje_path)

            os.mkdir(os.path.join(Exportdir_vyhovuje, "trajektorie"))
            trajektorie_vyhovuje = processing.run("native:clip", {
                'INPUT': trajektorie_all,
                'OVERLAY': dpb_vyhovuje,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            traj_vyhovuje_path = os.path.join(Exportdir_vyhovuje, "trajektorie", "trajektorie.shp")
            ulozeni_vektorove_vrstvy(trajektorie_vyhovuje, EPSG, traj_vyhovuje_path)
            
            polygony_ohrozenost_maska_union_singleparts_all_vyhovuje = processing.run("native:clip", {
                'INPUT': polygony_ohrozenost_maska_union_singleparts_all,
                'OVERLAY': dpb_vyhovuje,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            polygony_ohrozenost_maska_union_singleparts_all_vyhovuje_path = os.path.join(Exportdir_vyhovuje, "dalsi_vrstvy", f"ohrozenost_maska_union_s_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
            ulozeni_vektorove_vrstvy(polygony_ohrozenost_maska_union_singleparts_all_vyhovuje, EPSG, polygony_ohrozenost_maska_union_singleparts_all_vyhovuje_path)

            polygony_ohrozenost_maska_union_all_vyhovuje = processing.run("native:clip", {
                'INPUT': polygony_ohrozenost_maska_union_all,
                'OVERLAY': dpb_vyhovuje,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            polygony_ohrozenost_maska_union_all_vyhovuje_path = os.path.join(Exportdir_vyhovuje , "dalsi_vrstvy", f"ohrozenost_maska_union_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
            ulozeni_vektorove_vrstvy(polygony_ohrozenost_maska_union_all_vyhovuje, EPSG, polygony_ohrozenost_maska_union_all_vyhovuje_path)

            maska3_vyhovuje = processing.run("native:clip", {
                'INPUT': maska3_all,
                'OVERLAY': dpb_vyhovuje,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            maska3_vyhovuje_path = os.path.join(Exportdir_vyhovuje, "dalsi_vrstvy", f"Maska3p_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
            ulozeni_vektorove_vrstvy(maska3_vyhovuje, EPSG, maska3_vyhovuje_path)

            # Kostra jen při dalších kritériích: pásy + STP
            if pasy_bool == True and np_bool == True:
                os.mkdir(os.path.join(Exportdir_path, f"kostra_psp_{dist}m_{kod_uzivatele}_{id_procesu}"))
                kostra_vyhovuje = processing.run("native:clip", {
                    'INPUT': kostra_psp_all,
                    'OVERLAY': dpb_vyhovuje,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                kostra_vyhovuje.startEditing()
                for feat in kostra_vyhovuje.getFeatures():
                    if feat.geometry().area() < 1:
                        kostra_vyhovuje.deleteFeature(feat.id())
                kostra_vyhovuje.commitChanges()

                kostra_vyhovuje_path = os.path.join(Exportdir_path, f"kostra_psp_{dist}m_{kod_uzivatele}_{id_procesu}", f"kostra_psp_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
                ulozeni_vektorove_vrstvy(kostra_vyhovuje, EPSG, kostra_vyhovuje_path)
                if kostra_vyhovuje.featureCount() > 0:
                    kostra_vyhovuje_bool = True
                    self.dlg.lineEdit_kostraxlsx.setText(Exportdir_path)

            vrstevnice_path = processing.run("gdal:contour",
                                             {'INPUT': orez_dmt, 'BAND': 1, 'INTERVAL': 2, 'FIELD_NAME': 'ELEV',
                                              'CREATE_3D': False, 'IGNORE_NODATA': False, 'NODATA': None, 'OFFSET': 0,
                                              'EXTRA': '', 'OUTPUT': TEMPdir + "//Vrstevnice.shp"})["OUTPUT"]
            vrstevnice = QgsVectorLayer(vrstevnice_path, "vrstevnice", "ogr")
            vrstevnice.startEditing()
            new_field = QgsField("typ", QVariant.String)
            vrstevnice.addAttribute(new_field)
            vrstevnice.updateFields()
            for feat in vrstevnice.getFeatures():
                vyska = feat["ELEV"]
                if vyska % 10 == 0:
                    feat["typ"] = "velka"
                else:
                    feat["typ"] = "mala"
                vrstevnice.updateFeature(feat)
            vrstevnice.commitChanges()
            vrstevnice_path = os.path.join(Exportdir_vyhovuje, "dalsi_vrstvy", f"Vrstevnice_{dist}m_{kod_uzivatele}_{id_procesu}.shp")
            ulozeni_vektorove_vrstvy(vrstevnice, EPSG, vrstevnice_path)
            
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Zobrazení vrstev v projektu (------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------     
            

        dpb_chyba = processing.run("native:extractbyattribute", {
            'INPUT': dpb_all, 'FIELD': 'pocet_chyb', 'OPERATOR': 2, 'VALUE': '0',
            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        if dpb_chyba.featureCount() > 0:
            Exportdir_nevyhovuje = Exportdir_path + f"\\psp_nevyhovuje_{dist}m_{kod_uzivatele}_{id_procesu}\\"
            os.mkdir(Exportdir_nevyhovuje)

            dpb_nevyhovuje_path = Exportdir_nevyhovuje + f"DPB_nevyhovuje_{dist}m_{kod_uzivatele}_{id_procesu}.shp"
            ulozeni_vektorove_vrstvy(dpb_chyba, EPSG, dpb_nevyhovuje_path)



        if maska3_all.featureCount() > 0:
            maska3_all.setName(f"Maska3p_{dist}m_{kod_uzivatele}_{id_procesu}") 
            maska3_all.renderer().symbol().setColor(QColor("#f5d441"))
            maska3_all.triggerRepaint()
            QgsProject.instance().addMapLayer(maska3_all)

        if kostra_vyhovuje_bool:
            kostra_vyhovuje_show = QgsVectorLayer(kostra_vyhovuje_path, f"kostra_psp_{dist}m_{kod_uzivatele}_{id_procesu}", "ogr")
            symbology_kategorie(kostra_vyhovuje_show, 'SCHEMA', ["A", "B", "D", "E", "F", "ostatni"],
                                [QColor(102, 255, 102), QColor(102, 255, 255), QColor(192, 192, 192), QColor(65, 38, 171), QColor(42, 188, 159), QColor(247, 165, 183)], ["A", "B", "D", "E", "F", "ostatni"])
            QgsProject.instance().addMapLayer(kostra_vyhovuje_show)





        dpb_all.setName(f"DPB_stav návrhu_{dist}m_{kod_uzivatele}_{id_procesu}")
        symbology_kategorie(dpb_all, 'stav_DPB', ["Jsou splněny podmínky pro návrh projektu", "Není splněna nejméně jedna podmínka"], ["#32b259", "#e77148"],
                            ["Splňuje podmínky", "Nesplňuje nejméně jednu podmínku"])
        QgsProject.instance().addMapLayer(dpb_all)

        if siroke_pasy_all.featureCount() > 0:
            siroke_pasy_all.setName(f"Nadlimitní pásy_{dist}m_{kod_uzivatele}_{id_procesu}")
            symbology_kategorie(siroke_pasy_all, 'typ',
                                ["Poloha překročení šířky", "Široký pás mimo NEO", "Široký pás na NEO"],
                                ["#d13d96", "#e8ac16", "#1fe56e"],
                                ["Poloha překročení šířky", "Široký pás mimo NEO", "Široký pás na NEO"])
            QgsProject.instance().addMapLayer(siroke_pasy_all)

        if limit30_all.featureCount() > 0:
            limit30_all.setName(f"Limit30p_{dist}m_{kod_uzivatele}_{id_procesu}")
            symbology_kategorie(limit30_all, 'P_SKLstav', ["vyhovuje", "nevyhovuje"], ["#16e52f", "#e65975"],
                                ["Splňuje podmínky", f"Více než {limit_pro_limit30 } % plochy má překročený sklon"])
            QgsProject.instance().addMapLayer(limit30_all)

        if zeop_all.featureCount() > 0:       
            zeop_all.setName(f"ZEOP_{dist}m_{kod_uzivatele}_{id_procesu}")
            zeop_all.renderer().symbol().setColor(QColor.fromRgb(146, 112, 210))
            zeop_all.triggerRepaint()
            QgsProject.instance().addMapLayer(zeop_all)

        if dso_all.featureCount() > 0:
            dso_all.setName(f"DSO minimum_{dist}m_{kod_uzivatele}_{id_procesu}")
            dso_all.renderer().symbol().setColor(QColor("#18b1f3"))
            dso_all.triggerRepaint()
            QgsProject.instance().addMapLayer(dso_all)

        if dpb_spatne_sirky_all.featureCount() > 0:
            dpb_spatne_sirky_all.setName(f"Pravděpodobně špatně zadaná šířka pásů_{dist}m_{kod_uzivatele}_{id_procesu}")
            dpb_spatne_sirky_all.renderer().symbol().setColor(QColor("#d62d98"))
            dpb_spatne_sirky_all.triggerRepaint()
            QgsProject.instance().addMapLayer(dpb_spatne_sirky_all)

            self.iface.messageBar().pushMessage("Šířka pásů",
                                                "V návrhu se vyskytují DPB s trajektoriemi, které mají pravděpodobně špatně zadanou šířku pásů",
                                                level=Qgis.MessageLevel.Warning)
            
        if trajektorie_kontrola_all.featureCount() > 0:
            trajektorie_kontrola_all.setName(f"Pravděpodobně trajektorie mimo osu pásu_{dist}m_{kod_uzivatele}_{id_procesu}")
            trajektorie_kontrola_all.renderer().symbol().setColor(QColor("#e31a1c"))
            trajektorie_kontrola_all.triggerRepaint()
            QgsProject.instance().addMapLayer(trajektorie_kontrola_all)



        trajektorie_all.setName(f"Trajektorie_{dist}m_{kod_uzivatele}_{id_procesu}")
        QgsProject.instance().addMapLayer(trajektorie_all)

        self.dlg.progressBar_vypocet.setValue(100)
        self.dlg.progressBar_vypocet.setFormat("Hotovo")



        self.nacitani_vrstev_s_textem()

        # ---------------------------------------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------


    def spusteni_vypoctu(self):

        umisteni_kostraprojektu = self.dlg.lineEdit_kostraprojektu.text()
        slozka_kostraprojektu_existuje = os.path.isdir(umisteni_kostraprojektu)

        kod_uzivatele = self.dlg.lineEdit_koduzivatele.text()
        kod_uzivatele_existuje = kod_uzivatele.isdigit()

        # kontrola DMT
        chyby_dmt = 0
        selectedLayerDMT = self.dlg.comboBox_dmt.currentData()

        if selectedLayerDMT.rasterUnitsPerPixelX() != 2:
            chyby_dmt = chyby_dmt + 1
        if selectedLayerDMT.rasterUnitsPerPixelY() != 2:
            chyby_dmt = chyby_dmt + 1
        if selectedLayerDMT.extent().xMinimum() % 2 != 0:
            chyby_dmt = chyby_dmt + 1
        if selectedLayerDMT.extent().yMinimum() % 2 != 0:
            chyby_dmt = chyby_dmt + 1
            
            

        # Získání aktuálního uživatelského jména
        user_name = os.getlogin()
        # Regulární výraz pro detekci diakritických znaků
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')  
        
        vrstvy_v_comboboxech = [self.dlg.comboBox_maska.currentData(), 
                                self.dlg.comboBox_trajektorie.currentData(),
                                self.dlg.comboBox_np.currentData(),
                                self.dlg.comboBox_agroenvi.currentData(),
                                self.dlg.comboBox_pasy.currentData()
                                ]
        nazvy_vrstev_v_comboboxech = ["maska", "trajektorie", "stabilizační pásy", "agroenvi", "pásy"]
        
        
        # Spočítání výskytu hodnot
        counts = Counter(vrstvy_v_comboboxech)


        if ((slozka_kostraprojektu_existuje == False)):
            self.iface.messageBar().pushMessage("Chybějící údaje", "Chybí umístění složky", level=Qgis.MessageLevel.Critical)
        elif kod_uzivatele_existuje == False:
            self.iface.messageBar().pushMessage("Chybějící údaje", "Chybí kód uživatele nebo se nejedná o číslo",
                                                level=Qgis.MessageLevel.Critical)
        elif chyby_dmt > 0:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Raster DMR má špatné rozlišení (2x2) nebo počátek (celá sudá souřadnice). DMR 5G lze stáhnout tlačítkem",
                                                level=Qgis.MessageLevel.Critical)
        elif len(umisteni_kostraprojektu) > 60:
            self.iface.messageBar().pushMessage("Špatná cesta", "Cesta pro uložení výsledků je příliš dlouhá",
                                                level=Qgis.MessageLevel.Critical)
        elif diacritic_pattern.search(user_name):
            self.iface.messageBar().pushMessage("Špatné uživatelské jméno", "Varování" +\
            f"Vaše uživatelské jméno v systém Windows '{user_name}' obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte uživatelské jméno vašeho počítače.",
                                                level=Qgis.MessageLevel.Critical)
                
        elif ((self.dlg.comboBox_maska.currentData() == None) or (self.dlg.comboBox_trajektorie.currentData() == None) or (self.dlg.comboBox_dmt.currentData() == None)):
            self.iface.messageBar().pushMessage("Chybí vrstvy",
            "Chybí vrstva pro tajektorie, masku (DPB) nebo DMT", level=Qgis.MessageLevel.Critical)
                    
                      
        elif len(counts) != len(vrstvy_v_comboboxech):
            # Kontrola, zda jsou všechny hodnoty různé
            # Výpis, které proměnné jsou stejné
            shodna_jmena = []
            for value, count in counts.items():
                if count > 1:
                    # Najdeme všechny proměnné, které mají tuto hodnotu
                    matching_names = [nazvy_vrstev_v_comboboxech[i] for i in range(len(vrstvy_v_comboboxech)) if vrstvy_v_comboboxech[i] == value]
                    if value != None:
                        shodna_jmena.append(f"{', '.join(matching_names)}")
            
            
            if len(shodna_jmena) > 0:
                shodna_jmena = "\n"+"\n".join(shodna_jmena) + "\n\n"
                response = QMessageBox.information(None,
                                                   "Start",
                                                   f"Připraveno k výpočtu.\nTyto vrstvy jsou shodné:\n{shodna_jmena}Klikněte na OK pokud PŘESTO chcete pokračovat",
                                                   QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
                if response == QMessageBox.StandardButton.Ok:
                    print("Pokračuji...")
                    self.vypocet_sklonu()
                elif response == QMessageBox.StandardButton.Cancel:
                    print("Výpočet byl zastaven.")
            else:
                QgsProject.instance().setCrs(QgsCoordinateReferenceSystem("EPSG:5514"))
                
                response = QMessageBox.information(None,
                                                   "Start",
                                                   "Připraveno k výpočtu.\nKlikněte na OK pro pokračování",
                                                   QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
                if response == QMessageBox.StandardButton.Ok:
                    print("Pokračuji...")
                    self.vypocet_sklonu()
                elif response == QMessageBox.StandardButton.Cancel:
                    print("Výpočet byl zastaven.")
        
        
        
        
        else:
            
            QgsProject.instance().setCrs(QgsCoordinateReferenceSystem("EPSG:5514"))
            
            response = QMessageBox.information(None,
                                               "Start",
                                               "Připraveno k výpočtu.\nKlikněte na OK pro pokračování",
                                               QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
            if response == QMessageBox.StandardButton.Ok:
                print("Pokračuji...")
                self.vypocet_sklonu()
            elif response == QMessageBox.StandardButton.Cancel:
                print("Výpočet byl zastaven.")
            
            
    def vykresleni_linii(self):
        
        cesta_ulozeni = self.dlg.lineEdit_cestalinie.text()
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(cesta_ulozeni):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)
        elif os.path.isdir(cesta_ulozeni) == False:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Není vyplněna existující složka",
                                                level=Qgis.MessageLevel.Critical)
        else:
            self.vykresleni_linii_proces()

    def vykresleni_linii_proces(self):

        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Načítání dat a vrstev (------------------------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 
        
        sirkapas = self.dlg.spinBox_sirkapas2.value()
        
        settings = QSettings("MoPSP", "Settings")  # "MyPlugin" je název pluginu
        settings.setValue("width_value", sirkapas)

        self.dlg.progressBar_vypocet.setFormat("Start")
        self.dlg.progressBar_vypocet.setValue(5)
        
        selectedLayerKlicovaLinie = self.dlg.comboBox_klicovalinie.currentData()
        jmeno_orig_linie = selectedLayerKlicovaLinie.name()        

        selectedLayerKlicovaLinie.selectAll()
        LayerKlicovaLinie = \
        processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerKlicovaLinie, 'OUTPUT': 'memory:'})[
            'OUTPUT']
        selectedLayerKlicovaLinie.removeSelection()

        source_crs = QgsCoordinateReferenceSystem(LayerKlicovaLinie.crs().authid())
        target_crs = QgsCoordinateReferenceSystem("EPSG:5514")

        LayerKlicovaLinie.startEditing()
        for feat in LayerKlicovaLinie.getFeatures():
            geom = feat.geometry()
            geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))
            feat.setGeometry(geom)
            LayerKlicovaLinie.updateFeature(feat)
        LayerKlicovaLinie.setCrs(target_crs)
        LayerKlicovaLinie.commitChanges()
        LayerKlicovaLinie.setCrs(target_crs)
        LayerKlicovaLinie.setName("Klic_linie_5514")
        # QgsProject.instance().addMapLayer(LayerKlicovaLinie)

        selectedLayerMaskaLinie = self.dlg.comboBox_maskalinie.currentData()

        selectedLayerMaskaLinie.selectAll()
        LayerMaskaLinie = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerMaskaLinie, 'OUTPUT': 'memory:'})['OUTPUT']
        selectedLayerMaskaLinie.removeSelection()

        source_crs = QgsCoordinateReferenceSystem(LayerMaskaLinie.crs().authid())
        target_crs = QgsCoordinateReferenceSystem("EPSG:5514")

        area_maska = 0
        LayerMaskaLinie.startEditing()
        for feat in LayerMaskaLinie.getFeatures():
            geom = feat.geometry()
            area_maska = area_maska + geom.area()
            geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))
            feat.setGeometry(geom)
            LayerMaskaLinie.updateFeature(feat)
        LayerMaskaLinie.setCrs(target_crs)
        LayerMaskaLinie.commitChanges()
        LayerMaskaLinie.setCrs(target_crs)
        LayerMaskaLinie.setName("Maska_5514")
        # QgsProject.instance().addMapLayer(LayerMaskaLinie)
        
        

        pocetkrivek = 2
        area_buffer = 0
        while round(area_buffer,0) < round(area_maska,0):
            multiringbuffer = processing.run("native:multiringconstantbuffer", {
                'INPUT': LayerKlicovaLinie,
                'RINGS': pocetkrivek, 'DISTANCE': sirkapas, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

            multiringbuffer_orez = processing.run("native:clip", {'INPUT': multiringbuffer,
                                           'OVERLAY': LayerMaskaLinie,
                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            area_buffer = 0
            for feat in multiringbuffer_orez.getFeatures():
                area_buffer = area_buffer + feat.geometry().area()

            pocetkrivek = pocetkrivek + 1
        #QgsProject.instance().addMapLayer(multiringbuffer)
        
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Funkce (---------------------------------------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 
        
        
        # Funkce pro nalezeni volneho nazvu souboru
        def get_unique_filepath(base_dir, base_name):
            counter = 1
            while True:
                filepath = os.path.join(base_dir, f"{base_name}_{counter}.shp")
                if not os.path.exists(filepath):
                    return filepath
                counter += 1
                
        # Funkce pro ziskani poslednich 5 cisel ze souradnic bodu
        def generate_scelek_id(point_geometry):
            x = point_geometry.asPoint().x()
            y = point_geometry.asPoint().y()
            x_str = str(abs(int(x)))  # Prevod x souradnice na 5mistny string
            y_str = str(abs(int(y)))  # Prevod y souradnice na 5mistny string
            return x_str[-5:] + y_str[-5:]  # Poslednich 5 cisel z obou souradnic
        
        
        # Funkce pro nacteni vrstvy
        def reload_layer(layer_path, layer_name, provider):
            layer = QgsVectorLayer(layer_path, layer_name, provider)
            if not layer.isValid():
                print(f"Vrstva {layer_name} se nepodarilo nacist.")
            else:
                QgsProject.instance().addMapLayer(layer)
            return layer

        # Funkce pro odstraneni Z souradnic
        def remove_z_coordinates(geometry):
            if geometry.isEmpty():
                return geometry
            wkt = geometry.asWkt()
            wkt_2d = wkt.replace(' Z ', ' ')
            return QgsGeometry.fromWkt(wkt_2d)

        # Funkce pro kontrolu, zda jsou geometrie sousedni s toleranci
        def are_adjacent(geom1, geom2, tolerance=0.1):
            buffered_geom1 = geom1.buffer(tolerance, 5)
            return buffered_geom1.intersects(geom2)

        # Funkce pro zjisteni, zda jsou dve krivky paralelni s maximalni odchylkou
        def are_parallel(geom1, geom2, tolerance=0.1):
            for point in geom1.vertices():
                point_xy = QgsPointXY(point.x(), point.y())
                point_buffer = QgsGeometry.fromPointXY(point_xy).buffer(tolerance, 5)
                if not point_buffer.intersects(geom2):
                    return False
            return True

        # Funkce pro odstraneni duplicitnich krivek
        def remove_duplicate_curves(features, tolerance=0.1):
            unique_features = []
            for feature in features:
                geom = feature.geometry()
                duplicate_found = False
                for unique_feature in unique_features:
                    unique_geom = unique_feature.geometry()
                    if are_parallel(geom, unique_geom, tolerance):
                        duplicate_found = True
                        break
                if not duplicate_found:
                    unique_features.append(feature)
            return unique_features

        # Funkce pro vytvoreni pametove vrstvy
        def create_memory_layer(name, geom_type, crs):
            layer = QgsVectorLayer(f"{geom_type}?crs={crs.authid()}", name, "memory")
            if not layer.isValid():
                print(f"Vrstva {name} se nepodarilo vytvorit.")
            return layer

        # Funkce pro vytvoreni grafu sousedstvi
        def create_adjacency_graph(features, tolerance=0.01):
            graph = {}
            for feature in features:
                graph[feature.id()] = []
                for other_feature in features:
                    if feature.id() != other_feature.id():
                        if are_adjacent(feature.geometry(), other_feature.geometry(), tolerance):
                            graph[feature.id()].append(other_feature.id())
            return graph

        # Funkce pro prirazeni stitku s kontrolou sousedu a dodrzeni sekvence AB
        def assign_labels(graph, features, labels_sequence, start_feature_id):
            labels = {}
            visited = set()

            def bfs(start):
                queue = deque([start])
                while queue:
                    current = queue.popleft()
                    if current in visited:
                        continue
                    visited.add(current)
                    neighbors = graph[current]
                    used_labels = {labels[neighbor] for neighbor in neighbors if neighbor in labels}
                    available_labels = [label for label in labels_sequence if label not in used_labels]
                    if available_labels:
                        labels[current] = available_labels[0]
                        print(f"Prirazujeme stitek {labels[current]} prvku ID: {current}")
                    else:
                        print(f"Zadny volny stitek pro prvek ID: {current}")
                    for neighbor in neighbors:
                        if neighbor not in visited:
                            queue.append(neighbor)

            bfs(start_feature_id)
            return labels

        # Funkce pro zpracovani pruniku bufferu s maskou bez slevani geometrie
        def process_intersection_with_mask(buffer_layer, mask_layer, crs):
            layer_name = "razeni"
            intersect_layer = create_memory_layer(layer_name, "Polygon", crs)
            intersect_layer_data = intersect_layer.dataProvider()
            intersect_layer_data.addAttributes([QgsField("id", QVariant.Int), QgsField("SCHEMA", QVariant.String)])
            intersect_layer.updateFields()
            for buffer_feature in buffer_layer.getFeatures():
                buffer_geom = buffer_feature.geometry()
                for mask_feature in mask_layer.getFeatures():
                    mask_geom = mask_feature.geometry()
                    if buffer_geom.intersects(mask_geom):
                        intersection_geom = buffer_geom.intersection(mask_geom)
                        if not intersection_geom.isEmpty():
                            if intersection_geom.isMultipart():
                                singleparts = intersection_geom.asGeometryCollection()
                                for part in singleparts:
                                    intersect_feature = QgsFeature()
                                    intersect_feature.setGeometry(part)
                                    intersect_feature.setAttributes([buffer_feature['id'], ''])
                                    intersect_layer_data.addFeature(intersect_feature)
                            else:
                                intersect_feature = QgsFeature()
                                intersect_feature.setGeometry(intersection_geom)
                                intersect_feature.setAttributes([buffer_feature['id'], ''])
                                intersect_layer_data.addFeature(intersect_feature)
            intersect_layer.updateExtents()
            return intersect_layer

        # Funkce pro ulozeni vrstvy do shapefile
        def save_layer_as_shapefile(layer, filepath):
            try:
                os.makedirs(os.path.dirname(filepath), exist_ok=True)  # Vytvori cestu, pokud neexistuje
                options = QgsVectorFileWriter.SaveVectorOptions()
                options.driverName = "ESRI Shapefile"
                options.fileEncoding = "windows-1250"
                options.destCRS = layer.crs()
                error = QgsVectorFileWriter.writeAsVectorFormatV3(
                    layer, filepath, QgsCoordinateTransformContext(), options)
                if error[0] == QgsVectorFileWriter.WriterError.NoError:
                    print(f"Vrstva uspesne ulozena do {filepath}")
                else:
                    print(f"Chyba pri ukladani vrstvy do {filepath}: {error[1]}")
            except Exception as e:
                print(f"Doslo k chybe pri ukladani vrstvy: {str(e)}")

        

        def vymazat_nulove_plochy(lyr):
            lyr.startEditing()
            for feat in lyr.getFeatures():
                if feat.geometry().area() < 0.1:
                    lyr.deleteFeature(feat.id())

        # ---------------------------------------------------------------------------------------------------------------
        
        self.dlg.progressBar_vypocet.setFormat("Tvorba trajektorií") 
        self.dlg.progressBar_vypocet.setValue(45)
        
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Hlavní trajektorie (---------------------------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 


        mrb_linie = processing.run("native:polygonstolines", {
            'INPUT': multiringbuffer,
            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        mrb_linie_slouceni = processing.run("native:mergevectorlayers", {'LAYERS': [mrb_linie, LayerKlicovaLinie],
                                                                         'CRS': QgsCoordinateReferenceSystem(
                                                                             'EPSG:5514'),
                                                                         'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
           
        #tvorba trajektorií v osách pásů
        mrb_jednodilne = processing.run("native:multiparttosingleparts", {
            'INPUT': mrb_linie_slouceni,
            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        mrb_jednodilne.setName("multiring")
        #QgsProject.instance().addMapLayer(mrb_jednodilne)

        mrb_orez = processing.run("native:clip", {'INPUT': mrb_jednodilne,
                                                  'OVERLAY': LayerMaskaLinie,
                                                  'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        
        mrb_orez = processing.run("native:mergelines", {'INPUT':mrb_orez,
                                                         'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]

        mrb_orez = processing.run("native:deleteduplicategeometries", {
            'INPUT': mrb_orez,
            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        mrb_orez = processing.run("native:multiparttosingleparts", {
            'INPUT': mrb_orez,
            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
        symbol.setColor(QColor("darkgreen"))
        renderer = QgsSingleSymbolRenderer(symbol)
        mrb_orez.setRenderer(renderer)
        mrb_orez.triggerRepaint()     
        mrb_orez.setName(str(sirkapas) + "_m_trajektorie__" + jmeno_orig_linie)
        
        
        # Pouziti pointonsurface pouze jednou pro vstupni polygonovou vrstvu
        point_on_surface_result = processing.run("native:pointonsurface", {
            'INPUT': LayerMaskaLinie,
            'ALL_PARTS': False,
            'OUTPUT': 'TEMPORARY_OUTPUT'
        })

        single_point = next(point_on_surface_result['OUTPUT'].getFeatures())
        scelek_id = generate_scelek_id(single_point.geometry())  # Generovani SCELEK_ID z jedineho bodu
        
        
        if len(self.dlg.lineEdit_cestalinie.text()) > 0:
            output_dir = self.dlg.lineEdit_cestalinie.text()
            output_trajektorie_dir = output_dir + "\\trajektorie"
            if os.path.isdir(output_trajektorie_dir) == False:
                os.mkdir(output_trajektorie_dir)
            output_filepath_trajektorie = get_unique_filepath(output_trajektorie_dir, 'trajektorie_' + str(sirkapas) + "m_" + scelek_id)
            # Ulozeni vrstvy jako shapefile
            save_layer_as_shapefile(mrb_orez, output_filepath_trajektorie)
  
        
        if self.dlg.checkBox_ulozeniGPS.isChecked():
            
            #tvořeno v epsg 4326
            output_dir = self.dlg.lineEdit_cestalinie.text()
            output_dodatecne_trajektorie_dir = output_dir + "\\trajektorie_epsg_4326"
            os.makedirs(output_dodatecne_trajektorie_dir, exist_ok=True)
            
            output_filepath_trajektorie = get_unique_filepath(output_dodatecne_trajektorie_dir, str(sirkapas) + "m_trajektorie_4326_" + scelek_id)
            reproject_layer_5514_to_4326(mrb_orez, output_filepath_trajektorie, self.iface)
            
            
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Tvorba pásů (----------------------------------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 
        
        if self.dlg.checkBox_vcetnepasu.isChecked():
            
            # 1. Posunutí původní linie o polovinu šířky prstence – získáme základní offsetovanou křivku
            offset_result = processing.run("native:offsetline", {
                'INPUT': LayerKlicovaLinie,
                'DISTANCE': sirkapas / 2,
                'SEGMENTS': 8,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'OUTPUT': 'memory:'
            })
            base_curve = offset_result['OUTPUT']
            #QgsProject.instance().addMapLayer(base_curve)
             
            # 2. Vytvoření všech prstenců pomocí multiringconstantbuffer
            num_rings = pocetkrivek + 3  # předpokládaný maximální počet prstenců
            multi_buffer_result = processing.run("native:multiringconstantbuffer", {
                'INPUT': base_curve,
                'DISTANCE': sirkapas,
                'RINGS': num_rings,
                'OUTPUT': 'memory:'
            })
            all_rings_layer = multi_buffer_result['OUTPUT']
            
            # 3. Iterativní filtrování prstenců podle průniku s polygonem
            rings = []
            for feature in all_rings_layer.getFeatures():
                single_ring = QgsVectorLayer("Polygon?crs=" + all_rings_layer.crs().authid(), "ring", "memory")
                single_provider = single_ring.dataProvider()
                single_provider.addAttributes(all_rings_layer.fields())
                single_ring.updateFields()
                single_provider.addFeature(feature)
             
                extract_result = processing.run("native:extractbylocation", {
                    'INPUT': single_ring,
                    'PREDICATE': [0],  # 0 = intersects
                    'INTERSECT': LayerMaskaLinie,
                    'OUTPUT': 'memory:'
                })
                intersection = extract_result['OUTPUT']
             
                if any(intersection.getFeatures()):
                    rings.append(intersection)
                else:
                    break  # první nepřekrývající znamená konec smysluplných prstenců
             
            if not rings:
                raise Exception("Nebyl vygenerován žádný prstenec, který by se protínal s polygonem.")
                
            # 4. Sloučení všech prstenců do jedné vrstvy
            merge_rings_result = processing.run("native:mergevectorlayers", {
                'LAYERS': rings,
                'CRS': LayerKlicovaLinie.crs(),
                'OUTPUT': 'memory:'
            })
            merged_rings_layer = merge_rings_result['OUTPUT']
            #QgsProject.instance().addMapLayer(merged_rings_layer)
             
            # 5. Převod sloučených prstenců (polygonů) na linie
            polygon_to_line_result = processing.run("native:polygonstolines", {
                'INPUT': merged_rings_layer,
                'OUTPUT': 'memory:'
            })
            polygon_to_line_layer = polygon_to_line_result['OUTPUT']
            polygon_to_line_layer.setName("polygon_na_linie")
            #QgsProject.instance().addMapLayer(polygon_to_line_layer)
             
            # 6. Sjednocení vrstvy "polygon_na_linie" s offsetovanou křivkou (base_curve)
            merge_lines_result = processing.run("native:mergevectorlayers", {
                'LAYERS': [polygon_to_line_layer, base_curve],
                'CRS': polygon_to_line_layer.crs(),
                'OUTPUT': 'memory:'
            })
            merged_lines_layer = merge_lines_result['OUTPUT']
            #QgsProject.instance().addMapLayer(merged_lines_layer)
             
            # 7. Rozdělení původního polygonu pomocí výsledných linií
            split_result = processing.run("native:splitwithlines", {
                'INPUT': LayerMaskaLinie,
                'LINES': merged_lines_layer,
                'OUTPUT': 'memory:'
            })
            split_layer = split_result['OUTPUT']
            #QgsProject.instance().addMapLayer(split_layer)
            
            split_layer = processing.run("native:clip", {'INPUT':split_layer,
                                           'OVERLAY':LayerMaskaLinie,
                                           'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
            
            split_layer.startEditing()
            for feat in split_layer.getFeatures():
                if feat.geometry().area() < 1:
                    split_layer.deleteFeature(feat.id())
            split_layer.commitChanges()
            
             
            print("Skript dokončen, všechny vrstvy byly přidány do projektu QGIS.")

            split_layer_provider = split_layer.dataProvider()
            split_layer_provider.addAttributes([QgsField("id", QVariant.Int), QgsField("SCHEMA", QVariant.String)])
            split_layer.updateFields()
            crs = QgsCoordinateReferenceSystem("EPSG:5514")  
    
            if split_layer:
                labels_sequence = ['A', 'B']
                features = list(split_layer.getFeatures())
                adjacency_graph = create_adjacency_graph(features, tolerance=0.1)
    
                if features:
                    longest_side_feature = features[0]
                    labels = assign_labels(adjacency_graph, features, labels_sequence, longest_side_feature.id())
    
                    split_layer.startEditing()
                    for feature in split_layer.getFeatures():
                        label = labels.get(feature.id(), None)
                        if label is not None:
                            feature.setAttribute('SCHEMA', label)
                            split_layer.updateFeature(feature)
    
                    split_layer.commitChanges()
    
                    # Odstraneni prvku se stitkem "B"
                    filtered_layer = create_memory_layer("FilteredRazeni", "Polygon", crs)
                    filtered_layer_data = filtered_layer.dataProvider()
                    filtered_layer_data.addAttributes(split_layer.fields())
                    filtered_layer.updateFields()
    
                    for feature in split_layer.getFeatures():
                        if feature['SCHEMA'] == 'A':
                            filtered_layer_data.addFeature(feature)
    
                    filtered_layer.updateExtents()
                    #QgsProject.instance().addMapLayer(filtered_layer)
    
                    print("Skript SC1 uspesne dokonceny.")
                else:
                    print("Nenalezen zadny prvek.")
    
                # SC2 - operace rozdilu a slouceni s vrstvou filter_razeni.shp
                input_layer_path = LayerMaskaLinie
    
                result = processing.run("native:difference", {
                    'INPUT': input_layer_path,
                    'OVERLAY': filtered_layer,
                    'OUTPUT': 'TEMPORARY_OUTPUT',
                    'GRID_SIZE': None
                })
                result_layer = result['OUTPUT']
                #QgsProject.instance().addMapLayer(result_layer)
    
                """
                result_layer_1 = processing.run("native:buffer",
                                                {'INPUT': result_layer, 'DISTANCE': -0.05,
                                                 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                                 'DISSOLVE': False,
                                                 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
    
                result_layer = processing.run("native:buffer",
                                              {'INPUT': result_layer_1, 'DISTANCE': 0.05,
                                               'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                               'DISSOLVE': False,
                                               'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                
    
                filtered_layer_1 = processing.run("native:buffer",
                                                  {'INPUT': filtered_layer, 'DISTANCE': -0.05,
                                                   'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                                   'DISSOLVE': False,
                                                   'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
    
                filtered_layer = processing.run("native:buffer",
                                                {'INPUT': filtered_layer_1, 'DISTANCE': 0.05,
                                                 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                                 'DISSOLVE': False,
                                                 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                """
    
                # Pridani atributu SCHEMA a nastaveni hodnoty "B"
                result_layer_provider = result_layer.dataProvider()
                result_layer_provider.addAttributes([QgsField("SCHEMA", QVariant.String)])
                result_layer.updateFields()
    
                result_layer.startEditing()
                for feature in result_layer.getFeatures():
                    feature["SCHEMA"] = "B"
                    result_layer.updateFeature(feature)
                result_layer.commitChanges()
    
                # Slouceni rozdilove vrstvy s filtrovaci vrstvou
                merged_result = processing.run("native:mergevectorlayers", {
                    'LAYERS': [result_layer, filtered_layer],
                    'CRS': QgsCoordinateReferenceSystem('EPSG:5514'),
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })
    
                # Ziskani vysledne sloucene vrstvy
                merged_layer = merged_result['OUTPUT']
                merged_layer.setName("schema")  # Nastaveni nazvu vysledne vrstvy na "schema"
    
                # Rozdeleni vrstvy na singlepart
                singlepart_result = processing.run("native:multiparttosingleparts", {
                    'INPUT': merged_layer,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })
    
                # Ponechani pouze atributu SCHEMA
                final_layer = singlepart_result['OUTPUT']
                final_layer_provider = final_layer.dataProvider()
    
                # Odstraneni vsech atributu krome SCHEMA
                attributes_to_keep = [final_layer.fields().lookupField("SCHEMA")]
                final_layer_provider.deleteAttributes(
                    [i for i in range(final_layer.fields().count()) if i not in attributes_to_keep])
                final_layer.updateFields()
    
                
    
                # Pridani atributu SCELEK_ID a prirazeni stejnych hodnot pro vsechny prvky
                final_layer_provider.addAttributes([QgsField("SCELEK_ID", QVariant.String)])
                final_layer.updateFields()
    
                final_layer.startEditing()
                for feature in final_layer.getFeatures():
                    feature.setAttribute("SCELEK_ID", scelek_id)  # Nastaveni stejneho SCELEK_ID
                    final_layer.updateFeature(feature)
                final_layer.commitChanges()
    
                vymazat_nulove_plochy(final_layer)
    
                # Zmena nazvu vrstvy na "pasy_AB" (zde upraveno dle pozadavku)
                final_layer.setName("pasy_AB")
    
                # Urceni volneho nazvu souboru
                if len(self.dlg.lineEdit_cestalinie.text()) > 0:
                    output_dir = self.dlg.lineEdit_cestalinie.text()
                    output_pasy_dir = output_dir + "\\pasy"
                    if os.path.isdir(output_pasy_dir) == False:
                        os.mkdir(output_pasy_dir)
                    output_filepath_pasy = get_unique_filepath(output_pasy_dir, 'pasy_AB_' + str(sirkapas) + "m_" +  scelek_id)
                    # Ulozeni vrstvy jako shapefile
                    save_layer_as_shapefile(final_layer, output_filepath_pasy)
    
                lyr_pasy_AB = QgsVectorLayer(output_filepath_pasy, "pasy_AB", "ogr")  # final_layer
    
                # Vytvoreni nove vrstvy "pasy_BA" z vrstvy "pasy_AB"
                pasy_ba_layer = create_memory_layer("pasy_BA", "Polygon", lyr_pasy_AB.crs())
                pasy_ba_layer_data = pasy_ba_layer.dataProvider()
                pasy_ba_layer_data.addAttributes(lyr_pasy_AB.fields())
                pasy_ba_layer.updateFields()
    
                # Zameňování hodnot "A" a "B"
                for feature in lyr_pasy_AB.getFeatures():
                    new_feature = QgsFeature(feature)
                    current_schema = feature["SCHEMA"]
                    new_schema = "B" if current_schema == "A" else "A"
                    new_feature.setAttribute("SCHEMA", new_schema)
                    pasy_ba_layer_data.addFeature(new_feature)
    
                pasy_ba_layer.updateExtents()
    
                vymazat_nulove_plochy(pasy_ba_layer)
                # Urceni volneho nazvu souboru pro "pasy_BA"
                output_filepath_pasy_ba = get_unique_filepath(output_pasy_dir, 'pasy_BA_' + str(sirkapas) + "m_" + scelek_id)
    
                # Ulozeni vrstvy jako shapefile
                if len(self.dlg.lineEdit_cestalinie.text()) > 0:
                    save_layer_as_shapefile(pasy_ba_layer, output_filepath_pasy_ba)
    
                pasy_ba_layer = QgsVectorLayer(output_filepath_pasy_ba, "pasy_BA", "ogr")
    
                def symbology_kategorie(lyr, field, unique_values, colors_cat, names_cat):
                    categories = []
                    for unique_value in unique_values:
                        symbol = QgsSymbol.defaultSymbol(lyr.geometryType())
                        layer_style = {}
                        layer_style['color'] = colors_cat[unique_values.index(unique_value)]
                        layer_style['outline'] = '#000000'
                        symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)
                        if symbol_layer is not None:
                            symbol.changeSymbolLayer(0, symbol_layer)
                        category = QgsRendererCategory(unique_value, symbol,
                                                       names_cat[unique_values.index(unique_value)])
                        categories.append(category)
                    renderer = QgsCategorizedSymbolRenderer(field, categories)
                    if renderer is not None:
                        lyr.setRenderer(renderer)
                    lyr.triggerRepaint()
    
                symbology_kategorie(lyr_pasy_AB, "SCHEMA", ["A", "B"], [QColor("#00FF00"), QColor("#0000FF")], ["A", "B"])
                symbology_kategorie(pasy_ba_layer, "SCHEMA", ["A", "B"], [QColor("#00FF00"), QColor("#0000FF")], ["A", "B"])
    
                lyr_pasy_AB.startEditing()
                new_field = QgsField("sirka_pasu", QVariant.Int)
                lyr_pasy_AB.addAttribute(new_field)
                lyr_pasy_AB.updateFields()
                for feat in lyr_pasy_AB.getFeatures():
                    feat["sirka_pasu"] = sirkapas
                    lyr_pasy_AB.updateFeature(feat)
                lyr_pasy_AB.commitChanges()
    
                pasy_ba_layer.startEditing()
                new_field = QgsField("sirka_pasu", QVariant.Int)
                pasy_ba_layer.addAttribute(new_field)
                pasy_ba_layer.updateFields()
                for feat in pasy_ba_layer.getFeatures():
                    feat["sirka_pasu"] = sirkapas
                    pasy_ba_layer.updateFeature(feat)
                pasy_ba_layer.commitChanges()
    
                QgsProject.instance().addMapLayer(lyr_pasy_AB)
                QgsProject.instance().addMapLayer(pasy_ba_layer)
    
                print("Vrstvy byly uspesne vytvoreny.")
            else:
                print("Jedna nebo vice vrstev se nepodarilo nacist.")

        #vykresleni trajektorii nad pasy
        QgsProject.instance().addMapLayer(mrb_orez)
        
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Dodatečné trajektorie (------------------------------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 
        ring_distance = sirkapas  # původní šířka prstence
    
        if self.dlg.checkBox_rozestup1.isChecked() == True:
            vzdalenost_krivek1 = self.dlg.spinBox_rozestup1.value()

            if vzdalenost_krivek1 == sirkapas:
                self.iface.messageBar().pushMessage("Vzdálenosti", "Dodatečné trajektorie se musí lišit od zadané šířky pásu", level=Qgis.MessageLevel.Warning)
            else:
                # Parametry
                zaber_stroje1 = vzdalenost_krivek1  # šířka záběru stroje v metrech
                half_ring1 = (ring_distance / 2) + (zaber_stroje1 / 2)
                 
                # 1. Offset linie
                offset_result = processing.run("native:offsetline", {
                    'INPUT': LayerKlicovaLinie,
                    'DISTANCE': half_ring1,
                    'SEGMENTS': 20,
                    'JOIN_STYLE': 0,
                    'MITER_LIMIT': 2,
                    'OUTPUT': 'memory:'
                })
                okrajova1 = offset_result['OUTPUT']
                #QgsProject.instance().addMapLayer(okrajova1)
                 
                # 2. Multiring buffer kolem offsetované linie
                max_rings1 = (pocetkrivek+3) * (ring_distance/zaber_stroje1) # dostatečný počet prstenců
                multi_buffer_result = processing.run("native:multiringconstantbuffer", {
                    'INPUT': okrajova1,
                    'DISTANCE': zaber_stroje1,
                    'RINGS': max_rings1,
                    'OUTPUT': 'memory:'
                })
                all_rings_layer1 = multi_buffer_result['OUTPUT']
                 
                # 3. Převod polygonů na linie
                polygon_to_line_result1 = processing.run("native:polygonstolines", {
                    'INPUT': all_rings_layer1,
                    'OUTPUT': 'memory:'
                })
                polygon_to_line_layer1 = polygon_to_line_result1['OUTPUT']
                #QgsProject.instance().addMapLayer(polygon_to_line_layer)
                 
                # 4. Sjednocení s offsetovanou křivkou
                merge_lines_result1 = processing.run("native:mergevectorlayers", {
                    'LAYERS': [polygon_to_line_layer1, okrajova1],
                    'CRS': polygon_to_line_layer1.crs(),
                    'OUTPUT': 'memory:'
                })
                mrb_linie_slouceni1 = merge_lines_result1['OUTPUT']
                #QgsProject.instance().addMapLayer(mrb_linie_slouceni1)
                 
                mrb_linie_slouceni1_dissolve = processing.run("native:dissolve", {'INPUT':mrb_linie_slouceni1,
                                                                                  'FIELD':[],
                                                                                  'SEPARATE_DISJOINT':False,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_orez1 = processing.run("native:clip", {'INPUT': mrb_linie_slouceni1_dissolve,
                                                           'OVERLAY': LayerMaskaLinie,
                                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                mrb_orez1 = processing.run("native:mergelines", {'INPUT':mrb_orez1,
                                                                 'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                
    
                mrb_jednodilne1 = processing.run("native:multiparttosingleparts", {
                    'INPUT': mrb_orez1,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne1.selectAll()
                mrb_jednodilne1_4326 = \
                    processing.run("native:saveselectedfeatures", {'INPUT': mrb_jednodilne1, 'OUTPUT': 'memory:'})[
                        'OUTPUT']
                mrb_jednodilne1.removeSelection()
    
                mrb_jednodilne1_4326 = processing.run("native:deleteduplicategeometries",
                                                      {'INPUT': mrb_jednodilne1_4326, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                    "OUTPUT"]
    
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("darkgreen"))
                renderer = QgsSingleSymbolRenderer(symbol)
                mrb_jednodilne1_4326.setRenderer(renderer)
                mrb_jednodilne1_4326.triggerRepaint()
    
                mrb_jednodilne1_4326.setName(str(vzdalenost_krivek1) + "m_trajektorie__" + jmeno_orig_linie)
                QgsProject.instance().addMapLayer(mrb_jednodilne1_4326)
                
                if self.dlg.checkBox_ulozeniGPS.isChecked():
                    output_filepath_trajektorie1 = get_unique_filepath(output_dodatecne_trajektorie_dir, str(vzdalenost_krivek1) + "m_trajektorie_4326_" + scelek_id)
                    reproject_layer_5514_to_4326(mrb_jednodilne1_4326, output_filepath_trajektorie1, self.iface)
                                

        if self.dlg.checkBox_rozestup2.isChecked() == True:
            vzdalenost_krivek2 = self.dlg.spinBox_rozestup2.value()

            if vzdalenost_krivek2 == sirkapas:
                self.iface.messageBar().pushMessage("Vzdálenosti", "Dodatečné trajektorie se musí lišit od zadané šířky pásu", level=Qgis.MessageLevel.Warning)
            else:
                
                # Parametry
                zaber_stroje2 = vzdalenost_krivek2  # šířka záběru stroje v metrech
                half_ring2 = (ring_distance / 2) + (zaber_stroje2 / 2)
                 
                # 1. Offset linie
                offset_result2 = processing.run("native:offsetline", {
                    'INPUT': LayerKlicovaLinie,
                    'DISTANCE': half_ring2,
                    'SEGMENTS': 20,
                    'JOIN_STYLE': 0,
                    'MITER_LIMIT': 2,
                    'OUTPUT': 'memory:'
                })
                okrajova2 = offset_result2['OUTPUT']
                #QgsProject.instance().addMapLayer(okrajova1)
                 
                # 2. Multiring buffer kolem offsetované linie
                max_rings2 = (pocetkrivek+3) * (ring_distance/zaber_stroje2) # dostatečný počet prstenců
                multi_buffer_result2 = processing.run("native:multiringconstantbuffer", {
                    'INPUT': okrajova2,
                    'DISTANCE': zaber_stroje2,
                    'RINGS': max_rings2,
                    'OUTPUT': 'memory:'
                })
                all_rings_layer2 = multi_buffer_result2['OUTPUT']
                 
                # 3. Převod polygonů na linie
                polygon_to_line_result2 = processing.run("native:polygonstolines", {
                    'INPUT': all_rings_layer2,
                    'OUTPUT': 'memory:'
                })
                polygon_to_line_layer2 = polygon_to_line_result2['OUTPUT']
                #QgsProject.instance().addMapLayer(polygon_to_line_layer)
                 
                # 4. Sjednocení s offsetovanou křivkou
                merge_lines_result2 = processing.run("native:mergevectorlayers", {
                    'LAYERS': [polygon_to_line_layer2, okrajova2],
                    'CRS': polygon_to_line_layer2.crs(),
                    'OUTPUT': 'memory:'
                })
                mrb_linie_slouceni2 = merge_lines_result2['OUTPUT']
                
                #přidat dissolve
                mrb_linie_slouceni2_dissolve = processing.run("native:dissolve", {'INPUT':mrb_linie_slouceni2,
                                                                                  'FIELD':[],
                                                                                  'SEPARATE_DISJOINT':False,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_orez2 = processing.run("native:clip", {'INPUT': mrb_linie_slouceni2_dissolve,
                                                           'OVERLAY': LayerMaskaLinie,
                                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                #QgsProject.instance().addMapLayer(mrb_orez2)
                mrb_orez2 = processing.run("native:mergelines", {'INPUT':mrb_orez2,
                                                                 'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne2 = processing.run("native:multiparttosingleparts", {
                    'INPUT': mrb_orez2,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne2.selectAll()
                mrb_jednodilne2_4326 = \
                    processing.run("native:saveselectedfeatures", {'INPUT': mrb_jednodilne2, 'OUTPUT': 'memory:'})[
                        'OUTPUT']
                mrb_jednodilne2.removeSelection()
    
                mrb_jednodilne2_4326 = processing.run("native:deleteduplicategeometries",
                                                      {'INPUT': mrb_jednodilne2_4326, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                    "OUTPUT"]
    
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("darkgreen"))
                renderer = QgsSingleSymbolRenderer(symbol)
                mrb_jednodilne2_4326.setRenderer(renderer)
                mrb_jednodilne2_4326.triggerRepaint()
    
                mrb_jednodilne2_4326.setName(str(vzdalenost_krivek2) + "m_trajektorie__" + jmeno_orig_linie)
                QgsProject.instance().addMapLayer(mrb_jednodilne2_4326)
                
                if self.dlg.checkBox_ulozeniGPS.isChecked():
                    output_filepath_trajektorie2 = get_unique_filepath(output_dodatecne_trajektorie_dir, str(vzdalenost_krivek2) + "m_trajektorie_4326_" + scelek_id)
                    reproject_layer_5514_to_4326(mrb_jednodilne2_4326, output_filepath_trajektorie2, self.iface)

        if self.dlg.checkBox_rozestup3.isChecked() == True:
            vzdalenost_krivek3 = self.dlg.spinBox_rozestup3.value()
            
            if vzdalenost_krivek3 == sirkapas:
                self.iface.messageBar().pushMessage("Vzdálenosti", "Dodatečné trajektorie se musí lišit od zadané šířky pásu", level=Qgis.MessageLevel.Warning)
            else:
                # Parametry
                zaber_stroje3 = vzdalenost_krivek3  # šířka záběru stroje v metrech
                half_ring3 = (ring_distance / 2) + (zaber_stroje3 / 2)
                 
                # 1. Offset linie
                offset_result3 = processing.run("native:offsetline", {
                    'INPUT': LayerKlicovaLinie,
                    'DISTANCE': half_ring3,
                    'SEGMENTS': 20,
                    'JOIN_STYLE': 0,
                    'MITER_LIMIT': 2,
                    'OUTPUT': 'memory:'
                })
                okrajova3 = offset_result3['OUTPUT']
                #QgsProject.instance().addMapLayer(okrajova1)
                 
                # 2. Multiring buffer kolem offsetované linie
                max_rings3 = (pocetkrivek+3) * (ring_distance/zaber_stroje3) # dostatečný počet prstenců
                multi_buffer_result3 = processing.run("native:multiringconstantbuffer", {
                    'INPUT': okrajova3,
                    'DISTANCE': zaber_stroje3,
                    'RINGS': max_rings3,
                    'OUTPUT': 'memory:'
                })
                all_rings_layer3 = multi_buffer_result3['OUTPUT']
                 
                # 3. Převod polygonů na linie
                polygon_to_line_result3 = processing.run("native:polygonstolines", {
                    'INPUT': all_rings_layer3,
                    'OUTPUT': 'memory:'
                })
                polygon_to_line_layer3 = polygon_to_line_result3['OUTPUT']
                #QgsProject.instance().addMapLayer(polygon_to_line_layer)
                 
                # 4. Sjednocení s offsetovanou křivkou
                merge_lines_result3 = processing.run("native:mergevectorlayers", {
                    'LAYERS': [polygon_to_line_layer3, okrajova3],
                    'CRS': polygon_to_line_layer3.crs(),
                    'OUTPUT': 'memory:'
                })
                mrb_linie_slouceni3 = merge_lines_result3['OUTPUT']
                #QgsProject.instance().addMapLayer(mrb_linie_slouceni3)
    
                #přidat dissolve
                mrb_linie_slouceni3_dissolve = processing.run("native:dissolve", {'INPUT':mrb_linie_slouceni3,
                                                                                  'FIELD':[],
                                                                                  'SEPARATE_DISJOINT':False,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_orez3 = processing.run("native:clip", {'INPUT': mrb_linie_slouceni3_dissolve,
                                                           'OVERLAY': LayerMaskaLinie,
                                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                mrb_orez3 = processing.run("native:mergelines", {'INPUT':mrb_orez3,
                                                                 'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne3 = processing.run("native:multiparttosingleparts", {
                    'INPUT': mrb_orez3,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                #QgsProject.instance().addMapLayer(mrb_jednodilne3)
    
                mrb_jednodilne3.selectAll()
                mrb_jednodilne3_4326 = \
                    processing.run("native:saveselectedfeatures", {'INPUT': mrb_jednodilne3, 'OUTPUT': 'memory:'})[
                        'OUTPUT']
                mrb_jednodilne3.removeSelection()
    
                mrb_jednodilne3_4326 = processing.run("native:deleteduplicategeometries",
                                                      {'INPUT': mrb_jednodilne3_4326, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                    "OUTPUT"]
    
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("darkgreen"))
                renderer = QgsSingleSymbolRenderer(symbol)
                mrb_jednodilne3_4326.setRenderer(renderer)
                mrb_jednodilne3_4326.triggerRepaint()
    
                mrb_jednodilne3_4326.setName(str(vzdalenost_krivek3) + "m_trajektorie__" + jmeno_orig_linie)
                QgsProject.instance().addMapLayer(mrb_jednodilne3_4326)
                
                if self.dlg.checkBox_ulozeniGPS.isChecked():
                    output_filepath_trajektorie3 = get_unique_filepath(output_dodatecne_trajektorie_dir, str(vzdalenost_krivek3) + "m_trajektorie_4326_" + scelek_id)
                    reproject_layer_5514_to_4326(mrb_jednodilne3_4326, output_filepath_trajektorie3, self.iface)

        if self.dlg.checkBox_rozestup4.isChecked() == True:
            vzdalenost_krivek4 = self.dlg.spinBox_rozestup4.value()

            if vzdalenost_krivek4 == sirkapas:
                self.iface.messageBar().pushMessage("Vzdálenosti", "Dodatečné trajektorie se musí lišit od zadané šířky pásu", level=Qgis.MessageLevel.Warning)
            else:
                # Parametry
                zaber_stroje4 = vzdalenost_krivek4  # šířka záběru stroje v metrech
                half_ring4 = (ring_distance / 2) + (zaber_stroje4 / 2)
                 
                # 1. Offset linie
                offset_result4 = processing.run("native:offsetline", {
                    'INPUT': LayerKlicovaLinie,
                    'DISTANCE': half_ring4,
                    'SEGMENTS': 20,
                    'JOIN_STYLE': 0,
                    'MITER_LIMIT': 2,
                    'OUTPUT': 'memory:'
                })
                okrajova4 = offset_result4['OUTPUT']
                #QgsProject.instance().addMapLayer(okrajova1)
                 
                # 2. Multiring buffer kolem offsetované linie
                max_rings4 = (pocetkrivek+3) * (ring_distance/zaber_stroje4) # dostatečný počet prstenců
                multi_buffer_result4 = processing.run("native:multiringconstantbuffer", {
                    'INPUT': okrajova4,
                    'DISTANCE': zaber_stroje4,
                    'RINGS': max_rings4,
                    'OUTPUT': 'memory:'
                })
                all_rings_layer4 = multi_buffer_result4['OUTPUT']
                 
                # 3. Převod polygonů na linie
                polygon_to_line_result4 = processing.run("native:polygonstolines", {
                    'INPUT': all_rings_layer4,
                    'OUTPUT': 'memory:'
                })
                polygon_to_line_layer4 = polygon_to_line_result4['OUTPUT']
                #QgsProject.instance().addMapLayer(polygon_to_line_layer)
                 
                # 4. Sjednocení s offsetovanou křivkou
                merge_lines_result4 = processing.run("native:mergevectorlayers", {
                    'LAYERS': [polygon_to_line_layer4, okrajova4],
                    'CRS': polygon_to_line_layer4.crs(),
                    'OUTPUT': 'memory:'
                })
                mrb_linie_slouceni4 = merge_lines_result4['OUTPUT']
    
                
                #přidat dissolve
                mrb_linie_slouceni4_dissolve = processing.run("native:dissolve", {'INPUT':mrb_linie_slouceni4,
                                                                                  'FIELD':[],
                                                                                  'SEPARATE_DISJOINT':False,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_orez4 = processing.run("native:clip", {'INPUT': mrb_linie_slouceni4_dissolve,
                                                           'OVERLAY': LayerMaskaLinie,
                                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                mrb_orez4 = processing.run("native:mergelines", {'INPUT':mrb_orez4,
                                                                 'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne4 = processing.run("native:multiparttosingleparts", {
                    'INPUT': mrb_orez4,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                mrb_jednodilne4.selectAll()
                mrb_jednodilne4_4326 = \
                    processing.run("native:saveselectedfeatures", {'INPUT': mrb_jednodilne4, 'OUTPUT': 'memory:'})[
                        'OUTPUT']
                mrb_jednodilne4.removeSelection()
    
                mrb_jednodilne4_4326 = processing.run("native:deleteduplicategeometries",
                                                      {'INPUT': mrb_jednodilne4_4326, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                    "OUTPUT"]
    
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("darkgreen"))
                renderer = QgsSingleSymbolRenderer(symbol)
                mrb_jednodilne4_4326.setRenderer(renderer)
                mrb_jednodilne4_4326.triggerRepaint()
    
                mrb_jednodilne4_4326.setName(str(vzdalenost_krivek4) + "m_trajektorie__" + jmeno_orig_linie)
                QgsProject.instance().addMapLayer(mrb_jednodilne4_4326)
                
                if self.dlg.checkBox_ulozeniGPS.isChecked():
                    output_filepath_trajektorie4 = get_unique_filepath(output_dodatecne_trajektorie_dir, str(vzdalenost_krivek4) + "m_trajektorie_4326_" + scelek_id)
                    reproject_layer_5514_to_4326(mrb_jednodilne4_4326, output_filepath_trajektorie4, self.iface)

        # QgsProject.instance().addMapLayer(buffer)
        self.dlg.progressBar_vypocet.setFormat("Hotovo")
        self.dlg.progressBar_vypocet.setValue(100)
        """
        with open(f'{self.plugin_dir}/sirkapasu.txt', "w") as soubor:
            soubor.write(str(sirkapas))
        """

        self.nacitani_vrstev_s_textem()

        self.iface.messageBar().pushMessage("Success", "Úspěšně dokončeno", level=Qgis.MessageLevel.Success)

    def vyhlazeni_linii(self):

        pocet_iteraci = self.dlg.spinBox_pocetiteraci.value()
        simplifikace = self.dlg.doubleSpinBox_simplifikace.value()

        selectedLayerHlavniLinie = self.dlg.comboBox_hlavnilinka.currentData()
        problemy_layers = 0

        if problemy_layers == 0:


            if selectedLayerHlavniLinie.featureCount() > 1:
                self.iface.messageBar().pushMessage("Více linií", "Vkládejte pouze jednu linii", level=Qgis.MessageLevel.Critical)
            else:
                selectedLayerHlavniLinie_single = processing.run("native:multiparttosingleparts",
                               {'INPUT': selectedLayerHlavniLinie, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                if selectedLayerHlavniLinie_single.featureCount() > 1:
                    self.iface.messageBar().pushMessage("Multipart", "Vkládejte pouze jednodílné linie",
                                                        level=Qgis.MessageLevel.Critical)

                else:
                    selectedLayerHlavniLinie_single.selectAll()
                    LayerHlavniLinie = processing.run("native:saveselectedfeatures", {'INPUT': \
                                            selectedLayerHlavniLinie_single, 'OUTPUT': 'memory:'})['OUTPUT']
                    selectedLayerHlavniLinie_single.removeSelection()
                    jmeno_hlavnilinie = selectedLayerHlavniLinie.name()
                    

                    self.dlg.progressBar_vypocet.setValue(5)
                    self.dlg.progressBar_vypocet.setFormat("Nacitani")

                    if "fid" in LayerHlavniLinie.fields().names():
                        LayerHlavniLinie.startEditing()
                        field_id = LayerHlavniLinie.fields().indexFromName('fid')
                        LayerHlavniLinie.dataProvider().deleteAttributes([field_id])
                        LayerHlavniLinie.updateFields()
                        LayerHlavniLinie.commitChanges()


                    source_crs = QgsCoordinateReferenceSystem(selectedLayerHlavniLinie.crs().authid())
                    target_crs = QgsCoordinateReferenceSystem("EPSG:5514")
    
                    LayerHlavniLinie.startEditing()
                    for feat in LayerHlavniLinie.getFeatures():
                        geom = feat.geometry()
                        geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))
                        feat.setGeometry(geom)
                        LayerHlavniLinie.updateFeature(feat)
                    LayerHlavniLinie.setCrs(target_crs)
                    LayerHlavniLinie.commitChanges()
                    LayerHlavniLinie.setCrs(target_crs)
                    LayerHlavniLinie.setName("Hlavni_linie_5514")


                    self.dlg.progressBar_vypocet.setValue(15)
                    self.dlg.progressBar_vypocet.setFormat("Vyhlazovani linie")

                    vyhlazeny = processing.run("native:smoothgeometry",
                                               {'INPUT': LayerHlavniLinie, 'ITERATIONS': 10, 'OFFSET': 0.25,
                                                'MAX_ANGLE': 180, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    self.dlg.progressBar_vypocet.setValue(20)
                    self.dlg.progressBar_vypocet.setFormat("Zjednodusovani linie")

                    zjednoduseny = processing.run("native:simplifygeometries",
                                                  {'INPUT': vyhlazeny, 'METHOD': 0, 'TOLERANCE': 0.05,
                                                   'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    self.dlg.progressBar_vypocet.setFormat("Generalizace linie")
                    self.dlg.progressBar_vypocet.setValue(30)

                    _generalize_params = {
                        'input': zjednoduseny, 'type': [0], 'cats': '', 'where': '',
                        'method': 10, 'threshold': 1, 'look_ahead': 7, 'reduction': 50,
                        'slide': 0.5, 'angle_thresh': 3, 'degree_thresh': 0,
                        'closeness_thresh': 0, 'betweeness_thresh': 0, 'alpha': 1,
                        'beta': 1, 'iterations': pocet_iteraci, '-t': False, '-l': True,
                        'output': 'TEMPORARY_OUTPUT', 'error': 'TEMPORARY_OUTPUT',
                        'GRASS_REGION_PARAMETER': None,
                        'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
                        'GRASS_MIN_AREA_PARAMETER': 0.0001,
                        'GRASS_OUTPUT_TYPE_PARAMETER': 0, 'GRASS_VECTOR_DSCO': '',
                        'GRASS_VECTOR_LCO': '',
                        'GRASS_VECTOR_EXPORT_NOCAT': False}
                    linka_generalizovana = _run_processing_algs(
                        ("grass7:v.generalize", "grass:v.generalize"),
                        _generalize_params, "output")

                    self.dlg.progressBar_vypocet.setValue(80)
                    self.dlg.progressBar_vypocet.setFormat("Zjednodusovani linie")

                    zjednoduseny2 = processing.run("native:simplifygeometries",
                                                   {'INPUT': linka_generalizovana, 'METHOD': 0, 'TOLERANCE': simplifikace,
                                                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    self.dlg.progressBar_vypocet.setFormat("Uprava vysledku")
                    self.dlg.progressBar_vypocet.setValue(90)

                    zjednoduseny2.selectAll()
                    zjednoduseny_4326 = \
                        processing.run("native:saveselectedfeatures", {'INPUT': zjednoduseny2, 'OUTPUT': 'memory:'})[
                            'OUTPUT']
                    zjednoduseny2.removeSelection()


                    zjednoduseny_4326.startEditing()
                    field_id = zjednoduseny_4326.fields().indexFromName('fid')
                    zjednoduseny_4326.dataProvider().deleteAttributes([field_id])
                    zjednoduseny_4326.updateFields()
                    zjednoduseny_4326.commitChanges()


                    symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                    symbol.setColor(QColor("black"))
                    renderer = QgsSingleSymbolRenderer(symbol)
                    zjednoduseny_4326.setRenderer(renderer)
                    zjednoduseny_4326.triggerRepaint()

                    zjednoduseny_4326_nazev = "klicova_linie_iter_" + str(pocet_iteraci) + "_" + jmeno_hlavnilinie
                    zjednoduseny_4326.setName(zjednoduseny_4326_nazev)




                    QgsProject.instance().addMapLayer(zjednoduseny_4326)

                    self.dlg.progressBar_vypocet.setFormat("Hotovo")
                    self.dlg.progressBar_vypocet.setValue(100)

                    self.nacitani_vrstev()
                    self.iface.messageBar().pushMessage("Success", "Úspěšně dokončeno", level=Qgis.MessageLevel.Success)

                    
                    




    def vypocet_dostupnosti(self):
        """
        Dodatečná nástroj pro výpočet příčného sklonu
        Bikubická interpolace, může trvat dlouho

        """
        
        # Nastavení CRS projektu na EPSG:5514
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        
        response = QMessageBox.information(None,
                                           "Start",
                                           "Pro výpočet stiskněte OK.\nPozor, tento výpočet může trvat velmi dlouho,\nv závislosti na vykonu PC a velikosti řešené oblasti.",
                                           QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
        if response == QMessageBox.StandardButton.Ok:
            print("výpočet dostupnosti")
            self.vypocet_dostupnosti_process()
        elif response == QMessageBox.StandardButton.Cancel:
            print("Výpočet byl zastaven.")
        
    def vypocet_dostupnosti_process(self):
        rozchod_kol = self.dlg.doubleSpinBox_rozchodkol2.value()
        max_pricny_sklon = self.dlg.doubleSpinBox_maxpricnysklon2.value()

        layers = QgsProject.instance().layerTreeRoot().children()

        selectedLayerDMTName_prep = self.dlg.comboBox_dmt2.currentText()
        selectedLayerDMTName_prep = selectedLayerDMTName_prep.split()
        selectedLayerDMTName = " ".join(selectedLayerDMTName_prep[:-1])
        for i in range(len(layers)):
            if layers[i].name() == selectedLayerDMTName:
                selectedLayerDMTIndex = i
        selectedLayerDMT = layers[selectedLayerDMTIndex].layer()

        # ---------------------------------------------------------------------------------------------------------------
        # priprava vrstvy s trajektorii s crs shodnym s DMT
        selectedLayerTrajektorie = self.dlg.comboBox_trajektorie2.currentData()

        selectedLayerTrajektorie.selectAll()
        LayerTrajektorie = \
            processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerTrajektorie, 'OUTPUT': 'memory:'})[
                'OUTPUT']
        selectedLayerTrajektorie.removeSelection()

        LayerTrajektorie = processing.run("native:reprojectlayer", {'INPUT':LayerTrajektorie,
                                                 'TARGET_CRS':QgsCoordinateReferenceSystem('EPSG:5514'),
                                                 'CONVERT_CURVED_GEOMETRIES':False,
                                                 'OPERATION': operation_4326_to_5514(),
                                                 #'OPERATION':'+proj=pipeline +step +inv +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 +alpha=30.2881397527778 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +step +proj=push +v_3 +step +proj=cart +ellps=bessel +step +proj=helmert +x=589 +y=76 +z=480 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg',
                                                 'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
        LayerTrajektorie.setName("Kopie_traj")
        
        
        """
        source_crs = QgsCoordinateReferenceSystem(LayerTrajektorie.crs().authid())
        target_crs = QgsCoordinateReferenceSystem(selectedLayerDMT.crs().authid())
        LayerTrajektorie.startEditing()
        for feat in LayerTrajektorie.getFeatures():
            geom = feat.geometry()
            geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))
            feat.setGeometry(geom)
            LayerTrajektorie.updateFeature(feat)
        LayerTrajektorie.setCrs(target_crs)
        LayerTrajektorie.commitChanges()
        LayerTrajektorie.setCrs(target_crs)
        LayerTrajektorie.setName("Kopie_traj")
        """
        #QgsProject.instance().addMapLayer(LayerTrajektorie)
        # ---------------------------------------------------------------------------------------------------------------

        # ---------------------------------------------------------------------------------------------------------------

        orez_dmt = selectedLayerDMT

        # ---------------------------------------------------------------------------------------------------------------

        # ---------------------------------------------------------------------------------------------------------------
        # pricne sklony
        segmenty_prep2 = processing.run("native:splitlinesbylength",
                                        {'INPUT': LayerTrajektorie, 'LENGTH': 5,
                                         'OUTPUT': 'TEMPORARY_OUTPUT'})
        segmenty2 = segmenty_prep2['OUTPUT']

        transekt = processing.run("native:transect",
                                  {'INPUT': segmenty2, 'LENGTH': rozchod_kol, 'ANGLE': 90, 'SIDE': 2,
                                   'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
        transekt_se_sklonem = transekt

        def interpolace_vyska(ras, bod):
            xbod = bod.x()
            ybod = bod.y()
            dx = ras.rasterUnitsPerPixelX()
            dy = ras.rasterUnitsPerPixelY()
            xka = [(xbod // dx) * dx + l * dx for l in range(-1, 3)]
            yka = [(ybod // dy) * dy + l * dy for l in range(-1, 3)]
            coords = []
            vals = []
            for xsmer in range(4):
                for ysmer in range(4):
                    bodik = QgsPointXY(xka[xsmer], yka[ysmer])
                    val, res = ras.dataProvider().sample(bodik, 1)
                    coords.append([xka[xsmer], yka[ysmer]])
                    vals.append(val)
            hodnota = griddata(coords, vals, (xbod, ybod), method="cubic")
            return hodnota

        transekt_se_sklonem.startEditing()
        if self.dlg.comboBox_jednotky2.currentText() == "%":
            new_field = QgsField("pricSklon%", QVariant.Double)
        else:
            new_field = QgsField("pricSklon°", QVariant.Double)
        transekt_se_sklonem.addAttribute(new_field)
        transekt_se_sklonem.updateFields()
        new_field = QgsField("pricSklonX", QVariant.String)
        transekt_se_sklonem.addAttribute(new_field)
        transekt_se_sklonem.updateFields()
        for feat in transekt_se_sklonem.getFeatures():
            linka = feat.geometry()
            body = [v for v in linka.vertices()]
            kraj1 = body[0]
            kraj2 = body[-1]
            delka = feat.geometry().length()
            vyska1 = interpolace_vyska(orez_dmt, kraj1)
            vyska2 = interpolace_vyska(orez_dmt, kraj2)
            vyska1 = float(vyska1)
            vyska2 = float(vyska2)
            if self.dlg.comboBox_jednotky2.currentText() == "%":
                pricny_sklon = abs(vyska1 - vyska2) * 100 / delka
                pricny_sklon = round(pricny_sklon, 2)
                feat["pricSklon%"] = pricny_sklon
                if pricny_sklon > max_pricny_sklon:
                    feat["pricSklonX"] = "chyba"
                else:
                    feat["pricSklonX"] = "ok"
                transekt_se_sklonem.updateFeature(feat)
            else:
                pricny_sklon = abs(vyska1 - vyska2) / delka
                pricny_sklon = math.degrees(math.atan(pricny_sklon))
                pricny_sklon = round(pricny_sklon, 2)
                feat["pricSklon°"] = pricny_sklon
                if pricny_sklon > max_pricny_sklon:
                    feat["pricSklonX"] = "chyba"
                else:
                    feat["pricSklonX"] = "ok"
                transekt_se_sklonem.updateFeature(feat)
        transekt_se_sklonem.commitChanges()

        # ---------------------------------------------------------------------------------------------------------------

        categories = []
        colors_cat = ["black", "red"]
        unique_values = ["ok", "chyba"]
        names_cat = ["Ok",
                     "Prekroceno (" + str(round(max_pricny_sklon, 2)) + self.dlg.comboBox_jednotky2.currentText() + ")"]
        for i, value in enumerate(colors_cat):
            symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
            symbol.setColor(QColor(value))
            symbol.setWidth(1.5)
            category = QgsRendererCategory(unique_values[i], symbol, names_cat[i])
            categories.append(category)
        renderer = QgsCategorizedSymbolRenderer('pricSklonX', categories)
        if renderer is not None:
            transekt_se_sklonem.setRenderer(renderer)
        #transekt_se_sklonem.setOpacity(0.5)
        transekt_se_sklonem.triggerRepaint()

        field_names_transekt = transekt_se_sklonem.fields().names()
        rozdil_transekt = []
        for element in field_names_transekt:
            if ((element in ["TR_LENGTH", "pricSklon°", "pricSklon%", "pricSklonX"])) == False:
                rozdil_transekt.append(element)
        transekt_se_sklonem.startEditing()
        fields_to_delete = []
        for fieldname_to_delete in rozdil_transekt:
            fieldindex_to_delete = transekt_se_sklonem.fields().indexFromName(fieldname_to_delete)
            if fieldindex_to_delete == -1:
                continue
            fields_to_delete.append(fieldindex_to_delete)
        transekt_se_sklonem.dataProvider().deleteAttributes(fields_to_delete)
        transekt_se_sklonem.updateFields()
        transekt_se_sklonem.commitChanges()

        jmeno_trajektorie = selectedLayerTrajektorie.name()
        transekt_se_sklonem.setName("Příčný sklon__" + jmeno_trajektorie)

        QgsProject.instance().addMapLayer(transekt_se_sklonem)



    def tisk_reportu(self):
        """
        Kontroly všech podmínek daných metodikou
        Tisk dokumentace
        V případě, že projekt vyhovuje je vytvořen zip Import_psp

        """
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Získání cesty k souboru a výpočtu adresáře (---------------------------------------------------
        # --------------------------------------------------------------------------------------------------------------- 

        navrh_dir = self.dlg.lineEdit_kostraxlsx.text()    
        dir_celek = os.path.dirname(navrh_dir)
        
        # Extrakce ID z názvu adresáře
        id_cele = os.path.basename(dir_celek)
        if "Dokumentace_psp" in id_cele:
            id_cele = id_cele.replace("Dokumentace_psp", "")
        else:
            print("Dokumentace_psp nenalezena")
            
        # Rozdělení ID na jednotlivé části
        idecka = id_cele.split("_")
        dist = idecka[1][:-1]  # Distanc je odvozen z části ID
        id_procesu = idecka[3]
        id_uzivatel = idecka[2]
        
        
             
        # Kontrola existence adresáře pro "psp_vyhovuje"
        dir_psp_vyhovuje = os.path.join(navrh_dir, f"psp_vyhovuje{id_cele}")
        print("dir_psp_vyhovuje: ", dir_psp_vyhovuje)
        
        if os.path.isdir(dir_psp_vyhovuje):
            
            
            testovaci_set_bool = False
            if ((os.path.basename(navrh_dir)).split("_"))[0] == "Test":
                testovaci_set_bool = True
                
            print("testovaci_set_bool:", testovaci_set_bool)
            # Vytvoření adresáře pro dokumentaci projektu
            if testovaci_set_bool:
                dir_dokumentace = os.path.join(dir_celek, f"Test_prjkt_psp{id_cele}", f"Dokumentaceprojektu{id_cele}")
            else:
                dir_dokumentace = os.path.join(dir_celek, f"Projekt_psp{id_cele}", f"Dokumentaceprojektu{id_cele}")
            if not os.path.isdir(dir_dokumentace):
                os.makedirs(dir_dokumentace)
                
            # Vytvoření adresáře pro soubory do navigace
            if testovaci_set_bool:
                dir_navigace = os.path.join(dir_celek, f"Test_prjkt_psp{id_cele}", f"Navigace_epsg4326{id_cele}")
            else:
                dir_navigace = os.path.join(dir_celek, f"Projekt_psp{id_cele}", f"Navigace_epsg4326{id_cele}")
            if not os.path.isdir(dir_navigace):
                os.makedirs(dir_navigace)
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Načítání dat a vrstev (------------------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            
            # Načítání kódů plodin
            plodiny_txt = f'{self.plugin_dir}/kodyplodin_plus.txt'
            plodiny_kody = {}
            try:
                with open(plodiny_txt, "r") as plodiny_soubor:
                    for line in plodiny_soubor.readlines():
                        radek = line.split(", ")
                        cislo = radek[0]
                        text = radek[1]
                        ochrana = radek[2].strip()
                        celed = radek[3].strip()  # Odstraní případné nové řádky
                        plodiny_kody[cislo] = [text, ochrana, celed]
            except FileNotFoundError:
                print(f"Soubor {plodiny_txt} nebyl nalezen.")
                return
            
            # Načítání vrstev (shapefiles)
            lyr_dpb_path = os.path.join(dir_psp_vyhovuje, f"DPB_vyhovuje{id_cele}.shp")
            lyr_dpb = QgsVectorLayer(lyr_dpb_path, "DPB", "ogr")
            
            # Nastavení CRS pro projekt
            EPSG = "5514"
            QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(f"EPSG:{EPSG}"))
            
            
            # Kontrola existence dalších vrstev a jejich načítání
            
            # Maska pro svažitosti nad 3 %
            maska3_bool = False
            lyr_maska3_path = os.path.join(dir_psp_vyhovuje, f"dalsi_vrstvy/Maska3p{id_cele}.shp")
            if os.path.isfile(lyr_maska3_path):
                lyr_maska3 = QgsVectorLayer(lyr_maska3_path, "Maska se svažitosti nad 3 %", "ogr")
                maska3_bool = True
            
            # Načítání trajektorií
            trajektorie_bool = False
            lyr_trajektorie_path = os.path.join(dir_psp_vyhovuje, "trajektorie/trajektorie.shp")
            if os.path.isfile(lyr_trajektorie_path):
                lyr_trajektorie = QgsVectorLayer(lyr_trajektorie_path, "Trajektorie", "ogr")
                trajektorie_bool = True
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Načítání WFS vrstev (--------------------------------------------------------------------------
            # --------------------------------------------------------------------------------------------------------------- 
            chyby_nacteni = 0
            
            dso_bool = False
            extent = lyr_dpb.extent()
            xmin = int(extent.xMinimum()) - 100
            ymin = int(extent.yMinimum()) - 100
            xmax = int(extent.xMaximum()) + 100
            ymax = int(extent.yMaximum()) + 100
            bbox = f"{xmin},{ymin},{xmax},{ymax}"
            print(bbox)
            try:
                uri = "https://iprod.vumop.cz/wfs/dso.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:dso5&bbox=" + bbox
                lyr_dso = QgsVectorLayer(uri, "DSO5ha", "ogr")
                crs = lyr_dso.crs()
                crs.createFromId(5514)
                lyr_dso.setCrs(crs)
                dso_bool = True
            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu DSO 5 ha z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
                chyby_nacteni += 1
                

        
            
            if testovaci_set_bool:
                """lyr_dpb.selectAll()
                dpb_vlayer = processing.run("native:saveselectedfeatures", {'INPUT': lyr_dpb, 'OUTPUT': 'memory:'})['OUTPUT']
                lyr_dpb.removeSelection()"""
                dpb_vlayer = lyr_dpb.materialize(QgsFeatureRequest())
                dpb_vlayer.setName("DPB_účinné")
                dpb_vlayer_bool = True
            else:
                
                try:
                    uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_DPB_UCINNE&bbox=" + bbox
                    dpb_vlayer = QgsVectorLayer(uri, "DPB_účinné", "ogr")
                    crs = dpb_vlayer.crs()
                    crs.createFromId(5514)
                    dpb_vlayer.setCrs(crs)
                    #dpb_vlayer.setName("DPB_účinné")
                    dpb_vlayer_bool = True

                except:
                    self.iface.messageBar().pushMessage("Chybný vstup",
                                                        "Nepovedlo se načíst vrstvu DPB_UCINNE z WFS služby",
                                                        level=Qgis.MessageLevel.Warning)
                    dpb_vlayer_bool = False
                    chyby_nacteni += 1

            neo_bool = False
            try:
                uri = uri = "https://iprod.vumop.cz/wfs/neo.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:neo&bbox=" + bbox
                neo_vlayer = QgsVectorLayer(uri, "NEO", "ogr")
                crs = neo_vlayer.crs()
                crs.createFromId(5514)
                neo_vlayer.setCrs(crs)
                lyr_neo = processing.run("native:fixgeometries",
                               {'INPUT': neo_vlayer, 'METHOD': 1,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                lyr_neo.setName("NEO")
                neo_bool = True

            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu NEO z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
                chyby_nacteni += 1
                
            kp_vlayer_bool = False
            try:
                uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_EVP_UCINNE&bbox=" + bbox
                kp_vlayer0 = QgsVectorLayer(uri, "DPB_wfs", "ogr")
                # WFS/OGR má často neplatné CRS; saveselectedfeatures pak v QGIS 4 vrátí 0 prvků
                kp_vlayer0.setCrs(QgsCoordinateReferenceSystem("EPSG:5514"))
                kp_vlayer = kp_vlayer0.materialize(QgsFeatureRequest())
                
                kp_vlayer.startEditing()
                kp_vlayer_provider = kp_vlayer.dataProvider()
                kp_vlayer_fields = [QgsField("CTVEREC", QVariant.String),
                               QgsField("ZKOD", QVariant.String) ]
                kp_vlayer_provider.addAttributes(kp_vlayer_fields)
                kp_vlayer.updateFields()
                _kp_flds = {n.lower(): n for n in kp_vlayer.fields().names()}
                _src_ctverec = _kp_flds.get("ctverec")
                _src_zkod = _kp_flds.get("zkracenykod")
                for feat in kp_vlayer.getFeatures():
                    if _src_ctverec:
                        feat["CTVEREC"] = feat[_src_ctverec]
                    if _src_zkod:
                        feat["ZKOD"] = feat[_src_zkod]
                    kp_vlayer.updateFeature(feat)
                kp_vlayer.commitChanges()
                # WFS LPIS_EVP_UCINNE občas vrátí totožné polygony vícekrát
                if kp_vlayer.featureCount() > 0:
                    kp_vlayer = processing.run("native:deleteduplicategeometries", {
                        'INPUT': kp_vlayer, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                kp_vlayer.setName("EVP_účinné")
                #QgsProject.instance().addMapLayer(kp_vlayer)
                kp_vlayer_bool = kp_vlayer.featureCount() > 0

            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu LPIS_EVP_UCINNE z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
                chyby_nacteni += 1
                
            if ((dso_bool is True) and (kp_vlayer_bool is True)):
                lyr_dso_bezKP = processing.run("native:difference", {'INPUT':lyr_dso,'OVERLAY':kp_vlayer,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                DSO_pasy = processing.run("native:buffer", {'INPUT':lyr_dso_bezKP,'DISTANCE':7.5,'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            if ((dso_bool is True) and (kp_vlayer_bool is False)):
                DSO_pasy = processing.run("native:buffer", {'INPUT':lyr_dso,'DISTANCE':7.5,'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
  
        
            if chyby_nacteni == 0:
                
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Načítání SHP vrstev (--------------------------------------------------------------------------
                # --------------------------------------------------------------------------------------------------------------- 
                    
                ohrozenost_bool = False
                lyr_ohrozenost_path = os.path.join(dir_psp_vyhovuje,"dalsi_vrstvy", f"ohrozenost_maska_union{id_cele}.shp")
                if os.path.isfile(lyr_ohrozenost_path):
                    lyr_ohrozenost = QgsVectorLayer(lyr_ohrozenost_path, "ohrozenost", "ogr")
                    ohrozenost_bool = True
                    
                ohrozenost_s_bool = False
                lyr_ohrozenost_s_path = os.path.join(dir_psp_vyhovuje,"dalsi_vrstvy", f"ohrozenost_maska_union_s{id_cele}.shp")
                if os.path.isfile(lyr_ohrozenost_s_path):
                    lyr_ohrozenost_s = QgsVectorLayer(lyr_ohrozenost_s_path, "ohrozenost single", "ogr")
                    ohrozenost_s_bool = True
                    
                vrstevnice_bool = False
                lyr_vrstevnice_path = os.path.join(dir_psp_vyhovuje,"dalsi_vrstvy", f"Vrstevnice{id_cele}.shp")
                if os.path.isfile(lyr_vrstevnice_path):
                    lyr_vrstevnice = QgsVectorLayer(lyr_vrstevnice_path, "vrstevnice", "ogr")
                    vrstevnice_bool = True
    
                dir_dokumentace = os.path.dirname(navrh_dir)
                kostra_bool = False
                if testovaci_set_bool:
                    kostra_path = os.path.join(dir_dokumentace,f"Test_prjkt_psp{id_cele}", f"priprava{id_cele}","plan_osevu_psp.shp")
                else:
                    kostra_path = os.path.join(dir_dokumentace,f"Projekt_psp{id_cele}", f"priprava{id_cele}","plan_osevu_psp.shp")
                if os.path.isfile(kostra_path): 
                    lyr_kostra = QgsVectorLayer(kostra_path, "Plodiny", "ogr")
                    kostra_bool = True
    
    
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Příprava vrstev pro celý projekt (-------------------------------------------------------------
                # ---------------------------------------------------------------------------------------------------------------       
                
                #vytvoření vrstev podle DPB ok a neok
                DPB_vyhovujici = QgsVectorLayer("Polygon?crs=EPSG:5514", "DPB_vyhovuje", "memory")
                DPB_nevyhovujici = QgsVectorLayer("Polygon?crs=EPSG:5514", "DPB_nevyhovuje", "memory")
                
                
                navigace_osev_all = QgsVectorLayer("Polygon?crs=EPSG:5514", "navigace_osev_all", "memory")
                fields = lyr_kostra.fields()
                navigace_osev_all_provider = navigace_osev_all.dataProvider()
                navigace_osev_all_provider.addAttributes(fields)  # Přidáme atributy
                navigace_osev_all.updateFields()    
                
                navigace_spojpasy_all = QgsVectorLayer("Polygon?crs=EPSG:5514", "navigace_spojpasy_all", "memory")
                navigace_bezzasah_all = QgsVectorLayer("Polygon?crs=EPSG:5514", "navigace_bezzasah_all", "memory")
                navigace_trajektorie_all = QgsVectorLayer("LineString?crs=EPSG:5514", "navigace_trajektorie_all", "memory")
            
                seznam_pdf = []
                merger = PdfWriter()
                
                
                #čítač pro pdf podle DPB
                N = 0
    
                for feat_dpb in lyr_dpb.getFeatures():
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Příprava layoutu pro tisk (--------------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------    
    
                    projekt = QgsProject.instance()
                    manager = projekt.layoutManager()
                    
                    # Vytvoření názvu pro nový layout s aktuálním datem
                    layoutName = "PSP_layout_tisk_" + strftime('%Y_%m_%d', localtime(time.time()))
                    layouts_list = manager.printLayouts()
                    
                    # Odstranění existujícího layoutu se stejným názvem
                    for lt in layouts_list:
                        if lt.name() == layoutName:
                            manager.removeLayout(lt)
    
                    # Vytvoření nového layoutu a přidání stránek
                    layout_psp = QgsPrintLayout(projekt)
                    layout_psp.initializeDefaults()
                    layout_psp.setName(layoutName)
                    manager.addLayout(layout_psp)
                    
                    
                    
                    #vyska a sirka dpb pro velikost jednotlivych obrazku v pdf
                    sirka_pdf = feat_dpb.geometry().boundingBox().xMaximum() - feat_dpb.geometry().boundingBox().xMinimum()
                    vyska_pdf = feat_dpb.geometry().boundingBox().yMaximum() - feat_dpb.geometry().boundingBox().yMinimum()
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Tvorba vrstvy z prvku DPB (--------------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------    
                     
                    #DPB -> převedení feature na vrstvu
                    lyr_dpb.select(feat_dpb.id())
                    lyr_dpb_i = processing.run("native:saveselectedfeatures", {'INPUT': lyr_dpb, 'OUTPUT': 'memory:'})[
                        'OUTPUT']
                    lyr_dpb.removeSelection()
    
                    # Nastavení symbolu pro vrstvu DPB
                    lyr_dpb_i.setName("DPB")
                    
                    sym = lyr_dpb_i.renderer().symbol()
                    syms = sym[0]
                    syms.setColor(QColor.fromRgb(222, 226, 194))
                    syms.setStrokeColor(QColor("transparent"))
                    lyr_dpb_i.triggerRepaint()      
                    
                    # ---------------------------------------------------------------------------------------------------------------    
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Tvorba kostra_i a plochy podle PLOD_ID + jedinečnost id_zakresu (------------------------------
                    # ---------------------------------------------------------------------------------------------------------------    
                    
                    kostra_i_bool = False
                    if kostra_bool:
                        lyr_kostra_i = processing.run("native:clip", {
                            'INPUT': lyr_kostra,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if lyr_kostra_i.featureCount() > 0:
                            lyr_kostra_i.setName("Plán osevu")
                            kostra_i_bool = True
                        
                    if kostra_i_bool:
                        # Nalezení unikátních hodnot pro PLOD_ID
                        idx = lyr_kostra_i.fields().indexOf('PLOD_ID')
                        unique_values = list(lyr_kostra_i.uniqueValues(idx))
                        
                        # Slovník obsahující ID plodiny a jejich plochy
                        plochy_plodiny = {}
                        vymera_plan_osevu = 0
                        for plodina in unique_values:
                            plochy_plodiny[plodina] = 0
                        for feat_plodiny in lyr_kostra_i.getFeatures():
                            plodina = feat_plodiny['PLOD_ID']
                            plochy_plodiny[plodina] += feat_plodiny.geometry().area() / 10000 # Převod na hektary
        
                        # Sčítání plochy plodin
                        for value in plochy_plodiny.values():
                            vymera_plan_osevu += round(value,4)
                        
                        # Nastavení kategorií pro symbologii na základě plodiny a její plochy
                        #symbology - do textu se přiřadí plochy plodin s jejich názvy
                        #taky se řeší zda jsou PLOD_ID v seznamu plodin
    
                        plody_v_seznamu = True
                        names_cat_dict = {}
                        for plod in unique_values:
                            
                            if plod in list(plodiny_kody.keys()):
                                if plodiny_kody[plod][1] == "NOF":
                                    text = f"{plod} - {plodiny_kody[plod][0]} - {plodiny_kody[plod][2]} - {plochy_plodiny[plod]:.4f} ha - nízká ochranná funkce"
                                else:
                                    text = f"{plod} - {plodiny_kody[plod][0]} - {plodiny_kody[plod][2]} - {plochy_plodiny[plod]:.4f} ha"
                                
                            elif plod == NULL:
                                text = "Není vyplněno"
                                plody_v_seznamu = False
                            else:
                                text = f"{plod} - PLOD_ID není v seznamu - {plochy_plodiny[plod]:.4f} ha"
                                plody_v_seznamu = False
                            names_cat_dict[plod] = text
                           
                        unikatni_hodnoty = []
                        
                        def prevedeni_list2list(uv_old, uv_new, val):
                            if val in unique_values:
                                uv_new.append(val)
                                uv_old.remove(val)
                        
                        prevedeni_list2list(unique_values, unikatni_hodnoty, "471")
                        prevedeni_list2list(unique_values, unikatni_hodnoty, "50082")
                        prevedeni_list2list(unique_values, unikatni_hodnoty, "459")
                        prevedeni_list2list(unique_values, unikatni_hodnoty, "460")
                        prevedeni_list2list(unique_values, unikatni_hodnoty, "50018")
                        
                        list_ne_nof = []
                        list_nof = []
                        for plod in unique_values:
                            if plodiny_kody[plod][1] == "NOF":
                                list_nof.append(plod)
                            else:
                                list_ne_nof.append(plod)
                                       
                        for plod in list_ne_nof:
                            unikatni_hodnoty.append(plod)
                        for plod in list_nof:
                            unikatni_hodnoty.append(plod)
                        
                        categories = []
                        for value in unikatni_hodnoty:
                            symbol = QgsSymbol.defaultSymbol(lyr_kostra_i.geometryType())
                            #category = QgsRendererCategory(value, symbol, names_cat[unique_values.index(value)])
                            category = QgsRendererCategory(value, symbol, names_cat_dict[value])
                            categories.append(category)
                            
                        renderer = QgsCategorizedSymbolRenderer('PLOD_ID', categories)
                        renderer.updateColorRamp(QgsRandomColorRamp())
                        lyr_kostra_i.setRenderer(renderer)
                        lyr_kostra_i.triggerRepaint()
                        
                        
                        
                        if plody_v_seznamu:
                            podminka_plody_seznam = "SPLNĚNO"
                        else:
                            podminka_plody_seznam = "NESPLNĚNO"
                        
                        
                        # Kontrola jedinečnosti ZAKRES_ID a porovnání plochy DPB
                        #kontrola, zda ZP obsahují unikátní hodnoty pro ZAKRES_ID a zda plocha ZP se rovnají ploše DPB  
                        zakresy_id = []
                        plocha_kostra_m = 0
                        for feat in lyr_kostra_i.getFeatures():
                            zakresy_id.append(feat["ZAKRES_ID"])
                            plocha_kostra_m += feat.geometry().area()
                            
                        zakresy_id_unique = list(set(zakresy_id))
                        podminka_jedinecnost = "NESPLNĚNO"
                        if len(zakresy_id) == len(zakresy_id_unique):
                            podminka_jedinecnost = "SPLNĚNO"
                        # podmínka pro NULL v id_zakresu
                        if NULL in zakresy_id_unique:
                            podminka_jedinecnost = "NESPLNĚNO"
                        
                        podminka_plochy_parcel = "NESPLNĚNO"
                        if ((plocha_kostra_m/feat_dpb.geometry().area() < 1.0001) and ((plocha_kostra_m/feat_dpb.geometry().area() > 0.9999))):
                            podminka_plochy_parcel = "SPLNĚNO"
                    
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Tvorba StP_i (NP) a AEnvi a kontrola plochy (--------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------      
                        
                    np_i_bool = False
                    if kostra_i_bool:
                        #STP vytvořeno z planu osevu
                        lyr_np_i = processing.run("native:extractbyattribute", {'INPUT':lyr_kostra_i,
                                                                                'FIELD':'PLOD_ID',
                                                                                'OPERATOR':0,'VALUE':'471',
                                                                                'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if lyr_np_i.featureCount() > 0:
                            
                            lyr_np_i = processing.run("native:dissolve", {'INPUT':lyr_np_i, 
                                                                          'FIELD':[],
                                                                          'SEPARATE_DISJOINT':False,
                                                                          'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            lyr_np_i_plus = processing.run("native:buffer", {'INPUT': lyr_np_i,
                                                             'DISTANCE':0.001,
                                                             'SEGMENTS':5,
                                                             'END_CAP_STYLE':1,
                                                             'JOIN_STYLE':1,
                                                             'MITER_LIMIT':2,
                                                             'DISSOLVE':False,
                                                             'SEPARATE_DISJOINT':False,
                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            lyr_np_i = processing.run("native:buffer", {'INPUT': lyr_np_i_plus,
                                                             'DISTANCE':-0.001,
                                                             'SEGMENTS':5,
                                                             'END_CAP_STYLE':1,
                                                             'JOIN_STYLE':1,
                                                             'MITER_LIMIT':2,
                                                             'DISSOLVE':False,
                                                             'SEPARATE_DISJOINT':False,
                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            
                            lyr_np_i.setName("Bezzásahové části\nstabilizačních ploch")
                            
                            # Nastavení barvy symbolu pro STP
                            sym = lyr_np_i.renderer().symbol()
                            syms = sym[0]
                            syms.setColor(QColor("#7df1de"))
                            syms.setStrokeColor(QColor("transparent"))
                            lyr_np_i.triggerRepaint()
                            np_i_bool = True
                    
                    
                    aenvi_i_bool = False
                    if kostra_i_bool:
                        # Definujeme hodnoty, které chceme extrahovat
                        target_values = ["459", "460", "50018"]
                        # Vytvoříme nový prázdný seznam pro extrahované prvky
                        extracted_features = []
                        # Procházíme všechny objekty ve vrstvě
                        for feature in lyr_kostra_i.getFeatures():
                            if feature['PLOD_ID'] in target_values:
                                extracted_features.append(feature)
                        
                        # Pokud byly nalezeny nějaké odpovídající prvky
                        if extracted_features:
                            # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                            lyr_aenvi_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                        
                            # Kopírujeme pole z původní vrstvy do nové
                            new_fields = lyr_kostra_i.fields()
                            lyr_aenvi_i.dataProvider().addAttributes(new_fields)
                            lyr_aenvi_i.updateFields()
                        
                            # Přidáme extrahované prvky do nové vrstvy
                            lyr_aenvi_i.startEditing()
                            lyr_aenvi_i.dataProvider().addFeatures(extracted_features)
                            lyr_aenvi_i.commitChanges()   
                            lyr_aenvi_i.setName("Agroenviromentální\nplochy")
                            
                            # Nastavení barvy symbolu pro STP
                            sym = lyr_aenvi_i.renderer().symbol()
                            syms = sym[0]
                            syms.setColor(QColor("#7df1de")) #!!!! barvu
                            syms.setStrokeColor(QColor("transparent"))
                            lyr_aenvi_i.triggerRepaint()
                            aenvi_i_bool = True
                            
                            
                    stp_s_aenvi_i_bool = False
                    if kostra_i_bool:
                        # Definujeme hodnoty, které chceme extrahovat
                        target_values = ["471", "459", "460", "50018"]
                        # Vytvoříme nový prázdný seznam pro extrahované prvky
                        extracted_features = []
                        # Procházíme všechny objekty ve vrstvě
                        for feature in lyr_kostra_i.getFeatures():
                            if feature['PLOD_ID'] in target_values:
                                extracted_features.append(feature)
                        
                        # Pokud byly nalezeny nějaké odpovídající prvky
                        if extracted_features:
                            # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                            lyr_stp_s_aenvi_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                        
                            # Kopírujeme pole z původní vrstvy do nové
                            new_fields = lyr_kostra_i.fields()
                            lyr_stp_s_aenvi_i.dataProvider().addAttributes(new_fields)
                            lyr_stp_s_aenvi_i.updateFields()
                        
                            # Přidáme extrahované prvky do nové vrstvy
                            lyr_stp_s_aenvi_i.startEditing()
                            lyr_stp_s_aenvi_i.dataProvider().addFeatures(extracted_features)
                            lyr_stp_s_aenvi_i.commitChanges()    
                            
                            lyr_stp_s_aenvi_i = processing.run("native:dissolve", {'INPUT':lyr_stp_s_aenvi_i, 
                                                                          'FIELD':[],
                                                                          'SEPARATE_DISJOINT':False,
                                                                          'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            lyr_stp_s_aenvi_i_plus = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i,
                                                             'DISTANCE':0.001,
                                                             'SEGMENTS':5,
                                                             'END_CAP_STYLE':1,
                                                             'JOIN_STYLE':1,
                                                             'MITER_LIMIT':2,
                                                             'DISSOLVE':False,
                                                             'SEPARATE_DISJOINT':False,
                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            lyr_stp_s_aenvi_i = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i_plus,
                                                             'DISTANCE':-0.001,
                                                             'SEGMENTS':5,
                                                             'END_CAP_STYLE':1,
                                                             'JOIN_STYLE':1,
                                                             'MITER_LIMIT':2,
                                                             'DISSOLVE':False,
                                                             'SEPARATE_DISJOINT':False,
                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            stp_s_aenvi_i_bool = True
                            #QgsProject.instance().addMapLayer(lyr_stp_s_aenvi_i)
    
                        
                    #kontrola plochy STP (5-30 % z DPB) včetně aenvi
                    area_np_s_ae = 0
                    
                    if stp_s_aenvi_i_bool:
                        for feat in lyr_stp_s_aenvi_i.getFeatures():
                            area_np_s_ae += feat.geometry().area() 
                    
                    """
                    if np_i_bool:
                        for feat in lyr_np_i.getFeatures():
                            area_np_s_ae += feat.geometry().area() 
                    if aenvi_i_bool:
                        for feat in lyr_aenvi_i.getFeatures():
                            area_np_s_ae += feat.geometry().area()  
                    """
                            
                    if ((area_np_s_ae/feat_dpb.geometry().area() > 0.05) and (area_np_s_ae/feat_dpb.geometry().area() < 0.3)):
                        podminka_plocha_np = "SPLNĚNO"
                    else:
                        podminka_plocha_np = "NESPLNĚNO"
                        
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Tvorba masky3p a inverzni plochy (-------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------   
               
                    #tvorba masky3p (maska sklonitost nad 3%)
                    maska3_i_bool = False
                    if maska3_bool:
                        lyr_maska3_i = processing.run("native:clip", {
                            'INPUT': lyr_maska3,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if lyr_maska3_i.featureCount() > 0:
                            lyr_maska3_i.setName("Sklonitost nad 3 %")
                            maska3_i_bool = True
                    
                    
                    # Inverze masky sklonu, aby zobrazila oblasti s rovinkou (plocha, která nebude řešena v následujících krocích)
                    if maska3_i_bool:
                        lyr_maska3_invert_i = processing.run("native:difference", {'INPUT': lyr_dpb_i,'OVERLAY':lyr_maska3_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"] 
                        # Nastavení barvy pro inverzní masku (pro rovinné oblasti)
                        #lyr_maska3_invert_i.renderer().symbol().setColor(QColor.fromRgb(218, 207, 86))
                        sym = lyr_maska3_invert_i.renderer().symbol()
                        syms = sym[0]
                        syms.setColor(QColor.fromRgb(218, 207, 86))
                        syms.setStrokeColor(QColor("transparent"))
                        lyr_maska3_invert_i.triggerRepaint()
                    
                    
                    # Výpočet celkové plochy masky 3p (masky pro sklon) a její inverzní verze (rovinné oblasti)
                    lyr_maska3_area = 0
                    if maska3_i_bool:
                        for feat in lyr_maska3_i.getFeatures():
                            lyr_maska3_area += feat.geometry().area()
                        
                    lyr_maska3_invert_area = 0
                    if maska3_i_bool:
                        if lyr_maska3_invert_i.featureCount() > 0:
                            for feat in lyr_maska3_invert_i.getFeatures():
                                lyr_maska3_invert_area += feat.geometry().area()
                    
                    # Kontrola, zda inverzní maska (rovinné oblasti) pokrývá více než 25 % celkové plochy DPB, letos neřešeno
                    if (lyr_maska3_invert_area/(feat_dpb.geometry().area())) > 0.25:
                        podminka_maska3_area = "NESPLNĚNO"
                    else:
                        podminka_maska3_area = "SPLNĚNO"
                        
                    # Nastavení názvu vrstvy, která ukazuje procento plochy s rovinkou (sklon pod 3%)
                    if maska3_i_bool:
                        lyr_maska3_invert_i.setName(f"Sklonitost pod 3 %\n{(100*(lyr_maska3_invert_area/(feat_dpb.geometry().area()))):.1f} % z DPB")
                    
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Vytváření vrstvy ukazující oblasti, kde je překročen podélný sklon (---------------------------
                    # ---------------------------------------------------------------------------------------------------------------  
                    
                    # Oříznutí vrstvy ohroženosti ('lyr_ohrozenost') podle hranice DPB ('lyr_dpb_i')
                    limit30_i_bool = False
                    if ohrozenost_bool:
                        lyr_ohrozenost_i = processing.run("native:clip", {
                            'INPUT': lyr_ohrozenost,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        # Extrakce oblastí, kde je sklon překročen (hodnota '1' v poli 'result_2')
                        plosky_prekroceno = processing.run("native:extractbyattribute", {
                            'INPUT': lyr_ohrozenost_i,
                            'FIELD': 'result_2', 'OPERATOR': 0, 'VALUE': '1', 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        
                        # Sloučení překročených oblastí do jedné vrstvy (sloučení překrývajících se oblastí)
                        plosky_prekroceno_diss = processing.run("native:dissolve",
                                                                {'INPUT': plosky_prekroceno, 'FIELD': ['result_2'],
                                                                 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        
                        #QgsProject.instance().addMapLayer(plosky_prekroceno_diss)
        
                        # Vytvoření 0,2 metrové buffer zóny kolem sloučených oblastí
                        buffer5 = processing.run("native:buffer", {
                            'INPUT': plosky_prekroceno_diss,
                            'DISTANCE': 0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                            'DISSOLVE': False,
                            'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                        # Zúžení bufferu o 0,2 metru pro finální hranice
                        buffer6 = processing.run("native:buffer", {
                            'INPUT': buffer5,
                            'DISTANCE': -0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                            'DISSOLVE': False,
                            'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                        buffer6 = processing.run("native:fixgeometries", {
                            'INPUT': buffer6,
                            'METHOD': 1, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                        
                        #QgsProject.instance().addMapLayer(buffer6)
                        
                        # Intersekce výsledného bufferu s maskou 3% sklonu pro nalezení překrytí
                        lyr_limit30_i = processing.run("native:multiintersection", {
                            'INPUT': buffer6,
                            'OVERLAYS': [lyr_maska3_i],
                            'OVERLAY_FIELDS_PREFIX': '', 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                        if lyr_limit30_i.featureCount() > 0:
                            limit30_i_bool = True
                            
                        #odečtení KP
                        if ((lyr_limit30_i.featureCount() > 0) and (kp_vlayer_bool == True)):
                            lyr_limit30_i = processing.run("native:difference", {'INPUT':lyr_limit30_i,
                                                                                 'OVERLAY':kp_vlayer,
                                                                                 'OUTPUT':'TEMPORARY_OUTPUT',
                                                                                 'GRID_SIZE':None})["OUTPUT"]
                            #smazaní odřezků
                            lyr_limit30_i.startEditing()
                            for feat in lyr_limit30_i.getFeatures():
                                if feat.geometry().area() < 1:
                                    lyr_limit30_i.deleteFeature(feat.id())
                            lyr_limit30_i.commitChanges()
                            
                            if lyr_limit30_i.featureCount() > 0:
                                limit30_i_bool = True
                            else:
                                limit30_i_bool = False
    
                    # ---- Úprava masky odstraněním nežádoucích oblastí ----
                    # Odstranění oblastí z vrstvy DPB, které jsou v oblasti NP ('lyr_np_i')
                    lyr_dpb_i.selectAll()
                    upravena_maska =  processing.run("native:saveselectedfeatures", {'INPUT': lyr_dpb_i, 'OUTPUT': 'memory:'})['OUTPUT']
                    lyr_dpb_i.removeSelection()
                    if np_i_bool:
                        upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                          'OVERLAY': lyr_np_i,
                                                                          'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                          'GRID_SIZE': None})['OUTPUT']
                    if kp_vlayer_bool:
                        upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                              'OVERLAY': kp_vlayer,
                                                                              'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                              'GRID_SIZE': None})['OUTPUT']
                        
                    if aenvi_i_bool:
                        upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                              'OVERLAY': lyr_aenvi_i,
                                                                              'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                              'GRID_SIZE': None})['OUTPUT']
                    
                    # Odstranění malých prvků (méně než 1 m²) z upravené masky
                    upravena_maska.startEditing()
                    for feat in upravena_maska.getFeatures():
                        if feat.geometry().area() < 1:
                            upravena_maska.deleteFeature(feat.id())
                    upravena_maska.commitChanges()
    
                    # Vytvoření malého zúžení bufferu pro finální hranice
                    upravena_maska_minus = processing.run("native:buffer", {
                        'INPUT': upravena_maska,
                        'DISTANCE': -0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
    
                    # Opětovné zvětšení bufferu o 0,1 metru pro vrácení do požadovaných hranic
                    upravena_maska = processing.run("native:buffer", {
                        'INPUT': upravena_maska_minus,
                        'DISTANCE': 0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    
                    # ---- Finální kontrola oblastí, kde je překročen podélný sklon ----
                    if limit30_i_bool:  
                        # Oříznutí vrstvy 'lyr_limit30_i' (oblasti s překročeným sklonem) podle upravené masky
                        lyr_limit30_i = processing.run("native:clip", {
                            'INPUT': lyr_limit30_i,
                            'OVERLAY': upravena_maska,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        # Odstranění malých prvků z oříznuté vrstvy
                        lyr_limit30_i.startEditing()
                        for feat in lyr_limit30_i.getFeatures():
                            if feat.geometry().area() < 1:
                                lyr_limit30_i.deleteFeature(feat.id())
                        lyr_limit30_i.commitChanges()
                        
                        # Přidání nového pole 'P_SKL(%)', které ukazuje procento plochy masky 3% sklonu, které obsahuje překročení sklonu
                        lyr_limit30_i.startEditing()
                        new_fields = [QgsField("P_SKL(%)", QVariant.Double)]
                        lyr_limit30_i.dataProvider().addAttributes(new_fields)
                        lyr_limit30_i.updateFields()
                        
                        # Výpočet procenta pro každý prvek a aktualizace atributu
                        for feat in lyr_limit30_i.getFeatures():
                            plocha_limit30 = feat.geometry().area()
                            podminka_limit30 = "NESPLNĚNO"
                            if (100 * plocha_limit30 / lyr_maska3_area) <= 30:     
                                podminka_limit30 = "SPLNĚNO"
                            limit30_procenta = round(100 * plocha_limit30 / lyr_maska3_area, 1)
                            feat["P_SKL(%)"] = limit30_procenta
                            lyr_limit30_i.updateFeature(feat)
                        lyr_limit30_i.commitChanges()
                        
                        # Nastavení názvu vrstvy a její zbarvení na zeleno pro zobrazení oblastí s překročeným sklonem
                        lyr_limit30_i.setName(f"Překročený podélný\nsklon\n{(100 * plocha_limit30 / lyr_maska3_area):.1f} %")
                        
                        sym = lyr_limit30_i.renderer().symbol()
                        syms = sym[0]
                        syms.setColor(QColor.fromRgb(22, 229, 47))
                        syms.setStrokeColor(QColor("transparent"))
                        
                        #lyr_limit30_i.renderer().symbol().setColor(QColor.fromRgb(22, 229, 47))
                        lyr_limit30_i.triggerRepaint()
                    else:
                        podminka_limit30 = "SPLNĚNO"
                        
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Řešení ZEOP (Značně Erozí ohrožené plochy) (---------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------  
    
                    zeop_all_procenta = 0
                    podminka_zeop = "SPLNĚNO"
                    zeop_i_bool = False
                    
                    # Kontrola, zda je vrstva ohroženosti dostupná
                    if ohrozenost_s_bool:
                        # Extrakce ploch, které mají hodnotu '2' v poli 'podelny_sk' (ohrožené plochy)
                        zeop_prep = processing.run("native:extractbyattribute", {
                            'INPUT': lyr_ohrozenost_s, 'FIELD': 'podelny_sk', 'OPERATOR': 0,
                            'VALUE': '2',
                            'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                        
                        zeop_prep = processing.run("native:clip", {
                            'INPUT': zeop_prep,
                            'OVERLAY': upravena_maska,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        
                        # Pokud byly nalezeny plochy
                        if zeop_prep.featureCount() > 0:
                            # Sloučení těchto ploch do jedné
                            zeop_prep2 = processing.run("native:dissolve",
                                                       {'INPUT': zeop_prep, 'FIELD': [],
                                                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                            
                            
                            # Odstranění oblastí překrývajících se s STP (zeop_prep3)
                            if stp_s_aenvi_i_bool:        
                                zeop_prep2 = processing.run("native:difference", {'INPUT': zeop_prep2,
                                                                                  'OVERLAY': lyr_stp_s_aenvi_i,
                                                                                  'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                                  'GRID_SIZE': None})['OUTPUT']
                            
                            
                            # Rozdělení více části na jednotlivé části
                            zeop = processing.run("native:multiparttosingleparts", {'INPUT':zeop_prep2,   
                                                                                    'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            zeop = processing.run("native:fieldcalculator", {'INPUT':zeop,
                                                                             'FIELD_NAME':'plocha',
                                                                             'FIELD_TYPE':0,
                                                                             'FIELD_LENGTH':10,
                                                                             'FIELD_PRECISION':2,
                                                                             'FORMULA':' $area '
                                                                             ,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            zeop = processing.run("native:extractbyattribute", {'INPUT':zeop,
                                                                                'FIELD':'plocha',
                                                                                'OPERATOR':2,
                                                                                'VALUE':'10000',
                                                                                'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
    
                            # Odstranění malých ploch (méně než 1 m²)
                            zeop.startEditing()
                            for feat in zeop.getFeatures():
                                if feat.geometry().area() < 1:
                                    zeop.deleteFeature(feat.id())
                            zeop.commitChanges()
                            
                            if zeop.featureCount() > 0:
                                # Nastavení flagu a výchozích podmínek pro ZEOP
                                zeop_i_bool = True
                                podminka_zeop = "NESPLNĚNO"
                                zeop_all_area = 0
                                zeop_all_procenta = 0
                                pocet_zeop_nad2ha = 0
                                
                                # Přidání nových polí pro výpočty a aktualizace atributů
                                zeop.startEditing()
                                new_fields = [QgsField("ZEOP(%)", QVariant.Double),
                                              QgsField("VYMZEOP", QVariant.Double, len=10, prec=4),
                                              QgsField("ZEOPstav", QVariant.String)
                                              ]
                                zeop.dataProvider().addAttributes(new_fields)
                                zeop.updateFields()
                                
                                # Výpočty pro každou plochu ZEOP
                                for feat in zeop.getFeatures():
                                    plocha_zeop = feat.geometry().area()
                                    zeop_all_area = zeop_all_area + plocha_zeop
                                    zeop_procenta = 100 * plocha_zeop / lyr_maska3_area
                                    zeop_all_procenta = zeop_all_procenta + zeop_procenta
                                    feat["ZEOP(%)"] = round(zeop_procenta,1)
                                    feat["VYMZEOP"] = round(plocha_zeop/10000, 4)
                                    
                                    # Určení vyhodnocení plochy podle velikosti
                                    if ((zeop_procenta <= 10) and (plocha_zeop <= 20000)):
                                        feat["ZEOPstav"] = "OK"
                                    else:
                                        feat["ZEOPstav"] = "překračuje limity"
                                        pocet_zeop_nad2ha = pocet_zeop_nad2ha + 1
                                    zeop.updateFeature(feat)
                                zeop.commitChanges()
                                
                                # Nastavení názvu vrstvy ZEOP a barvy podle procenta plochy
                                zeop.setName(f"Značně erozně\nohrožené plochy\ncelkem {zeop_all_procenta:.1f} %")
                                if (((100 * zeop_all_area / lyr_maska3_area) <= 10) and (pocet_zeop_nad2ha == 0)):   
                                    podminka_zeop = "SPLNĚNO"
                                
                                # Nastavení rendereru pro různé kategorie stavu ZEOP
                                categories = []
                                colors_cat = ["#9270d2", "#db7b90"]
                                unique_values = ["OK", "překračuje limity"]
                                names_cat = ["ZEOP\ndo 2 ha", "ZEOP\nnad 2 ha"]
                                for i, value in enumerate(colors_cat):
                                    symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.PolygonGeometry)
                                    symbol.setColor(QColor(value))
                                    category = QgsRendererCategory(unique_values[i], symbol, names_cat[i])
                                    categories.append(category)
                                renderer = QgsCategorizedSymbolRenderer('ZEOPstav', categories)
                                if renderer is not None:
                                    zeop.setRenderer(renderer)
                                zeop.triggerRepaint()
                            
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Oříznutí vrstevnic a trajektorií podle dpb (---------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------  
                    
                    #oříznutí vrstevnic podle dpb
                    vrstevnice_i_bool = False
                    if vrstevnice_bool:
                        lyr_vrstevnice_i = processing.run("native:clip", {
                            'INPUT': lyr_vrstevnice,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        lyr_vrstevnice_i.setName("Vrstevnice (2 m)")
                        if lyr_vrstevnice_i.featureCount() > 0:
                            symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                            symbol.setColor(QColor("brown"))
                            symbol.setWidth(0.1)
                            renderer = QgsSingleSymbolRenderer(symbol)
                            lyr_vrstevnice_i.setRenderer(renderer)
                            lyr_vrstevnice_i.triggerRepaint()
                            vrstevnice_i_bool = True
    
    
                    #oříznutí trajektorií podle dpb
                    trajektorie_i_bool = False
                    if trajektorie_bool:
                        lyr_trajektorie_i = processing.run("native:clip", {
                            'INPUT': lyr_trajektorie,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        lyr_trajektorie_i.setName("Trajektorie")
                        if lyr_trajektorie_i.featureCount() > 0:
                            symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                            symbol.setColor(QColor("black"))
                            symbol.setWidth(0.1)
                            renderer = QgsSingleSymbolRenderer(symbol)
                            lyr_trajektorie_i.setRenderer(renderer)
                            lyr_trajektorie_i.triggerRepaint()
                            lyr_trajektorie_i.setName("Trajektorie")
                            trajektorie_i_bool = True
                            
                    #QgsProject.instance().addMapLayer(lyr_trajektorie_i)
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Řešení spojených/širokých pásů (---------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------  
    
                    #určení pásů s plodinami (lyr_pasy_i) z plánu osevu
                    pasy_i_bool = False
                    if kostra_i_bool:
                        # Definujeme hodnoty, které chceme extrahovat
                        target_values = ["459", "460", "471", "50018", "50082"]
                        # Vytvoříme nový prázdný seznam pro extrahované prvky
                        extracted_features = []
                        # Procházíme všechny objekty ve vrstvě
                        for feature in lyr_kostra_i.getFeatures():
                            if feature['PLOD_ID'] not in target_values:
                                extracted_features.append(feature)
                        
                        # Pokud byly nalezeny nějaké odpovídající prvky
                        if extracted_features:
                            # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                            lyr_pasy_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                        
                            # Kopírujeme pole z původní vrstvy do nové
                            new_fields = lyr_kostra_i.fields()
                            lyr_pasy_i.dataProvider().addAttributes(new_fields)
                            lyr_pasy_i.updateFields()
                        
                            # Přidáme extrahované prvky do nové vrstvy
                            lyr_pasy_i.startEditing()
                            lyr_pasy_i.dataProvider().addFeatures(extracted_features)
                            lyr_pasy_i.commitChanges()
                            
                            pasy_i_bool = True
                        
                      
                    #spojené pásy -> všechny pásy s větší šířkou
                    #nalezení širokých pásů -> tam kde existuje vnitřní buffer pro 21.45 m               
                    spojene_bool = False
                    if pasy_i_bool:
                        LayerPasy_i_vnitrni_buffer = processing.run("native:buffer",
                                       {'INPUT': lyr_pasy_i,
                                        'DISTANCE': -21.45, 'SEGMENTS': 5, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2,
                                        'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        LayerPasy_i_vnitrni_buffer.startEditing()
                        for feat in LayerPasy_i_vnitrni_buffer.getFeatures():
                            if feat.geometry().area() < 0.011:
                                LayerPasy_i_vnitrni_buffer.deleteFeature(feat.id())
                        LayerPasy_i_vnitrni_buffer.commitChanges()
                        
                        #QgsProject.instance().addMapLayer(LayerPasy_i_vnitrni_buffer)
    
                        # Zde vytvoříme vrstvu z pásů, uvnitř kterých se vyskytují buffery zmíněné výše
                        if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                            spojene_bool = True
                            LayerPasy_i_s_vnitrnim_bufferem0 = processing.run("native:extractbylocation",
                                           {'INPUT': lyr_pasy_i,
                                            'PREDICATE': [1],
                                            'INTERSECT': LayerPasy_i_vnitrni_buffer,
                                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            lyr_pasy_i.removeSelection()
                            processing.run("native:selectbylocation", {'INPUT':lyr_pasy_i,
                                                                       'PREDICATE':[1],
                                                                       'INTERSECT':LayerPasy_i_vnitrni_buffer,
                                                                       'METHOD':0})
                            
                            # zbyvajici_pasy jsou pasy, kde neni překročena šířka
                            lyr_pasy_i.invertSelection()
                            zbyvajici_pasy = processing.run("native:saveselectedfeatures", {'INPUT': lyr_pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                            lyr_pasy_i.removeSelection()
                            
                            zbyvajici_pasy.setName("zbyvajici_pasy")
                            #QgsProject.instance().addMapLayer(zbyvajici_pasy)
                        
                    """
                    neo_i_bool = False
                    siroke_pasy_area = 0
                    pocet_prekroceni_80 = 0
                    if spojene_bool:
                        #tvorba vrstvy široké pásy
                        siroke_pasy_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Spojené pásy a\npásy s nadlimitní šířkou", "memory")
                        siroke_pasy_i_provider = siroke_pasy_i.dataProvider()
                        siroke_pasy_i_fields = [QgsField("typ", QVariant.String),
                                              QgsField("NEO(%)", QVariant.Double, prec=1, len=10)
                                         ]
                        siroke_pasy_i_provider.addAttributes(siroke_pasy_i_fields)
                        siroke_pasy_i.updateFields()    
                        
                        #pokud existuje NEO, vytvoří se průnik NEO s pásy, které jsou široké
                        if neo_bool:
                            lyr_neo_i = processing.run("native:clip", {
                                'INPUT': lyr_neo,
                                'OVERLAY': LayerPasy_i_s_vnitrnim_bufferem0,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            if lyr_neo_i.featureCount() > 0 :
                                lyr_neo_i.setName("NEO uvnitř\nspojených pásů")
                                neo_i_bool = True
                                lyr_neo_i.renderer().symbol().setColor(QColor("#4cd3a6"))
                                lyr_neo_i.triggerRepaint()
                                
                    #řešení překročení neo na širokých pásech
                    #do siroke_pasy_i se umístí geometrie průniků a info o procentech plochy
                    siroke_pasy_i_bool = False
                    if spojene_bool:
                        for feat_spojpas in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                            geom = feat_spojpas.geometry()
                            plocha_siroky_pas = geom.area()
                            plocha_neo_pod_pasem = 0
                            if neo_i_bool:
                                for feat_neo in lyr_neo_i.getFeatures():
                                    geom_prunik = geom.intersection(feat_neo.geometry())
                                    plocha_neo_pod_pasem = plocha_neo_pod_pasem + geom_prunik.area()
                            
                            new_feature = QgsFeature(siroke_pasy_i.fields())
                            new_feature.setGeometry(geom)
                            new_feature["NEO(%)"] = round((100*plocha_neo_pod_pasem/plocha_siroky_pas),1)
                            if 100*plocha_neo_pod_pasem/plocha_siroky_pas < 80:
                                new_feature["typ"] = "Široký pás mimo NEO"
                                pocet_prekroceni_80 = pocet_prekroceni_80 + 1
                            else:
                                new_feature["typ"] = "Široký pás na NEO"
                            siroke_pasy_i.dataProvider().addFeature(new_feature)
                        siroke_pasy_i.updateExtents()
                        
                        if siroke_pasy_i.featureCount() > 0:
                            siroke_pasy_i_bool = True
                            
                    # vyhodnocení proběhne až po přidání "úzkých" spojených pásů
                    """
                    
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Nalezení vnitřních prvků a tvorba minima pro StP (---------------------------------------------
                    # --------------------------------------------------------------------------------------------------------------- 
                        
                    dpb_vlayer_i_bool = False  
                    kp_vlayer_i_bool = False
                    
                    #QgsProject.instance().addMapLayer(dpb_vlayer)
                    #lyr_dpb_i.setName("lyr_dpb_i")
                    #QgsProject.instance().addMapLayer(lyr_dpb_i)
                    #řešení účinných dpb a krajinných prvků
                    #nalezení účinných DPB a KP uvnitř DPB
                    DPB_i_bez_dur = processing.run("native:deleteholes", {'INPUT':lyr_dpb_i,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    if dpb_vlayer_bool:
                        
                        dpb_vlayer_i0 = processing.run("native:clip", {'INPUT':dpb_vlayer,'OVERLAY':DPB_i_bez_dur,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if testovaci_set_bool is False:
                        #vytvoření vrstvy podle výběru -> prvních 20 písmen nerovná se "standardní orná půda"
                            if dpb_vlayer_i0.featureCount() > 0:
                                id_pro_select = []
                                for feat_dpb_vlayer in dpb_vlayer_i0.getFeatures():
                                    if feat_dpb_vlayer["kultura"][:20] != "standardní orná půda" :
                                        id_pro_select.append(feat_dpb_vlayer.id())
                                dpb_vlayer_i0.selectByIds(id_pro_select)
                                dpb_vlayer_i1 = processing.run("native:saveselectedfeatures", {'INPUT': dpb_vlayer_i0, 'OUTPUT': 'memory:'})['OUTPUT']
                                dpb_vlayer_i0.removeSelection()
                                dpb_vlayer_i = processing.run("native:deleteholes", {'INPUT':dpb_vlayer_i1,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                                dpb_vlayer_i_bool = True
    
                    if kp_vlayer_bool:
                        kp_vlayer_i0 = processing.run("native:clip", {'INPUT':kp_vlayer,'OVERLAY':DPB_i_bez_dur,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        kp_vlayer_i = processing.run("native:deleteholes", {'INPUT':kp_vlayer_i0,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        if kp_vlayer_i.featureCount() > 0:
                            kp_vlayer_i_bool = True
                    
                    #DPB_i_bez_dur.setName("DPB_i_bez_dur")
                    #QgsProject.instance().addMapLayer(DPB_i_bez_dur)
                    
                    #spojení vnitřních prvků do jedné vrstvy
                    vnitrni_prvky_bool = False
                    if ((dpb_vlayer_i_bool == True) and (kp_vlayer_i_bool == False)):
                        vnitrni_prvky0 = dpb_vlayer_i
                        vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        vnitrni_prvky_bool = True
                    elif ((dpb_vlayer_i_bool == False) and (kp_vlayer_i_bool == True)):
                        vnitrni_prvky0 = kp_vlayer_i
                        vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        vnitrni_prvky_bool = True
                    elif ((dpb_vlayer_i_bool == True) and (kp_vlayer_i_bool == True)):
                        vnitrni_prvky0 = processing.run("native:mergevectorlayers", {'LAYERS':[dpb_vlayer_i, kp_vlayer_i],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        vnitrni_prvky_bool = True
                    else:
                        vnitrni_prvky_bool = False
                      
                    #určení minima pro STP, včetně DSO
                    if vnitrni_prvky_bool:
                        DPB_bez_vnitrnich_prvku = processing.run("native:difference", {'INPUT':DPB_i_bez_dur,'OVERLAY':vnitrni_prvky,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                    else:
                        DPB_bez_vnitrnich_prvku = DPB_i_bez_dur
                      
                    #vnitrni_prvky.setName("vnitrni_prvky")
                    #QgsProject.instance().addMapLayer(vnitrni_prvky)
                    #DPB_bez_vnitrnich_prvku.setName("DPB_bez_vnitrnich_prvku")
                    #QgsProject.instance().addMapLayer(DPB_bez_vnitrnich_prvku)
                        
                    #buffer 15 m dovnitř okolo okrajů, kde musí být
                    STP_ringbuffery = processing.run("native:multiringconstantbuffer", {'INPUT':DPB_bez_vnitrnich_prvku,'RINGS':1,'DISTANCE':-15,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    STP_ringbuffer = processing.run("native:extractbyattribute", {'INPUT':STP_ringbuffery,'FIELD':'distance','OPERATOR':0,'VALUE':'-15','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    STP_ringbuffer = processing.run("native:clip", {'INPUT':STP_ringbuffer,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    STP_zaklad0 = processing.run("native:dissolve", {'INPUT':STP_ringbuffer,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    # odečet širokých pásů

                    #QgsProject.instance().addMapLayer(STP_zaklad0)
                                        
                    #zde se určují místa, kde pásy sahají až k okraji nebo téměř okraji, což se projeví tím, že protnout STP_zaklad0
                    #jedná se o plochy, které leží pod NEO (měly by) proto nepotřebují STP
                    
                    lyr_pasy_i.removeSelection()
                    
                    vybrane_pasy_id = []
                    if spojene_bool:
                    
                        for pas_feat in zbyvajici_pasy.getFeatures():
                            geom_pas = pas_feat.geometry()
                            for stp_feat in STP_zaklad0.getFeatures():
                                geom_stp = stp_feat.geometry()
                                prunik_geom = geom_pas.intersection(geom_stp)
                                if prunik_geom.area() > 1:
                                    vybrane_pasy_id.append(pas_feat.id())
                                    
                        zbyvajici_pasy.selectByIds(vybrane_pasy_id)
                                    
                        uzke_siroke_pasy_i = processing.run("native:saveselectedfeatures", {'INPUT': zbyvajici_pasy, 'OUTPUT': 'memory:'})['OUTPUT']
                        zbyvajici_pasy.removeSelection()
                        
                    else:
                    
                        for pas_feat in lyr_pasy_i.getFeatures():
                            geom_pas = pas_feat.geometry()
                            for stp_feat in STP_zaklad0.getFeatures():
                                geom_stp = stp_feat.geometry()
                                prunik_geom = geom_pas.intersection(geom_stp)
                                if prunik_geom.area() > 1:
                                    vybrane_pasy_id.append(pas_feat.id())
                                    
                        lyr_pasy_i.selectByIds(vybrane_pasy_id)
                                    
                        uzke_siroke_pasy_i = processing.run("native:saveselectedfeatures", {'INPUT': lyr_pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                        lyr_pasy_i.removeSelection()
                    
                    uzke_siroke_pasy_i.setName("uzke_siroke_pasy_i")
                    #QgsProject.instance().addMapLayer(uzke_siroke_pasy_i)
                    # přidání těchto pásů do vrstvy siroke_pasy -> LayerPasy_i_s_vnitrnim_bufferem0             
                    if uzke_siroke_pasy_i.featureCount() > 0:
                        if spojene_bool:
                            for feat in uzke_siroke_pasy_i.getFeatures():
                                geom = feat.geometry()
                                new_feature = QgsFeature()
                                new_feature.setGeometry(geom)
                                #new_feature.setAttributes(feat.attributes())
                                LayerPasy_i_s_vnitrnim_bufferem0.dataProvider().addFeature(new_feature)
                            LayerPasy_i_s_vnitrnim_bufferem0.updateExtents()
                            LayerPasy_i_s_vnitrnim_bufferem0.setName("LayerPasy_i_s_vnitrnim_bufferem0")
                            #QgsProject.instance().addMapLayer(LayerPasy_i_s_vnitrnim_bufferem0)
                        else:
                            LayerPasy_i_s_vnitrnim_bufferem0 = uzke_siroke_pasy_i
                            spojene_bool = True
                            LayerPasy_i_s_vnitrnim_bufferem0.setName("LayerPasy_i_s_vnitrnim_bufferem0")
                            #QgsProject.instance().addMapLayer(LayerPasy_i_s_vnitrnim_bufferem0)
                            
                    
                    neo_i_bool = False
                    siroke_pasy_area = 0
                    pocet_prekroceni_80 = 0
                    if spojene_bool:
                        #tvorba vrstvy široké pásy
                        siroke_pasy_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Spojené pásy a\npásy s nadlimitní šířkou", "memory")
                        siroke_pasy_i_provider = siroke_pasy_i.dataProvider()
                        siroke_pasy_i_fields = [QgsField("typ", QVariant.String),
                                              QgsField("NEO(%)", QVariant.Double, prec=1, len=10)
                                         ]
                        siroke_pasy_i_provider.addAttributes(siroke_pasy_i_fields)
                        siroke_pasy_i.updateFields()    
                        
                        #pokud existuje NEO, vytvoří se průnik NEO s pásy, které jsou široké
                        if neo_bool:
                            lyr_neo_i = processing.run("native:clip", {
                                'INPUT': lyr_neo,
                                'OVERLAY': LayerPasy_i_s_vnitrnim_bufferem0,
                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            if lyr_neo_i.featureCount() > 0 :
                                lyr_neo_i.setName("NEO uvnitř\nspojených pásů")
                                neo_i_bool = True
                                
                                # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                                # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                                symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'black'})
                                # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                                props = {
                                    "line_color": "black",     # Barva šrafovacích čar
                                    "line_width": "0.15",       # Tloušťka čar (jako textový řetězec)
                                    "distance": "0.8",         # Vzdálenost mezi čarami v milimetrech
                                    "angle": "45",           # Úhel šrafování
                                    "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                                }
                                hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                                # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                                symbol.appendSymbolLayer(hatch_layer)
                                # Aplikace nového symbolu na vrstvu a překreslení
                                lyr_neo_i.renderer().setSymbol(symbol)
                                lyr_neo_i.triggerRepaint()
                                
                                
                    #řešení překročení neo na širokých pásech
                    #do siroke_pasy_i se umístí geometrie průniků a info o procentech plochy
                    siroke_pasy_i_bool = False
                    if spojene_bool:
                        for feat_spojpas in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                            geom = feat_spojpas.geometry()
                            plocha_siroky_pas = geom.area()
                            plocha_neo_pod_pasem = 0
                            if neo_i_bool:
                                for feat_neo in lyr_neo_i.getFeatures():
                                    geom_prunik = geom.intersection(feat_neo.geometry())
                                    plocha_neo_pod_pasem = plocha_neo_pod_pasem + geom_prunik.area()
                            
                            new_feature = QgsFeature(siroke_pasy_i.fields())
                            new_feature.setGeometry(geom)
                            new_feature["NEO(%)"] = round((100*plocha_neo_pod_pasem/plocha_siroky_pas),1)
                            if 100*plocha_neo_pod_pasem/plocha_siroky_pas < 80:
                                new_feature["typ"] = "Široký pás mimo NEO"
                                pocet_prekroceni_80 = pocet_prekroceni_80 + 1
                            else:
                                new_feature["typ"] = "Široký pás na NEO"
                            siroke_pasy_i.dataProvider().addFeature(new_feature)
                        siroke_pasy_i.updateExtents()
                        
                        if siroke_pasy_i.featureCount() > 0:
                            siroke_pasy_i_bool = True
                    
                    #QgsProject.instance().addMapLayer(siroke_pasy_i)
                    
                    #určení kolik % DPB pokrývají široké pasy
                    if siroke_pasy_i_bool:
                        for feat in siroke_pasy_i.getFeatures():
                            siroke_pasy_area += feat.geometry().area()
                        siroke_pasy_p = 100*(siroke_pasy_area/feat_dpb.geometry().area())
                        siroke_pasy_i.setName(f"Spojené pásy a\npásy s nadlimitní šířkou\ncelkem {siroke_pasy_p:.1f} % z DPB")
    
                        #symbologie
                        
                        categories = []
                        colors_cat = ["firebrick", "lime"]
                        unique_values = ["Široký pás mimo NEO", "Široký pás na NEO"]
                        names_cat = ["Nepokrývá NEO", "Pokrývá NEO"]
    
                        for i, value in enumerate(colors_cat):
                            symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.PolygonGeometry)
                            symbol.setColor(QColor(value))
                            # Získáme první symbolovou vrstvu (fill layer)
                            fill_layer = symbol.symbolLayer(0)
                            if fill_layer:
                                # Nastavíme okraj na průhledný
                                fill_layer.setStrokeColor(QColor(0, 0, 0, 0))  # Průhledný okraj
                                fill_layer.setStrokeWidth(0)  # Můžeme také nastavit šířku okraje na 0
                            category = QgsRendererCategory(unique_values[i], symbol, names_cat[i])
                            categories.append(category)
                        renderer = QgsCategorizedSymbolRenderer('typ', categories)  
                        if renderer is not None:
                            siroke_pasy_i.setRenderer(renderer)
                        siroke_pasy_i.triggerRepaint()
                        
                    #v případě, že se vyskytují plochy kde je NEO pod 80 % plochy není splněna podmínka
                    if pocet_prekroceni_80 > 0:
                        podminka_neo80 = "NESPLNĚNO"
                    else:
                        podminka_neo80 = "SPLNĚNO"
                        
                    print("siroke pasy plocha:", siroke_pasy_area)
                        
                    if (siroke_pasy_area/feat_dpb.geometry().area() > 0.1):
                        podminka_sirokepasy_plocha = "NESPLNĚNO"
                    else:
                        podminka_sirokepasy_plocha = "SPLNĚNO"
                    
    
    
                    #kontrola podminek
                    
                    if siroke_pasy_area > 0:
                        STP_zaklad0 = processing.run("native:difference", {'INPUT': STP_zaklad0,
                                                                              'OVERLAY': siroke_pasy_i,
                                                                              'OUTPUT': 'TEMPORARY_OUTPUT',        
                                                                              'GRID_SIZE': None})['OUTPUT']
                    #QgsProject.instance().addMapLayer(STP_zaklad0)
                    #přidání DSO
                    if dso_bool:
                        DSO_pasy_i = processing.run("native:clip", {'INPUT':DSO_pasy,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        STP_zaklad = processing.run("native:mergevectorlayers", {'LAYERS':[STP_zaklad0, DSO_pasy_i],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    else:
                        STP_zaklad = STP_zaklad0

                    if aenvi_i_bool:
                        STP_zaklad = processing.run("native:difference", {'INPUT': STP_zaklad,
                                                                              'OVERLAY': lyr_aenvi_i,
                                                                              'OUTPUT': 'TEMPORARY_OUTPUT',        
                                                                              'GRID_SIZE': None})['OUTPUT']
                        
                    STP_zaklad = processing.run("native:dissolve", {'INPUT':STP_zaklad,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    STP_zaklad = processing.run("native:multiparttosingleparts", {'INPUT':STP_zaklad,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                          
                    
                    #odstranění odřezků
                    STP_zaklad.startEditing()
                    for feat in STP_zaklad.getFeatures():
                        if feat.geometry().area() < 1:
                            STP_zaklad.deleteFeature(feat.id())
                    STP_zaklad.commitChanges()               
                    
                    STP_zaklad.setName("STP povinné minimum")
                    #QgsProject.instance().addMapLayer(STP_zaklad)
                    
                    #určeni ďur, pro různé další práce
                    diry_i_bool = False
                    Layer_diry_i = processing.run("native:difference", {'INPUT':DPB_bez_vnitrnich_prvku,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                    Layer_diry_i.startEditing()
                    for feat in Layer_diry_i.getFeatures():
                        if feat.geometry().area() < 1:
                            Layer_diry_i.deleteFeature(feat.id())
                    Layer_diry_i.commitChanges()
                    #QgsProject.instance().addMapLayer(Layer_diry_i) 
                    if Layer_diry_i.featureCount() > 0:
                        diry_i_bool = True
                        
                    #odečtení ďur z STP_zaklad
                    if diry_i_bool:
                        STP_zaklad = processing.run("native:difference", {'INPUT':STP_zaklad,'OVERLAY':Layer_diry_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
      
                    
                    #vyhodnocení zda STPmin leží unitř STP -> jestli tedy STP slňuje povinné minimum
                    plocha_stpmin_v_stp = 0
                    plocha_stpmin = 0
                    for feat_stpmin in STP_zaklad.getFeatures():
                        geom_stpmin = feat_stpmin.geometry()
                        plocha_stpmin += geom_stpmin.area()
                        if np_i_bool:
                            for feat_stp in lyr_np_i.getFeatures():
                                geom_stp = feat_stp.geometry()
                                geom_prunik = geom_stpmin.intersection(geom_stp)
                                plocha_stpmin_v_stp += geom_prunik.area()
                                
                    #podmínka, že stp min leží v stp           
                    if abs(plocha_stpmin_v_stp-plocha_stpmin) < 1:
                        podminka_stp_v_stpmin = "SPLNĚNO"
                    else:
                        podminka_stp_v_stpmin = "NESPLNĚNO"          
                        
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Určení zda konce trajektorií leží v StP (------------------------------------------------------
                    # --------------------------------------------------------------------------------------------------------------- 
                    print("trajektorie_i_bool", trajektorie_i_bool)
    
                    vyhodnoceni_konce_pasu = "NEŘEŠENO"
                    koncove_body_buffer = QgsVectorLayer(
                        "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                        "Konce pásů neležící v StP", "memory")

                    if trajektorie_i_bool:
                        
                        #odečíst STP -> bo STP může rozdělit prstenec
                        lyr_trajektorie_i = processing.run("native:difference", {
                            'INPUT':lyr_trajektorie_i,
                            'OVERLAY':lyr_np_i,
                            'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
      
                        
                        lyr_trajektorie_i_dissolve = processing.run("native:dissolve", {
                                    'INPUT': lyr_trajektorie_i,
                                    'FIELD': [],
                                    'SEPARATE_DISJOINT': False,
                                    'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                        lyr_trajektorie_i_dissolve.setName("lyr_trajektorie_i_dissolve")
                        #QgsProject.instance().addMapLayer(lyr_trajektorie_i_dissolve)
                        if lyr_trajektorie_i_dissolve.featureCount() > 0:
                            lyr_trajektorie_i_dissolve_clip = processing.run("native:clip", {'INPUT':lyr_trajektorie_i_dissolve,'OVERLAY':DPB_bez_vnitrnich_prvku,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            lyr_trajektorie_i_dissolve_clip = processing.run("native:mergelines", {'INPUT':lyr_trajektorie_i_dissolve_clip,
                                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            line_layer = processing.run("native:multiparttosingleparts", {
                                                'INPUT': lyr_trajektorie_i_dissolve_clip,
                                                'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                            #lyr_trajektorie_i_dissolve_clip.setName("lyr_trajektorie_i_dissolve_clip")
                            #QgsProject.instance().addMapLayer(lyr_trajektorie_i_dissolve_clip)
                            #siroke_pasy_i.setName("siroke_pasy_i")
                            #QgsProject.instance().addMapLayer(siroke_pasy_i)
                
                            if siroke_pasy_area > 0:
                                line_layer = processing.run("native:difference", {'INPUT':line_layer,'OVERLAY':siroke_pasy_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                                line_layer = processing.run("native:multiparttosingleparts", {
                                                    'INPUT': line_layer,
                                                    'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                                line_layer.startEditing()
                                for feat in line_layer.getFeatures():
                                    if feat.geometry().length() < 0.1:
                                        line_layer.deleteFeature(feat.id())
                                line_layer.commitChanges()
                            
                            #line_layer.setName("line_layer")
                            #QgsProject.instance().addMapLayer(line_layer)
                            
                            line_layer = processing.run("native:mergelines", {'INPUT':line_layer,
                                                                             'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                                
                            if line_layer.featureCount() > 0:
                                endpoint_layer = QgsVectorLayer("Point?crs=EPSG:5514", "koncove_body_linii", "memory")
                                for feature in line_layer.getFeatures():
                                    geom = feature.geometry()
                                    if geom.isMultipart():  # Zpracovani vicenasobnych linii
                                        line_parts = geom.parts()  # Ziskani jednotlivych casti vicenasobne linie
                                        for part in line_parts:
                                            line_points = list(part.vertices())  # Ziskani vsech bodu v linii
                                            # Pridani bodu na zacatek linie
                                            start_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[0]))
                                            start_feature = QgsFeature()
                                            start_feature.setGeometry(start_point_geom)
                                            endpoint_layer.dataProvider().addFeature(start_feature)
                                
                                            # Pridani bodu na konec linie
                                            end_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[-1]))
                                            end_feature = QgsFeature()
                                            end_feature.setGeometry(end_point_geom)
                                            endpoint_layer.dataProvider().addFeature(end_feature)
                                    else:  # Zpracovani jednoduchych linii
                                        line_points = list(geom.vertices())
                                        
                                        # Pridani bodu na zacatek linie
                                        start_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[0]))
                                        start_feature = QgsFeature()
                                        start_feature.setGeometry(start_point_geom)
                                        endpoint_layer.dataProvider().addFeature(start_feature)
                                
                                        # Pridani bodu na konec linie
                                        end_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[-1]))
                                        end_feature = QgsFeature()
                                        end_feature.setGeometry(end_point_geom)
                                        endpoint_layer.dataProvider().addFeature(end_feature)
                                
                
                                koncove_body_buffer = processing.run("native:buffer", {
                                                                    'INPUT': endpoint_layer,  # pouziti vrstvy koncove_body_linii
                                                                    'DISTANCE': 1,  # nastaveno na 1 metr
                                                                    'SEGMENTS': 5,
                                                                    'END_CAP_STYLE': 0,
                                                                    'JOIN_STYLE': 0,
                                                                    'MITER_LIMIT': 2,
                                                                    'DISSOLVE': False,
                                                                    'SEPARATE_DISJOINT': False,
                                                                    'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]  
                                #QgsProject.instance().addMapLayer(koncove_body_buffer)   
                                
                                koncove_body_buffer.removeSelection()
                                
                                if diry_i_bool:
                                    processing.run("native:selectbylocation", {'INPUT':koncove_body_buffer,
                                                                               'PREDICATE':[0],
                                                                               'INTERSECT':Layer_diry_i,
                                                                               'METHOD':1})
                                if stp_s_aenvi_i_bool:
                                    processing.run("native:selectbylocation", {'INPUT':koncove_body_buffer,
                                                                               'PREDICATE':[0],
                                                                               'INTERSECT':lyr_stp_s_aenvi_i,
                                                                               'METHOD':1})
                                
                                if koncove_body_buffer.selectedFeatureCount() > 0:
                                    koncove_body_buffer.startEditing()
                                    koncove_body_buffer.deleteSelectedFeatures()
                                    koncove_body_buffer.commitChanges()
                                    
                                print("koncove_body_buffer.featureCount()", koncove_body_buffer.featureCount())
                                if koncove_body_buffer.featureCount() > 0:
                                    vyhodnoceni_konce_pasu = "NESPLNĚNO"
                                    koncove_body_buffer.setName("Konce pásů neležící v StP")
                                    #QgsProject.instance().addMapLayer(koncove_body_buffer)
                                else:
                                    vyhodnoceni_konce_pasu = "SPLNĚNO"
                                            
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Určení zda trajektorie leží v osách pásů (-----------------------------------------------------
                    # --------------------------------------------------------------------------------------------------------------- 
                                       
                    if trajektorie_i_bool:
                        #udělá se vnitřní buffer co nejde až do středu, a převede se na linie
                        if pasy_i_bool:
                            pasy_i = processing.run("native:deleteholes", {'INPUT':lyr_pasy_i,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            vnitrni_buffer = processing.run("native:buffer", {'INPUT': pasy_i ,'DISTANCE': (1-int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':0,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                            vnitrni_buffer_linie = processing.run("native:polygonstolines", {'INPUT':vnitrni_buffer,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            #linie se oříznou podle bufferu kolem STP a ďur -> tímto se odstraní "čela" vnitřních bufferů
                            #a zůstanou pouze linky kolem trajektorie
                            #trajektorie tyto linky nesmí protnout, pokud jsou v ose pásu
                            
                            spojene_vrstvy = []
                            if stp_s_aenvi_i_bool:
                                np_buffer = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i ,'DISTANCE': (int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                                spojene_vrstvy.append(np_buffer)
                            if diry_i_bool:
                                diry_buffer = processing.run("native:buffer", {'INPUT': Layer_diry_i ,'DISTANCE': (int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                                spojene_vrstvy.append(diry_buffer)
                            if len(spojene_vrstvy) > 0:
                                spojeny_buffer = processing.run("native:mergevectorlayers", {'LAYERS':spojene_vrstvy,'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                                spojeny_buffer = processing.run("native:dissolve", {'INPUT':spojeny_buffer,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"] 
                                vnejsi_linky = processing.run("native:difference", {'INPUT':vnitrni_buffer_linie,'OVERLAY':spojeny_buffer,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                            else:
                                vnejsi_linky = vnitrni_buffer_linie
                            # použijeme line_layer abychom neřešili oblasti spojenych pasu
                            protinajici_linky = processing.run("native:extractbylocation", {'INPUT':line_layer,'PREDICATE':[0],'INTERSECT': vnejsi_linky,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            #QgsProject.instance().addMapLayer(vnejsi_linky)     
                            #QgsProject.instance().addMapLayer(protinajici_linky) 
                        
                        if protinajici_linky.featureCount() > 0:
                            vyhodnoceni_traj_v_ose = "NESPLNĚNO"
                        else:
                            vyhodnoceni_traj_v_ose = "SPLNĚNO"
                            
                            
                        # ---------------------------------------------------------------------------------------------------------------
                                
                        
                        # ---------------------------------------------------------------------------------------------------------------
                        # --------------) Určení odhadu šířky pásů + trajektorie v pásech (----------------------------------------------
                        # --------------------------------------------------------------------------------------------------------------- 
                                                
                        #kontrola že se v pasech vyskytuji trajektorie
                        if pasy_i_bool:
                            vnitrni_buffer_pro_osy = processing.run("native:buffer", {'INPUT': pasy_i ,'DISTANCE': (0.2-int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':0,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                            vnitrni_buffer_pro_osy.startEditing()
                            for feat in vnitrni_buffer_pro_osy.getFeatures():
                                if feat.geometry().area() < 1:
                                    vnitrni_buffer_pro_osy.deleteFeature(feat.id())
                            vnitrni_buffer_pro_osy.commitChanges()
                            #QgsProject.instance().addMapLayer(vnitrni_buffer_pro_osy) 
                            #QgsProject.instance().addMapLayer(LayerPasy_i_vnitrni_buffer) 
                            
                            if vnitrni_buffer_pro_osy.featureCount() > 0:
                                id_resene_pasy = []
                                for feat in vnitrni_buffer_pro_osy.getFeatures():
                                    id_resene_pasy.append(feat["ZAKRES_ID"])
                                    
                                if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                                    for feat in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                                        if feat["ZAKRES_ID"] in id_resene_pasy:
                                            id_resene_pasy.remove(feat["ZAKRES_ID"])
                                
                                              
                                #pasy neširoke -> ve skutečnosti pasy neuzke a neširoke
                                bez_trajektorie = 0
                                #QgsProject.instance().addMapLayer(pasy_i) 
                                #QgsProject.instance().addMapLayer(lyr_trajektorie_i_dissolve) 
                                pasy_i.selectByExpression("ZAKRES_ID in {}".format(tuple(id_resene_pasy)))
                                for feat_pas in pasy_i.selectedFeatures():
                                    geom_pas = feat_pas.geometry()
                                    for feat_traj in lyr_trajektorie_i_dissolve.getFeatures():
                                        geom_traj = feat_traj.geometry()
                                        geom_prunik = geom_traj.intersection(geom_pas)
                                        if (geom_prunik.length() < 1):
                                            bez_trajektorie = bez_trajektorie + 1
                                pasy_i.removeSelection()
                                if bez_trajektorie > 0:
                                    vyhodnoceni_pokryti_trajektorie = "NESPLNĚNO"
                                else:
                                    vyhodnoceni_pokryti_trajektorie = "SPLNĚNO"
                                    
                                    
                    
                    
                    
                                pasy_i.selectByExpression("ZAKRES_ID in {}".format(tuple(id_resene_pasy)))
                                pasy_nesiroke_i = processing.run("native:saveselectedfeatures", {'INPUT': pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                                pasy_i.removeSelection()
                                pasy_nesiroke_i.setName("pasy neširoke")
                                #QgsProject.instance().addMapLayer(pasy_nesiroke_i)
                                
                                trajektorie_nesiroke_i = processing.run("native:clip", {'INPUT':lyr_trajektorie_i,
                                                                                        'OVERLAY':pasy_nesiroke_i,
                                                                                        'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                                #QgsProject.instance().addMapLayer(trajektorie_nesiroke_i)
                
                                if pasy_nesiroke_i.featureCount() > 0:
                                    plochy_prekryvu = []
                                    for sirka in range(1, 44):
                                        buffery = processing.run("native:buffer",
                                                               {'INPUT': trajektorie_nesiroke_i, 'DISTANCE': sirka / 2, 'SEGMENTS': 5,
                                                                'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2, 'DISSOLVE': False,
                                                                'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                                        plocha_prunik = 0
                                        for f1 in buffery.getFeatures():
                                            for f2 in buffery.getFeatures():
                                                if f2 != f1:
                                                    prunik = f1.geometry().intersection(f2.geometry())
                                                    plocha_prunik = plocha_prunik + prunik.area()
                                        plochy_prekryvu.append(round(plocha_prunik))
                                    
                                    druhe_derivace = [0 for n in range(1,44)]
                                    for n in range(1,42):
                                        print(n)
                                        druhe_derivace[n] = (plochy_prekryvu[n-1] - 2*plochy_prekryvu[n] + plochy_prekryvu[n+1])
                                        
                                    print("sirka, překryv, druhá derivace")
                                    druhe_derivace = [0 for n in range(1,44)]
                                    for n in range(1,42):
                                        druhe_derivace[n] = (plochy_prekryvu[n-1] - 2*plochy_prekryvu[n] + plochy_prekryvu[n+1])
                                        print(n, plochy_prekryvu[n], druhe_derivace[n])
                                        
                                    # použití z_skore pro nalezení výrazných maxim
                                    z_skore = []
                                    prumer = sum(druhe_derivace)/len(druhe_derivace)
                                    odchylka = np.std(druhe_derivace)
                                    
                                    print("sirka, z-skore")
                                    for nk, clen in enumerate(druhe_derivace):
                                        n = nk + 1
                                        z_skore_i = (clen - prumer)/odchylka
                                        z_skore.append(z_skore_i)
                                        print(n, z_skore_i)
                                    
                                    sirka_odhad = -1
                                    for index, number in enumerate(z_skore):
                                        if number > 2:
                                            sirka_odhad = index + 1
                                            break
                                            
                                    if sirka_odhad < 0:
                                        for index, number in enumerate(z_skore):
                                            if number > 1:
                                                sirka_odhad = index + 1
                                                break
                                    
                                    if sirka_odhad < 0:
                                        sirka_odhad = z_skore.index(max(z_skore))+1
                                        
                                    print("sirka odhad:", sirka_odhad)    
                                    
                                    if sirka_odhad != int(dist):
                                        vyhodnoceni_sirka_pasu = "NESPLNĚNO"
                                    else:
                                        vyhodnoceni_sirka_pasu = "SPLNĚNO"
                                else:
                                    vyhodnoceni_sirka_pasu = "NESPLNĚNO"
                            
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola DPB (porovnání s účinným DPB) (-------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------         

                    chyby_v_dpb = 0
                    if testovaci_set_bool:
                        vyhodnoceni_dpb = "NEŘEŠENO"
                    else:
                        if dpb_vlayer_bool:
                            zkody = []
                            ctverce = []
                            index = QgsSpatialIndex(dpb_vlayer.getFeatures())
                            geometry1 = feat_dpb.geometry()
                            # Projdeme všechny polygony v druhé vrstvě a zkontrolujeme, zda se protínají
                            for feature2 in dpb_vlayer.getFeatures():
                                geometry2 = feature2.geometry()
                                # Zkontrolujeme, zda se geometrie kryjí (intersect)
                                if geometry1.intersects(geometry2):
                                    #dáme pryč odřezky
                                    geom_prunik = geometry1.intersection(geometry2)
                                    if geom_prunik.area() > 1: 
                                        zkody.append(feature2["zkracenyKod"]) 
                                        ctverce.append(feature2["ctverec"])
                                        print((abs(geom_prunik.area()-feat_dpb.geometry().area())), (abs(geom_prunik.area()-geometry2.area())))
                                        if ((abs(geom_prunik.area()-feat_dpb.geometry().area()) < 1) and (abs(geom_prunik.area()-geometry2.area()) < 1)):
                                            pass
                                        else:  
                                            chyby_v_dpb = chyby_v_dpb + 1
                                             
                            zkody = list(set(zkody))
                            ctverce = list(set(ctverce))
                            
                            print(zkody, ctverce)
                            print(feat_dpb["ZKOD"], feat_dpb["CTVEREC"])
                            if len(zkody) == 1:
                                if feat_dpb["ZKOD"] != zkody[0]:
                                    chyby_v_dpb = chyby_v_dpb + 1
                            else:
                                chyby_v_dpb = chyby_v_dpb + 1
                                
                            if len(ctverce) == 1:
                                if feat_dpb["CTVEREC"] != ctverce[0]:
                                    chyby_v_dpb = chyby_v_dpb + 1
                            else:
                                chyby_v_dpb = chyby_v_dpb + 1
                            
                            
                            if chyby_v_dpb > 0:
                                vyhodnoceni_dpb = "NESPLNĚNO"
                            else:
                                vyhodnoceni_dpb = "SPLNĚNO"
                            
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola zákázaných sousedících plodin (-------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    # Vytvoření prostorového indexu pro rychlé vyhledávání sousedních prvků
                    spatial_index_plodinysousedi = QgsSpatialIndex(lyr_pasy_i.getFeatures())
                    distance_threshold = 0.1  # Maximální vzdálenost v metrech
    
                    # Seznam nových prvků pro novou vrstvu
                    new_features_druh = []
    
                    # Projdi všechny prvky ve vrstvě
                    for feature in lyr_pasy_i.getFeatures():
                        geom = feature.geometry()
                        
                        #filtrování prvků podle PLOD_ID -> čeledi
                        plodina1 = feature["PLOD_ID"]
                        plodina1_celed = plodiny_kody[plodina1][2]
                        plodina1_nazev = plodiny_kody[plodina1][0]
                        
                            
    
                        # Najdi možné sousedy pomocí prostorového indexu
                        neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())
    
                        # Iterace přes sousední prvky
                        for neighbor_id in neighbors_ids:
                            neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                            neighbor_geom = neighbor_feature.geometry()
                            
                            plodina2 = neighbor_feature["PLOD_ID"]
                            plodina2_celed = plodiny_kody[plodina2][2]
                            plodina2_nazev = plodiny_kody[plodina2][0]
                            
                            print(plodina1_celed, plodina2_celed)
                            # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                            if feature.id() != neighbor_feature.id() and plodina1_celed == plodina2_celed:
                                print("Stejné čeledi")
                                #kontrola že čeled neni neznama
                                if plodina1_celed != "Neřešená":
                                    
                                    if (plodina1_nazev.split()[0] in ["Kukuřice", "Čirok"]):
                                        print("1")
                                        if plodina2_nazev.split()[0] not in ["Kukuřice", "Čirok"]:
                                            pass
                                        else:
                                            # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                            if geom.distance(neighbor_geom) <= distance_threshold:
                                                # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                                if feature not in new_features_druh:
                                                    new_features_druh.append(feature)
                                                if neighbor_feature not in new_features_druh:
                                                    new_features_druh.append(neighbor_feature)
                                                    
                                    elif (plodina2_nazev.split()[0] in ["Kukuřice", "Čirok"]):
                                        print("2")
                                        if plodina1_nazev.split()[0] not in ["Kukuřice", "Čirok"]:
                                            pass
                                        else:
                                            # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                            if geom.distance(neighbor_geom) <= distance_threshold:
                                                # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                                if feature not in new_features_druh:
                                                    new_features_druh.append(feature)
                                                if neighbor_feature not in new_features_druh:
                                                    new_features_druh.append(neighbor_feature)
                                                    
                                    else:
                                        print("3")
                                        print(plodina1_nazev, plodina2_nazev)
                                        # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                        print(geom.distance(neighbor_geom))
                                        if geom.distance(neighbor_geom) <= distance_threshold:
                                            
                                            # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                            if feature not in new_features_druh:
                                                new_features_druh.append(feature)
                                            if neighbor_feature not in new_features_druh:
                                                new_features_druh.append(neighbor_feature)
                                    
                    print(new_features_druh)
                    # Vytvoření nové vrstvy pro sousední prvky
                    sousedi_stejne_celedi = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "sousedi_stejne_celedi",
                                                  "memory")
                    sousedi_stejne_celedi_data_provider = sousedi_stejne_celedi.dataProvider()
    
                    # Přidej stejné atributy jako v původní vrstvě
                    sousedi_stejne_celedi_data_provider.addAttributes(lyr_pasy_i.fields())
                    sousedi_stejne_celedi.updateFields()
    
                    # Přidání nových prvků do vrstvy
                    sousedi_stejne_celedi_data_provider.addFeatures(new_features_druh)
    
                    # Přidání nové vrstvy do projektu
                    #QgsProject.instance().addMapLayer(output_layer)
    
                    if len(new_features_druh) > 0:
                        podminka_stejne_celedi = "NESPLNĚNO"
                        # Použití nástroje native:dissolve k rozpuštění vrstvy
                        dissolved_result_stejplod = processing.run("native:dissolve", {
                            'INPUT': sousedi_stejne_celedi,
                            'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                            'SEPARATE_DISJOINT': False,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })
    
                        # Přidání rozpuštěné vrstvy do projektu
                        dissolved_stejplod_layer = dissolved_result_stejplod['OUTPUT']
                        dissolved_stejplod_layer.setName("Sousedi_nevyhovujici_plodiny")
                        #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)
    
                        # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                        multipart_stejplod_result = processing.run("native:multiparttosingleparts", {
                            'INPUT': dissolved_stejplod_layer,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })
    
                        # Přidání vrstvy s rozdělenými prvky do projektu
                        multipart_stejplod_layer = multipart_stejplod_result['OUTPUT']
                        multipart_stejplod_layer.setName("Sousedi stejné čeledi plodin")
                        
                        # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                        # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                        symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'blue'})
                        # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                        props = {
                            "line_color": "blue",     # Barva šrafovacích čar
                            "line_width": "0.5",       # Tloušťka čar (jako textový řetězec)
                            "distance": "2.5",         # Vzdálenost mezi čarami v milimetrech
                            "angle": "45",           # Úhel šrafování
                            "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                        }
                        hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                        # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                        symbol.appendSymbolLayer(hatch_layer)
                        # Aplikace nového symbolu na vrstvu a překreslení
                        multipart_stejplod_layer.renderer().setSymbol(symbol)
                        multipart_stejplod_layer.triggerRepaint()
                        
                        #QgsProject.instance().addMapLayer(multipart_stejplod_layer)
                        
                    else:
                        podminka_stejne_celedi = "SPLNĚNO"
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola sousedících plodin s nízkou ochrannou funkcí (----------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
    
                    distance_threshold = 0.1  # Maximální vzdálenost v metrech
    
                    # Seznam nových prvků pro novou vrstvu
                    new_features_nof = []
    
                    # Projdi všechny prvky ve vrstvě
                    for feature in lyr_pasy_i.getFeatures():
                        geom = feature.geometry()
                        
                        #filtrování prvků podle PLODINA_AK
                        plodina1 = feature["PLOD_ID"]
                        plodina1_of = plodiny_kody[plodina1][1]
    
                        # Najdi možné sousedy pomocí prostorového indexu
                        neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())
    
                        # Iterace přes sousední prvky
                        for neighbor_id in neighbors_ids:
                            neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                            neighbor_geom = neighbor_feature.geometry()
                            
                            plodina2 = neighbor_feature["PLOD_ID"]
                            plodina2_of = plodiny_kody[plodina2][1]
                            
                        
                            # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                            if feature.id() != neighbor_feature.id() and plodina1_of == "NOF" and plodina2_of == "NOF":
                                # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                if geom.distance(neighbor_geom) <= distance_threshold:
                                    # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                    if feature not in new_features_nof:
                                        new_features_nof.append(feature)
                                    if neighbor_feature not in new_features_nof:
                                        new_features_nof.append(neighbor_feature)
    
                    # Vytvoření nové vrstvy pro sousední prvky
                    sousedi_nof = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "sousedi_nof",
                                                  "memory")
                    sousedi_nof_data_provider = sousedi_nof.dataProvider()
    
                    # Přidej stejné atributy jako v původní vrstvě
                    sousedi_nof_data_provider.addAttributes(lyr_pasy_i.fields())
                    sousedi_nof.updateFields()
    
                    # Přidání nových prvků do vrstvy
                    sousedi_nof_data_provider.addFeatures(new_features_nof)
    
                    # Přidání nové vrstvy do projektu
                    #QgsProject.instance().addMapLayer(output_layer)
    
                    if len(new_features_nof) > 0:
                        podminka_nof = "NESPLNĚNO"
                        # Použití nástroje native:dissolve k rozpuštění vrstvy
                        dissolved_result_nof = processing.run("native:dissolve", {
                            'INPUT': sousedi_nof,
                            'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                            'SEPARATE_DISJOINT': False,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })
    
                        # Přidání rozpuštěné vrstvy do projektu
                        dissolved_nof_layer = dissolved_result_nof['OUTPUT']
                        dissolved_nof_layer.setName("Sousedi_NOF")
                        #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)
    
                        # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                        multipart_nof_result = processing.run("native:multiparttosingleparts", {
                            'INPUT': dissolved_nof_layer,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })
    
                        # Přidání vrstvy s rozdělenými prvky do projektu
                        multipart_nof_layer = multipart_nof_result['OUTPUT']
                        multipart_nof_layer.setName("Sousedi s nízkou ochrannou funkcí")
                        
                        
                        # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                        # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                        symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'red'})
                        # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                        props = {
                            "line_color": "red",     # Barva šrafovacích čar
                            "line_width": "0.5",       # Tloušťka čar (jako textový řetězec)
                            "distance": "2",         # Vzdálenost mezi čarami v milimetrech
                            "angle": "45",           # Úhel šrafování
                            "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                        }
                        hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                        # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                        symbol.appendSymbolLayer(hatch_layer)
                        # Aplikace nového symbolu na vrstvu a překreslení
                        multipart_nof_layer.renderer().setSymbol(symbol)
                        multipart_nof_layer.triggerRepaint()
                        
                        
                        #QgsProject.instance().addMapLayer(multipart_nof_layer)
                        
                    else:
                        podminka_nof = "SPLNĚNO"
                        
                    # ---------------------------------------------------------------------------------------------------------------
                    
                
                    """
                    # Vytvoření prostorového indexu pro rychlé vyhledávání sousedních prvků
                    spatial_index_plodinysousedi = QgsSpatialIndex(lyr_pasy_i.getFeatures())
                    distance_threshold = 0.1  # Maximální vzdálenost v metrech
    
                    # Seznam nových prvků pro novou vrstvu
                    new_features = []
    
                    # Projdi všechny prvky ve vrstvě
                    if pasy_i_bool:
                        for feature in lyr_pasy_i.getFeatures():
                            geom = feature.geometry()
                            
                            #filtrování prvků podle PLODINA_AK, pokud je plodina v seznamu nepovolených sousedících dostane hodnotu 1
                            if (feature["PLODINA_AK"][:10] == "Slunečnice" or \
                                feature["PLODINA_AK"][:8] == "Kukuřice" or \
                                feature["PLODINA_AK"][:4] == "Sója" or \
                                feature["PLODINA_AK"][:3] == "Mák" or \
                                feature["PLODINA_AK"][:5] == "Čirok" or \
                                feature["PLODINA_AK"][:10] == "Řepa krmná" or \
                                feature["PLODINA_AK"][:8] == "Cukrovka"):
                                
                                vyhodnoceni_plodiny = 1
                            else:
                                vyhodnoceni_plodiny = 0
                                
                            
                            if vyhodnoceni_plodiny == 1:
                                # Najdi možné sousedy pomocí prostorového indexu
                                neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())
            
                                # Iterace přes sousední prvky
                                for neighbor_id in neighbors_ids:
                                    neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                                    neighbor_geom = neighbor_feature.geometry()
                                    
                                    if (neighbor_feature["PLODINA_AK"][:10] == "Slunečnice" or \
                                        neighbor_feature["PLODINA_AK"][:8] == "Kukuřice" or \
                                        neighbor_feature["PLODINA_AK"][:4] == "Sója" or \
                                        neighbor_feature["PLODINA_AK"][:3] == "Mák" or \
                                        neighbor_feature["PLODINA_AK"][:5] == "Čirok" or \
                                        neighbor_feature["PLODINA_AK"][:10] == "Řepa krmná" or \
                                        neighbor_feature["PLODINA_AK"][:8] == "Cukrovka"):
                                        
                                        vyhodnoceni_plodiny_soused = 1
                                    else:
                                        vyhodnoceni_plodiny_soused = 0
                                
                                    # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                                    if feature.id() != neighbor_feature.id() and vyhodnoceni_plodiny_soused == 1:
                                        # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                        if geom.distance(neighbor_geom) <= distance_threshold:
                                            # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                            if feature not in new_features:
                                                new_features.append(feature)
                                            if neighbor_feature not in new_features:
                                                new_features.append(neighbor_feature)
        
                        # Vytvoření nové vrstvy pro sousední prvky
                        sousedi_nevyhovujici_plodiny = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "Sousedi_nevyhovujici_plodiny",
                                                      "memory")
                        sousedi_nevyhovujici_plodiny_data_provider = sousedi_nevyhovujici_plodiny.dataProvider()
        
                        # Přidej stejné atributy jako v původní vrstvě
                        sousedi_nevyhovujici_plodiny_data_provider.addAttributes(lyr_pasy_i.fields())
                        sousedi_nevyhovujici_plodiny.updateFields()
        
                        # Přidání nových prvků do vrstvy
                        sousedi_nevyhovujici_plodiny_data_provider.addFeatures(new_features)
        
                        # Přidání nové vrstvy do projektu
                        #QgsProject.instance().addMapLayer(output_layer)
        
                        if len(new_features) > 0:
                            podminka_sousedici_plodiny = "NESPLNĚNO"
                            # Použití nástroje native:dissolve k rozpuštění vrstvy
                            dissolved_result_sousplod = processing.run("native:dissolve", {
                                'INPUT': sousedi_nevyhovujici_plodiny,
                                'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                                'SEPARATE_DISJOINT': False,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            })
        
                            # Přidání rozpuštěné vrstvy do projektu
                            dissolved_sousplod_layer = dissolved_result_sousplod['OUTPUT']
                            dissolved_sousplod_layer.setName("Sousedi_nevyhovujici_plodiny")
                            #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)
        
                            # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                            multipart_sousplod_result = processing.run("native:multiparttosingleparts", {
                                'INPUT': dissolved_sousplod_layer,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            })
        
                            # Přidání vrstvy s rozdělenými prvky do projektu
                            multipart_sousplod_layer = multipart_sousplod_result['OUTPUT']
                            multipart_sousplod_layer.setName("Sousedi nevyhovujici plodiny")
                            QgsProject.instance().addMapLayer(multipart_sousplod_layer)
                            
                        else:
                            podminka_sousedici_plodiny = "SPLNĚNO"
                            
                        # ---------------------------------------------------------------------------------------------------------------
                        
                        
                        # ---------------------------------------------------------------------------------------------------------------
                        # --------------) Kontrola sousedících plodin stejného rodu (----------------------------------------------------
                        # ---------------------------------------------------------------------------------------------------------------
                             
                        # Načtení vrstvy do projektu
                        if not lyr_pasy_i.isValid():
                            print("Chyba při načítání vrstvy!")
                            exit()
        
                        distance_threshold = 0.1  # Maximální vzdálenost v metrech
        
                        # Seznam nových prvků pro novou vrstvu
                        new_features_druh = []
        
                        # Projdi všechny prvky ve vrstvě
                        for feature in lyr_pasy_i.getFeatures():
                            geom = feature.geometry()
                            
                            #filtrování prvků podle PLODINA_AK
                            plodina1 = feature["PLODINA_AK"]
                            plodina1_druh = plodina1.split()[0]
                                
        
                            # Najdi možné sousedy pomocí prostorového indexu
                            neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())
        
                            # Iterace přes sousední prvky
                            for neighbor_id in neighbors_ids:
                                neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                                neighbor_geom = neighbor_feature.geometry()
                                
                                plodina2 = neighbor_feature["PLODINA_AK"]
                                plodina2_druh = plodina2.split()[0]
                                
                            
                                # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                                if feature.id() != neighbor_feature.id() and plodina1_druh == plodina2_druh:
                                    # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                    if geom.distance(neighbor_geom) <= distance_threshold:
                                        # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                        if feature not in new_features_druh:
                                            new_features_druh.append(feature)
                                        if neighbor_feature not in new_features_druh:
                                            new_features_druh.append(neighbor_feature)
        
                        # Vytvoření nové vrstvy pro sousední prvky
                        sousedi_stejne_plodiny = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "sousedi_stejne_plodiny",
                                                      "memory")
                        sousedi_stejne_plodiny_data_provider = sousedi_stejne_plodiny.dataProvider()
        
                        # Přidej stejné atributy jako v původní vrstvě
                        sousedi_stejne_plodiny_data_provider.addAttributes(lyr_pasy_i.fields())
                        sousedi_stejne_plodiny.updateFields()
        
                        # Přidání nových prvků do vrstvy
                        sousedi_stejne_plodiny_data_provider.addFeatures(new_features_druh)
        
                        # Přidání nové vrstvy do projektu
                        #QgsProject.instance().addMapLayer(output_layer)
        
                        if len(new_features_druh) > 0:
                            podminka_stejne_plodiny = "NESPLNĚNO"
                            # Použití nástroje native:dissolve k rozpuštění vrstvy
                            dissolved_result_stejplod = processing.run("native:dissolve", {
                                'INPUT': sousedi_stejne_plodiny,
                                'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                                'SEPARATE_DISJOINT': False,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            })
        
                            # Přidání rozpuštěné vrstvy do projektu
                            dissolved_stejplod_layer = dissolved_result_stejplod['OUTPUT']
                            dissolved_stejplod_layer.setName("Sousedi_nevyhovujici_plodiny")
                            #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)
        
                            # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                            multipart_stejplod_result = processing.run("native:multiparttosingleparts", {
                                'INPUT': dissolved_stejplod_layer,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            })
        
                            # Přidání vrstvy s rozdělenými prvky do projektu
                            multipart_stejplod_layer = multipart_stejplod_result['OUTPUT']
                            multipart_stejplod_layer.setName("Sousedi stejné druhy plodin")
                            QgsProject.instance().addMapLayer(multipart_stejplod_layer)
                            
                        else:
                            podminka_stejne_plodiny = "SPLNĚNO"
                            
                        if ((podminka_sousedici_plodiny == "SPLNĚNO") and (podminka_stejne_plodiny == "SPLNĚNO")):
                            podminka_plodiny = "SPLNĚNO"
                        else:
                            podminka_plodiny = "NESPLNĚNO"
                            
                        # ---------------------------------------------------------------------------------------------------------------
                    """
                        
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola na brambory (-------------------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
                        
                    #kontrola na brambory
                    # Projdi všechny prvky ve vrstvě
                    podminka_brambory = "SPLNĚNO"
                    for feature in lyr_pasy_i.getFeatures():
                        geom = feature.geometry()
                        #filtrování prvků podle PLODINA_AK
                        if (feature["PLODINA_AK"][:8] == "Brambory" or feature["PLODINA_AK"][:6] == "Batáty"):
                            podminka_brambory = "NESPLNĚNO"
                            break   
                            
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Spojení kontroly na dpb min 4 ha a kontroly na parcele min 50 m2 (-----------------------------
                    # ---------------------------------------------------------------------------------------------------------------                   
                        
                    vymera_4ha = "NEŘEŠENO"
                    if feat_dpb.geometry().area() < 40000:
                        vymera_4ha = "NESPLNĚNO"
                    else:
                        if kostra_i_bool:
                            plan_osevu_dissolve =  processing.run("native:dissolve", {'INPUT':lyr_kostra_i,'FIELD':['PLOD_ID'],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                            plan_osevu_dissolve_single = processing.run("native:multiparttosingleparts", {'INPUT':plan_osevu_dissolve,'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                            for feat in plan_osevu_dissolve_single.getFeatures():
                                if feat.geometry().area() < 50:
                                    vymera_4ha = "NESPLNĚNO"
                                    break
                                vymera_4ha = "SPLNĚNO"
                                                 
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola spojovací část a bezzásahová část (---------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
    
                    # Bez kostry/StP se podmínka nehodnotí (stejně jako KP).
                    podminka_bezzasahova_cast = "NEŘEŠENO"
                    spojovaci_casti = QgsVectorLayer(
                        "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                        "Spojovací části\nstabilizačních ploch", "memory")
                    bezzasahova_cast = QgsVectorLayer(
                        "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                        "Bezzásahové části\nstabilizačních ploch", "memory")

                    # Filtr pro výběr polygonů, které nemají PLOD_ID 471 nebo 50082
                    expression = '"PLOD_ID" NOT IN (471, 50082)'
                 
                    # Vytvoření nové vrstvy pro filtrované prvky
                    filtered_layer_bool = False
                    if kostra_i_bool:
                        filtered_layer = QgsVectorLayer("Polygon?crs=" + lyr_kostra_i.crs().authid(), "Filtered Polygons", "memory")
                        # Přidání filtrovaných prvků do nové vrstvy
                        features = lyr_kostra_i.getFeatures(QgsFeatureRequest().setFilterExpression(expression))
                        filtered_layer.dataProvider().addFeatures(features)
                        filtered_layer_bool = True
                        # Přidání vrstvy do projektu
                        #QgsProject.instance().addMapLayer(filtered_layer)
                     
                        print("Filtrovaná vrstva byla přidána do projektu.")
                     
                    if filtered_layer_bool:
                        # Vytvoření bufferů
                        buffer_distance = 0.01
                     
                        # Plochý buffer
                        flat_buffer_layer = QgsVectorLayer("Polygon?crs=" + filtered_layer.crs().authid(), "Flat Buffer", "memory")
                     
                        flat_buffer_features = []
                        for feature in filtered_layer.getFeatures():
                            geom = feature.geometry()
                            flat_buffer_geom = geom.buffer(buffer_distance, 5)
                            if flat_buffer_geom:
                                new_feature = QgsFeature()
                                new_feature.setGeometry(flat_buffer_geom)
                                flat_buffer_features.append(new_feature)
                     
                        flat_buffer_layer.dataProvider().addFeatures(flat_buffer_features)
                        #QgsProject.instance().addMapLayer(flat_buffer_layer)
                     
                        print("Plochý buffer byl přidán do projektu.")
                     
                     
                        # Rozpuštění výsledného bufferu
                        dissolved_result = processing.run(
                            "native:dissolve",
                            {
                                'INPUT': flat_buffer_layer,
                                'FIELD': [],
                                'SEPARATE_DISJOINT': False,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            }
                        )
                     
                        dissolved_layer = dissolved_result['OUTPUT']
                        #QgsProject.instance().addMapLayer(dissolved_layer)
                     
                        print("Rozpuštěný buffer byl přidán do projektu.")
                     
                        # Převod multipart na singlepart
                        singleparts_result = processing.run(
                            "native:multiparttosingleparts",
                            {
                                'INPUT': dissolved_layer,
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            }
                        )
                     
                        singleparts_layer = singleparts_result['OUTPUT']
                        QgsProject.instance().addMapLayer(singleparts_layer)
                     
                        print("Vrstva s rozdělenými geometriemi byla přidána do projektu.")
                     
                        # Iterace přes jednotlivé části
                        all_intersections = []
                        for feature in singleparts_layer.getFeatures():
                            # Nastavení aktuálního prvku jako vybraného
                            singleparts_layer.selectByIds([feature.id()])
                     
                            # Vytvoření bufferu pro aktuální prvek
                            buffer_result = processing.run(
                                "native:buffer",
                                {
                                    'INPUT': QgsProcessingFeatureSourceDefinition(singleparts_layer.id(), selectedFeaturesOnly=True),
                                    'DISTANCE': 4.99,
                                    'SEGMENTS': 5,
                                    'END_CAP_STYLE': 1,
                                    'JOIN_STYLE': 1,
                                    'MITER_LIMIT': 2,
                                    'DISSOLVE': False,
                                    'OUTPUT': 'TEMPORARY_OUTPUT'
                                }
                            )
                     
                            buffer_layer = buffer_result['OUTPUT']
                     
        
                            # Průnik bufferu s vrstvou PLOD_ID 471
                            intersection_result = processing.run(
                                "native:intersection",
                                {
                                    'INPUT': buffer_layer,
                                    'OVERLAY': lyr_np_i,
                                    'OUTPUT': 'TEMPORARY_OUTPUT'
                                }
                            )
                     
                            intersection_layer = intersection_result['OUTPUT']
                            all_intersections.append(intersection_layer)
                            singleparts_layer.removeSelection()
                            
                     
                        # Sloučení všech výsledků průniků do jedné vrstvy
                        merge_result = processing.run(
                            "native:mergevectorlayers",
                            {
                                'LAYERS': all_intersections,
                                'CRS': singleparts_layer.crs().authid(),
                                'OUTPUT': 'TEMPORARY_OUTPUT'
                            }
                        )
                     
                        spojovaci_casti = merge_result['OUTPUT']
                        #QgsProject.instance().addMapLayer(spojovaci_casti)
                     
                        print("Všechny výsledky průniků byly sloučeny do jedné vrstvy a přidány do projektu.")
                     
                        # Vyhodnocení dotyků a průniků ve vrstvě "Sloučený"
                        spojovaci_casti.startEditing()
                     
                        for feature in spojovaci_casti.getFeatures():
                            geom = feature.geometry()
                            podminka_bezzasahova_cast = "SPLNĚNO"
                            for other_feature in spojovaci_casti.getFeatures():
                                if feature.id() != other_feature.id():
                                    other_geom = other_feature.geometry()
                                    if geom.touches(other_geom) or geom.intersects(other_geom):
                                        podminka_bezzasahova_cast = "NESPLNĚNO"
                                        break
                            spojovaci_casti.updateFeature(feature)
                        spojovaci_casti.commitChanges()
                        
        
                        field_names_vrstva = spojovaci_casti.fields().names()
                        rozdil_vrstva = []
                        for element in field_names_vrstva:
                            if (element in ["ZKOD", "CTVEREC"]) == False:
                                rozdil_vrstva.append(element)
                        spojovaci_casti.startEditing()
                        fields_to_delete = []
                        for fieldname_to_delete in rozdil_vrstva:
                            fieldindex_to_delete = spojovaci_casti.fields().indexFromName(fieldname_to_delete)
                            if fieldindex_to_delete == -1:
                                continue
                            fields_to_delete.append(fieldindex_to_delete)
                        spojovaci_casti.dataProvider().deleteAttributes(fields_to_delete)
                        spojovaci_casti.updateFields()
                        spojovaci_casti.commitChanges()
                        
                        QgsProject.instance().removeMapLayer(singleparts_layer)
                        #QgsProject.instance().addMapLayer(spojovaci_casti)
                     
                        spojovaci_casti.setName("Spojovací části\nstabilizačních ploch")
                        sym = spojovaci_casti.renderer().symbol()
                        syms = sym[0]
                        syms.setColor(QColor("brown"))
                        syms.setStrokeColor(QColor("transparent"))
                        
                        #vytvoření bezzasahove časti
                        pocet_np = lyr_np_i.featureCount()
                        
                        bezzasahova_cast = processing.run("native:difference", {'INPUT':lyr_np_i,
                                                                                'OVERLAY':spojovaci_casti,
                                                                                'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                        
                        bezzasahova_cast.setName("Bezzásahové části\nstabilizačních ploch")
                        sym = bezzasahova_cast.renderer().symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#7df1de"))
                        syms.setStrokeColor(QColor("transparent"))
                    
                        for feat in bezzasahova_cast.getFeatures():
                            if feat.geometry().area() < 1:
                                bezzasahova_cast.deleteFeature(feat.id())
                        bezzasahova_cast.commitChanges()
                        
                        pocet_bc = bezzasahova_cast.featureCount()
                        
                        if pocet_bc > pocet_np:
                            if podminka_bezzasahova_cast == "SPLNĚNO":
                                podminka_bezzasahova_cast = "NESPLNĚNO"
                                
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Kontrola krajinných prvků (--------------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
                    # KP na DPB nemusí být; bez vrstvy/prvků se podmínka nehodnotí.
                    vyhodnoceni_KP = "NEŘEŠENO"
                    if kp_vlayer_bool:
                        try:
                            KP_v_planu = processing.run("native:extractbyattribute", {'INPUT':lyr_kostra_i,'FIELD':'PLOD_ID','OPERATOR':0,'VALUE':'50082','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            kp_v_planu_bool = True
                        except:
                            kp_v_planu_bool = False
                        try:
                            KP_v_DPB = processing.run("native:clip", {'INPUT':kp_vlayer,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            kp_v_dpb_bool = True
                        except:
                            kp_v_dpb_bool = False
                        
                        if ((kp_v_planu_bool==True) and (kp_v_dpb_bool == True)):
                            prunik_KP = processing.run("native:clip", {'INPUT':KP_v_DPB,'OVERLAY':KP_v_planu,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                            plocha_kp_v_dpb = 0
                            plocha_kp_v_planu = 0
                            plocha_punik = 0
                            for feat in KP_v_DPB.getFeatures():
                                plocha_kp_v_dpb += feat.geometry().area()
                            for feat in KP_v_planu.getFeatures():
                                plocha_kp_v_planu += feat.geometry().area()
                            for feat in prunik_KP.getFeatures():
                                plocha_punik += feat.geometry().area()
                            if ((abs(plocha_punik - plocha_kp_v_dpb) < 1) and (abs(plocha_punik - plocha_kp_v_planu) < 1)):
                                vyhodnoceni_KP = "SPLNĚNO"
                            else:
                                vyhodnoceni_KP = "NESPLNĚNO"
                        else:
                            vyhodnoceni_KP = "NESPLNĚNO"
                            
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) DSO pro vykreslení v mapce (linka) (-----------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
                            
                    if dso_bool:
                        lyr_dso_i = processing.run("native:clip", {
                            'INPUT': lyr_dso,
                            'OVERLAY': lyr_dpb_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        lyr_dso_i.setName("DSO")
                        sym = lyr_dso_i.renderer().symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#1b8aec"))
                        syms.setStrokeColor(QColor("transparent"))
                        syms.setWidth(0.1)
                        lyr_dso_i.triggerRepaint()
                        
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Příprava tisku a tisk první stránky s vyhodnocením (-------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
    
                    if vyska_pdf > sirka_pdf:
                        pass
                    else:
                        pass
    
                    pomer_stran = vyska_pdf / sirka_pdf
                    if pomer_stran > 10 / 6:
                        map1_vyska = 100
                        map1_sirka = 100 / pomer_stran
                    else:
                        map1_vyska = 60 * pomer_stran
                        map1_sirka = 60
                        
                    pc = layout_psp.pageCollection()
    
                    # Nastavení velikosti stránek na A4
                    pc.page(0).setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
                    page = QgsLayoutItemPage(layout_psp)
                    page.setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
                    layout_psp.pageCollection().addPage(page)
                    
                    page2 = QgsLayoutItemPage(layout_psp)
                    page2.setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
                    layout_psp.pageCollection().addPage(page2)
                        
                    if vymera_4ha == "NESPLNĚNO":
                        page3 = QgsLayoutItemPage(layout_psp)
                        page3.setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
                        layout_psp.pageCollection().addPage(page3)
                        
                    
                    title = QgsLayoutItemLabel(layout_psp)
                    title.setText("Vyhodnocení projektu PSP")
                    title.setFont(QFont("Arial", 23))
                    layout_psp.addLayoutItem(title)
                    title.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    hlavicka = QgsLayoutItemLabel(layout_psp)
                    hlavicka.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 1")
                    hlavicka.setFont(QFont("Arial", 12))
                    layout_psp.addLayoutItem(hlavicka)
                    hlavicka.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    subtitle2 = QgsLayoutItemLabel(layout_psp)
                    subtitle2.setText("Vytištěno dne: " + strftime('%d.%m.%Y', localtime(
                        time.time())) + "     ID procesu: " + id_procesu + "\nID uživatele: " + id_uzivatel + \
                        "\nVýměra DPB: %.4f" %(feat_dpb.geometry().area()/10000) + " ha\nEPSG: " + \
                        EPSG + "\nŠířka pásů: " + str(dist) + \
                        " m")
                    subtitle2.setFont(QFont("Arial", 8))
                    layout_psp.addLayoutItem(subtitle2)
                    subtitle2.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                    if testovaci_set_bool:
                        hlavicka3 = QgsLayoutItemLabel(layout_psp)
                        hlavicka3.setText("TEST")
                        hlavicka3.setFont(QFont("Arial", 20))
                        hlavicka3.setFontColor(QColor(250, 0, 0))
                        layout_psp.addLayoutItem(hlavicka3)
                        hlavicka3.attemptMove(QgsLayoutPoint(100, 100, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                    
                    texty_all = ["\n\nSplnění všech podmínek.",
                                 
                    "\n\nDPB v Projektu musí být účinný v době podání Projektu k ověření na SPU, hodnoty atributů ZKOD a\nCTVEREC v souboru „planu_osevu_psp“ musí být " + \
                    "platné.Kultura DPB musí být R (orná půda).",
                    
                    "\n\nKódy plodin v atributu PLOD_ID v souboru Projektu s názvem\"plan_osevu_psp\" musí odpovídat platnému\ncentrálnímu číselníku plodin " + \
                    "MZe.",
                    
                    "\n\nCelková výměra zákresů s plodinami na DPB musí být shodná s výměrou příslušného DPB v Projektu. Míra\nshody bude nejméně 99.99 % výměry " + \
                    "zákresů s plodinami budou vypočítány z jejich geometrie s přesností\nna čtyři desetinná místa. Jejich hodnoty budou přiřazeny každému polygonu v" +\
                    "souboru Projektu\n\"plan_osevu_psp\" v atributu VYMZAKRES.",
                    
                    "\n\nAtribut ZAKRES_ID v souboru Projektu s názvem \"plan_osevu_psp\" bude " +\
                    "obsahovat jedinečné číselné\nidentifikátory (a bude vyplněn).",
                    
                    "\n\nHodnoty atributu SIRKA_PASU v souboru Projektu s názvem \"trajektorie\" musí být celé číslo. Šířka pásů v\nProjektu bude v metrech a bude odpovídat kolmé " + \
                    "vzdálenosti vzájemně sousedících paralelních trajektorií v\nsouvislém celku. " +\
                    "Hodnoty atributu budou přiřazeny každému prvku v souboru \"trajektorie\".",
                    
                    "\n\nVelikost výměry DPB v Projektu bude nejméně 4 ha. Navíc plocha žádné zemědělské parcely není menší než\n50 m².",
                    
                    "\n\nCelková výměra částí plochy DPB se sklonitostí menší než 3 procenta bude maximálně 25% výměry DPB.\n(Parametr bude povinný pro Projekty podávané " +\
                    "v JŽ od roku 2026.)",
                    
                    "\n\nTrajektorie musí pokrývat celý DPB v Projektu, jak je uvedeno v tomto " + \
                    "metodickém postupu. Trajektorie v\nkaždém souvislém celku DPB musí být paralelní.",
                    
                    "\n\nTrajektorie v každém souvislém celku musí mít vzájemně stejnou vzdálenost v celém Projektu.",
                    
                    "\n\nTrajektorie musí procházet osami všech příslušných pásů na každém DPB v Projektu.",
                    
                    "\n\nProcentuální podíl výměry celkové plochy segmentů pásů, jejichž podélný sklon je větší nebo je roven\npolovině sklonu terénu, případně je větší než 7 %, " +\
                    "nesmí být větší než 30 % výměry celkové plochy se\nsklonitostí větší než 3 % na DPB.",
                    
                    "\n\nSouvislé plochy s výměrou nad 1 ha a s podélným sklonem nad 7 % (ZEOP) nesmí být větší než 2 ha a jejich\ncelková výměra na DPB nesmí překročit 10 % " +\
                    "výměry celkové plochy se sklonitostí větší než 3 % na DPB.",
                    
                    "\n\nMaximální celková výměra spojených pásů a pásů s nadlimitní šířkou na "+\
                    "každém DPB v Projektu nesmí být\nvětší než 10 % z výměry DPB.",
                    
                    "\n\nKaždá souvislá plocha spojených pásů musí ležet alespoň osmdesáti " + \
                    "procenty své výměry na částech DPB s\nerozní ohrožeností kategorie NEO.",
                    
                    "\n\nProcentuální podíl výměry stabilizačních ploch musí být minimálně 5 % a "+\
                    "maximálně 30 % z výměry DPB.",
                    
                    "\n\nKonce pásů se musí vždy napojovat na stabilizační plochu.",
                    
                    "\n\nOkolo hranic DPB a krajinných prvků musí být stabilizační plocha v rozsahu obalové zóny o šíři nejméně\n15 m. Osu obalové zóny tvoří hranice DPB nebo " +\
                    "krajinných prvků. Na DSO musí být navrženy stabilizační\nplochy nejméně v "  \
                    "rozsahu obalové vrstvy okolo každé osy DSO o šíři minimálně 7,5 m.",
                    
                    "\n\nKaždá stabilizační plocha v Projektu musí obsahovat spojovací i bezzásahovou část.",
                    
                    "\n\nNa dílu půdního bloku jsou pěstovány plodiny náležející do různých čeledí rostlin podle definice botanického\nsystému klasifikace plodin s výjimkou kukuřice a čiroku,které lze pravidelně střídat v pásech s ostatními\nplodinami z čeledi lipnicovité (Poaceae).",
                    
                    "\n\nNa dílu půdního bloku nejsou pravidelně střídány výhradně plodiny s nízkou ochrannou funkcí uvedené v\n§ 8 odst. 1 písm. c) nařízení vlády upravujícího pravidla podmíněnosti plateb zemědělcům nebo mák setý.",                
                    
                    "\n\nNa díle půdního bloku se nevyskytují brambory či batáty.",
                    
                    "\n\nKrajinné prvky na DPB musí odpovídat zákresu v LPIS."]
                        
                        
                    
                        
                    if ((vyhodnoceni_dpb == "SPLNĚNO") and (podminka_plody_seznam == "SPLNĚNO") and (podminka_plochy_parcel == "SPLNĚNO") and (podminka_jedinecnost == "SPLNĚNO") and \
                        (vyhodnoceni_sirka_pasu == "SPLNĚNO") and (vymera_4ha == "SPLNĚNO") and (vyhodnoceni_pokryti_trajektorie == "SPLNĚNO") and (vyhodnoceni_traj_v_ose == "SPLNĚNO") and \
                        (podminka_limit30 == "SPLNĚNO") and (podminka_zeop == "SPLNĚNO") and (podminka_sirokepasy_plocha == "SPLNĚNO") and (podminka_neo80 == "SPLNĚNO") and \
                        (podminka_plocha_np == "SPLNĚNO") and (vyhodnoceni_konce_pasu != "NESPLNĚNO") and (podminka_stp_v_stpmin == "SPLNĚNO") and (podminka_stejne_celedi == "SPLNĚNO") and \
                        (podminka_brambory == "SPLNĚNO") and (podminka_bezzasahova_cast != "NESPLNĚNO") and (vyhodnoceni_KP != "NESPLNĚNO") and (podminka_nof == "SPLNĚNO")
                        ):
                        vyhodnoceni_celek = "SPLNĚNO"
                    else:
                        vyhodnoceni_celek = "NESPLNĚNO"
                    
                    podminky_all = [vyhodnoceni_celek, vyhodnoceni_dpb, podminka_plody_seznam, podminka_plochy_parcel, podminka_jedinecnost, vyhodnoceni_sirka_pasu, vymera_4ha, \
                                    podminka_maska3_area, vyhodnoceni_pokryti_trajektorie, vyhodnoceni_sirka_pasu, vyhodnoceni_traj_v_ose, podminka_limit30, podminka_zeop, podminka_sirokepasy_plocha, \
                                    podminka_neo80, podminka_plocha_np, vyhodnoceni_konce_pasu, podminka_stp_v_stpmin, podminka_bezzasahova_cast, \
                                    podminka_stejne_celedi, podminka_nof, podminka_brambory, vyhodnoceni_KP]
                    radky_all = [1,2,2,4,2,3,2,2,2,1,1,3,2,2,2,1,1,3,1,3, 2,1,1]
                    
                    podminky_text_nesplneno = QgsLayoutItemLabel(layout_psp)
                    nesplnene_text = 6*"\n"
                    for podminka, radky in zip(podminky_all, radky_all):
                        nesplnene_text += (radky-1)*"\n"
                        if podminka == "SPLNĚNO":
                            nesplnene_text += "\n\n"
                        elif podminka == "NEŘEŠENO":
                            nesplnene_text += "NEŘEŠENO\n\n"
                        else:
                            nesplnene_text += "NESPLNĚNO\n\n"
                    podminky_text_nesplneno.setText(nesplnene_text)
                    podminky_text_nesplneno.setFont(QFont("Arial", 8))
                    podminky_text_nesplneno.setFontColor(QColor(250, 0, 0))
                    layout_psp.addLayoutItem(podminky_text_nesplneno)
                    podminky_text_nesplneno.attemptMove(QgsLayoutPoint(160, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                    
                    podminky_text_splneno = QgsLayoutItemLabel(layout_psp)
                    splnene_text = 6*"\n"
                    for podminka, radky in zip(podminky_all, radky_all):
                        splnene_text += (radky-1)*"\n"
                        if podminka == "SPLNĚNO":
                            splnene_text += "SPLNĚNO\n\n"
                        else:
                            splnene_text += 2*"\n"
                    podminky_text_splneno.setText(splnene_text)
                    podminky_text_splneno.setFont(QFont("Arial", 8))
                    layout_psp.addLayoutItem(podminky_text_splneno)
                    podminky_text_splneno.attemptMove(QgsLayoutPoint(160, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                    
                    
                    text_splneno = QgsLayoutItemLabel(layout_psp)
                    splneno_text = 4*"\n"
                    for textik, radky, podminka in zip(texty_all, radky_all, podminky_all):
                        if podminka == "SPLNĚNO":
                            splneno_text += textik
                        else:
                            splneno_text += (radky+1)*"\n"
                    text_splneno.setText(splneno_text)
                    text_splneno.setFont(QFont("Arial", 8))
                    layout_psp.addLayoutItem(text_splneno)
                    text_splneno.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                    text_nesplneno = QgsLayoutItemLabel(layout_psp)
                    nesplneno_text = 4*"\n"
                    for textik, radky, podminka in zip(texty_all, radky_all, podminky_all):
                        if podminka == "NESPLNĚNO":
                            nesplneno_text += textik
                        else:
                            nesplneno_text += (radky+1)*"\n"
                    text_nesplneno.setText(nesplneno_text)
                    text_nesplneno.setFont(QFont("Arial", 8))
                    text_nesplneno.setFontColor(QColor(250, 0, 0))
                    layout_psp.addLayoutItem(text_nesplneno)
                    text_nesplneno.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                    
                                 
                    
                    if ((vyhodnoceni_dpb == "SPLNĚNO") and (podminka_plody_seznam == "SPLNĚNO") and (podminka_plochy_parcel == "SPLNĚNO") and (podminka_jedinecnost == "SPLNĚNO") and \
                        (vyhodnoceni_sirka_pasu == "SPLNĚNO") and (vymera_4ha == "SPLNĚNO") and (vyhodnoceni_pokryti_trajektorie == "SPLNĚNO") and (vyhodnoceni_traj_v_ose == "SPLNĚNO") and \
                        (podminka_limit30 == "SPLNĚNO") and (podminka_zeop == "SPLNĚNO") and (podminka_sirokepasy_plocha == "SPLNĚNO") and (podminka_neo80 == "SPLNĚNO") and \
                        (podminka_plocha_np == "SPLNĚNO") and (vyhodnoceni_konce_pasu != "NESPLNĚNO") and (podminka_stp_v_stpmin == "SPLNĚNO") and (podminka_stejne_celedi == "SPLNĚNO") and \
                        (podminka_brambory == "SPLNĚNO") and (podminka_bezzasahova_cast != "NESPLNĚNO") and (podminka_nof == "SPLNĚNO")
                        ):
                        #dpb patří do DPB_vyhovuje
                        DPB_vyhovujici_provider = DPB_vyhovujici.dataProvider()
                        geom = feat_dpb.geometry()
                        new_feature = QgsFeature()
                        new_feature.setGeometry(geom)
                        DPB_vyhovujici_provider.addFeature(new_feature)
                        DPB_vyhovujici.updateExtents()
                        vyhodnoceni_celek_dpb = "SPLNĚNO"
                        
                        
                        lyr_pasy_i0 =  processing.run("native:extractbyattribute", {'INPUT':lyr_kostra_i,
                                                                                  'FIELD':'PLOD_ID',
                                                                                 'OPERATOR':1,'VALUE':'471',
                                                                            'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        lyr_pasy_i =  processing.run("native:extractbyattribute", {'INPUT':lyr_pasy_i0,
                                                                                  'FIELD':'PLOD_ID',
                                                                                 'OPERATOR':1,'VALUE':'50082',
                                                                            'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        #přidání prvků do hromadných vrstev
                        #QgsProject.instance().addMapLayer(lyr_pasy_i)
                        for feat in lyr_pasy_i.getFeatures():      
                            geom = feat.geometry()
                            new_feature = QgsFeature(navigace_osev_all.fields())
                            new_feature.setGeometry(geom)
                            for pole in navigace_osev_all.fields().names():
                                try:
                                    new_feature[pole] = feat[pole]
                                except:
                                    pass
                            navigace_osev_all.dataProvider().addFeature(new_feature)
                            navigace_osev_all.updateExtents()
                        
                        for feat in spojovaci_casti.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_spojpasy_all.dataProvider().addFeature(new_feature)
                            navigace_spojpasy_all.updateExtents()
                            
                        for feat in bezzasahova_cast.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_bezzasah_all.dataProvider().addFeature(new_feature)
                            navigace_bezzasah_all.updateExtents()                    
                        
                        for feat in lyr_trajektorie_i.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_trajektorie_all.dataProvider().addFeature(new_feature)
                            navigace_trajektorie_all.updateExtents()
                    
                    elif testovaci_set_bool:
                        vyhodnoceni_celek_dpb = "NESPLNĚNO"
                        for feat in lyr_pasy_i.getFeatures():      
                            geom = feat.geometry()
                            new_feature = QgsFeature(navigace_osev_all.fields())
                            new_feature.setGeometry(geom)
                            for pole in navigace_osev_all.fields().names():
                                try:
                                    new_feature[pole] = feat[pole]
                                except:
                                    pass
                            navigace_osev_all.dataProvider().addFeature(new_feature)
                            navigace_osev_all.updateExtents()
                        
                        for feat in spojovaci_casti.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_spojpasy_all.dataProvider().addFeature(new_feature)
                            navigace_spojpasy_all.updateExtents()
                            
                        for feat in bezzasahova_cast.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_bezzasah_all.dataProvider().addFeature(new_feature)
                            navigace_bezzasah_all.updateExtents()                    
                        
                        for feat in lyr_trajektorie_i.getFeatures():
                            geom = feat.geometry()
                            new_feature = QgsFeature()
                            new_feature.setGeometry(geom)
                            navigace_trajektorie_all.dataProvider().addFeature(new_feature)
                            navigace_trajektorie_all.updateExtents()
                    
                    else:
                        #dpb patří do DPB_nevyhovuje
                        DPB_nevyhovujici_provider = DPB_nevyhovujici.dataProvider()
                        geom = feat_dpb.geometry()
                        new_feature = QgsFeature()
                        new_feature.setGeometry(geom)
                        DPB_nevyhovujici_provider.addFeature(new_feature)
                        DPB_nevyhovujici.updateExtents()
                        vyhodnoceni_celek_dpb = "NESPLNĚNO"
                        
    
    
    
                    title = QgsLayoutItemLabel(layout_psp)
                    title.setText("Vyhodnocení projektu PSP")
                    title.setFont(QFont("Arial", 23))
                    layout_psp.addLayoutItem(title)
                    title.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    hlavicka = QgsLayoutItemLabel(layout_psp)
                    hlavicka.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 2")
                    hlavicka.setFont(QFont("Arial", 12))
                    layout_psp.addLayoutItem(hlavicka)
                    hlavicka.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    
                    if testovaci_set_bool:
                        hlavicka3 = QgsLayoutItemLabel(layout_psp)
                        hlavicka3.setText("TEST")
                        hlavicka3.setFont(QFont("Arial", 20))
                        hlavicka3.setFontColor(QColor(250, 0, 0))
                        layout_psp.addLayoutItem(hlavicka3)
                        hlavicka3.attemptMove(QgsLayoutPoint(100, 100, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Vykreslení map (-------------------------------------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------
    
                    map1 = QgsLayoutItemMap(layout_psp)
                    map1.setRect(20, 20, 20, 20)
                    lyr_trajektorie_i.setName("Trajektorie")
    
                    if limit30_i_bool:
                        layers1 = [lyr_trajektorie_i, lyr_limit30_i, lyr_dpb_i]
                    else:
                        layers1 = [lyr_trajektorie_i, lyr_dpb_i]
                    rectangle = feat_dpb.geometry().boundingBox()
                    map1.setExtent(rectangle)
    
                    layout_psp.addLayoutItem(map1)
                    map1.setLayers(layers1)
                    map1.attemptMove(
                        QgsLayoutPoint(int(35 - map1_sirka / 2), int(115 - map1_vyska / 2), QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    map1.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    newFontSG = QFont("MS Shell Dlg 2", 10)
                    newFontSL = QFont("MS Shell Dlg 2", 10)
    
                    legend1 = QgsLayoutItemLegend(layout_psp)
                    strom1 = QgsLayerTree()
                    for lyr in layers1:
                        strom1.addLayer(lyr)
                    legend1.model().setRootGroup(strom1)
                    layout_psp.addLayoutItem(legend1)
                    legend1.attemptMove(QgsLayoutPoint(65, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    legend1.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend1.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend1.setSymbolHeight(2)
                    legend1.setSymbolWidth(4)
                    legend1.adjustBoxSize()
                    
                    map1text = QgsLayoutItemLabel(layout_psp)
                    map1text.setText("Místa s překročeným podélným sklonem")
                    map1text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map1text)
                    map1text.attemptMove(QgsLayoutPoint(15, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    map2 = QgsLayoutItemMap(layout_psp)
                    map2.setRect(20, 20, 20, 20)
                    layers2 = []
                    if zeop_i_bool:
                        layers2.append(zeop)           
                    layers2.append(lyr_dpb_i)   
                    rectangle = feat_dpb.geometry().boundingBox()
                    map2.setExtent(rectangle)
                    layout_psp.addLayoutItem(map2)
                    map2.setLayers(layers2)
                    map2.attemptMove(
                        QgsLayoutPoint(int(140 - map1_sirka / 2), int(115 - map1_vyska / 2),
                                       QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    map2.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend2 = QgsLayoutItemLegend(layout_psp)
                    strom2 = QgsLayerTree()
                    for lyr in layers2:
                        strom2.addLayer(lyr)
                    legend2.model().setRootGroup(strom2)
                    layout_psp.addLayoutItem(legend2)
                    legend2.attemptMove(QgsLayoutPoint(170, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    legend2.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend2.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend2.setSymbolHeight(2)
                    legend2.setSymbolWidth(4)
                    legend2.adjustBoxSize()
                    
                    map2text = QgsLayoutItemLabel(layout_psp)
                    map2text.setText("Značně erozně ohrožené plochy")
                    map2text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map2text)
                    map2text.attemptMove(QgsLayoutPoint(115, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    map3 = QgsLayoutItemMap(layout_psp)
                    map3.setRect(20, 20, 20, 20)
                    layers3 = [lyr_maska3_invert_i, lyr_dpb_i]
                    rectangle = feat_dpb.geometry().boundingBox()
                    map3.setExtent(rectangle)
                    layout_psp.addLayoutItem(map3)
                    map3.setLayers(layers3)
    
                    map3.attemptMove(
                        QgsLayoutPoint(int(35 - map1_sirka / 2), int(232 - map1_vyska / 2), QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    map3.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend3 = QgsLayoutItemLegend(layout_psp)
                    strom3 = QgsLayerTree()
                    for lyr in layers3:
                        strom3.addLayer(lyr)
                    legend3.model().setRootGroup(strom3)
                    layout_psp.addLayoutItem(legend3)
                    legend3.attemptMove(QgsLayoutPoint(65, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    legend3.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend3.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend3.setSymbolHeight(2)
                    legend3.setSymbolWidth(4)
                    legend3.adjustBoxSize()
                    
                    map3text = QgsLayoutItemLabel(layout_psp)
                    map3text.setText("Plochy s nízkou svažitosti")
                    map3text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map3text)
                    map3text.attemptMove(QgsLayoutPoint(24, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    map4 = QgsLayoutItemMap(layout_psp)
                    map4.setRect(20, 20, 20, 20)
                    layers4 = []
                    if trajektorie_i_bool:
                        layers4.append(lyr_trajektorie_i)
                    if vrstevnice_i_bool:
                        layers4.append(lyr_vrstevnice_i)
                    layers4.append(lyr_dpb_i)
                    rectangle = feat_dpb.geometry().boundingBox()
                    map4.setExtent(rectangle)
                    layout_psp.addLayoutItem(map4)
                    map4.setLayers(layers4)
    
                    map4.attemptMove(
                        QgsLayoutPoint(int(140 - map1_sirka / 2), int(232 - map1_vyska / 2),
                                       QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                    map4.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend4 = QgsLayoutItemLegend(layout_psp)
                    strom4 = QgsLayerTree()
                    for lyr in layers4:
                        strom4.addLayer(lyr)
                    legend4.model().setRootGroup(strom4)
                    layout_psp.addLayoutItem(legend4)
                    legend4.attemptMove(QgsLayoutPoint(170, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    legend4.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend4.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend4.setSymbolHeight(2)
                    legend4.setSymbolWidth(4)
                    legend4.adjustBoxSize()
                    
                    map4text = QgsLayoutItemLabel(layout_psp)
                    map4text.setText("Vrstevnice a trajektorie")
                    map4text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map4text)
                    map4text.attemptMove(QgsLayoutPoint(115, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
    
                    title2 = QgsLayoutItemLabel(layout_psp)
                    title2.setText("Vyhodnocení projektu PSP")
                    title2.setFont(QFont("Arial", 23))
                    layout_psp.addLayoutItem(title2)
                    title2.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
                    hlavicka2 = QgsLayoutItemLabel(layout_psp)
                    hlavicka2.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 3")
                    hlavicka2.setFont(QFont("Arial", 12))
                    layout_psp.addLayoutItem(hlavicka2)
                    hlavicka2.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    
                    
                    if testovaci_set_bool:
                        hlavicka3 = QgsLayoutItemLabel(layout_psp)
                        hlavicka3.setText("TEST")
                        hlavicka3.setFont(QFont("Arial", 20))
                        hlavicka3.setFontColor(QColor(250, 0, 0))
                        layout_psp.addLayoutItem(hlavicka3)
                        hlavicka3.attemptMove(QgsLayoutPoint(100, 100, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
    
    
                    if vyhodnoceni_celek_dpb == "NESPLNĚNO":
                        ctverec = QgsLayoutItemShape(layout_psp)
                        ctverec.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec)
                        ctverec.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        ctverec.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#ff0501"))
                        syms.setStrokeColor(QColor("transparent"))
    
                        ctverec2 = QgsLayoutItemShape(layout_psp)
                        ctverec2.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec2)
                        ctverec2.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                        ctverec2.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec2.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#ff0501"))
                        syms.setStrokeColor(QColor("transparent"))
                        
                        ctverec3 = QgsLayoutItemShape(layout_psp)
                        ctverec3.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec3)
                        ctverec3.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                        ctverec3.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec3.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#ff0501"))
                        syms.setStrokeColor(QColor("transparent"))
                    else:
                        ctverec = QgsLayoutItemShape(layout_psp)
                        ctverec.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec)
                        ctverec.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        ctverec.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#5aee15"))
                        syms.setStrokeColor(QColor("transparent"))
    
                        ctverec2 = QgsLayoutItemShape(layout_psp)
                        ctverec2.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec2)
                        ctverec2.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                        ctverec2.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec2.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#5aee15"))
                        syms.setStrokeColor(QColor("transparent"))
                        
                        ctverec3 = QgsLayoutItemShape(layout_psp)
                        ctverec3.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                        layout_psp.addLayoutItem(ctverec3)
                        ctverec3.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                        ctverec3.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                        sym = ctverec3.symbol()
                        syms = sym[0]
                        syms.setColor(QColor("#5aee15"))
                        syms.setStrokeColor(QColor("transparent"))                
     
    
                    map5 = QgsLayoutItemMap(layout_psp)
                    map5.setRect(20, 20, 20, 20)
                    layers5 = []
                    if podminka_stejne_celedi == "NESPLNĚNO":
                        layers5.append(multipart_stejplod_layer)
                    if podminka_nof == "NESPLNĚNO":
                        layers5.append(multipart_nof_layer)
                    layers5.append(lyr_kostra_i)
                    rectangle = feat_dpb.geometry().boundingBox()
                    map5.setExtent(rectangle)
                    layout_psp.addLayoutItem(map5)
                    map5.setLayers(layers5)
    
                    map5.attemptMove(
                        QgsLayoutPoint(int(35 - map1_sirka / 2), int(115 - map1_vyska / 2),
                                       QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    map5.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend5 = QgsLayoutItemLegend(layout_psp)
                    strom5 = QgsLayerTree()
                    for lyr in layers5:
                        strom5.addLayer(lyr)
                    legend5.model().setRootGroup(strom5)
                    layout_psp.addLayoutItem(legend5)
                    legend5.attemptMove(QgsLayoutPoint(65, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
                    legend5.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend5.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend5.setSymbolHeight(2)
                    legend5.setSymbolWidth(4)
                    legend5.adjustBoxSize()
                    
                    popisek5 = QgsLayoutItemLabel(layout_psp)
                    popisek5.setText(f"Výměra veškerých plodin: {vymera_plan_osevu:.4f} ha\nVýměra DPB: {(feat_dpb.geometry().area()/10000):.4f} ha")
                    popisek5.setFont(newFontSG)
                    layout_psp.addLayoutItem(popisek5)
                    popisek5.attemptMove(QgsLayoutPoint(65, 65, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    
                    map5text = QgsLayoutItemLabel(layout_psp)
                    map5text.setText("Výměry zemědělských parcel")
                    map5text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map5text)
                    map5text.attemptMove(QgsLayoutPoint(15, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    
                    
    
    
    
                    map6 = QgsLayoutItemMap(layout_psp)
                    map6.setRect(20, 20, 20, 20)
                    if koncove_body_buffer.featureCount() > 0:
                        layers6 = [koncove_body_buffer]
                    else:
                        layers6 = []
                    if dso_bool:
                        layers6.append(lyr_dso_i)
                    if spojovaci_casti.featureCount() > 0:
                        layers6.append(spojovaci_casti)
                    if bezzasahova_cast.featureCount() > 0:
                        layers6.append(bezzasahova_cast)
                    layers6.append(lyr_dpb_i)
                    
                    
                    rectangle = feat_dpb.geometry().boundingBox()
                    map6.setExtent(rectangle)
                    layout_psp.addLayoutItem(map6)
                    map6.setLayers(layers6)
    
                    map6.attemptMove(
                        QgsLayoutPoint(int(35 - map1_sirka / 2), int(232 - map1_vyska / 2),
                                       QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    map6.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend6 = QgsLayoutItemLegend(layout_psp)
                    strom6 = QgsLayerTree()
                    for lyr in layers6:
                        strom6.addLayer(lyr)
                    legend6.model().setRootGroup(strom6)
                    layout_psp.addLayoutItem(legend6)
                    legend6.attemptMove(QgsLayoutPoint(65, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
                    legend6.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend6.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend6.setSymbolHeight(2)
                    legend6.setSymbolWidth(4)
                    legend6.adjustBoxSize()
                    
                    map6text = QgsLayoutItemLabel(layout_psp)
                    map6text.setText("Stabilizační plochy")
                    map6text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map6text)
                    map6text.attemptMove(QgsLayoutPoint(24, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
    
    
                    map7 = QgsLayoutItemMap(layout_psp)
                    map7.setRect(20, 20, 20, 20)
                    layers7 = []
                    if neo_i_bool:
                        layers7.append(lyr_neo_i)
                    if siroke_pasy_i_bool:
                        layers7.append(siroke_pasy_i)
                    layers7.append(lyr_dpb_i)
                    rectangle = feat_dpb.geometry().boundingBox()
                    map7.setExtent(rectangle)
                    layout_psp.addLayoutItem(map7)
                    map7.setLayers(layers7)
    
                    map7.attemptMove(
                        QgsLayoutPoint(int(140 - map1_sirka / 2), int(232 - map1_vyska / 2),
                                       QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    map7.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
    
                    legend7 = QgsLayoutItemLegend(layout_psp)
                    strom7 = QgsLayerTree()
                    for lyr in layers7:
                        strom7.addLayer(lyr)
                    legend7.model().setRootGroup(strom7)
                    layout_psp.addLayoutItem(legend7)
                    legend7.attemptMove(QgsLayoutPoint(170, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
    
                    legend7.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
                    legend7.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
                    legend7.setSymbolHeight(2)
                    legend7.setSymbolWidth(4)
                    legend7.adjustBoxSize()
                    
                    map7text = QgsLayoutItemLabel(layout_psp)
                    map7text.setText("Spojené/široké pásy a plochy NEO")
                    map7text.setFont(QFont("MS Shell Dlg 2", 10))
                    layout_psp.addLayoutItem(map7text)
                    map7text.attemptMove(QgsLayoutPoint(115, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                    
                    
                    
                    if vymera_4ha == "NESPLNĚNO":
                        
                        title4 = QgsLayoutItemLabel(layout_psp)
                        title4.setText("Vyhodnocení projektu PSP")
                        title4.setFont(QFont("Arial", 23))
                        layout_psp.addLayoutItem(title4)
                        title4.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=3)
                        
                        title45 = QgsLayoutItemLabel(layout_psp)
                        title45.setText("Seznam parcel s malou výměrou")
                        title45.setFont(QFont("Arial", 12))
                        layout_psp.addLayoutItem(title45)
                        title45.attemptMove(QgsLayoutPoint(8, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=3)
    
                        hlavicka4 = QgsLayoutItemLabel(layout_psp)
                        hlavicka4.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 4")
                        hlavicka4.setFont(QFont("Arial", 12))
                        layout_psp.addLayoutItem(hlavicka4)
                        hlavicka4.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=3)
                        
                        hlavicka3 = QgsLayoutItemLabel(layout_psp)
                        hlavicka3.setText("TEST")
                        hlavicka3.setFont(QFont("Arial", 20))
                        hlavicka3.setFontColor(QColor(250, 0, 0))
                        layout_psp.addLayoutItem(hlavicka3)
                        hlavicka3.attemptMove(QgsLayoutPoint(161, 7, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=3)
                                          
                        table1 = QgsLayoutItemTextTable(layout_psp)
                        layout_psp.addMultiFrame(table1)
                        cols = [QgsLayoutTableColumn(), QgsLayoutTableColumn(), QgsLayoutTableColumn(), QgsLayoutTableColumn()]
                        cols[0].setHeading("ZAKRES_ID")
                        cols[1].setHeading("VYMZAKRES")
                        cols[2].setHeading("PLOD_ID")
                        cols[3].setHeading("PLODINA_AK")
                        table1.setColumns(cols)
                        for feat in lyr_kostra_i.getFeatures():
                            if feat["VYMZAKRES"] < 0.0050:
                                zakrid = feat["ZAKRES_ID"]
                                vym = round(feat["VYMZAKRES"],4)
                                plodid = feat["PLOD_ID"]
                                plodak = feat["PLODINA_AK"]
                                table1.addRow([str(zakrid), str((vym)), str(plodid), str(plodak)])
                        table1.setGridStrokeWidth(0.1)
                        content_format = QgsTextFormat()
                        content_format.setSize(11)
                        table1.setContentTextFormat(content_format)
                        header_format = QgsTextFormat()
                        header_format.setSize(10)
                        table1.setHeaderTextFormat(header_format)
                        frame = QgsLayoutFrame(layout_psp, table1)
                        frame.attemptMove(QgsLayoutPoint(10, 35, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=3)
                        frame.attemptResize(QgsLayoutSize(45, 180), True)
                        table1.addFrame(frame)
                    
    
                        
                        
                    
                    
    
    
    
                    layout_tisk = manager.layoutByName(layoutName)
                    exporter = QgsLayoutExporter(layout_tisk)
    
                    if testovaci_set_bool:
                        dir_dokumenty = dir_dokumentace + "\\Test_prjkt_psp" + id_cele + f"\\Dokumentaceprojektu{id_cele}\\Jednotlive_DPB"
                    else:
                        dir_dokumenty = dir_dokumentace + "\\Projekt_psp" + id_cele + f"\\Dokumentaceprojektu{id_cele}\\Jednotlive_DPB"
                        
                    if os.path.isdir(dir_dokumenty) == False:
                        os.mkdir(dir_dokumenty)
    
                    exporter.exportToPdf(dir_dokumenty + "\\Dokumentace_psp_" + str(N) + ".pdf",
                                         QgsLayoutExporter.PdfExportSettings())
    
                    seznam_pdf.append(dir_dokumenty + "\\Dokumentace_psp_" + str(N) + ".pdf")
    
                    N = N + 1
                    
                # ---------------------------------------------------------------------------------------------------------------
                
                
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Seskupení pdf s jednotlivými DPB do jednoho souboru (------------------------------------------
                # ---------------------------------------------------------------------------------------------------------------
    
                for pdf in seznam_pdf:
                    merger.append(pdf)
    
                if testovaci_set_bool:
                    merger.write(
                        dir_dokumentace + "\\Test_prjkt_psp" + id_cele + f"\\Dokumentaceprojektu{id_cele}\\Dokumentace{id_cele}.pdf")
                    merger.close()
                else:
                    merger.write(
                        dir_dokumentace + "\\Projekt_psp" + id_cele + f"\\Dokumentaceprojektu{id_cele}\\Dokumentace{id_cele}.pdf")
                    merger.close()
                
                #QgsProject.instance().addMapLayer(DPB_vyhovujici)
                #QgsProject.instance().addMapLayer(DPB_nevyhovujici)
                
                # ---------------------------------------------------------------------------------------------------------------
                
                
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Vykreslení vyhovujících vrstev do epsg 4326 pro navigaci (-------------------------------------
                # ---------------------------------------------------------------------------------------------------------------          
                
                if testovaci_set_bool is False:
                    #prunik dpb, které vyhovuje a nevyhovuje s planem osevu a trajektoriemi
                    vyhovujici_path = os.path.join(dir_dokumentace, "Projekt_psp" + id_cele, "Import_projekt_psp" + id_cele)
                    os.makedirs(vyhovujici_path, exist_ok=True)
                
                
                
                if ((DPB_vyhovujici.featureCount() > 0) ):
                    #plan_osevu_vyhovujici = 
                    processing.run("native:clip", {'INPUT':lyr_kostra,
                                                                           'OVERLAY':DPB_vyhovujici,
                                                                           'OUTPUT':vyhovujici_path + "\\plan_osevu_psp.shp"})
                    #trajektorie_osevu_vyhovujici = 
                    processing.run("native:clip", {'INPUT':lyr_trajektorie,
                                                                           'OVERLAY':DPB_vyhovujici,
                                                                           'OUTPUT':vyhovujici_path + "\\trajektorie.shp"})
                    
                    def zip_folder(folder_path, output_zip):
                        # Otevřít nový zip soubor
                        with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
                            # Procházet všechny soubory a složky
                            for root, dirs, files in os.walk(folder_path):
                                for file in files:
                                    # Získat úplnou cestu k souboru
                                    file_path = os.path.join(root, file)
                                    # Přidat soubor do archivu se správnou relativní cestou
                                    zipf.write(file_path, os.path.relpath(file_path, folder_path))
                                    
                    zip_folder(vyhovujici_path, dir_dokumentace + f"//Projekt_psp{id_cele}//Import_projekt_psp{id_cele}.zip")
                    
                if ((DPB_vyhovujici.featureCount() > 0) or (testovaci_set_bool is True)):    
                    
                    navigace_osev_all_path = os.path.join(dir_navigace, "pasy.shp")
                    reproject_layer_5514_to_4326(navigace_osev_all, navigace_osev_all_path, self.iface)
                    
                    navigace_spojpasy_all_path = os.path.join(dir_navigace, "spojovaci_casti_StP.shp")
                    reproject_layer_5514_to_4326(navigace_spojpasy_all, navigace_spojpasy_all_path, self.iface)
                    
                    navigace_bezzasah_all_path = os.path.join(dir_navigace, "bezzasahove_casti_StP.shp")
                    reproject_layer_5514_to_4326(navigace_bezzasah_all, navigace_bezzasah_all_path, self.iface)
                    
                    navigace_trajektorie_all = processing.run("native:dissolve", {'INPUT':navigace_trajektorie_all,
                                                                                  'FIELD':[],
                                                                                  'SEPARATE_DISJOINT':False,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    navigace_trajektorie_all = processing.run("native:multiparttosingleparts", {'INPUT':navigace_trajektorie_all,
                                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    navigace_trajektorie_all_path = os.path.join(dir_navigace, f"trajektorie_{dist}m.shp")
                    reproject_layer_5514_to_4326(navigace_trajektorie_all, navigace_trajektorie_all_path, self.iface)

                    # Split plan_osevu_psp podle PLODINA_AK do Navigace (EPSG:4326, stejná transformace)
                    # Stejný název po úpravě → jeden společný SHP
                    # DPB z psp_vyhovuje → Navigace jako DPB.shp
                    if lyr_dpb.isValid() and lyr_dpb.featureCount() > 0:
                        navigace_dpb_path = os.path.join(dir_navigace, "DPB.shp")
                        reproject_layer_5514_to_4326(lyr_dpb, navigace_dpb_path, self.iface)

                    def nazev_shp_z_plodina_ak(hodnota):
                        if hodnota is None or hodnota == NULL:
                            return None
                        text = str(hodnota).strip()
                        if not text:
                            return None
                        text = unicodedata.normalize("NFKD", text)
                        text = "".join(c for c in text if not unicodedata.combining(c))
                        text = text.replace(" ", "_")
                        text = re.sub(r"[^\w\-]", "_", text)
                        text = re.sub(r"_+", "_", text).strip("_")
                        if not text:
                            text = "bez_nazvu"
                        return text[:80]

                    if kostra_bool and lyr_kostra.isValid() and lyr_kostra.fields().indexOf("PLODINA_AK") >= 0:
                        skupiny_plodin = {}
                        for plodina_ak in lyr_kostra.uniqueValues(lyr_kostra.fields().indexOf("PLODINA_AK")):
                            nazev_souboru = nazev_shp_z_plodina_ak(plodina_ak)
                            if nazev_souboru is None:
                                continue
                            skupiny_plodin.setdefault(nazev_souboru, []).append(plodina_ak)

                        for nazev_souboru, hodnoty_plodin in skupiny_plodin.items():
                            hodnoty_esc = []
                            for hodnota in hodnoty_plodin:
                                text = str(hodnota).replace("'", "''")
                                hodnoty_esc.append(f"'{text}'")
                            vyraz = f"\"PLODINA_AK\" IN ({','.join(hodnoty_esc)})"
                            lyr_kostra.selectByExpression(vyraz)
                            lyr_plodina = processing.run(
                                "native:saveselectedfeatures",
                                {'INPUT': lyr_kostra, 'OUTPUT': 'memory:'}
                            )['OUTPUT']
                            lyr_kostra.removeSelection()
                            if lyr_plodina.featureCount() == 0:
                                continue
                            vystup_plodina_path = os.path.join(dir_navigace, f"{nazev_souboru}.shp")
                            reproject_layer_5514_to_4326(lyr_plodina, vystup_plodina_path, self.iface)
            else:
                self.iface.messageBar().pushMessage("Nelze provést export", "Chyba načtení WFS souborů",
                                                    level=Qgis.MessageLevel.Critical)
        else:
            self.iface.messageBar().pushMessage("Nelze provést export", "Nejsou správně vyplněny cesty do složek",
                                                level=Qgis.MessageLevel.Critical)
            
        QMessageBox.information(None,
                                           "End",
                                           "Hotovo")


    def import_kostry(self):

        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))

        umisteni_navrhu_dir = self.dlg.lineEdit_kostraxlsx.text()
        id_cele = (os.path.basename(umisteni_navrhu_dir))
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(umisteni_navrhu_dir):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)
                
        
        if "Navrh_psp" in id_cele:
            id_cele = id_cele.replace("Navrh_psp", "")
            test_bool = False
        elif "Test_psp" in id_cele:
            id_cele = id_cele.replace("Test_psp", "")
            test_bool = True
        else:
            print("Navrh_psp nenalezen")

        umisteni_kostry_dir = umisteni_navrhu_dir + "\\kostra_psp" + id_cele
        kostraprojektudir_existuje = os.path.isdir(umisteni_kostry_dir)
        kostra_shp = os.path.join(umisteni_kostry_dir, f"kostra_psp{id_cele}.shp")

        def prevod_id_na_jmeno(lyr):
            plodiny_txt = f'{self.plugin_dir}/kodyplodin_plus.txt'
            plodiny_soubor = open(plodiny_txt, "r")
            plodiny_kody = {}
            for line in plodiny_soubor.readlines():
                radek = line.split(", ")
                cislo = radek[0]
                text = radek[1]
                plodiny_kody[cislo] = text
            plodiny_soubor.close()

            lyr.startEditing()
            for feat in lyr.getFeatures():
                plod_id = feat["PLOD_ID"]
                if plod_id in list(plodiny_kody.keys()):
                    feat["PLODINA_AK"] = plodiny_kody[plod_id]
                else:
                    feat["PLODINA_AK"] = "ID není v seznamu"
                lyr.updateFeature(feat)
            lyr.commitChanges()

        if kostraprojektudir_existuje:

            def zip_folder(folder_path, output_zip):
                # Otevřít nový zip soubor
                with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
                    # Procházet všechny soubory a složky
                    for root, dirs, files in os.walk(folder_path):
                        for file in files:
                            # Získat úplnou cestu k souboru
                            file_path = os.path.join(root, file)
                            # Přidat soubor do archivu se správnou relativní cestou
                            zipf.write(file_path, os.path.relpath(file_path, folder_path))

            dopocteno = False

            # manualně vyplněna kostra
            kostra_shp_layer = QgsVectorLayer(kostra_shp, "kostra_shp", "ogr")
            vyplneno_plodiny_id = True
            for feat in kostra_shp_layer.getFeatures():
                if feat["PLOD_ID"] == NULL:
                    vyplneno_plodiny_id = False
                    break

            if vyplneno_plodiny_id:
                dir_celek = os.path.dirname(umisteni_navrhu_dir)


                if test_bool:
                    dir_projekt = dir_celek + "\\Test_prjkt_psp" + id_cele
                else:
                    dir_projekt = dir_celek + "\\Projekt_psp" + id_cele
                if os.path.isdir(dir_projekt) == False:
                    os.mkdir(dir_projekt)

                dir_pro_import = dir_projekt + "\\priprava" + id_cele
                if os.path.isdir(dir_pro_import) == False:
                    os.mkdir(dir_pro_import)

                kostra_shp_layer_path = processing.run("native:multiparttosingleparts",
                                                       {'INPUT': kostra_shp_layer,
                                                        'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                osev_layer = kostra_shp_layer_path
                # kopirovani trajektorie do importu
                shutil.copytree(
                    umisteni_navrhu_dir + f"\\psp_vyhovuje{id_cele}\\trajektorie",
                    dir_pro_import,
                    dirs_exist_ok=True)
                # QgsProject.instance().addMapLayer(kostra_shp_layer)

                prevod_id_na_jmeno(osev_layer)
                #QgsProject.instance().addMapLayer(osev_layer)

                dopocteno = True

            else:
                self.iface.messageBar().pushMessage("Nelze provést import",
                                                    "Nejsou vyplněny všechny hodnoty PLODINY_ID",
                                                    level=Qgis.MessageLevel.Critical)

            if dopocteno:

                self.dlg.progressBar_vypocet.setFormat("Připraveno")
                self.dlg.progressBar_vypocet.setValue(40)
                
                from collections import defaultdict
                
                #1. Buffer -0.001 m
               
                buffer1 = processing.run("native:buffer", {
                
                    'INPUT': osev_layer,
                
                    'DISTANCE': -0.001,
                
                    'SEGMENTS': 5,
                
                    'END_CAP_STYLE': 1,
                
                    'JOIN_STYLE': 1,
                
                    'MITER_LIMIT': 2,
                
                    'DISSOLVE': False,
                
                    'SEPARATE_DISJOINT': False,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                
                singleparts0 = processing.run("native:multiparttosingleparts", {
                
                    'INPUT': buffer1,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                
                #odstranění odřezků
                singleparts0.startEditing()
                for feat in singleparts0.getFeatures():
                    if feat.geometry().area() < 1:
                        singleparts0.deleteFeature(feat.id())
                singleparts0.commitChanges()
                
                 
                # 2. Buffer +0.001 m
                
                osev_layer = processing.run("native:buffer", {
                
                    'INPUT': singleparts0,
                
                    'DISTANCE': 0.001,
                
                    'SEGMENTS': 5,
                
                    'END_CAP_STYLE': 1,
                
                    'JOIN_STYLE': 1,
                
                    'MITER_LIMIT': 2,
                
                    'DISSOLVE': False,
                
                    'SEPARATE_DISJOINT': False,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                
                 
                # Přidej pole VYMZAKRES, pokud neexistuje
                if 'VYMZAKRES' not in [field.name() for field in osev_layer.fields()]:
                    osev_layer.dataProvider().addAttributes([QgsField('VYMZAKRES', QVariant.Double, len=10, prec=4)])
                    osev_layer.updateFields()
                 
                # Připrav proměnné
                id_map = defaultdict(list)
                null_ids = []
                zero_ids = []
                max_id = 0
                 
                # 1. Získání maxima ZAKRES_ID a detekce duplicit, NULL, 0
                for feature in osev_layer.getFeatures():
                    zakres_id_raw = feature['ZAKRES_ID']
                    if zakres_id_raw is None or zakres_id_raw == NULL or str(zakres_id_raw).strip() == '':
                        null_ids.append(feature.id())
                        continue        
                    
                    try:
                        zakres_id = int(str(zakres_id_raw)) 
                    except ValueError:
                        print(f"Přeskočena nečíselná hodnota: {zakres_id_raw}")
                        continue
                    
                    if zakres_id == 0:
                        zero_ids.append(feature.id())
                        continue
                 
                 
                    id_map[zakres_id].append(feature.id())
                    if zakres_id > max_id:
                        max_id = zakres_id
                 
                print(id_map)
                duplicates = {k: v for k, v in id_map.items() if len(v) > 1}
                 
                osev_layer.startEditing()     
                
                # 2. Oprava duplicitních hodnot
                offset = 1
                for dup_id, feat_ids in duplicates.items():
                    for i, fid in enumerate(feat_ids):
                        if i == 0:
                            continue
                        new_id = max_id + offset
                        offset += 1
                        feature = osev_layer.getFeature(fid)
                        feature['ZAKRES_ID'] = str(new_id)
                        osev_layer.updateFeature(feature)
             
                print(f"Upraveno {offset - 1} duplicitních hodnot.")
             
                # 3. Náhrada NULL hodnot
                for fid in null_ids:
                    new_id = max_id + offset
                    offset += 1
                    feature = osev_layer.getFeature(fid)
                    feature['ZAKRES_ID'] = str(new_id)
                    osev_layer.updateFeature(feature)
             
                print(f"Nahrazeno {len(null_ids)} NULL hodnot v 'ZAKRES_ID'.")
             
                # 4. Náhrada hodnot ZAKRES_ID == 0
                for fid in zero_ids:
                    new_id = max_id + offset
                    offset += 1
                    feature = osev_layer.getFeature(fid)
                    feature['ZAKRES_ID'] = str(new_id)
                    osev_layer.updateFeature(feature)
             
                print(f"Nahrazeno {len(zero_ids)} nulových hodnot v 'ZAKRES_ID'.")
                
                osev_layer.commitChanges()  
             

                
                
                

                # Načtení vrstvy do projektu
                input_layer = osev_layer
                if not input_layer.isValid():
                    print("Chyba při načítání vrstvy!")
                    exit()

                # Vytvoření prostorového indexu pro rychlé vyhledávání sousedních prvků
                spatial_index = QgsSpatialIndex(input_layer.getFeatures())

                # Sloupec, který nás zajímá
                attribute_field = "PLOD_ID"
                distance_threshold = 0.1  # Maximální vzdálenost v metrech

                # Seznam nových prvků pro novou vrstvu
                new_features = []
                
                #seznam ZAKRES_ID pro pozdější mazání
                seznam_spojenych = []

                # Projdi všechny prvky ve vrstvě
                for feature in input_layer.getFeatures():
                    geom = feature.geometry()

                    # Filtrování prvků podle hodnoty PLOD_ID
                    attribute_value = feature[attribute_field]

                    # Najdi možné sousedy pomocí prostorového indexu
                    neighbors_ids = spatial_index.intersects(geom.boundingBox())

                    # Iterace přes sousední prvky
                    for neighbor_id in neighbors_ids:
                        neighbor_feature = input_layer.getFeature(neighbor_id)
                        neighbor_geom = neighbor_feature.geometry()

                        # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                        if feature.id() != neighbor_feature.id() and neighbor_feature[
                            attribute_field] == attribute_value:
                            # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                            if geom.distance(neighbor_geom) <= distance_threshold:
                                # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                if feature not in new_features:
                                    new_features.append(feature)
                                    seznam_spojenych.append(feature["ZAKRES_ID"])
                                if neighbor_feature not in new_features:
                                    new_features.append(neighbor_feature)
                                    seznam_spojenych.append(neighbor_feature["ZAKRES_ID"])

                # Vytvoření nové vrstvy pro sousední prvky
                output_layer = QgsVectorLayer("Polygon?crs=" + input_layer.crs().authid(), "Sousedi_PLOD_ID",
                                              "memory")
                output_layer_data_provider = output_layer.dataProvider()

                # Přidej stejné atributy jako v původní vrstvě
                output_layer_data_provider.addAttributes(input_layer.fields())
                output_layer.updateFields()

                # Přidání nových prvků do vrstvy
                output_layer_data_provider.addFeatures(new_features)

                # Přidání nové vrstvy do projektu
                #QgsProject.instance().addMapLayer(output_layer)

                if len(new_features) > 0:
                    output_layer_bufferminus = processing.run("native:buffer", {'INPUT':output_layer,
                                                     'DISTANCE':-0.001,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    output_layer_bufferplus = processing.run("native:buffer", {'INPUT':output_layer_bufferminus,
                                                     'DISTANCE':0.101,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                
                    # Použití nástroje native:dissolve k rozpuštění vrstvy
                    dissolved_layer = processing.run("native:dissolve", {
                        'INPUT': output_layer_bufferplus,
                        'FIELD': ["PLOD_ID"],  # Rozpustí všechny prvky bez rozdělení podle atributů
                        'SEPARATE_DISJOINT': False,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    })['OUTPUT']
                    
                    dissolved_layer = processing.run("native:buffer", {'INPUT':dissolved_layer,
                                                     'DISTANCE':-0.1,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    

                    # Přidání rozpuštěné vrstvy do projektu

                    dissolved_layer.setName("spojene")
                    #QgsProject.instance().addMapLayer(dissolved_layer)

                    # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                    multipart_result = processing.run("native:multiparttosingleparts", {
                        'INPUT': dissolved_layer,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    })

                    # Přidání vrstvy s rozdělenými prvky do projektu
                    multipart_layer = multipart_result['OUTPUT']
                    multipart_layer.setName("spsousede")
                    #QgsProject.instance().addMapLayer(multipart_layer)

                    multipart_layer_plus = processing.run("native:buffer",
                                   {'INPUT': multipart_layer, 'DISTANCE': 0.1,
                                    'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                    'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    multipart_layer = processing.run("native:buffer",
                                           {'INPUT': multipart_layer_plus, 'DISTANCE': -0.1,
                                            'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                                            'DISSOLVE': False, 'SEPARATE_DISJOINT': False,
                                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]


                    # Vytvoření bufferu kolem vrstvy spsousede pomocí nástroje native:buffer
                    buffer_result = processing.run("native:buffer", {
                        'INPUT': multipart_layer,
                        'DISTANCE': -1,  # Vzdálenost bufferu (negativní hodnota pro vnitřní buffer) (proč -21??)
                        'SEGMENTS': 5,  # Počet segmentů pro zaoblení rohů
                        'END_CAP_STYLE': 0,  # Styl zakončení (0 = ploché zakončení)
                        'JOIN_STYLE': 0,  # Styl spojení hran (0 = zaoblené rohy)
                        'MITER_LIMIT': 2,
                        'DISSOLVE': False,  # Není třeba rozpouštět buffer
                        'SEPARATE_DISJOINT': False,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    })

                    # Přidání vrstvy s bufferem do projektu
                    buffer_layer = buffer_result['OUTPUT']
                    buffer_layer.setName("sbuffer")
                    #QgsProject.instance().addMapLayer(buffer_layer)



                    # Provedení výběru prvků z vrstvy "spsousede" pomocí vrstvy "sbuffer"
                    processing.run("native:selectbylocation", {
                        'INPUT': multipart_layer,
                        'PREDICATE': [0],  # Předikát 0 = 'intersects' (prvky, které se překrývají)
                        'INTERSECT': buffer_layer,
                        'METHOD': 0  # Výběrová metoda 0 = 'create new selection'
                    })

                    # Získání vybraných prvků
                    selected_features = multipart_layer.selectedFeatures()

                    # Vytvoření nové vrstvy "spojpasy" pro vybrané prvky
                    spojpasy_layer = QgsVectorLayer("Polygon?crs=" + multipart_layer.crs().authid(), "spojpasy", "memory")
                    spojpasy_layer_data_provider = spojpasy_layer.dataProvider()

                    # Přidání nového atributu "SPOJPASY"
                    spojpasy_layer_data_provider.addAttributes([QgsField("SPOJPASY", QVariant.String),
                                                                QgsField("SPOJPASYID", QVariant.String),
                                                                QgsField("CTVEREC", QVariant.String),
                                                                QgsField("ZKOD", QVariant.String),
                                                                QgsField("PLOD_ID", QVariant.String),
                                                                QgsField("ZAKRES_ID", QVariant.String),
                                                                QgsField("VYMZAKRES", QVariant.Double, len=10, prec=4),
                                                                QgsField("JI", QVariant.String),
                                                                QgsField("PLODINA_AK", QVariant.String)   
                                                                ])
                    spojpasy_layer.updateFields()
    
                    # Přidání vybraných prvků s novým atributem
                    fn = 0
                    for feature in selected_features:
                        new_feature = QgsFeature()
                        new_feature.setGeometry(feature.geometry())
                        new_feature.setAttributes(["ANO", str(fn)])  # Nastavení hodnoty atributu "SPOJPASY"
                        spojpasy_layer_data_provider.addFeature(new_feature)
                        fn = fn + 1

                    # Přidání vrstvy "spojpasy" do projektu
                    #QgsProject.instance().addMapLayer(spojpasy_layer)
                    print(
                        "Skript úspěšně dokončen, vrstvy 'Sousedi_PLOD_ID', 'spojene', 'spsousede', 'sbuffer' a 'spojpasy' byly přidány do projektu.")
                    #QgsProject.instance().addMapLayer(spojpasy_layer)

                    print(spojpasy_layer.featureCount())
                    if spojpasy_layer.featureCount() > 0:

                        dpb_vyhovuje = QgsVectorLayer(umisteni_navrhu_dir + f"\\psp_vyhovuje{id_cele}\\DPB_vyhovuje{id_cele}.shp", "DPB vyhovuje", "ogr")
                        spojene_path = umisteni_navrhu_dir + f"\\psp_vyhovuje{id_cele}\\dalsi_vrstvy\\spojene{id_cele}.shp"
                        processing.run("native:clip", {'INPUT': spojpasy_layer, 'OVERLAY': dpb_vyhovuje,
                                                                        'OUTPUT': spojene_path})
                        spojene_vrstva = QgsVectorLayer(spojene_path, "spojené pásy", "ogr")

                        #QgsProject.instance().addMapLayer(spojene_vrstva)
                        #QgsProject.instance().addMapLayer(neo_ve_spojene)
                        
                        buffer_spojene_vrstva = processing.run("native:buffer", {
                            'INPUT': spojene_vrstva,
                            'DISTANCE': -2,  # Vzdálenost bufferu (negativní hodnota pro vnitřní buffer)
                            'SEGMENTS': 5,  # Počet segmentů pro zaoblení rohů
                            'END_CAP_STYLE': 0,  # Styl zakončení (0 = ploché zakončení)
                            'JOIN_STYLE': 0,  # Styl spojení hran (0 = zaoblené rohy)
                            'MITER_LIMIT': 2,
                            'DISSOLVE': False,  # Není třeba rozpouštět buffer
                            'SEPARATE_DISJOINT': False,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })["OUTPUT"]
                        
                        #tvorba slovniku id_att obsahujici hodnoty atributu pro jednotlive spojene prvky
                        id_att = {}
                        for feat_bsv in buffer_spojene_vrstva.getFeatures():
                            if feat_bsv["SPOJPASYID"] is None or feat_bsv["SPOJPASYID"] == NULL:
                                continue
                            idcko = str(feat_bsv["SPOJPASYID"])
                            if not feat_bsv.geometry() or feat_bsv.geometry().isEmpty():
                                continue

                            buffer_spojene_vrstva.select(feat_bsv.id())
                            buffer_spojene_vrstva_selected = processing.run("native:saveselectedfeatures", {'INPUT': buffer_spojene_vrstva, 'OUTPUT': 'memory:'})['OUTPUT']
                            buffer_spojene_vrstva.removeSelection()
                            
                            processing.run("native:selectbylocation", {
                                'INPUT':input_layer,
                                'PREDICATE':[0],
                                'INTERSECT':buffer_spojene_vrstva_selected,
                                'METHOD':0})["OUTPUT"]
                        
                            if input_layer.selectedFeatureCount() > 0:
                                for sf in input_layer.selectedFeatures():
                                    id_att[idcko] = [sf["CTVEREC"], sf["ZKOD"], sf["PLOD_ID"], sf["JI"], sf["PLODINA_AK"]]
                                    break    
                            input_layer.removeSelection()

                        # fallback: pokud -2 m buffer nic nenamapoval, zkus puvodni geometrii spojeneho pasu
                        for feat in spojene_vrstva.getFeatures():
                            if feat["SPOJPASYID"] is None or feat["SPOJPASYID"] == NULL:
                                continue
                            idcko = str(feat["SPOJPASYID"])
                            if idcko in id_att:
                                continue
                            if not feat.geometry() or feat.geometry().isEmpty():
                                continue
                            spojene_vrstva.select(feat.id())
                            spojene_sel = processing.run("native:saveselectedfeatures", {'INPUT': spojene_vrstva, 'OUTPUT': 'memory:'})['OUTPUT']
                            spojene_vrstva.removeSelection()
                            processing.run("native:selectbylocation", {
                                'INPUT': input_layer,
                                'PREDICATE': [0],
                                'INTERSECT': spojene_sel,
                                'METHOD': 0})["OUTPUT"]
                            if input_layer.selectedFeatureCount() > 0:
                                for sf in input_layer.selectedFeatures():
                                    id_att[idcko] = [sf["CTVEREC"], sf["ZKOD"], sf["PLOD_ID"], sf["JI"], sf["PLODINA_AK"]]
                                    break
                            input_layer.removeSelection()
                                
                        spojene_vrstva.startEditing()
                        for feat in spojene_vrstva.getFeatures():
                            if feat["SPOJPASYID"] is None or feat["SPOJPASYID"] == NULL:
                                feat["VYMZAKRES"] = round((feat.geometry().area()/10000),4)
                                spojene_vrstva.updateFeature(feat)
                                continue
                            idcko = str(feat["SPOJPASYID"])
                            feat["VYMZAKRES"] = round((feat.geometry().area()/10000),4)
                            if idcko in id_att:
                                ct, zk, pid, ji, pa = id_att[idcko]
                                feat["CTVEREC"] = ct
                                feat["ZKOD"] = zk 
                                feat["PLOD_ID"] = pid
                                feat["JI"] = ji
                                feat["PLODINA_AK"] = pa
                            spojene_vrstva.updateFeature(feat)
                        spojene_vrstva.commitChanges()
                        #QgsProject.instance().addMapLayer(spojene_vrstva)
                        

                        point_layer_sv = processing.run("native:pointonsurface", {
                            'INPUT': spojene_vrstva,
                            'ALL_PARTS': False,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })['OUTPUT']
                        
                        spojene_vrstva.startEditing()
                        for feature in spojene_vrstva.getFeatures():
                            geom = feature.geometry()
                            for feature_point in point_layer_sv.getFeatures():               
                                if geom.intersects(feature_point.geometry()):                              
                                    point_geom = feature_point.geometry().asPoint()
                                    x_coord = str(int(point_geom.x()))
                                    y_coord = str(int(point_geom.y()))
                                    x_last5 = re.sub(r'\D', '', x_coord)[-5:]
                                    y_last5 = re.sub(r'\D', '', y_coord)[-5:]
                                    zakres_id = x_last5 + y_last5
                                    feature.setAttribute("ZAKRES_ID", zakres_id)
                                    spojene_vrstva.updateFeature(feature)
                        spojene_vrstva.commitChanges()
                                    
                        field_names_vrstva = spojene_vrstva.fields().names()
                        rozdil_vrstva = []
                        for element in field_names_vrstva:
                            if (element in ["CTVEREC", "ZKOD", "PLOD_ID", "ZAKRES_ID", "JI", "VYMZAKRES", "PLODINA_AK"]) == False:
                                rozdil_vrstva.append(element)
                        spojene_vrstva.startEditing()
                        fields_to_delete = []
                        for fieldname_to_delete in rozdil_vrstva:
                            fieldindex_to_delete = spojene_vrstva.fields().indexFromName(fieldname_to_delete)
                            if fieldindex_to_delete == -1:
                                continue
                            fields_to_delete.append(fieldindex_to_delete)
                        spojene_vrstva.dataProvider().deleteAttributes(fields_to_delete)
                        spojene_vrstva.updateFields()
                        spojene_vrstva.commitChanges()
                        
                        #smazat konretni zemědělské pozemky
                        features_to_delete = []
                        
                        # Procházíme všechny prvky ve vrstvě a vybíráme ty, které mají hodnotu v seznamu
                        for feature in input_layer.getFeatures():
                            if feature['ZAKRES_ID'] in seznam_spojenych:
                                features_to_delete.append(feature.id())
                        # Zahájení úpravy vrstvy
                        input_layer.startEditing()
                        input_layer.deleteFeatures(features_to_delete)
                        input_layer.commitChanges()
                        
                        vrstva_plan_osevu = processing.run("native:mergevectorlayers", {'LAYERS':[input_layer, spojene_vrstva],
                                                                                        'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),
                                                                                        'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        
                        
                else:        
                    vrstva_plan_osevu = input_layer
                    
                vrstva_plan_osevu_single = processing.run("native:multiparttosingleparts", {'INPUT':vrstva_plan_osevu,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                
                
    
                
                #odstraněni cancourku
                 
                # 1. Buffer -0.001 m
                
                buffer1 = processing.run("native:buffer", {
                
                    'INPUT': vrstva_plan_osevu_single,
                
                    'DISTANCE': -0.001,
                
                    'SEGMENTS': 5,
                
                    'END_CAP_STYLE': 1,
                
                    'JOIN_STYLE': 1,
                
                    'MITER_LIMIT': 2,
                
                    'DISSOLVE': False,
                
                    'SEPARATE_DISJOINT': False,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                 
                # 2. Buffer +0.001 m
                
                buffer2 = processing.run("native:buffer", {
                
                    'INPUT': buffer1,
                
                    'DISTANCE': 0.001,
                
                    'SEGMENTS': 5,
                
                    'END_CAP_STYLE': 1,
                
                    'JOIN_STYLE': 1,
                
                    'MITER_LIMIT': 2,
                
                    'DISSOLVE': False,
                
                    'SEPARATE_DISJOINT': False,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                 
                # 3. Multipart na singlepart
                
                singleparts = processing.run("native:multiparttosingleparts", {
                
                    'INPUT': buffer2,
                
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                
                })['OUTPUT']
                 
                # 4. Přidání atributu "kontrolavym" a výpočet plochy
                
                layer = singleparts
                
                layer.startEditing()
                
                layer.dataProvider().addAttributes([QgsField('kontrolavym', QVariant.Double, 'double', 20, 9)])
                
                layer.updateFields()
                 
                expression = QgsExpression('round($area, 9)')
                
                context = QgsExpressionContext()
                
                context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(layer))
                 
                for feature in layer.getFeatures():
                
                    context.setFeature(feature)
                
                    value = expression.evaluate(context)
                
                    layer.changeAttributeValue(feature.id(), layer.fields().indexFromName('kontrolavym'), value)
                 
                layer.commitChanges()
                 
                # 5. Odstranění duplicit podle ZAKRES_ID, výběr prvku s nejvyšší kontrolavym
                
                zakres_idx = layer.fields().indexFromName('ZAKRES_ID')
                
                kontrola_idx = layer.fields().indexFromName('kontrolavym')
                 
                best_features = {}
                
                for feature in layer.getFeatures():
                
                    zakres_id = feature['ZAKRES_ID']
                
                    vym = feature['kontrolavym']
                
                    if zakres_id not in best_features or vym > best_features[zakres_id]['kontrolavym']:
                
                        best_features[zakres_id] = feature
                 
                # 6. Vytvoření nové paměťové vrstvy a naplnění nejlepšími prvky
                
                crs = layer.crs().authid()
                
                vrstva_plan_osevu_single = QgsVectorLayer(f"Polygon?crs={crs}", "Vybrané_prvky", "memory")
                
                final_layer_data = vrstva_plan_osevu_single.dataProvider()
                
                final_layer_data.addAttributes(layer.fields())
                
                vrstva_plan_osevu_single.updateFields()
                 
                vrstva_plan_osevu_single.startEditing()
                
                for feat in best_features.values():
                
                    vrstva_plan_osevu_single.addFeature(feat)
                
                vrstva_plan_osevu_single.commitChanges()
                 
                # 7. Přidání vrstvy do projektu
                
                #QgsProject.instance().addMapLayer(vrstva_plan_osevu_single)
                 


                vrstva_plan_osevu_single.startEditing()
                fields_to_delete = []
                for fieldname_to_delete in ["kontrolavym"]:
                    fieldindex_to_delete = vrstva_plan_osevu_single.fields().indexFromName(fieldname_to_delete)
                    if fieldindex_to_delete == -1:
                        continue
                    fields_to_delete.append(fieldindex_to_delete)
                vrstva_plan_osevu_single.dataProvider().deleteAttributes(fields_to_delete)
                vrstva_plan_osevu_single.updateFields()
                vrstva_plan_osevu_single.commitChanges()

 
               
                vrstva_plan_osevu_single.startEditing()
                # 5. Výpočet výměr v hektarech
                for feature in vrstva_plan_osevu_single.getFeatures():
                    geom = feature.geometry()
                    if not geom or geom.isEmpty():
                        continue
                    area_ha = round(geom.area() / 10000, 4)
                    feature['VYMZAKRES'] = area_ha
                    vrstva_plan_osevu_single.updateFeature(feature)
                vrstva_plan_osevu_single.commitChanges()  
                print("Přepočteny výměry v hektarech do atributu 'VYMZAKRES'.")
                
                # 6. Smazání prvků bez výměry
                remove_ids = []
                for feature in vrstva_plan_osevu_single.getFeatures():
                    if feature['VYMZAKRES'] is None:
                        remove_ids.append(feature.id())
             
                if remove_ids:
                    vrstva_plan_osevu_single.dataProvider().deleteFeatures(remove_ids)
                    print(f"Odstraněno {len(remove_ids)} prvků s prázdnou výměrou.")
                else:
                    print("Všechny prvky mají výměru.")
                
                
                
                plan_osevu_celek_path = dir_pro_import + "\\plan_osevu_psp.shp" 
                options = QgsVectorFileWriter.SaveVectorOptions()
                options.driverName = "ESRI Shapefile"
                options.fileEncoding = "windows-1250"
                QgsVectorFileWriter.writeAsVectorFormatV3(
                    vrstva_plan_osevu_single,
                    plan_osevu_celek_path,
                    QgsCoordinateTransformContext(),
                    options)

                self.dlg.progressBar_vypocet.setFormat("Tisk")
                self.dlg.progressBar_vypocet.setValue(70)
                
                response = QMessageBox.information(None,
                                                   "Start",
                                                   "Připraveno k výpočtu.\nKlikněte na OK pro pokračování",
                                                   QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
                if response == QMessageBox.StandardButton.Ok:
                    print("tisk")
                    self.tisk_reportu()
                elif response == QMessageBox.StandardButton.Cancel:
                    print("Výpočet byl zastaven.")

                    

                self.dlg.progressBar_vypocet.setFormat("Hotovo")
                self.dlg.progressBar_vypocet.setValue(100)


        else:
            self.iface.messageBar().pushMessage("Nelze provést import",
                                                "Neplatná cesta ke složce ve které je návrh (Navrh_psp_[id])",
                                                level=Qgis.MessageLevel.Critical)


    def download_dmr(self):

        cesta = self.dlg.lineEdit_kostraprojektu.text()
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(cesta):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)


        elif os.path.isdir(cesta):

            def check_layer_validity(layer, layer_name):
                if not layer.isValid():
                    print(f"Vrstva {layer_name} není platná.")


            output_folder = cesta + "\\DMR_DSO_NEO\\"  # Cesta k adresáři pro uložení
            if os.path.isdir(output_folder) == False:
                os.mkdir(output_folder)

            # Načtení vrstvy ořezu
            polygon_layer = self.dlg.comboBox_maska.currentData()

            # priptavit pro orezy
            maska_dso = processing.run("native:buffer",
                                           {'INPUT': polygon_layer, 'DISTANCE': 60, 'SEGMENTS': 5,
                                            'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2,
                                            'DISSOLVE': True,
                                            'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            # QgsProject.instance().addMapLayer(maska_dso_neo)

            extent = polygon_layer.extent()
            sirka = int(extent.xMaximum() - extent.xMinimum()) + 200
            vyska = int(extent.yMaximum() - extent.yMinimum()) + 200
            xmin = int(extent.xMinimum()) - 100
            ymin = int(extent.yMinimum()) - 100
            if xmin % 2 != 0:
                xmin = xmin - 1
            if ymin % 2 != 0:
                ymin = ymin - 1
            xmax = xmin + sirka
            ymax = ymin + vyska
            if xmax % 2 != 0:
                xmax = xmax + 1
            if ymax % 2 != 0:
                ymax = ymax + 1
            bbox = f"{xmin},{ymin},{xmax},{ymax}"
            print(bbox)

            hrana = 5000 #m

            xpocet = int(sirka / hrana) + 1
            ypocet = int(vyska / hrana) + 1

            list_of_tifs = []
            list_of_dwnld = []
            docasne_tiff_dir = None
            poradi = 0
            for xn in range(xpocet):
                for yn in range(ypocet):
                    xmin0 = xmin + xn * hrana
                    xmax0 = xmin0 + hrana
                    if xmax0 > xmax:
                        xmax0 = xmax
                    ymin0 = ymin + yn * hrana
                    ymax0 = ymin0 + hrana
                    if ymax0 > ymax:
                        ymax0 = ymax
                    bbox0 = f"{xmin0},{ymin0},{xmax0},{ymax0}"

                    coords = [(xmin0, ymin0), (xmin0, ymax0), (xmax0, ymax0), (xmax0, ymin0), (xmin0, ymin0)]
                    polygon = QgsGeometry.fromPolygonXY([[QgsPointXY(pair[0], pair[1]) for pair in coords]])

                    lyr_polygon = QgsVectorLayer("Polygon?crs=epsg:5514", "polygon", "memory")
                    lyr_polygon.startEditing()
                    pr_lyr_polygon = lyr_polygon.dataProvider()
                    seg = QgsFeature()
                    seg.setGeometry(polygon)
                    pr_lyr_polygon.addFeature(seg)
                    lyr_polygon.updateExtents()
                    lyr_polygon.commitChanges()
                    QgsProject.instance().addMapLayer(lyr_polygon)

                    prunik = processing.run("native:clip", {
                        'INPUT': polygon_layer,
                        'OVERLAY': lyr_polygon, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    QgsProject.instance().removeMapLayer(lyr_polygon.id())

                    if prunik.featureCount() > 0:

                        # Výpočet velikosti obrázku (šířka a výška v pixelech) na základě rozsahu vrstvy
                        # Tato část předpokládá, že chcete 1 pixel na 1 metr (můžeš to upravit podle potřeby)
                        width_in_meters = int(xmax0 - xmin0)
                        height_in_meters = int(ymax0 - ymin0)

                        # Velikost obrázku (počet pixelů)
                        size_x = int(width_in_meters / 2)
                        size_y = int(height_in_meters / 2)
                        size = f"{size_x},{size_y}"

                        # API URL pro stahování dat DMR5G
                        export_url = "https://ags.cuzk.cz/arcgis2/rest/services/dmr5g/ImageServer/exportImage"
                        # Parametry pro API požadavek
                        params = {
                            "bbox": bbox0,
                            "imageSR": 5514,
                            "bboxSR": 5514,
                            "size": size,  # Velikost výstupního obrázku
                            "format": "tiff",
                            "f": "image"
                        }
                        response = requests.get(export_url, params=params, timeout=30)
                        if response.status_code != 200:
                            self.iface.messageBar().pushMessage("Chyba stahování",
                                                                "Nepodařilo se stáhnout tiff s DMR5G",
                                                                level=Qgis.MessageLevel.Critical)

                        else:
                            # Získání URL staženého obrázku
                            url = response.url
                            stazeno = False
                            try:
                                r = requests.get(url, allow_redirects=True, timeout=30)
                                stazeno = True
                            except requests.ConnectionError as e:
                                self.iface.messageBar().pushMessage("Chyba spojení",
                                                                    str(e),
                                                                    level=Qgis.MessageLevel.Critical)

                            if stazeno:
                                output_folder_2 = output_folder + "\\docasne_tiff"
                                docasne_tiff_dir = output_folder_2
                                if os.path.isdir(output_folder_2) == False:
                                    os.mkdir(output_folder_2)
                                output_path = os.path.join(output_folder_2, f"dmr5g_output_{poradi}.tif")

                                with open(output_path, 'wb') as f:
                                    f.write(r.content)

                                # vezme raster a uloží ho s CRS 5514
                                dmr5g_prep = QgsRasterLayer(output_path, "dmr", "gdal")
                                crs = dmr5g_prep.crs()
                                crs.createFromId(5514)
                                dmr5g_prep.setCrs(crs)

                                file_name = output_path[:-4] + "_x.tif"
                                file_writer = QgsRasterFileWriter(file_name)
                                pipe = QgsRasterPipe()
                                provider = dmr5g_prep.dataProvider()
                                if not pipe.set(provider.clone()):
                                    print("nejde setnout pipe provider")

                                file_writer.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(),
                                                        provider.crs())

                                # Uvolnit GDAL zámek na staženém TIF (jinak Windows nesmaže docasne_tiff).
                                del provider
                                del pipe
                                del file_writer
                                del dmr5g_prep

                                list_of_dwnld.append(output_path)
                                list_of_tifs.append(file_name)

                                # Přidání vrstev do projektu
                                # QgsProject.instance().addMapLayer(polygon_layer)
                                # QgsProject.instance().addMapLayer(raster_layer)

                                print(f"Data byla úspěšně stažena: {output_path}")
                                poradi = poradi + 1
                                
            def symbology_pro_rastr(rlayer):

                # Získání statistik rastrové vrstvy
                stats = rlayer.dataProvider().bandStatistics(1, QgsRasterBandStats.Stats.All)
                min_val = stats.minimumValue
                max_val = stats.maximumValue
                print(f"Min: {min_val}, Max: {max_val}")
                # Kontrola rozsahu hodnot
                if min_val == max_val:
                    print("Minimální a maximální hodnota jsou stejné. Nelze vytvořit barevnou škálu.")   
                    return 
                # Vytvoření barevné škály viridis/turbo
                viridis = cm.get_cmap('turbo', 256)
                color_ramp_items = []
                steps = 10  # Počet kroků v barevné škále
                for i in range(steps + 1):
                    value = min_val + (max_val - min_val) * (i / steps)
                    color = viridis(i / steps)
                    qcolor = QColor.fromRgbF(*color[:3])  # Pouze RGB
                    color_ramp_items.append(QgsColorRampShader.ColorRampItem(value, qcolor, f"{value:.2f}"))
                # Nastavení shaderu
                fnc = QgsColorRampShader()
                fnc.setColorRampType(QgsColorRampShader.Type.Interpolated)
                fnc.setColorRampItemList(color_ramp_items)
                # Použití shaderu na rastrovou vrstvu         
                shader = QgsRasterShader()        
                shader.setRasterShaderFunction(fnc)           
                renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)            
                # Explicitní nastavení rozsahu hodnot v rendereru           
                renderer.setClassificationMin(min_val)  
                renderer.setClassificationMax(max_val)
                rlayer.setRenderer(renderer)  
                # Obnovení vrstvy
                rlayer.triggerRepaint()    
                # Nastavení vlastností legendy (gradient a rozsah hodnot) 
                rlayer.setCustomProperty("legend/value_type", "gradient")
                rlayer.setCustomProperty("legend/class_min", min_val)  
                rlayer.setCustomProperty("legend/class_max", max_val)     
                print("Symbologie a legenda úspěšně nastavena.")

            print(list_of_tifs)
            if len(list_of_tifs) > 0:
                counter = 1
                nalezen = False
                while nalezen == False:
                    DMR5G_celek_path = output_folder + f"\\DMR5G_projekt_{counter}.tiff"
                    if not os.path.exists(DMR5G_celek_path):
                        nalezen = True
                    else:
                        counter += 1
                print(DMR5G_celek_path)

                processing.run("gdal:merge", {
                    'INPUT': list_of_tifs, 'PCT': False,
                    'SEPARATE': False, 'NODATA_INPUT': None, 'NODATA_OUTPUT': None, 'OPTIONS': '', 'EXTRA': '',
                    'DATA_TYPE': 5, 'OUTPUT': DMR5G_celek_path})

                DMR5G = QgsRasterLayer(DMR5G_celek_path, f"DMR 5G {counter}", "gdal")
                symbology_pro_rastr(DMR5G)
                QgsProject.instance().addMapLayer(DMR5G)

                layers = QgsProject.instance().layerTreeRoot().children()
                layers_raster = []
                jmena = [l.name() for l in layers]
                jmena = list(dict.fromkeys(jmena))
                for jmeno in jmena:
                    vrstvy = QgsProject.instance().mapLayersByName(jmeno)
                    for vrstva in vrstvy:
                        try:
                            feats = vrstva.getFeatures()
                            for feat in feats:
                                geom = feat.geometry()
                                if geom.type() == QgsWkbTypes.GeometryType.PolygonGeometry:
                                    break
                                elif geom.type() == QgsWkbTypes.GeometryType.LineGeometry:
                                    break
                        except:
                            layers_raster.append(vrstva)
                self.dlg.comboBox_dmt.clear()
                for lyr in layers_raster:
                    self.dlg.comboBox_dmt.addItem(lyr.name() + " (" + lyr.crs().authid() + ")", lyr)

                _smaz_docasne_tiff_slozku(docasne_tiff_dir, list_of_tifs, list_of_dwnld)



            vrstevnice = processing.run("gdal:contour", {'INPUT': DMR5G, 'BAND': 1, 'INTERVAL': 2, 'FIELD_NAME': 'ELEV',
                                                         'CREATE_3D': False, 'IGNORE_NODATA': False, 'NODATA': None,
                                                         'OFFSET': 0, 'EXTRA': '',
                                                         'OUTPUT': output_folder + "\\vrstevnice_prep.shp"})
            
            counter = 1
            nalezen = False
            while nalezen == False:
                vrstevnice_path = output_folder + f"\\vrstevnice_{counter}.shp"
                if not os.path.exists(vrstevnice_path):
                    nalezen = True
                else:
                    counter += 1
            print(vrstevnice_path)
            
            vrstevnice_lyr0 = processing.run("native:clip", {
                'INPUT': vrstevnice["OUTPUT"],
                'OVERLAY': maska_dso, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            processing.run("native:multiparttosingleparts", {'INPUT':vrstevnice_lyr0,
                                                             'OUTPUT':vrstevnice_path})
    
            vrstevnice_lyr = QgsVectorLayer(vrstevnice_path, f"Vrstevnice_{counter}", "ogr")
            symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
            symbol.setColor(QColor("brown"))
            symbol.setWidth(0.12)
            renderer = QgsSingleSymbolRenderer(symbol)
            vrstevnice_lyr.setRenderer(renderer)
            vrstevnice_lyr.triggerRepaint()
            QgsProject.instance().addMapLayer(vrstevnice_lyr)




        else:
            self.iface.messageBar().pushMessage("Chybná cesta ke složce",
                                                "Uvedená cesta nevede ke složce",
                                                level=Qgis.MessageLevel.Critical)


    def download_wfs(self):

        cesta = self.dlg.lineEdit_kostraprojektu.text()
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(cesta):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

        elif os.path.isdir(cesta):

            def check_layer_validity(layer, layer_name):
                if not layer.isValid():
                    print(f"Vrstva {layer_name} není platná.")
                    raise SystemExit(1)

            output_folder = cesta + "\\DMR_DSO_NEO\\"  # Cesta k adresáři pro uložení
            if os.path.isdir(output_folder) == False:
                os.mkdir(output_folder)

            # Načtení vrstvy ořezu
            polygon_layer = self.dlg.comboBox_maska.currentData()

            # priptavit pro orezy
            maska_dso = processing.run("native:buffer",
                                       {'INPUT': polygon_layer, 'DISTANCE': 60, 'SEGMENTS': 5,
                                        'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2,
                                        'DISSOLVE': True,
                                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            # QgsProject.instance().addMapLayer(maska_dso_neo)

            extent = polygon_layer.extent()
            sirka = int(extent.xMaximum() - extent.xMinimum()) + 200
            vyska = int(extent.yMaximum() - extent.yMinimum()) + 200
            xmin = int(extent.xMinimum()) - 100
            ymin = int(extent.yMinimum()) - 100
            if xmin % 2 != 0:
                xmin = xmin - 1
            if ymin % 2 != 0:
                ymin = ymin - 1
            xmax = xmin + sirka
            ymax = ymin + vyska
            if xmax % 2 != 0:
                xmax = xmax + 1
            if ymax % 2 != 0:
                ymax = ymax + 1
            bbox = f"{xmin},{ymin},{xmax},{ymax}"
            print(bbox)


            # stahnout DSO
            dso_bool = False
            try:
                uri = "https://iprod.vumop.cz/wfs/dso.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:dso5&bbox=" + bbox
                dso_vlayer = QgsVectorLayer(uri, "DSO5ha", "ogr")

                crs = dso_vlayer.crs()
                crs.createFromId(5514)
                dso_vlayer.setCrs(crs)

                dso_bool = True
                # QgsProject.instance().addMapLayer(dso_vlayer)

            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu DSO 5 ha z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
            if dso_bool:
                counter = 1
                nalezen = False
                while nalezen == False:
                    path_dso_vlayer = output_folder + f"\\DSO5ha_{counter}.shp"
                    if not os.path.exists(path_dso_vlayer):
                        nalezen = True
                    else:
                        counter += 1

                DSO_layer = processing.run("native:clip", {
                    'INPUT': dso_vlayer,
                    'OVERLAY': maska_dso, 'OUTPUT': path_dso_vlayer})
                DSO_layer = QgsVectorLayer(path_dso_vlayer, f"DSO 5 ha_{counter}", "ogr")
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("#2e40e0"))
                symbol.setWidth(0.36)
                renderer = QgsSingleSymbolRenderer(symbol)
                DSO_layer.setRenderer(renderer)
                DSO_layer.triggerRepaint()


            neo_bool = False
            try:
                uri = "https://iprod.vumop.cz/wfs/neo.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:neo&bbox=" + bbox
                neo_vlayer = QgsVectorLayer(uri, "neo", "ogr")

                crs = neo_vlayer.crs()
                crs.createFromId(5514)
                neo_vlayer.setCrs(crs)

                neo_bool = True

                neo_vlayer = processing.run("native:fixgeometries",
                                            {'INPUT': neo_vlayer, 'METHOD': 1,
                                             'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                # QgsProject.instance().addMapLayer(neo_vlayer)
            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu NEO z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
            if neo_bool:
                counter = 1
                nalezen = False
                while nalezen == False:
                    path_neo_vlayer = output_folder + f"\\NEO_{counter}.shp"
                    if not os.path.exists(path_neo_vlayer):
                        nalezen = True
                    else:
                        counter += 1

                NEO_layer = processing.run("native:clip", {
                    'INPUT': neo_vlayer,
                    'OVERLAY': polygon_layer, 'OUTPUT': path_neo_vlayer})
                NEO_layer = QgsVectorLayer(path_neo_vlayer, f"NEO plochy_{counter}", "ogr")
                NEO_layer.renderer().symbol().setColor(QColor("#56f3b7"))
                NEO_layer.triggerRepaint()


            if neo_bool:
                QgsProject.instance().addMapLayer(NEO_layer)
            if dso_bool:
                QgsProject.instance().addMapLayer(DSO_layer)


        else:
            self.iface.messageBar().pushMessage("Chybná cesta ke složce",
                                                "Uvedená cesta nevede ke složce",
                                                level=Qgis.MessageLevel.Critical)
            
            
    def download_kp(self):

        cesta = self.dlg.lineEdit_kostraprojektu.text()
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(cesta):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

        elif os.path.isdir(cesta):

            def check_layer_validity(layer, layer_name):
                if not layer.isValid():
                    print(f"Vrstva {layer_name} není platná.")
                    raise SystemExit(1)

            output_folder = cesta + "\\DMR_DSO_NEO\\"  # Cesta k adresáři pro uložení
            if os.path.isdir(output_folder) == False:
                os.mkdir(output_folder)


            # Načtení vrstvy ořezu
            polygon_layer = self.dlg.comboBox_maska.currentData()

            # priptavit pro orezy
            extent = polygon_layer.extent()
            sirka = int(extent.xMaximum() - extent.xMinimum()) + 200
            vyska = int(extent.yMaximum() - extent.yMinimum()) + 200
            xmin = int(extent.xMinimum()) - 100
            ymin = int(extent.yMinimum()) - 100
            if xmin % 2 != 0:
                xmin = xmin - 1
            if ymin % 2 != 0:
                ymin = ymin - 1
            xmax = xmin + sirka
            ymax = ymin + vyska
            if xmax % 2 != 0:
                xmax = xmax + 1
            if ymax % 2 != 0:
                ymax = ymax + 1
            bbox = f"{xmin},{ymin},{xmax},{ymax}"
            print(bbox)


            # stahnout DPB
            try:
                uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_DPB_UCINNE&bbox=" + bbox
                dpb_vlayer = QgsVectorLayer(uri, "DPB_wfs", "ogr")
                crs = dpb_vlayer.crs()
                crs.createFromId(5514)
                dpb_vlayer.setCrs(crs)
                
                dpb_vlayer.selectAll()
                dpb_vlayer_i = processing.run("native:saveselectedfeatures", {'INPUT': dpb_vlayer, 'OUTPUT': 'memory:'})['OUTPUT']
                dpb_vlayer.removeSelection()
                
                
                
                dpb_vlayer_i.startEditing()
                dpb_vlayer_provider = dpb_vlayer_i.dataProvider()
                dpb_vlayer_fields = [QgsField("CTVEREC", QVariant.String),
                               QgsField("ZKOD", QVariant.String),
                               QgsField("CTVEREC2", QVariant.String),]
                dpb_vlayer_provider.addAttributes(dpb_vlayer_fields)
                dpb_vlayer_i.updateFields()
                for feat in dpb_vlayer_i.getFeatures():
                    feat["CTVEREC2"] = feat["ctverec"]
                    feat["ZKOD"] = feat["zkracenyKod"]
                    dpb_vlayer_i.updateFeature(feat)
                dpb_vlayer_i.commitChanges()
                
                # Získání indexu atributu podle názvu
                field_index = dpb_vlayer_i.fields().indexOf("ctverec")  
                if field_index != -1:
                    # Smazání atributu
                    dpb_vlayer_i.dataProvider().deleteAttributes([field_index])
                    dpb_vlayer_i.updateFields()  # Aktualizace polí
                
                dpb_vlayer_i.startEditing()
                for feat in dpb_vlayer_i.getFeatures():
                    feat["CTVEREC"] = feat["CTVEREC2"]
                    dpb_vlayer_i.updateFeature(feat)
                dpb_vlayer_i.commitChanges()
                
                # Získání indexu atributu podle názvu
                field_index = dpb_vlayer_i.fields().indexOf("CTVEREC2")  
                if field_index != -1:
                    # Smazání atributu
                    dpb_vlayer_i.dataProvider().deleteAttributes([field_index])
                    dpb_vlayer_i.updateFields()  # Aktualizace polí
                
                dpb_vlayer_i.setName("DPB_účinné")
                QgsProject.instance().addMapLayer(dpb_vlayer_i)

            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu DPB_UCINNE z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)
                
            try:
                uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_EVP_UCINNE&bbox=" + bbox
                evp_vlayer = QgsVectorLayer(uri, "EVP_wfs", "ogr")
                crs = evp_vlayer.crs()
                crs.createFromId(5514)
                evp_vlayer.setCrs(crs)
                if evp_vlayer.featureCount() > 0:
                    QgsProject.instance().addMapLayer(evp_vlayer)

            except:
                self.iface.messageBar().pushMessage("Chybný vstup",
                                                    "Nepovedlo se načíst vrstvu EVP_UCINNE z WFS služby",
                                                    level=Qgis.MessageLevel.Warning)


        else:
            self.iface.messageBar().pushMessage("Chybná cesta ke složce",
                                                "Uvedená cesta nevede ke složce",
                                                level=Qgis.MessageLevel.Critical)





    def kontrola_projektu_prep(self):
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        
        cesta_vysledky_dir = self.dlg.lineEdit_vysledkykontroly.text()
        cesta_vysledky_existuje = os.path.isdir(cesta_vysledky_dir)
        
        cesta_vstupy_zip = self.dlg.lineEdit_cestazip.text()
        cesta_vstupy_existuje = os.path.isfile(cesta_vstupy_zip)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
                
        if ((cesta_vysledky_existuje == False)):
            self.iface.messageBar().pushMessage("Chybějící údaje", "Chybí umístění složky pro výsledky", level=Qgis.MessageLevel.Critical)
        elif ((cesta_vstupy_existuje == False)):
            self.iface.messageBar().pushMessage("Chybějící údaje", "Chybí umístění souboru zip se vstupy", level=Qgis.MessageLevel.Critical)
        elif (cesta_vstupy_zip[-4:] != ".zip"):
            self.iface.messageBar().pushMessage("Špatný formát", "Vstup není zip soubor", level=Qgis.MessageLevel.Critical)
        elif diacritic_pattern.search(cesta_vysledky_dir):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)
        elif diacritic_pattern.search(cesta_vstupy_zip):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)      
        
        else:
            #ještě kontrola epsg, k tomu se zip rozbali

            chyba_zip = 0
            # Otevřeme ZIP soubor
            with zipfile.ZipFile(cesta_vstupy_zip, 'r') as zip_file:
                shapefiles = []
                
                # Projdeme všechny soubory v ZIPu
                for file_name in zip_file.namelist():
                    if file_name.endswith(".shp"):
                        shapefiles.append(file_name)
                
                # Zkontrolujeme, že jsou přesně 2 shapefily
                if len(shapefiles) != 2:
                    self.iface.messageBar().pushMessage("Špatný vstup", f"V ZIPu není přesně 2 shapefile soubory. Nalezeno {len(shapefiles)}", level=Qgis.MessageLevel.Critical)
                    chyba_zip += 1
                    
                else:
                    # Ujistíme se, že soubory mají názvy 'plan_osevu_psp' a 'trajektorie'
                    shapefiles_sorted = sorted(shapefiles)
                    if shapefiles_sorted[0] != "plan_osevu_psp.shp" or shapefiles_sorted[1] != "trajektorie.shp":
                        self.iface.messageBar().pushMessage("Špatný vstup", "Shapefile soubory neodpovídají očekávaným názvům 'plan_osevu_psp.shp' a 'trajektorie.shp'", level=Qgis.MessageLevel.Critical)
                        chyba_zip += 1
                        
                    else:
                        zipbase = '/vsizip/' + cesta_vstupy_zip.replace(os.sep, '/')
                        shp_name1 = 'plan_osevu_psp.shp'
                        shp_name2 = 'trajektorie.shp'
                        shp1 = QgsVectorLayer(f"{zipbase}/{shp_name1}", 'zip1', 'ogr')
                        shp2 = QgsVectorLayer(f"{zipbase}/{shp_name2}", 'zip2', 'ogr')
                        if not shp1.isValid():
                            self.iface.messageBar().pushMessage("Špatný vstup", f"Vrstva {shp_name1} není platná", level=Qgis.MessageLevel.Critical)
                            chyba_zip += 1
                        else:
                            # Získáme CRS (projekce) vrstvy a EPSG kód
                            epsg_code = shp1.crs().authid()  # EPSG kód
                            print(f"Shapefile {shp_name1} má EPSG kód: {epsg_code}")
                            if epsg_code != 'EPSG:5514':
                                self.iface.messageBar().pushMessage("Špatný vstup", f"Vrstva {shp_name1} nemá EPSG kód 5514", level=Qgis.MessageLevel.Critical)
                                chyba_zip += 1
                                
                        del shp1
                                
                        if not shp2.isValid():
                            self.iface.messageBar().pushMessage("Špatný vstup", f"Vrstva {shp_name2} není platná", level=Qgis.MessageLevel.Critical)
                            chyba_zip += 1
                        else:
                            # Získáme CRS (projekce) vrstvy a EPSG kód
                            epsg_code = shp2.crs().authid()  # EPSG kód
                            print(f"Shapefile {shp_name2} má EPSG kód: {epsg_code}")
                            if epsg_code != 'EPSG:5514':
                                self.iface.messageBar().pushMessage("Špatný vstup", f"Vrstva {shp_name2} nemá EPSG kód 5514", level=Qgis.MessageLevel.Critical)
                                chyba_zip += 1
                                
                        del shp2
                         
            if chyba_zip == 0:     
        
                response = QMessageBox.information(None,
                "Start",
                "Připraveno k ověření.\nKlikněte na OK pro pokračování.",
                QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
                
                if response == QMessageBox.StandardButton.Ok:
                    print("Pokračuji...")
                    self.kontrola_projektu()
                    #self.dlg.progressBar_vypocet.setFormat("Hotovo")
                    #self.dlg.progressBar_vypocet.setValue(100)
                elif response == QMessageBox.StandardButton.Cancel:
                    print("Výpočet byl zastaven.")
                
                        
                
            
        
        

    def kontrola_projektu(self):

        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5514))
        EPSG = "5514"
        cesta_vysledky_dir = self.dlg.lineEdit_vysledkykontroly.text()
        print(cesta_vysledky_dir)
        
        # ---------------------------------------------------------------------------------------------------------------
        
        self.dlg.progressBar_vypocet.setValue(3)
        self.dlg.progressBar_vypocet.setFormat("Start")
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Načtení vstupů ze zipu + kontrola názvů a epsg (----------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
   
        cesta_vstupy_dir = self.dlg.lineEdit_cestazip.text()
        basename_00 = os.path.basename(cesta_vstupy_dir)
        basename_0 = os.path.splitext(basename_00)[0]

        id_cele = basename_0.replace("Import_projekt_psp", "")

        idecka = id_cele.split("_")
        dist = int(idecka[1][:-1])
        id_procesu = idecka[3]
        kod_uzivatele = idecka[2]
        
        zipbase = '/vsizip/' + cesta_vstupy_dir.replace(os.sep, '/')
        shp_name1 = 'plan_osevu_psp.shp'
        selectedLayerPlanosevu = QgsVectorLayer(f"{zipbase}/{shp_name1}", 'Plán osevu', 'ogr')
        if not selectedLayerPlanosevu.isValid():
            print ("Layer failed to load!")
        else:
            pass
            #QgsProject.instance().addMapLayer(selectedLayerPlanosevu)
            
        shp_name2 = 'trajektorie.shp'
        selectedLayerTrajektorie = QgsVectorLayer(f"{zipbase}/{shp_name2}", 'Trajektorie', 'ogr')
        if not selectedLayerTrajektorie.isValid():
            print ("Layer failed to load!")
        else:
            pass
            #QgsProject.instance().addMapLayer(selectedLayerTrajektorie)
        
        # vytvoření základní složky a složky s mezivýstupy

        self.dlg.progressBar_vypocet.setValue(0)
        self.dlg.progressBar_vypocet.setFormat("Start")

        if os.path.isdir(cesta_vysledky_dir) == True:
            TEMPdir_path = self.dlg.lineEdit_vysledkykontroly.text()
            TEMPdir = TEMPdir_path + f"\\Overeni{id_cele}\\mezivystupy\\"
            if os.path.isdir(TEMPdir) == False:
                os.makedirs(TEMPdir)
            Exportdir_path = self.dlg.lineEdit_vysledkykontroly.text() + f"\\Overeni{id_cele}"

        def crs_na_5514(lyr):
            source_crs = QgsCoordinateReferenceSystem(lyr.crs().authid())
            target_crs = QgsCoordinateReferenceSystem("EPSG:5514")
            lyr.startEditing()
            for feat in lyr.getFeatures():
                geom = feat.geometry()
                geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()))
                feat.setGeometry(geom)
                lyr.updateFeature(feat)
            lyr.setCrs(target_crs)
            lyr.commitChanges()
            lyr.setCrs(target_crs)


        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Načtení vrstev a dat (-------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
 
        # priprava vrstvy s trajektorii se spravnym crs, je vytvorena kopie, nemeni se puvodni vrstva
        selectedLayerTrajektorie.selectAll()
        LayerTrajektorie = \
            processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerTrajektorie, 'OUTPUT': 'memory:'})[
                'OUTPUT']
        selectedLayerTrajektorie.removeSelection()      
        crs_na_5514(LayerTrajektorie)
        #QgsProject.instance().addMapLayer(LayerTrajektorie)

        selectedLayerPlanosevu.selectAll()
        LayerPlanosevu = processing.run("native:saveselectedfeatures", {'INPUT': selectedLayerPlanosevu, 'OUTPUT': 'memory:'})[
            'OUTPUT']
        selectedLayerPlanosevu.removeSelection()
        crs_na_5514(LayerPlanosevu)

        # Načítání kódů plodin
        """
        plodiny_txt = f'{self.plugin_dir}/kodyplodin_plus.txt'
        plodiny_kody = {}
        try:
            with open(plodiny_txt, "r") as plodiny_soubor:
                for line in plodiny_soubor.readlines():
                    radek = line.split("\t")
                    cislo = radek[0]
                    text = radek[1].strip()  # Odstraní případné nové řádky
                    plodiny_kody[cislo] = text
        except FileNotFoundError:
            print(f"Soubor {plodiny_txt} nebyl nalezen.")
            return
        """
        
        plodiny_txt = f'{self.plugin_dir}/kodyplodin_plus.txt'
        plodiny_kody = {}
        try:
            with open(plodiny_txt, "r") as plodiny_soubor:
                for line in plodiny_soubor.readlines():
                    radek = line.split(", ")
                    cislo = radek[0]
                    text = radek[1]
                    ochrana = radek[2].strip()
                    celed = radek[3].strip()  # Odstraní případné nové řádky
                    plodiny_kody[cislo] = [text, ochrana, celed]
        except FileNotFoundError:
            print(f"Soubor {plodiny_txt} nebyl nalezen.")
            return
        
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Načtení WFS vrstev (---------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
 
        dso_bool = False
        extent = LayerPlanosevu.extent()
        xmin = int(extent.xMinimum()) - 100
        ymin = int(extent.yMinimum()) - 100
        xmax = int(extent.xMaximum()) + 100
        ymax = int(extent.yMaximum()) + 100
        bbox = f"{xmin},{ymin},{xmax},{ymax}"
        print(bbox)
        try:
            uri = "https://iprod.vumop.cz/wfs/dso.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:dso5&bbox=" + bbox
            lyr_dso = QgsVectorLayer(uri, "DSO5ha", "ogr")
            crs = lyr_dso.crs()
            crs.createFromId(5514)
            lyr_dso.setCrs(crs)
            dso_bool = True
        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu DSO 5 ha z WFS služby",
                                                level=Qgis.MessageLevel.Warning)
            
        if dso_bool:
            DSO_pasy = processing.run("native:buffer", {'INPUT':lyr_dso,'DISTANCE':7.5,'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
  
            
        dpb_vlayer_bool = False
        try:
            uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_DPB_UCINNE&bbox=" + bbox
            dpb_vlayer = QgsVectorLayer(uri, "DPB_wfs", "ogr")

            crs = dpb_vlayer.crs()
            crs.createFromId(5514)
            dpb_vlayer.setCrs(crs)

            dpb_vlayer.setName("DPB_účinné")
            dpb_vlayer_bool = True

        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu DPB_UCINNE z WFS služby",
                                                level=Qgis.MessageLevel.Warning)

        neo_bool = False
        try:
            uri = uri = "https://iprod.vumop.cz/wfs/neo.php?service=WFS&version=1.0.0&request=GetFeature&typename=ms:neo&bbox=" + bbox
            neo_vlayer = QgsVectorLayer(uri, "NEO", "ogr")

            crs = neo_vlayer.crs()
            crs.createFromId(5514)
            neo_vlayer.setCrs(crs)
            lyr_neo = processing.run("native:fixgeometries",
                           {'INPUT': neo_vlayer, 'METHOD': 1,
                            'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

            lyr_neo.setName("NEO")
            neo_bool = True

        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu NEO z WFS služby",
                                                level=Qgis.MessageLevel.Warning)
            
        kp_vlayer_bool = False
        try:
            uri = "https://mze.gov.cz/public/app/wms/plpis_wfs.fcgi?service=WFS&version=1.0.0&request=GetFeature&typename=ms:LPIS_EVP_UCINNE&bbox=" + bbox
            kp_vlayer0 = QgsVectorLayer(uri, "DPB_wfs", "ogr")
            # WFS/OGR má často neplatné CRS; saveselectedfeatures pak v QGIS 4 vrátí 0 prvků
            kp_vlayer0.setCrs(QgsCoordinateReferenceSystem("EPSG:5514"))
            kp_vlayer = kp_vlayer0.materialize(QgsFeatureRequest())
            
            kp_vlayer.startEditing()
            kp_vlayer_provider = kp_vlayer.dataProvider()
            kp_vlayer_fields = [QgsField("CTVEREC", QVariant.String),
                           QgsField("ZKOD", QVariant.String) ]
            kp_vlayer_provider.addAttributes(kp_vlayer_fields)
            kp_vlayer.updateFields()
            _kp_flds = {n.lower(): n for n in kp_vlayer.fields().names()}
            _src_ctverec = _kp_flds.get("ctverec")
            _src_zkod = _kp_flds.get("zkracenykod")
            for feat in kp_vlayer.getFeatures():
                if _src_ctverec:
                    feat["CTVEREC"] = feat[_src_ctverec]
                if _src_zkod:
                    feat["ZKOD"] = feat[_src_zkod]
                kp_vlayer.updateFeature(feat)
            kp_vlayer.commitChanges()
            # WFS LPIS_EVP_UCINNE občas vrátí totožné polygony vícekrát
            if kp_vlayer.featureCount() > 0:
                kp_vlayer = processing.run("native:deleteduplicategeometries", {
                    'INPUT': kp_vlayer, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            kp_vlayer.setName("EVP_účinné")
            #QgsProject.instance().addMapLayer(kp_vlayer)
            kp_vlayer_bool = kp_vlayer.featureCount() > 0

        except:
            self.iface.messageBar().pushMessage("Chybný vstup",
                                                "Nepovedlo se načíst vrstvu LPIS_EVP_UCINNE z WFS služby",
                                                level=Qgis.MessageLevel.Warning)
            
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Převzetí DPB z WFS, které se překrývají s plánem osevu (---------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
 
        LayerMaska0 = processing.run("native:dissolve", {
            'INPUT': LayerPlanosevu,
            'FIELD': ['CTVEREC', 'ZKOD'], 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
        #QgsProject.instance().addMapLayer(LayerMaska0)
            
            
        for f1 in dpb_vlayer.getFeatures():
            for f2 in LayerMaska0.getFeatures():
                prunik = f1.geometry().intersection(f2.geometry())
                if prunik.area() > 1:
                    dpb_vlayer.select(f1.id())
        LayerDPB_wfs = processing.run("native:saveselectedfeatures", {'INPUT': dpb_vlayer, 'OUTPUT': 'memory:'})['OUTPUT']
        dpb_vlayer.removeSelection()
        #QgsProject.instance().addMapLayer(LayerDPB_wfs)
    
        LayerDPB_wfs.startEditing()
        dpb_vlayer_provider = LayerDPB_wfs.dataProvider()
        dpb_vlayer_fields = [QgsField("CTVEREC", QVariant.String),
                       QgsField("ZKOD", QVariant.String),
                       QgsField("CTVEREC2", QVariant.String),]
        dpb_vlayer_provider.addAttributes(dpb_vlayer_fields)
        LayerDPB_wfs.updateFields()
        for feat in LayerDPB_wfs.getFeatures():
            feat["CTVEREC2"] = feat["ctverec"]
            feat["ZKOD"] = feat["zkracenyKod"]
            LayerDPB_wfs.updateFeature(feat)
        LayerDPB_wfs.commitChanges()
        
        
        # Získání indexu atributu podle názvu
        field_index = LayerDPB_wfs.fields().indexOf("ctverec")  
        if field_index != -1:
            # Smazání atributu
            LayerDPB_wfs.dataProvider().deleteAttributes([field_index])
            LayerDPB_wfs.updateFields()  # Aktualizace polí

        
        LayerDPB_wfs.startEditing()
        for feat in LayerDPB_wfs.getFeatures():
            feat["CTVEREC"] = feat["CTVEREC2"]
            LayerDPB_wfs.updateFeature(feat)
        LayerDPB_wfs.commitChanges()
        
        # Získání indexu atributu podle názvu
        field_index = LayerDPB_wfs.fields().indexOf("CTVEREC2")  
        if field_index != -1:
            # Smazání atributu
            LayerDPB_wfs.dataProvider().deleteAttributes([field_index])
            LayerDPB_wfs.updateFields()  # Aktualizace polí
        #QgsProject.instance().addMapLayer(LayerDPB_wfs)
         

        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Stažení DMR (----------------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------

        TEMPdir = TEMPdir_path + f"\\Overeni{id_cele}\\mezivystupy\\"

        def check_layer_validity(layer, layer_name):
            if not layer.isValid():
                print(f"Vrstva {layer_name} není platná.")
                raise SystemExit(1)

        # Načtení vrstvy ořezu
        polygon_layer = LayerMaska0

        # priptavit pro orezy
        extent = polygon_layer.extent()
        sirka = int(extent.xMaximum() - extent.xMinimum()) + 200
        vyska = int(extent.yMaximum() - extent.yMinimum()) + 200
        xmin = int(extent.xMinimum()) - 100
        ymin = int(extent.yMinimum()) - 100
        if xmin % 2 != 0:
            xmin = xmin - 1
        if ymin % 2 != 0:
            ymin = ymin - 1
        xmax = xmin + sirka
        ymax = ymin + vyska
        if xmax % 2 != 0:
            xmax = xmax + 1
        if ymax % 2 != 0:
            ymax = ymax + 1
        bbox = f"{xmin},{ymin},{xmax},{ymax}"
        print(bbox)

        hrana = 5000  # m

        xpocet = int(sirka / hrana) + 1
        ypocet = int(vyska / hrana) + 1

        list_of_tifs = []
        list_of_dwnld = []
        docasne_tiff_dir = None
        poradi = 0
        for xn in range(xpocet):
            for yn in range(ypocet):
                xmin0 = xmin + xn * hrana
                xmax0 = xmin0 + hrana
                if xmax0 > xmax:
                    xmax0 = xmax
                ymin0 = ymin + yn * hrana
                ymax0 = ymin0 + hrana
                if ymax0 > ymax:
                    ymax0 = ymax
                bbox0 = f"{xmin0},{ymin0},{xmax0},{ymax0}"

                coords = [(xmin0, ymin0), (xmin0, ymax0), (xmax0, ymax0), (xmax0, ymin0), (xmin0, ymin0)]
                polygon = QgsGeometry.fromPolygonXY([[QgsPointXY(pair[0], pair[1]) for pair in coords]])

                lyr_polygon = QgsVectorLayer("Polygon?crs=epsg:5514", "polygon", "memory")
                lyr_polygon.startEditing()
                pr_lyr_polygon = lyr_polygon.dataProvider()
                seg = QgsFeature()
                seg.setGeometry(polygon)
                pr_lyr_polygon.addFeature(seg)
                lyr_polygon.updateExtents()
                lyr_polygon.commitChanges()
                QgsProject.instance().addMapLayer(lyr_polygon)

                prunik = processing.run("native:clip", {
                    'INPUT': polygon_layer,
                    'OVERLAY': lyr_polygon, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                QgsProject.instance().removeMapLayer(lyr_polygon.id())

                if prunik.featureCount() > 0:

                    # Výpočet velikosti obrázku (šířka a výška v pixelech) na základě rozsahu vrstvy
                    # Tato část předpokládá, že chcete 1 pixel na 1 metr (můžeš to upravit podle potřeby)
                    width_in_meters = int(xmax0 - xmin0)
                    height_in_meters = int(ymax0 - ymin0)

                    # Velikost obrázku (počet pixelů)
                    size_x = int(width_in_meters / 2)
                    size_y = int(height_in_meters / 2)
                    size = f"{size_x},{size_y}"

                    # API URL pro stahování dat DMR5G
                    export_url = "https://ags.cuzk.cz/arcgis2/rest/services/dmr5g/ImageServer/exportImage"
                    # Parametry pro API požadavek
                    params = {
                        "bbox": bbox0,
                        "imageSR": 5514,
                        "bboxSR": 5514,
                        "size": size,  # Velikost výstupního obrázku
                        "format": "tiff",
                        "f": "image"
                    }
                    response = requests.get(export_url, params=params, timeout=30)
                    if response.status_code != 200:
                        self.iface.messageBar().pushMessage("Chyba stahování",
                                                            "Nepodařilo se stáhnout tiff s DMR5G",
                                                            level=Qgis.MessageLevel.Critical)

                    else:
                        # Získání URL staženého obrázku
                        url = response.url
                        stazeno = False
                        try:
                            r = requests.get(url, allow_redirects=True, timeout=30)
                            stazeno = True
                        except requests.ConnectionError as e:
                            self.iface.messageBar().pushMessage("Chyba spojení",
                                                                str(e),
                                                                level=Qgis.MessageLevel.Critical)

                        if stazeno:
                            output_folder_2 = TEMPdir + "docasne_tiff"
                            docasne_tiff_dir = output_folder_2
                            if os.path.isdir(output_folder_2) == False:
                                os.mkdir(output_folder_2)
                            output_path = os.path.join(output_folder_2, f"dmr5g_output_{poradi}.tif")

                            with open(output_path, 'wb') as f:
                                f.write(r.content)

                            # vezme raster a uloží ho s CRS 5514
                            dmr5g_prep = QgsRasterLayer(output_path, "dmr", "gdal")
                            crs = dmr5g_prep.crs()
                            crs.createFromId(5514)
                            dmr5g_prep.setCrs(crs)

                            file_name = output_path[:-4] + "_x.tif"
                            file_writer = QgsRasterFileWriter(file_name)
                            pipe = QgsRasterPipe()
                            provider = dmr5g_prep.dataProvider()
                            if not pipe.set(provider.clone()):
                                print("nejde setnout pipe provider")

                            file_writer.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(),
                                                    provider.crs())

                            # Uvolnit GDAL zámek na staženém TIF (jinak Windows nesmaže docasne_tiff).
                            del provider
                            del pipe
                            del file_writer
                            del dmr5g_prep

                            list_of_dwnld.append(output_path)
                            list_of_tifs.append(file_name)
                            # raster_layer = QgsRasterLayer(output_path, f"DMR5G vrstva{poradi}")
                            # check_layer_validity(raster_layer, "DMR5G vrstva")

                            # Přidání vrstev do projektu
                            # QgsProject.instance().addMapLayer(polygon_layer)
                            # QgsProject.instance().addMapLayer(raster_layer)

                            print(f"Data byla úspěšně stažena: {output_path}")
                            poradi = poradi + 1

        print(list_of_tifs)
        if len(list_of_tifs) > 0:
            counter = 1
            nalezen = False
            while nalezen == False:
                DMR5G_celek_path = TEMPdir + f"DMR5G_projekt_{counter}.tiff"
                if not os.path.exists(DMR5G_celek_path):
                    nalezen = True
                else:
                    counter += 1
            print(DMR5G_celek_path)

            processing.run("gdal:merge", {
                'INPUT': list_of_tifs, 'PCT': False,
                'SEPARATE': False, 'NODATA_INPUT': None, 'NODATA_OUTPUT': None, 'OPTIONS': '', 'EXTRA': '',
                'DATA_TYPE': 5, 'OUTPUT': DMR5G_celek_path})


            _smaz_docasne_tiff_slozku(docasne_tiff_dir, list_of_tifs, list_of_dwnld)


        LayerDMT = QgsRasterLayer(DMR5G_celek_path, "DMR 5G", "gdal")
        #QgsProject.instance().addMapLayer(LayerDMT)

        # ---------------------------------------------------------------------------------------------------------------

        self.dlg.progressBar_vypocet.setValue(10)
        self.dlg.progressBar_vypocet.setFormat("Zpracovani vstupu")

        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Tvorba ořezu DMR a výpočet svažitosti (--------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        dx = LayerDMT.rasterUnitsPerPixelX()
        dy = LayerDMT.rasterUnitsPerPixelY()


        LayerMaska_plus = processing.run("native:buffer",
                                         {'INPUT': LayerDPB_wfs, 'DISTANCE': 80, 'SEGMENTS': 5,
                                          'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 42, 'DISSOLVE': False,
                                          'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        orez_dmt_prep = processing.run("gdal:cliprasterbymasklayer", {'INPUT': LayerDMT,
                                                                      'MASK': LayerMaska_plus,
                                                                      'SOURCE_CRS': QgsCoordinateReferenceSystem(
                                                                          LayerDMT.crs().authid()),
                                                                      'TARGET_CRS': QgsCoordinateReferenceSystem(
                                                                          'EPSG:' + EPSG),
                                                                      'TARGET_EXTENT': None, 'NODATA': -9999,
                                                                      'ALPHA_BAND': False,
                                                                      'CROP_TO_CUTLINE': True, 'KEEP_RESOLUTION': False,
                                                                      'SET_RESOLUTION': False, 'X_RESOLUTION': dx,
                                                                      'Y_RESOLUTION': dy, 'MULTITHREADING': False,
                                                                      'OPTIONS': '',
                                                                      'DATA_TYPE': 0, 'EXTRA': '',
                                                                      'OUTPUT': TEMPdir + "orez_dmt.tif"})
        orez_dmt = QgsRasterLayer(orez_dmt_prep["OUTPUT"], "orez_dmt", "gdal")
        # QgsProject.instance().addMapLayer(orez_dmt)

        sklon_prep = processing.run("gdal:slope", {'INPUT': orez_dmt, 'BAND': 1, 'SCALE': 1, 'AS_PERCENT': False,
                                                   'COMPUTE_EDGES': True, 'ZEVENBERGEN': False, 'OPTIONS': '',
                                                   'EXTRA': '', 'OUTPUT': TEMPdir + "slope.tif"})
        sklon_layer = QgsRasterLayer(sklon_prep["OUTPUT"], "sklon (°)", "gdal")
        target_crs = QgsCoordinateReferenceSystem("EPSG:5514")
        sklon_layer.setCrs(target_crs)
        sklon_layer.setName("Sklon °_" + id_procesu)

        # ---------------------------------------------------------------------------------------------------------------

        self.dlg.progressBar_vypocet.setValue(25)
        self.dlg.progressBar_vypocet.setFormat("Sklon nad 3 %")

        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Tvorba masky kde je plocha se sklonem nad 3 % (------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        # trida podle sklonu
        reclass_slope_prep = processing.run("native:reclassifybytable",
                                            {'INPUT_RASTER': sklon_layer, 'RASTER_BAND': 1,
                                             'TABLE': ['1.718', '100', '1'], 'NO_DATA': -9999, 'RANGE_BOUNDARIES': 0,
                                             'NODATA_FOR_MISSING': True, 'DATA_TYPE': 5,
                                             'OUTPUT': TEMPdir + "reclass_slope.tif"})
        reclass_slope_layer = QgsRasterLayer(reclass_slope_prep["OUTPUT"], "reclass sklon", "gdal")
        reclass_slope_layer.setCrs(target_crs)
        # QgsProject.instance().addMapLayer(reclass_slope_layer)

        reclass_slope_polyg_prep = processing.run("gdal:polygonize",
                                                  {'INPUT': reclass_slope_layer, 'BAND': 1, 'FIELD': 'VALUE',
                                                   'EIGHT_CONNECTEDNESS': False, 'EXTRA': '',
                                                   'OUTPUT': TEMPdir + "reclass_slope_polyg.shp"})
        reclass_slope_polyg = QgsVectorLayer(reclass_slope_polyg_prep["OUTPUT"], "reclass sklon polyg", "ogr")
        reclass_slope_polyg.setCrs(target_crs)
        # QgsProject.instance().addMapLayer(reclass_slope_polyg)

        buffer1 = processing.run("native:buffer",
                                 {'INPUT': reclass_slope_polyg,
                                  'DISTANCE': 0.5, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                  'MITER_LIMIT': 2,
                                  'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
            "OUTPUT"]
        # QgsProject.instance().addMapLayer(buffer1)

        buffer1_diss = processing.run("native:dissolve", {
            'INPUT': buffer1,
            'FIELD': ['VALUE'], 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

        maska_3pr = processing.run("native:buffer",
                                   {'INPUT': buffer1_diss,
                                    'DISTANCE': -0.5, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                    'MITER_LIMIT': 2,
                                    'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
            "OUTPUT"]
        # QgsProject.instance().addMapLayer(maska_3pr)
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Funkce pro výpočty (---------------------------------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        def vypocet_uhlu(p1, p2, p3):
            def vzdalenost(a, b):
                return math.sqrt((a.x() - b.x()) ** 2 + (a.y() - b.y()) ** 2)

            a = vzdalenost(p2, p3)
            b = vzdalenost(p1, p3)
            c = vzdalenost(p1, p2)
            if c == 0 or a == 0:  # Ochrana pred nulovou vzdalenosti
                return 180
            if ((a ** 2 + c ** 2 - b ** 2) / (2 * a * c) > 1):
                uhel = 0
            elif ((a ** 2 + c ** 2 - b ** 2) / (2 * a * c) < -1):
                uhel = 180
            else:
                uhel = math.degrees(math.acos((a ** 2 + c ** 2 - b ** 2) / (2 * a * c)))
            return uhel

        # Funkce pro odstraneni Z-souradnic z geometrie
        def odstranit_z_souradnice(geom):
            if geom.isMultipart():
                parts = geom.asMultiPolyline()
                new_parts = []
                for part in parts:
                    new_part = [QgsPoint(p.x(), p.y()) for p in part]  # Odebrání Z-souřadnic
                    new_parts.append(new_part)
                return QgsGeometry.fromMultiPolyline(new_parts)
            else:
                part = geom.asPolyline()
                new_part = [QgsPoint(p.x(), p.y()) for p in part]  # Odebrání Z-souřadnic
                return QgsGeometry.fromPolyline(new_part)

        # pomocné funkce
        def ulozeni_vektorove_vrstvy(lyr, path_lyr, DN="ESRI Shapefile", FE="windows-1250"):
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = DN
            options.fileEncoding = FE
            options.destCRS = QgsCoordinateReferenceSystem("EPSG:" + EPSG)
            error = QgsVectorFileWriter.writeAsVectorFormatV3(lyr, path_lyr,
                                                              QgsProject.instance().transformContext(), options)
            if error[0] == QgsVectorFileWriter.WriterError.NoError:
                print("ok")
            else:
                print(error)

        def symbology_kategorie(lyr, field, unique_values, colors_cat, names_cat):
            categories = []
            for unique_value in unique_values:
                symbol = QgsSymbol.defaultSymbol(lyr.geometryType())
                layer_style = {}
                layer_style['color'] = colors_cat[unique_values.index(unique_value)]
                layer_style['outline'] = '#000000'
                symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)
                if symbol_layer is not None:
                    symbol.changeSymbolLayer(0, symbol_layer)
                category = QgsRendererCategory(unique_value, symbol,
                                               names_cat[unique_values.index(unique_value)])
                categories.append(category)
            renderer = QgsCategorizedSymbolRenderer(field, categories)
            if renderer is not None:
                lyr.setRenderer(renderer)
            lyr.triggerRepaint()

        def rozdel_krivku_na_segmenty(line_geometry, delka_segmentu):
            if line_geometry.isMultipart():
                parts = line_geometry.asMultiPolyline()
            else:
                parts = [line_geometry.asPolyline()]

            segments = []
            for part in parts:
                vzdalenost = 0
                pocet = (line_geometry.length() / delka_segmentu)
                if int(pocet) == pocet:
                    pocet = int(pocet)
                else:
                    pocet = int(pocet) + 1
                print(pocet)
                vertexy = [v for v in line_geometry.vertices()]
                prvni = vertexy[0]
                posledni = vertexy[-1]
                pocatek = prvni
                if posledni.x() < prvni.x():
                    pocatek = posledni
                if posledni.x() == prvni.x():
                    if posledni.y() < prvni.y():
                        pocatek = posledni

                if QgsPoint(line_geometry.interpolate(0).asPoint()) == pocatek:
                    print("pocatek")
                    vzdalenost0 = 10
                    print(vzdalenost0)
                else:
                    print("konec")
                    vzdalenost0 = line_geometry.length() - (pocet - 1) * delka_segmentu
                    print(vzdalenost0)

                while vzdalenost < line_geometry.length():
                    # Vytvoreni bodu na krivce
                    start_point = QgsPoint(line_geometry.interpolate(vzdalenost).asPoint())
                    if vzdalenost == 0:
                        segments.append(start_point)
                        next_point = QgsPoint(
                            line_geometry.interpolate(min(vzdalenost + vzdalenost0, line_geometry.length())).asPoint())
                        vzdalenost += vzdalenost0
                        segments.append(next_point)
                    else:
                        next_point = QgsPoint(line_geometry.interpolate(
                            min(vzdalenost + delka_segmentu, line_geometry.length())).asPoint())
                        vzdalenost += delka_segmentu
                        segments.append(next_point)

            return segments

        def mazani_poli(vrstva, list_pole_zustavaji):
            field_names_vrstva = vrstva.fields().names()
            rozdil_vrstva = []
            for element in field_names_vrstva:
                if (element in list_pole_zustavaji) == False:
                    rozdil_vrstva.append(element)
            vrstva.startEditing()
            fields_to_delete = []
            for fieldname_to_delete in rozdil_vrstva:
                fieldindex_to_delete = vrstva.fields().indexFromName(fieldname_to_delete)
                if fieldindex_to_delete == -1:
                    continue
                fields_to_delete.append(fieldindex_to_delete)
            vrstva.dataProvider().deleteAttributes(fields_to_delete)
            vrstva.updateFields()
            vrstva.commitChanges()

        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Řešení po jednotlivých DPB -> účinné DPB z WFS (-----------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        pocet_dpb = LayerDPB_wfs.featureCount()
        pocitadlo_dpb = 1
        
        dobre_dpb = 0
        spatne_dpb = 0
    
        seznam_pdf = []
        merger = PdfWriter()
        
        for feat_dpb in LayerDPB_wfs.getFeatures():

                        
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Příprava layoutu pro tisk (--------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            
            projekt = QgsProject.instance()
            manager = projekt.layoutManager()
            
            # Vytvoření názvu pro nový layout s aktuálním datem
            layoutName = "PSP_layout_tisk_" + strftime('%Y_%m_%d', localtime(time.time()))
            layouts_list = manager.printLayouts()
            
            # Odstranění existujícího layoutu se stejným názvem
            for lt in layouts_list:
                if lt.name() == layoutName:
                    manager.removeLayout(lt)

            # Vytvoření nového layoutu a přidání stránek
            layout_psp = QgsPrintLayout(projekt)
            layout_psp.initializeDefaults()
            layout_psp.setName(layoutName)
            manager.addLayout(layout_psp)
            
            pc = layout_psp.pageCollection()

            # Nastavení velikosti stránek na A4
            pc.page(0).setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
            page = QgsLayoutItemPage(layout_psp)
            page.setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
            layout_psp.pageCollection().addPage(page)
            
            page2 = QgsLayoutItemPage(layout_psp)
            page2.setPageSize("A4", QgsLayoutItemPage.Orientation.Portrait)
            layout_psp.pageCollection().addPage(page2)
            
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Převod feature DPB na vrstvu (-----------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            
            LayerDPB_wfs.select(feat_dpb.id())
            lyr_dpb_i = processing.run("native:saveselectedfeatures", {'INPUT': LayerDPB_wfs, 'OUTPUT': 'memory:'})['OUTPUT']
            LayerDPB_wfs.removeSelection()
            #QgsProject.instance().addMapLayer(lyr_dpb_i)
            
            # Nastavení symbolu pro vrstvu DPB
            lyr_dpb_i.setName("DPB")
            lyr_dpb_i.renderer().symbol().setColor(QColor.fromRgb(222, 226, 194))
            lyr_dpb_i.triggerRepaint()
            
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) vrstvy pro daný DPB (--------------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
     

            
            kostra_i_bool = False
            lyr_planosevu_i = processing.run("native:clip", {
                'INPUT': selectedLayerPlanosevu,
                'OVERLAY': lyr_dpb_i,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            if lyr_planosevu_i.featureCount() > 0:
                lyr_planosevu_i.setName("Plán osevu")
                kostra_i_bool = True
            
            
            try:
                lyr_trajektorie_i = processing.run("native:clip", {
                    'INPUT': LayerTrajektorie,
                    'OVERLAY': lyr_dpb_i,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                lyr_trajektorie_i.setName("Trajektorie")   
                lyr_trajektorie_i_bool = True
            except:
                lyr_trajektorie_i_bool = False
                
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) řešení plánu osevu -> unikátnost id, plochy plodin (-------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
     
            if kostra_i_bool:
                # Nalezení unikátních hodnot pro PLOD_ID
                idx = lyr_planosevu_i.fields().indexOf('PLOD_ID')
                unique_values = list(lyr_planosevu_i.uniqueValues(idx))
                
                # Slovník obsahující ID plodiny a jejich plochy
                plochy_plodiny = {}
                vymera_plan_osevu = 0
                for plodina in unique_values:
                    plochy_plodiny[plodina] = 0
                for feat_plodiny in lyr_planosevu_i.getFeatures():
                    plodina = feat_plodiny['PLOD_ID']
                    plochy_plodiny[plodina] += feat_plodiny.geometry().area() / 10000 # Převod na hektary
    
                # Sčítání plochy plodin
                for value in plochy_plodiny.values():
                    vymera_plan_osevu += round(value,4)
                
                # Nastavení kategorií pro symbologii na základě plodiny a její plochy
                #symbology - do textu se přiřadí plochy plodin s jejich názvy
                #taky se řeší zda jsou PLOD_ID v seznamu plodin
                plody_v_seznamu = True
                names_cat_dict = {}
                for plod in unique_values:
                    
                    if plod in list(plodiny_kody.keys()):
                        if plodiny_kody[plod][1] == "NOF":
                            text = f"{plod} - {plodiny_kody[plod][0]} - {plodiny_kody[plod][2]} - {plochy_plodiny[plod]:.4f} ha - nízká ochranná funkce"
                        else:
                            text = f"{plod} - {plodiny_kody[plod][0]} - {plodiny_kody[plod][2]} - {plochy_plodiny[plod]:.4f} ha"
                        
                    elif plod == NULL:
                        text = "Není vyplněno"
                        plody_v_seznamu = False
                    else:
                        text = f"{plod} - PLOD_ID není v seznamu - {plochy_plodiny[plod]:.4f} ha"
                        plody_v_seznamu = False
                    names_cat_dict[plod] = text
                   
                unikatni_hodnoty = []
                
                def prevedeni_list2list(uv_old, uv_new, val):
                    if val in unique_values:
                        uv_new.append(val)
                        uv_old.remove(val)
                
                prevedeni_list2list(unique_values, unikatni_hodnoty, "471")
                prevedeni_list2list(unique_values, unikatni_hodnoty, "50082")
                prevedeni_list2list(unique_values, unikatni_hodnoty, "459")
                prevedeni_list2list(unique_values, unikatni_hodnoty, "460")
                prevedeni_list2list(unique_values, unikatni_hodnoty, "50018")
                
                list_ne_nof = []
                list_nof = []
                for plod in unique_values:
                    if plodiny_kody[plod][1] == "NOF":
                        list_nof.append(plod)
                    else:
                        list_ne_nof.append(plod)
                               
                for plod in list_ne_nof:
                    unikatni_hodnoty.append(plod)
                for plod in list_nof:
                    unikatni_hodnoty.append(plod)
                    
                categories = []
                for value in unikatni_hodnoty:
                    symbol = QgsSymbol.defaultSymbol(lyr_planosevu_i.geometryType())
                    category = QgsRendererCategory(value, symbol, names_cat_dict[value])
                    categories.append(category)
                    
                renderer = QgsCategorizedSymbolRenderer('PLOD_ID', categories)
                renderer.updateColorRamp(QgsRandomColorRamp())
                lyr_planosevu_i.setRenderer(renderer)
                lyr_planosevu_i.triggerRepaint()
                
                if plody_v_seznamu:
                    podminka_plody_seznam = "SPLNĚNO"
                else:
                    podminka_plody_seznam = "NESPLNĚNO"
                
                # Kontrola jedinečnosti ZAKRES_ID a porovnání plochy DPB
                #kontrola, zda ZP obsahují unikátní hodnoty pro ZAKRES_ID a zda plocha ZP se rovnají ploše DPB  
                zakresy_id = []
                plocha_kostra_m = 0
                for feat in lyr_planosevu_i.getFeatures():
                    zakresy_id.append(feat["ZAKRES_ID"])
                    plocha_kostra_m += feat.geometry().area()
                    
                zakresy_id_unique = list(set(zakresy_id))
                podminka_jedinecnost = "NESPLNĚNO"
                if len(zakresy_id) == len(zakresy_id_unique):
                    podminka_jedinecnost = "SPLNĚNO"
                # podmínka pro NULL v id_zakresu
                if NULL in zakresy_id_unique:
                    podminka_jedinecnost = "NESPLNĚNO"
                
                podminka_plochy_parcel = "NESPLNĚNO"
                if ((plocha_kostra_m/feat_dpb.geometry().area() < 1.0001) and ((plocha_kostra_m/feat_dpb.geometry().area() > 0.9999))):
                    podminka_plochy_parcel = "SPLNĚNO"
                    
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Extrahování StP a ověření jeho plochy (--------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
                
            np_i_bool = False
            if kostra_i_bool:
                #STP vytvořeno z planu osevu
                lyr_np_i = processing.run("native:extractbyattribute", {'INPUT':lyr_planosevu_i,
                                                                        'FIELD':'PLOD_ID',
                                                                        'OPERATOR':0,'VALUE':'471',
                                                                        'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                if lyr_np_i.featureCount() > 0:
                    
                    lyr_np_i = processing.run("native:dissolve", {'INPUT':lyr_np_i, 
                                                                  'FIELD':[],
                                                                  'SEPARATE_DISJOINT':False,
                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    lyr_np_i_plus = processing.run("native:buffer", {'INPUT': lyr_np_i,
                                                     'DISTANCE':0.001,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    lyr_np_i = processing.run("native:buffer", {'INPUT': lyr_np_i_plus,
                                                     'DISTANCE':-0.001,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    
                    lyr_np_i.setName("Stabilizační plochy")
                    
                    # Nastavení barvy symbolu pro STP
                    sym = lyr_np_i.renderer().symbol()
                    syms = sym[0]
                    syms.setColor(QColor("#7df1de"))
                    syms.setStrokeColor(QColor("transparent"))
                    lyr_np_i.triggerRepaint()
                    np_i_bool = True
                    
            aenvi_i_bool = False
            if kostra_i_bool:
                # Definujeme hodnoty, které chceme extrahovat
                target_values = ["459", "460", "50018"]
                # Vytvoříme nový prázdný seznam pro extrahované prvky
                extracted_features = []
                # Procházíme všechny objekty ve vrstvě
                for feature in lyr_planosevu_i.getFeatures():
                    if feature['PLOD_ID'] in target_values:
                        extracted_features.append(feature)
                
                # Pokud byly nalezeny nějaké odpovídající prvky
                if extracted_features:
                    # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                    lyr_aenvi_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                
                    # Kopírujeme pole z původní vrstvy do nové
                    new_fields = lyr_planosevu_i.fields()
                    lyr_aenvi_i.dataProvider().addAttributes(new_fields)
                    lyr_aenvi_i.updateFields()
                
                    # Přidáme extrahované prvky do nové vrstvy
                    lyr_aenvi_i.startEditing()
                    lyr_aenvi_i.dataProvider().addFeatures(extracted_features)
                    lyr_aenvi_i.commitChanges()   
                    lyr_aenvi_i.setName("Agroenviromentální\nplochy")
                    
                    # Nastavení barvy symbolu pro STP
                    sym = lyr_aenvi_i.renderer().symbol()
                    syms = sym[0]
                    syms.setColor(QColor("#7df1de")) 
                    syms.setStrokeColor(QColor("transparent"))
                    lyr_aenvi_i.triggerRepaint()
                    aenvi_i_bool = True
                    
            stp_s_aenvi_i_bool = False
            if kostra_i_bool:
                # Definujeme hodnoty, které chceme extrahovat
                target_values = ["471", "459", "460", "50018"]
                # Vytvoříme nový prázdný seznam pro extrahované prvky
                extracted_features = []
                # Procházíme všechny objekty ve vrstvě
                for feature in lyr_planosevu_i.getFeatures():
                    if feature['PLOD_ID'] in target_values:
                        extracted_features.append(feature)
                
                # Pokud byly nalezeny nějaké odpovídající prvky
                if extracted_features:
                    # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                    lyr_stp_s_aenvi_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                
                    # Kopírujeme pole z původní vrstvy do nové
                    new_fields = lyr_planosevu_i.fields()
                    lyr_stp_s_aenvi_i.dataProvider().addAttributes(new_fields)
                    lyr_stp_s_aenvi_i.updateFields()
                
                    # Přidáme extrahované prvky do nové vrstvy
                    lyr_stp_s_aenvi_i.startEditing()
                    lyr_stp_s_aenvi_i.dataProvider().addFeatures(extracted_features)
                    lyr_stp_s_aenvi_i.commitChanges()    
                    
                    lyr_stp_s_aenvi_i = processing.run("native:dissolve", {'INPUT':lyr_stp_s_aenvi_i, 
                                                                  'FIELD':[],
                                                                  'SEPARATE_DISJOINT':False,
                                                                  'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    lyr_stp_s_aenvi_i_plus = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i,
                                                     'DISTANCE':0.001,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    lyr_stp_s_aenvi_i = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i_plus,
                                                     'DISTANCE':-0.001,
                                                     'SEGMENTS':5,
                                                     'END_CAP_STYLE':1,
                                                     'JOIN_STYLE':1,
                                                     'MITER_LIMIT':2,
                                                     'DISSOLVE':False,
                                                     'SEPARATE_DISJOINT':False,
                                                     'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    stp_s_aenvi_i_bool = True
                    #QgsProject.instance().addMapLayer(lyr_stp_s_aenvi_i)

            #kontrola plochy STP (5-30 % z DPB) včetně aenvi
            area_np_s_ae = 0
            
            if stp_s_aenvi_i_bool:
                for feat in lyr_stp_s_aenvi_i.getFeatures():
                    area_np_s_ae += feat.geometry().area()    
                    
                
            if ((area_np_s_ae/feat_dpb.geometry().area() >= 0.05) and (area_np_s_ae/feat_dpb.geometry().area() <= 0.3)):
                podminka_plocha_np = "SPLNĚNO"
            else:
                podminka_plocha_np = "NESPLNĚNO"
            
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Tvorba masky3p a jeji inverze (----------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
                   
            maska3_i_bool = False
            lyr_maska3_i = processing.run("native:clip", {
                'INPUT': maska_3pr,
                'OVERLAY': lyr_dpb_i,
                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
            if lyr_maska3_i.featureCount() > 0:
                lyr_maska3_i.setName("Sklonitost nad 3 %")
                maska3_i_bool = True
            
            # Inverze masky sklonu, aby zobrazila oblasti s rovinkou (plocha, která nebude řešena v následujících krocích)
            if maska3_i_bool:
                lyr_maska3_invert_i = processing.run("native:difference", {'INPUT': lyr_dpb_i,'OVERLAY':lyr_maska3_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"] 
                # Nastavení barvy pro inverzní masku (pro rovinné oblasti)
                sym = lyr_maska3_invert_i.renderer().symbol()
                syms = sym[0]
                syms.setColor(QColor.fromRgb(218, 207, 86))
                syms.setStrokeColor(QColor("transparent"))
                lyr_maska3_invert_i.triggerRepaint()
            
            # Výpočet celkové plochy masky 3p (masky pro sklon) a její inverzní verze (rovinné oblasti)
            lyr_maska3_area = 0
            if maska3_i_bool:
                for feat in lyr_maska3_i.getFeatures():
                    lyr_maska3_area += feat.geometry().area()
                
            lyr_maska3_invert_area = 0
            if maska3_i_bool:
                if lyr_maska3_invert_i.featureCount() > 0:
                    for feat in lyr_maska3_invert_i.getFeatures():
                        lyr_maska3_invert_area += feat.geometry().area()
            
            # Kontrola, zda inverzní maska (rovinné oblasti) pokrývá více než 25 % celkové plochy DPB, letos neřešeno
            if (lyr_maska3_invert_area/(feat_dpb.geometry().area())) > 0.25:
                podminka_maska3_area = "NESPLNĚNO"
            else:
                podminka_maska3_area = "SPLNĚNO"
                
            # Nastavení názvu vrstvy, která ukazuje procento plochy s rovinkou (sklon pod 3%)
            if maska3_i_bool:
                lyr_maska3_invert_i.setName(f"Sklonitost pod 3 %\n{(100*(lyr_maska3_invert_area/(feat_dpb.geometry().area()))):.1f} % z DPB")
            
            # ---------------------------------------------------------------------------------------------------------------
            

            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Práce s trajektoriemi, ostré úhly + segmenty po 10 m (-----------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
               
            # úprava trajektorií, jsou rozdělené v místě s ostrým úhlem
            # Overeni platnosti vrstvy a pridani do projektu
            if lyr_trajektorie_i_bool:
                if not lyr_trajektorie_i.isValid():
                    print("Vrstva nebyla uspesne nactena!")
                else:
                    # QgsProject.instance().addMapLayer(LayerTrajektorie)
                    print("Vrstva byla uspesne nactena a pridana do projektu.")

                    # Rozpusteni vrstvy (nastroj "Dissolve")
                    dissolve_params = {
                        'INPUT': lyr_trajektorie_i,
                        'FIELD': [],
                        'SEPARATE_DISJOINT': False,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    }
                    rozpkrivka = processing.run("native:dissolve", dissolve_params)['OUTPUT']

                    # Pridani rozpustene vrstvy do projektu
                    rozpkrivka.setName("rozpkrivka")
                    # QgsProject.instance().addMapLayer(rozpkrivka)
                    print("Vrstva byla rozpustena a pridana jako 'rozpkrivka'.")

                    # Rozdeleni multipartnich geometrii na jednotlivé části (nastroj "Multipart to singleparts")
                    multipart_params = {
                        'INPUT': rozpkrivka,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    }
                    multipart_result = processing.run("native:multiparttosingleparts", multipart_params)
                    singkrivka = multipart_result['OUTPUT']

                    # Pridani singl vrstvy do projektu
                    singkrivka.setName("singkrivka")
                    # QgsProject.instance().addMapLayer(singkrivka)
                    print("Vrstva byla rozdelena na jednotlive casti jako 'singkrivka'.")

                    # Odstraneni Z-souradnic z vrstvy "singkrivka" a vytvoreni nove vrstvy "NOZ"
                    noz_layer = QgsVectorLayer("LineString?crs=EPSG:5514", "NOZ", "memory")
                    noz_provider = noz_layer.dataProvider()
                    noz_provider.addAttributes(singkrivka.fields())
                    noz_layer.updateFields()

                    for feature in singkrivka.getFeatures():
                        geom = feature.geometry()
                        new_geom = odstranit_z_souradnice(geom)  # Odstraneni Z-souřadnic
                        new_feature = QgsFeature(noz_layer.fields())
                        new_feature.setGeometry(new_geom)
                        new_feature.setAttributes(feature.attributes())
                        noz_provider.addFeature(new_feature)

                    noz_layer.updateExtents()
                    # QgsProject.instance().addMapLayer(noz_layer)
                    print("Vrstva 'singkrivka' byla transformovana do vrstvy 'NOZ' bez Z-souřadnic.")

                    LayerTrajektorie_1 = \
                        processing.run("native:deleteduplicategeometries",
                                       {'INPUT': noz_layer, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                            "OUTPUT"]
                    # QgsProject.instance().addMapLayer(LayerTrajektorie_1)

                    noz_layer = processing.run("native:multiparttosingleparts",
                                               {'INPUT': LayerTrajektorie_1,
                                                'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    # Rozdeleni lomovych bodu v uhlu mensim nez 120 stupnu a vetsim nez 240 stupnu na vrstve "NOZ"
                    ostreuhly_layer = QgsVectorLayer("LineString?crs=EPSG:5514", "ostreuhly", "memory")
                    ostreuhly_provider = ostreuhly_layer.dataProvider()
                    ostreuhly_provider.addAttributes(noz_layer.fields())  # Pouziti vrstvy NOZ
                    ostreuhly_layer.updateFields()

                    for feature in noz_layer.getFeatures():  # Pouziti vrstvy NOZ
                        geom = feature.geometry()
                        line = geom.asPolyline()  # Ziskani linie
                        if len(line) < 3:
                            pass
                        # Rozdelovani podle uhlu
                        segment = [QgsPoint(p) for p in line[:1]]  # Používáme QgsPoint namísto QgsPointXY
                        for i in range(1, len(line) - 1):
                            uhel = vypocet_uhlu(QgsPoint(line[i - 1]), QgsPoint(line[i]),
                                                QgsPoint(line[i + 1]))  # Konverze na QgsPoint
                            if uhel < 140 or uhel > 240:  # Rozdeleni v lomovych bodech
                                segment.append(QgsPoint(line[i]))
                                segment_geom = QgsGeometry.fromPolyline(segment)
                                new_feature = QgsFeature(ostreuhly_layer.fields())
                                new_feature.setGeometry(segment_geom)
                                new_feature.setAttributes(feature.attributes())
                                ostreuhly_provider.addFeature(new_feature)
                                segment = [QgsPoint(line[i])]
                            else:
                                segment.append(QgsPoint(line[i]))
                        segment.append(QgsPoint(line[-1]))
                        segment_geom = QgsGeometry.fromPolyline(segment)
                        new_feature = QgsFeature(ostreuhly_layer.fields())
                        new_feature.setGeometry(segment_geom)
                        new_feature.setAttributes(feature.attributes())
                        ostreuhly_provider.addFeature(new_feature)

                    ostreuhly_layer.updateExtents()
                    # QgsProject.instance().addMapLayer(ostreuhly_layer)
                    print("Vrstva 'ostreuhly' byla vytvorena a pridana do projektu.")

                LayerTrajektorie_i = ostreuhly_layer
                # Zobrazeni vsech vrstev
                print("Vizualizace všech vrstev byla dokončena.")
                # QgsProject.instance().addMapLayer(LayerTrajektorie)
                # ---------------------------------------------------------------------------------------------------------------
            #Vytvoření segmentů po 10 m
            if lyr_trajektorie_i_bool:
                kolmice = QgsVectorLayer("LineString?crs=epsg:5514", "kolmice", "memory")
                kolmice_prov = kolmice.dataProvider()

                # Overeni platnosti vrstvy a pridani do projektu
                if not lyr_trajektorie_i.isValid():
                    print("Vrstva nebyla uspesne nactena! ")
                else:
                    # QgsProject.instance().addMapLayer(layer)
                    print("Vrstva byla uspesne nactena a pridana do projektu.")

                    # Nacteni CRS puvodni vrstvy (pokud je treba)
                    crs = lyr_trajektorie_i.crs().authid()
                    print(f"CRS puvodni vrstvy: {crs}")

                    # Delka segmentu
                    delka_segmentu = 10.0

                    # Pruchod jednotlivymi prvky vrstvy a rozdeleni krivek
                    for feature in lyr_trajektorie_i.getFeatures():
                        geom = feature.geometry()
                        if geom.isNull():
                            continue

                        pocet_segmentu = 0
                        # Kontrola, zda je geometrie typu linie

                        if geom.type() != QgsWkbTypes.GeometryType.LineGeometry:
                            print("Prvek neni krivka, preskocen.")
                            continue

                        docasna_linka = QgsVectorLayer("LineString?crs=epsg:5514", "docasna", "memory")
                        linka_prov = docasna_linka.dataProvider()
                        feat_linka = QgsFeature()
                        feat_linka.setGeometry(geom)
                        linka_prov.addFeatures([feat_linka])
                        docasna_linka.updateExtents()

                        docasne_linky = processing.run("native:multiparttosingleparts",
                                                       {'INPUT': docasna_linka, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                        # QgsProject.instance().addMapLayer(docasne_linky)

                        # smazat z docasne linky ty linky co maji mensi delku jak 1 m
                        docasne_linky.startEditing()
                        for feat in docasne_linky.getFeatures():
                            if feat.geometry().length() < 1:
                                docasne_linky.deleteFeature(feat.id())
                        docasne_linky.commitChanges()

                        for f in docasne_linky.getFeatures():
                            geom_docasne = f.geometry()

                            segment_layer = QgsVectorLayer("Point?crs=EPSG:5514", "Dělící body", "memory")
                            segment_layer_pr = segment_layer.dataProvider()

                            segments = rozdel_krivku_na_segmenty(geom_docasne, delka_segmentu)

                            for segment_geom in segments:
                                new_feature = QgsFeature(segment_layer.fields())
                                new_feature.setGeometry(segment_geom)
                                new_feature.setAttributes(feature.attributes())
                                segment_layer_pr.addFeature(new_feature)
                                pocet_segmentu += 1

                            # Aktualizace rozsahu nove vrstvy a jeji pridani do projektu
                            segment_layer.updateExtents()
                            QgsProject.instance().addMapLayer(segment_layer)

                            kolmicky = processing.run("native:geometrybyexpression",
                                                      {'INPUT': docasne_linky, 'OUTPUT_GEOMETRY': 1, 'WITH_Z': False,
                                                       'WITH_M': False,
                                                       'EXPRESSION': "collect_geometries (\r\n    array_foreach (\r\n        aggregate( \r\n            'Dělící body', \r\n            'array_agg', \r\n            $geometry\r\n        ),\r\n        extend (\r\n            make_line(\r\n                line_interpolate_point( \r\n                    $geometry,\r\n                    line_locate_point($geometry,@element)\r\n                ),\r\n            project (\r\n                 line_interpolate_point( \r\n                    $geometry,\r\n                    line_locate_point($geometry,@element)\r\n                ),\r\n                10,\r\n                radians(\r\n                    90+line_interpolate_angle( \r\n                        $geometry,\r\n                        line_locate_point($geometry,@element)\r\n            )))),\r\n            10,\r\n            0\r\n)))",
                                                       'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                            # QgsProject.instance().addMapLayer(kolmicky)

                            for feat_kolmicky in kolmicky.getFeatures():
                                feat_kolmice = QgsFeature()
                                feat_kolmice.setGeometry(feat_kolmicky.geometry())
                                kolmice_prov.addFeatures([feat_kolmice])

                            # Vypis poctu vytvorenych segmentu
                            print(f"Pocet vytvorenych segmentu: {pocet_segmentu}")
                            QgsProject.instance().removeMapLayer(segment_layer.id())

                kolmice.updateExtents()
                # QgsProject.instance().addMapLayer(kolmice)

                segmenty = processing.run("native:splitwithlines",
                                          {'INPUT': LayerTrajektorie_i, 'LINES': kolmice,
                                           'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(segmenty)

                segmenty.startEditing()
                segmenty_provider = segmenty.dataProvider()
                new_fields = [QgsField("Slope_%", QVariant.Double),
                              QgsField("z_first", QVariant.Double),
                              QgsField("z_last", QVariant.Double),
                              QgsField("delka_seg", QVariant.Double)]
                segmenty_provider.addAttributes(new_fields)
                segmenty.updateFields()
                for feat in segmenty.getFeatures():
                    linka = feat.geometry()
                    body = [v for v in linka.vertices()]
                    kraj1 = body[0]
                    kraj2 = body[-1]
                    delka = linka.length()
                    vyska1, res = orez_dmt.dataProvider().sample(QgsPointXY(kraj1.x(), kraj1.y()), 1)
                    vyska2, res = orez_dmt.dataProvider().sample(QgsPointXY(kraj2.x(), kraj2.y()), 1)
                    sklon = (abs(vyska1 - vyska2)) * 100 / delka
                    sklon = round(sklon, 1)
                    feat["Slope_%"] = sklon
                    feat["z_first"] = vyska1
                    feat["z_last"] = vyska2
                    feat["delka_seg"] = round(linka.length(), 2)
                    segmenty.updateFeature(feat)
                segmenty.commitChanges()
                segmenty.setName("Segmenty")
                #QgsProject.instance().addMapLayer(segmenty)
                
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Vytvoření plošek kolem segmentů a řešení podélného sklonu (------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
     
            #Vytvoření plošek kolem segmentů
            if lyr_trajektorie_i_bool:
                plosky = processing.run("native:buffer", {
                    'INPUT': segmenty,
                    'DISTANCE': dist / 2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(plosky)

                #určení sklonu na plošce
                plosky_slope = processing.run("native:zonalstatisticsfb", {
                    'INPUT': plosky,
                    'INPUT_RASTER': sklon_layer, 'RASTER_BAND': 1,
                    'COLUMN_PREFIX': 'slope_', 'STATISTICS': [2, 6], 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # urceni tridy prekroceni sklonu
                plosky_slope.startEditing()
                new_field = QgsField("result", QVariant.Int)
                plosky_slope.addAttribute(new_field)
                plosky_slope.updateFields()
                for feat in plosky_slope.getFeatures():
                    mean_slope_st = feat["slope_mean"]
                    mean_slope_pr = 100 * (math.tan(math.radians(mean_slope_st)))
                    sklon_trajektorie_pr = feat["Slope_%"]
                    if mean_slope_pr > 3:
                        if sklon_trajektorie_pr <= 7:
                            if sklon_trajektorie_pr > mean_slope_pr / 2:
                                feat["result"] = 1
                            else:
                                feat["result"] = 0
                        else:
                            feat["result"] = 2
                    else:
                        feat["result"] = 0
                    plosky_slope.updateFeature(feat)
                plosky_slope.commitChanges()
                #QgsProject.instance().addMapLayer(plosky_slope)

                # pouziti neprodukční plochy ci ne
                lyr_dpb_i.selectAll()
                upravena_maska = processing.run("native:saveselectedfeatures", {'INPUT': lyr_dpb_i, 'OUTPUT': 'memory:'})['OUTPUT']
                lyr_dpb_i.removeSelection()
                if np_i_bool:
                    upravena_maska = processing.run("native:difference", {'INPUT': lyr_dpb_i,
                                                                          'OVERLAY': lyr_np_i,
                                                                          'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                          'GRID_SIZE': None})['OUTPUT']
                
                if kp_vlayer_bool:
                    upravena_maska = processing.run("native:difference", {'INPUT': upravena_maska,
                                                                          'OVERLAY': kp_vlayer,
                                                                          'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                          'GRID_SIZE': None})['OUTPUT']

                #odstranění odřezků
                upravena_maska.startEditing()
                for feat in upravena_maska.getFeatures():
                    if feat.geometry().area() < 1:
                        upravena_maska.deleteFeature(feat.id())
                upravena_maska.commitChanges()

                upravena_maska_minus = processing.run("native:buffer", {
                    'INPUT': upravena_maska,
                    'DISTANCE': -0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                upravena_maska = processing.run("native:buffer", {
                    'INPUT': upravena_maska_minus,
                    'DISTANCE': 0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']

                plosky_final = plosky_slope

                #buffer +, dissolve a buffer -        
                buffer3 = processing.run("native:buffer", {
                    'INPUT': plosky_final,
                    'DISTANCE': 0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2,
                    'DISSOLVE': False,
                    'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                #QgsProject.instance().addMapLayer(buffer3)

                buffer3_diss = processing.run("native:dissolve", {
                    'INPUT': buffer3,
                    'FIELD': ['result'], 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                # QgsProject.instance().addMapLayer(buffer3_diss)

                buffer4 = processing.run("native:buffer",
                                         {'INPUT': buffer3_diss,
                                          'DISTANCE': -0.1, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1,
                                          'MITER_LIMIT': 42,
                                          'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                buffer4.startEditing()
                for feat in buffer4.getFeatures():
                    if feat.geometry().area() < 1:
                        buffer4.deleteFeature(feat.id())
                buffer4.commitChanges()
                # QgsProject.instance().addMapLayer(buffer4)

                polygony_ohrozenost = processing.run("native:fixgeometries", {
                    'INPUT': buffer4,
                    'METHOD': 1, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                #QgsProject.instance().addMapLayer(buffer4)
                
                try:
                    if polygony_ohrozenost.featureCount() > 0:
                        polygony_ohrozenost_bool = True
                    else:
                        polygony_ohrozenost_bool = False
                except:
                    polygony_ohrozenost_bool = False
                
                if polygony_ohrozenost_bool:

                    polygony_ohrozenost_maska_union = processing.run("native:union", {
                        'INPUT': polygony_ohrozenost,
                        'OVERLAY': lyr_dpb_i, 'OVERLAY_FIELDS_PREFIX': '',
                        'OUTPUT': 'TEMPORARY_OUTPUT', 'GRID_SIZE': None})["OUTPUT"]
    
                    polygony_ohrozenost_maska_union_singleparts = processing.run("native:multiparttosingleparts", {
                        'INPUT': polygony_ohrozenost_maska_union,
                        'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]

                    zeop_i_bool = False
                    polygony_ohrozenost_maska_union_singleparts.startEditing()
                    new_field = QgsField("podelny_sklon", QVariant.Int)
                    polygony_ohrozenost_maska_union_singleparts.addAttribute(new_field)
                    polygony_ohrozenost_maska_union_singleparts.updateFields()
                    for feat in polygony_ohrozenost_maska_union_singleparts.getFeatures():
                        if ((feat["result"] == 2) and (feat.geometry().area() > 10000)):
                            zeop_i_bool = True
                            feat["podelny_sklon"] = 2
                        elif (feat["result"] == 1):
                            feat["podelny_sklon"] = 1
                        elif (feat["result"] == 0):
                            feat["podelny_sklon"] = 0
                        elif (feat["result"] == NULL):
                            feat["podelny_sklon"] = NULL
                        else:
                            feat["podelny_sklon"] = 1
                        polygony_ohrozenost_maska_union_singleparts.updateFeature(feat)
                    polygony_ohrozenost_maska_union_singleparts.commitChanges()
                    polygony_ohrozenost_maska_union_singleparts.setName("podelna sklonitost trajektorie uložení")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_singleparts)
                    
                    mazani_poli(polygony_ohrozenost_maska_union_singleparts, ["ZKOD", "CTVEREC", "result", "podelny_sklon"])
                    
                    polygony_ohrozenost_maska_union_singleparts_final = processing.run("native:clip", {
                        'INPUT': polygony_ohrozenost_maska_union_singleparts,
                        'OVERLAY': upravena_maska, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    polygony_ohrozenost_maska_union_singleparts_final.startEditing()
                    for feat in polygony_ohrozenost_maska_union_singleparts_final.getFeatures():
                        if feat.geometry().area() < 1:
                            polygony_ohrozenost_maska_union_singleparts_final.deleteFeature(feat.id())
                    polygony_ohrozenost_maska_union_singleparts_final.commitChanges()
                    polygony_ohrozenost_maska_union_singleparts_final.setName("polygony_ohrozenost_maska_union_singleparts_final_výpočty")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_singleparts_final)
                    
    
                    polygony_ohrozenost_maska_union.startEditing()
                    new_field = QgsField("result_2", QVariant.Int)
                    polygony_ohrozenost_maska_union.addAttribute(new_field)
                    polygony_ohrozenost_maska_union.updateFields()
                    for feat in polygony_ohrozenost_maska_union.getFeatures():
                        if ((feat["result"] == 1) or (feat["result"] == 2)):
                            feat["result_2"] = 1
                        else:
                            feat["result_2"] = 0
                        polygony_ohrozenost_maska_union.updateFeature(feat)
                    polygony_ohrozenost_maska_union.commitChanges()
                    polygony_ohrozenost_maska_union.setName("polygony_ohrozenost_maska_union_uložení")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union)
                    
                    mazani_poli(polygony_ohrozenost_maska_union, ["ZKOD", "CTVEREC", "result", "result_2"])
 
                    polygony_ohrozenost_maska_union_final = processing.run("native:clip", {
                        'INPUT': polygony_ohrozenost_maska_union,
                        'OVERLAY': upravena_maska, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    polygony_ohrozenost_maska_union_final.startEditing()
                    for feat in polygony_ohrozenost_maska_union_final.getFeatures():
                        if feat.geometry().area() < 1:
                            polygony_ohrozenost_maska_union_final.deleteFeature(feat.id())
                    polygony_ohrozenost_maska_union_final.commitChanges()
                    polygony_ohrozenost_maska_union_final.setName("polygony_ohrozenost_maska_union_final_výpočty")
                    #QgsProject.instance().addMapLayer(polygony_ohrozenost_maska_union_final)

                    plosky_prekroceno = processing.run("native:extractbyattribute", {
                        'INPUT': polygony_ohrozenost_maska_union_final,
                        'FIELD': 'result_2', 'OPERATOR': 0, 'VALUE': '1', 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(plosky_prekroceno)
    
                    plosky_prekroceno_diss = processing.run("native:dissolve",
                                                            {'INPUT': plosky_prekroceno, 'FIELD': ['result_2'],
                                                             'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})[
                        "OUTPUT"]
                    #QgsProject.instance().addMapLayer(plosky_prekroceno_diss)
    
                    buffer5 = processing.run("native:buffer", {
                        'INPUT': plosky_prekroceno_diss,
                        'DISTANCE': 0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 42,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    buffer6 = processing.run("native:buffer", {
                        'INPUT': buffer5,
                        'DISTANCE': -0.2, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 42,
                        'DISSOLVE': False,
                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    buffer6 = processing.run("native:fixgeometries", {
                        'INPUT': buffer6,
                        'METHOD': 1, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    # QgsProject.instance().addMapLayer(buffer6)

                    limit30 = processing.run("native:multiintersection", {
                        'INPUT': buffer6,
                        'OVERLAYS': [lyr_maska3_i],
                        'OVERLAY_FIELDS_PREFIX': '', 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                    
                    
                    # ---- Finální kontrola oblastí, kde je překročen podélný sklon ----                
                    limit30_i_bool = False
                    podminka_limit30 = "SPLNĚNO"
                    if limit30.featureCount() > 0:
                        limit30_i_bool = True
                        limit30.startEditing()
                        new_fields = [QgsField("P_SKL(%)", QVariant.Double)]
                        limit30.dataProvider().addAttributes(new_fields)                 
                        limit30.updateFields()
                        # Výpočet procenta pro každý prvek a aktualizace atributu
                        for feat in limit30.getFeatures():
                            plocha_limit30 = feat.geometry().area()
                            podminka_limit30 = "NESPLNĚNO"
                            if (100 * plocha_limit30 / lyr_maska3_area) <= 30:     
                                podminka_limit30 = "SPLNĚNO"
                            limit30_procenta = round(100 * plocha_limit30 / lyr_maska3_area, 1)
                            feat["P_SKL(%)"] = limit30_procenta
                            limit30.updateFeature(feat)
                        limit30.commitChanges()
                        limit30.commitChanges()
                        limit30.setName(f"Překročený podélný\nsklon\n{(100 * plocha_limit30 / lyr_maska3_area):.1f} %")
                        limit30.renderer().symbol().setColor(QColor.fromRgb(22, 229, 47))
                        limit30.triggerRepaint()
                        #QgsProject.instance().addMapLayer(limit30)
                        
                    #odečtení KP
                    if ((limit30.featureCount() > 0) and (kp_vlayer_bool == True)):
                        limit30 = processing.run("native:difference", {'INPUT':limit30,
                                                                             'OVERLAY':kp_vlayer,
                                                                             'OUTPUT':'TEMPORARY_OUTPUT',
                                                                             'GRID_SIZE':None})["OUTPUT"]
                        #smazaní odřezků
                        limit30.startEditing()
                        for feat in limit30.getFeatures():
                            if feat.geometry().area() < 1:
                                limit30.deleteFeature(feat.id())
                        limit30.commitChanges()
                        
                        if limit30.featureCount() > 0:
                            limit30_i_bool = True
                        else:
                            limit30_i_bool = False
                            
                    # ---------------------------------------------------------------------------------------------------------------
                    
                    
                    # ---------------------------------------------------------------------------------------------------------------
                    # --------------) Řešení ZEOP (Značně Erozí ohrožené plochy) (---------------------------------------------------
                    # ---------------------------------------------------------------------------------------------------------------

                    zeop_all_procenta = 0
                    podminka_zeop = "SPLNĚNO"                    
                    
                    if zeop_i_bool: 
                        zeop_prep = processing.run("native:extractbyattribute", {
                            'INPUT': polygony_ohrozenost_maska_union_singleparts_final, 'FIELD': 'podelny_sklon', 'OPERATOR': 0,
                            'VALUE': '2',
                            'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
     
                        if zeop_prep.featureCount() > 0:
                            zeop_prep2 = processing.run("native:dissolve",
                                                       {'INPUT': zeop_prep, 'FIELD': [],
                                                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})['OUTPUT']
                            
                            # Odstranění oblastí překrývajících se s STP (zeop_prep3)
                            if np_i_bool:
                                zeop_prep2 = processing.run("native:difference", {'INPUT': zeop_prep2,
                                                                                  'OVERLAY': lyr_np_i,
                                                                                  'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                                  'GRID_SIZE': None})['OUTPUT']
                                
                            # Rozdělení více části na jednotlivé části
                            zeop = processing.run("native:multiparttosingleparts", {'INPUT':zeop_prep2,   
                                                                                    'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            zeop = processing.run("native:fieldcalculator", {'INPUT':zeop,
                                                                             'FIELD_NAME':'plocha',
                                                                             'FIELD_TYPE':0,
                                                                             'FIELD_LENGTH':10,
                                                                             'FIELD_PRECISION':2,
                                                                             'FORMULA':' $area '
                                                                             ,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            zeop = processing.run("native:extractbyattribute", {'INPUT':zeop,
                                                                                'FIELD':'plocha',
                                                                                'OPERATOR':2,
                                                                                'VALUE':'10000',
                                                                                'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                            
                            if zeop.featureCount() > 0:
                        
                                # Odstranění malých ploch (méně než 1 m²)
                                zeop.startEditing()
                                for feat in zeop.getFeatures():
                                    if feat.geometry().area() < 1:
                                        zeop.deleteFeature(feat.id())
                                zeop.commitChanges()
                                    
                                # Nastavení flagu a výchozích podmínek pro ZEOP
                                zeop_i_bool = True
                                podminka_zeop = "NESPLNĚNO"
                                zeop_all_area = 0
                                zeop_all_procenta = 0
                                pocet_zeop_nad2ha = 0
                                
                                # Přidání nových polí pro výpočty a aktualizace atributů
                                zeop.startEditing()
                                new_fields = [QgsField("ZEOP(%)", QVariant.Double),
                                              QgsField("VYMZEOP", QVariant.Double, len=10, prec=4),
                                              QgsField("ZEOPstav", QVariant.String)
                                              ]
                                zeop.dataProvider().addAttributes(new_fields)
                                zeop.updateFields()
                                
                                # Výpočty pro každou plochu ZEOP
                                for feat in zeop.getFeatures():
                                    plocha_zeop = feat.geometry().area()
                                    zeop_all_area = zeop_all_area + plocha_zeop
                                    zeop_procenta = 100 * plocha_zeop / lyr_maska3_area
                                    zeop_all_procenta = zeop_all_procenta + zeop_procenta
                                    feat["ZEOP(%)"] = round(zeop_procenta,1)
                                    feat["VYMZEOP"] = round(plocha_zeop/10000, 4)
                                    
                                    # Určení vyhodnocení plochy podle velikosti
                                    if ((zeop_procenta <= 10) and (plocha_zeop <= 20000)):
                                        feat["ZEOPstav"] = "OK"
                                    else:
                                        feat["ZEOPstav"] = "překračuje limity"
                                        pocet_zeop_nad2ha = pocet_zeop_nad2ha + 1
                                    zeop.updateFeature(feat)
                                zeop.commitChanges()
                                
                                # Nastavení názvu vrstvy ZEOP a barvy podle procenta plochy
                                zeop.setName(f"Značně erozně\nohrožené plochy\ncelkem {zeop_all_procenta:.1f} %")
                                if (((100 * zeop_all_area / lyr_maska3_area) <= 10) and (pocet_zeop_nad2ha == 0)):   
                                    podminka_zeop = "SPLNĚNO"
                                
                                # Nastavení rendereru pro různé kategorie stavu ZEOP
                                categories = []
                                colors_cat = ["#9270d2", "#db7b90"]
                                unique_values = ["OK", "překračuje limity"]
                                names_cat = ["ZEOP\ndo 2 ha", "ZEOP\nnad 2 ha"]
                                for i, value in enumerate(colors_cat):
                                    symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.PolygonGeometry)
                                    symbol.setColor(QColor(value))
                                    category = QgsRendererCategory(unique_values[i], symbol, names_cat[i])
                                    categories.append(category)
                                renderer = QgsCategorizedSymbolRenderer('ZEOPstav', categories)
                                if renderer is not None:
                                    zeop.setRenderer(renderer)
                                zeop.triggerRepaint()
                
            # ---------------------------------------------------------------------------------------------------------------
        
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Řešení spojených/širokých pásů (---------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            #určení pásů s plodinami (lyr_pasy_i) z plánu osevu
            pasy_i_bool = False
            if kostra_i_bool:
                # Definujeme hodnoty, které nechceme extrahovat
                target_values = ["459", "460", "471", "50018", "50082"]
                # Vytvoříme nový prázdný seznam pro extrahované prvky
                extracted_features = []
                # Procházíme všechny objekty ve vrstvě
                for feature in lyr_planosevu_i.getFeatures():
                    if feature['PLOD_ID'] not in target_values:
                        extracted_features.append(feature)
                
                # Pokud byly nalezeny nějaké odpovídající prvky
                if extracted_features:
                    # Vytvoříme novou prázdnou vektorovou vrstvu (stejný typ geometrie jako původní vrstva)
                    lyr_pasy_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Extrahovaná vrstva", "memory")
                
                    # Kopírujeme pole z původní vrstvy do nové
                    new_fields = lyr_planosevu_i.fields()
                    lyr_pasy_i.dataProvider().addAttributes(new_fields)
                    lyr_pasy_i.updateFields()
                
                    # Přidáme extrahované prvky do nové vrstvy
                    lyr_pasy_i.startEditing()
                    lyr_pasy_i.dataProvider().addFeatures(extracted_features)
                    lyr_pasy_i.commitChanges()
                    
                    pasy_i_bool = True
                
            #spojené pásy -> všechny pásy s větší šířkou
            #nalezení širokých pásů -> tam kde existuje vnitřní buffer pro 21.45 m
            spojene_bool = False
            if pasy_i_bool:
                LayerPasy_i_vnitrni_buffer = processing.run("native:buffer",
                               {'INPUT': lyr_pasy_i,
                                'DISTANCE': -21.45, 'SEGMENTS': 5, 'END_CAP_STYLE': 0, 'JOIN_STYLE': 0, 'MITER_LIMIT': 2,
                                'DISSOLVE': False, 'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                
                LayerPasy_i_vnitrni_buffer.startEditing()
                for feat in LayerPasy_i_vnitrni_buffer.getFeatures():
                    if feat.geometry().area() < 0.011:
                        LayerPasy_i_vnitrni_buffer.deleteFeature(feat.id())
                LayerPasy_i_vnitrni_buffer.commitChanges()
    
                # Zde vytvoříme vrstvu z pásů, uvnitř kterých se vyskytují buffery zmíněné výše
                if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                    spojene_bool = True
                    LayerPasy_i_s_vnitrnim_bufferem0 = processing.run("native:extractbylocation",
                                   {'INPUT': lyr_pasy_i,
                                    'PREDICATE': [1],
                                    'INTERSECT': LayerPasy_i_vnitrni_buffer,
                                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    
                    lyr_pasy_i.removeSelection()
                    processing.run("native:selectbylocation", {'INPUT':lyr_pasy_i,
                                                               'PREDICATE':[1],
                                                               'INTERSECT':LayerPasy_i_vnitrni_buffer,
                                                               'METHOD':0})
                    lyr_pasy_i.invertSelection()
                    zbyvajici_pasy = processing.run("native:saveselectedfeatures", {'INPUT': lyr_pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                    lyr_pasy_i.removeSelection()
                  
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Vnitřní prvky, minimum pro StP + kontrola (----------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
                
            dpb_vlayer_i_bool = False  
            kp_vlayer_i_bool = False    
            
            #řešení účinných dpb a krajinných prvků
            #nalezení účinných DPB a KP uvnitř DPB
            DPB_i_bez_dur = processing.run("native:deleteholes", {'INPUT':lyr_dpb_i,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            if dpb_vlayer_bool:
                dpb_vlayer_i0 = processing.run("native:clip", {'INPUT':dpb_vlayer,'OVERLAY':DPB_i_bez_dur,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                #vytvoření vrstvy podle výběru -> prvních 20 písmen = "standardní orná půda"
                if dpb_vlayer_i0.featureCount() > 0:
                    id_pro_select = []
                    for feat_dpb_vlayer in dpb_vlayer_i0.getFeatures():
                        if feat_dpb_vlayer["kultura"][:20] != "standardní orná půda" :
                            id_pro_select.append(feat_dpb_vlayer.id())
                    dpb_vlayer_i0.selectByIds(id_pro_select)
                    dpb_vlayer_i1 = processing.run("native:saveselectedfeatures", {'INPUT': dpb_vlayer_i0, 'OUTPUT': 'memory:'})['OUTPUT']
                    dpb_vlayer_i0.removeSelection()
                    dpb_vlayer_i = processing.run("native:deleteholes", {'INPUT':dpb_vlayer_i1,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    dpb_vlayer_i_bool = True
            if kp_vlayer_bool:
                kp_vlayer_i0 = processing.run("native:clip", {'INPUT':kp_vlayer,'OVERLAY':DPB_i_bez_dur,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                kp_vlayer_i = processing.run("native:deleteholes", {'INPUT':kp_vlayer_i0,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                if kp_vlayer_i.featureCount() > 0:
                    kp_vlayer_i_bool = True
            
            #spojení vnitřních prvků do jedné vrstvy
            vnitrni_prvky_bool = False
            if ((dpb_vlayer_i_bool == True) and (kp_vlayer_i_bool == False)):
                vnitrni_prvky0 = dpb_vlayer_i
                vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_prvky_bool = True
            elif ((dpb_vlayer_i_bool == False) and (kp_vlayer_i_bool == True)):
                vnitrni_prvky0 = kp_vlayer_i
                vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_prvky_bool = True
            elif ((dpb_vlayer_i_bool == True) and (kp_vlayer_i_bool == True)):
                vnitrni_prvky0 = processing.run("native:mergevectorlayers", {'LAYERS':[dpb_vlayer_i, kp_vlayer_i],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_prvky = processing.run("native:dissolve", {'INPUT':vnitrni_prvky0,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                vnitrni_prvky_bool = True
            else:
                vnitrni_prvky_bool = False
              
            #určení minima pro STP, včetně DSO
            if vnitrni_prvky_bool:
                DPB_bez_vnitrnich_prvku = processing.run("native:difference", {'INPUT':DPB_i_bez_dur,'OVERLAY':vnitrni_prvky,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
            else:
                DPB_bez_vnitrnich_prvku = DPB_i_bez_dur
            #buffer 15 m dovnitř okolo okrajů, kde musí být
            STP_ringbuffery = processing.run("native:multiringconstantbuffer", {'INPUT':DPB_bez_vnitrnich_prvku,'RINGS':1,'DISTANCE':-15,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_ringbuffer = processing.run("native:extractbyattribute", {'INPUT':STP_ringbuffery,'FIELD':'distance','OPERATOR':0,'VALUE':'-15','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_ringbuffer = processing.run("native:clip", {'INPUT':STP_ringbuffer,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            
            STP_zaklad0 = processing.run("native:dissolve", {'INPUT':STP_ringbuffer,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            
            lyr_pasy_i.removeSelection()
            
            vybrane_pasy_id = []
            if spojene_bool:
            
                for pas_feat in zbyvajici_pasy.getFeatures():
                    geom_pas = pas_feat.geometry()
                    for stp_feat in STP_zaklad0.getFeatures():
                        geom_stp = stp_feat.geometry()
                        prunik_geom = geom_pas.intersection(geom_stp)
                        if prunik_geom.area() > 1:
                            vybrane_pasy_id.append(pas_feat.id())
                            
                zbyvajici_pasy.selectByIds(vybrane_pasy_id)
                            
                uzke_siroke_pasy_i = processing.run("native:saveselectedfeatures", {'INPUT': zbyvajici_pasy, 'OUTPUT': 'memory:'})['OUTPUT']
                zbyvajici_pasy.removeSelection()
                
            else:
            
                for pas_feat in lyr_pasy_i.getFeatures():
                    geom_pas = pas_feat.geometry()
                    for stp_feat in STP_zaklad0.getFeatures():
                        geom_stp = stp_feat.geometry()
                        prunik_geom = geom_pas.intersection(geom_stp)
                        if prunik_geom.area() > 1:
                            vybrane_pasy_id.append(pas_feat.id())
                            
                lyr_pasy_i.selectByIds(vybrane_pasy_id)
                            
                uzke_siroke_pasy_i = processing.run("native:saveselectedfeatures", {'INPUT': lyr_pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                lyr_pasy_i.removeSelection()
                
            if uzke_siroke_pasy_i.featureCount() > 0:
                if spojene_bool:
                    for feat in uzke_siroke_pasy_i.getFeatures():
                        geom = feat.geometry()
                        new_feature = QgsFeature()
                        new_feature.setGeometry(geom)
                        #new_feature.setAttributes(feat.attributes())
                        LayerPasy_i_s_vnitrnim_bufferem0.dataProvider().addFeature(new_feature)
                    LayerPasy_i_s_vnitrnim_bufferem0.updateExtents()
                else:
                    LayerPasy_i_s_vnitrnim_bufferem0 = uzke_siroke_pasy_i
                    spojene_bool = True
                    #QgsProject.instance().addMapLayer(LayerPasy_i_s_vnitrnim_bufferem0)
                    
            neo_i_bool = False
            siroke_pasy_area = 0
            pocet_prekroceni_80 = 0
            if spojene_bool:
                #tvorba vrstvy široké pásy
                siroke_pasy_i = QgsVectorLayer("Polygon?crs=EPSG:5514", "Spojené pásy a\npásy s nadlimitní šířkou", "memory")
                siroke_pasy_i_provider = siroke_pasy_i.dataProvider()
                siroke_pasy_i_fields = [QgsField("typ", QVariant.String),
                                      QgsField("NEO(%)", QVariant.Double, prec=1, len=10)
                                 ]
                siroke_pasy_i_provider.addAttributes(siroke_pasy_i_fields)
                siroke_pasy_i.updateFields()    
                
                #pokud existuje NEO, vytvoří se průnik NEO s pásy, které jsou široké
                if neo_bool:
                    lyr_neo_i = processing.run("native:clip", {
                        'INPUT': lyr_neo,
                        'OVERLAY': LayerPasy_i_s_vnitrnim_bufferem0,
                        'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                    if lyr_neo_i.featureCount() > 0 :
                        lyr_neo_i.setName("NEO uvnitř\nspojených pásů")
                        neo_i_bool = True
                        
                        # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                        # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                        symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'black'})
                        # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                        props = {
                            "line_color": "black",     # Barva šrafovacích čar
                            "line_width": "0.15",       # Tloušťka čar (jako textový řetězec)
                            "distance": "0.8",         # Vzdálenost mezi čarami v milimetrech
                            "angle": "45",           # Úhel šrafování
                            "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                        }
                        hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                        # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                        symbol.appendSymbolLayer(hatch_layer)
                        # Aplikace nového symbolu na vrstvu a překreslení
                        lyr_neo_i.renderer().setSymbol(symbol)
                        lyr_neo_i.triggerRepaint()
                        
                        
            #řešení překročení neo na širokých pásech
            #do siroke_pasy_i se umístí geometrie průniků a info o procentech plochy
            siroke_pasy_i_bool = False
            if spojene_bool:
                for feat_spojpas in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                    geom = feat_spojpas.geometry()
                    plocha_siroky_pas = geom.area()
                    plocha_neo_pod_pasem = 0
                    if neo_i_bool:
                        for feat_neo in lyr_neo_i.getFeatures():
                            geom_prunik = geom.intersection(feat_neo.geometry())
                            plocha_neo_pod_pasem = plocha_neo_pod_pasem + geom_prunik.area()
                    
                    new_feature = QgsFeature(siroke_pasy_i.fields())
                    new_feature.setGeometry(geom)
                    new_feature["NEO(%)"] = round((100*plocha_neo_pod_pasem/plocha_siroky_pas),1)
                    if 100*plocha_neo_pod_pasem/plocha_siroky_pas < 80:
                        new_feature["typ"] = "Široký pás mimo NEO"
                        pocet_prekroceni_80 = pocet_prekroceni_80 + 1
                    else:
                        new_feature["typ"] = "Široký pás na NEO"
                    siroke_pasy_i.dataProvider().addFeature(new_feature)
                siroke_pasy_i.updateExtents()
                
                if siroke_pasy_i.featureCount() > 0:
                    siroke_pasy_i_bool = True
            
            #QgsProject.instance().addMapLayer(siroke_pasy_i)
            
            #určení kolik % DPB pokrývají široké pasy
            if siroke_pasy_i_bool:
                for feat in siroke_pasy_i.getFeatures():
                    siroke_pasy_area += feat.geometry().area()
                siroke_pasy_p = 100*(siroke_pasy_area/feat_dpb.geometry().area())
                siroke_pasy_i.setName(f"Spojené pásy a\npásy s nadlimitní šířkou\ncelkem {siroke_pasy_p:.1f} % z DPB")

                #symbologie
                
                categories = []
                colors_cat = ["firebrick", "lime"]
                unique_values = ["Široký pás mimo NEO", "Široký pás na NEO"]
                names_cat = ["Nepokrývá NEO", "Pokrývá NEO"]

                for i, value in enumerate(colors_cat):
                    symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.PolygonGeometry)
                    symbol.setColor(QColor(value))
                    # Získáme první symbolovou vrstvu (fill layer)
                    fill_layer = symbol.symbolLayer(0)
                    if fill_layer:
                        # Nastavíme okraj na průhledný
                        fill_layer.setStrokeColor(QColor(0, 0, 0, 0))  # Průhledný okraj
                        fill_layer.setStrokeWidth(0)  # Můžeme také nastavit šířku okraje na 0
                    category = QgsRendererCategory(unique_values[i], symbol, names_cat[i])
                    categories.append(category)
                renderer = QgsCategorizedSymbolRenderer('typ', categories)  
                if renderer is not None:
                    siroke_pasy_i.setRenderer(renderer)
                siroke_pasy_i.triggerRepaint()
                
            #v případě, že se vyskytují plochy kde je NEO pod 80 % plochy není splněna podmínka
            if pocet_prekroceni_80 > 0:
                podminka_neo80 = "NESPLNĚNO"
            else:
                podminka_neo80 = "SPLNĚNO"
                
            print("siroke pasy plocha:", siroke_pasy_area)
                
            if (siroke_pasy_area/feat_dpb.geometry().area() > 0.1):
                podminka_sirokepasy_plocha = "NESPLNĚNO"
            else:
                podminka_sirokepasy_plocha = "SPLNĚNO"    
                
                
            if siroke_pasy_area > 0:
                STP_zaklad0 = processing.run("native:difference", {'INPUT': STP_zaklad0,
                                                                      'OVERLAY': siroke_pasy_i,
                                                                      'OUTPUT': 'TEMPORARY_OUTPUT',
                                                                      'GRID_SIZE': None})['OUTPUT']
            #přidání DSO
            if dso_bool:
                DSO_pasy_i = processing.run("native:clip", {'INPUT':DSO_pasy,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                STP_zaklad = processing.run("native:mergevectorlayers", {'LAYERS':[STP_zaklad0, DSO_pasy_i],'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            else:
                STP_zaklad = STP_zaklad0
                
            #odečtení aenvi
            if aenvi_i_bool:
                STP_zaklad = processing.run("native:difference", {'INPUT': STP_zaklad,
                                                                      'OVERLAY': lyr_aenvi_i,
                                                                      'OUTPUT': 'TEMPORARY_OUTPUT',        
                                                                      'GRID_SIZE': None})['OUTPUT']
                
            STP_zaklad = processing.run("native:dissolve", {'INPUT':STP_zaklad,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            STP_zaklad = processing.run("native:multiparttosingleparts", {'INPUT':STP_zaklad,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
            
            #odstranění odřezků
            STP_zaklad.startEditing()
            for feat in STP_zaklad.getFeatures():
                if feat.geometry().area() < 1:
                    STP_zaklad.deleteFeature(feat.id())
            STP_zaklad.commitChanges()               
            
            STP_zaklad.setName("STP povinné minimum")
            #QgsProject.instance().addMapLayer(STP_zaklad)
            
            #určeni ďur, pro různé další práce
            diry_i_bool = False
            Layer_diry_i = processing.run("native:difference", {'INPUT':DPB_bez_vnitrnich_prvku,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
            Layer_diry_i.startEditing()
            for feat in Layer_diry_i.getFeatures():
                if feat.geometry().area() < 1:
                    Layer_diry_i.deleteFeature(feat.id())
            Layer_diry_i.commitChanges()
            #QgsProject.instance().addMapLayer(Layer_diry_i)  
            if Layer_diry_i.featureCount() > 0:
                diry_i_bool = True
            
            #vyhodnocení zda STPmin leží unitř STP -> jestli tedy STP slňuje povinné minimum
            plocha_stpmin_v_stp = 0
            plocha_stpmin = 0
            for feat_stpmin in STP_zaklad.getFeatures():
                geom_stpmin = feat_stpmin.geometry()
                plocha_stpmin += geom_stpmin.area()
                if np_i_bool:
                    for feat_stp in lyr_np_i.getFeatures():
                        geom_stp = feat_stp.geometry()
                        geom_prunik = geom_stpmin.intersection(geom_stp)
                        plocha_stpmin_v_stp += geom_prunik.area()
                        
            #podmínka, že stp min leží v stp           
            if abs(plocha_stpmin_v_stp-plocha_stpmin) < 1:
                podminka_stp_v_stpmin = "SPLNĚNO"
            else:
                podminka_stp_v_stpmin = "NESPLNĚNO"
                
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola zda konce trajektorií leží v StP (----------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            vyhodnoceni_konce_pasu = "NEŘEŠENO"
            koncove_body_buffer = QgsVectorLayer(
                "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                "Konce pásů neležící v StP", "memory")

            if lyr_trajektorie_i_bool:
                lyr_trajektorie_i_dissolve = processing.run("native:dissolve", {
                            'INPUT': lyr_trajektorie_i,
                            'FIELD': [],
                            'SEPARATE_DISJOINT': False,
                            'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                if lyr_trajektorie_i_dissolve.featureCount() > 0:
                    lyr_trajektorie_i_dissolve_clip = processing.run("native:clip", {'INPUT':lyr_trajektorie_i_dissolve,'OVERLAY':DPB_bez_vnitrnich_prvku,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    line_layer = processing.run("native:multiparttosingleparts", {
                                            'INPUT': lyr_trajektorie_i_dissolve_clip,
                                            'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
            
                    if siroke_pasy_area > 0:
                        line_layer = processing.run("native:difference", {'INPUT':line_layer,'OVERLAY':siroke_pasy_i,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                        line_layer = processing.run("native:multiparttosingleparts", {
                                            'INPUT': line_layer,
                                            'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]
                        line_layer.startEditing()
                        for feat in line_layer.getFeatures():
                            if feat.geometry().length() < 0.1:
                                line_layer.deleteFeature(feat.id())
                        line_layer.commitChanges()
                        
                    if line_layer.featureCount() > 0:
                        endpoint_layer = QgsVectorLayer("Point?crs=EPSG:5514", "koncove_body_linii", "memory")
                        for feature in line_layer.getFeatures():
                            geom = feature.geometry()
                            if geom.isMultipart():  # Zpracovani vicenasobnych linii
                                line_parts = geom.parts()  # Ziskani jednotlivych casti vicenasobne linie
                                for part in line_parts:
                                    line_points = list(part.vertices())  # Ziskani vsech bodu v linii
                                    # Pridani bodu na zacatek linie
                                    start_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[0]))
                                    start_feature = QgsFeature()
                                    start_feature.setGeometry(start_point_geom)
                                    endpoint_layer.dataProvider().addFeature(start_feature)
                        
                                    # Pridani bodu na konec linie
                                    end_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[-1]))
                                    end_feature = QgsFeature()
                                    end_feature.setGeometry(end_point_geom)
                                    endpoint_layer.dataProvider().addFeature(end_feature)
                            else:  # Zpracovani jednoduchych linii
                                line_points = list(geom.vertices())
                                
                                # Pridani bodu na zacatek linie
                                start_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[0]))
                                start_feature = QgsFeature()
                                start_feature.setGeometry(start_point_geom)
                                endpoint_layer.dataProvider().addFeature(start_feature)
                        
                                # Pridani bodu na konec linie
                                end_point_geom = QgsGeometry.fromPointXY(QgsPointXY(line_points[-1]))
                                end_feature = QgsFeature()
                                end_feature.setGeometry(end_point_geom)
                                endpoint_layer.dataProvider().addFeature(end_feature)
                        
            
                        koncove_body_buffer = processing.run("native:buffer", {
                                                            'INPUT': endpoint_layer,  # pouziti vrstvy koncove_body_linii
                                                            'DISTANCE': 1,  # nastaveno na 1 metr
                                                            'SEGMENTS': 5,
                                                            'END_CAP_STYLE': 0,
                                                            'JOIN_STYLE': 0,
                                                            'MITER_LIMIT': 2,
                                                            'DISSOLVE': False,
                                                            'SEPARATE_DISJOINT': False,
                                                            'OUTPUT': "TEMPORARY_OUTPUT"})["OUTPUT"]  
                        #QgsProject.instance().addMapLayer(koncove_body_buffer)   
                        
                        koncove_body_buffer.removeSelection()
                        
                        processing.run("native:selectbylocation", {'INPUT':koncove_body_buffer,
                                                                   'PREDICATE':[0],
                                                                   'INTERSECT':Layer_diry_i,
                                                                   'METHOD':1})
                        processing.run("native:selectbylocation", {'INPUT':koncove_body_buffer,
                                                                   'PREDICATE':[0],
                                                                   'INTERSECT':lyr_stp_s_aenvi_i,
                                                                   'METHOD':1})
                        
                        if koncove_body_buffer.selectedFeatureCount() > 0:
                            koncove_body_buffer.startEditing()
                            koncove_body_buffer.deleteSelectedFeatures()
                            koncove_body_buffer.commitChanges()
                            
                        if koncove_body_buffer.featureCount() > 0:
                            vyhodnoceni_konce_pasu = "NESPLNĚNO"
                            koncove_body_buffer.setName("Konce pásů neležící v StP")
                            #QgsProject.instance().addMapLayer(koncove_body_buffer)
                        else:
                            vyhodnoceni_konce_pasu = "SPLNĚNO"
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola zda trajektorie leží v osách pásů (---------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            
            if lyr_trajektorie_i_bool:
                #udělá se vnitřní buffer co nejde až do středu, a převede se na linie
                if pasy_i_bool:
                    pasy_i = processing.run("native:deleteholes", {'INPUT':lyr_pasy_i,'MIN_AREA':0,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    vnitrni_buffer = processing.run("native:buffer", {'INPUT': pasy_i ,'DISTANCE': (1-int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':0,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                    vnitrni_buffer_linie = processing.run("native:polygonstolines", {'INPUT':vnitrni_buffer,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #linie se oříznou podle bufferu kolem STP a ďur -> tímto se odstraní "čela" vnitřních bufferů
                    #a zůstanou pouze linky kolem trajektorie
                    #trajektorie tyto linky nesmí protnout, pokud jsou v ose pásu
                    
                    spojene_vrstvy = []
                    if stp_s_aenvi_i_bool:
                        np_buffer = processing.run("native:buffer", {'INPUT': lyr_stp_s_aenvi_i ,'DISTANCE': (int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]        
                        spojene_vrstvy.append(np_buffer)
                    if diry_i_bool:
                        diry_buffer = processing.run("native:buffer", {'INPUT': Layer_diry_i ,'DISTANCE': (int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':1,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                        spojene_vrstvy.append(diry_buffer)
                    if len(spojene_vrstvy) > 0:
                        spojeny_buffer = processing.run("native:mergevectorlayers", {'LAYERS':spojene_vrstvy,'CRS':QgsCoordinateReferenceSystem('EPSG:5514'),'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                        spojeny_buffer = processing.run("native:dissolve", {'INPUT':spojeny_buffer,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"] 
                        vnejsi_linky = processing.run("native:difference", {'INPUT':vnitrni_buffer_linie,'OVERLAY':spojeny_buffer,'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                    else:
                        vnejsi_linky = vnitrni_buffer_linie
                    protinajici_linky = processing.run("native:extractbylocation", {'INPUT':line_layer,'PREDICATE':[0],'INTERSECT': vnejsi_linky,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    #QgsProject.instance().addMapLayer(vnejsi_linky)     
                    #QgsProject.instance().addMapLayer(protinajici_linky) 
                    
                if protinajici_linky.featureCount() > 0:
                    vyhodnoceni_traj_v_ose = "NESPLNĚNO"
                else:
                    vyhodnoceni_traj_v_ose = "SPLNĚNO"
                    
                # ---------------------------------------------------------------------------------------------------------------
                # --------------) Určení odhadu šířky pásů + trajektorie v pásech (----------------------------------------------
                # ---------------------------------------------------------------------------------------------------------------     
                    
                #kontrola že se v pasech vyskytuji trajektorie
                if pasy_i_bool:
                    vnitrni_buffer_pro_osy = processing.run("native:buffer", {'INPUT': pasy_i ,'DISTANCE': (0.2-int(dist)/2),'SEGMENTS':5,'END_CAP_STYLE':1,'JOIN_STYLE':0,'MITER_LIMIT':2,'DISSOLVE':False,'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                    vnitrni_buffer_pro_osy.startEditing()
                    for feat in vnitrni_buffer_pro_osy.getFeatures():
                        if feat.geometry().area() < 1:
                            vnitrni_buffer_pro_osy.deleteFeature(feat.id())
                    vnitrni_buffer_pro_osy.commitChanges()
                    
                    if vnitrni_buffer_pro_osy.featureCount() > 0:
                        id_resene_pasy = []
                        for feat in vnitrni_buffer_pro_osy.getFeatures():
                            id_resene_pasy.append(feat["ZAKRES_ID"])

                        if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                            for feat in LayerPasy_i_s_vnitrnim_bufferem0.getFeatures():
                                if feat["ZAKRES_ID"] in id_resene_pasy:
                                    id_resene_pasy.remove(feat["ZAKRES_ID"])
                
                
                        #pasy neširoke -> ve skutečnosti pasy neuzke a neširoke
                        bez_trajektorie = 0
                        #QgsProject.instance().addMapLayer(pasy_i) 
                        pasy_i.selectByExpression("ZAKRES_ID in {}".format(tuple(id_resene_pasy)))
                        for feat_pas in pasy_i.selectedFeatures():
                            geom_pas = feat_pas.geometry()
                            for feat_traj in lyr_trajektorie_i_dissolve.getFeatures():
                                geom_traj = feat_traj.geometry()
                                geom_prunik = geom_traj.intersection(geom_pas)
                                if (geom_prunik.length() < 1):
                                    bez_trajektorie = bez_trajektorie + 1
                        pasy_i.removeSelection()
                        if bez_trajektorie > 0:
                            vyhodnoceni_pokryti_trajektorie = "NESPLNĚNO"
                        else:
                            vyhodnoceni_pokryti_trajektorie = "SPLNĚNO"
                
                
                
                        pasy_i.selectByExpression("ZAKRES_ID in {}".format(tuple(id_resene_pasy)))
                        pasy_nesiroke_i = processing.run("native:saveselectedfeatures", {'INPUT': pasy_i, 'OUTPUT': 'memory:'})['OUTPUT']
                        pasy_i.removeSelection()
                        pasy_nesiroke_i.setName("pasy neširoke")
                        #QgsProject.instance().addMapLayer(pasy_nesiroke_i)
                        
                        trajektorie_nesiroke_i = processing.run("native:clip", {'INPUT':lyr_trajektorie_i,
                                                                                'OVERLAY':pasy_nesiroke_i,
                                                                                'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                        #QgsProject.instance().addMapLayer(trajektorie_nesiroke_i)
                        
                        if pasy_nesiroke_i.featureCount() > 0:
                            plochy_prekryvu = []
                            for sirka in range(1, 44):
                                buffery = processing.run("native:buffer",
                                                       {'INPUT': trajektorie_nesiroke_i, 'DISTANCE': sirka / 2, 'SEGMENTS': 5,
                                                        'END_CAP_STYLE': 1, 'JOIN_STYLE': 1, 'MITER_LIMIT': 2, 'DISSOLVE': False,
                                                        'SEPARATE_DISJOINT': False, 'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                                plocha_prunik = 0
                                for f1 in buffery.getFeatures():
                                    for f2 in buffery.getFeatures():
                                        if f2 != f1:
                                            prunik = f1.geometry().intersection(f2.geometry())
                                            plocha_prunik = plocha_prunik + prunik.area()
                                plochy_prekryvu.append(round(plocha_prunik))
                            
                            druhe_derivace = [0 for n in range(1,44)]
                            for n in range(1,42):
                                print(n)
                                druhe_derivace[n] = (plochy_prekryvu[n-1] - 2*plochy_prekryvu[n] + plochy_prekryvu[n+1])
                                
                            print("sirka, překryv, druhá derivace")
                            druhe_derivace = [0 for n in range(1,44)]
                            for n in range(1,42):
                                druhe_derivace[n] = (plochy_prekryvu[n-1] - 2*plochy_prekryvu[n] + plochy_prekryvu[n+1])
                                print(n, plochy_prekryvu[n], druhe_derivace[n])
                                
                            # použití z_skore pro nalezení výrazných maxim
                            z_skore = []
                            prumer = sum(druhe_derivace)/len(druhe_derivace)
                            odchylka = np.std(druhe_derivace)
                            
                            print("sirka, z-skore")
                            for nk, clen in enumerate(druhe_derivace):
                                n = nk + 1
                                z_skore_i = (clen - prumer)/odchylka
                                z_skore.append(z_skore_i)
                                print(n, z_skore_i)
                            
                            sirka_odhad = -1
                            for index, number in enumerate(z_skore):
                                if number > 2:
                                    sirka_odhad = index + 1
                                    break
                                    
                            if sirka_odhad < 0:
                                for index, number in enumerate(z_skore):
                                    if number > 1:
                                        sirka_odhad = index + 1
                                        break
                            
                            if sirka_odhad < 0:
                                sirka_odhad = z_skore.index(max(z_skore))+1
                                
                            print("sirka odhad:", sirka_odhad)    
                            
                            
                            if sirka_odhad != int(dist):
                                vyhodnoceni_sirka_pasu = "NESPLNĚNO"
                            else:
                                vyhodnoceni_sirka_pasu = "SPLNĚNO"
                        else:
                            vyhodnoceni_sirka_pasu = "NESPLNĚNO"
                    
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola DPB (plán osevu) vs účinné DPB (------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            chyby_v_dpb = 0
            if dpb_vlayer_bool:
                zkody = []
                ctverce = []
                uzivatele = []
                index = QgsSpatialIndex(dpb_vlayer.getFeatures())
                geometry1 = feat_dpb.geometry()
                # Projdeme všechny polygony v druhé vrstvě a zkontrolujeme, zda se protínají
                dissolve_osev = processing.run("native:dissolve", {'INPUT':lyr_planosevu_i,'FIELD':[],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                for feature2 in dissolve_osev.getFeatures():
                    geometry2 = feature2.geometry()
                    # Zkontrolujeme, zda se geometrie kryjí (intersect)
                    if geometry1.intersects(geometry2):
                        #dáme pryč odřezky
                        geom_prunik = geometry1.intersection(geometry2)
                        if geom_prunik.area() > 1: 
                            zkody.append(feature2["ZKOD"]) 
                            ctverce.append(feature2["CTVEREC"])
                            uzivatele.append(feature2["JI"])
                            print(abs(geom_prunik.area()-feat_dpb.geometry().area()))
                            if ((abs(geom_prunik.area()-feat_dpb.geometry().area()) < 1) and (abs(geom_prunik.area()-geometry2.area()) < 1)):
                                pass
                            else:  
                                #chyby_v_dpb = chyby_v_dpb + 1
                                pass

                
                zkody = list(set(zkody)) 
                ctverce = list(set(ctverce)) 
                uzivatele = list(set(uzivatele)) 
                print(zkody, ctverce, uzivatele)
                
                if len(zkody) == 1:
                    if feat_dpb["ZKOD"] != zkody[0]:
                        chyby_v_dpb += 2
                        print("chyba zkod")
                else:
                    chyby_v_dpb += 2
                    print("chyba zkod")
                    
                if len(ctverce) == 1:
                    if feat_dpb["CTVEREC"] != ctverce[0]:
                        chyby_v_dpb += 3
                        print("chyba ctverce")
                else:
                    chyby_v_dpb += 3
                    print("chyba ctverce")
                    
                if len(uzivatele) == 1:
                    if str(feat_dpb["JIuzivatele"]) != (uzivatele[0]):
                        chyby_v_dpb += 4
                        print("chyba uzivatele")
                else:
                    chyby_v_dpb += 4
                    print("chyba uzivatele")
                    
            
                if chyby_v_dpb > 0:
                    vyhodnoceni_dpb = "NESPLNĚNO"
                else:
                    vyhodnoceni_dpb = "SPLNĚNO"
                    
    
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola sousedících nevhodných plodin (-------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            # kontrola, že sousedi ruzne čeledi

            # Vytvoření prostorového indexu pro rychlé vyhledávání sousedních prvků
            spatial_index_plodinysousedi = QgsSpatialIndex(lyr_pasy_i.getFeatures())
            distance_threshold = 0.1  # Maximální vzdálenost v metrech

            # Seznam nových prvků pro novou vrstvu
            new_features_druh = []

            # Projdi všechny prvky ve vrstvě
            for feature in lyr_pasy_i.getFeatures():
                geom = feature.geometry()
                
                #filtrování prvků podle PLOD_ID -> čeledi
                plodina1 = feature["PLOD_ID"]
                plodina1_celed = plodiny_kody[plodina1][2]
                plodina1_nazev = plodiny_kody[plodina1][0]
                
                    

                # Najdi možné sousedy pomocí prostorového indexu
                neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())

                # Iterace přes sousední prvky
                for neighbor_id in neighbors_ids:
                    neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                    neighbor_geom = neighbor_feature.geometry()
                    
                    plodina2 = neighbor_feature["PLOD_ID"]
                    plodina2_celed = plodiny_kody[plodina2][2]
                    plodina2_nazev = plodiny_kody[plodina2][0]
                    
                    print(plodina1_celed, plodina2_celed)
                    # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                    if feature.id() != neighbor_feature.id() and plodina1_celed == plodina2_celed:
                        print("Stejné čeledi")
                        #kontrola že čeled neni neznama
                        if plodina1_celed != "Neřešená":
                            
                            if (plodina1_nazev.split()[0] in ["Kukuřice", "Čirok"]):
                                print("1")
                                if plodina2_nazev.split()[0] not in ["Kukuřice", "Čirok"]:
                                    pass
                                else:
                                    # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                    if geom.distance(neighbor_geom) <= distance_threshold:
                                        # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                        if feature not in new_features_druh:
                                            new_features_druh.append(feature)
                                        if neighbor_feature not in new_features_druh:
                                            new_features_druh.append(neighbor_feature)
                                            
                            elif (plodina2_nazev.split()[0] in ["Kukuřice", "Čirok"]):
                                print("2")
                                if plodina1_nazev.split()[0] not in ["Kukuřice", "Čirok"]:
                                    pass
                                else:
                                    # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                    if geom.distance(neighbor_geom) <= distance_threshold:
                                        # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                        if feature not in new_features_druh:
                                            new_features_druh.append(feature)
                                        if neighbor_feature not in new_features_druh:
                                            new_features_druh.append(neighbor_feature)
                                            
                            else:
                                print("3")
                                print(plodina1_nazev, plodina2_nazev)
                                # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                                print(geom.distance(neighbor_geom))
                                if geom.distance(neighbor_geom) <= distance_threshold:
                                    
                                    # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                                    if feature not in new_features_druh:
                                        new_features_druh.append(feature)
                                    if neighbor_feature not in new_features_druh:
                                        new_features_druh.append(neighbor_feature)
                            
            print(new_features_druh)
            # Vytvoření nové vrstvy pro sousední prvky
            sousedi_stejne_celedi = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "sousedi_stejne_celedi",
                                          "memory")
            sousedi_stejne_celedi_data_provider = sousedi_stejne_celedi.dataProvider()

            # Přidej stejné atributy jako v původní vrstvě
            sousedi_stejne_celedi_data_provider.addAttributes(lyr_pasy_i.fields())
            sousedi_stejne_celedi.updateFields()

            # Přidání nových prvků do vrstvy
            sousedi_stejne_celedi_data_provider.addFeatures(new_features_druh)

            # Přidání nové vrstvy do projektu
            #QgsProject.instance().addMapLayer(output_layer)
            
            
            if len(new_features_druh) > 0:
                podminka_stejne_celedi = "NESPLNĚNO"
                # Použití nástroje native:dissolve k rozpuštění vrstvy
                dissolved_result_stejplod = processing.run("native:dissolve", {
                    'INPUT': sousedi_stejne_celedi,
                    'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                    'SEPARATE_DISJOINT': False,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })

                # Přidání rozpuštěné vrstvy do projektu
                dissolved_stejplod_layer = dissolved_result_stejplod['OUTPUT']
                dissolved_stejplod_layer.setName("Sousedi_nevyhovujici_plodiny")
                #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)

                # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                multipart_stejplod_result = processing.run("native:multiparttosingleparts", {
                    'INPUT': dissolved_stejplod_layer,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })

                # Přidání vrstvy s rozdělenými prvky do projektu
                multipart_stejplod_layer = multipart_stejplod_result['OUTPUT']
                multipart_stejplod_layer.setName("Sousedi stejné čeledi plodin")
                
                # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'blue'})
                # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                props = {
                    "line_color": "blue",     # Barva šrafovacích čar
                    "line_width": "0.5",       # Tloušťka čar (jako textový řetězec)
                    "distance": "2.5",         # Vzdálenost mezi čarami v milimetrech
                    "angle": "45",           # Úhel šrafování
                    "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                }
                hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                symbol.appendSymbolLayer(hatch_layer)
                # Aplikace nového symbolu na vrstvu a překreslení
                multipart_stejplod_layer.renderer().setSymbol(symbol)
                multipart_stejplod_layer.triggerRepaint()
                
                #QgsProject.instance().addMapLayer(multipart_stejplod_layer)
                
            else:
                podminka_stejne_celedi = "SPLNĚNO"



            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola sousedících plodin stejného rodu (----------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
  
            distance_threshold = 0.1  # Maximální vzdálenost v metrech

            # Seznam nových prvků pro novou vrstvu
            new_features_nof = []

            # Projdi všechny prvky ve vrstvě
            for feature in lyr_pasy_i.getFeatures():
                geom = feature.geometry()
                
                #filtrování prvků podle PLODINA_AK
                plodina1 = feature["PLOD_ID"]
                plodina1_of = plodiny_kody[plodina1][1]

                # Najdi možné sousedy pomocí prostorového indexu
                neighbors_ids = spatial_index_plodinysousedi.intersects(geom.boundingBox())

                # Iterace přes sousední prvky
                for neighbor_id in neighbors_ids:
                    neighbor_feature = lyr_pasy_i.getFeature(neighbor_id)
                    neighbor_geom = neighbor_feature.geometry()
                    
                    plodina2 = neighbor_feature["PLOD_ID"]
                    plodina2_of = plodiny_kody[plodina2][1]
                    
                
                    # Ověř, zda se jedná o jiný prvek a zda má stejný PLOD_ID
                    if feature.id() != neighbor_feature.id() and plodina1_of == "NOF" and plodina2_of == "NOF":
                        # Ověř, zda mají sdílenou hranici nebo jsou velmi blízko
                        if geom.distance(neighbor_geom) <= distance_threshold:
                            # Přidání obou prvků do seznamu, pokud ještě nebyly přidány
                            if feature not in new_features_nof:
                                new_features_nof.append(feature)
                            if neighbor_feature not in new_features_nof:
                                new_features_nof.append(neighbor_feature)

            # Vytvoření nové vrstvy pro sousední prvky
            sousedi_nof = QgsVectorLayer("Polygon?crs=" + lyr_pasy_i.crs().authid(), "sousedi_nof",
                                          "memory")
            sousedi_nof_data_provider = sousedi_nof.dataProvider()

            # Přidej stejné atributy jako v původní vrstvě
            sousedi_nof_data_provider.addAttributes(lyr_pasy_i.fields())
            sousedi_nof.updateFields()

            # Přidání nových prvků do vrstvy
            sousedi_nof_data_provider.addFeatures(new_features_nof)

            # Přidání nové vrstvy do projektu
            #QgsProject.instance().addMapLayer(output_layer)

            if len(new_features_nof) > 0:
                podminka_nof = "NESPLNĚNO"
                # Použití nástroje native:dissolve k rozpuštění vrstvy
                dissolved_result_nof = processing.run("native:dissolve", {
                    'INPUT': sousedi_nof,
                    'FIELD': [],  # Rozpustí všechny prvky bez rozdělení podle atributů
                    'SEPARATE_DISJOINT': False,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })

                # Přidání rozpuštěné vrstvy do projektu
                dissolved_nof_layer = dissolved_result_nof['OUTPUT']
                dissolved_nof_layer.setName("Sousedi_NOF")
                #QgsProject.instance().addMapLayer(dissolved_sousplod_layer)

                # Použití nástroje native:multiparttosingleparts k rozdělení vrstev na jednotlivé části
                multipart_nof_result = processing.run("native:multiparttosingleparts", {
                    'INPUT': dissolved_nof_layer,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })

                # Přidání vrstvy s rozdělenými prvky do projektu
                multipart_nof_layer = multipart_nof_result['OUTPUT']
                multipart_nof_layer.setName("Sousedi s nízkou ochrannou funkcí")
                
                
                # Vytvoření symbolu s transparentní výplní a červeným obrysem.
                # Tím se vytvoří symbolová vrstva typu QgsSimpleFillSymbolLayer, která má obrys nastavený na červenou.
                symbol = QgsFillSymbol.createSimple({'color': '0,0,0,0', 'outline_color': 'red'})
                # Do stávajícího symbolu (který již obsahuje obrys) přidáme další symbolovou vrstvu se šrafováním.
                props = {
                    "line_color": "red",     # Barva šrafovacích čar
                    "line_width": "0.5",       # Tloušťka čar (jako textový řetězec)
                    "distance": "2",         # Vzdálenost mezi čarami v milimetrech
                    "angle": "45",           # Úhel šrafování
                    "fill_color": "0,0,0,0"    # Transparentní výplň (bez barvy)
                }
                hatch_layer = QgsLinePatternFillSymbolLayer.create(props)
                # Přidáme vrstvu se šrafováním nad základní vrstvu (obrys zůstane zobrazen)
                symbol.appendSymbolLayer(hatch_layer)
                # Aplikace nového symbolu na vrstvu a překreslení
                multipart_nof_layer.renderer().setSymbol(symbol)
                multipart_nof_layer.triggerRepaint()
                
                
                #QgsProject.instance().addMapLayer(multipart_nof_layer)
                
            else:
                podminka_nof = "SPLNĚNO"
                
            # ---------------------------------------------------------------------------------------------------------------
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola na brambory (-------------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
                
            #kontrola na brambory
            # Projdi všechny prvky ve vrstvě
            podminka_brambory = "SPLNĚNO"
            for feature in lyr_pasy_i.getFeatures():
                geom = feature.geometry()
                #filtrování prvků podle PLODINA_AK
                if (feature["PLODINA_AK"][:8] == "Brambory" or feature["PLODINA_AK"][:6] == "Batáty"):
                    podminka_brambory = "NESPLNĚNO"
                    break   
                    
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola ploch parcel a DPB (------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            vymera_4ha = "NEŘEŠENO"
            if feat_dpb.geometry().area() < 40000:
                vymera_4ha = "NESPLNĚNO"
            else:
                if kostra_i_bool:
                    plan_osevu_dissolve =  processing.run("native:dissolve", {'INPUT':lyr_planosevu_i,'FIELD':['PLOD_ID'],'SEPARATE_DISJOINT':False,'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                    plan_osevu_dissolve_single = processing.run("native:multiparttosingleparts", {'INPUT':plan_osevu_dissolve,'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
                    for feat in plan_osevu_dissolve_single.getFeatures():
                        if feat.geometry().area() < 50:
                            vymera_4ha = "NESPLNĚNO"
                            break
                        vymera_4ha = "SPLNĚNO"
                
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Řešení spojovací a bezzásahové části StP (-----------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            # Bez kostry/StP se podmínka nehodnotí (stejně jako KP).
            podminka_bezzasahova_cast = "NEŘEŠENO"
            spojovaci_casti = QgsVectorLayer(
                "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                "Spojovací části\nstabilizačních ploch", "memory")
            bezzasahova_cast = QgsVectorLayer(
                "Polygon?crs=" + lyr_dpb_i.crs().authid(),
                "Bezzásahové části\nstabilizačních ploch", "memory")

            # Filtr pro výběr polygonů, které nemají PLOD_ID 471 nebo 50082
            expression = '"PLOD_ID" NOT IN (471, 50082)'
         
            # Vytvoření nové vrstvy pro filtrované prvky
            filtered_layer_bool = False
            if kostra_i_bool:
                filtered_layer = QgsVectorLayer("Polygon?crs=" + lyr_planosevu_i.crs().authid(), "Filtered Polygons", "memory")
         
                # Přidání filtrovaných prvků do nové vrstvy
                features = lyr_planosevu_i.getFeatures(QgsFeatureRequest().setFilterExpression(expression))
                filtered_layer.dataProvider().addFeatures(features)
                filtered_layer_bool = True
                # Přidání vrstvy do projektu
                #QgsProject.instance().addMapLayer(filtered_layer)
         
                print("Filtrovaná vrstva byla přidána do projektu.")
         
            if filtered_layer_bool:
                # Vytvoření bufferů
                buffer_distance = 0.01
             
                # Plochý buffer
                flat_buffer_layer = QgsVectorLayer("Polygon?crs=" + filtered_layer.crs().authid(), "Flat Buffer", "memory")
         
                flat_buffer_features = []
                for feature in filtered_layer.getFeatures():
                    geom = feature.geometry()
                    flat_buffer_geom = geom.buffer(buffer_distance, 5)
                    if flat_buffer_geom:
                        new_feature = QgsFeature()
                        new_feature.setGeometry(flat_buffer_geom)
                        flat_buffer_features.append(new_feature)
             
                flat_buffer_layer.dataProvider().addFeatures(flat_buffer_features)
                #QgsProject.instance().addMapLayer(flat_buffer_layer)
             
                print("Plochý buffer byl přidán do projektu.")
         
             
                # Rozpuštění výsledného bufferu
                dissolved_result = processing.run(
                    "native:dissolve",
                    {
                        'INPUT': flat_buffer_layer,
                        'FIELD': [],
                        'SEPARATE_DISJOINT': False,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    }
                )
         
                dissolved_layer = dissolved_result['OUTPUT']
                #QgsProject.instance().addMapLayer(dissolved_layer)
             
                print("Rozpuštěný buffer byl přidán do projektu.")
         
                # Převod multipart na singlepart
                singleparts_result = processing.run(
                    "native:multiparttosingleparts",
                    {
                        'INPUT': dissolved_layer,
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    }
                )
             
                singleparts_layer = singleparts_result['OUTPUT']
                QgsProject.instance().addMapLayer(singleparts_layer)
         
                print("Vrstva s rozdělenými geometriemi byla přidána do projektu.")
         
                # Iterace přes jednotlivé části
                all_intersections = []
                for feature in singleparts_layer.getFeatures():
                    # Nastavení aktuálního prvku jako vybraného
                    singleparts_layer.selectByIds([feature.id()])
             
                    # Vytvoření bufferu pro aktuální prvek
                    buffer_result = processing.run(
                        "native:buffer",
                        {
                            'INPUT': QgsProcessingFeatureSourceDefinition(singleparts_layer.id(), selectedFeaturesOnly=True),
                            'DISTANCE': 4.99,
                            'SEGMENTS': 5,
                            'END_CAP_STYLE': 1,
                            'JOIN_STYLE': 1,
                            'MITER_LIMIT': 2,
                            'DISSOLVE': False,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        }
                    )
         
                    buffer_layer = buffer_result['OUTPUT']
             
    
                    # Průnik bufferu s vrstvou PLOD_ID 471
                    intersection_result = processing.run(
                        "native:intersection",
                        {
                            'INPUT': buffer_layer,
                            'OVERLAY': lyr_np_i,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        }
                    )
             
                    intersection_layer = intersection_result['OUTPUT']
                    all_intersections.append(intersection_layer)
                    singleparts_layer.removeSelection()
                
         
                # Sloučení všech výsledků průniků do jedné vrstvy
                merge_result = processing.run(
                    "native:mergevectorlayers",
                    {
                        'LAYERS': all_intersections,
                        'CRS': singleparts_layer.crs().authid(),
                        'OUTPUT': 'TEMPORARY_OUTPUT'
                    }
                )
             
                spojovaci_casti = merge_result['OUTPUT']
                #QgsProject.instance().addMapLayer(spojovaci_casti)
             
                print("Všechny výsledky průniků byly sloučeny do jedné vrstvy a přidány do projektu.")
         
                # Vyhodnocení dotyků a průniků ve vrstvě "Sloučený"
                spojovaci_casti.startEditing()
             
                for feature in spojovaci_casti.getFeatures():
                    geom = feature.geometry()
                    podminka_bezzasahova_cast = "SPLNĚNO"
                    for other_feature in spojovaci_casti.getFeatures():
                        if feature.id() != other_feature.id():
                            other_geom = other_feature.geometry()
                            if geom.touches(other_geom) or geom.intersects(other_geom):
                                podminka_bezzasahova_cast = "NESPLNĚNO"
                                break
                    spojovaci_casti.updateFeature(feature)
                spojovaci_casti.commitChanges()
            

                field_names_vrstva = spojovaci_casti.fields().names()
                rozdil_vrstva = []
                for element in field_names_vrstva:
                    if (element in ["ZKOD", "CTVEREC"]) == False:
                        rozdil_vrstva.append(element)
                spojovaci_casti.startEditing()
                fields_to_delete = []
                for fieldname_to_delete in rozdil_vrstva:
                    fieldindex_to_delete = spojovaci_casti.fields().indexFromName(fieldname_to_delete)
                    if fieldindex_to_delete == -1:
                        continue
                    fields_to_delete.append(fieldindex_to_delete)
                spojovaci_casti.dataProvider().deleteAttributes(fields_to_delete)
                spojovaci_casti.updateFields()
                spojovaci_casti.commitChanges()
                
                QgsProject.instance().removeMapLayer(singleparts_layer)
                #QgsProject.instance().addMapLayer(spojovaci_casti)
                
                spojovaci_casti.setName("Spojovací části\nstabilizačních ploch")
                sym = spojovaci_casti.renderer().symbol()
                syms = sym[0]
                syms.setColor(QColor("brown"))
                syms.setStrokeColor(QColor("transparent"))
         
                
                # vytvoření bezzasahove časti
                pocet_np = lyr_np_i.featureCount()
                
                bezzasahova_cast = processing.run("native:difference", {'INPUT':lyr_np_i,
                                                                        'OVERLAY':spojovaci_casti,
                                                                        'OUTPUT':'TEMPORARY_OUTPUT','GRID_SIZE':None})["OUTPUT"]
                
                bezzasahova_cast.setName("Bezzásahové části\nstabilizačních ploch")
                sym = bezzasahova_cast.renderer().symbol()
                syms = sym[0]
                syms.setColor(QColor("#7df1de"))
                syms.setStrokeColor(QColor("transparent"))
            
                for feat in bezzasahova_cast.getFeatures():
                    if feat.geometry().area() < 1:
                        bezzasahova_cast.deleteFeature(feat.id())
                bezzasahova_cast.commitChanges()
                
                for feat in bezzasahova_cast.getFeatures():
                    if feat.geometry().area() < 1:
                        bezzasahova_cast.deleteFeature(feat.id())
                bezzasahova_cast.commitChanges()
                
                pocet_bc = bezzasahova_cast.featureCount()
                
                if pocet_bc > pocet_np:
                    if podminka_bezzasahova_cast == "SPLNĚNO":
                        podminka_bezzasahova_cast = "NESPLNĚNO"
                        
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Kontrola krajinných prvků (--------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
            # KP na DPB nemusí být; bez vrstvy/prvků se podmínka nehodnotí.
            vyhodnoceni_KP = "NEŘEŠENO"
            # kontrola krajinných prvků  
            if kp_vlayer_bool:
                try:
                    KP_v_planu = processing.run("native:extractbyattribute", {'INPUT':lyr_planosevu_i,'FIELD':'PLOD_ID','OPERATOR':0,'VALUE':'50082','OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    kp_v_planu_bool = True
                    #QgsProject.instance().addMapLayer(KP_v_planu)
                except:
                    kp_v_planu_bool = False
                try:
                    KP_v_DPB = processing.run("native:clip", {'INPUT':kp_vlayer,'OVERLAY':lyr_dpb_i,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]
                    kp_v_dpb_bool = True
                    #QgsProject.instance().addMapLayer(KP_v_DPB)
                except:
                    kp_v_dpb_bool = False
                
                if ((kp_v_planu_bool==True) and (kp_v_dpb_bool == True)):
                    prunik_KP = processing.run("native:clip", {'INPUT':KP_v_DPB,'OVERLAY':KP_v_planu,'OUTPUT':'TEMPORARY_OUTPUT'})["OUTPUT"]  
                    
                    plocha_kp_v_dpb = 0
                    plocha_kp_v_planu = 0
                    plocha_punik = 0
                    for feat in KP_v_DPB.getFeatures():
                        plocha_kp_v_dpb += feat.geometry().area()
                    for feat in KP_v_planu.getFeatures():
                        plocha_kp_v_planu += feat.geometry().area()
                    for feat in prunik_KP.getFeatures():
                        plocha_punik += feat.geometry().area()
                    if ((abs(plocha_punik - plocha_kp_v_dpb) < 1) and (abs(plocha_punik - plocha_kp_v_planu) < 1)):
                        vyhodnoceni_KP = "SPLNĚNO"
                    else:
                        vyhodnoceni_KP = "NESPLNĚNO"
                else:
                    vyhodnoceni_KP = "NESPLNĚNO"     
            # ---------------------------------------------------------------------------------------------------------------
        
        
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) DSO pro vykreslení v mapce (linka) (-----------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
                    
            if dso_bool:
                lyr_dso_i = processing.run("native:clip", {
                    'INPUT': lyr_dso,
                    'OVERLAY': lyr_dpb_i,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                lyr_dso_i.setName("DSO")
                sym = lyr_dso_i.renderer().symbol()
                syms = sym[0]
                syms.setColor(QColor("#1b8aec"))
                syms.setStrokeColor(QColor("transparent"))
                syms.setWidth(0.1)
                lyr_dso_i.triggerRepaint()
                
            # ---------------------------------------------------------------------------------------------------------------

            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Symbologie vrstev (----------------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            """
            if dso_bool:
                lyr_dso_i = processing.run("native:clip", {
                    'INPUT': lyr_dso,
                    'OVERLAY': lyr_dpb_i,
                    'OUTPUT': 'TEMPORARY_OUTPUT'})["OUTPUT"]
                lyr_dso_i.setName("DSO")
                sym = lyr_dso_i.renderer().symbol()
                syms = sym[0]
                syms.setColor(QColor("#1b8aec"))
                syms.setStrokeColor(QColor("transparent"))
                syms.setWidth(0.1)
                lyr_dso_i.triggerRepaint()
                
     
            if lyr_trajektorie_i_bool:
                lyr_trajektorie_i.setName("Trajektorie")
                symbol = QgsSymbol.defaultSymbol(QgsWkbTypes.GeometryType.LineGeometry)
                symbol.setColor(QColor("black"))
                symbol.setWidth(0.1)
                renderer = QgsSingleSymbolRenderer(symbol)
                lyr_trajektorie_i.setRenderer(renderer)
                lyr_trajektorie_i.triggerRepaint()
                lyr_trajektorie_i.setName("Trajektorie")
            """
            limit30.setName(f"Překročený podélný\nsklon\n{(100 * plocha_limit30 / lyr_maska3_area):.1f} %")
            
            sym = limit30.renderer().symbol()
            syms = sym[0]
            syms.setColor(QColor.fromRgb(22, 229, 47))
            syms.setStrokeColor(QColor("transparent"))
            
            #limit30.renderer().symbol().setColor(QColor.fromRgb(22, 229, 47))
            limit30.triggerRepaint()
            
            
            # ---------------------------------------------------------------------------------------------------------------
           
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Příprava pro tisk + stránka s vyhodnocením (---------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------
      
            #vyska a sirka dpb pro velikost jednotlivych obrazku v pdf
            sirka_pdf = feat_dpb.geometry().boundingBox().xMaximum() - feat_dpb.geometry().boundingBox().xMinimum()
            vyska_pdf = feat_dpb.geometry().boundingBox().yMaximum() - feat_dpb.geometry().boundingBox().yMinimum()
                    
            if vyska_pdf > sirka_pdf:
                pass
            else:
                pass

            pomer_stran = vyska_pdf / sirka_pdf
            if pomer_stran > 10 / 6:
                map1_vyska = 100
                map1_sirka = 100 / pomer_stran
            else:
                map1_vyska = 60 * pomer_stran
                map1_sirka = 60
                   
         
            title = QgsLayoutItemLabel(layout_psp)
            title.setText("Vyhodnocení projektu PSP")
            title.setFont(QFont("Arial", 23))
            layout_psp.addLayoutItem(title)
            title.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            hlavicka = QgsLayoutItemLabel(layout_psp)
            hlavicka.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 1")
            hlavicka.setFont(QFont("Arial", 12))
            layout_psp.addLayoutItem(hlavicka)
            hlavicka.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            subtitle2 = QgsLayoutItemLabel(layout_psp)
            subtitle2.setText("Vytištěno dne: " + strftime('%d.%m.%Y', localtime(
                time.time())) + "     ID procesu: " + id_procesu + "\nID uživatele: " + kod_uzivatele + \
                "\nVýměra DPB: %.4f" %(feat_dpb.geometry().area()/10000) + " ha\nEPSG: " + \
                EPSG + "\nŠířka pásů: " + str(dist) + \
                " m")
            subtitle2.setFont(QFont("Arial", 8))
            layout_psp.addLayoutItem(subtitle2)
            subtitle2.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
            
            
            texty_all = ["\n\nSplnění všech podmínek.",
                         
            "\n\nDPB v Projektu musí být účinný v době podání Projektu k ověření na SPU, hodnoty atributů ZKOD a\nCTVEREC v souboru „planu_osevu_psp“ musí být " + \
            "platné.Kultura DPB musí být R (orná půda).",
            
            "\n\nKódy plodin v atributu PLOD_ID v souboru Projektu s názvem\"plan_osevu_psp\" musí odpovídat platnému\ncentrálnímu číselníku plodin " + \
            "MZe.",
            
            "\n\nCelková výměra zákresů s plodinami na DPB musí být shodná s výměrou příslušného DPB v Projektu. Míra\nshody bude nejméně 99.99 % výměry " + \
            "zákresů s plodinami budou vypočítány z jejich geometrie s přesností\nna čtyři desetinná místa. Jejich hodnoty budou přiřazeny každému polygonu v" +\
            "souboru Projektu\n\"plan_osevu_psp\" v atributu VYMZAKRES.",
            
            "\n\nAtribut ZAKRES_ID v souboru Projektu s názvem \"plan_osevu_psp\" bude " +\
            "obsahovat jedinečné číselné\nidentifikátory (a bude vyplněn).",
            
            "\n\nHodnoty atributu SIRKA_PASU v souboru Projektu s názvem \"trajektorie\" musí být celé číslo. Šířka pásů v\nProjektu bude v metrech a bude odpovídat kolmé " + \
            "vzdálenosti vzájemně sousedících paralelních trajektorií v\nsouvislém celku. " +\
            "Hodnoty atributu budou přiřazeny každému prvku v souboru \"trajektorie\".",
            
            "\n\nVelikost výměry DPB v Projektu bude nejméně 4 ha. Navíc plocha žádné zemědělské parcely není menší než\n50 m².",
            
            "\n\nCelková výměra částí plochy DPB se sklonitostí menší než 3 procenta bude maximálně 25% výměry DPB.\n(Parametr bude povinný pro Projekty podávané " +\
            "v JŽ od roku 2026.)",
            
            "\n\nTrajektorie musí pokrývat celý DPB v Projektu, jak je uvedeno v tomto " + \
            "metodickém postupu. Trajektorie v\nkaždém souvislém celku DPB musí být paralelní.",
            
            "\n\nTrajektorie v každém souvislém celku musí mít vzájemně stejnou vzdálenost v celém Projektu.",
            
            "\n\nTrajektorie musí procházet osami všech příslušných pásů na každém DPB v Projektu.",
            
            "\n\nProcentuální podíl výměry celkové plochy segmentů pásů, jejichž podélný sklon je větší nebo je roven\npolovině sklonu terénu, případně je větší než 7 %, " +\
            "nesmí být větší než 30 % výměry celkové plochy se\nsklonitostí větší než 3 % na DPB.",
            
            "\n\nSouvislé plochy s výměrou nad 1 ha a s podélným sklonem nad 7 % (ZEOP) nesmí být větší než 2 ha a jejich\ncelková výměra na DPB nesmí překročit 10 % " +\
            "výměry celkové plochy se sklonitostí větší než 3 % na DPB.",
            
            "\n\nMaximální celková výměra spojených pásů a pásů s nadlimitní šířkou na "+\
            "každém DPB v Projektu nesmí být\nvětší než 10 % z výměry DPB.",
            
            "\n\nKaždá souvislá plocha spojených pásů musí ležet alespoň osmdesáti " + \
            "procenty své výměry na částech DPB s\nerozní ohrožeností kategorie NEO.",
            
            "\n\nProcentuální podíl výměry stabilizačních ploch musí být minimálně 5 % a "+\
            "maximálně 30 % z výměry DPB.",
            
            "\n\nKonce pásů se musí vždy napojovat na stabilizační plochu.",
            
            "\n\nOkolo hranic DPB a krajinných prvků musí být stabilizační plocha v rozsahu obalové zóny o šíři nejméně\n15 m. Osu obalové zóny tvoří hranice DPB nebo " +\
            "krajinných prvků. Na DSO musí být navrženy stabilizační\nplochy nejméně v "  \
            "rozsahu obalové vrstvy okolo každé osy DSO o šíři minimálně 7,5 m.",
            
            "\n\nKaždá stabilizační plocha v Projektu musí obsahovat spojovací i bezzásahovou část.",
            
            "\n\nNa dílu půdního bloku jsou pěstovány plodiny náležející do různých čeledí rostlin podle definice botanického\nsystému klasifikace plodin s výjimkou kukuřice a čiroku,které lze pravidelně střídat v pásech s ostatními\nplodinami z čeledi lipnicovité (Poaceae).",
            
            "\n\nNa dílu půdního bloku nejsou pravidelně střídány výhradně plodiny s nízkou ochrannou funkcí uvedené v\n§ 8 odst. 1 písm. c) nařízení vlády upravujícího pravidla podmíněnosti plateb zemědělcům nebo mák setý.",                
            
            "\n\nNa díle půdního bloku se nevyskytují brambory či batáty.",
            
            "\n\nKrajinné prvky na DPB musí odpovídat zákresu v LPIS."]
                

            if ((vyhodnoceni_dpb == "SPLNĚNO") and (podminka_plody_seznam == "SPLNĚNO") and (podminka_plochy_parcel == "SPLNĚNO") and (podminka_jedinecnost == "SPLNĚNO") and \
                (vyhodnoceni_sirka_pasu == "SPLNĚNO") and (vymera_4ha == "SPLNĚNO") and (vyhodnoceni_pokryti_trajektorie == "SPLNĚNO") and (vyhodnoceni_traj_v_ose == "SPLNĚNO") and \
                (podminka_limit30 == "SPLNĚNO") and (podminka_zeop == "SPLNĚNO") and (podminka_sirokepasy_plocha == "SPLNĚNO") and (podminka_neo80 == "SPLNĚNO") and \
                (podminka_plocha_np == "SPLNĚNO") and (vyhodnoceni_konce_pasu != "NESPLNĚNO") and (podminka_stp_v_stpmin == "SPLNĚNO") and (podminka_stejne_celedi == "SPLNĚNO") and \
                (podminka_brambory == "SPLNĚNO") and (podminka_bezzasahova_cast != "NESPLNĚNO") and (vyhodnoceni_KP != "NESPLNĚNO") and (podminka_nof == "SPLNĚNO")
                ):
                vyhodnoceni_celek = "SPLNĚNO"
                dobre_dpb += 1
                vyhodnoceni_celek_dpb = "SPLNĚNO"
            else:
                vyhodnoceni_celek = "NESPLNĚNO"
                spatne_dpb += 1
                vyhodnoceni_celek_dpb = "NESPLNĚNO"
            
            podminky_all = [vyhodnoceni_celek, vyhodnoceni_dpb, podminka_plody_seznam, podminka_plochy_parcel, podminka_jedinecnost, vyhodnoceni_sirka_pasu, vymera_4ha, \
                            podminka_maska3_area, vyhodnoceni_pokryti_trajektorie, vyhodnoceni_sirka_pasu, vyhodnoceni_traj_v_ose, podminka_limit30, podminka_zeop, podminka_sirokepasy_plocha, \
                            podminka_neo80, podminka_plocha_np, vyhodnoceni_konce_pasu, podminka_stp_v_stpmin, podminka_bezzasahova_cast, \
                            podminka_stejne_celedi, podminka_nof, podminka_brambory, vyhodnoceni_KP]
            radky_all = [1,2,2,4,2,3,2,2,2,1,1,3,2,2,2,1,1,3,1,3, 2,1,1]
            
            podminky_text_nesplneno = QgsLayoutItemLabel(layout_psp)
            nesplnene_text = 6*"\n"
            for podminka, radky in zip(podminky_all, radky_all):
                nesplnene_text += (radky-1)*"\n"
                if podminka == "SPLNĚNO":
                    nesplnene_text += "\n\n"
                elif podminka == "NEŘEŠENO":
                    nesplnene_text += "NEŘEŠENO\n\n"
                else:
                    nesplnene_text += "NESPLNĚNO\n\n"
            podminky_text_nesplneno.setText(nesplnene_text)
            podminky_text_nesplneno.setFont(QFont("Arial", 8))
            podminky_text_nesplneno.setFontColor(QColor(250, 0, 0))
            layout_psp.addLayoutItem(podminky_text_nesplneno)
            podminky_text_nesplneno.attemptMove(QgsLayoutPoint(160, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
            
            
            podminky_text_splneno = QgsLayoutItemLabel(layout_psp)
            splnene_text = 6*"\n"
            for podminka, radky in zip(podminky_all, radky_all):
                splnene_text += (radky-1)*"\n"
                if podminka == "SPLNĚNO":
                    splnene_text += "SPLNĚNO\n\n"
                else:
                    splnene_text += 2*"\n"
            podminky_text_splneno.setText(splnene_text)
            podminky_text_splneno.setFont(QFont("Arial", 8))
            layout_psp.addLayoutItem(podminky_text_splneno)
            podminky_text_splneno.attemptMove(QgsLayoutPoint(160, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
            
            
            
            text_splneno = QgsLayoutItemLabel(layout_psp)
            splneno_text = 4*"\n"
            for textik, radky, podminka in zip(texty_all, radky_all, podminky_all):
                if podminka == "SPLNĚNO":
                    splneno_text += textik
                else:
                    splneno_text += (radky+1)*"\n"
            text_splneno.setText(splneno_text)
            text_splneno.setFont(QFont("Arial", 8))
            layout_psp.addLayoutItem(text_splneno)
            text_splneno.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
            
            text_nesplneno = QgsLayoutItemLabel(layout_psp)
            nesplneno_text = 4*"\n"
            for textik, radky, podminka in zip(texty_all, radky_all, podminky_all):
                if podminka == "NESPLNĚNO":
                    nesplneno_text += textik
                else:
                    nesplneno_text += (radky+1)*"\n"
            text_nesplneno.setText(nesplneno_text)
            text_nesplneno.setFont(QFont("Arial", 8))
            text_nesplneno.setFontColor(QColor(250, 0, 0))
            layout_psp.addLayoutItem(text_nesplneno)
            text_nesplneno.attemptMove(QgsLayoutPoint(8, 18, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
            
            
            
            
            title = QgsLayoutItemLabel(layout_psp)
            title.setText("Vyhodnocení projektu PSP")
            title.setFont(QFont("Arial", 23))
            layout_psp.addLayoutItem(title)
            title.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)

            hlavicka = QgsLayoutItemLabel(layout_psp)
            hlavicka.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 2")
            hlavicka.setFont(QFont("Arial", 12))
            layout_psp.addLayoutItem(hlavicka)
            hlavicka.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Vykreslení map (-------------------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------

            map1 = QgsLayoutItemMap(layout_psp)
            map1.setRect(20, 20, 20, 20)

            if limit30_i_bool:
                layers1 = [lyr_trajektorie_i, limit30, lyr_dpb_i]
            else:
                layers1 = [lyr_trajektorie_i, lyr_dpb_i]
            rectangle = feat_dpb.geometry().boundingBox()
            map1.setExtent(rectangle)

            layout_psp.addLayoutItem(map1)
            map1.setLayers(layers1)
            map1.attemptMove(
                QgsLayoutPoint(int(35 - map1_sirka / 2), int(115 - map1_vyska / 2), QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            map1.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            newFontSG = QFont("MS Shell Dlg 2", 10)
            newFontSL = QFont("MS Shell Dlg 2", 10)

            legend1 = QgsLayoutItemLegend(layout_psp)
            strom1 = QgsLayerTree()
            for lyr in layers1:
                strom1.addLayer(lyr)
            legend1.model().setRootGroup(strom1)
            layout_psp.addLayoutItem(legend1)
            legend1.attemptMove(QgsLayoutPoint(65, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)

            legend1.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend1.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend1.setSymbolHeight(2)
            legend1.setSymbolWidth(4)
            legend1.adjustBoxSize()
            
            
            map1text = QgsLayoutItemLabel(layout_psp)
            map1text.setText("Místa s překročeným podélným sklonem")
            map1text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map1text)
            map1text.attemptMove(QgsLayoutPoint(15, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            

            map2 = QgsLayoutItemMap(layout_psp)
            map2.setRect(20, 20, 20, 20)
            layers2 = []
            if zeop_i_bool:
                layers2.append(zeop)           
            layers2.append(lyr_dpb_i)   
            rectangle = feat_dpb.geometry().boundingBox()
            map2.setExtent(rectangle)
            layout_psp.addLayoutItem(map2)
            map2.setLayers(layers2)
            map2.attemptMove(
                QgsLayoutPoint(int(140 - map1_sirka / 2), int(115 - map1_vyska / 2),
                               QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            map2.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            legend2 = QgsLayoutItemLegend(layout_psp)
            strom2 = QgsLayerTree()
            for lyr in layers2:
                strom2.addLayer(lyr)
            legend2.model().setRootGroup(strom2)
            layout_psp.addLayoutItem(legend2)
            legend2.attemptMove(QgsLayoutPoint(170, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)

            legend2.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend2.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend2.setSymbolHeight(2)
            legend2.setSymbolWidth(4)
            legend2.adjustBoxSize()
            
            map2text = QgsLayoutItemLabel(layout_psp)
            map2text.setText("Značně erozně ohrožené plochy")
            map2text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map2text)
            map2text.attemptMove(QgsLayoutPoint(115, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)



            map3 = QgsLayoutItemMap(layout_psp)
            map3.setRect(20, 20, 20, 20)
            layers3 = [lyr_maska3_invert_i, lyr_dpb_i]
            rectangle = feat_dpb.geometry().boundingBox()
            map3.setExtent(rectangle)
            layout_psp.addLayoutItem(map3)
            map3.setLayers(layers3)

            map3.attemptMove(
                QgsLayoutPoint(int(35 - map1_sirka / 2), int(232 - map1_vyska / 2), QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            map3.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            legend3 = QgsLayoutItemLegend(layout_psp)
            strom3 = QgsLayerTree()
            for lyr in layers3:
                strom3.addLayer(lyr)
            legend3.model().setRootGroup(strom3)
            layout_psp.addLayoutItem(legend3)
            legend3.attemptMove(QgsLayoutPoint(65, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)

            legend3.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend3.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend3.setSymbolHeight(2)
            legend3.setSymbolWidth(4)
            legend3.adjustBoxSize()
            
            map3text = QgsLayoutItemLabel(layout_psp)
            map3text.setText("Plochy s nízkým sklonem")
            map3text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map3text)
            map3text.attemptMove(QgsLayoutPoint(24, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
            
            title2 = QgsLayoutItemLabel(layout_psp)
            title2.setText("Vyhodnocení projektu PSP")
            title2.setFont(QFont("Arial", 23))
            layout_psp.addLayoutItem(title2)
            title2.attemptMove(QgsLayoutPoint(8, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)

            hlavicka2 = QgsLayoutItemLabel(layout_psp)
            hlavicka2.setText(f"ČTVEREC: {feat_dpb['CTVEREC']}\nZKOD: {feat_dpb['ZKOD']}\nČÁST 3")
            hlavicka2.setFont(QFont("Arial", 12))
            layout_psp.addLayoutItem(hlavicka2)
            hlavicka2.attemptMove(QgsLayoutPoint(150, 5, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            
            
            if vyhodnoceni_celek_dpb == "NESPLNĚNO":
                ctverec = QgsLayoutItemShape(layout_psp)
                ctverec.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec)
                ctverec.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                ctverec.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec.symbol()
                syms = sym[0]
                syms.setColor(QColor("#ff0501"))
                syms.setStrokeColor(QColor("transparent"))

                ctverec2 = QgsLayoutItemShape(layout_psp)
                ctverec2.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec2)
                ctverec2.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                ctverec2.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec2.symbol()
                syms = sym[0]
                syms.setColor(QColor("#ff0501"))
                syms.setStrokeColor(QColor("transparent"))
                
                ctverec3 = QgsLayoutItemShape(layout_psp)
                ctverec3.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec3)
                ctverec3.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                ctverec3.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec3.symbol()
                syms = sym[0]
                syms.setColor(QColor("#ff0501"))
                syms.setStrokeColor(QColor("transparent"))
            else:
                ctverec = QgsLayoutItemShape(layout_psp)
                ctverec.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec)
                ctverec.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                ctverec.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec.symbol()
                syms = sym[0]
                syms.setColor(QColor("#5aee15"))
                syms.setStrokeColor(QColor("transparent"))

                ctverec2 = QgsLayoutItemShape(layout_psp)
                ctverec2.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec2)
                ctverec2.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=1)
                ctverec2.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec2.symbol()
                syms = sym[0]
                syms.setColor(QColor("#5aee15"))
                syms.setStrokeColor(QColor("transparent"))
                
                ctverec3 = QgsLayoutItemShape(layout_psp)
                ctverec3.setShapeType(QgsLayoutItemShape.Shape.Rectangle)
                layout_psp.addLayoutItem(ctverec3)
                ctverec3.attemptMove(QgsLayoutPoint(150, 20, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
                ctverec3.attemptResize(QgsLayoutSize(50, 8, QgsUnitTypes.LayoutUnit.LayoutMillimeters))
                sym = ctverec3.symbol()
                syms = sym[0]
                syms.setColor(QColor("#5aee15"))
                syms.setStrokeColor(QColor("transparent"))   
            
            
            map5 = QgsLayoutItemMap(layout_psp)
            map5.setRect(20, 20, 20, 20)
            
            layers5 = []
            if podminka_stejne_celedi == "NESPLNĚNO":
                layers5.append(multipart_stejplod_layer)
            if podminka_nof == "NESPLNĚNO":
                layers5.append(multipart_nof_layer)
            layers5.append(lyr_planosevu_i)
            
            rectangle = feat_dpb.geometry().boundingBox()
            map5.setExtent(rectangle)
            layout_psp.addLayoutItem(map5)
            map5.setLayers(layers5)

            map5.attemptMove(
                QgsLayoutPoint(int(35 - map1_sirka / 2), int(115 - map1_vyska / 2),
                               QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            map5.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            legend5 = QgsLayoutItemLegend(layout_psp)
            strom5 = QgsLayerTree()
            for lyr in layers5:
                strom5.addLayer(lyr)
            legend5.model().setRootGroup(strom5)
            layout_psp.addLayoutItem(legend5)
            legend5.attemptMove(QgsLayoutPoint(65, 70, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)

            legend5.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend5.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend5.setSymbolHeight(2)
            legend5.setSymbolWidth(4)
            legend5.adjustBoxSize()
            
            popisek5 = QgsLayoutItemLabel(layout_psp)
            popisek5.setText(f"Výměra veškerých plodin: {vymera_plan_osevu:.4f} ha\nVýměra DPB: {(feat_dpb.geometry().area()/10000):.4f} ha")
            popisek5.setFont(newFontSG)
            layout_psp.addLayoutItem(popisek5)
            popisek5.attemptMove(QgsLayoutPoint(65, 65, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            
            map5text = QgsLayoutItemLabel(layout_psp)
            map5text.setText("Výměry zemědělských parcel")
            map5text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map5text)
            map5text.attemptMove(QgsLayoutPoint(15, 57, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            
        

            map6 = QgsLayoutItemMap(layout_psp)
            map6.setRect(20, 20, 20, 20)
            if koncove_body_buffer.featureCount() > 0:
                layers6 = [koncove_body_buffer]
            else:
                layers6 = []
            if dso_bool:
                layers6.append(lyr_dso_i)
            if spojovaci_casti.featureCount() > 0:
                layers6.append(spojovaci_casti)
            if bezzasahova_cast.featureCount() > 0:
                layers6.append(bezzasahova_cast)
            layers6.append(lyr_dpb_i)
            
            
            rectangle = feat_dpb.geometry().boundingBox()
            map6.setExtent(rectangle)
            layout_psp.addLayoutItem(map6)
            map6.setLayers(layers6)

            map6.attemptMove(
                QgsLayoutPoint(int(35 - map1_sirka / 2), int(232 - map1_vyska / 2),
                               QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            map6.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            legend6 = QgsLayoutItemLegend(layout_psp)
            strom6 = QgsLayerTree()
            for lyr in layers6:
                strom6.addLayer(lyr)
            legend6.model().setRootGroup(strom6)
            layout_psp.addLayoutItem(legend6)
            legend6.attemptMove(QgsLayoutPoint(65, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)

            legend6.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend6.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend6.setSymbolHeight(2)
            legend6.setSymbolWidth(4)
            legend6.adjustBoxSize()
            
            map6text = QgsLayoutItemLabel(layout_psp)
            map6text.setText("Stabilizační plochy")
            map6text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map6text)
            map6text.attemptMove(QgsLayoutPoint(24, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)



            map7 = QgsLayoutItemMap(layout_psp)
            map7.setRect(20, 20, 20, 20)
            layers7 = []
            if neo_i_bool:
                layers7.append(lyr_neo_i)
            if LayerPasy_i_vnitrni_buffer.featureCount() > 0:
                layers7.append(siroke_pasy_i)
            layers7.append(lyr_dpb_i)
            rectangle = feat_dpb.geometry().boundingBox()
            map7.setExtent(rectangle)
            layout_psp.addLayoutItem(map7)
            map7.setLayers(layers7)

            map7.attemptMove(
                QgsLayoutPoint(int(140 - map1_sirka / 2), int(232 - map1_vyska / 2),
                               QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            map7.attemptResize(QgsLayoutSize(map1_sirka, map1_vyska, QgsUnitTypes.LayoutUnit.LayoutMillimeters))

            legend7 = QgsLayoutItemLegend(layout_psp)
            strom7 = QgsLayerTree()
            for lyr in layers7:
                strom7.addLayer(lyr)
            legend7.model().setRootGroup(strom7)
            layout_psp.addLayoutItem(legend7)
            legend7.attemptMove(QgsLayoutPoint(170, 192, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)

            legend7.setStyleFont(QgsLegendStyle.Style.Subgroup, newFontSG)
            legend7.setStyleFont(QgsLegendStyle.Style.SymbolLabel, newFontSL)
            legend7.setSymbolHeight(2)
            legend7.setSymbolWidth(4)
            legend7.adjustBoxSize()
            
            map7text = QgsLayoutItemLabel(layout_psp)
            map7text.setText("Spojené/široké pásy a plochy NEO")
            map7text.setFont(QFont("MS Shell Dlg 2", 10))
            layout_psp.addLayoutItem(map7text)
            map7text.attemptMove(QgsLayoutPoint(115, 174, QgsUnitTypes.LayoutUnit.LayoutMillimeters), page=2)
            # ---------------------------------------------------------------------------------------------------------------
            
            
            # ---------------------------------------------------------------------------------------------------------------
            # --------------) Tisk jednotlivých DPB (------------------------------------------------------------------------
            # ---------------------------------------------------------------------------------------------------------------


            layout_tisk = manager.layoutByName(layoutName)
            exporter = QgsLayoutExporter(layout_tisk)
    
            dir_dokumenty = os.path.join(Exportdir_path, f"Dokumentaceprojektu{id_cele}", "Jednotlive_DPB")
            if os.path.isdir(dir_dokumenty) == False:
                os.makedirs(dir_dokumenty)
    
            exporter.exportToPdf(dir_dokumenty + "\\Dokumentace_psp_" + str(pocitadlo_dpb) + ".pdf",
                                 QgsLayoutExporter.PdfExportSettings())
    
            seznam_pdf.append(dir_dokumenty + "\\Dokumentace_psp_" + str(pocitadlo_dpb) + ".pdf")
            
            #progress bar
            posun = int(25 + (pocitadlo_dpb / pocet_dpb) * 60)
            self.dlg.progressBar_vypocet.setValue(posun)
            self.dlg.progressBar_vypocet.setFormat(f"Bylo vyřešeno {pocitadlo_dpb}/{pocet_dpb} DPB")
    
            pocitadlo_dpb += 1
            
            
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Spojení pdf pro jednotlivé DPB do jednoho souboru (--------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------

        for pdf in seznam_pdf:
            merger.append(pdf)
            
        merger.write(os.path.join(Exportdir_path, f"Dokumentaceprojektu{id_cele}", f"Dokumentace{id_cele}.pdf"))
        merger.close()
        # ---------------------------------------------------------------------------------------------------------------
        
        
        # ---------------------------------------------------------------------------------------------------------------
        # --------------) Výpis vyhodnocení (----------------------------------------------------
        # ---------------------------------------------------------------------------------------------------------------
        
        self.dlg.progressBar_vypocet.setValue(100)
        self.dlg.progressBar_vypocet.setFormat("Hotovo")
        
        QMessageBox.information(None,
        "Start",
        f"Ověření dokončeno.\nPočty\nDPB vyhovuje: {dobre_dpb}\nDPB nevyhovuje: {spatne_dpb}")
        
        
        

    def select_tisk(self):
        filename = QFileDialog.getExistingDirectory(
            self.dlg, "Select output folder ", "", QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks)
        self.dlg.lineEdit_tisk.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)
        
        

    def select_kontrola(self):
        filename = QFileDialog.getExistingDirectory(
            self.dlg, "Select output folder ", "", QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks)
        self.dlg.lineEdit_vysledkykontroly.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_output_maska(self):
        filename, _filter = QFileDialog.getOpenFileName(
            self.dlg, "Select output file ", "", "*.shp")
        self.dlg.lineEdit_maska.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_output_trajektorie(self):
        filename, _filter = QFileDialog.getOpenFileName(
            self.dlg, "Select output file ", "", "*.shp")
        self.dlg.lineEdit_trajektorie.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_output_dmt(self):
        filter = "Images(*.tif *.tiff)"
        filename, _filter = QFileDialog.getOpenFileName(self.dlg, "Select output file ", "", filter)
        self.dlg.lineEdit_dmt.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_output_np(self):
        filename, _filter = QFileDialog.getOpenFileName(
            self.dlg, "Select output file ", "", "*.shp")
        self.dlg.lineEdit_np.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_tiskdir(self):
        filename = QFileDialog.getExistingDirectory(
            self.dlg, "Select output folder ", "", QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks)
        self.dlg.lineEdit_kostraprojektu.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_cestalinie(self):
        filename = QFileDialog.getExistingDirectory(
            self.dlg, "Select output folder ", "", QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks)
        self.dlg.lineEdit_cestalinie.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def select_cestakostraxlsx(self):
        filename = QFileDialog.getExistingDirectory(
            self.dlg, "Select output folder ", "", QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks)
        self.dlg.lineEdit_kostraxlsx.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def webciselnik(self):
        url = "https://mze.gov.cz/public/app/lpisext/lpis/ng/plodiny-plpis/"
        webbrowser.open(url, new=0, autoraise=True)       
        
    def select_zip(self):
        filename, _filter = QFileDialog.getOpenFileName(
            self.dlg, "Select output file ", "", "*.zip")
        self.dlg.lineEdit_cestazip.setText(filename)
        
        diacritic_pattern = re.compile(r'[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]')
        
        if diacritic_pattern.search(filename):
            self.iface.messageBar().pushMessage("Špatná cesta", "Vaše cesta obsahuje diakritické znaky. " +\
            "To může způsobit problémy s některými funkcemi QGIS. MoPSP nebude pracovat správně. " +\
            "Změňte cestu pro složku.", level=Qgis.MessageLevel.Critical)

    def odstraneni_vrstvy(self):
        self.nacitani_vrstev()
        pass
    
    def zmena_textu_tlacitko(self):
        
        if self.dlg.checkBox_vcetnepasu.isChecked():
            if self.dlg.checkBox_ulozeniGPS.isChecked():
                self.dlg.pushButton_vykrslenilinii.setText("Vykreslit trajektorie + pásy + vybrané dodatečné trajektorie, trajektorie uložit pro GNSS")
            else:
                self.dlg.pushButton_vykrslenilinii.setText("Vykreslit trajektorie + pásy + vybrané dodatečné trajektorie")
            
        else:
            if self.dlg.checkBox_ulozeniGPS.isChecked():
                self.dlg.pushButton_vykrslenilinii.setText("Vykreslit trajektorie + vybrané dodatečné trajektorie, trajektorie uložit pro GNSS")
            else:
                self.dlg.pushButton_vykrslenilinii.setText("Vykreslit trajektorie + vybrané dodatečné trajektorie")
    
  

    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            if self.dockwidget == None:
                self.dockwidget = MoPSPDockWidget()
                
            
            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            self.iface.addDockWidget(_RIGHT_DOCK, self.dockwidget)
            self.dockwidget.show()

            self.dlg = self.dockwidget
            self.nacitani_vrstev_s_textem()

            try:
                ensure_jtsk_grids(iface=self.iface, show_guide_on_fail=True)
                maybe_show_install_info()
            except Exception:
                pass
            
            soucasna_verze = "MoPSP_v03"
            #response = requests.get("https://spu.gov.cz/pudni-sluzba/pasove-stridani-plodin/zasuvny-modul-mopsp/ke-stazeni") #nove
            try:
                response = requests.get(
                    "https://www.spucr.cz/pudni-sluzba/pasove-stridani-plodin/zasuvny-modul-mopsp/ke-stazeni",
                    timeout=10)
                if response.status_code == 200:
                    tree = html.fromstring(response.content)
                    elements = tree.xpath('//*[@class="downloadFile "]')
                    sedi_nejaka_verze = 0
                    for element in elements:
                        print(element.text_content())
                        if ((soucasna_verze == element.text_content()) or (soucasna_verze + ".zip" == element.text_content())):
                            sedi_nejaka_verze += 1
                     
                    if sedi_nejaka_verze == 0:
                        try:
                            url = "https://www.spucr.cz/pudni-sluzba/pasove-stridani-plodin/zasuvny-modul-mopsp"
                            webbrowser.open(url, new=0, autoraise=True)       
                        except:
                            self.iface.messageBar().pushMessage("Chyba připojení", "Nepodařilo se otevřít stránku SPÚ", level=Qgis.MessageLevel.Warning, duration=5)
                            
                        box = QMessageBox()
                        box.setText("Máte zastaralou verzi MoPSP.\nProveďte její aktualizaci.\n\nNa stránce www.spucr.cz\nsi stáhněte nový instalační soubor ZIP.\n\nV zásuvných modulech QGIS\nodinstalujte starou verzi MoPSP\na nainstalujte nový soubor ZIP.")
                        box.setStandardButtons(QMessageBox.StandardButton.Ok)
                        box.exec()
                else:
                    self.iface.messageBar().pushMessage("Chyba připojení", "Nepodařilo se zkontrolovat aktuální verze", level=Qgis.MessageLevel.Warning, duration=5)
            except Exception:
                self.iface.messageBar().pushMessage("Chyba připojení", "Nepodařilo se zkontrolovat aktuální verze", level=Qgis.MessageLevel.Warning, duration=5)

            settings = QSettings("MoPSP", "Settings") 
            saved_certifikat_value = settings.value("certifikat", defaultValue=0)
            if saved_certifikat_value == 0:
                box2 = QMessageBox()
                box2.setText("Na stránce www.spucr.cz je informace o instalaci certifikátu, bez kterého nebude\nmodul plně funkční.")
                box2.setStandardButtons(QMessageBox.StandardButton.Ok)
                dont_repeat_btn = box2.addButton("Příště neukazovat", QMessageBox.ButtonRole.ActionRole)
                box2.exec()
                
                if box2.clickedButton() == dont_repeat_btn:
                    settings.setValue("certifikat", 1)


            self.dlg.pushButton_nacitani.clicked.connect(self.nacitani_vrstev_s_textem)
            self.dlg.pushButton_vypocetsklonu.clicked.connect(self.spusteni_vypoctu)
            self.dlg.pushButton_kontrolaprojektu.clicked.connect(self.kontrola_projektu_prep)

            self.dlg.pushButton_vykrslenilinii.clicked.connect(self.vykresleni_linii)
            self.dlg.pushButton_vyhlazeni.clicked.connect(self.vyhlazeni_linii)
            self.dlg.pushButton_vypocetdostupnosti.clicked.connect(self.vypocet_dostupnosti)
            self.dlg.pushButton_importkostry.clicked.connect(self.import_kostry)

            self.dlg.pushButton_kostraprojektu.clicked.connect(self.select_tiskdir)
            self.dlg.pushButton_cestalinie.clicked.connect(self.select_cestalinie)
            self.dlg.pushButton_kostraxlsx.clicked.connect(self.select_cestakostraxlsx)
            self.dlg.pushButton_selectkontrola.clicked.connect(self.select_kontrola)
            self.dlg.pushButton_selectslozkazip.clicked.connect(self.select_zip)

            self.dlg.pushButton_downloaddmr.clicked.connect(self.download_dmr)
            self.dlg.pushButton_downloadwfs.clicked.connect(self.download_wfs)
            self.dlg.pushButton_downloadkp.clicked.connect(self.download_kp)

            self.dlg.pushButton_ciselnikplodin.clicked.connect(self.webciselnik)
                    
            self.dlg.checkBox_vcetnepasu.stateChanged.connect(self.zmena_textu_tlacitko)
            self.dlg.checkBox_ulozeniGPS.stateChanged.connect(self.zmena_textu_tlacitko)
            QgsProject.instance().layersRemoved.connect(self.odstraneni_vrstvy)


