├── collections ├── profiles │ ├── preview │ │ ├── img_01.png │ │ └── img_02.png │ ├── style │ │ ├── Profilo.qml │ │ ├── Fincatura.qml │ │ ├── Traccia_profilo.qml │ │ └── Vertici.qml │ ├── processing │ │ └── profiles.py │ └── models │ │ └── Traccia_profilo.model3 ├── distance-measurements │ ├── preview │ │ ├── dimensions_line.png │ │ ├── distance_measure.png │ │ └── dimensions_polygon.png │ ├── symbol │ │ ├── distance_measure.xml │ │ ├── dimensions_polygon.xml │ │ └── dimensions_line.xml │ └── style │ │ ├── distance_measure.qml │ │ └── line_dimensions.qml └── processing-scripts │ ├── preview │ └── frazionamenti_img_01.png │ └── processing │ ├── qnorth.py │ ├── calcoli.py │ └── frazionamenti.py ├── README.md └── metadata.ini /collections/profiles/preview/img_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/profiles/preview/img_01.png -------------------------------------------------------------------------------- /collections/profiles/preview/img_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/profiles/preview/img_02.png -------------------------------------------------------------------------------- /collections/distance-measurements/preview/dimensions_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/distance-measurements/preview/dimensions_line.png -------------------------------------------------------------------------------- /collections/distance-measurements/preview/distance_measure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/distance-measurements/preview/distance_measure.png -------------------------------------------------------------------------------- /collections/distance-measurements/preview/dimensions_polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/distance-measurements/preview/dimensions_polygon.png -------------------------------------------------------------------------------- /collections/processing-scripts/preview/frazionamenti_img_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/faunalia/QGIS-Resources/HEAD/collections/processing-scripts/preview/frazionamenti_img_01.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Faunalia Sharing Resources 2 | 3 | This repository contains styles, scripts, models and other QGIS 4 | resources that can be shared with the QGIS Resources Sharing. 5 | 6 | ## Collections 7 | 8 | [**Distance Measurements**](https://github.com/faunalia/QGIS-Resources/tree/master/collections/distance-measurements): automatically measure line length or polygon perimeter 9 | and area with style! 10 | 11 | ![Dimension Line](collections/distance-measurements/preview/dimensions_line.png) 12 | 13 | ![Dimension Polygon](collections/distance-measurements/preview/dimensions_polygon.png) 14 | 15 | ![Distance Measurement](collections/distance-measurements/preview/distance_measure.png) 16 | 17 | [**Profiles**](https://github.com/faunalia/QGIS-Resources/tree/master/collections/profiles): collection of Processing Scripts and style to generate profiles 18 | on the Map Canvas. Special thanks to @Korto19 19 | 20 | ![Profile 1](collections/profiles/preview/img_01.png) 21 | 22 | ![Profile 2](collections/profiles/preview/img_02.png) 23 | -------------------------------------------------------------------------------- /metadata.ini: -------------------------------------------------------------------------------- 1 | [general] 2 | collections=distance-measurements,processing-scripts,profiles 3 | 4 | [distance-measurements] 5 | author=Paolo Cavallini 6 | email=cavallini@faunalia.it 7 | name=Distance Measurement Styles 8 | tags=symbol, style, arrow, distance, geometry 9 | description=Faunalia Repository of measurements symbology and style 10 | qgis_minimum_version=3.00 11 | qgis_maximum_version=3.98 12 | license=GNU GPL 3 13 | license_file=LICENSE.md 14 | preview=preview/dimensions_line.png, preview/dimensions_polygon.png 15 | 16 | [processing-scripts] 17 | author=Matteo Ghetta 18 | email=matteo.ghetta@faunalia.eu 19 | name=Faunalia Processing Scripts 20 | tags=processing, script, python, analysis, spatial 21 | description=Faunalia Repository of Processing scripts 22 | qgis_minimum_version=3.00 23 | qgis_maximum_version=3.98 24 | license=GNU GPL 3 25 | license_file=LICENSE.md 26 | preview=preview/frazionamenti_img_01.png 27 | 28 | [profiles] 29 | author=Giulio Fattori, Matteo Ghetta 30 | email=matteo.ghetta@faunalia.eu 31 | name=Processing Scripts for Profiling 32 | tags=processing, script, python, analysis, spatial, profiles, geology 33 | description=Faunalia Repository of Processing Profiling Scripts 34 | qgis_minimum_version=3.00 35 | qgis_maximum_version=3.98 36 | license=GNU GPL 3 37 | license_file=license 38 | preview=preview/img_01.png, preview/img_02.png 39 | -------------------------------------------------------------------------------- /collections/processing-scripts/processing/qnorth.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | *************************************************************************** 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | *************************************************************************** 12 | """ 13 | 14 | from qgis.PyQt.QtCore import QCoreApplication 15 | from qgis.core import (QgsProcessing, 16 | QgsFeatureSink, 17 | QgsProcessingException, 18 | QgsProcessingAlgorithm, 19 | QgsProcessingParameterFeatureSource, 20 | QgsProcessingParameterFeatureSink) 21 | from qgis import processing 22 | import operator 23 | 24 | 25 | class QNorth(QgsProcessingAlgorithm): 26 | 27 | INPUT = 'INPUT' 28 | OUTPUT = 'OUTPUT' 29 | 30 | def tr(self, string): 31 | return QCoreApplication.translate('Processing', string) 32 | 33 | def createInstance(self): 34 | return QNorth() 35 | 36 | def name(self): 37 | return 'qnorth' 38 | 39 | def displayName(self): 40 | return self.tr('QNorth') 41 | 42 | def group(self): 43 | return self.tr('Example scripts') 44 | 45 | def groupId(self): 46 | return 'examplescripts' 47 | 48 | def shortHelpString(self): 49 | return self.tr("Restituisce il punto più a nord di un layer lineare") 50 | 51 | def initAlgorithm(self, config=None): 52 | 53 | self.addParameter( 54 | QgsProcessingParameterFeatureSource( 55 | self.INPUT, 56 | self.tr('Layer in ingresso'), 57 | [QgsProcessing.TypeVectorPoint] 58 | ) 59 | ) 60 | 61 | self.addParameter( 62 | QgsProcessingParameterFeatureSink( 63 | self.OUTPUT, 64 | self.tr('Punto a nord'), 65 | QgsProcessing.TypeVectorPoint 66 | ) 67 | ) 68 | 69 | def processAlgorithm(self, parameters, context, feedback): 70 | 71 | source = self.parameterAsSource( 72 | parameters, 73 | self.INPUT, 74 | context 75 | ) 76 | 77 | if source is None: 78 | raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) 79 | 80 | (sink, dest_id) = self.parameterAsSink( 81 | parameters, 82 | self.OUTPUT, 83 | context, 84 | source.fields(), 85 | source.wkbType(), 86 | source.sourceCrs() 87 | ) 88 | 89 | # feedback.pushInfo('CRS is {}'.format(source.sourceCrs().authid())) 90 | 91 | if sink is None: 92 | raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) 93 | 94 | total = 100.0 / source.featureCount() if source.featureCount() else 0 95 | features = source.getFeatures() 96 | 97 | d = {} 98 | 99 | for current, feature in enumerate(features): 100 | 101 | d[feature] = feature.geometry().asPoint().y() 102 | 103 | dd = sorted(d.items(), key=operator.itemgetter(1)) 104 | 105 | maximumy = dd[-1][0] 106 | 107 | sink.addFeature(maximumy, QgsFeatureSink.FastInsert) 108 | 109 | return {self.OUTPUT: dest_id} 110 | 111 | -------------------------------------------------------------------------------- /collections/profiles/style/Profilo.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 0 47 | 0 48 | 1 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 0 139 | 140 | 156 | 0 157 | generatedlayout 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | fid 166 | 167 | 1 168 | 169 | -------------------------------------------------------------------------------- /collections/profiles/style/Fincatura.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 0 47 | 0 48 | 1 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 118 | 119 | 120 | 121 | 122 | 123 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 0 175 | 176 | 192 | 0 193 | generatedlayout 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | fid 208 | 209 | 1 210 | 211 | -------------------------------------------------------------------------------- /collections/profiles/style/Traccia_profilo.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 0 102 | 0 103 | 1 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 159 | 160 | 161 | 162 | 163 | 164 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 0 206 | 207 | 223 | 0 224 | generatedlayout 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | begin 236 | 237 | 1 238 | 239 | -------------------------------------------------------------------------------- /collections/distance-measurements/symbol/distance_measure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 200 | 201 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /collections/processing-scripts/processing/calcoli.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | *************************************************************************** 5 | * GF 13.03.2020 * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | *************************************************************************** 12 | """ 13 | 14 | from PyQt5.QtCore import QCoreApplication, QVariant 15 | from qgis.core import (QgsProcessing, 16 | QgsFeatureSink, 17 | QgsFeature, 18 | QgsField, 19 | QgsLayerItem, 20 | QgsProcessingParameterString, 21 | QgsProcessingParameterNumber, 22 | QgsProcessingParameterVectorLayer, 23 | QgsProcessingParameterBoolean, 24 | QgsProcessingParameterEnum, 25 | QgsProcessingAlgorithm, 26 | QgsProcessingParameterFeatureSource, 27 | QgsProcessingParameterFeatureSink, 28 | QgsProcessingParameterField, 29 | QgsFeatureRequest, 30 | QgsProcessingParameterDefinition, 31 | ) 32 | import datetime 33 | 34 | 35 | class CalcoliSuiCampiProcessingAlgorithm(QgsProcessingAlgorithm): 36 | """ 37 | Algorithm that generate vari calcoli sui campi di un layer 38 | """ 39 | INPUT = 'INPUT' 40 | OUTPUT = 'OUTPUT' 41 | OPTIONAL_START_VALUE = 'optional_start_value' 42 | OPERATION_FIELD_NAME = 'operation_field_name' 43 | WEIGHT_FIELD_NAME = 'weight_field_name' 44 | RESULT_FIELD_NAME = 'result_field_name' 45 | OUTPUT_OPERATION = 'output_operation' 46 | ID_CALC = 'id_calc' 47 | ID_DEC = 'id_dec' 48 | 49 | 50 | def tr(self, string): 51 | """ 52 | Returns a translatable string with the self.tr() function. 53 | """ 54 | return QCoreApplication.translate('Processing', string) 55 | 56 | def createInstance(self): 57 | return CalcoliSuiCampiProcessingAlgorithm() 58 | 59 | def name(self): 60 | """ 61 | Returns the algorithm name, used for identifying the algorithm. This 62 | string should be fixed for the algorithm, and must not be localised. 63 | The name should be unique within each provider. Names should contain 64 | lowercase alphanumeric characters only and no spaces or other 65 | formatting characters. 66 | """ 67 | return 'calcoli_sui_campi' 68 | 69 | def displayName(self): 70 | """ 71 | Returns the translated algorithm name, which should be used for any 72 | user-visible display of the algorithm name. 73 | """ 74 | return self.tr('Aggiunge un campo calcolato') 75 | 76 | def group(self): 77 | """ 78 | Returns the name of the group this algorithm belongs to. This string 79 | should be localised. 80 | """ 81 | return self.tr('FGscripts') 82 | 83 | def groupId(self): 84 | """ 85 | Returns the unique ID of the group this algorithm belongs to. This 86 | string should be fixed for the algorithm, and must not be localised. 87 | The group id should be unique within each provider. Group id should 88 | contain lowercase alphanumeric characters only and no spaces or other 89 | formatting characters. 90 | """ 91 | return 'FGscripts' 92 | 93 | def shortHelpString(self): 94 | """ 95 | Returns a localised short helper string for the algorithm. This string 96 | should provide a basic description about what the algorithm does and the 97 | parameters and outputs associated with it.. 98 | """ 99 | return self.tr("Replica il layer aggiungendo un nuovo campo con: \n progressiva,\ 100 | % sul totale, media mobile, media ponderata, variazione, variazione % \ncalcolata con ordinamento per id record\ 101 | \nIl campo generato ha lo stesso nome dell'origine più un suffisso automatico che richiama il calcolo es: 'lunghezza_prog'\ 102 | \nLa Media Ponderata è un indice e non genera layer risultante\ 103 | \nIl nuovo layer ha per nome Calc_timestamp\ 104 | \nLA VARIAZIONE E LA VARIAZIONE % NECESSITANO DI LAYER NON TEMPORANEI\ 105 | \nLa variazione % da 0 a un qualsiasi valore è indicata con 9999999\ 106 | \n \ 107 | \n **** PARAMETRI AVANZATI **** \ 108 | \nOpzionalmente:\ 109 | \n- il valore della progressiva di partenza\ 110 | \n- ulteriore suffisso es: 'lunghezza_prog_gruppoA'\ 111 | \n- campo con l'id del record utilizzato dall'ordinamento del calcolo\ 112 | \n- 5 decimali anzichè 3 se le % lo richiedessero") 113 | 114 | def initAlgorithm(self, config=None): 115 | """ 116 | Here we define the inputs and output of the algorithm, along with some other properties. 117 | """ 118 | # We add the input vector features source. It can have any kind of geometry. 119 | self.addParameter( 120 | QgsProcessingParameterFeatureSource( 121 | self.INPUT, 122 | self.tr('Input layer'), 123 | [QgsProcessing.TypeVector] 124 | ) 125 | ) 126 | 127 | optional_start_value = QgsProcessingParameterNumber( 128 | self.OPTIONAL_START_VALUE, 129 | self.tr('Optional start value for progressive (default = 0)'), 0 130 | ) 131 | optional_start_value.setFlags(optional_start_value.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 132 | self.addParameter(optional_start_value) 133 | 134 | result_field_name = QgsProcessingParameterString( 135 | self.RESULT_FIELD_NAME, 136 | self.tr('Optional new Field name suffix'), ' ' 137 | ) 138 | result_field_name.setFlags(result_field_name.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 139 | self.addParameter(result_field_name) 140 | 141 | id_calc = QgsProcessingParameterBoolean( 142 | self.ID_CALC, 143 | self.tr('Optional add Id calculation column'), 0 144 | ) 145 | id_calc.setFlags(id_calc.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 146 | self.addParameter(id_calc) 147 | 148 | id_dec = QgsProcessingParameterBoolean( 149 | self.ID_DEC, 150 | self.tr('Optional 5 decimal places'), 0 151 | ) 152 | id_dec.setFlags(id_dec.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 153 | self.addParameter(id_dec) 154 | 155 | 156 | self.addParameter(QgsProcessingParameterField(self.OPERATION_FIELD_NAME, 157 | 'Choose operation field', 158 | type=QgsProcessingParameterField.Numeric, 159 | parentLayerParameterName=self.INPUT)) 160 | 161 | self.addParameter(QgsProcessingParameterEnum(self.OUTPUT_OPERATION, 'Option calc: Prog, %, M Mobile, M Ponderata, Var, Var %', 162 | options=['PROGRESSIVA','PERCENTUALE','MEDIA MOBILE','MEDIA PONDERATA','VARIAZIONE','VARIAZIONE %'], 163 | allowMultiple=False, defaultValue = None)) 164 | 165 | self.addParameter(QgsProcessingParameterField(self.WEIGHT_FIELD_NAME, 166 | self.tr('Choose weight field'), 167 | optional = 1, 168 | type=QgsProcessingParameterField.Numeric, 169 | parentLayerParameterName=self.INPUT)) 170 | 171 | 172 | # We add a feature sink in which to store our processed features (this 173 | # usually takes the form of a newly created vector layer when the 174 | # algorithm is run in QGIS). 175 | self.addParameter( 176 | QgsProcessingParameterFeatureSink( 177 | self.OUTPUT, 178 | self.tr('Calc_' + str(datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S"))) 179 | ) 180 | ) 181 | 182 | def processAlgorithm(self, parameters, context, feedback): 183 | """ 184 | Here is where the processing itself takes place. 185 | """ 186 | source = self.parameterAsSource( 187 | parameters, 188 | self.INPUT, 189 | context) 190 | 191 | source_vl = source.materialize(QgsFeatureRequest()) 192 | 193 | optional_start_value = self.parameterAsDouble( 194 | parameters, 195 | self.OPTIONAL_START_VALUE, 196 | context) 197 | operation_field_name = self.parameterAsString( 198 | parameters, 199 | self.OPERATION_FIELD_NAME, 200 | context) 201 | weight_field_name = self.parameterAsString( 202 | parameters, 203 | self.WEIGHT_FIELD_NAME, 204 | context) 205 | output_operation = self.parameterAsString( 206 | parameters, 207 | self.OUTPUT_OPERATION, 208 | context) 209 | result_field_name = self.parameterAsString( 210 | parameters, 211 | self.RESULT_FIELD_NAME, 212 | context) 213 | id_calc = self.parameterAsBoolean( 214 | parameters, 215 | self.ID_CALC, 216 | context) 217 | id_dec = self.parameterAsBoolean( 218 | parameters, 219 | self.ID_DEC, 220 | context) 221 | 222 | if result_field_name == " ": 223 | result_field_name = "" 224 | else : 225 | result_field_name = "_" + result_field_name 226 | 227 | if output_operation == '0': 228 | result_field_name = "_prog" + result_field_name #progressiva 229 | if output_operation == '1': 230 | result_field_name = "_%_tot" + result_field_name #percentuale 231 | if output_operation == '2': 232 | result_field_name = "_mobile_av" + result_field_name #media mobile 233 | if output_operation == '3': 234 | result_field_name = "_weight_av" + result_field_name #indice media pesata 235 | if output_operation == '4': 236 | result_field_name = "_delta" + result_field_name #variazione 237 | if output_operation == '5': 238 | result_field_name = "_delta%" + result_field_name #variazione percentuale 239 | 240 | if id_dec == 1: 241 | nd = 5 242 | else: 243 | nd = 3 244 | 245 | fields = source.fields() 246 | result_field_name = operation_field_name + result_field_name 247 | fields.append(QgsField(result_field_name,QVariant.Double,'',20,nd)) 248 | if id_calc == 1: 249 | fields.append(QgsField('Id_calc',QVariant.Double,'',20,0)) 250 | 251 | (sink, dest_id) = self.parameterAsSink( 252 | parameters, 253 | self.OUTPUT, 254 | context, fields, source.wkbType(), source.sourceCrs()) 255 | 256 | #feedback.pushInfo('Get features') 257 | features = source.getFeatures() 258 | 259 | 260 | # Running the processing algorithm 261 | feedback.pushInfo('Calculate ' + output_operation +": "+ result_field_name + '\n') 262 | 263 | if output_operation == '0': 264 | k = 0 265 | partial = optional_start_value 266 | 267 | if output_operation == '1': 268 | k = 1 269 | partial = 0 270 | sum_values = 0 271 | for f in source.getFeatures(): 272 | sum_values = sum_values + f[operation_field_name] 273 | 274 | if output_operation == '2': 275 | k = 1 276 | partial = 0 277 | 278 | if output_operation == '3': 279 | if weight_field_name == '': 280 | feedback.pushInfo ('\n!!!!!!!!!!!! WEIGHT FIELD MISSING !!!!!!!!!!!!!\n') 281 | k = 1 282 | partial = 0 283 | sum_weight = 0 284 | for f in source.getFeatures(): 285 | sum_weight = sum_weight + f[weight_field_name] 286 | 287 | if output_operation == '4' or output_operation == '5': 288 | k = 0 289 | partial = 0 290 | #feedback.pushInfo (source) 291 | 292 | produttoria = 0 293 | k=0 294 | 295 | # Read the layer and create output features 296 | for f in source.getFeatures(): 297 | new_feature = QgsFeature() 298 | new_feature.setGeometry(f.geometry()) 299 | 300 | new_f = f.attributes() 301 | 302 | 303 | if output_operation == '0': 304 | partial = partial + f[operation_field_name] 305 | 306 | if output_operation == '1': 307 | if f[operation_field_name] != 0: 308 | partial = (f[operation_field_name] / sum_values)*100 309 | 310 | if output_operation == '2': 311 | if k == 0: 312 | partial = partial + f[operation_field_name] 313 | else: 314 | partial = (partial * k + f[operation_field_name])/(k+1) 315 | 316 | if output_operation == '3': 317 | #feedback.pushInfo ('ci son passato ' + str(sum_weight)) 318 | produttoria = produttoria + (f[operation_field_name] * float(f[weight_field_name])) 319 | partial = produttoria/sum_weight 320 | 321 | 322 | if output_operation == '4': 323 | if k != 0: 324 | request = QgsFeatureRequest().setFilterFid(k-1) 325 | feat = next(source.getFeatures(request)) 326 | partial = f[operation_field_name] - feat[operation_field_name] 327 | #feedback.pushInfo(str(k) +" -- " +str(feat[operation_field_name])+" "+str(f[operation_field_name])+" "+str(partial)) 328 | else: 329 | partial = 0 330 | #feedback.pushInfo(str(k) + " " +str(partial)) 331 | 332 | if output_operation == '5': 333 | if k != 0: 334 | request = QgsFeatureRequest().setFilterFid(k-1) 335 | feat = next(source.getFeatures(request)) 336 | if feat[operation_field_name] != 0: 337 | partial = ((f[operation_field_name] - feat[operation_field_name])/ feat[operation_field_name])*100 338 | else: 339 | partial = 9999999 340 | else: 341 | partial=0 342 | k = k + 1 343 | 344 | if output_operation != '3': 345 | new_f.append(partial) 346 | if id_calc == 1: 347 | new_f.append(f.id()) 348 | new_feature.setAttributes(new_f) 349 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 350 | 351 | if output_operation == '3': 352 | feedback.pushInfo ('MEDIA PONDERATA = ' + str(partial)) 353 | feedback.pushInfo('nValori : ' + operation_field_name) 354 | feedback.pushInfo('nPeso : ' + weight_field_name + '\n') 355 | 356 | 357 | if output_operation != '3': 358 | return {self.OUTPUT: dest_id} 359 | else: 360 | return {} -------------------------------------------------------------------------------- /collections/distance-measurements/symbol/dimensions_polygon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 200 | 201 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | -------------------------------------------------------------------------------- /collections/distance-measurements/symbol/dimensions_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 225 | 226 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /collections/profiles/style/Vertici.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 | 65 | 66 | 73 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 0 96 | 0 97 | 1 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 153 | 154 | 155 | 156 | 157 | 158 | 160 | 161 | 162 | 163 | 164 | 165 | 167 | 168 | 169 | 170 | 171 | 172 | 174 | 175 | 176 | 177 | 178 | 179 | 181 | 182 | 183 | 184 | 185 | 186 | 188 | 189 | 190 | 191 | 192 | 193 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 0 260 | 261 | 277 | 0 278 | generatedlayout 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | begin 300 | 301 | 0 302 | 303 | -------------------------------------------------------------------------------- /collections/distance-measurements/style/distance_measure.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 0 268 | 0 269 | 1 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 0 312 | 313 | 330 | 0 331 | generatedlayout 332 | 333 | 334 | 335 | 336 | 337 | 1 338 | 339 | -------------------------------------------------------------------------------- /collections/profiles/processing/profiles.py: -------------------------------------------------------------------------------- 1 | # -*-coding: utf-8 -*- 2 | 3 | """ 4 | *************************************************************************** 5 | * * 6 | * Giulio Fattori 13.04.2020 * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | *************************************************************************** 14 | """ 15 | 16 | from PyQt5.QtCore import QCoreApplication, QVariant 17 | from qgis.core import (QgsProcessing, 18 | QgsFeatureSink, 19 | QgsFeature, 20 | QgsFeatureRequest, 21 | QgsField, 22 | QgsFields, 23 | QgsGeometry, 24 | QgsPoint, 25 | QgsPointXY, 26 | QgsWkbTypes, 27 | QgsProject, 28 | QgsVectorLayer, 29 | QgsDistanceArea, 30 | QgsCoordinateReferenceSystem, 31 | QgsProcessingException, 32 | QgsProcessingAlgorithm, 33 | QgsProcessingParameterBoolean, 34 | QgsProcessingParameterEnum, 35 | QgsProcessingParameterFile, 36 | QgsProcessingParameterString, 37 | QgsProcessingParameterFeatureSource, 38 | QgsProcessingParameterFeatureSink, 39 | QgsProcessingParameterField, 40 | QgsProcessingParameterNumber, 41 | QgsProcessingParameterDefinition, 42 | QgsProcessingFeatureSourceDefinition, 43 | ) 44 | import processing 45 | import datetime 46 | import math 47 | import sys 48 | 49 | 50 | class ProfileBeta_ProcessingAlgorithm(QgsProcessingAlgorithm): 51 | """ 52 | Algorithm that fractions a poligon in n parts. 53 | """ 54 | INPUT_L = 'INPUT_L' #layer linea profilo 55 | INPUT_S = 'INPUT_S' #scala 56 | INPUT_D = 'INPUT_D' #dalla sezione 57 | INPUT_A = 'INPUT_A' #alla sezione 58 | INPUT_P = 'INPUT_P' #quota riferimento anche ai sotto profili 59 | 60 | OUTPUT = 'OUTPUT' 61 | LABELS = 'LABELS' 62 | EARTH = 'EARTH' 63 | 64 | def tr(self, string): 65 | """ 66 | Returns a translatable string with the self.tr() function. 67 | """ 68 | return QCoreApplication.translate('Processing', string) 69 | 70 | def createInstance(self): 71 | return ProfileBeta_ProcessingAlgorithm() 72 | 73 | def name(self): 74 | """ 75 | Returns the algorithm name, used for identifying the algorithm. This 76 | string should be fixed for the algorithm, and must not be localised. 77 | The name should be unique within each provider. Names should contain 78 | lowercase alphanumeric characters only and no spaces or other 79 | formatting characters. 80 | """ 81 | return '0 Profili Beta' 82 | 83 | def displayName(self): 84 | """ 85 | Returns the translated algorithm name, which should be used for any 86 | user-visible display of the algorithm name. 87 | """ 88 | return self.tr('Profili') 89 | 90 | def group(self): 91 | """ 92 | Returns the name of the group this algorithm belongs to. This string 93 | should be localised. 94 | """ 95 | return self.tr(self.groupId()) 96 | 97 | def groupId(self): 98 | """ 99 | Returns the unique ID of the group this algorithm belongs to. This 100 | string should be fixed for the algorithm, and must not be localised. 101 | The group id should be unique within each provider. Group id should 102 | contain lowercase alphanumeric characters only and no spaces or other 103 | formatting characters. 104 | """ 105 | return '' 106 | 107 | def shortHelpString(self): 108 | """ 109 | Returns a localised short helper string for the algorithm. This string 110 | should provide a basic description about what the algorithm does and the 111 | parameters and outputs associated with it.. 112 | """ 113 | return self.tr( 114 | "COSTRUISCE UN PROFILO DA UNA TRACCIA\ 115 | \n------------------ PARAMETRI --------------------\ 116 | \n- layer: LinestringZ o Linestring25D con feature dotata di Z\ 117 | \n- scala: selezionare il rapporto di scala\ 118 | \n- dal picchetto: picchetto o sezioni di inizio profilo\ 119 | \n- al picchetto: picchetto o sezioni di fine profilo\ 120 | \n- eventuale riduzione della quota di riferimento sui sottoprofili\ 121 | \n- NOTE: se -dal picchetto- minore di -al picchetto- inverte automaticamente" 122 | 123 | ) 124 | 125 | def helpUrl(self): 126 | """ 127 | Returns the URL of the help online 128 | """ 129 | return 'https://github.com/Korto19/Profili/#profili' 130 | 131 | 132 | def initAlgorithm(self, config=None): 133 | """ 134 | Here we define the inputs and output of the algorithm, along 135 | with some other properties. 136 | """ 137 | # We add the point input vector features source 138 | #QgsProcessingFeatureSourceDefinition 139 | self.addParameter( 140 | QgsProcessingParameterFeatureSource( 141 | self.INPUT_L, 142 | self.tr('Input LineZ or Line25D layer'), 143 | [QgsProcessing.TypeVectorLine], 144 | 145 | ) 146 | ) 147 | 148 | self.addParameter( 149 | QgsProcessingParameterEnum( 150 | self.INPUT_S, 'Scala', 151 | options=['1:1','1:10','1:2','1:20'], 152 | allowMultiple=False, defaultValue = 0 153 | ) 154 | ) 155 | 156 | self.addParameter( 157 | QgsProcessingParameterNumber( 158 | self.INPUT_D, 159 | self.tr('Dal picchetto n'), 160 | QgsProcessingParameterNumber.Integer, 161 | 0, False, 0 162 | ) 163 | ) 164 | 165 | self.addParameter( 166 | QgsProcessingParameterNumber( 167 | self.INPUT_A, 168 | self.tr('Al picchetto n'), 169 | QgsProcessingParameterNumber.Integer, 170 | 0, False, 0 171 | ) 172 | ) 173 | 174 | self.addParameter( 175 | QgsProcessingParameterBoolean( 176 | self.INPUT_P, 177 | self.tr('Riduzione Quota riferimento sottoprofili'), 178 | 0 179 | ) 180 | ) 181 | 182 | # We add a feature sink's in which to store our processed features (this usually 183 | # takes the form of a newly created vector layer when the algorithm is run in QGIS) 184 | self.addParameter( 185 | QgsProcessingParameterFeatureSink( 186 | self.LABELS, 187 | self.tr('Label_' + str((datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")))) 188 | ) 189 | ) 190 | 191 | self.addParameter( 192 | QgsProcessingParameterFeatureSink( 193 | self.OUTPUT, 194 | self.tr('Finca_' + str((datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")))) 195 | ) 196 | ) 197 | 198 | self.addParameter( 199 | QgsProcessingParameterFeatureSink( 200 | self.EARTH, 201 | self.tr('Profi_' + str((datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")))) 202 | ) 203 | ) 204 | 205 | 206 | def processAlgorithm(self, parameters, context, feedback): 207 | """ 208 | Here is where the processing itself takes place. 209 | """ 210 | sourceL = self.parameterAsSource( 211 | parameters, 212 | self.INPUT_L, 213 | context) 214 | 215 | scalaXZ = self.parameterAsInt( 216 | parameters, 217 | self.INPUT_S, 218 | context) 219 | 220 | da_sez = self.parameterAsInt( 221 | parameters, 222 | self.INPUT_D, 223 | context) 224 | 225 | al_sez = self.parameterAsInt( 226 | parameters, 227 | self.INPUT_A, 228 | context) 229 | 230 | rid_rif = self.parameterAsInt( 231 | parameters, 232 | self.INPUT_P, 233 | context) 234 | 235 | fields = sourceL.fields() 236 | fields.append(QgsField('Etichette', QVariant.String)) 237 | 238 | fields_e = sourceL.fields() 239 | 240 | 241 | earth_fields = QgsFields() 242 | 243 | 244 | (sink, dest_id) = self.parameterAsSink( 245 | parameters, 246 | self.OUTPUT, 247 | context, fields_e, QgsWkbTypes.LineString, sourceL.sourceCrs() 248 | ) 249 | 250 | (earth, dest_id) = self.parameterAsSink( 251 | parameters, 252 | self.EARTH, 253 | context, earth_fields, QgsWkbTypes.LineString, sourceL.sourceCrs() 254 | ) 255 | 256 | (label, dest_id) = self.parameterAsSink( 257 | parameters, 258 | self.LABELS, 259 | context, fields, QgsWkbTypes.Point, sourceL.sourceCrs() 260 | ) 261 | 262 | #verifica compatibilità intervallo picchetti 263 | if da_sez > al_sez: 264 | feedback.pushInfo('Da picchetto MINORE di a Picchetto, scambiati !!') 265 | tmp = al_sez 266 | al_sez = da_sez 267 | da_sez = tmp 268 | 269 | prog_da_sez = da_sez 270 | 271 | #feedback.pushInfo(str(scalaXZ)) 272 | tupla_scale = ([1,1],[1,10],[2,2],[2,20]) 273 | f_scalaX = tupla_scale [scalaXZ][0] 274 | f_scalaZ = tupla_scale [scalaXZ][1] 275 | 276 | if sourceL.wkbType() in (QgsWkbTypes.LineStringZ, QgsWkbTypes.LineString25D): 277 | for feature in sourceL.getFeatures(): 278 | 279 | vertices = feature.geometry().asPolyline() 280 | line = feature.geometry().constGet() 281 | n = len(vertices) - 1 282 | 283 | if al_sez == 0 or al_sez > n: 284 | al_sez = n 285 | 286 | if rid_rif: 287 | Q_minima = min(line.zAt(v) for v in range(da_sez,al_sez+1)) - 1 288 | else: 289 | Q_minima = min(line.zAt(v) for v in range(0,len(vertices))) - 1 290 | 291 | progressiva = parziale = k = 0 292 | for v in vertices: 293 | if k > 0: 294 | progressiva = progressiva + parziale / f_scalaX 295 | if k < n: 296 | parziale = QgsDistanceArea().measureLine(vertices[k],vertices[k + 1])/ f_scalaX 297 | #print(v, parziale, progressiva, line.zAt(k)) 298 | 299 | if k >= da_sez and k <= al_sez: 300 | if k == da_sez: 301 | prog_da_sez = progressiva 302 | 303 | prog_al_sez = progressiva 304 | #feedback.pushInfo(str(prog_al_sez)) 305 | 306 | #costruzione grafico profilo 307 | #segmento 308 | new_feature = QgsFeature() 309 | new_feature.setAttributes(feature.attributes()) 310 | line_start = QgsPoint(progressiva,-5.4) 311 | line_end = QgsPoint(progressiva,-3.4) 312 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 313 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 314 | 315 | #candela 316 | line_start = QgsPoint(progressiva,0) 317 | line_end = QgsPoint(progressiva,(line.zAt(k)-Q_minima) / f_scalaZ) 318 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 319 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 320 | 321 | # linea terreno 322 | if k == da_sez: 323 | line_end_p = line_end 324 | else: 325 | new_feature = QgsFeature() 326 | new_feature.setAttributes(feature.attributes()) 327 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_end_p, line_end])) 328 | earth.addFeature(new_feature, QgsFeatureSink.FastInsert) 329 | line_end_p = line_end 330 | 331 | #etichette punto 332 | E_punto = feature.attributes() 333 | E_punto.append('Pi_'+ str(k)) 334 | newP_feature = QgsFeature() 335 | newP_feature.setAttributes(E_punto) 336 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(progressiva,-0.7))) 337 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 338 | 339 | #progressiva 340 | E_prog = feature.attributes() 341 | E_prog.append('Pr_' + format(progressiva, '.2f')) 342 | newP_feature.setAttributes(E_prog) 343 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(progressiva,-2.4))) 344 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 345 | 346 | #quota 347 | E_quota = feature.attributes() 348 | E_quota.append('Qu_'+ str(line.zAt(k))) 349 | newP_feature.setAttributes(E_quota) 350 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(progressiva,-6.4))) 351 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 352 | 353 | #punto parziale 354 | if k < al_sez and k < n: 355 | mid_point = progressiva + parziale / 2 356 | newPP_feature = QgsFeature() 357 | newPP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(mid_point,-4.4))) 358 | 359 | #distanza parziale 360 | new_f = feature.attributes() 361 | new_f.append('Dp_' + format(parziale,'.2f')) 362 | #feedback.pushInfo(str(parziale)) 363 | newPP_feature.setAttributes(new_f) 364 | 365 | label.addFeature(newPP_feature, QgsFeatureSink.FastInsert) 366 | 367 | k += 1 368 | 369 | #finche orizzontali 370 | xi_finca = prog_da_sez - 10 371 | xf_finca = prog_al_sez + 1 372 | 373 | #finche orizzontali 374 | line_start = QgsPoint(xi_finca,0) 375 | line_end = QgsPoint(xf_finca,0) 376 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 377 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 378 | 379 | line_start = QgsPoint(xi_finca ,-1.4) 380 | line_end = QgsPoint(xf_finca ,-1.4) 381 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 382 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 383 | 384 | line_start = QgsPoint(xi_finca,-3.4) 385 | line_end = QgsPoint(xf_finca,-3.4) 386 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 387 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 388 | 389 | line_start = QgsPoint(xi_finca,-5.4) 390 | line_end = QgsPoint(xf_finca,-5.4) 391 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 392 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 393 | 394 | line_start = QgsPoint(xi_finca,-7.4) 395 | line_end = QgsPoint(xf_finca,-7.4) 396 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 397 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 398 | 399 | #finche chiusura 400 | line_start = QgsPoint(xi_finca,0) 401 | line_end = QgsPoint(xi_finca,-7.4) 402 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 403 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 404 | 405 | line_start = QgsPoint(xf_finca,0) 406 | line_end = QgsPoint(xf_finca,-7.4) 407 | new_feature.setGeometry(QgsGeometry.fromPolyline([line_start, line_end])) 408 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 409 | 410 | #testi fincatura 411 | xi_finca += 1 412 | #Picchetto 413 | E_finca = feature.attributes() 414 | E_finca.append('Picchetto') 415 | newP_feature = QgsFeature() 416 | newP_feature.setAttributes(E_finca) 417 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca,-0.7))) 418 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 419 | 420 | E_finca = feature.attributes() 421 | E_finca.append('Distanza progressiva') 422 | newP_feature.setAttributes(E_finca) 423 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca,-2.4))) 424 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 425 | 426 | E_finca = feature.attributes() 427 | E_finca.append('Distanza parziale') 428 | newP_feature.setAttributes(E_finca) 429 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca,-4.4))) 430 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 431 | 432 | E_finca = feature.attributes() 433 | E_finca.append('Quota terreno') 434 | newP_feature.setAttributes(E_finca) 435 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca,-6.4))) 436 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 437 | 438 | E_finca = feature.attributes() 439 | E_finca.append('Q.rif_'+str(format(Q_minima,'.2f'))) 440 | newP_feature.setAttributes(E_finca) 441 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca,0))) 442 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 443 | 444 | E_finca = feature.attributes() 445 | E_finca.append('Xsc_'+str(format(f_scalaX,'.0f'))) 446 | newP_feature.setAttributes(E_finca) 447 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca+8,0))) 448 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 449 | 450 | E_finca = feature.attributes() 451 | E_finca.append('Zsc_'+str(format(f_scalaZ,'.0f'))) 452 | newP_feature.setAttributes(E_finca) 453 | newP_feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(xi_finca+8,0))) 454 | label.addFeature(newP_feature, QgsFeatureSink.FastInsert) 455 | 456 | return {self.OUTPUT: dest_id} 457 | else: 458 | feedback.pushInfo('LAYER NON 3D \n') 459 | print(QgsWkbTypes.displayString(sourceL.wkbType())) 460 | return {None} 461 | -------------------------------------------------------------------------------- /collections/distance-measurements/style/line_dimensions.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 231 | 232 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 0 308 | 0 309 | 1 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 0 383 | 384 | 401 | 0 402 | generatedlayout 403 | 404 | 405 | 406 | 407 | 408 | 409 | 1 410 | 411 | -------------------------------------------------------------------------------- /collections/processing-scripts/processing/frazionamenti.py: -------------------------------------------------------------------------------- 1 | # -*-coding: utf-8 -*- 2 | 3 | """ 4 | *************************************************************************** 5 | * * 6 | * Giulio Fattori 01.05.2020 * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | *************************************************************************** 14 | """ 15 | 16 | from PyQt5.QtCore import QCoreApplication, QVariant 17 | from qgis.core import (QgsProcessing, 18 | QgsFeatureSink, 19 | QgsFeature, 20 | QgsFeatureRequest, 21 | QgsField, 22 | QgsFields, 23 | QgsGeometry, 24 | QgsPoint, 25 | QgsPointXY, 26 | QgsWkbTypes, 27 | QgsProject, 28 | QgsVectorLayer, 29 | QgsCoordinateReferenceSystem, 30 | QgsProcessingException, 31 | QgsProcessingAlgorithm, 32 | QgsProcessingParameterBoolean, 33 | QgsProcessingParameterEnum, 34 | QgsProcessingParameterFile, 35 | QgsProcessingParameterString, 36 | QgsProcessingParameterFeatureSource, 37 | QgsProcessingParameterFeatureSink, 38 | QgsProcessingParameterField, 39 | QgsProcessingParameterNumber, 40 | QgsProcessingParameterDefinition, 41 | QgsProcessingFeatureSourceDefinition, 42 | ) 43 | import processing 44 | import datetime 45 | import math 46 | import sys 47 | 48 | 49 | class Frazionamenti_ProcessingAlgorithm(QgsProcessingAlgorithm): 50 | """ 51 | Algorithm that fractions a poligon in n parts. 52 | """ 53 | INPUTP = 'INPUTP' #layer poligonale con la particella da tagliare 54 | INPUTL = 'INPUTL' #layer lineare con una sola linea di taglio 55 | INPUTA = 'INPUTA' #numero di parti 56 | INPUTS = 'INPUTS' #superficie target 57 | INPUTV = 'INPUTV' #verso relativamente alla linea 58 | INPUTT = 'INPUTT' #taglio diretto senza calcoli 59 | INPUTN = 'INPUTN' #suddivisione nelle n parti per n > 2 60 | 61 | OUTPUT = 'OUTPUT' 62 | 63 | def tr(self, string): 64 | """ 65 | Returns a translatable string with the self.tr() function. 66 | """ 67 | return QCoreApplication.translate('Processing', string) 68 | 69 | def createInstance(self): 70 | return Frazionamenti_ProcessingAlgorithm() 71 | 72 | def name(self): 73 | """ 74 | Returns the algorithm name, used for identifying the algorithm. This 75 | string should be fixed for the algorithm, and must not be localised. 76 | The name should be unique within each provider. Names should contain 77 | lowercase alphanumeric characters only and no spaces or other 78 | formatting characters. 79 | """ 80 | return 'Frazionamenti' 81 | 82 | def displayName(self): 83 | """ 84 | Returns the translated algorithm name, which should be used for any 85 | user-visible display of the algorithm name. 86 | """ 87 | return self.tr('Frazionamenti') 88 | 89 | def group(self): 90 | """ 91 | Returns the name of the group this algorithm belongs to. This string 92 | should be localised. 93 | """ 94 | return self.tr('FGscripts') 95 | 96 | def groupId(self): 97 | """ 98 | Returns the unique ID of the group this algorithm belongs to. This 99 | string should be fixed for the algorithm, and must not be localised. 100 | The group id should be unique within each provider. Group id should 101 | contain lowercase alphanumeric characters only and no spaces or other 102 | formatting characters. 103 | """ 104 | return 'FGscripts' 105 | 106 | def shortHelpString(self): 107 | """ 108 | Returns a localised short helper string for the algorithm. This string 109 | should provide a basic description about what the algorithm does and the 110 | parameters and outputs associated with it.. 111 | """ 112 | return self.tr( 113 | "Fraziona la particella interessata in n parti in funzione di una linea\ 114 | creando un nuovo layer denominato 'Fraz_' seguito da data e ora\ 115 | \n**** PARAMETRI **** \n\ 116 | - layer poligonale contenente elementi da frazionare\n\ 117 | - layer lineare contenente la dividente\n\ 118 | - n numero parti o un ennesimo da ottenere\n\ 119 | \n- [opz] taglio lungo linea posizionata manualmente \ 120 | \n- [opz] frazionamento in n parti eguali\ 121 | \n- [opz] superficie da ottenere in alternativa alla parte\ 122 | \n- [opz] inversione delle parti\ 123 | \n !!!!------------ AVVERTENZA -------------!!!! \ 124 | \n !!!! POTREBBE NON DARE RISULTATO !!!! \ 125 | \n !!!!------ PER POLIGONI CONCAVI -----!!!!") 126 | 127 | def initAlgorithm(self, config=None): 128 | """ 129 | Here we define the inputs and output of the algorithm, along 130 | with some other properties. 131 | """ 132 | # We add the polygonal input vector features source 133 | #QgsProcessingFeatureSourceDefinition 134 | self.addParameter( 135 | QgsProcessingParameterFeatureSource( 136 | self.INPUTP, 137 | self.tr('Input Poly layer'), 138 | [QgsProcessing.TypeVectorPolygon] 139 | ) 140 | ) 141 | 142 | # We add the line input vector features source 143 | self.addParameter( 144 | QgsProcessingParameterFeatureSource( 145 | self.INPUTL, 146 | self.tr('Input Line layer'), 147 | [QgsProcessing.TypeVectorLine] 148 | ) 149 | ) 150 | 151 | #taglio diretto 152 | INPUTT = QgsProcessingParameterBoolean( 153 | self.INPUTT, 154 | self.tr('Taglio con dividente posizionata manualmente'), 0 155 | ) 156 | #INPUTT.setFlags(INPUTT.flags())# | QgsProcessingParameterDefinition.FlagAdvanced) 157 | self.addParameter(INPUTT) 158 | 159 | #We add the number of parcels 160 | self.addParameter( 161 | QgsProcessingParameterNumber( 162 | self.INPUTA, 163 | self.tr('Denominatore frazione o n parti della superficie'), 164 | QgsProcessingParameterNumber.Integer, 165 | 2, False, 2 166 | ) 167 | ) 168 | 169 | #Numero parti se > 2 170 | INPUTN = QgsProcessingParameterBoolean( 171 | self.INPUTN, 172 | self.tr('Frazionamento in parti eguali'), 0 173 | ) 174 | #INPUTN.setFlags(INPUTN.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 175 | self.addParameter(INPUTN) 176 | 177 | #We add the superficie target 178 | self.addParameter( 179 | QgsProcessingParameterNumber( 180 | self.INPUTS, 181 | self.tr('Superficie da ottenere in alternativa alla frazione'), 182 | QgsProcessingParameterNumber.Double, 183 | 0, False, 0 184 | ) 185 | ) 186 | 187 | #inversione taglio se occorresse 188 | INPUTV = QgsProcessingParameterBoolean( 189 | self.INPUTV, 190 | self.tr('Inverte parti rispetto alla dividente Up/Dn - Sx/dx'), 0 191 | ) 192 | #INPUTV.setFlags(INPUTV.flags() | QgsProcessingParameterDefinition.FlagAdvanced) 193 | self.addParameter(INPUTV) 194 | 195 | # We add a feature sink in which to store our processed features (this usually 196 | # takes the form of a newly created vector layer when the algorithm is run in QGIS) 197 | self.addParameter( 198 | QgsProcessingParameterFeatureSink( 199 | self.OUTPUT, 200 | self.tr('Fraz_' + str((datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")))) 201 | ) 202 | ) 203 | 204 | def processAlgorithm(self, parameters, context, feedback): 205 | """ 206 | Here is where the processing itself takes place. 207 | """ 208 | sourceP = self.parameterAsSource( 209 | parameters, 210 | self.INPUTP, 211 | context) 212 | 213 | sourceL = self.parameterAsSource( 214 | parameters, 215 | self.INPUTL, 216 | context) 217 | 218 | parti = self.parameterAsDouble( 219 | parameters, 220 | self.INPUTA, 221 | context) 222 | 223 | sup_target = self.parameterAsDouble( 224 | parameters, 225 | self.INPUTS, 226 | context) 227 | 228 | frazioni = self.parameterAsBoolean( 229 | parameters, 230 | self.INPUTN, 231 | context) 232 | 233 | direct = self.parameterAsBoolean( 234 | parameters, 235 | self.INPUTT, 236 | context) 237 | 238 | verso = self.parameterAsBoolean( 239 | parameters, 240 | self.INPUTV, 241 | context) 242 | 243 | 244 | fields = sourceP.fields() 245 | fields.append(QgsField('Fraz_sub', QVariant.String)) 246 | fields.append(QgsField('Fraz_part', QVariant.Double)) 247 | fields.append(QgsField('Fraz_area', QVariant.Double)) 248 | 249 | 250 | (sink, dest_id) = self.parameterAsSink( 251 | parameters, 252 | self.OUTPUT, 253 | context, fields, QgsWkbTypes.Polygon, sourceP.sourceCrs() #QgsCoordinateReferenceSystem('EPSG:32632') ) 254 | ) 255 | 256 | def extend_move_line(feat_L, feat_P): 257 | """input 2 feature output 1 feature""" 258 | """estende la linea alla dimensione della diagonale dell'estensione del poligono""" 259 | 260 | xmin = feat_P.geometry().boundingBox().xMinimum() 261 | xmax = feat_P.geometry().boundingBox().xMaximum() 262 | ymin = feat_P.geometry().boundingBox().yMinimum() 263 | ymax = feat_P.geometry().boundingBox().yMaximum() 264 | l_p_diag = math.sqrt((xmin - xmax)**2 + (ymin - ymax)**2) 265 | delta = (l_p_diag - feat_L.geometry().length()) 266 | feat_L.setGeometry(feat_L.geometry().extendLine(delta,delta)) 267 | 268 | """sposta il centroide della linea sul centroide del poligono""" 269 | xp = feat_P.geometry().centroid().asPoint().x() 270 | yp = feat_P.geometry().centroid().asPoint().y() 271 | xl = feat_L.geometry().centroid().asPoint().x() 272 | yl = feat_L.geometry().centroid().asPoint().y() 273 | feat_t = feat_L.geometry() 274 | feat_t.translate(xp - xl,yp - yl) 275 | feat_L.setGeometry(feat_t) 276 | 277 | return feat_L 278 | 279 | 280 | def trim_poly_by_line(feat_L, feat_P, verso): 281 | """ trim the polygon by line and get subpolygon area """ 282 | """first max second min""" 283 | 284 | if feat_L.geometry().intersects(feat_P.geometry()): 285 | success, splits, topo = feat_P.geometry().splitGeometry(feat_L.geometry().asPolyline(), True) 286 | if success == 0: 287 | risultato = QgsFeature() 288 | risultato.setGeometry(splits[0]) 289 | else: 290 | sys.exit("1 !! LINE TOUCH BUT NOT INTERSECTS POLY !!") 291 | 292 | feat_r = feat_L.geometry() 293 | feat_r.rotate(180,feat_r.centroid().asPoint()) 294 | 295 | success, splits, topo = feat_P.geometry().splitGeometry(feat_r.asPolyline(), True) 296 | if success == 0: 297 | risultato1 = QgsFeature() 298 | risultato1.setGeometry(splits[0]) 299 | else: 300 | sys.exit("2 !! LINE TOUCH BUT NOT INTERSECTS POLY !!") 301 | 302 | else: 303 | sys.exit("!! LINE NOT INTERSECTS POLY !!") 304 | 305 | if risultato.geometry().area() >= risultato1.geometry().area(): 306 | smax = risultato 307 | smin = risultato1 308 | else: 309 | smax = risultato1 310 | smin = risultato 311 | 312 | rlist = [] 313 | rlist.extend([smax, smax.geometry().area(), smax.geometry().centroid().asPoint()]) 314 | rlist.extend([smin, smin.geometry().area(), smin.geometry().centroid().asPoint()]) 315 | 316 | return rlist 317 | 318 | 319 | def bisezione(feat_L, feat_P, parti, decimali, val_prec, iterazioni, verso): 320 | 321 | area_mappale = feat_P.geometry().area() 322 | area_target = area_mappale / 2 323 | 324 | rlist = trim_poly_by_line(feat_L, feat_P, verso) 325 | residuo = round((rlist[1] - area_target), int(decimali)) 326 | 327 | sign = lambda a: (a>0) - (a<0) 328 | n = 0 329 | k = 10 330 | while abs(residuo) >= val_prec and n < iterazioni: 331 | if residuo > 0: 332 | #sign = lambda a: (a>0) - (a<0) 333 | sx = (rlist[2].x()-feat_L.geometry().centroid().asPoint().x()) 334 | d_x = sign(sx)/k 335 | sy = (rlist[2].y()-feat_L.geometry().centroid().asPoint().y()) 336 | d_y = sign (sy)/k 337 | else: 338 | #sign = lambda a: (a>0) - (a<0) 339 | sx = (rlist[5].x()-feat_L.geometry().centroid().asPoint().x()) 340 | d_x = sign(sx)/k 341 | sy = (rlist[5].y()-feat_L.geometry().centroid().asPoint().y()) 342 | d_y = sign (sy)/k 343 | 344 | #sposto la linea 345 | feat_t = feat_L.geometry() 346 | feat_t.translate(d_x, d_y) 347 | feat_L.setGeometry(feat_t) 348 | 349 | #taglio e calcolo residuo 350 | residuo_p = residuo 351 | rlist = trim_poly_by_line(feat_L, feat_P, verso) 352 | residuo = round((rlist[1] - area_target), int(decimali)) 353 | if residuo > residuo_p: 354 | k *=10 355 | n += 1 356 | 357 | 358 | if n < iterazioni: 359 | feedback.pushInfo(str(n) + ' tagli --- residuo = ' + str(round(residuo,5)) + '\n' ) 360 | else: 361 | feedback.pushInfo('residuo = ' + str(round(residuo,5)) + '\n' ) 362 | return 363 | 364 | 365 | 366 | def nnsezione(feat_L, feat_P, parti, decimali, val_prec, iterazioni, verso, sup_target): 367 | #feedback.pushInfo(str(sup_target)) 368 | area_mappale = feat_P.geometry().area() 369 | 370 | if sup_target != 0: 371 | if area_mappale > sup_target: 372 | if sup_target > area_mappale / 2: 373 | sup_target = area_mappale - sup_target 374 | parti = area_mappale / sup_target 375 | area_target = sup_target 376 | feedback.pushInfo('parti ' + str(format(1/parti,'.3%'))) 377 | else: 378 | sys.exit("PARTE MAGGIORE DELL'INTERO") 379 | else: 380 | area_target = area_mappale / parti 381 | feedback.pushInfo('parti ' + str(format(1/parti,'.3%'))) 382 | 383 | rlist = trim_poly_by_line(feat_L, feat_P, verso) 384 | residuo = round((rlist[1] - area_target), int(decimali)) 385 | 386 | #centroide iniziale linea 387 | xl0 = feat_L.geometry().centroid().asPoint().x() 388 | yl0 = feat_L.geometry().centroid().asPoint().y() 389 | 390 | #inversione delle parti 391 | if verso: 392 | pte = 2 393 | else: 394 | pte = 5 395 | #centroide iniziale parte scelta 396 | xc0 = xlf = rlist[pte].x() 397 | yc0 = ylf = rlist[pte].y() 398 | 399 | n = 0 400 | while residuo > 0: 401 | #memorizzo il centroide della linea 402 | xl0 = feat_L.geometry().centroid().asPoint().x() 403 | yl0 = feat_L.geometry().centroid().asPoint().y() 404 | #calcolo spostamento sul centroide della parte 405 | d_x = (xc0 - feat_L.geometry().centroid().asPoint().x())/2 406 | d_y = (yc0 - feat_L.geometry().centroid().asPoint().y())/2 407 | #sposto linea sul centroide 408 | feat_t = feat_L.geometry() 409 | feat_t.translate(d_x, d_y) 410 | feat_L.setGeometry(feat_t) 411 | #nuovo taglio con linea sul centroide 412 | rlist = trim_poly_by_line(feat_L, feat_P, verso) 413 | #nuovo centoide parte minore 414 | xc0 = rlist[5].x() 415 | yc0 = rlist[5].y() 416 | #calcolo residuo 417 | residuo = round((rlist[4] - area_target), int(decimali)) 418 | #memorizzo posizione finale centroide linea 419 | xlf = feat_L.geometry().centroid().asPoint().x() 420 | ylf = feat_L.geometry().centroid().asPoint().y() 421 | 422 | n += 1 423 | #print('----------------------------------------------------') 424 | 425 | n = 0 426 | while abs(residuo) >= val_prec and n < iterazioni: 427 | if residuo < 0: 428 | #memorizzo posizione finale centroide linea 429 | xlf = feat_L.geometry().centroid().asPoint().x() 430 | ylf = feat_L.geometry().centroid().asPoint().y() 431 | #calcolo spostamento 432 | d_x = (xl0 - xlf)/2 433 | d_y = (yl0 - ylf)/2 434 | 435 | else: 436 | #memorizzo posizione finale centroide linea 437 | xl0 = feat_L.geometry().centroid().asPoint().x() 438 | yl0 = feat_L.geometry().centroid().asPoint().y() 439 | #calcolo spostamento 440 | d_x = (xlf - xl0)/2 441 | d_y = (ylf - yl0)/2 442 | 443 | #sposto la linea 444 | feat_t = feat_L.geometry() 445 | feat_t.translate(d_x, d_y) 446 | feat_L.setGeometry(feat_t) 447 | 448 | #taglio e calcolo residuo 449 | rlist = trim_poly_by_line(feat_L, feat_P, verso) 450 | residuo = round((rlist[4] - area_target), int(decimali)) 451 | n += 1 452 | 453 | if n < iterazioni: 454 | feedback.pushInfo(str(n) + ' tagli --- residuo = ' + str(round(residuo,5)) + '\n' ) 455 | else: 456 | feedback.pushInfo('residuo = ' + str(round(residuo,5)) + '\n' ) 457 | return rlist 458 | 459 | 460 | #------------------ PARAMETRI ELABORAZIONE ------------------ 461 | str_decimali = '.4f' 462 | decimali = 5 463 | val_prec = 0.000001 464 | iterazioni = 200 465 | #------------------ PARAMETRI ELABORAZIONE ------------------ 466 | 467 | for f in sourceP.getFeatures(): 468 | mappale = f 469 | area_mappale = f.geometry().area() 470 | 471 | for f in sourceL.getFeatures(): 472 | dividente = f 473 | 474 | if not frazioni or ( frazioni and parti==2): 475 | if direct: 476 | feedback.pushInfo('Trim Direct') 477 | rlist = trim_poly_by_line(dividente, mappale, verso) 478 | elif parti == 2 and sup_target == 0: 479 | feedback.pushInfo('Trim Fifty Fifty') 480 | dividente = extend_move_line(dividente, mappale) 481 | bisezione(dividente, mappale, parti, decimali, val_prec, iterazioni, verso) 482 | rlist = trim_poly_by_line(dividente, mappale, verso) 483 | elif sup_target != 0: 484 | feedback.pushInfo('Trim Target area') 485 | dividente = extend_move_line(dividente, mappale) 486 | rlist = nnsezione(dividente, mappale, parti, decimali, val_prec, iterazioni, verso, sup_target) 487 | rlist = trim_poly_by_line(dividente, mappale, verso) 488 | else: 489 | feedback.pushInfo('Trim Target 1/'+ str(int(parti)) + ' and ' + str(int(parti-1)) + '/' + str(int(parti))) 490 | dividente = extend_move_line(dividente, mappale) 491 | rlist = nnsezione(dividente, mappale, parti, decimali, val_prec, iterazioni, verso, sup_target) 492 | rlist = trim_poly_by_line(dividente, mappale, verso) 493 | 494 | else: 495 | feedback.pushInfo('Target n 1/n Trim') 496 | while parti > 2: 497 | feedback.pushInfo(str(parti)) 498 | dividente = extend_move_line(dividente, mappale) 499 | rlist = nnsezione(dividente, mappale, parti, decimali, val_prec, iterazioni, verso, sup_target) 500 | for f in sourceP.getFeatures(): 501 | new_feature = QgsFeature() 502 | new_feature.setGeometry(rlist[3].geometry()) 503 | new_f = f.attributes() 504 | new_f.append('sub '+ str(int(parti))) 505 | new_f.append(format(rlist[4]/area_mappale,'.2%')) 506 | new_f.append(format(rlist[4],str_decimali)) 507 | new_feature.setAttributes(new_f) 508 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 509 | mappale = rlist[0] 510 | parti -= 1 511 | 512 | feedback.pushInfo('2.0') 513 | 514 | dividente = extend_move_line(dividente, mappale) 515 | rlist = bisezione(dividente, mappale, parti, decimali, val_prec, iterazioni, verso) 516 | rlist = trim_poly_by_line(dividente, mappale, verso) 517 | 518 | for i in range(0,4,3): 519 | for f in sourceP.getFeatures(): 520 | new_feature = QgsFeature() 521 | new_feature.setGeometry(rlist[i].geometry()) 522 | new_f = f.attributes() 523 | new_f.append('sub '+ str(int(i/3+1))) 524 | new_f.append(format(rlist[i+1]/area_mappale,'.2%')) 525 | new_f.append(format(rlist[i+1],str_decimali)) 526 | new_feature.setAttributes(new_f) 527 | sink.addFeature(new_feature, QgsFeatureSink.FastInsert) 528 | p = parti - 1 529 | 530 | return {self.OUTPUT: dest_id} 531 | -------------------------------------------------------------------------------- /collections/profiles/models/Traccia_profilo.model3: -------------------------------------------------------------------------------- 1 | 2 | 19 | 40 | 52 | 53 | 62 | 63 | 64 | 65 | 80 | 96 | 97 | 103 | 104 | 105 | 110 | 111 | 117 | 118 | 119 | 124 | 125 | 126 | 127 | 142 | 159 | 160 | 169 | 170 | 171 | 172 | 173 | 174 | 189 | 205 | 206 | 211 | 212 | 217 | 218 | 223 | 224 | 229 | 230 | 236 | 237 | 242 | 243 | 244 | 245 | 260 | 281 | 293 | 294 | 302 | 303 | 308 | 309 | 315 | 316 | 321 | 322 | 323 | 324 | 325 | 333 | 338 | 339 | 340 | 341 | 351 | 358 | 370 | 374 | 381 | 393 | 405 | 406 | 420 | 429 | 441 | 450 | 462 | 471 | 472 | 473 | --------------------------------------------------------------------------------