-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImportPhotos.py
261 lines (229 loc) · 44.2 KB
/
ImportPhotos.py
1
2
3
4
5
6
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
37
38
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
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
224
225
226
227
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
254
255
256
257
258
259
260
261
# -*- coding: utf-8 -*-
"""
ImportPhotos.py
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Leandro França'
__date__ = '2021-02-16'
__copyright__ = '(C) 2021, Leandro França'
from qgis.PyQt.QtCore import QCoreApplication
from PyQt5.QtCore import QVariant
from qgis.core import (QgsApplication,
QgsProcessingParameterVectorLayer,
QgsGeometry,
QgsPointXY,
QgsWkbTypes,
QgsFeature,
QgsField,
QgsFields,
QgsCoordinateReferenceSystem,
QgsProcessing,
QgsProcessingParameterFile,
QgsProcessingParameterField,
QgsProcessingParameterBoolean,
QgsProcessingParameterEnum,
QgsProcessingParameterNumber,
QgsFeatureSink,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
import PIL.Image, PIL.ExifTags
import datetime
import shutil
import os
class ImportPhotos(QgsProcessingAlgorithm):
LOC = QgsApplication.locale()
def translate(self, string):
return QCoreApplication.translate('Processing', string)
def tr(self, *string):
# Traduzir para o portugês: arg[0] - english (translate), arg[1] - português
if self.LOC == 'pt':
if len(string) == 2:
return string[1]
else:
return self.translate(string[0])
else:
return self.translate(string[0])
def createInstance(self):
return ImportPhotos()
def name(self):
return 'importphotos'
def displayName(self):
return self.tr('Photos with Geotag', 'Fotos com Geotag')
def group(self):
return self.tr('LF Reambulation', 'LF Reambulação')
def groupId(self):
return 'lf_reambulation'
def tags(self):
return self.tr('import','photo','reambulation','geotag','geophoto','reambulação','fotografia','photography').split(',')
def shortHelpString(self):
txt_en = 'Imports photos with geotag to a Point Layer.'
txt_pt = 'Importa fotos com geotag para uma camada de pontos.'
dic_BW = {'face': 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMwAADDMBUlqVhwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIUSURBVEiJvZa9quJAGIbfMfEYTUSUQAqLYOnehJobsBTlHLbRQtKKlY3lObegxRa7pRdg7y0saiuoKAErMZif2Squ2eTEOCfsC1Pk+3uYb2YyQwCg1+u9UUqHAKoAOCQrB8ASwPt0Ov1JdF3/bprmj4QhoXp5eXnjTdMcUEr/Bw+WZQ15Smn1q4UIIZBlGaIoghBys2+3W1yv19u367rfeAAc6ww5jkOz2USj0YAoigH/aDTCbrfzpfCUUrAC2+02NE2LjPm3NjNQkiTU6/WHsFAgi1RVRSqVCthd171BwmozA/P5fMA2n88xm81g2zYAwHGccCAL9H43elosFrhcLpE5zMCwHMdxImtRSp8DptNpZDIZAIAgCAG/IAi+42Ga5q29nkin06FxgZqmodvtxooFgPF4jPV67bM9NcNnW384HJI7h49kWRZOp9PXgOfzGfv9HgCQy+VQKBR8fsMwYFkWAOB4PMJ13UAN0mq1Yq/hfVytVoOu6z7/YDDAZrP5Wzzk6CR6LOLEJLqGcWrxYX2OW5wJmOQOjQX0ApOERgIrlQoTUJblgK1cLodeWZ4IIeDDngZx5P1T75XNZiFJUmQeTyl1wPAW/awrD7rlpDiOW3qL/cz4DBY1CCG/U4qifDw7O1YpivJBAGAymbwahjG0bbtKKeXjJJdKJaiq6rOtVqvAjU8IsTmOWxaLxfd+v//rD1H2cZ8dKhk8AAAAAElFTkSuQmCC', 'github': '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', 'instagram': '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', 'lattes': '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', 'linkedin': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6QAADOkBmiiHWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJRSURBVEiJ7ZU/aCJREMa/t7soa5LOoGihktZOQSxSWykBIYVaWZ6NVa6wSZ/WI5BGziJypA1CQBLsgkKKgBjFQkEtkouJ+AdxdeeKnHvurXdcXK84uK/amfl4v9m3s++xbrdrury8PGm324dEZMYGxRj7arPZvoRCoSPh/Pz8pFqtftgkYEnmTqeT6PV6xDscjs9EZPpLIADAy8uLS5jP52bGGACA4ziEw2H4/X5IkoSrqytcX1/rBhHRrrCcCAaDCAQCShyJRPD6+oq7uzvdMG458Hg8GoPX69UN0YDG47HGsCqnG5TP50FESjyZTFAoFDYCYvF4nBbDAAB7e3vw+XyQJAnFYhGPj4+6IUQE4eekJEm4vb0F8DaFC1mtVphMb3+BLMtotVogItjtdjgcDhiNRvT7fTw8PKzcbhXI5XIhlUqpOkkkEpjP5zg+PoYg/LCfnp5if38fbrdbteB0OsXFxQVubm5+DTIYDKoiYww8z4OIwPO8qhaLxbCzs6Pp3GAwIBqN4vn5Gff390qe0zj/UKsgywqFQqpY843eo1KphHK5DLPZjIODAxiNRqXmdDqxvb2N4XCoD1Sv13F2dqbEs9kM0WhU5bFYLApo7a1bTOZClUpF49na2lKe1wb1ej1VvGqklwdobdB79R/0j4FkWdYYiEh1dawrAcATgF0AaDabyOVyyuE5HA4xmUwAAJlMRjl2ZFlGo9FQLTQajZDNZiGKouKp1WqL8hNLJpPpwWCQ0N3ybySKYpqLxWJHjLFP399s03riOC4dCAQ+fgMeouMzfwx22gAAAABJRU5ErkJggg==', 'RG': 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAcCAYAAAB2+A+pAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMfwAADH8BdgxfmQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJtZdLSytJFMd/1dXB+OiQRJEQBEnbPgISJGIQcePKjyBZzoP5AH6OuR9gFjPMznwC1650EbKSy00WPhJ8EMlDtG1M0p2axZCA1871cZM/NDRFnfqdqjrnVJUAODg4+E0IsQ8sA5LRyANKQogve3t7/4hcLvcH8NeIYL5SSv2uAftDHhSl1A/7CCH2dWBxWNBoNIppmgSDQarVKufn53ie59d1RQO0YUBjsRg7OztomkatVmNpaYnNzU2EEH7dNX0YUKUUpmlyd3dHPp9HKcXV1RXT09MIIXyXfihgKSWGYVCpVPoQ27axbXugjS/4HcHh29btdlFKsbq6SiwWA6BQKHB/f/82WEpJKpUiEAi8aA8EAiilaLVaNBoNrq+vabfbr+BCCG5vb3l8fCSTyaDr/ov6KrA8z6NcLtNqtUgkEszPz+M4Ds1mE9u2MQyDjY0Ndnd3mZmZ6ds4jkMoFAKg0Wjw8PCAEIJOp+ML9nWnZ5hIJJBSUiqV+gMIIbAsi3Q6zdbWFoeHh7iuS7lcZn19HcdxsG0by7Ko1+sD93lgcCml6Ha7SClftZ+dnbG4uIhhGMzOznJzc0OlUkHTNBYWFtB1nXq9zunp6aA8/lxUe57H09MThmEwPj7ed+ji4oLLy0uEEHieNyiHPw+WUjI5OYlS6lXE9krmj6DwyaplmiaGYVCtVqnX658Z4u0ZCyGIx+O0223GxsaYm5sjHo9Tq9U4OTn5FPRdYCkly8vLCCEIh8MopSgUCpTLZVzXHR3YdV2Ojo7wPI/t7W1isRjBYPCnoPDOPVZK4XlePz2SySThcHj04J4ajQbFYhEpJZlM5lWOjwwMUCwWaTabRCIR0un08MG9gt/778l1XfL5PJ1OB9M0WVlZGR54amoKy7IIBoPouo5lWYRCof7SNptN8vk83W6XVCrF2toaExMTHwKLXC734vCVUpJOp9F1/cW5rGkapVLpRcGIRqMkk0kikQiO43B8fMzz8/O7wd73Mx90EfArg0opNE178/LwnboaUPID+H2DnPkgFOCbppT68lGrn5VS6k8tm83+DfwKfOX/Z8ao5AFflVK/ZLPZf/8DudZq3wvXLmgAAAAASUVORK5CYII=', 'tweeter': 'iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMMQAADDEBLaRWDgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK5SURBVEiJpZU7T+NAFEZP4kAePBwZ8TA0EUIRKKIgQhSImnZ/wDYr7Q/barddbRu2QVAQhChAgBQqQClwFEIcx8IYfLdKNk5sJ4GRRh6PPN+Z+90749jZ2VnGsqyfwD6QEREARISocdRcT7dF5AD4lmi327+AL0GCn4QgIhkR+SIiPxIish8k3i/yQVCn7ydEJD0sgjDBMUCZxCg2hQmqqsri4iKKotBoNKhWq741vesSvULpdJrJyUkajcZQy7a2tlheXqa3FQoFzs/PmZubQ9M0Dg8Pu2vivQJLS0sUi0Wy2WykFfl8fgACkEql2N3dJZfLcXFxgaqq/0G9O04mk8RiMba3t8nlcqHRrK6uDkB628TEBDs7O5imORgRgGVZ3Y/z+Tx7e3ssLCz4QMlkkng8HglqNpscHBzw9vbmz1EHVK1WWVtb6wpNTU1RLBZ5f3/HMAzq9TqO40RCAGq1Gq7r+jboK4aZmRmurq7Y3Nz0LVQUBV3X0XV9KATAcZwBy7vlLSJomjbU/1Ha8/PzAMhXdQ8PD5+GABiGEQ1qt9tcXl5+CvL09MTLy8ugdf0T9/f32LbNxsYGs7OzY4Our68DD/oASEQoFApMT0+PDTFNk7u7u0BQPAhULpdxXXds0PHxMZ7nDUBCQa1Wi1KpRKVSwTTNkSAnJyfU6/XQWz4QJCI4jsPj4yOKogyFnJ6ecnt7G3nTd3OUSCSYn59HURRUVUXXdTKZTCTAtm2Ojo585dwP6rx3Qa+vrzSbTdbX11lZWSEWi4UCLMvi5uaGSqWC53mh/67esa/qTNOkXC4DoGka2WyWVCoFgOu6tFotDMPAtu3QXISNA8tbRKjVaoEnPCwPYZZ1nnHP8+ww2Ed7P0RE7LjneX/7ff6ocES0pbiIfBWRP57n2aMAwywKGdsi8ltRlO//AFPkniYXwGRMAAAAAElFTkSuQmCC', 'udemy': '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', 'youtube': 'iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMNwAADDcBracSlQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKkSURBVEiJxZcxSBthFIC/918uGhxMsyptcGjoIgGHW9wSihQKGZrNthHsIC7S1TqWgkRwcZV2lKo0FouixaEuEQ4khIIdrClkEoIZgiae93fQgFgll5jqt93x3v++e3f/3TvhGgYHBx/UarUUEAMeA48A/3WxDagBf4A9EdmsVqsfd3d3j64GyeWDZDJpFAqFKWAC6G6haCPKIjKTzWbfA+4/Ev39/V2dnZ3LwNP/UPwqaycnJy9yuVwFQF2cVIFA4PMdCQAMBQKBL8lk0gAwACzLmtJav7kjgTp95XK5ViwWf0g0Gg36/f7fQLBRltYaEWkU5hkRKTmO06dM03ztRaAuEQ6H0Vq3RUJrHTIM46XR29v7jvNt2BClFEtLS0QiEfb39ymVSrfujIg4Cog0mxiPx1lYWGBycpKenh5c122cdANa64gCHra6QCKRYHl5mfHxcYLBII7jtLJMWAEdrUrUSaVSrK6uMjo6SigU4uzsrJn0DtU4xhs+n4+xsTFWVlYYHh6mq6vL821qm0Qd0zSZmJggk8kQi8XuR6LO1tYW+XzeUzd87S6ey+WYnZ0ln88jIijV+DrbJnF4eMj09DTb29u4rtvU+8MHVLnFDjk+PiadTrO+vs7p6WkrS1R9QAGPb8zLaK2Zm5tjcXGRSqXiqe03sO8D9pqVyGQyzM/PUywWMQzjNgIAv3xa600Ree4l2nEcRkZGODg4QCmFYRi3KQ6AiGzIwMBAt2EYB9znp9y27bLWesZjUtsELkjbtl2ur6osy/qqtX7W7io3ISIb2Wx2CHDrT5TrOE4SWLsjgW+O4yS4mLiv9ldZljWptX6Lx2mrSY6A9M7OzgeuG/kvE41Gg6ZpvhKROPCE85mj5Z8fEfnpuu5313U/2bZdvhr0F9Fo9phaoDu9AAAAAElFTkSuQmCC'}
image = '/9j/4AAQSkZJRgABAQEAeAB4AAD/4QBYRXhpZgAATU0AKgAAAAgABAExAAIAAAARAAAAPlEQAAEAAAABAQAAAFERAAQAAAABAAAJjFESAAQAAAABAAAJjAAAAAB3d3cuaW5rc2NhcGUub3JnAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCACqAQ4DASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK8U8Yf8FAPhp4P8bah4dk1pbnVtLma3uYYig8uRThl+ZhyDx0xXtdfmD/wVa/4Jz+I7Dx9rHxQ8H28mraXqchvNRtoB/pWnTHl5FH8UbHLZHKkkYxg11YONCVS2Idl3/qxx42rVp0+ekrn29pX7b3gfVGA86+hzzl41x+jZ/Su08N/HDwr4r/489atGbGSshMe3/voAV+CXhv46+IPCk5sobiZJQ6h4rucqpKnp8wO38cD1Ir6A+D/xl8eadBHdTabqESuDsaKRWjuM9435R8Y52Mfw6V9dh+F8NiOWNOq+Z9lJq3k7b9bHkUs8cnZo/ZaC4juolkikSSNujKdwP40+vyz0X9v3WfAN+PtU2pabJwMshhJPv2I6V7p8P/8AgrTpOm3sNn4ieG6VkVmlC+TKgPc8bSOnQc+tcOY8I4zDKVSlapGO7W69U9UvN6HpUczoz0loz7YorjfhP8ffCnxq09ZvD+rW91Jt3NAWCzIP93uPdcj3rsq+XnCUHaSszvjJNXQUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU2WJZ4mjkVXjcFWVhkMD1BFOooA/Jf/AIKx/s2aR8IPjpZzabY2sOm+I7Y3tup+QwOG2yRq390HDc4ADgZ4r5r+HHirxL8NdceLSdYjsVnOfK81rbzx7oytFIP+Age9fZX/AAcbX1hY+FfhqzCb+1d2o+SUYBRH/o27dxnrjGMd6+Nv2OvgT40+MViyWci3Fnkboboho3Pphwyk/UfjX6p4e5hglVeFr0rq12+Z2Wu7T0T+/Sx8TnWHl7f93v5HtEPxy8V32j+TqXhnw3r0LLtZbmz8vcPTdGWjH4AV4l8cm0/XI1EngvVvB1wvypJaXz3Fmy5zgK4+UZOcBsewr3P4kfs6zfs+T2za9JN4RvZhmDZqAt7eY+3mebAx/wBlGT6CvfP2Mf2K/FH7QOgNrvjDUms/CsxxYk2sf2rU0/vgcqsZ7Mc7uwxg19xxHLJ8PQ+sKTUJaaNTi730Sbb1V+qRz4fD4qs/ZPc/PL4ZfGH4kfCbxDa3WgySzw2xBjktZRHIpByDj5fyA/Gv19/4Jf8A7ZviT9rb4b6tH4q0G/03VvDTwwvfSW7Rw6gHDEYPTzF2/Njsyng5rb0T/glt8F9Im82XwzLfS5yWmvJI8n3ERQfpXt3gbwDovwz8Nw6PoGm2mk6bb5KQW6bVyepPcse5OSa/Lc9z3KMVgvYYejL2t1aTskkuyXdK1n959FluX4mhPmqTvHsbFFFFfCnuBRRRQAUUUUAFFVdc1eHQNHur2c4htY2kb3AGaytP8bLFoEN7qiwWG5VaTdKFSMsQACWx6ge5oA36Kqw61bzorK/ysMg9QfyqZLqOT7sin8aAJKKM0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABQTgUjusaMzEKqjJJ6AV+Sn/AAUH/wCC22oeLbrWfBvw8jm0nT4Jzay3bZW61JQ2Gwf+WcZx0HzEHrziurB4VV6nLKahHVuUnZKybt5tpPlitZPRHLi8ZTw8Oaf3HG/8Flvjev7Rn7RDQaTDNdaL4Ph/s20uU+e3uZN2ZZAR6OSM9GWNSK7j9kr4h6V8EPh7p0cckTbIw7uSPnPUk18xfDf4j2t5osCSXDCYMZ7gTcFR/dB7/wA6oeJ/F9v8RND1PUNOimhg3Bbgl5ITHhRgbQdpyMZAB5JzzX71w9k+UQwrxGElpKKUlP3dl0kk1q9Xe3c+Lr4yq6rqS36WPsfwFYz/APBR39rrT9HvHZvA+izG6vIzyt3DEQzLj0dtiZ7B89cV+oun6fb6RYQWtrDDbWtrGsUMMSBI4kUYVVA4AAAAA6Cvy5/4IDLf3fxe8YXWo30l0iaGsNiGVI1CfaIzJtVep4jyxA7de36mV+W8bVpvGxw+0YRjZXVtVdtWbXZb62u9T6rKEnQ9p1kFFFFfGnqBRRRQAUUUUAFFFBOBQBx/xMuf7W1DTNDTpdSfarnHaKMggH6tt/AGvz6/4ODv2ldY8BfCXwl8O/Cd5Hba54kvRql4CgcC0gOERlPGHmYH/tga+9/DNx/wkWu6prTf6u4k+z22e0MeQD+Lbj+Ir+cX/gpJ/wAFIZP2p/2zfH+qaG19rXh3T9SGn6ILWIz+Vb2uYRLGADhJcNIc4GXzzmu/LqfNV5ui1OTGVLU7dz1b9kP9uj4ifBTQ7fTbDxJqlx+8Z/sEk6rbu2SWEci/OqnBGMfKexGc/oX+zn/wUS1j4u6ZINN15v7U08KuoaTfJFLcWbH1IGXQ9nBwfY5A/CfQ/jZ4m8U6nHJp/h1rU2LYjjaR1uZ8kKRxkAg5+bA/E9fX/D3xj+JPw68UW3iH+xL3w61qU/eWlzFNIXf5sAswI3ANkEMM8EHpX2eHx1Fe7iIKcfNJ/c2j5bFYOpJXoTcJeTav6n7xaR+2d4l08D7Xo+m3qr18iR7dv13D9K6jSP29dKBC6lo+tWbdzGEuFH45U/pX59/sef8ABSPQ/ivpUFv47ht9DvJBmK/gT9zKoJXc6gsVyRzgcE4xjDH6y8L6LoXxO0Q6hoWoWesWe4qZbdslD6EHBH4gV1zwOTVVzSpcvmm1+tvwPBqZ1m+Dly1JXXmk19//AAT6A0H9svwJrRVf7dtrVz/DdxyW+PxYbf1ruvD/AMTNF8UoG0/UrG+U97a5Sb/0E18ZeIPgmzKxWLcvXpyK4DxJ8JpLOUsiPHIpyGXgj8amPB+WYj/d68ovzSl+XKdVHjauv41NP0bX+Z+kSalC/wDy0x9eKmSVZPusrfQ1+Ytv448feBD/AMSvxZ4gtUX7sZvHkjH/AABiV/StXTf2/fi14NYfaLrSdaRe15YhSR9Yilc2I8OsdFc1CpGa+af5Nfie1h+MsJP+JFx+5/19x+k9FfBfhr/grtqmnFU1zwSsn96XT9QK4+kbqf8A0KvRvCf/AAVw+G+rlV1JfEOhv0Y3dh5qD8YWc/oK+fxPCea0Piot+ln+TbPYo55gavw1F89PzPq6ivJfBv7cPwv8clVsfG3h1pH6Rz3YtZD/AMBl2mvSNM8WWOs2yzW1xHcQt0kicSKfoQTXh1sPWpO1WLj6pr8z0qdanUV4ST9Hc0qKhS+hk6SL+JxUwbcOKxNAooooAKKKKAOS+Pmj634h+B/jDT/De3/hIL7Rru307c+wGd4WVPm6A7iME8A4r+bzxq03w3+Jeoaf4g0G6j1K3na3u7afdbXVq6nBBDA4I7hlP4da/pwrw/8Aa1/4J3fCr9tC3WXxl4fVdchTZb63p7C21GADoPMAIkUdlkV1GTgA80RhF1YSnsnqeVmuBqYin+6dpLufiTpOh6Rc/Ds6lZ6pDb3N0WgWLUALTA2Es27JjwOBy4PPQV9OfsZfsw2tv+zBbtr+n2txcaxC9+sl5H5glEp3RhZVyD+72cg4Jyc81q/tMf8ABJHUNA8f6L8N/BWtW/iKTUIRNCLtfss1kpEzlnYEox2wH+6CQox8wr2bxd+zP8Rvht4NGm6X4V1zy7W3W3jj0/E+UUYAHlE9gK/esrzTBYmUMLQrQVOMVa/utuXLzXUrbcu9npI+bjgq9J81WDv96/A+TvgF8Yrj9kv9vr4fX2mbodBEraTqthHI7GaO6cRswXJX5fkcY5LRgV+4Ffkr+xH/AME6fiR48/bA8P8AjDxx4R1XQ/Dnh7UBqss2qL5Mk0kWXhjWNjvbMgXPGNobJ6A/rVXwfiNisFXzXmwdrWSbTutNFa2i22PfyOnVjRftL6vS4UUUV8Ce0FFFFABRRRQAVzvxQ1uTSfCskVu2281FxZ2+OoZ+C3/AVyfwroq4fV5/+Em+JW371roMW32M8gyf++Vx/wB9GgD5y/4K1/tIN+xn/wAE7PGWq6WJF1rULNfDukCKURPHPdAxGVWJGDFH5soPrGB3r+cb4ba/b2treahaWs2lxw2q2wure8kiijfIBd41+9nAJBLYOT6Y+4P+Dqn/AIKLzz/tW+GvgvorWd3pPgfTRqOtxyhmVtRulDohCsBmO3EbAnp9oYV+Vdz8f1ijt47XT4Le2kPmzpbSMqu/HCg5wAMdep74wK9jASjTjdnmYyMpysj6I8eeKRFf6fJpuqXVrczQrGup2QKo5K5fBJ3fe47nocU248Can4ttAt54ga/uoHaQE3TyrKdpwu0gMCMDj1wPQV5j4f1mx+IWlRxwXjXFxt3zQyvIpQg++QvJGSMg4qT7XeeHY1hha6dQ7bY2bekbLySrKAwAPUjGSa9Tmuro4OXoezaVpviX4b+C49SuLSS4t5mWeFhJ5f2cBjufYMfMMD5WIJJUdOD9AfsYf8FFfEXw/wDGVrbQ3VxY6lN+4mWIfuJoyOWVWB5PUL2IGPQfJ+heP9Y1bQYZNQ0+/uNNvpY455Y4fMlnTdjIYkq2RxhhkHA9KxJtbuvD/iqw1Tw/czWi2DrETdlRPJCS247GwAFAwQT1Y884rSliZQbts+hNShGpHlmj9pvBX/BQDx0NYW3jubfVoJlM8EmoRxfZ5oxjIMi7SrdsE4z0r2nwN+2V4f8AGGiWj+KdFk0ua7k8v7ZYstxYoOQWaTd8uCMEZJ46V+PesfHnUvhh4U+xyeILrVdD1Jhc2OrwBZmgbJGHXJDZ98ruPGMYruPhF+1XZaf8OE8zVLWW1hkxcP8AaSih3+7JsYAryCMkdTjgYz7HtaLaUdH5aHgVsnoVFrG3pofsNr3wysfEOjw6hps0N5Y3kYlgniO5JEPIIPvXlfiv4XeWzL5f6V5N+yl+3+3gfwzaWtxPHrnhhbd7pbcNm5tbdSQzRMTyVPLRsc8k5UV9V+BfjF8O/j7p9vN4d8SaXdTXaB1tZn8i5+nlvhjjpwCPevYwecYjCO09Y9/8z5HGYCrQk9LrufOeufDLBb91XK6p8L95b93+lfX2v/B5iW2xfpXIat8KltMtMqxoOrNwB+NfUYfiLD1V7xyU60tj5SvvhRuJ/d/pUOleFdY8JXXn6TqGpaZNniSzuHhb81INe1fFPxl4Z+GGnXE9z9qv2t+HW0h3jOBgBjhT1A4J6145pv7Z3hPWblGGjXUdpy08izpJLaoDgl0A6jn5QScDpzWdXiHKm+Wcvwuj6DD5fj5RU4Qf4L82d/4N/ag+Mngratp411i6jX+C/wBt7n8ZQx/WvU/Cn/BSf4oaCq/2ppHh/V0Xq3kyW0jfirFf/Ha+RPjP+15FZ3Mn/CG+StlDGm64vbXEkzsu4gK2QoXgZPJ5PSvF1/ai8Qavqs1hYarq11qcq7IxFMzq+TnKqm7JIHpxyPTPyuPzHIak+X6upeaSj+Wp9FhcHmkY3dXl8r3/AOAfrN4b/wCCt9nAVXXvBmt2XZnsrqO7H1w4j/nXqnw5/wCCjfw3+Imo29jDql3Z31ywWOC8sJY2YntuUMn61+Unw2+KmtaPMZ/Hzw6N4d8qMyXGqfu71GwASsEatJhjz86jrx79n4q/bU8H/DPQGh8Hw6f4turi5SWOS25VUIyokYNvJGAcfKCc4A5r53MaPD/sOegpRn/Knt6t82npr6HsYWpmiqctVxce9t/RK39dz9hNK+KeiaxMI7fUtPnlOPkjuUZuRkcZzyOa2Y9Whcfe2/UV+Inw3/aGvPilpmtalYahNrWsavsOoW9pdtbWcDRfIgVC4VMdGGfmJBINafiT9of4sfDnQZrjRfGzWHiJXtlhtp9YmbTyoO+YEp+7DEDAVckBuD0z8nLDw3hI9yNRtXaP2uS5jk+66t9DT6/Eu1/4K8/GL4TtpkaeLrfxZHfP9s/06yt5o5oSHYpG6rE4UYABckkKxGccdl+zf/wcI+P/AIp+PI/COueDfCseoahHOkU+n3VzbyREI5WQI3mq/Ck43KOOo4J46loT9m3ra/3Gimmffv7O6/8AC0/2p/H3jN/3lrpIOkWLNztLMqtj/tnbROPa5Pqa+ha+Vf8Agl78ZNH+JPwQ14aIsyyaH4kudN1B5drLLMkUJXaQeQsLQoScHdG3FfUWmXTXlp5jY3b3Xj2Yj+lF09UUWKKKKACiiigAooooAKKKKAKfiLW4vDmhXd9N/q7WJpD74HT8eleb3fiuy+Dnwh1rxZ4im8i10yzuNb1SXuqojSvj1wAQB9BXQfE+5/tnV9L0JPuzyfa7r2ijPyg/Vsf98mviX/gvh+1vb/s/fstaf4QtbxbXWviFd/ZwAR8tnb7ZJifZmMKYPBDv6U46s58XiFRoyqvov+GP52P2q9B8U/tS/tC+NviRrkrS6p4y1e41WdJI/MW3WVyViUjB2IpRFH91QK8k1v4HatAWCWqsWbH7qRlwOOzZ9PXtX3Zf6xY6xoKzXkemxy3hXBjjVGcAkk5Hr09OPaqKaRosULhrWGZ2ZQASQwz3HODXbzJaHxkc+qr4kfAc/hjW9BuWmWO/gkhXYrIuQD9VJ/ya1PDXjTxPpUMKWuoW7CQSJ5Esixna/wB7Kvg5J9O9fbeveDtHuolX+x7bYpLHG35+OBxn25rFh+BXhnxVfRRnT0hkUjzN0qANzyAGwOMgY71SrcvU6Y8QU2rzieCad468QaT4TaG+bXbGRW8/eqS+TduWzksDxg8g89T0rOi+IcPie0vv7bvLmHVI/wDj0miIjUjBUB2xlh0+9jOOor6Zi/ZN8J3UG7R9WbQryFyGfypbYsSeBvR9pwfzrm/iR/wT/wBQ8X38Mr+MNN1C5dNsZkdCxXsMlMn8+tW8wgt3/X4GlHNsNUdrtfI5X4VeL9F0/wAAWtlda1ptv4gt3cfZ5wTZajAVHyS7RgNhmwwyeD1GKPit8N7bwHPa3mh6zZ6haX8KXLW0N0sjWe4fdzn515GMjgY+tZPiP/gnP420O4kjMMcrRMRlXdOeR1y2e/QVzM/7MvjbQ5G8rT7u4XG3EBWRB2zztPb0rX+1KUo8ra8tTsioTd4S/A93/Z0/av1j4N6xZfalhvtNt4pI1tWQJE4dSH3DBKsRgZGQQBkYAr2H4MfHvUNZt5LPVL6XT9BuZibYyQSzqMHK7SuBwCeh7civj/wz+zL8VLrzriy0a91Py4lY7IzIYsckntn+XSrkOp/Eb4XRtHfQ+I9JeKRmZ2WWBRgHaB06HB5rpp5tXUOWnL8mRWwF9Wj9lPgj+1x4wtPCsekx+NrlNB0pRHOJFVby3QkktFvBmfblRtJ77QMDI82+PPx88a/ECW6inuNW1PTbRy9vbTXzTTy9djPCxyVzzwg6Yz1r88v2dPij421Txrp9rZ+JLuO2ZDNOLsiVGTd825GBydpHpyCc19XXviLWvBfxslt1sdPuLHVdOjS5uXkdWsyiNsKqDhjjccEYxj1r5DOOMpZfW5aqTdnJvVbLb1b9fyLwuW0kuaEEtd7amT4h+K3inwfodmY4damsdLnRxFcxOIoJMqXbbym5cgnrtHauH8SfFA+ALHV9Xa7ga/up2SC2t2cEhsZMreXtIKk/cJ6Yznmub8X/ALQup3C32nm2uZLOOSTbKZW2NuOCCufTGcZxXjv7UHxut/Fvi1NP0/T7zw/bW8MdrFDO6BtwUb84A+8x6k5bj2A5aPE2JxEZJWi5Wt1sutv66nqfVUran1R8ItDtviP480m61S5e70trJ7iSKyLSYdfmUsDj+HJORlhkc4r3rx58Ifh74D+HmneJ9PupWvrhSuny28zxrcSDkqGV+2SDjA4HTHPwn8DvjJf6VqlvZ2twZp4X2wjymDrEqEPnkoI2VMEdfT0r1PVv2i7nx54H8ya6tri00OzdreIBI1jdPmYAcc5xx0wecVy4niKdODox1m9bvpd69ul7efoaxopGzq3w0fWLjUbzxBpd5Jotg4eS9W8neIbsbUYM2c4wMrkZPOK+oP2fvgzpPhPwPCvgVdMW3vrc3E+p3H+sZSq8MGGCMMAM8DcBnvXyz8cf2z4LL9lvwPPqN5ousSX0oVtNtSzNAkShd0hChFAZgNqk5yBwAQb2n/GWH4uweEtaXWpvCf8AZs0VudkwJuNoXAXaMDdtHHJAUnkgCvYrZ/Rg4U7aaXfRX/N9whTUbvqeoeNPA143iAva2em+HbrTb/bb2z3G2PU1LHyvN2Y/dkhWVG9GJOGUHJ+PGpeLNR+G9vBf6fp6y2NwjT7NVZWvowu7ySMN+7GSoAIU4KkDHPP654u0fxNoNulhHqOt65Y34EwXSljtpxvBeVnL7i2FOcBf94Va+K7R+I/BOoS6bavHDp9qFaAy7mCyR/Ko3AOSFzngbiTznp52ZZ97CKqwabukl0t3/S9+o+mh4v4b1XWvi74cu9U1q6s7HTtLd9OLwMsbz7SMBY5DkBQfvDbxwAe27+zN8RtJ+F/xQ8QeIr68WSHQdGuJdPvDnKTz+VbxxhScOx81nHI4Rs46iVfiF4dtfh6nhmX7bqt1C7XFpPE2Ps0pc4Vk+5nnjOMHr1IPCvIniTWtYsYGhthbqkcVs37nzSp45UfeG3B4OOox38LHZ17XEe3gtkvJL799e33nTTilA/Z//g3A1e51b9kvx1LePHLcP4zmlaZGLLMGsrQq/PcrjOM85r9HfDlxHLYsqurMssmQDkjLsRX5bf8ABsvpF1dfsm/Eax1K5uJ0i8XbrcM5/dIbG2UFeTwxTdzjkniv0t8MeALW3kabzrjzIZMDBAHQH+tfW5fZ4eLv0CW51lFCjaoHXHc96K6xBRRRQAUUUUAFDNtXJ4A5NFcz8V9bk0vwo1vbsVvNUcWcGOoLfeYf7q5P4UAYnhKb/hI9b1TXW5W7k8i2J7Qx5Ax9Tlvxr81/+CmHw+1T9qD9qC+kaOc6X4diTTLAeU7R7Fy0rklCmWkZxwclVX2r9GfiX480/wCAfwku9XuY5GttJgVI4Y8b5XOFVR+J/AAmvlOT9oH4V+JLe41DXNC1awj83mWKzuJGDEHBwI88kEAqD1z3rws2zjC4acaFaqoSeurtp6/JmOIwcMTT5Kmx+efjb9jPUrfR7hLjT9N1COPDW8Sxws0SE5IAC7gMk8A9STivLdY/ZQsb23khm0u4sJdvDQqVaM9uD7+or9YNV1X4Z6/pE1romvWWi61IoaN9WiYRlSc4KM0bkkEYPQZ74ry34p/sUL8QtLhurvxJpK61FbBttj5McdxJgbxG8sm/byTkjGO+ME8lPM4VNaFRS66ST/W55P8Aqym/cmj849B/Z7n8N3QX7HcahCRxG8Ryw+qsBVnWvh5pOmwLdXXhlrONmAkKRvuI9AS+M+xJ6V9O3H7E0NlBDdTw+JNRbslu1pcuArD5iRMCQeeBzwe+Krp/wT8l+JFrcSC4vtNZQZPKvrOWEJwTgBWccDrknrjit442o3bUcuE5b3R8w6Pe+B9ZgglsY2h+0KnlbXdvLJ/vdQn0rvNF1Hwv4Tuo7ix17w7NcQ4LoEMhXg5weQDn19qvz/8ABMfVINXvmjhh1FZFO6aOykXYinGA5j3Zzxwc9fepYv8AgnybbSZ4ZINQ09YW5uA0tqqDJJJMyJuH+6ScdhXQql1eTMv9VZX0RBcftE+EdL11trL9s27XnuZBzn0GVUdSa88l+Meg/DrW11TT9YvLZYJC6SwNGFRs/wAIDZ/SvRrv/gn5JaeNPAGiw6t/wktv4z1Z4rmHTJhPdfZLWLz7oYORuClAO/zcAng+ZfGv9jnwrbfth6l8K/BOr6jqk8dn/aNsbrTVDXQWJZWjLI2Q0Yb5vkQ4U98VleM9JPr+O+h6GHySrQalFtHvXwj/AOCqcOlTW/8AaqafrkPGZHVra4Ve+SFVT+Rr6t+Ff7Snwh/ac0b7FNb6bILhgJba8t1ZXbuVkXgt+IPtX5p2n/BLL4qatqxuJ75ZG2jC28r2429AuGXp1yK9q+Dv7KXxO+HdqzL4dZpWYR7lvEVZVBxllDKCfqe/etPaVYaQfMuzR71GNRK1Q+4rX/gnH8C/Hd19qj0mytrwniRVKuh6ZDhtwzknGe4GBXi/xY/4JZWd/wCKZr7w/bXupf2aJ7fz/tstvc7CuMCOfdHMCDwwYZI7cmuP0fwr8ZPCd2JrPRbqTfnfE17Coyck4w5wOcDBz8td14L+KPx48LWStDoOtsOgWQRzYz26k/8A6q5sZhqGIjy1INea0/PT8Db2MfL8D5T+Jn/BLW58Fi5ka38Q6bbTOht7zUtIeZYHGM/vIdyEHA9B1JHp4H4t/wCCVU/if4h/arbX9F1Oyn3/AGqRJDGclsjhjlegGcnHPB6V+oyftx/Fzw2xi1HwZqUqqCrrJp0m1SOoyvH6Vh+MP2q7DxmLeTxR8JdOu+SPMewMcgzjncFUj8DmvKll9SlLmoV/lOP6xa/Il4ZM/OHwX+ybrX7POj6ldXfh3XfEVxHZvBFLptk99G25sFf3SkgnIOccgc46V4T8dPEepeD75dFOk3dq10u/7Klu1tdrJIAWUnvnkHdnqeO1fqX4/t/A/iW1FzoNl4n8FXibiJMtfWuDxgrI4bOTxh64HxqPE+m2kcUGpWvjCz6qbknA7YaGZSvfoC3XrXkzjWoV/bVaXPfdxlf8HZmc8L5H5eeBPGAs9UtbfxBY2MdpGZreKy1aB5Y4G37gcAAk5OA3I+T0zXfRfGDR9M8ZaLpkekR2Wm2lykoCsCu4nBZCONpKk+/PSvqn4kfDPw/4ntt3iD4a6PHty32i2sPsQXIwSDBsHIOOneuK0H9j74V6t4qsdRWXxBp8dqpjigi1CK4QDB4CXCk7ee5OOcYo+v4CpU56nNB+d7L7r6nLLDuJ3/wE+Imk67oFiyP5sE072zJIFLIm1jwPUnjI7464rjPiz8Rlbxlr2ktJNHYyWGdqZXyZd2U5AzySBkeg6V0Gp/sZ+EfD/iGG88J+IbzSpIl8yJLu2ktcv6hvMkjz7qAD6Vzvj/8AZh+JviHQdYaxm0W8uL6dLqFra72z24SMLtLYEbZYMzcZZj9KnCYfB1a7Ua0Xba+l3e/W1+hcYacrX6/kcl8KvhdNHNrV95i3dwb5raW7jtWSSGPKhgqbgGDYwWxnIIB9fQ/iX8HP+ETt71tMm/0y6Jki3IVcggnBY4HJIOOvr0wOJtPBXxK+Cfhi+tfE3hHxPZ21xOuoHV7fS5LqO6cqu8iSPK4bB5yNvoM8d94o+N/h/Sfilqvh9tYWa886AXR1BGRhHJEu0K5z5knIG09OuKqpl2Jgm5Jt8y+7p/XT5msIq3Kj9Iv+DZ69hu/2efiN5D3G1NftgyTIFaM/Yo/QDJPGT+A4Ffp54fPyXX/Xb/2RK/M3/g3csrPTPDnxihs5pLiGbU9Gu1cOXh2y6ZGyhOB2xkdsgdq/TLw+ci7/AOuw/wDRaV+gZbG2Ggv63OWatKxoUUUV3EhRRRQAUUUUAFcHqlx/wlPxPbHzWugR+WPQzvgt+S4H4mur8XeJLfwh4ZvtUumWOCxhaZixwOBXmnws+IPh+fQwRrWnT3107T3BWYcyMcnn2zj6UAflr/wc6ftr3HhnxX8PfhDoevahok0I/wCEm1i4sbloXXcWhtoyy85C+e5UkA7oz6V+ffhT9pbxtfa07P8AGa8t760VIY9OvF3fboSVymZFIGVUEHBBZvQ1+vn7eX/BAXwr+3h8Y9c+IB+LXjLRtf15l3xtDbX1jDGqCNIkjAjYKqgYy5PqTXxn8Uv+DWD4seHLq8vPCfjjwP4r5XyU1GS60+4ZVxtAOyUD/vsCvz/PuHq+OrOpVWnSyjJWv2ktLre3W9mjxcRTxHtHOKdvJmT4a/4KdaX4Wl0/TLrWvDepG1hVp7SfSZI/NiCltoaJ9nTqxjAznOK9m0n9vH4W3vh1buG88HR299CVfdcOkqcFhGGVi4YYPGMjPGelfD37Sn/BGD9q7wWlvJN8Fb7VBp6Ze98OanBqZvsEkbo0cynqeqgnjIr5J8a+BPiL8AdUlbxb4F8TeE7w5VjrWiXNpkg5yNyqev8AP3r89xHhq6kVLnqQa0avv62tp/TJWOxNNap/M/Z67/4KGfB6KC30yTxFodrJ5amKSO6mvLZZASAquU3Kw5Y8AdfevR/hl8cJvG2kzah4f1y01i1mQTCS0geVrePaEJK7wcEZyW4/lX4WeAf2t9HtbJ4fEujw6x5Q/dtDK0WwEncTjJLen5cc17b8D/8Agp/4f+DXiPTbxbC6/s3TbWaP7JDJ5RumOSI3KtkxkhVb6nHpXzmN4CzKFaKw9Spe+r5rpLys09O2lzoo5lOUv3jt95+tXxK+MPjbT9sCXmm31mpDyS7FVAH29fkZkKgMCGweOeDWXrPxk1TVtL3XWlzGSSQEJBfGPzcfeddmd2emGC456AV+XWgf8FmI/BtxcR6HZ/Zre+h/fjzCxuGJbhw3BGAvJ6AkDHWvRfCX/BVPQ/iN4KsbW/0axlvtPd5VuXj8yRWcoCB0yAq8Kc7ecdTlyyPieiuaWIqRXrL5LWT0+63W+50U8wd/jaPr7RdDj139p7SdQ8Wp4i0mOx09rLTdThuRHdaDdSzJKl2jR7lZvkRCCT8oIYMCRXlv7JOjeIvjp+3N488Uf8JBoFhq081+bN7m2WS61aVrnZIkT4ARfLz90EZj4GORqab8brX4q+AZL3T7mS1t4bNZWkgIVLPBXClVHGNoOBwenXINr9mTR/BfwT1BZPEUzyaTqtrHFFcW7bbrSbpC5jlVmwR8zhmHAyM8jOPoOF+KsXTxMcHmj2lo3frH7T73dk+mvy9Cnj5P3Zv5+R6N+19/wUS0/wAD+HdO8Rnw7dR31xa3F1OY3+yx3mHklSRG2tGxZF2dmBXvjNec/sUf8FjtF/ar8bWvhz/hHG0/UJo5JXdroymONRkFgAByeAB6Mc9q8Z/4KFfFPT9F/Zr8XeEZNStdSsfD0NxDpbeb++khe5eNH6/MPMyfUD1BFfAv7FNz4btfiBcasuoappzQ2skdxNCm8W7MFG8AENgKzZIPy8EZxg/uFOUprS9/JeRpKs4y6WP6LNN+Pej23hiO5kuLVIFALMjqpiI6hgzDHK9+nvzVjVP2s9B0CBftNrdQPMeHiWOZX4+8Dv5XrgjGSPxP4uw/H/4v/s53MNxdrb/EXwpeMsVnqKy/a47hSeNk4G5W6fLIM9tvFfQXwP8A2vPDPxkg1Gztb9tF1u18uN9PvoMPCGA6OScjqCcKcjGOmefFVMTSg5w1S7f5HTTqUpu0tH2Z+kEH7VGg67pMkjXclhIw2wv9lG1mwTgEE498gV5V8YvH2j6xZN9n8SWtxeOSGaS2ijkjGc44KttJXvkdK+aNTv7W4tM3c24wkPbtAokZ+Scjft49l7k+lcdrvi3T7i7mk8jbcJL/AK+8OzzQDjscD7o42n618HmHGidNwj7z+a++xr7SlDVM9X1nTrSGScSX1mwLGQPHH5iE88FhkdfXjnrXH6l4tvbNl/seeJZlOYpC3lEErklWz94Z7kfhmvPk8XtdxtJdWd6kMkpURWMjXBUdd7KVHGB2os7e5ilkhXXEktZm+S3uUETHIOFOV45Gemc18XVzifNeMOXzu3/mc8sQnqkdR8Nha+EzeRS32v6hNcSF5YNSmN0oY/e5kJbnk4z1J78na1bwT4f8WMPtGn6fC0nKMlv5bDrx5gJK47A8fyrgJ7fVNWvVt4Z4xCOkdrKCxblQTx8wyuOenHB6COaHWNHvFt5p5C8eN+y2D7Qcnjn/AHs8Zqv7Qq19XP8AH9P+AYSxDat0OitfAqaS3/En1a8gkL+XJCZ/tUZHqQRk59MnrUeoQ61oc73C/Z4LqNhtktZJLKT8OQPyrlY/ivdabfMC8ix8IZZIyqk5yVAxkY9eld34e8bNr9l5fmx+dcAYGVOQvpu+9jJ5/lUv3fekvmYRqX2Zr6D+0v43+H8azW+u39vPwrRXVvHd7zwMMxG4jnvVrWv2qdN8U2k0PifwD8O/Ecj5Ml5HZnTLotz829Rt3DsSpwa5rXvFE8D+XeaZDe2i/K1yluFVucAjDDBzzwpzSppHg/xfBBG8clpeKMEsfkJGc8bRge+R1r1MLnWMpK1Oo2u17r7mdEa03sz9BP8AghlN4VvNC+KF14Y0i80j7bfadLdRz3MVwg227xRpG0cafIqx4AK8Z4Pp+gnh44e6X/porf8Ajij+lfnv/wAEM/h0Ph9p3xM8tY/s+oTafLHJGyMsmBcjqrHpnvX6D6CcXVyPZD+hH9K/YOH8TPEYCnVqbu/S3VoyqX5ve3NOiiivYICiiigAooooAq63odn4k0qax1C1t76zuV2SwTxiSORfQqeCK8v1/wDYd+GOuuzp4bj0uZv+Wmm3ElmfyjYD9K9aooA8Bu/2EU0lt/hzx94v0dh92OaVLuMf99KG/wDHqpyfBX42eDhnS/GXh/xBGvSO9gktXP4jeK+iqKAPnB/iP8aPBv8AyFvh4mrRp96XS7yKbI9QpKt/47Ve8/bN0q1ga18XeEfEGjxyDbIt/psnkkd8ll2kfjX0vTZoEuE2yIsinqGGQaAPiPxp+z7+xz+1Gsv/AAkPw2+Fuo3N0T5s50WC1umJ65miCyZ/4FXhvxR/4Nl/2MvjcrS6DZ+IvBs0nKPoPiSR1Q+yXXnDHsMV+kHiv9n3wP44JOreE9AvXb+OSyj3/wDfQGf1rg9X/YD8AXLGTTF1zw/L2bT9TlVV/wCAMWX9Kh04vVoh04vVo/IP4v8A/BmBoepGafwH8cdStd2THb65oaXAJ7ZmhkT/ANF183+Pv+DT79qD4Tus3hu88B+OI7dy8Y0/WmtZ5B2yl0kSA8DjeR7mv30m/Y28WeGyW8N/FDWItv3YtStUuF+m5Ch/Sq7+Fvj54M/1UnhTxRCn92dreV/wdcZ/4FWVTCwnHlZlLDQkrH86fjP9g/8Aa4/ZkiiN98JviDa/Z+XuNNsJNTt0A4AMlsZF5xnr0ry3Vfj34gsdVvNH8RNr2m6leBBMl/5lv5TBwN+HIII4OMflya/p6f8AaH+IXhD/AJGL4X68sa/emsVW7X/yGzH9Kx/E37T/AMJ/ibbf2d458O2ciN8rWviDSEkX3BWZP6V87W4Rwc5c6Wve3/DHN/Z9vhkfy1/tKftHape/Au68E6zb2GpNb3UbWGpwKEuIo+MwvxyuU4GeMe9c1+yZNZ3vhfXXtYbPT9Rs7aIQPNKVkkuFmaTfG3QMUCqVPBCk8V/TB8Sf+CW/7D/7U0JbUvhn4FillYuJNHeXRmVz/F/orxqT9Qa8I8bf8Gof7OfiNpbnwD42+IXgueRxKkcOo2+o2qMM7Ttkj8w4z/z1r18PgJUqKpKW3Xt8v0OmEKkYcrd2fkjH+2XceAvEGn69pP8AZ62utQ79Y0sQ/wDEve4DODuiUDZjg7lGR3DZrqfDFzp/xu+I8XjvwXqem+DviDEA13otwS9jqiLtBKOMhlPH3emOgIr7B+P3/Bo18QnnjvPh58YvCeoXEasrwa1pM+nJOOvJiacAnvhcemOlfPuq/wDBvR+158DdIkht/Bmk+Jvs7+dFeaHrlvIFdc42JI8Uylh3Vcg4rHHZbVrpTo1HTqx2a1jLyknuvxXRsmMq1rS+7+tjxLx38f8A4j/s9eM7jUWtlsU1G8M0mj3sH2jTtrZY+Q54wM4wpUgEZr0DwR+3TofxJ0p9L8SW9z4ZW/dw15GPtNlOpGeAQWj5IGDwMdT36fSvAHxJ8L6DHo/xv+FHjTSLcEwi61bw7deSvTJkwmxxt58xDn2ABNeTfFv9iXdolxfeBNWt7iCQ7o9PaTKbW6FW6r16OMY/ir4zFTwNSr9Wz6h7Gr0qR+GXmpfpK9utilUlbT7j3nwNouk63FJdabIt/pCp5v7ycPDIOxVo2ODkA8DOOMd66Lwl4l8PeI9Unh8r7LJHGXdBKs3PIAO9cc9epO3B4r85dO13xp+z34gmW1v9Q0DUFOLi1JzFJ9V+6ynsefavXvhn+3UEdrfxVp62d9KPnv7JBJE/QAvD6ZAyQT9M152ZcA1lT9phJe1i9U07P/J/fr2KhUij61k8WaTo0c1s2izWMjOUFxbhWQMAejIcqvHYEgnpyK8y+MPi3XvDUEK6ZNe+dNIAYvNLDO7GA3UAk8Ag+4FN8OfFiLxjaR3mmeJNL1rT7aEs4uAitHymcnBdcYJwR2HSuC8ffGjwf4w1CabT9esVuACWEbSFCQxHDbccAdQeeOT1r5vD5XiI1OX2Tco76Sf3r/gFTqXhoev+Bte1a70JLm88ucIv76RGO+EnOcL6ZPXgj1wa1l1e+u7xgkN5eMy+bLllLyLtJXbkhhjGDknIP4V5P4J8eTXNjDcWt/deXeAytNHd+YsSBsfK2T0GQc9zg89E034kNJqF802oXlmvlBY1JSSI7iT8wwc8ADPbP1NKWHfO1KOq9fuMVUtueh6lr5utPhjksdqtLvCFtvzEgAEMMnrj5ieQR71ux3Ui2zTWd/GkkbHEE/ygjaOMkEHPPToc+teXJ8YNOvWtmkEd5JGNpY6aZMkkEAHqMDJz2x1NaXgzxvFql/ceZZWtmIwTOsTvE3POAp649hwMkHPFVLCtq8dP68w9rqfq/wD8EB/EEutJ8UFkj2eX/ZvIztf/AI+hkZ9cc1+kuhf8f9x/1yj/AJvX5W/8G7niGTV/HPxeRfLFmLTSTEAzbiQbrJIYn+8BkHnFfqhoR/4mVx/1xj/9Ckr9e4Ui45XTi/73/pTOiLurmtRRRX0RQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFU9V8P2GuwtHe2VpeRtwVmhWQH8CKuUUAeaeJf2PPhn4rdpLjwfpMEzf8ALWzQ2sn/AH1GVNclqH7AegWr79B8TeMPD7dVWK/+0Rj8JQx/WveKKAPnd/2a/it4S50L4kWepRr92LU7FoyfqyMR/wCO1C+t/HfwX/x+eE9G8RRL/Hp1+m5v+AybDX0dRQB82P8Atfal4Z+XxR8P/Fmj7eHkNhJJEP8AgShl/WsbUPid+z/8Z5mXXtD8JXl1J97+0dKhaYHv8zLuBr6sI3DnmsDxP8K/DPjSIpq3h/R9SVuv2izjkP5kVnUpwqR5ZpNeeoHxl8Uv+CTv7Jv7S+kTW914Z0yH7RyJdO1KWGSM9im5iqn6DH1r5H+L/wDwaIfDbxZcrc+BPi94u8O+W/mxxalY2+qKDzxujMJxz3zX6ia7+wl8M9XZnt9Dm0aVuQ+mXs1rg/7qtt/Sueuv2G73RWL+G/iP4q01h92O7Ed3GP0Vv1qcPh6WHjy0IqK7JWX3LQnkj2PxM+Jv/Bpt8efAusHVvBPjzwJr0iyfPElxc6XPcxnqMMjIM9/3mDmvjH4x/wDBCP8AbC/Z41G4nl+DPi/VbWLnz/Ds0OreYO/y2skj4+qj8K/p4f4VfHTwb/yD/EvhfxJEvRblZLWRv0cfrUL/ABd+Lvg7/kN/DS6vo1+9Npk8dwD7hVbd/wCO1u3fUFBI/ki8PWXjf9n74j6TY6/4M8Y+Db2S9WGS31WxmsI5FdgGV45FXKk5yOlfVeo+FtPt/D0mq2Vrf2TXoRVmCuwGN2MhQdoycDg8KK/om1L9srwre2xsfGHhnVtMjfh4tV0xxEfqJF2mud1j4X/svfHy2Ed94V8CzeYdxMVmlm5Oc5LQ7Tn3zXy3EGQ1MfKM6UlFpWd+vq1/kLk6H84M3xJ1O21RrfWtNe8hOFD4RGUcAjzItpwQcg4JGD6V1Z1q70rSruWxVmaSQrFb+YhcrjoWJZiQeB1PY1+3PxA/4IK/s2/FW+lvtAu/EPhi8lXCNpesLPHH6ELcLIeM9iK+d/iR/wAGs9zFqral4I+MjLOWJ+z6tpJSOVf7jSQyHv32dTnGa+eq8L4tfZXyej+Tt/mYexktLD/+DYu9kb4hfFqG4S7hujp2ntKk7qzZWWcfw8cZxnv74zX7DaJxqkn+1Av6M3+Nfnf/AMEb/wDgm78XP2EPi342uPiNN4P1TT9X0mC0sdT0W+lmknaOZm2yRyRRlcK3UZBOfWv0P0g41df9qBv0Zf8AGvtMlw9ShhI0qis1f82bU1aNjYooor1TQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAI7qyhvYyk0Mcyt1V1DA/nXFeK/2Zvh/wCNmZtS8H6DcSN1kFoscn/fSgH9a7migDw/VP2AfBLuZNHuvEvh2XsbLVJGUf8AAZNwrJl/ZG8d+Fzu8OfFG8ZV+7FqlkJfwLRsv8q+hqKAPnN9N+PvgzrZ+F/FEK/8+935Mjf8BkUD/wAeruvgN4+8VeL9curfxR4P1LwzcWUBKSylHgudzLwrKxG4Yzj0NepUUAFFFFABRRRQAUUUUAf/2Q=='
footer = '''<div>
<div align="center">
<img src="data:image/jpg;base64,'''+ image +'''
</div>
<div align="right">
<p align="right">
<b>'''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''</b>
</p>
<a target="_blank" rel="noopener noreferrer" href="https://www.udemy.com/user/leandro-luiz-silva-de-franca/"><img title="Udemy" src="data:image/png;base64,'''+dic_BW['udemy']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/GEOCAPT/"><img title="Facebook" src="data:image/png;base64,'''+dic_BW['face']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/channel/UCLrewDGciytcBG9r0OxTW2w"><img title="Youtube" src="data:image/png;base64,'''+dic_BW['youtube']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.researchgate.net/profile/Leandro_Franca2"><img title="ResearchGate" src="data:image/png;base64,'''+dic_BW['RG']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="https://github.com/LEOXINGU"><img title="GitHub" src="data:image/png;base64,'''+dic_BW['github']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="https://www.linkedin.com/in/leandro-fran%C3%A7a-93093714b/"><img title="Linkedin" src="data:image/png;base64,'''+dic_BW['linkedin']+'''"></a> <a target="_blank" rel="noopener noreferrer" href="http://lattes.cnpq.br/8559852745183879"><img title="Lattes" src="data:image/png;base64,'''+dic_BW['lattes']+'''"></a>
</div>
</div>'''
return self.tr(txt_en, txt_pt) + footer
FOLDER = 'FOLDER'
NONGEO = 'NONGEO'
OUTPUT = 'OUTPUT'
def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterFile(
self.FOLDER,
self.tr('Folder with JPEG photos', 'Pasta com fotos JPEG'),
behavior=QgsProcessingParameterFile.Folder,
defaultValue=None
)
)
self.addParameter(
QgsProcessingParameterFile(
self.NONGEO,
self.tr('Folder to copy the photos without geotag', 'Pasta para copiar as fotos sem geotag'),
behavior=QgsProcessingParameterFile.Folder,
defaultValue=None,
optional = True
)
)
self.addParameter(
QgsProcessingParameterFeatureSink(
self.OUTPUT,
self.tr('Geolocated photos', 'Fotos Geolocalizadas')
)
)
def processAlgorithm(self, parameters, context, feedback):
pasta = self.parameterAsFile(
parameters,
self.FOLDER,
context
)
if not pasta:
raise QgsProcessingException(self.invalidSourceError(parameters, self.FOLDER))
fotos_nao_geo = self.parameterAsFile(
parameters,
self.NONGEO,
context
)
lista = os.listdir(pasta)
tam = len(lista)
copy_ngeo = False
if os.path.isdir(fotos_nao_geo):
copy_ngeo = True
# Funcao para transformar os dados do EXIF em coordenadas em graus decimais
def coordenadas(exif):
try:
ref_lat = exif['GPSInfo'][1][0]
ref_lon = exif['GPSInfo'][3][0]
sinal_lat, sinal_lon = 0, 0
if ref_lat == 'S':
sinal_lat = -1
elif ref_lat == 'N':
sinal_lat = 1
if ref_lon == 'W':
sinal_lon = -1
elif ref_lon == 'E':
sinal_lon = 1
grausLat,grausLon = exif['GPSInfo'][2][0][0], exif['GPSInfo'][4][0][0]
minLat, minLon = exif['GPSInfo'][2][1][0], exif['GPSInfo'][4][1][0]
segLat = exif['GPSInfo'][2][2][0]/float(exif['GPSInfo'][2][2][1])
segLon = exif['GPSInfo'][4][2][0]/float(exif['GPSInfo'][4][2][1])
if sinal_lat!=0 and sinal_lon!=0:
lat = sinal_lat*(float(grausLat)+minLat/60.0+segLat/3600.0)
lon = sinal_lon*(float(grausLon)+minLon/60.0+segLon/3600.0)
return lat, lon
except:
return 0,0
# Funcao para pegar Azimute
def azimute(exif):
Az = exif['GPSInfo'][17]
if isinstance(Az, tuple):
Az = Az[0]/float(Az[1])
return Az
else:
return Az
# Funcao para gerar o padrao data-hora
def data_hora(texto):
data_hora = texto.replace(' ',':')
data_hora = data_hora.split(':')
ano = int(data_hora[0])
mes = int(data_hora[1])
dia = int(data_hora[2])
hora = int(data_hora[3])
minuto = int(data_hora[4])
segundo = int(data_hora[5])
data_hora = unicode(datetime.datetime(ano, mes, dia, hora, minuto, segundo))
return data_hora
# Criando Output
crs = QgsCoordinateReferenceSystem()
crs.createFromSrid(4326)
fields = QgsFields()
fields.append(QgsField(self.tr('name','nome'), QVariant.String))
fields.append(QgsField(self.tr('azimuth','azimute'), QVariant.Int))
fields.append(QgsField(self.tr('date_time','data_hora'), QVariant.String))
fields.append(QgsField(self.tr('path','caminho'), QVariant.String))
(sink, dest_id) = self.parameterAsSink(
parameters,
self.OUTPUT,
context,
fields,
QgsWkbTypes.Point,
crs
)
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
Percent = 100.0/tam if tam!=0 else 0
for index, arquivo in enumerate(lista):
if (arquivo).lower().endswith(('.jpg', '.jpeg')):
img = PIL.Image.open(os.path.join(pasta,arquivo))
if img._getexif():
exif = {
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()
if k in PIL.ExifTags.TAGS
}
else:
exif = {}
lon, lat = 0, 0
Az = None
date_time = None
if 'GPSInfo' in exif:
lat, lon = coordenadas(exif)
if 17 in exif['GPSInfo']:
Az = azimute(exif)
if 'DateTimeOriginal' in exif:
date_time = data_hora(exif['DateTimeOriginal'])
elif 'DateTime' in exif:
date_time = data_hora(exif['DateTime'])
if lon != 0:
feature = QgsFeature(fields)
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(lon, lat)))
feature.setAttributes([arquivo, Az, date_time, os.path.join(pasta, arquivo)])
sink.addFeature(feature, QgsFeatureSink.FastInsert)
else:
print()
feedback.pushInfo(self.tr('The file "{}" has no geotag!'.format(arquivo), 'A imagem "{}" não possui geotag!'.format(arquivo)))
if copy_ngeo:
shutil.copy2(os.path.join(pasta, arquivo), os.path.join(fotos_nao_geo, arquivo))
if feedback.isCanceled():
break
feedback.setProgress(int((index+1) * Percent))
feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
return {self.OUTPUT: dest_id}