documentation".
106 | #html_title = None
107 |
108 | # A shorter title for the navigation bar. Default is the same as html_title.
109 | #html_short_title = None
110 |
111 | # The name of an image file (relative to this directory) to place at the top
112 | # of the sidebar.
113 | #html_logo = None
114 |
115 | # The name of an image file (within the static path) to use as favicon of the
116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
117 | # pixels large.
118 | #html_favicon = None
119 |
120 | # Add any paths that contain custom static files (such as style sheets) here,
121 | # relative to this directory. They are copied after the builtin static files,
122 | # so a file named "default.css" will overwrite the builtin "default.css".
123 | html_static_path = ['_static']
124 |
125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
126 | # using the given strftime format.
127 | #html_last_updated_fmt = '%b %d, %Y'
128 |
129 | # If true, SmartyPants will be used to convert quotes and dashes to
130 | # typographically correct entities.
131 | #html_use_smartypants = True
132 |
133 | # Custom sidebar templates, maps document names to template names.
134 | #html_sidebars = {}
135 |
136 | # Additional templates that should be rendered to pages, maps page names to
137 | # template names.
138 | #html_additional_pages = {}
139 |
140 | # If false, no module index is generated.
141 | #html_domain_indices = True
142 |
143 | # If false, no index is generated.
144 | #html_use_index = True
145 |
146 | # If true, the index is split into individual pages for each letter.
147 | #html_split_index = False
148 |
149 | # If true, links to the reST sources are added to the pages.
150 | #html_show_sourcelink = True
151 |
152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
153 | #html_show_sphinx = True
154 |
155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
156 | #html_show_copyright = True
157 |
158 | # If true, an OpenSearch description file will be output, and all pages will
159 | # contain a tag referring to it. The value of this option must be the
160 | # base URL from which the finished HTML is served.
161 | #html_use_opensearch = ''
162 |
163 | # This is the file name suffix for HTML files (e.g. ".xhtml").
164 | #html_file_suffix = None
165 |
166 | # Output file base name for HTML help builder.
167 | htmlhelp_basename = 'TemplateClassdoc'
168 |
169 |
170 | # -- Options for LaTeX output --------------------------------------------------
171 |
172 | # The paper size ('letter' or 'a4').
173 | #latex_paper_size = 'letter'
174 |
175 | # The font size ('10pt', '11pt' or '12pt').
176 | #latex_font_size = '10pt'
177 |
178 | # Grouping the document tree into LaTeX files. List of tuples
179 | # (source start file, target name, title, author, documentclass [howto/manual]).
180 | latex_documents = [
181 | ('index', 'LFTools.tex', u'LFTools Documentation',
182 | u'Leandro Franca', 'manual'),
183 | ]
184 |
185 | # The name of an image file (relative to this directory) to place at the top of
186 | # the title page.
187 | #latex_logo = None
188 |
189 | # For "manual" documents, if this is true, then toplevel headings are parts,
190 | # not chapters.
191 | #latex_use_parts = False
192 |
193 | # If true, show page references after internal links.
194 | #latex_show_pagerefs = False
195 |
196 | # If true, show URL addresses after external links.
197 | #latex_show_urls = False
198 |
199 | # Additional stuff for the LaTeX preamble.
200 | #latex_preamble = ''
201 |
202 | # Documents to append as an appendix to all manuals.
203 | #latex_appendices = []
204 |
205 | # If false, no module index is generated.
206 | #latex_domain_indices = True
207 |
208 |
209 | # -- Options for manual page output --------------------------------------------
210 |
211 | # One entry per manual page. List of tuples
212 | # (source start file, name, description, authors, manual section).
213 | man_pages = [
214 | ('index', 'TemplateClass', u'LFTools Documentation',
215 | [u'Leandro Franca'], 1)
216 | ]
217 |
--------------------------------------------------------------------------------
/help/source/index.rst:
--------------------------------------------------------------------------------
1 | .. LFTools documentation master file, created by
2 | sphinx-quickstart on Sun Feb 12 17:11:03 2012.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to LFTools's documentation!
7 | ============================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 | Indices and tables
15 | ==================
16 |
17 | * :ref:`genindex`
18 | * :ref:`modindex`
19 | * :ref:`search`
20 |
21 |
--------------------------------------------------------------------------------
/images/cadastre.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/cadastre.png
--------------------------------------------------------------------------------
/images/cart_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/cart_frame.png
--------------------------------------------------------------------------------
/images/cart_frames.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/cart_frames.png
--------------------------------------------------------------------------------
/images/cart_frames2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/cart_frames2.png
--------------------------------------------------------------------------------
/images/contours.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/contours.png
--------------------------------------------------------------------------------
/images/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/document.png
--------------------------------------------------------------------------------
/images/drone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/drone.png
--------------------------------------------------------------------------------
/images/easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/easy.png
--------------------------------------------------------------------------------
/images/lftools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/lftools.png
--------------------------------------------------------------------------------
/images/lftools_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/lftools_logo.png
--------------------------------------------------------------------------------
/images/postgis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/postgis.png
--------------------------------------------------------------------------------
/images/raster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/raster.png
--------------------------------------------------------------------------------
/images/reamb_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/reamb_camera.png
--------------------------------------------------------------------------------
/images/satellite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/satellite.png
--------------------------------------------------------------------------------
/images/statistics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/statistics.png
--------------------------------------------------------------------------------
/images/tools/GEOONE.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
67 |
--------------------------------------------------------------------------------
/images/tools/UTM.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
108 |
--------------------------------------------------------------------------------
/images/total_station.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/total_station.png
--------------------------------------------------------------------------------
/images/tutorial/cadastre_adjoiners.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/cadastre_adjoiners.jpg
--------------------------------------------------------------------------------
/images/tutorial/cadastre_connectFeatures.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/cadastre_connectFeatures.jpg
--------------------------------------------------------------------------------
/images/tutorial/cadastre_frontlotline.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/cadastre_frontlotline.jpg
--------------------------------------------------------------------------------
/images/tutorial/cadastre_geonumbering.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/cadastre_geonumbering.jpg
--------------------------------------------------------------------------------
/images/tutorial/cadastre_polygon2point.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/cadastre_polygon2point.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_analytical_results.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_analytical_results.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_descriptive_memorial.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_descriptive_memorial.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_descriptive_table.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_descriptive_table.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_mark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_mark.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_pointsFromText.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_pointsFromText.jpg
--------------------------------------------------------------------------------
/images/tutorial/doc_validation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/doc_validation.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_copySelectedFiles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_copySelectedFiles.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_createGCP.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_createGCP.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_georref_adjust.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_georref_adjust.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_histogram.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_histogram.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_joinFolders.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_joinFolders.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_photosByBlocks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_photosByBlocks.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_point_cloud_adjust.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_point_cloud_adjust.jpg
--------------------------------------------------------------------------------
/images/tutorial/drone_verticalAdjustment.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/drone_verticalAdjustment.jpg
--------------------------------------------------------------------------------
/images/tutorial/easy_coord_layer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/easy_coord_layer.jpg
--------------------------------------------------------------------------------
/images/tutorial/easy_expr_ascii.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/easy_expr_ascii.jpg
--------------------------------------------------------------------------------
/images/tutorial/easy_get_attributes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/easy_get_attributes.jpg
--------------------------------------------------------------------------------
/images/tutorial/easy_measure_layer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/easy_measure_layer.jpg
--------------------------------------------------------------------------------
/images/tutorial/easy_selectByKey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/easy_selectByKey.jpg
--------------------------------------------------------------------------------
/images/tutorial/gnss_nmea.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/gnss_nmea.jpg
--------------------------------------------------------------------------------
/images/tutorial/gnss_pos2layer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/gnss_pos2layer.jpg
--------------------------------------------------------------------------------
/images/tutorial/gnss_ppk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/gnss_ppk.jpg
--------------------------------------------------------------------------------
/images/tutorial/gnss_rtk_correction.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/gnss_rtk_correction.jpg
--------------------------------------------------------------------------------
/images/tutorial/grid_coord_utm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/grid_coord_utm.jpg
--------------------------------------------------------------------------------
/images/tutorial/grid_ext_utm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/grid_ext_utm.jpg
--------------------------------------------------------------------------------
/images/tutorial/grid_inom_utm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/grid_inom_utm.jpg
--------------------------------------------------------------------------------
/images/tutorial/grid_lines_frames.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/grid_lines_frames.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_backup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_backup.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_clonedb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_clonedb.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_deletedb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_deletedb.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_encoding.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_encoding.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_importraster.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_importraster.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_renamedb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_renamedb.jpg
--------------------------------------------------------------------------------
/images/tutorial/post_restore.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/post_restore.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_bandArithmetic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_bandArithmetic.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_classification.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_classification.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_create_holes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_create_holes.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_define_null_px.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_define_null_px.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_extract_band.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_extract_band.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_fill_holes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_fill_holes.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_getpointvalue.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_getpointvalue.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_histogram.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_histogram.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_histogrammatching.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_histogrammatching.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_inventory.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_inventory.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_jpeg_compress.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_jpeg_compress.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_jpeg_tfw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_jpeg_tfw.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_loadByLocation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_loadByLocation.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_mosaic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_mosaic.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_overviews.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_overviews.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_remove_alpha.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_remove_alpha.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_rgb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_rgb.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_rgb2hsv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_rgb2hsv.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_split.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_split.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_thresholding.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_thresholding.jpg
--------------------------------------------------------------------------------
/images/tutorial/raster_zonalstatistics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/raster_zonalstatistics.jpg
--------------------------------------------------------------------------------
/images/tutorial/reamb_geotag.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/reamb_geotag.jpg
--------------------------------------------------------------------------------
/images/tutorial/reamb_kml_photos.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/reamb_kml_photos.jpg
--------------------------------------------------------------------------------
/images/tutorial/reamb_resize_photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/reamb_resize_photo.jpg
--------------------------------------------------------------------------------
/images/tutorial/relief_defineZ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/relief_defineZ.jpg
--------------------------------------------------------------------------------
/images/tutorial/relief_dem2txt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/relief_dem2txt.jpg
--------------------------------------------------------------------------------
/images/tutorial/relief_demfilter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/relief_demfilter.jpg
--------------------------------------------------------------------------------
/images/tutorial/relief_difference.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/relief_difference.jpg
--------------------------------------------------------------------------------
/images/tutorial/relief_spot_elevation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/relief_spot_elevation.jpg
--------------------------------------------------------------------------------
/images/tutorial/stat_central_tendency.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/stat_central_tendency.jpg
--------------------------------------------------------------------------------
/images/tutorial/stat_ellipses.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/stat_ellipses.jpg
--------------------------------------------------------------------------------
/images/tutorial/stat_nearestPoints.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/stat_nearestPoints.jpg
--------------------------------------------------------------------------------
/images/tutorial/stat_random_points.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/stat_random_points.jpg
--------------------------------------------------------------------------------
/images/tutorial/stat_standard_distance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/stat_standard_distance.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_3D_coord.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_3D_coord.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_LTP.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_LTP.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_azimuth_distance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_azimuth_distance.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_closed_polygonal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_closed_polygonal.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_helmert2D.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_helmert2D.jpg
--------------------------------------------------------------------------------
/images/tutorial/survey_traverse.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/survey_traverse.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_connectLayers.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_connectLayers.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_cross_sections.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_cross_sections.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_directional_merge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_directional_merge.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_extend_lines.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_extend_lines.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_line_sequence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_line_sequence.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_lines2polygon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_lines2polygon.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_orient_polygon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_orient_polygon.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_overlapping.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_overlapping.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_point2polygon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_point2polygon.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_polygon_angles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_polygon_angles.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_reprojectGPKG.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_reprojectGPKG.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_reverse_vertex_sequence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_reverse_vertex_sequence.jpg
--------------------------------------------------------------------------------
/images/tutorial/vect_sequence_points.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/tutorial/vect_sequence_points.jpg
--------------------------------------------------------------------------------
/images/vetor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/images/vetor.png
--------------------------------------------------------------------------------
/metadata.txt:
--------------------------------------------------------------------------------
1 | # This file contains metadata for your plugin.
2 |
3 | # This file should be included when you package your plugin.# Mandatory items:
4 |
5 | [general]
6 | name=LF Tools
7 | qgisMinimumVersion=3.10
8 | description=Tools for cartographic production, surveying, database management, digital image processing and spatial analysis.
9 | version=2.1.7
10 | author=Leandro França
11 | email=suporte@geoone.com.br
12 |
13 | about=The LFTools plugin is a true "Swiss Army knife" developed for QGIS, bringing together more than 126 scripts, expression functions, and toolbar tools. It caters to a wide range of needs, including cartographic production, surveying, drone operations, GNSS, image processing, database management, and spatial analysis. Since its launch in March 2021, it has become the most downloaded Brazilian-developed plugin on the platform, widely adopted by surveyors, cartographers, geographers, and other professionals working with geotechnologies. LFTools stands out for offering practical and automated solutions for creating topographic plans, descriptive reports, and other technical documents, combining automation efficiency with QGIS Atlas features and Python expressions.
14 |
15 | tracker=https://github.com/LEOXINGU/lftools/issues
16 | repository=https://github.com/LEOXINGU/lftools
17 | # End of mandatory metadata
18 |
19 | # Recommended items:
20 |
21 | hasProcessingProvider=yes
22 | # Uncomment the following line and add your changelog:
23 | # changelog=
24 | 2.1.7 - bug fix in "Calculate polygon angles" tool for minimum distance
25 | 2.1.6 - improvement in "Calculate polygon angles" tool to create angle interior and exterior lines
26 | 2.1.5 - improvement in "get attribute by location tool" for only selected features and other minor bug fix
27 | 2.1.4 - deedtable functions with also calculation in LTP and different precisions
28 | 2.1.3 - deedtext function with also calculation in LTP
29 | 2.1.2 - DMS option for Points From Text tool
30 | 2.1.1 - Bug fix in unloading lftools plugin
31 | 2.1.0 - New tools added: Set Z and select by key attribute
32 | 2.0.0 - Tool bar added
33 | 1.12.13 - Bug fix for photo with geotag tool
34 | 1.12.12 - Translation to Spanish
35 | 1.12.11 - Improvements to calculate Local Tangent Plane measurements
36 | 1.12.10 - Improvements in documentation tools with new coordinates types
37 | 1.12.9 - Anti-dumb condition for the Table to point layer tool
38 | 1.12.8 - Bug fix for QgsProcessingParameterNumber in QGIS 3.36
39 | 1.12.7 - Improvement of the Validate topology tool
40 | 1.12.6 - Bug fix for font-size geoneighbors function
41 | 1.12.5 - Bug fix in deedtext for repeated vertex codes
42 | 1.12.4 - Database tools updated to PostgreSQL 16
43 | 1.12.3 - Font type configuration for deedtext
44 | 1.12.2 - Improvements to the Deed description tool
45 | 1.12.1 - Bug fix in Nearest points and Adjoiner Lines tools
46 | 1.12.0 - New tools for Cartography, Vector and Easy
47 | 1.11.0 - New tools for Cadastre, Vector, Raster and Statistics
48 | 1.10.0 - New tools for GNSS, Vector and Statistics
49 | 1.9.4 - Tooltip and action for geotag photos tool
50 | 1.9.3 - Bug fix in NMEA to layer tool
51 | 1.9.2 - Topological validation in the Deed description tool
52 | 1.9.1 - Bug fix of Points from Text tool and polygon orientation improvement
53 | 1.9.0 - New tool for GNSS stop and go
54 | 1.8.0 - New function to calculate magnetic declination
55 | 1.7.2 - Bug fix of Calculate Polygon Angles tool
56 | 1.7.1 - Bug fix of Points from Text tool
57 | 1.7.0 - New tools for cadastre and others
58 | 1.6.2 - Bug fix of the Front Lot Lines tool
59 | 1.6.1 - Bug fix of Descriptive Memorial for PointZ error
60 | 1.6.0 - New tools for Cadastre, Raster and GNSS
61 | 1.5.0 - New tools for DTM and spot elevations
62 | 1.4.1 - Bug fix of the join folders extensions
63 | 1.4.0 - New tools for drones'image pre and pos processing
64 | 1.3.7 - Bug fix of the calculate polygon angles tool
65 | 1.3.6 - Adaptation to get the JPEG's geotag for the newest QGIS's version
66 | 1.3.5 - Documentation tools and filefilter Improvements
67 | 1.3.4 - CRS's checking and logo option for documentation tools
68 | 1.3.3 - exifread module replaced by PIL.TiffTags to work in linux
69 | 1.3.2 - Geotag for TIFF image included
70 | 1.3.1 - Bug fix of the supervised classification tool
71 | 1.3.0 - New tool for Raster Binary Thresholding
72 | 1.2.0 - New tool for saving Raster as jpeg
73 | 1.1.2 - Documentation tools adapted to english parameters
74 | 1.1.1 - Bug fix of the estimated 3D coordinates tool for Linux
75 | 1.1.0 - Expressions added
76 | 1.0.1 - Improvement in tools' translation and description
77 | 1.0 - Initial version
78 | # Tags are comma separated with spaces allowed
79 | tags=cartography, surveying, topography, raster, vector, postgis, cadastre, processing, reambulation, geotag, expressions, document, memorial, description, drones, GNSS, NMEA, RTKLIB, magnetic, ellipses, lftools, brazil, GeoOne
80 |
81 | homepage=https://github.com/LEOXINGU/lftools/wiki/LF-Tools-for-QGIS
82 | category=cartography
83 | icon=images/lftools_logo.png
84 | # experimental flag
85 | experimental=False
86 |
87 | # deprecated flag (applies to the whole plugin, not just a single version)
88 | deprecated=False
89 |
90 | # Since QGIS 3.8, a comma separated list of plugins to be installed
91 | # (or upgraded) can be specified.
92 | # Check the documentation for more information.
93 | # plugin_dependencies=
94 |
95 | Category of the plugin: Raster, Vector, Database or Web
96 | # category= Processing
97 |
98 | # If the plugin can run on QGIS Server.
99 | server=False
100 |
--------------------------------------------------------------------------------
/pb_tool.cfg:
--------------------------------------------------------------------------------
1 | #/***************************************************************************
2 | # LFTools
3 | #
4 | # Configuration file for plugin builder tool (pb_tool)
5 | # Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
6 | # -------------------
7 | # begin : 2021-02-18
8 | # copyright : (C) 2021 by Leandro Franca
9 | # email : geoleandro.franca@gmail.com
10 | # ***************************************************************************/
11 | #
12 | #/***************************************************************************
13 | # * *
14 | # * This program is free software; you can redistribute it and/or modify *
15 | # * it under the terms of the GNU General Public License as published by *
16 | # * the Free Software Foundation; either version 2 of the License, or *
17 | # * (at your option) any later version. *
18 | # * *
19 | # ***************************************************************************/
20 | #
21 | #
22 | # You can install pb_tool using:
23 | # pip install http://geoapt.net/files/pb_tool.zip
24 | #
25 | # Consider doing your development (and install of pb_tool) in a virtualenv.
26 | #
27 | # For details on setting up and using pb_tool, see:
28 | # http://g-sherman.github.io/plugin_build_tool/
29 | #
30 | # Issues and pull requests here:
31 | # https://github.com/g-sherman/plugin_build_tool:
32 | #
33 | # Sane defaults for your plugin generated by the Plugin Builder are
34 | # already set below.
35 | #
36 | # As you add Python source files and UI files to your plugin, add
37 | # them to the appropriate [files] section below.
38 |
39 | [plugin]
40 | # Name of the plugin. This is the name of the directory that will
41 | # be created in .qgis2/python/plugins
42 | name: lftools
43 |
44 | # Full path to where you want your plugin directory copied. If empty,
45 | # the QGIS default path will be used. Don't include the plugin name in
46 | # the path.
47 | plugin_path:
48 |
49 | [files]
50 | # Python files that should be deployed with the plugin
51 | python_files: __init__.py lftools.py
52 |
53 | # The main dialog file that is loaded (not compiled)
54 | main_dialog:
55 |
56 | # Other ui files for dialogs you create (these will be compiled)
57 | compiled_ui_files:
58 |
59 | # Resource file(s) that will be compiled
60 | resource_files:
61 |
62 | # Other files required for the plugin
63 | extras: metadata.txt
64 |
65 | # Other directories to be deployed with the plugin.
66 | # These must be subdirectories under the plugin directory
67 | extra_dirs:
68 |
69 | # ISO code(s) for any locales (translations), separated by spaces.
70 | # Corresponding .ts files must exist in the i18n directory
71 | locales:
72 |
73 | [help]
74 | # the built help directory that should be deployed with the plugin
75 | dir: help/build/html
76 | # the name of the directory to target in the deployed plugin
77 | target: help
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/plugin_upload.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding=utf-8
3 | """This script uploads a plugin package to the plugin repository.
4 | Authors: A. Pasotti, V. Picavet
5 | git sha : $TemplateVCSFormat
6 | """
7 |
8 | import sys
9 | import getpass
10 | import xmlrpc.client
11 | from optparse import OptionParser
12 |
13 | standard_library.install_aliases()
14 |
15 | # Configuration
16 | PROTOCOL = 'https'
17 | SERVER = 'plugins.qgis.org'
18 | PORT = '443'
19 | ENDPOINT = '/plugins/RPC2/'
20 | VERBOSE = False
21 |
22 |
23 | def main(parameters, arguments):
24 | """Main entry point.
25 |
26 | :param parameters: Command line parameters.
27 | :param arguments: Command line arguments.
28 | """
29 | address = "{protocol}://{username}:{password}@{server}:{port}{endpoint}".format(
30 | protocol=PROTOCOL,
31 | username=parameters.username,
32 | password=parameters.password,
33 | server=parameters.server,
34 | port=parameters.port,
35 | endpoint=ENDPOINT)
36 | print("Connecting to: %s" % hide_password(address))
37 |
38 | server = xmlrpc.client.ServerProxy(address, verbose=VERBOSE)
39 |
40 | try:
41 | with open(arguments[0], 'rb') as handle:
42 | plugin_id, version_id = server.plugin.upload(
43 | xmlrpc.client.Binary(handle.read()))
44 | print("Plugin ID: %s" % plugin_id)
45 | print("Version ID: %s" % version_id)
46 | except xmlrpc.client.ProtocolError as err:
47 | print("A protocol error occurred")
48 | print("URL: %s" % hide_password(err.url, 0))
49 | print("HTTP/HTTPS headers: %s" % err.headers)
50 | print("Error code: %d" % err.errcode)
51 | print("Error message: %s" % err.errmsg)
52 | except xmlrpc.client.Fault as err:
53 | print("A fault occurred")
54 | print("Fault code: %d" % err.faultCode)
55 | print("Fault string: %s" % err.faultString)
56 |
57 |
58 | def hide_password(url, start=6):
59 | """Returns the http url with password part replaced with '*'.
60 |
61 | :param url: URL to upload the plugin to.
62 | :type url: str
63 |
64 | :param start: Position of start of password.
65 | :type start: int
66 | """
67 | start_position = url.find(':', start) + 1
68 | end_position = url.find('@')
69 | return "%s%s%s" % (
70 | url[:start_position],
71 | '*' * (end_position - start_position),
72 | url[end_position:])
73 |
74 |
75 | if __name__ == "__main__":
76 | parser = OptionParser(usage="%prog [options] plugin.zip")
77 | parser.add_option(
78 | "-w", "--password", dest="password",
79 | help="Password for plugin site", metavar="******")
80 | parser.add_option(
81 | "-u", "--username", dest="username",
82 | help="Username of plugin site", metavar="user")
83 | parser.add_option(
84 | "-p", "--port", dest="port",
85 | help="Server port to connect to", metavar="80")
86 | parser.add_option(
87 | "-s", "--server", dest="server",
88 | help="Specify server name", metavar="plugins.qgis.org")
89 | options, args = parser.parse_args()
90 | if len(args) != 1:
91 | print("Please specify zip file.\n")
92 | parser.print_help()
93 | sys.exit(1)
94 | if not options.server:
95 | options.server = SERVER
96 | if not options.port:
97 | options.port = PORT
98 | if not options.username:
99 | # interactive mode
100 | username = getpass.getuser()
101 | print("Please enter user name [%s] :" % username, end=' ')
102 |
103 | res = input()
104 | if res != "":
105 | options.username = res
106 | else:
107 | options.username = username
108 | if not options.password:
109 | # interactive mode
110 | options.password = getpass.getpass()
111 | main(options, args)
112 |
--------------------------------------------------------------------------------
/processing_provider/Drone_copySelectedPhotos.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Drone_copySelectedPhotos.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-11-07'
16 | __copyright__ = '(C) 2021, Leandro França'
17 |
18 | from qgis.utils import iface
19 | from qgis.PyQt.QtCore import QCoreApplication
20 | from qgis.core import *
21 | from lftools.geocapt.imgs import Imgs
22 | from lftools.translations.translate import translate
23 | import os, shutil
24 | from qgis.PyQt.QtGui import QIcon
25 |
26 | class CopySelectedPhotos(QgsProcessingAlgorithm):
27 |
28 | LOC = QgsApplication.locale()[:2]
29 |
30 | def tr(self, *string):
31 | return translate(string, self.LOC)
32 |
33 | def createInstance(self):
34 | return CopySelectedPhotos()
35 |
36 | def name(self):
37 | return 'copyselectedphotos'
38 |
39 | def displayName(self):
40 | return self.tr('Copy selected files', 'Copiar arquivos selecionados')
41 |
42 | def group(self):
43 | return self.tr('Drones')
44 |
45 | def groupId(self):
46 | return 'drones'
47 |
48 | def tags(self):
49 | return self.tr('drones,fotografia,photography,blocks,copy,copiar,separate,separar,organize,organizar,filtrar,filter').split(',')
50 |
51 | def icon(self):
52 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/drone.png'))
53 |
54 | txt_en = 'This tool makes it possible to copy or move files to a new folder from a point layer with file paths.'
55 | txt_pt = 'Esta ferramenta possibilita copiar ou mover arquivos para uma nova pasta a partir de uma camada de pontos com os caminhos dos arquivos.'
56 | figure = 'images/tutorial/drone_copySelectedFiles.jpg'
57 |
58 | def shortHelpString(self):
59 | social_BW = Imgs().social_BW
60 | footer = '''
61 |
), self.figure) +''')
62 |
63 |
64 |
65 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
66 |
'''+ social_BW + '''
67 | '''
68 | return self.tr(self.txt_en, self.txt_pt) + footer
69 |
70 | POINTS = 'POINTS'
71 | FILEPATH = 'FILEPATH'
72 | OPTION = 'OPTION'
73 | FOLDER = 'FOLDER'
74 |
75 | def initAlgorithm(self, config=None):
76 | self.addParameter(
77 | QgsProcessingParameterVectorLayer(
78 | self.POINTS,
79 | self.tr('Points', 'Pontos'),
80 | [QgsProcessing.TypeVectorPoint]
81 | )
82 | )
83 |
84 | self.addParameter(
85 | QgsProcessingParameterField(
86 | self.FILEPATH,
87 | self.tr('Field with file path', 'Campo com o caminho do arquivo'),
88 | parentLayerParameterName=self.POINTS,
89 | type=QgsProcessingParameterField.String
90 | )
91 | )
92 |
93 | opt = [self.tr('Copy','Copiar'),
94 | self.tr('Move','Mover')
95 | ]
96 |
97 | self.addParameter(
98 | QgsProcessingParameterEnum(
99 | self.OPTION,
100 | self.tr('Option', 'Opção'),
101 | options = opt,
102 | defaultValue= 0
103 | )
104 | )
105 |
106 | self.addParameter(
107 | QgsProcessingParameterFile(
108 | self.FOLDER,
109 | self.tr('Destination folder for photos', 'Pasta de destino para fotografias'),
110 | behavior=QgsProcessingParameterFile.Folder,
111 | defaultValue=None
112 | )
113 | )
114 |
115 | def processAlgorithm(self, parameters, context, feedback):
116 |
117 | pontos = self.parameterAsVectorLayer(
118 | parameters,
119 | self.POINTS,
120 | context
121 | )
122 | if pontos is None:
123 | raise QgsProcessingException(self.invalidSourceError(parameters, self.POINTS))
124 |
125 | campo = self.parameterAsFields(
126 | parameters,
127 | self.FILEPATH,
128 | context
129 | )
130 | if campo is None:
131 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FILEPATH))
132 |
133 | columnIndex = pontos.fields().indexFromName(campo[0])
134 |
135 | opcao = self.parameterAsEnum(
136 | parameters,
137 | self.OPTION,
138 | context
139 | )
140 |
141 | destino = self.parameterAsFile(
142 | parameters,
143 | self.FOLDER,
144 | context
145 | )
146 | if not destino:
147 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FOLDER))
148 |
149 | # Verificar se tem arquivos selecionados
150 | if pontos.selectedFeatureCount() <1:
151 | raise QgsProcessingException(self.tr('At least one feature must be selected!', 'Pelo menos uma feição deve ser selecionada!'))
152 |
153 | # Copiando arquivos selecionados para a nova pasta
154 | total = 100.0 / pontos.selectedFeatureCount()
155 | cont = 1
156 | for pnt in pontos.getSelectedFeatures():
157 | origem = pnt[columnIndex]
158 | if os.path.exists(origem):
159 | nome = os.path.split(origem)[-1]
160 | if opcao == 0:
161 | shutil.copy2(origem, os.path.join(destino, nome))
162 | elif opcao == 1:
163 | shutil.move(origem, os.path.join(destino, nome))
164 | else:
165 | feedback.reportError('📢 ' + self.tr('Path {} does not exist!', 'Caminho {} não exite!').format(origem))
166 |
167 | if feedback.isCanceled():
168 | break
169 | feedback.setProgress(int((cont) * total))
170 | cont += 1
171 |
172 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
173 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
174 |
175 | return {}
176 |
--------------------------------------------------------------------------------
/processing_provider/Drone_createGCPfile.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Drone_createGCPfile.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-11-08'
16 | __copyright__ = '(C) 2021, Leandro França'
17 |
18 | from qgis.PyQt.QtCore import QCoreApplication
19 | from qgis.core import (QgsApplication,
20 | QgsProcessingParameterVectorLayer,
21 | QgsGeometry,
22 | QgsProcessing,
23 | QgsProcessingParameterField,
24 | QgsProcessingParameterString,
25 | QgsProcessingParameterEnum,
26 | QgsProcessingParameterNumber,
27 | QgsProcessingParameterBoolean,
28 | QgsProcessingParameterFileDestination,
29 | QgsFeatureSink,
30 | QgsProcessingException,
31 | QgsProcessingAlgorithm,
32 | QgsProcessingParameterFeatureSource,
33 | QgsProcessingParameterFeatureSink)
34 | from lftools.geocapt.imgs import Imgs
35 | from lftools.translations.translate import translate
36 | import os
37 | from qgis.PyQt.QtGui import QIcon
38 |
39 | class CreateGCPfile(QgsProcessingAlgorithm):
40 |
41 | LOC = QgsApplication.locale()[:2]
42 |
43 | def tr(self, *string):
44 | return translate(string, self.LOC)
45 |
46 | def createInstance(self):
47 | return CreateGCPfile()
48 |
49 | def name(self):
50 | return 'creategcpfile'
51 |
52 | def displayName(self):
53 | return self.tr('Generate GCP file for WebODM', 'Gerar arquivo de GCP para o WebODM')
54 |
55 | def group(self):
56 | return self.tr('Drones')
57 |
58 | def groupId(self):
59 | return 'drones'
60 |
61 | def tags(self):
62 | return self.tr('drones,fotografia,webodm,opendronemap,odm,photography,gcp,copy,points,control,ground,quality,homologous,controle,terreno').split(',')
63 |
64 | def icon(self):
65 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/drone.png'))
66 |
67 | txt_en = 'Generate text file with Ground Control Points (GCP) from a point layer to WebODM.'
68 | txt_pt = 'Gera arquivo texto com Pontos de Controle no Terreno (GCP) a partir de uma camada de pontos.'
69 | figure = 'images/tutorial/drone_createGCP.jpg'
70 |
71 | def shortHelpString(self):
72 | social_BW = Imgs().social_BW
73 | footer = '''
74 |
), self.figure) +''')
75 |
76 |
77 |
78 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
79 |
'''+ social_BW + '''
80 | '''
81 | return self.tr(self.txt_en, self.txt_pt) + footer
82 |
83 | POINTS = 'POINTS'
84 | NAME = 'NAME'
85 | FILE = 'FILE'
86 | DECIMAL = 'DECIMAL'
87 |
88 | def initAlgorithm(self, config=None):
89 | self.addParameter(
90 | QgsProcessingParameterVectorLayer(
91 | self.POINTS,
92 | self.tr('Point Layer', 'Camada de Pontos'),
93 | [QgsProcessing.TypeVectorPoint]
94 | )
95 | )
96 |
97 | self.addParameter(
98 | QgsProcessingParameterField(
99 | self.NAME,
100 | self.tr('GCP name', 'Nome do ponto de controle'),
101 | parentLayerParameterName=self.POINTS,
102 | type=QgsProcessingParameterField.String
103 | )
104 | )
105 |
106 | self.addParameter(
107 | QgsProcessingParameterNumber(
108 | self.DECIMAL,
109 | self.tr('Decimal places', 'Casas decimais'),
110 | type = QgsProcessingParameterNumber.Type.Integer,
111 | defaultValue = 3,
112 | minValue = 1
113 | )
114 | )
115 |
116 | self.addParameter(
117 | QgsProcessingParameterFileDestination(
118 | self.FILE,
119 | self.tr('Ground Control Points (GCP)', 'Pontos de Controle (GCP)'),
120 | fileFilter = 'Text (*.txt)'
121 | )
122 | )
123 |
124 | def processAlgorithm(self, parameters, context, feedback):
125 |
126 | pontos = self.parameterAsVectorLayer(
127 | parameters,
128 | self.POINTS,
129 | context
130 | )
131 | if pontos is None:
132 | raise QgsProcessingException(self.invalidSourceError(parameters, self.POINTS))
133 |
134 | campo = self.parameterAsFields(
135 | parameters,
136 | self.NAME,
137 | context
138 | )
139 | if campo is None:
140 | raise QgsProcessingException(self.invalidSourceError(parameters, self.NAME))
141 |
142 | columnIndex = pontos.fields().indexFromName(campo[0])
143 |
144 | decimal = self.parameterAsInt(
145 | parameters,
146 | self.DECIMAL,
147 | context
148 | )
149 | if decimal is None or decimal<1:
150 | raise QgsProcessingException(self.invalidSourceError(parameters, self.DECIMAL))
151 |
152 | format_num = '{:.Xf}'.replace('X', str(decimal))
153 |
154 | filepath = self.parameterAsFile(
155 | parameters,
156 | self.FILE,
157 | context
158 | )
159 | if not filepath:
160 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FILE))
161 |
162 | # Verificando se a camada possui coordenada Z
163 | for feat in pontos.getFeatures():
164 | geom = feat.geometry()
165 | break
166 | t = str(geom.constGet().z())
167 | try:
168 | t = str(geom.constGet().z())
169 | except:
170 | t = 'nan'
171 | if t == 'nan':
172 | eh3d = False
173 | feedback.pushInfo(self.tr('''Layer features do not have a Z coordinate.
174 | The Z coordinate will be set to 0 (zero)!''', '''Feições da camada não possuem coordenada Z.
175 | A coordena Z será definida com 0 (zero)!'''))
176 | else:
177 | eh3d = True
178 |
179 | # Criando arquivo de pontos de controle
180 | arq = open(filepath, 'w')
181 |
182 | # Escrevendo SRC como WKT
183 | arq.write(pontos.sourceCrs().toProj4() + '\n')
184 |
185 | for feat in pontos.getFeatures():
186 | nome = feat[columnIndex]
187 | geom = feat.geometry()
188 | if not eh3d:
189 | pnt = geom.asPoint()
190 | X, Y, Z = pnt.x(), pnt.y(), 0
191 | else:
192 | X, Y, Z = geom.constGet().x(), geom.constGet().y(), geom.constGet().z()
193 | arq.write(nome + '\t' + format_num.format(X) + '\t' + format_num.format(Y) + '\t' + format_num.format(Z) + '\n')
194 | if feedback.isCanceled():
195 | break
196 |
197 | arq.close()
198 |
199 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
200 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
201 |
202 | return {}
203 |
--------------------------------------------------------------------------------
/processing_provider/Drone_joinFolders.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Drone_joinFolders.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-11-08'
16 | __copyright__ = '(C) 2021, Leandro França'
17 |
18 | from qgis.PyQt.QtCore import QCoreApplication
19 | from qgis.core import (QgsApplication,
20 | QgsProcessingParameterVectorLayer,
21 | QgsGeometry,
22 | QgsProcessing,
23 | QgsProcessingParameterField,
24 | QgsProcessingParameterString,
25 | QgsProcessingParameterEnum,
26 | QgsProcessingParameterBoolean,
27 | QgsProcessingParameterFile,
28 | QgsFeatureSink,
29 | QgsProcessingException,
30 | QgsProcessingAlgorithm,
31 | QgsProcessingParameterFeatureSource,
32 | QgsProcessingParameterFeatureSink)
33 | from lftools.geocapt.imgs import Imgs
34 | from lftools.translations.translate import translate
35 | import os, shutil
36 | from qgis.PyQt.QtGui import QIcon
37 |
38 | class JoinFolders(QgsProcessingAlgorithm):
39 |
40 | LOC = QgsApplication.locale()[:2]
41 |
42 | def tr(self, *string):
43 | return translate(string, self.LOC)
44 |
45 | def createInstance(self):
46 | return JoinFolders()
47 |
48 | def name(self):
49 | return 'joinfolders'
50 |
51 | def displayName(self):
52 | return self.tr('Join folders', 'Juntar pastas')
53 |
54 | def group(self):
55 | return self.tr('Drones')
56 |
57 | def groupId(self):
58 | return 'drones'
59 |
60 | def tags(self):
61 | return self.tr('drones,fotografia,photography,blocks,join,juntar,organize,organizar').split(',')
62 |
63 | def icon(self):
64 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/drone.png'))
65 |
66 | txt_en = '''This tool has the objective of joining the files from several folders in another new folder, with the possibility of renaming the files.
67 | It is a very useful procedure for joining multiple drone images with repeated names into a single folder.'''
68 | txt_pt = '''Esta ferramenta tem o objetivo de juntar os arquivos de várias pastas em uma outra nova pasta, com a possibilidade de renomear os arquivos.
69 | É um procedimento muito útil para juntar várias imagens de drone com nomes repetidos em uma única pasta.'''
70 | figure = 'images/tutorial/drone_joinFolders.jpg'
71 |
72 | def shortHelpString(self):
73 | social_BW = Imgs().social_BW
74 | footer = '''
75 |
), self.figure) +''')
76 |
77 |
78 |
79 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
80 |
'''+ social_BW + '''
81 | '''
82 | return self.tr(self.txt_en, self.txt_pt) + footer
83 |
84 | FOLDERS = 'FOLDERS'
85 | RENAME = 'RENAME'
86 | PREFIX = 'PREFIX'
87 | OUT_FOLDER = 'OUT_FOLDER'
88 |
89 | def initAlgorithm(self, config=None):
90 | #inputs
91 | self.addParameter(
92 | QgsProcessingParameterFile(
93 | self.FOLDERS,
94 | self.tr('Folders with files', 'Pastas com arquivos'),
95 | behavior=QgsProcessingParameterFile.Folder,
96 | defaultValue=None
97 | )
98 | )
99 |
100 | self.addParameter(
101 | QgsProcessingParameterBoolean(
102 | self.RENAME,
103 | self.tr('Rename copied files', 'Renomear arquivos copiados'),
104 | defaultValue = True
105 | )
106 | )
107 |
108 | self.addParameter(
109 | QgsProcessingParameterString(
110 | self.PREFIX,
111 | self.tr('File name prefix', 'Prefixo do nome do arquivo'),
112 | defaultValue = self.tr('IMG_')
113 | )
114 | )
115 |
116 | #output
117 | self.addParameter(
118 | QgsProcessingParameterFile(
119 | self.OUT_FOLDER,
120 | self.tr('Destination folder', 'Pasta de destino'),
121 | behavior=QgsProcessingParameterFile.Folder,
122 | defaultValue=None
123 | )
124 | )
125 |
126 | def processAlgorithm(self, parameters, context, feedback):
127 |
128 | caminho_geral = self.parameterAsFile(
129 | parameters,
130 | self.FOLDERS,
131 | context
132 | )
133 | if not caminho_geral:
134 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FOLDERS))
135 |
136 | renomear = self.parameterAsBool(
137 | parameters,
138 | self.RENAME,
139 | context
140 | )
141 |
142 | prefixo = self.parameterAsString(
143 | parameters,
144 | self.PREFIX,
145 | context
146 | )
147 |
148 | destino = self.parameterAsFile(
149 | parameters,
150 | self.OUT_FOLDER,
151 | context
152 | )
153 | if not destino:
154 | raise QgsProcessingException(self.invalidSourceError(parameters, self.OUT_FOLDER))
155 |
156 | # contagem de arquivos
157 | feedback.pushInfo(self.tr('Checking files in the folders...', 'Checando arquivos nas pastas...'))
158 | lista = []
159 | for root, dirs, files in os.walk(caminho_geral, topdown=True):
160 | for name in files:
161 | if (name).lower().endswith(('.jpg', '.jpeg', '.tif', '.tiff')):
162 | lista += [os.path.join(root, name)]
163 |
164 | cont_files = len(lista)
165 | feedback.pushInfo(self.tr('Number of files to be copied: {}'.format(cont_files), 'Total de arquivos a serem copiados: {}'.format(cont_files)))
166 | total = 100.0 / cont_files if cont_files else 0
167 |
168 | # copiando os arquivos
169 | for cont, filepath in enumerate(lista):
170 | if os.path.join(caminho_geral, '') in os.path.join(destino, ''):
171 | raise QgsProcessingException(self.tr('Choose another output folder!', 'Escolha outra pasta de destino!'))
172 | else:
173 | head, arq = os.path.split(filepath)
174 | shutil.copy(filepath,
175 | os.path.join(destino, prefixo + "{:05d}.".format(cont+1) + arq.split('.')[-1]) if renomear else os.path.join(destino, arq))
176 | if feedback.isCanceled():
177 | break
178 | feedback.setProgress(int((cont) * total))
179 |
180 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
181 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
182 |
183 | return {}
184 |
--------------------------------------------------------------------------------
/processing_provider/Drone_overviewsJPEG.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Drone_overviewsJPEG.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-11-01'
16 | __copyright__ = '(C) 2021, Leandro França'
17 |
18 | from PyQt5.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsProcessing,
20 | QgsFeatureSink,
21 | QgsWkbTypes,
22 | QgsFields,
23 | QgsField,
24 | QgsFeature,
25 | QgsPointXY,
26 | QgsGeometry,
27 | QgsProcessingException,
28 | QgsProcessingAlgorithm,
29 | QgsProcessingParameterString,
30 | QgsProcessingParameterNumber,
31 | QgsProcessingParameterField,
32 | QgsProcessingParameterBoolean,
33 | QgsProcessingParameterCrs,
34 | QgsProcessingParameterEnum,
35 | QgsFeatureRequest,
36 | QgsExpression,
37 | QgsProcessingParameterFeatureSource,
38 | QgsProcessingParameterFeatureSink,
39 | QgsProcessingParameterFileDestination,
40 | QgsProcessingParameterMultipleLayers,
41 | QgsProcessingParameterRasterLayer,
42 | QgsProcessingParameterRasterDestination,
43 | QgsApplication,
44 | QgsProject,
45 | QgsRasterLayer,
46 | QgsCoordinateTransform,
47 | QgsCoordinateReferenceSystem)
48 |
49 | from osgeo import osr, gdal_array, gdal # https://gdal.org/programs/gdaladdo.html
50 | from lftools.geocapt.imgs import Imgs
51 | from lftools.translations.translate import translate
52 | from qgis.PyQt.QtGui import QIcon
53 | from qgis.utils import iface
54 | import os
55 |
56 | class OverviewsJPEG(QgsProcessingAlgorithm):
57 |
58 | LOC = QgsApplication.locale()[:2]
59 |
60 | def tr(self, *string):
61 | return translate(string, self.LOC)
62 |
63 | def createInstance(self):
64 | return OverviewsJPEG()
65 |
66 | def name(self):
67 | return 'overviewsjpeg'
68 |
69 | def displayName(self):
70 | return self.tr('Overviews with JPEG compression', 'Pirâmides com Compressão JPEG')
71 |
72 | def group(self):
73 | return self.tr('Drones')
74 |
75 | def groupId(self):
76 | return 'drones'
77 |
78 | def tags(self):
79 | return self.tr('drone,compression,reduce,size,JPEG,JPG,photometric,compact,image,overviews,piramides,faster,velocity').split(',')
80 |
81 | def icon(self):
82 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/drone.png'))
83 |
84 | txt_en = 'This tool aims to create an Overviews file (.ovr). This algorithm has the advantage of applying a JPEG compression at each level, greatly reducing the generated file size.'
85 | txt_pt = 'Esta ferramenta tem como objetivo criar um arquivo .ovr, correspondente às Overviews (ou pirâmides, em português). Este algoritmo tem a vantagem de aplicar uma compressão JPEG em cada nível, reduzindo bastante o tamanho do arquivo gerado.'
86 | figure = 'images/tutorial/raster_overviews.jpg'
87 |
88 | def shortHelpString(self):
89 | social_BW = Imgs().social_BW
90 | footer = '''
91 |
), self.figure) +''')
92 |
93 |
94 |
95 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
96 |
'''+ social_BW + '''
97 | '''
98 | return self.tr(self.txt_en, self.txt_pt) + footer
99 |
100 | def tags(self):
101 | return self.tr('jpeg,jpg,compressão,compression,compress,photo,comprimir,compact').split(',')
102 |
103 | RasterIN ='RasterIN'
104 | LEVELS = 'LEVELS'
105 | TYPE_GEN = 'TYPE_GEN'
106 | generalization = 'nearest,average,rms,bilinear,gauss,cubic,cubicspline,lanczos,average_magphase,mode'.split(',')
107 |
108 | def initAlgorithm(self, config=None):
109 | # INPUT
110 | self.addParameter(
111 | QgsProcessingParameterRasterLayer(
112 | self.RasterIN,
113 | self.tr('RGB Raster', 'Raster RGB'),
114 | [QgsProcessing.TypeRaster]
115 | )
116 | )
117 |
118 |
119 | self.addParameter(
120 | QgsProcessingParameterEnum(
121 | self.TYPE_GEN,
122 | self.tr('Resampling method', 'Método de reamostragem'),
123 | options = self.generalization,
124 | defaultValue= 1
125 | )
126 | )
127 |
128 | self.addParameter(
129 | QgsProcessingParameterString(
130 | self.LEVELS,
131 | self.tr('Factors', 'Fatores'),
132 | defaultValue = '2,4,8,16'
133 | )
134 | )
135 |
136 | def processAlgorithm(self, parameters, context, feedback):
137 |
138 | RasterIN = self.parameterAsRasterLayer(
139 | parameters,
140 | self.RasterIN,
141 | context
142 | )
143 | if RasterIN is None:
144 | raise QgsProcessingException(self.invalidSourceError(parameters, self.RasterIN))
145 | RasterIN = RasterIN.dataProvider().dataSourceUri()
146 |
147 | tipo = self.parameterAsEnum(
148 | parameters,
149 | self.TYPE_GEN,
150 | context
151 | )
152 | tipo = self.generalization[tipo]
153 |
154 |
155 | levels = self.parameterAsString(
156 | parameters,
157 | self.LEVELS,
158 | context
159 | )
160 | levels = eval ('[' + levels + ']')
161 |
162 | # Abrindo imagem e verificando número de bandas
163 | raster = gdal.OpenEx(RasterIN, gdal.OF_RASTER | gdal.OF_READONLY)
164 | nbands = raster.RasterCount
165 |
166 | gdal.SetConfigOption('COMPRESS_OVERVIEW', 'JPEG')
167 | # Definindo tipo de compressão JPEG para os OVR
168 | if nbands == 3:
169 | gdal.SetConfigOption('PHOTOMETRIC_OVERVIEW', 'YCBCR')
170 | elif nbands == 4:
171 | gdal.SetConfigOption('PHOTOMETRIC_OVERVIEW', 'RGB')
172 | else:
173 | raise QgsProcessingException(self.tr('The image must be RGB with 3 or 4 bands (alpha)!', 'A imagem deve ser RGB com 3 ou 4 bandas (alfa)!'))
174 |
175 | gdal.SetConfigOption('INTERLEAVE_OVERVIEW', 'PIXEL')
176 |
177 | # Criando as Overviews
178 | feedback.pushInfo(self.tr('Creating the Overviews...', 'Criando as Overviews...'))
179 | raster.BuildOverviews(tipo, levels)
180 |
181 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
182 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
183 |
184 | return {}
185 |
186 | def postProcessAlgorithm(self, context, feedback):
187 | canvas = iface.mapCanvas()
188 | canvas.refresh()
189 | return {}
190 |
--------------------------------------------------------------------------------
/processing_provider/Drone_photosByBlocks.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Drone_photosByBlocks.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-11-07'
16 | __copyright__ = '(C) 2021, Leandro França'
17 |
18 | from qgis.PyQt.QtCore import QCoreApplication
19 | from qgis.core import (QgsApplication,
20 | QgsProcessingParameterVectorLayer,
21 | QgsGeometry,
22 | QgsProcessing,
23 | QgsProcessingParameterField,
24 | QgsProcessingParameterString,
25 | QgsProcessingParameterEnum,
26 | QgsProcessingParameterBoolean,
27 | QgsProcessingParameterFile,
28 | QgsFeatureSink,
29 | QgsProcessingException,
30 | QgsProcessingAlgorithm,
31 | QgsProcessingParameterFeatureSource,
32 | QgsProcessingParameterFeatureSink)
33 | from lftools.geocapt.imgs import Imgs
34 | from lftools.translations.translate import translate
35 | import os, shutil
36 | from qgis.PyQt.QtGui import QIcon
37 |
38 | class PhotosByBlocks(QgsProcessingAlgorithm):
39 |
40 | LOC = QgsApplication.locale()[:2]
41 |
42 | def tr(self, *string):
43 | return translate(string, self.LOC)
44 |
45 | def createInstance(self):
46 | return PhotosByBlocks()
47 |
48 | def name(self):
49 | return 'photosbyblocks'
50 |
51 | def displayName(self):
52 | return self.tr('Photos by blocks', 'Fotos por blocos')
53 |
54 | def group(self):
55 | return self.tr('Drones')
56 |
57 | def groupId(self):
58 | return 'drones'
59 |
60 | def tags(self):
61 | return self.tr('drones,fotografia,photography,blocks,separate,separar,organize,organizar').split(',')
62 |
63 | def icon(self):
64 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/drone.png'))
65 |
66 | txt_en = 'This tool separates drone photographs into new folders to be processed by blocks, from a layer of polygons (blocks) and from layers of geotagged photographs.'
67 | txt_pt = 'Esta ferramenta separa fotografias de drones em novas pastas para serem processadas por blocos, a partir de uma camada de polígonos (blocos) e da camadas de fotografias com geotag.'
68 | figure = 'images/tutorial/drone_photosByBlocks.jpg'
69 |
70 | def shortHelpString(self):
71 | social_BW = Imgs().social_BW
72 | footer = '''
73 |
), self.figure) +''')
74 |
75 |
76 |
77 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
78 |
'''+ social_BW + '''
79 | '''
80 | return self.tr(self.txt_en, self.txt_pt) + footer
81 |
82 | POINTS = 'POINTS'
83 | FILEPATH = 'FILEPATH'
84 | BLOCKS = 'BLOCKS'
85 | PREFIX = 'PREFIX'
86 | FOLDER = 'FOLDER'
87 |
88 | def initAlgorithm(self, config=None):
89 | self.addParameter(
90 | QgsProcessingParameterVectorLayer(
91 | self.POINTS,
92 | self.tr('Points', 'Pontos'),
93 | [QgsProcessing.TypeVectorPoint]
94 | )
95 | )
96 |
97 | self.addParameter(
98 | QgsProcessingParameterField(
99 | self.FILEPATH,
100 | self.tr('Field with file path', 'Campo com o caminho do arquivo'),
101 | parentLayerParameterName=self.POINTS,
102 | type=QgsProcessingParameterField.String
103 | )
104 | )
105 |
106 | self.addParameter(
107 | QgsProcessingParameterVectorLayer(
108 | self.BLOCKS,
109 | self.tr('Blocks', 'Blocos'),
110 | [QgsProcessing.TypeVectorPolygon]
111 | )
112 | )
113 |
114 | self.addParameter(
115 | QgsProcessingParameterString(
116 | self.PREFIX,
117 | self.tr('Folder name prefix', 'Prefixo do nome da pasta'),
118 | defaultValue = self.tr('block_', 'bloco_')
119 | )
120 | )
121 |
122 | self.addParameter(
123 | QgsProcessingParameterFile(
124 | self.FOLDER,
125 | self.tr('Folder with raster files', 'Pasta com arquivos raster'),
126 | behavior=QgsProcessingParameterFile.Folder,
127 | defaultValue=None
128 | )
129 | )
130 |
131 | def processAlgorithm(self, parameters, context, feedback):
132 |
133 | pontos = self.parameterAsVectorLayer(
134 | parameters,
135 | self.POINTS,
136 | context
137 | )
138 | if pontos is None:
139 | raise QgsProcessingException(self.invalidSourceError(parameters, self.POINTS))
140 |
141 | poligono = self.parameterAsVectorLayer(
142 | parameters,
143 | self.BLOCKS,
144 | context
145 | )
146 | if poligono is None:
147 | raise QgsProcessingException(self.invalidSourceError(parameters, self.BLOCKS))
148 |
149 | campo = self.parameterAsFields(
150 | parameters,
151 | self.FILEPATH,
152 | context
153 | )
154 | if campo is None:
155 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FILEPATH))
156 |
157 | columnIndex = pontos.fields().indexFromName(campo[0])
158 |
159 | prefixo = self.parameterAsString(
160 | parameters,
161 | self.PREFIX,
162 | context
163 | )
164 |
165 | pasta = self.parameterAsFile(
166 | parameters,
167 | self.FOLDER,
168 | context
169 | )
170 | if not pasta:
171 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FOLDER))
172 |
173 | # As duas camadas devem ter o mesmo SRC
174 | if poligono.crs() != pontos.crs():
175 | raise QgsProcessingException(self.tr('Both layers must have the same CRS!', 'As duas camadas devem ter o mesmo SRC!'))
176 |
177 | # Copiando arquivos para as novas pastas
178 | total = 100.0 / (poligono.featureCount()*pontos.featureCount())
179 | block_count, cont = 1, 1
180 | for pol in poligono.getFeatures():
181 | geom_pol = pol.geometry()
182 | destino = os.path.join(pasta, prefixo + str(block_count))
183 | os.mkdir(destino)
184 | for pnt in pontos.getFeatures():
185 | geom_pnt = pnt.geometry()
186 | if geom_pnt.intersects(geom_pol):
187 | origem = pnt[columnIndex]
188 | nome = os.path.split(origem)[-1]
189 | shutil.copy2(origem, os.path.join(destino, nome))
190 | if feedback.isCanceled():
191 | break
192 | feedback.setProgress(int((cont) * total))
193 | cont += 1
194 | block_count += 1
195 |
196 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
197 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
198 |
199 | return {}
200 |
--------------------------------------------------------------------------------
/processing_provider/Easy_SelectByKeyAtt.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Easy_SelectByKeyAtt.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2024-11-10'
16 | __copyright__ = '(C) 2024, Leandro França'
17 |
18 | from PyQt5.QtCore import QCoreApplication, QVariant
19 | from qgis.core import *
20 | import numpy as np
21 | from pyproj.crs import CRS
22 | from lftools.geocapt.imgs import Imgs
23 | from lftools.geocapt.cartography import LayerIs3D
24 | from lftools.translations.translate import translate
25 | from lftools.geocapt.dip import Interpolar
26 | import os, processing
27 | from qgis.PyQt.QtGui import QIcon
28 |
29 | class SelectByKeyAtt(QgsProcessingAlgorithm):
30 |
31 | LOC = QgsApplication.locale()[:2]
32 |
33 | def tr(self, *string):
34 | return translate(string, self.LOC)
35 |
36 | def createInstance(self):
37 | return SelectByKeyAtt()
38 |
39 | def name(self):
40 | return 'SelectByKeyAtt'.lower()
41 |
42 | def displayName(self):
43 | return self.tr('Select by key attribute', 'Selecionar por atributo chave')
44 |
45 | def group(self):
46 | return self.tr('Easy', 'Mão na Roda')
47 |
48 | def groupId(self):
49 | return 'easy'
50 |
51 | def tags(self):
52 | return self.tr('selecionar,pimary,key,foreing,estrangeira,chave,selected,relação,relation').split(',')
53 |
54 | def icon(self):
55 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/easy.png'))
56 |
57 | txt_en = '''This tool allows you to select features that share the same foreign key attribute from multiple layers based on the primary key attribute of a selected feature from another layer.
58 | Note: Enter the foreign key field name if it is not the same as the primary key field name.'''
59 | txt_pt = '''Esta ferramenta permite selecionar feições que compartilham o mesmo atributo de chave estrangeira de diversas camadas com base no atributo de chave primária de uma feição selecionada de outra camada.
60 | Nota: Insira o nome do campo de chave estrangeira se não for igual ao nome do campo de chave primária.'''
61 | figure = 'images/tutorial/easy_selectByKey.jpg'
62 |
63 | def shortHelpString(self):
64 | social_BW = Imgs().social_BW
65 | footer = '''
66 |
), self.figure) +''')
67 |
68 |
69 |
70 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
71 |
'''+ social_BW + '''
72 | '''
73 | return self.tr(self.txt_en, self.txt_pt) + footer
74 |
75 | PRIMARY = 'PRIMARY'
76 | PRIMARY_FIELD = 'PRIMARY_FIELD'
77 | FOREIGNS ='FOREIGNS'
78 | FOREIGNS_FIELD = 'FOREIGNS_FIELD'
79 |
80 | def initAlgorithm(self, config=None):
81 |
82 | # INPUT
83 | self.addParameter(
84 | QgsProcessingParameterVectorLayer(
85 | self.PRIMARY,
86 | self.tr('Input Layer', 'Camada de entrada'),
87 | [QgsProcessing.TypeVectorAnyGeometry]
88 | )
89 | )
90 |
91 | self.addParameter(
92 | QgsProcessingParameterField(
93 | self.PRIMARY_FIELD,
94 | self.tr('Primary key', 'Chave primária'),
95 | parentLayerParameterName = self.PRIMARY
96 | )
97 | )
98 |
99 | self.addParameter(
100 | QgsProcessingParameterMultipleLayers(
101 | self.FOREIGNS,
102 | self.tr('Layers', 'Camadas'),
103 | layerType = QgsProcessing.TypeVectorAnyGeometry
104 | )
105 | )
106 |
107 | self.addParameter(
108 | QgsProcessingParameterString(
109 | self.FOREIGNS_FIELD,
110 | self.tr('Foreign key', 'Chave estrangeira'),
111 | optional = True
112 | )
113 | )
114 |
115 |
116 | def processAlgorithm(self, parameters, context, feedback):
117 |
118 | camada = self.parameterAsVectorLayer(
119 | parameters,
120 | self.PRIMARY,
121 | context
122 | )
123 | if camada is None:
124 | raise QgsProcessingException(self.invalidSourceError(parameters, self.PRIMARY))
125 |
126 | campo = self.parameterAsFields(
127 | parameters,
128 | self.PRIMARY_FIELD,
129 | context
130 | )
131 | if campo is None:
132 | raise QgsProcessingException(self.invalidSourceError(parameters, self.PRIMARY_FIELD))
133 |
134 | # Verificar se existe apenas uma feição selecionada
135 | if camada.selectedFeatureCount() != 1:
136 | raise QgsProcessingException(self.tr('At least one feature must be selected!', 'Pelo menos uma feição deve ser selecionada!'))
137 |
138 | campo_indice_pk = camada.fields().indexFromName(campo[0])
139 | campo_nome_pk = campo[0]
140 |
141 | layers = self.parameterAsLayerList(
142 | parameters,
143 | self.FOREIGNS,
144 | context
145 | )
146 |
147 | campo_nome_fk = self.parameterAsString(
148 | parameters,
149 | self.FOREIGNS_FIELD,
150 | context
151 | )
152 |
153 | if campo_nome_fk is None or campo_nome_fk == '':
154 | campo_nome_fk = campo_nome_pk
155 |
156 | # Obtendo o atributo chave
157 | for feat in camada.getSelectedFeatures():
158 | att = feat[campo_nome_pk]
159 |
160 | # Expressão para seleção
161 | expressao = QgsExpression('"{}" = \'{}\''.format(campo_nome_fk, att))
162 |
163 | for layer in layers:
164 | if campo_nome_fk in [field.name() for field in layer.fields()]:
165 | ids_selecionados = []
166 | for feat in layer.getFeatures(QgsFeatureRequest(expressao)):
167 | ids_selecionados.append(feat.id())
168 | layer.selectByIds(ids_selecionados)
169 | else:
170 | feedback.pushInfo(self.tr('Layer {} has no key field!', 'A camada {} não possui campo chave!').format(layer.name()))
171 |
172 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
173 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
174 |
175 | return {}
176 |
--------------------------------------------------------------------------------
/processing_provider/Post_ChangeEnconding.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Post_ChangeEnconding.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-03-10'
16 | __copyright__ = '(C) 2020, Leandro França'
17 |
18 | from PyQt5.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsProcessing,
20 | QgsProcessingException,
21 | QgsProcessingAlgorithm,
22 | QgsProcessingParameterString,
23 | QgsProcessingParameterBoolean,
24 | QgsProcessingParameterEnum,
25 | QgsProcessingParameterRasterLayer,
26 | QgsProcessingParameterFile,
27 | QgsProcessingParameterFileDestination,
28 | QgsApplication,
29 | QgsRasterLayer,
30 | QgsCoordinateReferenceSystem)
31 |
32 | from lftools.geocapt.imgs import Imgs
33 | from lftools.translations.translate import translate
34 | import os
35 | from qgis.PyQt.QtGui import QIcon
36 |
37 | class ChangeEnconding(QgsProcessingAlgorithm):
38 |
39 | LOC = QgsApplication.locale()[:2]
40 |
41 | def tr(self, *string):
42 | return translate(string, self.LOC)
43 |
44 | def createInstance(self):
45 | return ChangeEnconding()
46 |
47 | def name(self):
48 | return 'changeencoding'
49 |
50 | def displayName(self):
51 | return self.tr('Change SQL encoding', 'Trocar codificação de SQL')
52 |
53 | def group(self):
54 | return self.tr('PostGIS')
55 |
56 | def groupId(self):
57 | return 'postgis'
58 |
59 | def tags(self):
60 | return self.tr('postgis,postgresql,database,BD,DB,restore,backup,manager,import,encoding,sql,change').split(',')
61 |
62 | def icon(self):
63 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/postgis.png'))
64 |
65 | figure = 'images/tutorial/post_encoding.jpg'
66 | txt_en = '''This tool changes the encoding type of a .sql file. A new file will be created with the user-defined encoding.
67 | In some cases, this is a possible solution to transfer data between different operating systems, for example from Windows to Linux, and vice versa.'''
68 | txt_pt = '''Esta ferramenta realiza a troca do tipo de codificação de um arquivo .sql. Um novo arquivo será criado com a codificação definida pelo usuário.
69 | Em alguns casos, esse processo é uma possível solução para transferir dados entre diferentes sistemas operacionais, por exemplo de Window para Linux, e vice-versa.'''
70 |
71 | def shortHelpString(self):
72 | social_BW = Imgs().social_BW
73 | footer = '''
74 |
), self.figure) +''')
75 |
76 |
77 |
78 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
79 |
'''+ social_BW + '''
80 | '''
81 | return self.tr(self.txt_en, self.txt_pt) + footer
82 |
83 |
84 | FILE ='FILE'
85 | ORIGINAL = 'ORIGINAL'
86 | CHANGED = 'CHANGED'
87 |
88 | def initAlgorithm(self, config=None):
89 | # INPUT
90 | self.addParameter(
91 | QgsProcessingParameterFile(
92 | self.FILE,
93 | self.tr('SQL File', 'Arquivo SQL'),
94 | extension = 'sql'
95 | )
96 | )
97 |
98 | self.addParameter(
99 | QgsProcessingParameterString(
100 | self.ORIGINAL,
101 | self.tr('Original encoding', 'Codificação original'),
102 | defaultValue = 'Portuguese_Brazil.1252'
103 | )
104 | )
105 |
106 | self.addParameter(
107 | QgsProcessingParameterString(
108 | self.CHANGED,
109 | self.tr('New encoding', 'Nova codificação'),
110 | defaultValue = 'pt_BR.UTF-8'
111 | )
112 | )
113 |
114 |
115 | def processAlgorithm(self, parameters, context, feedback):
116 |
117 | file_path = self.parameterAsFile(
118 | parameters,
119 | self.FILE,
120 | context
121 | )
122 | if not file_path:
123 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FILE))
124 |
125 | original = self.parameterAsString(
126 | parameters,
127 | self.ORIGINAL,
128 | context
129 | )
130 |
131 | changed = self.parameterAsString(
132 | parameters,
133 | self.CHANGED,
134 | context
135 | )
136 |
137 | arq = open(file_path, 'r')
138 | data = arq.read()
139 | arq.close()
140 | data = data.replace(original, changed)
141 | path, file = os.path.split(file_path)
142 | new_file = file[:-3] + changed + '.sql'
143 | arq = open(os.path.join(path, new_file), 'w')
144 | arq.write(data)
145 | arq.close()
146 |
147 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
148 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
149 |
150 | return {}
151 |
--------------------------------------------------------------------------------
/processing_provider/Post_Restore.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Post_Restore.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2021-03-09'
16 | __copyright__ = '(C) 2020, Leandro França'
17 |
18 | from PyQt5.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsProcessing,
20 | QgsProcessingException,
21 | QgsProcessingAlgorithm,
22 | QgsProcessingParameterString,
23 | QgsProcessingParameterBoolean,
24 | QgsProcessingParameterEnum,
25 | QgsProcessingParameterRasterLayer,
26 | QgsProcessingParameterFile,
27 | QgsProcessingParameterFileDestination,
28 | QgsApplication,
29 | QgsRasterLayer,
30 | QgsCoordinateReferenceSystem)
31 |
32 | from lftools.geocapt.imgs import Imgs
33 | from lftools.translations.translate import translate
34 | import os
35 | from qgis.PyQt.QtGui import QIcon
36 |
37 | class Restore(QgsProcessingAlgorithm):
38 |
39 | LOC = QgsApplication.locale()[:2]
40 |
41 | def tr(self, *string):
42 | return translate(string, self.LOC)
43 |
44 | def createInstance(self):
45 | return Restore()
46 |
47 | def name(self):
48 | return 'restore'
49 |
50 | def displayName(self):
51 | return self.tr('Restore database', 'Restaurar BD')
52 |
53 | def group(self):
54 | return self.tr('PostGIS')
55 |
56 | def groupId(self):
57 | return 'postgis'
58 |
59 | def tags(self):
60 | return self.tr('postgis,postgresql,database,BD,DB,restore,backup,manager,export').split(',')
61 |
62 | def icon(self):
63 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/postgis.png'))
64 |
65 | txt_en = 'This tool allows you to restore a database content by importing all the backup information in a ".sql" file into a PostgreSQL server.'
66 | txt_pt = 'Esta ferramenta permite restaurar, ou seja, importar um banco de dados para um servidor PostgreSQL, a partir de um arquivo de backup no formato ".sql".'
67 | figure = 'images/tutorial/post_restore.jpg'
68 |
69 | def shortHelpString(self):
70 | social_BW = Imgs().social_BW
71 | footer = '''
72 |
), self.figure) +''')
73 |
74 |
75 |
76 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
77 |
'''+ social_BW + '''
78 | '''
79 | return self.tr(self.txt_en, self.txt_pt) + footer
80 |
81 |
82 | FILE ='FILE'
83 | HOST = 'HOST'
84 | VERSION = 'VERSION'
85 | USER = 'USER'
86 | PORT = 'PORT'
87 | versions = ['9.5', '9.6', '10', '11', '12', '13', '14', '15', '16', '17']
88 |
89 | def initAlgorithm(self, config=None):
90 | # INPUT
91 | self.addParameter(
92 | QgsProcessingParameterFile(
93 | self.FILE,
94 | self.tr('SQL File', 'Arquivo SQL'),
95 | extension = 'sql'
96 | )
97 | )
98 |
99 | self.addParameter(
100 | QgsProcessingParameterString(
101 | self.HOST,
102 | self.tr('Host', 'Host'),
103 | defaultValue = 'localhost'
104 | )
105 | )
106 |
107 | self.addParameter(
108 | QgsProcessingParameterString(
109 | self.PORT,
110 | self.tr('Port', 'Porta'),
111 | defaultValue = '5432'
112 | )
113 | )
114 |
115 | self.addParameter(
116 | QgsProcessingParameterString(
117 | self.USER,
118 | self.tr('User', 'Usuário'),
119 | defaultValue = 'postgres'
120 | )
121 | )
122 |
123 | self.addParameter(
124 | QgsProcessingParameterEnum(
125 | self.VERSION,
126 | self.tr('PostgreSQL version', 'Versão do PostgreSQL'),
127 | options = self.versions,
128 | defaultValue = 8
129 | )
130 | )
131 |
132 | def processAlgorithm(self, parameters, context, feedback):
133 |
134 | file_path = self.parameterAsFile(
135 | parameters,
136 | self.FILE,
137 | context
138 | )
139 | if not file_path:
140 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FILE))
141 |
142 | host = self.parameterAsString(
143 | parameters,
144 | self.HOST,
145 | context
146 | )
147 |
148 | version = self.parameterAsEnum(
149 | parameters,
150 | self.VERSION,
151 | context
152 | )
153 | version = self.versions[version]
154 |
155 | user = self.parameterAsString(
156 | parameters,
157 | self.USER,
158 | context
159 | )
160 |
161 | port = self.parameterAsString(
162 | parameters,
163 | self.PORT,
164 | context
165 | )
166 |
167 | # Procurando arquivo psql
168 | win64 = 'C:/Program Files (x86)/PostgreSQL/'+version+'/bin'
169 | win64d = 'D:/Program Files (x86)/PostgreSQL/'+version+'/bin'
170 | win32 = 'C:/Program Files/PostgreSQL/'+version+'/bin'
171 | win32d = 'D:/Program Files/PostgreSQL/'+version+'/bin'
172 | mac = '/Library/PostgreSQL/'+version+'/bin/'
173 | linux = '/usr/lib/postgresql/'+version+'/bin/'
174 | if os.path.isdir(win64):
175 | os.chdir(win64)
176 | elif os.path.isdir(win64d):
177 | os.chdir(win64d)
178 | elif os.path.isdir(win32):
179 | os.chdir(win32)
180 | elif os.path.isdir(win32d):
181 | os.chdir(win32d)
182 | elif os.path.isdir(mac):
183 | os.chdir(mac)
184 | elif os.path.isdir(linux):
185 | os.chdir(linux)
186 | else:
187 | raise QgsProcessingException(self.tr('Make sure your PostgreSQL version is correct!', 'Verifique se a versão do seu PostgreSQL está correta!'))
188 |
189 | # Realizando o Restore
190 | comando ='psql -d postgres -U '+user+' -h '+host+' -p '+port+' -f '+ '"' + file_path + '"'
191 | feedback.pushInfo('\n' + self.tr('Command: ','Comando: ') + comando)
192 | feedback.pushInfo('\n' + self.tr('Starting DB Restore process...', 'Iniciando processo de Restauracao do BD...'))
193 | result = os.system(comando)
194 |
195 | if result==0:
196 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
197 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
198 | else:
199 | feedback.pushInfo(self.tr('There was a problem while executing the command. Please check the input parameters.',
200 | 'Houve algum problema durante a execução do comando. Por favor, verifique os parâmetros de entrada.'))
201 |
202 | return {}
203 |
--------------------------------------------------------------------------------
/processing_provider/Rast_extractRasterBand.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Rast_extractRasterBand.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2020-12-15'
16 | __copyright__ = '(C) 2020, Leandro França'
17 |
18 | from PyQt5.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsProcessing,
20 | QgsFeatureSink,
21 | QgsWkbTypes,
22 | QgsFields,
23 | QgsField,
24 | QgsFeature,
25 | QgsPointXY,
26 | QgsGeometry,
27 | QgsProcessingException,
28 | QgsProcessingAlgorithm,
29 | QgsProcessingParameterString,
30 | QgsProcessingParameterField,
31 | QgsProcessingParameterBoolean,
32 | QgsProcessingParameterCrs,
33 | QgsProcessingParameterEnum,
34 | QgsFeatureRequest,
35 | QgsExpression,
36 | QgsProcessingParameterFeatureSource,
37 | QgsProcessingParameterFeatureSink,
38 | QgsProcessingParameterFileDestination,
39 | QgsProcessingParameterRasterLayer,
40 | QgsProcessingParameterBand,
41 | QgsProcessingParameterRasterDestination,
42 | QgsApplication,
43 | QgsProject,
44 | QgsRasterLayer,
45 | QgsCoordinateTransform,
46 | QgsCoordinateReferenceSystem)
47 |
48 | from osgeo import osr, gdal_array, gdal #https://gdal.org/python/
49 | from lftools.geocapt.imgs import Imgs
50 | from lftools.translations.translate import translate
51 | import os
52 | from qgis.PyQt.QtGui import QIcon
53 |
54 | class ExtractRasterBand(QgsProcessingAlgorithm):
55 |
56 | LOC = QgsApplication.locale()[:2]
57 |
58 | def tr(self, *string):
59 | return translate(string, self.LOC)
60 |
61 | def createInstance(self):
62 | return ExtractRasterBand()
63 |
64 | def name(self):
65 | return 'extractrasterband'
66 |
67 | def displayName(self):
68 | return self.tr('Extract raster band', 'Extrair banda de raster')
69 |
70 | def group(self):
71 | return self.tr('Raster')
72 |
73 | def groupId(self):
74 | return 'raster'
75 |
76 | def tags(self):
77 | return self.tr('bands,raster,extract,color,spectral,frequency,RGB,composite,channel').split(',')
78 |
79 | def icon(self):
80 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/raster.png'))
81 |
82 | txt_en = 'Extracts a difined band of a raster (for multiband rasters).'
83 | txt_pt = 'Extrai uma das bandas de um arquivo raster (para imagens multi-bandas/multi-canal).'
84 | figure = 'images/tutorial/raster_extract_band.jpg'
85 |
86 | def shortHelpString(self):
87 | social_BW = Imgs().social_BW
88 | footer = '''
89 |
), self.figure) +''')
90 |
91 |
92 |
93 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
94 |
'''+ social_BW + '''
95 | '''
96 | return self.tr(self.txt_en, self.txt_pt) + footer
97 |
98 | INPUT = 'INPUT'
99 | BAND = 'BAND'
100 | OUTPUT = 'OUTPUT'
101 | OPEN = 'OPEN'
102 |
103 | def initAlgorithm(self, config=None):
104 | # INPUT
105 | self.addParameter(
106 | QgsProcessingParameterRasterLayer(
107 | self.INPUT,
108 | self.tr('Multiband Input Raster', 'Raster multibandas'),
109 | [QgsProcessing.TypeRaster]
110 | )
111 | )
112 |
113 | self.addParameter(
114 | QgsProcessingParameterBand(
115 | self.BAND,
116 | self.tr('Band number', 'Número da banda'),
117 | parentLayerParameterName=self.INPUT,
118 | )
119 | )
120 |
121 | # OUTPUT
122 | self.addParameter(
123 | QgsProcessingParameterFileDestination(
124 | self.OUTPUT,
125 | self.tr('Selected band', 'Banda selecionada'),
126 | fileFilter = 'GeoTIFF (*.tif)'
127 | )
128 | )
129 |
130 | self.addParameter(
131 | QgsProcessingParameterBoolean(
132 | self.OPEN,
133 | self.tr('Load output raster', 'Carregar raster de saída'),
134 | defaultValue= True
135 | )
136 | )
137 |
138 | def processAlgorithm(self, parameters, context, feedback):
139 |
140 | entrada = self.parameterAsRasterLayer(
141 | parameters,
142 | self.INPUT,
143 | context
144 | )
145 | if entrada is None:
146 | raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
147 |
148 | n_banda = self.parameterAsInt(
149 | parameters,
150 | self.BAND,
151 | context
152 | )
153 | if n_banda is None:
154 | raise QgsProcessingException(self.invalidSourceError(parameters, self.BAND))
155 |
156 | saida = self.parameterAsFileOutput(
157 | parameters,
158 | self.OUTPUT,
159 | context
160 | )
161 |
162 | Carregar = self.parameterAsBool(
163 | parameters,
164 | self.OPEN,
165 | context
166 | )
167 |
168 | # Abrir banda
169 | feedback.pushInfo(self.tr('Reading the selected band...', 'Lendo a banda selecionada...'))
170 | image = gdal.Open(entrada.dataProvider().dataSourceUri())
171 | banda = image.GetRasterBand(n_banda).ReadAsArray()
172 | prj=image.GetProjection()
173 | geotransform = image.GetGeoTransform()
174 |
175 | # Criar objeto CRS
176 | CRS=osr.SpatialReference(wkt=prj)
177 |
178 | # Obter número de linhas e colunas
179 | cols = image.RasterXSize
180 | rows = image.RasterYSize
181 | image=None # fechar magem
182 |
183 | # Pegar tipo de dado do array
184 | GDT = gdal_array.NumericTypeCodeToGDALTypeCode(banda.dtype)
185 |
186 | # Criar imagem com uma única banda
187 | feedback.pushInfo(self.tr('Writing the selected band...', 'Escrevendo a banda selecionada...'))
188 | nova_imagem = gdal.GetDriverByName('GTiff').Create(saida, cols, rows, 1, GDT)
189 | nova_imagem.SetGeoTransform(geotransform)
190 | nova_imagem.SetProjection(CRS.ExportToWkt())
191 | nova_imagem.GetRasterBand(1).WriteArray(banda)
192 | nova_imagem.FlushCache() # Escrever no disco
193 | nova_imagem = None # Salvar e fechar
194 | CRS = None
195 |
196 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
197 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
198 | self.CAMINHO = saida
199 | self.CARREGAR = Carregar
200 | return {self.OUTPUT: saida}
201 |
202 | def postProcessAlgorithm(self, context, feedback):
203 | if self.CARREGAR:
204 | rlayer = QgsRasterLayer(self.CAMINHO, self.tr('Extracted band', 'Banda extraída'))
205 | QgsProject.instance().addMapLayer(rlayer)
206 | return {}
207 |
--------------------------------------------------------------------------------
/processing_provider/Vect_Overlapping.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Vect_Overlapping.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2023-05-14'
16 | __copyright__ = '(C) 2023, Leandro França'
17 |
18 | from qgis.PyQt.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsApplication,
20 | QgsGeometry,
21 | QgsWkbTypes,
22 | QgsFeature,
23 | QgsField,
24 | QgsFields,
25 | QgsProcessing,
26 | QgsSpatialIndex,
27 | QgsFeatureRequest,
28 | QgsProcessingParameterField,
29 | QgsProcessingParameterEnum,
30 | QgsProcessingParameterBoolean,
31 | QgsProcessingParameterNumber,
32 | QgsFeatureSink,
33 | QgsProcessingException,
34 | QgsProcessingAlgorithm,
35 | QgsProcessingParameterFeatureSource,
36 | QgsProcessingParameterFeatureSink)
37 | from lftools.geocapt.imgs import Imgs
38 | from lftools.translations.translate import translate
39 | from lftools.geocapt.cartography import OrientarPoligono
40 | import numpy as np
41 | import os
42 | from qgis.PyQt.QtGui import QIcon
43 |
44 | class Overlapping(QgsProcessingAlgorithm):
45 |
46 | LOC = QgsApplication.locale()[:2]
47 |
48 | def tr(self, *string):
49 | return translate(string, self.LOC)
50 |
51 | def createInstance(self):
52 | return Overlapping()
53 |
54 | def name(self):
55 | return 'overlapping'
56 |
57 | def displayName(self):
58 | return self.tr('Overlapping polygons', 'Sobreposição de polígonos')
59 |
60 | def group(self):
61 | return self.tr('Vector', 'Vetor')
62 |
63 | def groupId(self):
64 | return 'vector'
65 |
66 | def tags(self):
67 | return self.tr('cadastro,parcela,sequence,confrontante,vizinho,neighbours,sobreposição,overlap,cadastre,borderer,loteamento').split(',')
68 |
69 | def icon(self):
70 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/vetor.png'))
71 |
72 | txt_en = '''Identifies the overlap between features of a polygon type layer.'''
73 | txt_pt = '''Identifica a sobreposição entre feições de uma camada do tipo polígono.'''
74 | figure = 'images/tutorial/vect_overlapping.jpg'
75 |
76 | def shortHelpString(self):
77 | social_BW = Imgs().social_BW
78 | footer = '''
79 |
), self.figure) +''')
80 |
81 |
82 |
83 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
84 |
'''+ social_BW + '''
85 | '''
86 | return self.tr(self.txt_en, self.txt_pt) + footer
87 |
88 | INPUT = 'INPUT'
89 | OUTPUT = 'OUTPUT'
90 |
91 | def initAlgorithm(self, config = None):
92 | self.addParameter(
93 | QgsProcessingParameterFeatureSource(
94 | self.INPUT,
95 | self.tr('Polygon layer', 'Camada de polígonos'),
96 | [QgsProcessing.TypeVectorPolygon]
97 | )
98 | )
99 |
100 | # OUTPUT
101 | self.addParameter(
102 | QgsProcessingParameterFeatureSink(
103 | self.OUTPUT,
104 | self.tr('Overlapping', 'Sobreposição')
105 | )
106 | )
107 |
108 | def processAlgorithm(self, parameters, context, feedback):
109 |
110 | layer = self.parameterAsSource(
111 | parameters,
112 | self.INPUT,
113 | context
114 | )
115 | if layer is None:
116 | raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
117 |
118 |
119 | # Camada de Saída
120 | Fields = QgsFields()
121 | itens = {
122 | 'ID1' : QVariant.Int,
123 | 'ID2' : QVariant.Int,
124 | }
125 | for item in itens:
126 | Fields.append(QgsField(item, itens[item]))
127 | (sink, dest_id) = self.parameterAsSink(
128 | parameters,
129 | self.OUTPUT,
130 | context,
131 | Fields,
132 | QgsWkbTypes.Polygon,
133 | layer.sourceCrs()
134 | )
135 | if sink is None:
136 | raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
137 |
138 | # Validar:
139 | # não pode ser multipolígono
140 | for feat in layer.getFeatures():
141 | if feat.geometry().isMultipart():
142 | raise QgsProcessingException(self.tr('Feature id {} is multipart! Multipart features are not allowed!', 'Feição de id {} é multiparte! Feições multipartes não são permitidas!' ).format(feat.id()))
143 |
144 | feedback.pushInfo(self.tr('Creating spatial index...', 'Criando índice espacial...'))
145 |
146 | index = QgsSpatialIndex(layer.getFeatures())
147 |
148 | sobreposicoes = []
149 | feedback.pushInfo(self.tr('Identifying overlapping polygons...', 'Idenficando sobreposição entre polígonos...'))
150 | total = 100.0 / layer.featureCount() if layer.featureCount() else 0
151 |
152 | for current, feat1 in enumerate(layer.getFeatures()):
153 | ID1 = feat1.id()
154 | geom1 = feat1.geometry()
155 | linha1 = QgsGeometry.fromPolylineXY(geom1.asPolygon()[0])
156 | bbox1 = geom1.boundingBox()
157 | feat_ids = index.intersects(bbox1)
158 | for feat2 in layer.getFeatures(QgsFeatureRequest(feat_ids)):
159 | ID2 = feat2.id()
160 | if ID1 != ID2 and (ID2,ID1) not in sobreposicoes:
161 | geom2 = feat2.geometry()
162 | if geom1.intersects(geom2):
163 | inter = geom1.intersection(geom2)
164 | for item in inter.asGeometryCollection():
165 | if item.type() == 2: #polygon
166 | sobreposicoes += [(ID1, ID2)]
167 | if item.isMultipart():
168 | coords = item.asMultiPolygon()
169 | for coord in coords:
170 | feature = QgsFeature(Fields)
171 | feature.setGeometry(QgsGeometry.fromPolygonXY(coord))
172 | feature.setAttributes([ID1, ID2])
173 | sink.addFeature(feature, QgsFeatureSink.FastInsert)
174 | else:
175 | feature = QgsFeature(Fields)
176 | feature.setGeometry(item)
177 | feature.setAttributes([ID1, ID2])
178 | sink.addFeature(feature, QgsFeatureSink.FastInsert)
179 | if feedback.isCanceled():
180 | break
181 | feedback.setProgress(int((current+1) * total))
182 |
183 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
184 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
185 |
186 | return {self.OUTPUT: dest_id}
187 |
--------------------------------------------------------------------------------
/processing_provider/Vect_PointsToPolygon.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Vect_PointsToPolygon.py
5 | ***************************************************************************
6 | * *
7 | * This program is free software; you can redistribute it and/or modify *
8 | * it under the terms of the GNU General Public License as published by *
9 | * the Free Software Foundation; either version 2 of the License, or *
10 | * (at your option) any later version. *
11 | * *
12 | ***************************************************************************
13 | """
14 | __author__ = 'Leandro França'
15 | __date__ = '2023-01-21'
16 | __copyright__ = '(C) 2023, Leandro França'
17 |
18 | from qgis.PyQt.QtCore import QCoreApplication, QVariant
19 | from qgis.core import (QgsApplication,
20 | QgsProcessingParameterFeatureSource,
21 | QgsGeometry,
22 | QgsFeature,
23 | QgsProcessing,
24 | QgsProject,
25 | QgsFields,
26 | QgsField,
27 | QgsWkbTypes,
28 | QgsLineString,
29 | QgsPolygon,
30 | QgsPoint,
31 | QgsPointXY,
32 | QgsProcessingParameterField,
33 | QgsProcessingParameterEnum,
34 | QgsProcessingParameterBoolean,
35 | QgsProcessingParameterNumber,
36 | QgsFeatureSink,
37 | QgsProcessingException,
38 | QgsProcessingAlgorithm,
39 | QgsCoordinateTransform,
40 | QgsProcessingParameterFeatureSink)
41 | from lftools.geocapt.imgs import Imgs
42 | from lftools.translations.translate import translate
43 | import os
44 | from qgis.PyQt.QtGui import QIcon
45 |
46 | class PointsToPolygon(QgsProcessingAlgorithm):
47 |
48 | LOC = QgsApplication.locale()[:2]
49 |
50 | def tr(self, *string):
51 | return translate(string, self.LOC)
52 |
53 | def createInstance(self):
54 | return PointsToPolygon()
55 |
56 | def name(self):
57 | return 'pointstopolygon'
58 |
59 | def displayName(self):
60 | return self.tr('Points to polygon', 'Pontos para polígono')
61 |
62 | def group(self):
63 | return self.tr('Vector', 'Vetor')
64 |
65 | def groupId(self):
66 | return 'vector'
67 |
68 | def tags(self):
69 | return self.tr('sequence,points,pontos,order,ordenar,orientar,polygon,polígono').split(',')
70 |
71 | def icon(self):
72 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/vetor.png'))
73 |
74 | txt_en = 'This tool generates a polygon layer from a point layer and its filled order (sequence) attributes.'
75 | txt_pt = 'Esta ferramenta gera uma camada de polígono a partir de uma camada de pontos e seus atributos de ordem (sequência) preenchidos.'
76 | figure = 'images/tutorial/vect_point2polygon.jpg'
77 |
78 | def shortHelpString(self):
79 | social_BW = Imgs().social_BW
80 | footer = '''
81 |
), self.figure) +''')
82 |
83 |
84 |
85 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
86 |
'''+ social_BW + '''
87 | '''
88 | return self.tr(self.txt_en, self.txt_pt) + footer
89 |
90 | POINTS = 'POINTS'
91 | FIELD = 'FIELD'
92 | POLYGON = 'POLYGON'
93 |
94 | def initAlgorithm(self, config=None):
95 | self.addParameter(
96 | QgsProcessingParameterFeatureSource(
97 | self.POINTS,
98 | self.tr('Point layer', 'Camada de pontos'),
99 | [QgsProcessing.TypeVectorPoint]
100 | )
101 | )
102 |
103 | self.addParameter(
104 | QgsProcessingParameterField(
105 | self.FIELD,
106 | self.tr('Sequence Field', 'Campo de ordenação'),
107 | parentLayerParameterName=self.POINTS,
108 | type = QgsProcessingParameterField.Numeric
109 | )
110 | )
111 |
112 | self.addParameter(
113 | QgsProcessingParameterFeatureSink(
114 | self.POLYGON,
115 | self.tr('Polygon from points', 'Polígono a partir de pontos')
116 | )
117 | )
118 |
119 | def processAlgorithm(self, parameters, context, feedback):
120 |
121 | layer = self.parameterAsSource(
122 | parameters,
123 | self.POINTS,
124 | context
125 | )
126 | if layer is None:
127 | raise QgsProcessingException(self.invalidSourceError(parameters, self.POINTS))
128 |
129 |
130 | campo = self.parameterAsFields(
131 | parameters,
132 | self.FIELD,
133 | context
134 | )
135 | if campo is None:
136 | raise QgsProcessingException(self.invalidSourceError(parameters, self.FIELD))
137 |
138 | # OUTPUT
139 | Fields = QgsFields()
140 |
141 | itens = {
142 | 'id' : QVariant.Int,
143 | }
144 | for item in itens:
145 | Fields.append(QgsField(item, itens[item]))
146 |
147 | (sink, dest_id) = self.parameterAsSink(
148 | parameters,
149 | self.POLYGON,
150 | context,
151 | Fields,
152 | QgsWkbTypes.PolygonZ if layer.wkbType() != 1 else QgsWkbTypes.Polygon,
153 | layer.sourceCrs()
154 | )
155 | if sink is None:
156 | raise QgsProcessingException(self.invalidSinkError(parameters, self.ANGLES))
157 |
158 | # Validando atributos dos dados de entrada
159 | feedback.pushInfo(self.tr('Validating layer attributes...', 'Validando atributos das camadas...' ))
160 | # ponto_limite
161 | ordem_list = list(range(1,layer.featureCount()+1))
162 | ordem_comp = []
163 | for feat in layer.getFeatures():
164 | if feat[campo[0]] > 0:
165 | ordem_comp += [feat[campo[0]]]
166 | else:
167 | raise QgsProcessingException(self.tr('All attributes of the order field (sequence) must be greater than zero and not null!', 'Todos atributos do campo ordem (sequência) devem ser maiores que zero e não nulos!'))
168 | ordem_comp.sort()
169 | if ordem_list != ordem_comp:
170 | raise QgsProcessingException(self.tr('The point sequence field must be filled in correctly!', 'O campo de sequência dos pontos deve preenchido corretamente!'))
171 |
172 | # Pegar coordenadas dos pontos
173 | pontos = {}
174 | for feat in layer.getFeatures():
175 | geom = feat.geometry()
176 | pnt = geom.constGet()
177 | pontos[feat[campo[0]]] = QgsPoint(pnt.x(), pnt.y(), pnt.z()) if layer.wkbType() != 1 else QgsPointXY(pnt.x(), pnt.y())
178 |
179 | # Gerar polígono:
180 | COORDS = []
181 | for ordem in ordem_list:
182 | COORDS += [pontos[ordem]]
183 | COORDS = COORDS + [COORDS[0]]
184 | anel = QgsLineString(COORDS)
185 | pol = QgsPolygon(anel)
186 | Poligono = QgsGeometry(pol)
187 |
188 | feature = QgsFeature()
189 | feature.setGeometry(Poligono)
190 | feature.setAttributes([1])
191 | sink.addFeature(feature, QgsFeatureSink.FastInsert)
192 |
193 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
194 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
195 |
196 | return {self.POLYGON: dest_id}
197 |
--------------------------------------------------------------------------------
/processing_provider/Vect_reverseVertexOrder.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | """
5 | Vect_reverseVertexOrder.py
6 | ***************************************************************************
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 | __author__ = 'Leandro França'
16 | __date__ = '2020-02-14'
17 | __copyright__ = '(C) 2021, Leandro França'
18 |
19 | from qgis.PyQt.QtCore import QCoreApplication
20 | from qgis.core import (QgsApplication,
21 | QgsProcessingParameterVectorLayer,
22 | QgsGeometry,
23 | QgsProcessing,
24 | QgsProcessingParameterField,
25 | QgsProcessingParameterBoolean,
26 | QgsFeatureSink,
27 | QgsProcessingException,
28 | QgsProcessingAlgorithm,
29 | QgsProcessingParameterFeatureSource,
30 | QgsProcessingParameterFeatureSink)
31 | from lftools.geocapt.imgs import Imgs
32 | from lftools.translations.translate import translate
33 | import os
34 | from qgis.PyQt.QtGui import QIcon
35 |
36 | class ReverseVertexOrder(QgsProcessingAlgorithm):
37 |
38 | LOC = QgsApplication.locale()[:2]
39 |
40 | def tr(self, *string):
41 | return translate(string, self.LOC)
42 |
43 | def createInstance(self):
44 | return ReverseVertexOrder()
45 |
46 | def name(self):
47 | return 'reversevertexorder'
48 |
49 | def displayName(self):
50 | return self.tr('Reverse vertex order', 'Inverter ordem dos vértices')
51 |
52 | def group(self):
53 | return self.tr('Vector', 'Vetor')
54 |
55 | def groupId(self):
56 | return 'vector'
57 |
58 | def tags(self):
59 | return self.tr('sequence,reverse,vertex,point,organize,orientar,orientation,topography').split(',')
60 |
61 | def icon(self):
62 | return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/vetor.png'))
63 |
64 | txt_en = 'Inverts vertex order for polygons and lines.'
65 | txt_pt = 'Inverte a ordem dos vértices para polígonos e linhas.'
66 | figure = 'images/tutorial/vect_reverse_vertex_sequence.jpg'
67 |
68 | def shortHelpString(self):
69 | social_BW = Imgs().social_BW
70 | footer = '''
71 |
), self.figure) +''')
72 |
73 |
74 |
75 | '''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''
76 |
'''+ social_BW + '''
77 | '''
78 | return self.tr(self.txt_en, self.txt_pt) + footer
79 |
80 |
81 |
82 | INPUT = 'INPUT'
83 | SELECTED = 'SELECTED'
84 | SAVE = 'SAVE'
85 |
86 | def initAlgorithm(self, config=None):
87 |
88 | self.addParameter(
89 | QgsProcessingParameterVectorLayer(
90 | self.INPUT,
91 | self.tr('Input Layer', 'Camada de entrada'),
92 | [QgsProcessing.TypeVectorLine,
93 | QgsProcessing.TypeVectorPolygon]
94 | )
95 | )
96 |
97 | self.addParameter(
98 | QgsProcessingParameterBoolean(
99 | self.SELECTED,
100 | self.tr('Only selected', 'Apenas feições selecionadas'),
101 | defaultValue=False
102 | )
103 | )
104 |
105 | self.addParameter(
106 | QgsProcessingParameterBoolean(
107 | self.SAVE,
108 | self.tr('Save Editions', 'Salvar Edições'),
109 | defaultValue=True
110 | )
111 | )
112 |
113 | def processAlgorithm(self, parameters, context, feedback):
114 |
115 | camada = self.parameterAsVectorLayer(
116 | parameters,
117 | self.INPUT,
118 | context
119 | )
120 | if camada is None:
121 | raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
122 |
123 | selecionados = self.parameterAsBool(
124 | parameters,
125 | self.SELECTED,
126 | context
127 | )
128 | if selecionados is None:
129 | raise QgsProcessingException(self.invalidSourceError(parameters, self.SELECTED))
130 |
131 | salvar = self.parameterAsBool(
132 | parameters,
133 | self.SAVE,
134 | context
135 | )
136 | if salvar is None:
137 | raise QgsProcessingException(self.invalidSourceError(parameters, self.SAVE))
138 |
139 | camada.startEditing() # coloca no modo edição
140 |
141 | if not selecionados:
142 | total = 100.0 / camada.featureCount() if camada.featureCount() else 0
143 | for current, feat in enumerate(camada.getFeatures()):
144 | cont = 0
145 | geom = feat.geometry()
146 | new_geom = self.inv_vertex_order(geom)
147 | camada.changeGeometry(feat.id(), new_geom)
148 | feedback.setProgress(int(current * total))
149 | else:
150 | total = 100.0 / camada.selectedFeatureCount() if camada.selectedFeatureCount() else 0
151 | for current, feat in enumerate(camada.getSelectedFeatures()):
152 | cont = 0
153 | geom = feat.geometry()
154 | new_geom = self.inv_vertex_order(geom)
155 | camada.changeGeometry(feat.id(), new_geom)
156 | feedback.setProgress(int(current * total))
157 |
158 | if salvar:
159 | camada.commitChanges() # salva as edições
160 |
161 | feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
162 | feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))
163 |
164 | return {}
165 |
166 | def inv_vertex_order(self, geom):
167 | if geom.type() == 1: #Line
168 | if geom.isMultipart():
169 | linhas = geom.asMultiPolyline()
170 | newLines = []
171 | for linha in linhas:
172 | newLine = linha[::-1]
173 | newLines += [newLine]
174 | newGeom = QgsGeometry.fromMultiPolylineXY(newLines)
175 | return newGeom
176 | else:
177 | linha = geom.asPolyline()
178 | newLine = linha[::-1]
179 | newGeom = QgsGeometry.fromPolylineXY(newLine)
180 | return newGeom
181 | elif geom.type() == 2: #Polygon
182 | if geom.isMultipart():
183 | poligonos = geom.asMultiPolygon()
184 | newPolygons = []
185 | for pol in poligonos:
186 | newPol = []
187 | for anel in pol:
188 | newAnel = anel[::-1]
189 | newPol += [newAnel]
190 | newPolygons += [newPol]
191 | newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons)
192 | return newGeom
193 | else:
194 | pol = geom.asPolygon()
195 | newPol = []
196 | for anel in pol:
197 | newAnel = anel[::-1]
198 | newPol += [newAnel]
199 | newGeom = QgsGeometry.fromPolygonXY(newPol)
200 | return newGeom
201 | else:
202 | return None
203 |
--------------------------------------------------------------------------------
/processing_provider/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/processing_provider/__init__.py
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pillow
2 |
--------------------------------------------------------------------------------
/scripts/compile-strings.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | LRELEASE=$1
3 | LOCALES=$2
4 |
5 |
6 | for LOCALE in ${LOCALES}
7 | do
8 | echo "Processing: ${LOCALE}.ts"
9 | # Note we don't use pylupdate with qt .pro file approach as it is flakey
10 | # about what is made available.
11 | $LRELEASE i18n/${LOCALE}.ts
12 | done
13 |
--------------------------------------------------------------------------------
/scripts/run-env-linux.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | QGIS_PREFIX_PATH=/usr/local/qgis-2.0
4 | if [ -n "$1" ]; then
5 | QGIS_PREFIX_PATH=$1
6 | fi
7 |
8 | echo ${QGIS_PREFIX_PATH}
9 |
10 |
11 | export QGIS_PREFIX_PATH=${QGIS_PREFIX_PATH}
12 | export QGIS_PATH=${QGIS_PREFIX_PATH}
13 | export LD_LIBRARY_PATH=${QGIS_PREFIX_PATH}/lib
14 | export PYTHONPATH=${QGIS_PREFIX_PATH}/share/qgis/python:${QGIS_PREFIX_PATH}/share/qgis/python/plugins:${PYTHONPATH}
15 |
16 | echo "QGIS PATH: $QGIS_PREFIX_PATH"
17 | export QGIS_DEBUG=0
18 | export QGIS_LOG_FILE=/tmp/inasafe/realtime/logs/qgis.log
19 |
20 | export PATH=${QGIS_PREFIX_PATH}/bin:$PATH
21 |
22 | echo "This script is intended to be sourced to set up your shell to"
23 | echo "use a QGIS 2.0 built in $QGIS_PREFIX_PATH"
24 | echo
25 | echo "To use it do:"
26 | echo "source $BASH_SOURCE /your/optional/install/path"
27 | echo
28 | echo "Then use the make file supplied here e.g. make guitest"
29 |
--------------------------------------------------------------------------------
/scripts/update-strings.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | LOCALES=$*
3 |
4 | # Get newest .py files so we don't update strings unnecessarily
5 |
6 | CHANGED_FILES=0
7 | PYTHON_FILES=`find . -regex ".*\(ui\|py\)$" -type f`
8 | for PYTHON_FILE in $PYTHON_FILES
9 | do
10 | CHANGED=$(stat -c %Y $PYTHON_FILE)
11 | if [ ${CHANGED} -gt ${CHANGED_FILES} ]
12 | then
13 | CHANGED_FILES=${CHANGED}
14 | fi
15 | done
16 |
17 | # Qt translation stuff
18 | # for .ts file
19 | UPDATE=false
20 | for LOCALE in ${LOCALES}
21 | do
22 | TRANSLATION_FILE="i18n/$LOCALE.ts"
23 | if [ ! -f ${TRANSLATION_FILE} ]
24 | then
25 | # Force translation string collection as we have a new language file
26 | touch ${TRANSLATION_FILE}
27 | UPDATE=true
28 | break
29 | fi
30 |
31 | MODIFICATION_TIME=$(stat -c %Y ${TRANSLATION_FILE})
32 | if [ ${CHANGED_FILES} -gt ${MODIFICATION_TIME} ]
33 | then
34 | # Force translation string collection as a .py file has been updated
35 | UPDATE=true
36 | break
37 | fi
38 | done
39 |
40 | if [ ${UPDATE} == true ]
41 | # retrieve all python files
42 | then
43 | echo ${PYTHON_FILES}
44 | # update .ts
45 | echo "Please provide translations by editing the translation files below:"
46 | for LOCALE in ${LOCALES}
47 | do
48 | echo "i18n/"${LOCALE}".ts"
49 | # Note we don't use pylupdate with qt .pro file approach as it is flakey
50 | # about what is made available.
51 | pylupdate4 -noobsolete ${PYTHON_FILES} -ts i18n/${LOCALE}.ts
52 | done
53 | else
54 | echo "No need to edit any translation files (.ts) because no python files"
55 | echo "has been updated since the last update translation. "
56 | fi
57 |
--------------------------------------------------------------------------------
/styles/SVG/multidirectional.svg:
--------------------------------------------------------------------------------
1 |
2 |
60 |
--------------------------------------------------------------------------------
/test/__init__.py:
--------------------------------------------------------------------------------
1 | # import qgis libs so that ve set the correct sip api version
2 | import qgis # pylint: disable=W0611 # NOQA
--------------------------------------------------------------------------------
/test/qgis_interface.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """QGIS plugin implementation.
3 |
4 | .. note:: This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | .. note:: This source code was copied from the 'postgis viewer' application
10 | with original authors:
11 | Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk
12 | Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org
13 | Copyright (c) 2014 Tim Sutton, tim@linfiniti.com
14 |
15 | """
16 |
17 | __author__ = 'tim@linfiniti.com'
18 | __revision__ = '$Format:%H$'
19 | __date__ = '10/01/2011'
20 | __copyright__ = (
21 | 'Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk and '
22 | 'Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org'
23 | 'Copyright (c) 2014 Tim Sutton, tim@linfiniti.com'
24 | )
25 |
26 | import logging
27 | from qgis.PyQt.QtCore import QObject, pyqtSlot, pyqtSignal
28 | from qgis.core import QgsMapLayerRegistry
29 | from qgis.gui import QgsMapCanvasLayer
30 | LOGGER = logging.getLogger('QGIS')
31 |
32 |
33 | #noinspection PyMethodMayBeStatic,PyPep8Naming
34 | class QgisInterface(QObject):
35 | """Class to expose QGIS objects and functions to plugins.
36 |
37 | This class is here for enabling us to run unit tests only,
38 | so most methods are simply stubs.
39 | """
40 | currentLayerChanged = pyqtSignal(QgsMapCanvasLayer)
41 |
42 | def __init__(self, canvas):
43 | """Constructor
44 | :param canvas:
45 | """
46 | QObject.__init__(self)
47 | self.canvas = canvas
48 | # Set up slots so we can mimic the behaviour of QGIS when layers
49 | # are added.
50 | LOGGER.debug('Initialising canvas...')
51 | # noinspection PyArgumentList
52 | QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers)
53 | # noinspection PyArgumentList
54 | QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayer)
55 | # noinspection PyArgumentList
56 | QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers)
57 |
58 | # For processing module
59 | self.destCrs = None
60 |
61 | @pyqtSlot('QStringList')
62 | def addLayers(self, layers):
63 | """Handle layers being added to the registry so they show up in canvas.
64 |
65 | :param layers: list list of map layers that were added
66 |
67 | .. note:: The QgsInterface api does not include this method,
68 | it is added here as a helper to facilitate testing.
69 | """
70 | #LOGGER.debug('addLayers called on qgis_interface')
71 | #LOGGER.debug('Number of layers being added: %s' % len(layers))
72 | #LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers()))
73 | current_layers = self.canvas.layers()
74 | final_layers = []
75 | for layer in current_layers:
76 | final_layers.append(QgsMapCanvasLayer(layer))
77 | for layer in layers:
78 | final_layers.append(QgsMapCanvasLayer(layer))
79 |
80 | self.canvas.setLayerSet(final_layers)
81 | #LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))
82 |
83 | @pyqtSlot('QgsMapLayer')
84 | def addLayer(self, layer):
85 | """Handle a layer being added to the registry so it shows up in canvas.
86 |
87 | :param layer: list list of map layers that were added
88 |
89 | .. note: The QgsInterface api does not include this method, it is added
90 | here as a helper to facilitate testing.
91 |
92 | .. note: The addLayer method was deprecated in QGIS 1.8 so you should
93 | not need this method much.
94 | """
95 | pass
96 |
97 | @pyqtSlot()
98 | def removeAllLayers(self):
99 | """Remove layers from the canvas before they get deleted."""
100 | self.canvas.setLayerSet([])
101 |
102 | def newProject(self):
103 | """Create new project."""
104 | # noinspection PyArgumentList
105 | QgsMapLayerRegistry.instance().removeAllMapLayers()
106 |
107 | # ---------------- API Mock for QgsInterface follows -------------------
108 |
109 | def zoomFull(self):
110 | """Zoom to the map full extent."""
111 | pass
112 |
113 | def zoomToPrevious(self):
114 | """Zoom to previous view extent."""
115 | pass
116 |
117 | def zoomToNext(self):
118 | """Zoom to next view extent."""
119 | pass
120 |
121 | def zoomToActiveLayer(self):
122 | """Zoom to extent of active layer."""
123 | pass
124 |
125 | def addVectorLayer(self, path, base_name, provider_key):
126 | """Add a vector layer.
127 |
128 | :param path: Path to layer.
129 | :type path: str
130 |
131 | :param base_name: Base name for layer.
132 | :type base_name: str
133 |
134 | :param provider_key: Provider key e.g. 'ogr'
135 | :type provider_key: str
136 | """
137 | pass
138 |
139 | def addRasterLayer(self, path, base_name):
140 | """Add a raster layer given a raster layer file name
141 |
142 | :param path: Path to layer.
143 | :type path: str
144 |
145 | :param base_name: Base name for layer.
146 | :type base_name: str
147 | """
148 | pass
149 |
150 | def activeLayer(self):
151 | """Get pointer to the active layer (layer selected in the legend)."""
152 | # noinspection PyArgumentList
153 | layers = QgsMapLayerRegistry.instance().mapLayers()
154 | for item in layers:
155 | return layers[item]
156 |
157 | def addToolBarIcon(self, action):
158 | """Add an icon to the plugins toolbar.
159 |
160 | :param action: Action to add to the toolbar.
161 | :type action: QAction
162 | """
163 | pass
164 |
165 | def removeToolBarIcon(self, action):
166 | """Remove an action (icon) from the plugin toolbar.
167 |
168 | :param action: Action to add to the toolbar.
169 | :type action: QAction
170 | """
171 | pass
172 |
173 | def addToolBar(self, name):
174 | """Add toolbar with specified name.
175 |
176 | :param name: Name for the toolbar.
177 | :type name: str
178 | """
179 | pass
180 |
181 | def mapCanvas(self):
182 | """Return a pointer to the map canvas."""
183 | return self.canvas
184 |
185 | def mainWindow(self):
186 | """Return a pointer to the main window.
187 |
188 | In case of QGIS it returns an instance of QgisApp.
189 | """
190 | pass
191 |
192 | def addDockWidget(self, area, dock_widget):
193 | """Add a dock widget to the main window.
194 |
195 | :param area: Where in the ui the dock should be placed.
196 | :type area:
197 |
198 | :param dock_widget: A dock widget to add to the UI.
199 | :type dock_widget: QDockWidget
200 | """
201 | pass
202 |
203 | def legendInterface(self):
204 | """Get the legend."""
205 | return self.canvas
206 |
--------------------------------------------------------------------------------
/test/tenbytenraster.asc:
--------------------------------------------------------------------------------
1 | NCOLS 10
2 | NROWS 10
3 | XLLCENTER 1535380.000000
4 | YLLCENTER 5083260.000000
5 | DX 10
6 | DY 10
7 | NODATA_VALUE -9999
8 | 0 1 2 3 4 5 6 7 8 9
9 | 0 1 2 3 4 5 6 7 8 9
10 | 0 1 2 3 4 5 6 7 8 9
11 | 0 1 2 3 4 5 6 7 8 9
12 | 0 1 2 3 4 5 6 7 8 9
13 | 0 1 2 3 4 5 6 7 8 9
14 | 0 1 2 3 4 5 6 7 8 9
15 | 0 1 2 3 4 5 6 7 8 9
16 | 0 1 2 3 4 5 6 7 8 9
17 | 0 1 2 3 4 5 6 7 8 9
18 | CRS
19 | NOTES
20 |
--------------------------------------------------------------------------------
/test/tenbytenraster.asc.aux.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Point
4 |
5 |
6 |
7 | 9
8 | 4.5
9 | 0
10 | 2.872281323269
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/tenbytenraster.keywords:
--------------------------------------------------------------------------------
1 | title: Tenbytenraster
2 |
--------------------------------------------------------------------------------
/test/tenbytenraster.lic:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tim Sutton, Linfiniti Consulting CC
5 |
6 |
7 |
8 | tenbytenraster.asc
9 | 2700044251
10 | Yes
11 | Tim Sutton
12 | Tim Sutton (QGIS Source Tree)
13 | Tim Sutton
14 | This data is publicly available from QGIS Source Tree. The original
15 | file was created and contributed to QGIS by Tim Sutton.
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/tenbytenraster.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/test/tenbytenraster.qml:
--------------------------------------------------------------------------------
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 | 0
26 |
27 |
--------------------------------------------------------------------------------
/test/test_init.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """Tests QGIS plugin init."""
3 |
4 | __author__ = 'Tim Sutton '
5 | __revision__ = '$Format:%H$'
6 | __date__ = '17/10/2010'
7 | __license__ = "GPL"
8 | __copyright__ = 'Copyright 2012, Australia Indonesia Facility for '
9 | __copyright__ += 'Disaster Reduction'
10 |
11 | import os
12 | import unittest
13 | import logging
14 | import configparser
15 |
16 | LOGGER = logging.getLogger('QGIS')
17 |
18 |
19 | class TestInit(unittest.TestCase):
20 | """Test that the plugin init is usable for QGIS.
21 |
22 | Based heavily on the validator class by Alessandro
23 | Passoti available here:
24 |
25 | http://github.com/qgis/qgis-django/blob/master/qgis-app/
26 | plugins/validator.py
27 |
28 | """
29 |
30 | def test_read_init(self):
31 | """Test that the plugin __init__ will validate on plugins.qgis.org."""
32 |
33 | # You should update this list according to the latest in
34 | # https://github.com/qgis/qgis-django/blob/master/qgis-app/
35 | # plugins/validator.py
36 |
37 | required_metadata = [
38 | 'name',
39 | 'description',
40 | 'version',
41 | 'qgisMinimumVersion',
42 | 'email',
43 | 'author']
44 |
45 | file_path = os.path.abspath(os.path.join(
46 | os.path.dirname(__file__), os.pardir,
47 | 'metadata.txt'))
48 | LOGGER.info(file_path)
49 | metadata = []
50 | parser = configparser.ConfigParser()
51 | parser.optionxform = str
52 | parser.read(file_path)
53 | message = 'Cannot find a section named "general" in %s' % file_path
54 | assert parser.has_section('general'), message
55 | metadata.extend(parser.items('general'))
56 |
57 | for expectation in required_metadata:
58 | message = ('Cannot find metadata "%s" in metadata source (%s).' % (
59 | expectation, file_path))
60 |
61 | self.assertIn(expectation, dict(metadata), message)
62 |
63 | if __name__ == '__main__':
64 | unittest.main()
65 |
--------------------------------------------------------------------------------
/test/test_qgis_environment.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """Tests for QGIS functionality.
3 |
4 |
5 | .. note:: This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | """
11 | __author__ = 'tim@linfiniti.com'
12 | __date__ = '20/01/2011'
13 | __copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
14 | 'Disaster Reduction')
15 |
16 | import os
17 | import unittest
18 | from qgis.core import (
19 | QgsProviderRegistry,
20 | QgsCoordinateReferenceSystem,
21 | QgsRasterLayer)
22 |
23 | from .utilities import get_qgis_app
24 | QGIS_APP = get_qgis_app()
25 |
26 |
27 | class QGISTest(unittest.TestCase):
28 | """Test the QGIS Environment"""
29 |
30 | def test_qgis_environment(self):
31 | """QGIS environment has the expected providers"""
32 |
33 | r = QgsProviderRegistry.instance()
34 | self.assertIn('gdal', r.providerList())
35 | self.assertIn('ogr', r.providerList())
36 | self.assertIn('postgres', r.providerList())
37 |
38 | def test_projection(self):
39 | """Test that QGIS properly parses a wkt string.
40 | """
41 | crs = QgsCoordinateReferenceSystem()
42 | wkt = (
43 | 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",'
44 | 'SPHEROID["WGS_1984",6378137.0,298.257223563]],'
45 | 'PRIMEM["Greenwich",0.0],UNIT["Degree",'
46 | '0.0174532925199433]]')
47 | crs.createFromWkt(wkt)
48 | auth_id = crs.authid()
49 | expected_auth_id = 'EPSG:4326'
50 | self.assertEqual(auth_id, expected_auth_id)
51 |
52 | # now test for a loaded layer
53 | path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc')
54 | title = 'TestRaster'
55 | layer = QgsRasterLayer(path, title)
56 | auth_id = layer.crs().authid()
57 | self.assertEqual(auth_id, expected_auth_id)
58 |
59 | if __name__ == '__main__':
60 | unittest.main()
61 |
--------------------------------------------------------------------------------
/test/test_translations.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """Safe Translations Test.
3 |
4 | .. note:: This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | """
10 | from .utilities import get_qgis_app
11 |
12 | __author__ = 'ismailsunni@yahoo.co.id'
13 | __date__ = '12/10/2011'
14 | __copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
15 | 'Disaster Reduction')
16 | import unittest
17 | import os
18 |
19 | from qgis.PyQt.QtCore import QCoreApplication, QTranslator
20 |
21 | QGIS_APP = get_qgis_app()
22 |
23 |
24 | class SafeTranslationsTest(unittest.TestCase):
25 | """Test translations work."""
26 |
27 | def setUp(self):
28 | """Runs before each test."""
29 | if 'LANG' in iter(os.environ.keys()):
30 | os.environ.__delitem__('LANG')
31 |
32 | def tearDown(self):
33 | """Runs after each test."""
34 | if 'LANG' in iter(os.environ.keys()):
35 | os.environ.__delitem__('LANG')
36 |
37 | def test_qgis_translations(self):
38 | """Test that translations work."""
39 | parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir)
40 | dir_path = os.path.abspath(parent_path)
41 | file_path = os.path.join(
42 | dir_path, 'i18n', 'af.qm')
43 | translator = QTranslator()
44 | translator.load(file_path)
45 | QCoreApplication.installTranslator(translator)
46 |
47 | expected_message = 'Goeie more'
48 | real_message = QCoreApplication.translate("@default", 'Good morning')
49 | self.assertEqual(real_message, expected_message)
50 |
51 |
52 | if __name__ == "__main__":
53 | suite = unittest.makeSuite(SafeTranslationsTest)
54 | runner = unittest.TextTestRunner(verbosity=2)
55 | runner.run(suite)
56 |
--------------------------------------------------------------------------------
/test/utilities.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """Common functionality used by regression tests."""
3 |
4 | import sys
5 | import logging
6 |
7 |
8 | LOGGER = logging.getLogger('QGIS')
9 | QGIS_APP = None # Static variable used to hold hand to running QGIS app
10 | CANVAS = None
11 | PARENT = None
12 | IFACE = None
13 |
14 |
15 | def get_qgis_app():
16 | """ Start one QGIS application to test against.
17 |
18 | :returns: Handle to QGIS app, canvas, iface and parent. If there are any
19 | errors the tuple members will be returned as None.
20 | :rtype: (QgsApplication, CANVAS, IFACE, PARENT)
21 |
22 | If QGIS is already running the handle to that app will be returned.
23 | """
24 |
25 | try:
26 | from qgis.PyQt import QtGui, QtCore
27 | from qgis.core import QgsApplication
28 | from qgis.gui import QgsMapCanvas
29 | from .qgis_interface import QgisInterface
30 | except ImportError:
31 | return None, None, None, None
32 |
33 | global QGIS_APP # pylint: disable=W0603
34 |
35 | if QGIS_APP is None:
36 | gui_flag = True # All test will run qgis in gui mode
37 | #noinspection PyPep8Naming
38 | QGIS_APP = QgsApplication(sys.argv, gui_flag)
39 | # Make sure QGIS_PREFIX_PATH is set in your env if needed!
40 | QGIS_APP.initQgis()
41 | s = QGIS_APP.showSettings()
42 | LOGGER.debug(s)
43 |
44 | global PARENT # pylint: disable=W0603
45 | if PARENT is None:
46 | #noinspection PyPep8Naming
47 | PARENT = QtGui.QWidget()
48 |
49 | global CANVAS # pylint: disable=W0603
50 | if CANVAS is None:
51 | #noinspection PyPep8Naming
52 | CANVAS = QgsMapCanvas(PARENT)
53 | CANVAS.resize(QtCore.QSize(400, 400))
54 |
55 | global IFACE # pylint: disable=W0603
56 | if IFACE is None:
57 | # QgisInterface is a stub implementation of the QGIS plugin interface
58 | #noinspection PyPep8Naming
59 | IFACE = QgisInterface(CANVAS)
60 |
61 | return QGIS_APP, CANVAS, IFACE, PARENT
62 |
--------------------------------------------------------------------------------
/translations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEOXINGU/lftools/726cc5eeed13615d4478ade773b59555b47bf7be/translations/__init__.py
--------------------------------------------------------------------------------
/translations/translate.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 | __author__ = 'Leandro França'
14 | __date__ = '2024-06-23'
15 |
16 | from lftools.translations.dictionary import dic
17 |
18 | def translate(string, loc):
19 | # Português
20 | if loc == 'pt':
21 | if len(string) == 2:
22 | return string[1]
23 | else:
24 | return string[0]
25 | # Espanhol
26 | elif loc == 'es':
27 | if string[0] in dic:
28 | if loc in dic[string[0]]:
29 | return dic[string[0]][loc]
30 | else:
31 | return string[0]
32 | elif len(string) == 2:
33 | return string[1]
34 | else:
35 | return string[0]
36 | # Inglês
37 | else:
38 | return string[0]
39 |
--------------------------------------------------------------------------------