[general]
name=qgSurf
description=Processing of geological planes and surfaces
about=qgSurf is a field-mapping/structural-geology plugin that can be used as an aid in: a) estimating the attitude of sub-planar geological surfaces given three or more points on a topographic surface; b) determining the intersection between a geological plane and a topographic surface; c) calculating the distance between points and a geological plane; d) plotting geological data in a stereonet; e) creating geological profiles; f) interpreting exported geological profiles in an editable distance-elevation section plane.
category=Plugins
version=version 4.5.0
experimental=True
qgisMinimumVersion=4.0
author=Mauro Alberti
email=alberti.m65@gmail.com
icon=./icons/qgsurf.png

; start of optional metadata
changelog=
  4.5.0: [20260822] Section editor: the categories of a section are now those of the source layers, whole, instead of the ones the single profile happens to cross. A class of the geological map that this profile does not meet had no category in the section, so it could not be given to a body drawn at depth, and the classification came out different from one section to the next; the fallback colour, assigned by the position a unit had in the list of that profile alone, also gave the same unit a different colour in each of them. The whole classification of the intersected layers - every class of the polygon layer with the colour it is drawn in, every category of the intersected lines - now travels with the export in a new gp_source_categories table, the schema going to v4 with older databases upgraded in place; an export written before it carries none, and the categories are then gathered from all the loaded profiles together, which still keeps them common to every section
         [20260822] Section editor: a legend common to all the sections shown, drawn in the plane beside them: a column of swatches, one per category, in the order of the source layer legend and with the category name beside it, in a "Legend" group holding one layer for the geological units and one for the line intersections. It follows the sections when the layout or a frame moves them, and is sized against them. The new import option "Draw a legend beside the sections" leaves it out
         [20260822] Section editor: the styles of the categories are now shared and kept. A change made to a category - on the legend, on the unit bodies, on the outcrop bands or on the line intersections - is handed at once to every other layer of its family, the bands taking the colour of each category since they are lines where the bodies are fills; and it is stored in the GeoPackage for the result set, so that it is found again at the next load and in a later session, winning over the attributes the export carries. The new "Reset the category styles" button drops the choices made by hand and draws the categories again as the export has them
         [20260822] GeoProfiler and Section editor: the graphic attributes now travel with the exported profiles, so a section is drawn in the colours of the map it comes from. The export stores the styles the plot has at that moment - the colour of every geological unit, the colours, widths, line styles and markers of the topography and of the projections, the elevation range and the vertical exaggeration - in a new gp_graphical_params table, a profile exploded and restyled on its own carrying its own alongside those of the stacked plot; the schema goes to v3, older databases being upgraded in place and read as before. The Section editor paints the outcrop bands and the unit bodies seeded under them with the colour each unit has in the plot, instead of a palette of its own assigned in alphabetical order, which gave the same unit a different colour from one profile to the next; the topography, the projected data and the line intersections keep the styles they were plotted with. GeoProfiler puts the same styles back when it reimports a geoprofile, which until now reopened with default colours and recomputed axes - in a fresh session, with unit colours drawn at random - and no longer resynchronises them with a polygon layer the imported profiles have nothing to do with. The new import option "Use the graphic attributes exported from GeoProfiler", on by default and offered only when the database carries them, goes back to the previous look
         [20260822] GeoProfiler: fixed the export of a chosen subset of profiles, which wrote no profile at all while reporting success: the profiles were matched against the feature ids of the source line layer through an attribute they do not carry, so every one of them was skipped. The feature id each profile is drawn along is now kept with the profiles - it cannot ride on the profiles themselves, draping the traces on the DEM rebuilding them from their profilers - and reaches the export, which until now also left source_profile_fid empty and named every profile "profile" instead of after its source feature. "Fill from selection" in the export dialog now also reads the selection of a 3D line layer chosen among those already in the project, and not only of one the plugin generated itself, the two being remembered under different names
         [20260822] Section editor: fixed the colour of the unit bodies, which was neither the colour picked nor opaque as intended: the fill was built by appending the opacity to the hexadecimal colour, an eight-digit form Qt reads back as its own alpha-first one, so every body was drawn in a shifted colour and at a sixth of the intended opacity
         [20260820] Section editor: the section is now framed: a box enclosing the profile, an elevation grid, labelled ticks along the two axes and the two profile ends named A and A', so that a section is read against graduated axes instead of bare canvas coordinates. The frame is a backdrop layer like the others, derived from the extent of the profile alone and redrawn at every load: its two steps - elevation grid and distance ticks - are chosen automatically, graduating each axis into about eight round divisions, or set in the import dialog, and changing one only takes loading the profile again. The box is grown outwards to round elevations, and sits above the unit bodies, so the grid stays visible through their fills. Nothing is asked of the GeoProfiler export, which already carries the profile length and elevation range
         [20260820] Section editor: the frame is not tied to the elevation range of the topography any more: a bottom and a top can be given, in the import dialog and in the new "Section frame" group of the panel, together with the two steps, and "Redraw frame" draws the frame again in place - no reload of the section, the interpretation untouched - reporting the extent actually drawn, the automatic choices resolved. The bottom is what a section usually needs: the box used to stop at the lowest point of the topography, leaving everything interpreted below sea level outside the grid. The given elevations only extend the box, never cut the profile out of it, and the automatic grid step follows the enlarged range. The four values are stored per profile in the GeoPackage (gp_section_frame_params), so the frame comes back as it was left, in a later session too; the frame options no longer appear in the GeoProfiler import dialog, where they mean nothing
         [20260820] GeoProfiler: fixed the symbolization of polygon intersections, which did not follow the classification of the source polygon layer: a class whose legend label is empty - the QGIS default when the label is not filled in, as for the "all other values" catch-all - was dropped, and its polygons were silently attributed to the first class of the legend, which also received every feature the classification does not cover; a layer classified by expression, rather than by plain field, collapsed entirely into that first class, its classification never being evaluated. Classes are now named after their label, falling back on the value they classify, features outside the classification form an "unclassified" class of their own instead of joining an existing one, and the plot colours follow the same names, rule-based and graduated renderers included, instead of being read only from categorized ones. Polygon intersections of a single-symbol layer, until now computed and then silently discarded on export for want of a class name, are exported as "all features"
         [20260820] GeoProfiler: the "unclassified" class, gathering the polygons the source layer classification does not cover, now appears among the polygon intersection colours, in a neutral grey that can be changed like any other, instead of falling back on the plot default; it is listed only when some intersection actually belongs to it, so the legend never carries an empty class. The legend text size is settable in the same dialog, renamed "Polygon intersection style", and its default drops from the 10 points matplotlib uses to 7: the legend sits in a narrow column beside the profiles, where the larger text took room from the section itself
         [20260820] Section editor: the unit bodies are no longer seeded one per polygon of the source map: the bands of a same unit that touch one another become a single body, the boundaries between the map polygons they come from not being geological ones, and leaving them to be merged by hand made the editing unmanageable on a map holding a unit as many adjacent polygons; the same unit met again beyond another one still gets a body of its own. Bodies seeded one per polygon before this are recognized and not duplicated. The bodies also reach half as deep below their outcrop band as they did, a starting shape being easier to pull down than to push up
         [20260820] new Section editor module: loads a profile from the GeoProfiler export database into the QGIS canvas as a distance-elevation (s-z) working plane, with read-only backdrop layers (topography, projected attitudes drawn as segments dipping with their apparent dip, projected points, line and polygon intersections) and three editable GeoPackage layers - horizons, faults and unit bodies, the latter seeded once per polygon intersection as its outcrop band closed downward, to be reshaped into the interpreted body - carrying geological attributes (type, movement sense, units, confidence) and snapping to the attitudes and the topography; a plain-SQLite export database is copied, on confirmation, into a GeoPackage twin that stores the interpretation alongside the export tables, the backdrops are stored there too and rewritten at every load, so a saved QGIS project reopens complete instead of warning about temporary layers that come back empty, and reloading the same profile restores the interpretation drawn for it
  4.4.0: [20260817] GeoProfiler: added projection of earthquake focal mechanisms, plotted as beachballs either in map view or rotated into the section plane, with their own style (quadrant colours, size, outline, alpha, labels) and export/import to the profile database
         [20260817] GeoProfiler: point and focal mechanism projection can now read the vertical field as a depth instead of an elevation, measured either from sea level (default) or below the topographic surface from a DEM, in km (default) or m, converted to elevation for plotting
         [20260817] GeoProfiler: projection of large datasets is orders of magnitude faster (collinear segments of densified profiles are collapsed, and points beyond the maximum distance are excluded by a buffer pre-filter before any projection); the progress bar now advances per block of points, over the whole run, instead of once per profile
         [20260817] GeoProfiler: fixed saving and loading of graphical parameters, which failed on save and returned unusable parameters on load; fixed projection along individual axes, which used the axis of an arbitrary profile segment instead of the one given for each point; fixed attitudes being paired with the wrong elevation when a record had no valid one; made focal mechanism labels legible; removed unreachable duplicate point-projection code
         [20260817] GeoProfiler: a single profile can now be exploded into its own window, with the full height to itself instead of a sliver of the stacked plot, and with its own graphical parameters, restyled from the window itself; several exploded profiles can stay open side by side for comparison; fixed an exploded profile being labelled "1" and taking the first profile's line-intersection colours whatever profile it showed
         [20260817] GeoProfiler: readable profile axes: vertical tick labels without the always-zero decimal and capped in number (five per profile by default), both axes optionally labelled in km, the vertical one optionally as a depth counting downwards, and each axis named with its quantity and unit; the profile number moved out of the way of the elevation labels; all of it configurable in the graphical parameters dialog and saved with the styles; fixed the requested elevation range not being honoured, as writing out the ticks widened the axis to span them
         [20260818] fixed the reading of degenerate geometries, where a single defective feature discarded the whole source layer: features with null or empty geometries, and parts with too few points, are now skipped and reported in the "qgSurf" log panel, in line and polygon intersections, point/attitude/focal mechanism projections, plane distances and best-fit plane; polygon intersections now keep the line parts of results that are not lines only, as produced by a profile touching a polygon; profiles defined from a line layer now read single-part geometries as well, and no longer require multipart ones
         [20260818] help: the GeoProfiler help is aligned to the current interface (numbered command tree, focal mechanism projection with its beachball styles, vertical values read as depths, single profile exploded into its own window, axis units and names, polygon categories taken from the layer symbology, unreadable features skipped and logged) and illustrated again, with the figures to retake marked "TO BE UPDATED" and the missing ones marked "TO INSERT"; same marking in the stereonet help, whose interface, style and plot figures predate the 4.3.0 additions its text already describes; note on skipped records added to the best-fit plane and plane distances helps
         [20260819] GeoProfiler: the profile number is now written inside the top left corner of its plot box, clear of the elevation tick labels it used to sit against, on a light patch that keeps it legible where the topography reaches the corner; the elevation axis name moved closer to the box, the room kept for the profile number no longer being needed
         [20260819] GeoProfiler: generating a 3D profile without having defined the output storage is now refused with an explanatory message, instead of being reported as successful while nothing was written; a generation whose lines cannot all be written to the storage layer now reports what was written, instead of confirming success and confining the reason to the "qgSurf" log panel
         [20260819] GeoProfiler: the commands defining the profile storage now say what went wrong: giving a new 3D line layer the name of one already in the geopackage reported only "Error with adding vector layer", and now names the conflict and points to "Append to existing 3D line layer in geopackage"; appending to a layer that does not exist, or that does not hold 3D lines, is refused when the layer is chosen instead of failing at write time, once the profile has been computed; creating a new geopackage over an existing file, which recreated it from scratch and destroyed every layer it held while reporting success, now asks for confirmation first
         [20260819] GeoProfiler: fixed focal mechanism and attitude projections keeping one record per label: the projection stores one solution per record key, and those two used the label alone as the key, so all the records sharing a label value collapsed into the nearest one to the profile - a layer whose label field is not unique showed a single beachball, or a single attitude, per profile. Records are now keyed by feature id as the point projections already were, and still labelled as before; the exported "src_fid" of projected attitudes and focal mechanisms, until now always empty, carries the source feature id
         [20260819] GeoProfiler: the beachball outline width is now a style setting, next to the outline colour, and its default drops from the 2 points obspy draws to 0.5: at the size beachballs have on a section, a 2 point outline blotted out the quadrant boundaries it was drawing
         [20260819] help: the stereonet help is fully illustrated as well - the interface, layer input, text input, plot style and plot figures are retaken, and the two figures its text described without showing are there: the P-T axes plot and the canvas-linked floating window with its depth/Z histogram
         [20260819] Stereoplot: fixed the crash on plotting after a change of project ("wrapped C/C++ object of type QgsVectorLayer has been deleted"): the input layer defined from the previous project was kept and used although QGIS had destroyed it. The input is now checked before every use - plot, redraw on selection change, depth histogram, canvas-rectangle-linked replot - and a source whose layer is gone is dropped and reported, asking for the input to be defined again
         [20260819] help: the GeoProfiler help is fully illustrated - every figure now shows the current interface or the current plot, the "TO BE UPDATED" and "TO INSERT" markers are gone along with the legend box that explained them, and the nineteen figures are numbered without gaps; removed help_0.2.html, the illustrated guide the current help replaced, which no code opened and whose captions described screenshots since retaken under the same names
         [20260819] help: the GeoProfiler quickstart no longer skips the definition of the output geopackage and 3D line layer, which is mandatory and comes first, and states that a topographic profile one already has is used as it is, entering the workflow at "1 - Choose 3D topographic profile"; quickstart, workflow diagram and section numbering follow the numbered command tree
  4.3.1: [20260803] fixed security issues flagged by the QGIS plugin repository scanner (Bandit): replaced runtime assert statements with explicit exceptions and silent except/pass blocks with logged exceptions, in qgSurf's own code and in the bundled apsg/geogst/affine libraries
  4.3.0: [20260713] fixed a crash in the Plane Distances tool (DEM grid CRS parameter)
         [20260726] GeoProfiler: removed the separate "Create geoprofile" step (each stage now computes immediately on confirmation); sped up line/polygon intersection and point/attitude projection (up to ~240x faster); fixed a point-projection crash and a topographic-profile calculation bug; added configurable profile sampling distance; various UI/compatibility fixes
         [20260802] Stereoplot: added P-T axes and tangent lineation (Hoeppner) diagrams with dedicated styles; added live canvas-rectangle-linked filtering with a paired floating window showing the live stereoplot and a vertical depth/Z histogram (local vs. total distribution); main stereoplot now follows the layer's QGIS selection; fixed invisible/missing direction arrows (tangent lineation, faults) and a division-by-zero for near-vertical slickenlines; invalid records are now skipped and reported instead of raising; GeoProfiler: default export database format changed to SQLite
  4.2.0: [20260601] porting to QGIS 4
  4.1.1: [20260601] fixed security issues
  4.1.0: [20260328] implemented export and import methods for GeoProfiler; UI changes
  4.0.2: [20260108] refactored embedded modules and fixed missing affine link
  4.0.1: [20260104] fixed not implemented feature and offset bug in GeoProfiler
  4.0.0: [20260101] new version of GeoProfiler with additional functions
  3.2.2: [20241221] fixed error-print related bugs in Geoprofiler tool
  3.2.1: [20240608] fixed mpl(>3.7.3)-related bug ("module 'matplotlib.cbook' has no attribute 'mplDeprecation'"); changed experimental to False
  3.2.0: [20231101] improved 'DEM-plane intersections' tool; renamed 'Points-Plane Distances' tool to 'Plane distances from points/DEM cell' and improved
  3.1.0: [20230615] fixed embedded mplstereonet and point-distances bugs, in 'Best Fit Plane' added polygon layers as input and distances from mean plane as output
  3.0.1: [20230316] fixed np.float deprecation warning
  3.0.0: [20221126] added profiles module; embedded mplstereonet; restored original method for DEM-plane intersections; fixed various bugs
  2.1.3: [20220227] intercepted ogr Geometry Destroy action for ogr-related bug
  2.1.2: [20210310] updated embedded mplstereonet and apsg modules; fixed macOs gdal import error
  2.1.1: [20200502] fixed bugs related to (1) apsg plane plotting and (2) plot of linear data 
  2.1.0: [20190312] in DEM-plane intersection, dip angle is decimal (with one digit)
         [20190501] in Geological Plane - Points Distances, more variables for each point are calculated
  2.0.0: added stereonet tool from geocouche; added module for calculation of distance between points and a geological plane; improved best-fit plane module;code refactoring; removed old modules dependences
  1.0.0: added pygsf; minor modifications to GUI and help for best-fit-plane calculations
  0.5.0: porting to QGIS 3
  0.4.1: fixed bug related to deformation orientation; (re)added warning on geographic DEMs, still not correctly supported
  0.4.0: added support for geographic DEMs; fixed conceptual bug related to the use of the project CRS
  0.3.5: fixed bug related to the use of polar CRS (i.e., lat-lon)
  0.3.4: removed (for QGis compatibility issues) both "geosurface_simulation" and "geosurface_deformation" modules: they are now an independent, stand-alone Python project (simSurf, available in GitHub)
  0.3.3: best-fit-plane: added point input from loaded point/line layer
  0.3.2: best-fit-plane: added saving of one or more point set solutions as shapefiles
  0.3.1: support for on-the-fly-projection for Best-Fit-Plane interpolation and DEM-plane intersection; minor bugs fixing
  0.3.0: added modules for the processing of geological surfaces (non-planar)
  0.2.3: fix graphic bug (dem intersection symbol not deleted on plugin close)
  0.2.2: version compatible with QGis 2.0
  0.2.1: calculate best-fit plane orientation given points drawn in the QGis map window
  0.2.0: map display/interaction is now through the QGis map window

; tags are in comma separated value format, spaces are allowed
tags=raster, dem, intersection, structural geology, geological planes

homepage=https://gitlab.com/mauroalberti/qgSurf
tracker=https://gitlab.com/mauroalberti/qgSurf/-/work_items
repository=https://gitlab.com/mauroalberti/qgSurf

; deprecated flag (applies to the whole plugin and not only to the uploaded version)
deprecated=False
