{"name": "geodb.io", "package_name": "geodb", "version": "2.35.2", "experimental": false, "qgis_min": "3.0.0", "qgis_max": "4.99.0", "downloads": 21, "uploaded_by": "geodb", "upload_datetime": "2026-09-25T12:02:17.000059", "changelog": "2.35.2 - Pass the plugin repository's security scan\n- No change in behaviour. The plugin repository now blocks any\nversion with a security-scanner finding, and 2.35.1 was blocked\non 73 of them. None was a vulnerability: 69 were cleanup code that\ndeliberately ignores a failure (now written the idiomatic way),\ntwo flagged an empty login-token default, one flagged a settings\nkey whose NAME contains \"password\" (it stores a yes/no choice,\nnever a password), and one flagged the GPX exporter's XML import\n(it only writes GPX, it never reads XML).\n2.35.1 - Show what the server actually said when it refuses\n- A refusal carrying an HTTP status is now read and shown, instead of\nbeing reported as \"Network error: ... Unprocessable Entity\" with the\nserver's explanation thrown away. Claim document generation was the\ncase that exposed it: the server named the claim and the fields to\nshorten, and none of it reached the screen.\n- A refused request is no longer retried three times. Only a genuine\ntransport failure retries now.\n2.35.0 - Work a claim BLOCK end to end, against the server's geometry\n- A project CRS with no EPSG authority id now REFUSES to generate a\ngrid, instead of silently sending WGS84 degrees into a field the\nserver reads as metres.\n- \"Load Staff Orders\" now keeps the block you pulled from. Pulling a\nblock's proposed claims used to drop the order link, so every\ndocument generated afterwards came back attached to nothing. The\nclaims and the order were always the same job; the wizard now knows\nit, including on single-block projects where the block picker stays\nhidden.\n- The wizard reads the block's STAGE and the processing the server has\nalready stored for it. Monuments you dragged, reference points you\ntied to and LM corners you picked in an earlier session (or on the\nweb map) come back with the block instead of being silently\ndiscarded.\n- Processing a pulled block now runs on the server AND is saved there.\nThe result leads with what the processor found - corners on private\nland, claims with no PLSS section, claims straddling a state or\ncounty line, an LM corner it could not honour, MTRSC claims it does\nnot handle - so you see the problems before you commit anything.\n- Step 7 writes a processed block directly from the numbers you\nreviewed, instead of re-uploading the claims. Same LandHoldings,\nsame stakes, same package - but nothing can drift between what you\napproved and what is written, and re-running is safe: claims already\nwritten are skipped and reported.\n- Claim grids are always generated by the server now. The offline\nfallback has been removed: it drew claims from its own copy of the\n600 x 1500 ft dimensions, and it also ran when the server returned an\nerror - so a momentary server problem could quietly give you\nclient-drawn claims. Offline now says so instead.\n- Internal: the Idaho / New Mexico \"monument at a corner\" rule lived in\nfive places and each one drifted. It now lives in one.\n2.34.1 - Fix: claim layers split across two GeoPackages\n- The claims workflow now keeps ALL generated layers (Lode Claims,\nCorner Points, LM Corners, Monuments, Center Lines) AND the Reference\nPoints layer in the SAME GeoPackage as your Initial Layout, the way\nit did before 2.28.0. Since 2.28.0, reopening the wizard (or reloading\nthe plugin) could leave the workflow without the GeoPackage path in\nmemory, which caused it to create a SECOND file in the GeodbData\nfolder and write the generated layers there \u2014 splitting one claim\npackage across two GeoPackages, with the Reference Points layer\nfalling back to a non-persistent memory layer. The workflow no longer\nauto-creates a GeoPackage; it uses the one you created in Step 1\n(recovering its path from your claim layout if needed). If you did\nnot create a GeoPackage in Step 1, layers are held in memory as they\nwere before 2.28.0 \u2014 create one in Step 1 to persist your work.\n2.34.0 - Pushed claims keep their claim type\n- The claims wizard has always known whether each claim is a lode\nclaim, a placer claim, a mill site or a tunnel site, and the push to\nthe server never sent it. Every pushed claim therefore landed with\nthe server's default land status of \"Lode Claim\", whatever it\nactually was.\n- The push now sends the matching land holding type for each claim.\nThe type is matched against your company's own list, so a company\nthat has renamed its types keeps its own wording.\n- If a claim's type cannot be matched to one of your existing land\nholding types, the push simply leaves the land status to the server\nas before, rather than guessing. Nothing about the push can fail\nbecause of this.\n- The claim type now also survives processing in Step 6, where it was\npreviously dropped on the way back from the server.\n2.33.1 - Fix rasters loading as blank layers\n- Tiled rasters (GeoTIFFs, DEMs) could load as a layer that showed the\ncorrect name, CRS and extent but drew nothing at all. The tile\nrequests were being redirected, and QGIS does not follow redirects\nfor tile layers, so no image data ever arrived.\n- The plugin now checks that tiles actually load before using the\ntile-streaming path, and downloads the full raster file instead when\nthey do not. Previously this fallback existed but never ran, because\na layer with no working tiles still reports itself as valid.\n- Needs the matching geodb.io server update to take full effect.\n2.33.0 - Type-to-search on the company, project and claim-block dropdowns\n- Account tab: the Company and Project dropdowns now filter as you\ntype instead of forcing you to scroll a long list.\n- Proposed Claims tab: the Project dropdown filters the same way, and\nbecause each entry reads \"Project (Company) - N claims\" you can type\na company name to find its projects.\n- Matching is anywhere in the entry and ignores case, so \"sunshine\"\nfinds \"Sunshine Mine\" and \"nevada king\" finds that company's work.\n- Typing something that matches nothing leaves your current selection\nuntouched; the box snaps back rather than showing a stale entry.\n2.32.0 - Claim-block picker on the Proposed Claims pull\n- Multi-block projects: a \"Claim block\" dropdown appears when the\nproject has more than one block, so you can pull one batch (e.g.\na second phase) without wading through every earlier generation.\nFiltering happens server-side; \"All blocks\" keeps prior behavior.\n- Works against older servers too: no dropdown appears until the\nserver reports blocks, and unfiltered pulls are byte-compatible.\n2.31.0 - Expired sessions now prompt you to log in instead of failing the push\n- Sessions expire after 24 hours of inactivity. Previously, starting a\npush with an expired session reported the upload as \"complete\" with\nevery row listed as an error, which looked like a data problem rather\nthan an expired login.\n- The plugin now detects the expired session, renews it automatically\nwhen your password is saved, or asks you to log in again. Nothing is\nuploaded until the session is valid, so no partial pushes.\n- Affects planned sample pushes and all model data pushes.\n2.30.0 - Roads layer: pull, edit and push access roads\n- Roads now sync both ways like any other layer. Pull the project's\naccess roads into QGIS, edit their attributes (gate status, surface\ntype, condition, max width, seasonal window), and push the changes\nback. Roads match on name within the project, so an edited road\nupdates in place rather than duplicating.\n- Roads are styled automatically by access status - open green,\nclosed red, gated orange, seasonal amber, unrecorded grey, with\ngated and closed drawn dashed and seasonal dotted. Paved surfaces\ndraw one weight heavier.\n- The styling comes from the server, so the QGIS layer, the web map\nand the mobile field app always agree. Previously each client\ncarried its own copy of the palette and they could drift apart.\n- A road with no access attributes recorded renders grey. That is\nexpected, not an error: fill in gate status or route status and the\ncolour follows on the next pull.\n2.29.2 - Stamp the plugin version on every API request\n- Every request the plugin makes now carries an X-Plugin-Version\nheader identifying the exact build. This is purely diagnostic: it\nlets support pinpoint which plugin version a customer is running\nstraight from the server logs (the QGIS user-agent does not include\nthe plugin version), so a \"which build is this?\" question is answered\nin seconds instead of guesswork. No change to any feature behavior.\n2.29.1 - Fix: claims silently dropped from the Lode Claims layer\n- Editing a claim block with snapping (copy / move / snap / delete a\ngrid down to the claims you want) could leave some claims with a\nduplicated corner vertex - an invalid ring the server rejected, so\nthose claims silently vanished when the Lode Claims layer was built.\n- Claim boundaries are now de-duplicated of coincident vertices when\nread: a claim whose four corners are still present is repaired and\nkept; a claim actually collapsed below four distinct corners is\nskipped and named in the log so you know which one to redraw.\n- Also hardened ring-closing throughout so an already-closed corner\nlist is never doubly-closed, and geometry is cleaned once more right\nbefore it is sent to the server.\n- If the server still has to skip a claim for invalid geometry, the\nskipped claims are now listed by name after layer generation instead\nof quietly disappearing, so you know exactly which ones to redraw.\n- Root cause is a known, still-open QGIS bug (QGIS #62427): snapping\ncan duplicate a corner vertex during grid editing.\n2.29.0 - Location Notices: no more timeouts on large claim blocks\n- Generating Location Notices for large blocks (hundreds of claims) no\nlonger times out. Document generation now runs as a background job\nwith a live progress dialog and polls until finished, instead of\nholding one long request open (which could be cut off at ~100s on\nbig blocks even though the server kept working). Same reliable\nmechanism already used by Process Claims and Update LM Corners.\n- The \"Generate Location Notices\" button is now the primary blue style,\nmatching the \"Process Claims\" button, with its own progress bar.\n2.28.0 - Claim layers persist to GeoPackage; base layers survive reopen\n- Generated claim layers (Lode Claims, Corner Points, LM Corners,\nMonuments, Center Lines) are now always written to a GeoPackage.\nPreviously, if no GeoPackage was created in Step 1 they were held in\nmemory only and were lost if QGIS crashed or closed while adjusting\nLM corners. A GeoPackage is now auto-created in your GeodbData folder\nwhen one wasn't selected, so this work always survives a crash/reopen.\n- Streaming base layers (PLSS Grid, Federal Lands, AK State Lands) now\nremember their on/off state in the project. When you reopen a project\n(or after a crash) they re-add and resume streaming automatically\ninstead of having to be removed and re-toggled.\n2.27.1 - Vector layer dash-pattern fidelity\n- Dash arrays in server styles are recognized in both separator\nconventions (\"8 6\" and \"8,6\"), so dashed/dotted line styles map to\nthe matching QGIS line style instead of a generic dash. Found by\nthe headless QGIS 3.34 integration drive (16/16 scenarios passed).\n2.27.0 - Vector Layers: styled pull + push-as-draft\n- New \"Vector Layers\" entry in the Data Sync tab. Pick any vector\nlayer uploaded to geodb.io (geology units, faults, targets, ...)\nand pull it into QGIS with its styling translated to a native\nQGIS renderer - single, categorized and graduated styles map to\nthe matching QGIS renderer on the original attributes; fill\npatterns translate to the nearest QGIS fill style. Layers styled\nby the geoDB lithology/alteration/formation catalogs render with\ntheir catalog colors and legend labels.\n- Pull is always full resolution - geometry is never simplified,\nso an edit round trip cannot degrade untouched features.\n- Push uploads your edited copy back as a NEW DRAFT layer on the\nserver (the published layer is never modified from QGIS); review\nand promote the draft on the web. A snapshot diff detects whether\nanything actually changed - unchanged layers report \"nothing to\npush\" without touching the server. Your current QGIS symbology\ntravels with the draft.\n2.26.0 - Stay signed in + Data Sync tab refresh\n- Login credentials now actually persist. Previously a failed session\nrestore for ANY reason (offline at QGIS startup, a transient network\nerror) deleted the stored token, username and password; now only a\nserver-rejected password clears the saved password, and transient\nerrors keep everything. If the saved token has expired the plugin\nsilently re-authenticates with the saved password instead of\nprompting again.\n- \"Remember my email\" and \"Save password\" now default to ON, and your\nchoice is remembered between sessions. Two-factor accounts can save\ntheir password too. Re-logging in with the save box unticked no\nlonger silently wipes a previously saved password mid-session.\n- Data Sync tab restyled: friendly data type names with descriptions\n(Land Holdings, Drill Collars, ...), a live inline status line while\na pull or push runs plus a color-coded result summary right in the\ntab (no more digging through the Log tab), and a per-project \"last\npulled / last pushed\" line for the selected data type. Fully\ntheme-aware in light and dark mode, consistent with the login and\nclaims styling.\n2.25.0 - Number & Rename fix: server ordering restored, simple offline fallback\n- \"Number & Rename Claims\" silently numbered nothing on the server\npath: the request sent sort_direction where the endpoint reads\ndirection, and the reply was parsed for ordered_claims where the\nendpoint returns claims. The empty result skipped Manual_FID\nassignment without an error, so renaming fell back to feature\ninsertion order - the scrambled / right-to-left numbering seen in\nthe field. The request/response now match the endpoint, and any\nempty or mismatched reply raises so the offline fallback runs.\n- The offline fallback is now deliberately simple (strict north-south\nthen west-east sort). The row-banding port added in 2.22.1 was\nremoved: the rotation-tolerant banding rule is maintained\nserver-side only, so the two implementations cannot drift apart.\n- When the simple offline ordering runs (offline or server error),\nthe plugin warns on the message bar that rotated blocks may be\nmisnumbered and to re-run Number & Rename when online.\n2.24.0 - Lead-file plotted claims + tri-state quarter-sections\n- New streaming layers for the lead-file claim plotting service:\n\"Public Plotted Claims\" (claims whose private window has elapsed) and\n\"My Plotted Claims\" (your own plots, including in-window private ones\nwith a days-remaining note). Only you ever see your private plots.\n- New \"Quarter-sections (tri-state)\" layer colors each quarter-section by\nplot state: unplotted (class-color fill), plotted (tier-styled outline),\nor mixed/partially-plotted (black diagonal hatch that survives\nblack-and-white filing-map prints and color-blindness). The state is\ncomputed on the server for the signed-in account, so a private plot\nnever leaks its existence to anyone else.\n- The plotted-claims layer also carries the derivation chain (reference\npoint to tie line to corners) with the parsed course labels, matching\nthe web map overlay.\n2.23.1 - Fix Windows crash in PLSS/Federal Lands/BLM claims streaming\n- QGIS could crash with a fatal access violation while panning or\nzooming with PLSS Grid, Federal Lands, or BLM Claims streaming\nenabled. Each background fetch built its own SSL context on its\nown thread; on Windows, building more than one at the same time\nraces inside Python's SSL layer and corrupts memory, which then\ncrashed somewhere unrelated (often the map renderer) shortly\nafter.\n- Fix: all three streaming layers now share one SSL context per\nplugin session, built once and reused, so concurrent background\nfetches can no longer race during setup. No behavior change to\nstreaming itself.\n2.23.0 - Arizona filing maps ready for e-recording\n- AZ filing maps now keep all content inside a 1 inch page margin,\nas required by the Arizona e-file platform. The layout is scaled\nuniformly, so proportions, map scale, and the scale bar all stay\ncorrect.\n- Claim corners on AZ filing maps now show as plain black dots\nwithout C1-C4 text. Corner identification is already covered by\nthe bearing and distance edge labels and the bearings narrative,\nso the text only added clutter.\n2.22.10 - Planned samples no longer overwrite existing ones\n- When you push a new batch of planned samples, the sequence numbers\nnow start after the highest one already in the project, so a fresh\nbatch can't overwrite samples that are already planned or assigned.\nThe confirmation and log show the start that was used (e.g. \"started\nat SS-025 to avoid existing samples\"). Requires the matching server\nupdate; on older servers the existing overwrite warning still applies.\n2.22.9 - Fix: sample-name field dropdown now populates on open\n- The \"Name field\" dropdown in Plan Field Samples was empty because\nit was only bound when the layer changed, not for the layer already\nshown when the dialog opens. It now populates immediately and\nre-syncs when you tick the option, so the layer's fields are always\nlisted.\n2.22.8 - Plan samples using your own names from a layer field\n- When pushing a point layer as planned samples, you can now tick\n\"Use a layer field for the sample name\" and pick an attribute\n(e.g. your own \"AK26-1001S\" IDs). Those become the sample names\nshown on the web dashboard and the mobile app map / collect page.\n- Off by default - sequence numbers are still generated for\nnavigation, and names stay blank for the field crew to scan as\nbefore. The chosen field is checked up front: blanks, duplicates\nand over-50-character values are flagged before anything is pushed.\n2.22.7 - Claim map title block + grid polish\n- Field and filing map title blocks: the company name and the map\ntype/name line below it (e.g. \"BMX Lode Claims - Field Map\") now\nauto-fit to a single line. Long names shrink just enough to stay\nlegible and never wrap to a second line.\n- The author line populates from the signed-in geoDB user's name\n(e.g. \"Elizabeth White\") instead of a fixed placeholder.\n- Coordinate grid: the eastern (right-side) labels now sit outside\nthe map in the page margin instead of inside the map frame.\n2.22.6 - SQL identifier hardening\n- Queries that must name a table chosen at runtime (the\nformat-specific metadata table, table drops) no longer assemble SQL\nfrom the table name. The metadata read uses a ready-made literal\nquery per format; the remaining identifier sites validate the name\nas a bare SQL identifier (shared quote_identifier helper) before\nuse, so a malformed name raises instead of reaching the database.\nClears the string-built-query pattern flagged by security scanners.\nNo behavior change for normal use.\n2.22.4 - Claim numbering fix on rotated blocks\n- \"Number & Rename Claims\" could number claims right-to-left / out of\norder when the claim block was rotated even slightly off north. Two\ncauses: the numbering UI never passed the API client, so it always\nused the local fallback; and that fallback (plus the server path it\nshould have used) sorted strictly by northing-then-easting, which\ninterleaves rows when a row's claims don't share an exact northing.\nNumbering now bands claims into rows first, then orders each row\nwest-to-east \u2014 top-to-bottom, left-to-right book order \u2014 matching\nhow grid generation already numbers. Serpentine ordering uses the\nsame row banding so the two never disagree.\n- Security: HTTP requests now go through a scheme-restricted opener (http/https only) for defense in depth.\n2.22.0 - Dark-mode compliance for QGIS 4\n- The plugin's UI hardcoded a light-theme color palette, so on\nQGIS 4's dark theme some text was low-contrast or invisible (most\nvisibly the login form, where input text rendered white-on-white).\nAll widget styling now flows through one palette-aware token layer\n(utils/theme.py) that detects light vs dark and resolves each color\naccordingly. Light mode is unchanged; dark mode is readable.\n- Semantic data colors (commodity/mineral swatches, map-feature and\nclaim-type fills, range-category colors) are intentionally\npreserved across both themes.\n2.21.2 - QGIS 4 (Qt6) Storage dialog crash fix\n- Configuring storage / pulling data crashed under QGIS 4 because\nQStandardPaths.DocumentsLocation and .TempLocation were still\nreferenced in their old unscoped form, which PyQt6 removed. These\nnow resolve through the existing Qt5/Qt6 compatibility shim.\n2.21.1 - QGIS 4 (Qt6) load-crash fix\n- The main dialog crashed on open under QGIS 4 because a few Qt\nenums were still referenced in their old unscoped form\n(QFrame.HLine, QFont.Bold, QSizePolicy.*), which PyQt6 removed.\nThese now resolve through the existing Qt5/Qt6 compatibility\nshim, so the plugin loads on QGIS 4 as well as 3.\n2.21.0 - Map Capture: resolution control + fix CRS-dependent distortion\n- New \"Resolution\" selector in the Project Files > Map Capture tab\n(Screen / High 2048 / Very high 4096 / Maximum 8192 px) with a\nlive estimated output size (W x H px and approx MB) that updates\nwith the current view and selection. Higher resolutions give\ncrisper web tiles; the longest edge is the target and the other\nedge is derived from the Web-Mercator extent so aspect is exact.\n- Fix: captured rasters were distorted when the project CRS was\nWGS84 (or a Web-Mercator alias) and undistorted only in UTM. The\nre-render into Web Mercator reused the native canvas pixel\ndimensions, whose aspect ratio differs from the Web-Mercator\nextent (Mercator stretches latitude by sec(phi)), so QGIS\nre-fit the extent and the reported bounds no longer matched the\nimage. The server's affine georeferencing then stretched it.\nEvery capture now renders through one path: reproject to\nEPSG:3857, size the image to the 3857 extent's aspect ratio, and\nreport the actual rendered extent as bounds. Correct at any\nproject CRS and latitude.\n2.20.0 - Stream Alaska state-land polygons from geodb.io\n- New \"Show AK State Lands (Streaming)\" toggle under Basemaps,\nalongside the existing Federal Lands toggle. Reuses the same\n/services/api/federal-lands/ endpoint with\nownership=state&state=AK, sourced from AK DNR's\nOwnership_StateLandAll FeatureServer (~22k polygons\nstatewide). Same QClaims access gate as federal lands.\n- Important for MTRSC siting: AK DNR's Sept-2022 fact sheet\nrequires witness posts on adjacent state land when a section\ncorner falls on private overlap. Surfacing the overlay live\nin QGIS lets the operator see those alternative monument\nsites at planning time.\n- Style: pale gold (#F5E6A1) single-category fill \u2014 matches\nthe staff PLSS preview map's state-land overlay and the\nMTRSC filing-map renderer's `state` category.\n2.19.7 - Drop ID/NM LM-typed stakes from Step-7 push (CP-2026-0059 final)\n- Idaho Code 47-602 and NMSA 69-3-1 require the Location Monument\nto be at a CORNER. Those states have no separate Location\nMonument stake \u2014 the LM is one of the four WP-typed corner\nstakes, identified via LandHolding.lm_corner. Pushing a\nstake_type='LM' for an ID/NM claim creates a stake at a\nregulatorily-invalid (non-corner) position; the resulting\nlocation notice cannot be filed.\n- Server stopped emitting these for ID/NM in production\n2026-05-07 (offset_lm waypoint removed, monument-overrides at\nnon-corner positions rejected). API serializer now rejects\ninbound LM stakes linked to ID/NM LandHoldings as a backstop.\n- This release adds the matching client-side filter: claims\nmanager's push_to_server drops 'discovery'-typed waypoints\nwhose claim is in ID/NM before they're formatted as stakes.\nStops the per-stake 400 chatter when an old QGIS project still\nhas a stale Monuments layer from a pre-2026-05-07 run; user\nsees a clean push instead. Filter only triggers when EVERY\nlinked claim is ID/NM \u2014 shared waypoints with at least one\nnon-ID/NM claim still go through (server validates per-link).\n- No behavior change for non-ID/NM states: NV/CA/AZ/WY/MT/CO/OR/\nWA/UT/AK/SD continue to push their discovery monuments\nnormally. Auto-LM placement for those states is unchanged.\n2.19.6 - Fix v2.19.5 reading State attribute from the wrong layer\n- v2.19.5's per-claim state lookup used `state.claims_layer` to read\nthe State attribute. That property resolves to the Initial Layout\npolygon layer (from Step 2), NOT the Lode Claims layer \u2014 Initial\nLayout has no State attribute, so the lookup always returned None,\nand `None in {ID, NM}` was False. Filter never fired. Every claim\nin the Monuments layer was sent through as an override regardless\nof state, and the server obediently re-stamped manual_override=True\non the same 155 RC claims (visible in pod logs as \"Manual LM\noverride applied \u2014 using ...\")\n- Fix: build a per-claim {name: state} lookup from the best\navailable source. Prefer state.processed_claims (in-memory dicts\nfrom the most recent server response \u2014 has 'state' per claim);\nfall back to scanning the project for a layer whose name starts\nwith \"Lode Claims\" and reading its State attribute. State has no\ntracked layer id for the Lode Claims layer, so this name-based\nsearch is the only reliable path\n2.19.5 - Skip ID/NM claims in monument_overrides capture\n- The plugin's read_monument_overrides_from_state reads ALL features\nfrom the QGIS Monuments layer and sends them to the server as\nuser-moved overrides (\"preserve these positions across regen\").\nFor ID and NM that flow has no legal use \u2014 those states require\nthe LM at a corner. Sending an override for an ID/NM claim made\nthe server stamp manual_override=True and re-emit the off-corner\nLM the v2.19.4 layer-clear was supposed to make impossible\n- Created a feedback loop on Joshua's Rock Creek RC re-walk:\nstale Monuments features \u2192 \"overrides\" pushed \u2192 server replays \u2192\nfresh-but-identical Monuments rendered \u2192 still 155 LMs\n- Fix: skip claims whose state is ID/NM in the override capture.\nState is read from the Lode Claims layer's `State` attribute\n(already populated by claims_layer_generator). Non-ID/NM states\n(NV/CA/AZ/WY/etc.) keep the override-preservation behavior\nunchanged\n2.19.4 - Always clear stale Monuments / Sideline / Endline layers on regen\n- The plugin's claims_layer_generator only created the Monuments,\nSideline Monuments, and Endline Monuments layers when the server\nresponse had non-empty data for them. After 2026-05-06's removal\nof the regulatorily-invalid Phase 3 slide-from-corner code, the\nserver correctly stopped emitting discovery monuments for ID/NM\nclaims. But the plugin's \"remove existing layers before regen\"\npass only matched layer names that were ALSO in the new response,\nso the old Monuments layer's 155 stale features (from yesterday's\nPhase-3 run) persisted in QGIS memory across re-walks\n- Step 6's _read_monument_positions_from_layers then read the stale\nfeatures and stamped them into state.processed_claims; the Step 7\npush wrote `discovery_monument` back into qclaims_data on 155\nLandHolding rows (Rock Creek CP-2026-0059) even though the new\nserver algorithm had decided not to place any. The pod-side\n[CLAIM_STAKE_LINKING] log lines reading \"discovery=yes\" for ID\nclaims were the visible signal\n- Fix: _remove_existing_layers now always includes the optional\nstate-dependent layers (Monuments / Sideline / Endline) in its\nremoval set, regardless of whether the new response contains\nentries for them. Missing entry in the new response now correctly\ntranslates to \"layer absent in project,\" not \"layer left as it\nwas last time.\" Side-effect cleanup of the Step 6 read path is\nimplicit: no layer means no features means no monument data\nmerged into the push.\n2.19.3 - Fix v2.19.2 rehydrate building invalid LandHolding geometry\n- Rebuilt corners only carried easting/northing (UTM), no lat/lon.\nclaims_manager._format_landholding falls back to building GeoJSON\nfrom `[c.get('lon'), c.get('lat')]` when no `geometry` field is\nset on the claim \u2014 but those keys were missing, so it shipped\n[[None, None], ...] to the server. OGR rejected all 711 LandHolding\nrows with \"Invalid geometry pointer returned from\nOGR_G_CreateGeometryFromJson\".\n- Fix: rehydrate now transforms each polygon ring vertex through a\nQgsCoordinateTransform from the layer's source CRS to EPSG:4326,\nstores both UTM (easting/northing) and WGS84 (lat/lon) on every\ncorner, and constructs `rotated_geometry` (WGS84 GeoJSON) and\n`rotated_geometry_utm` (UTM GeoJSON) directly so the format\nfunction doesn't take the fallback path at all.\n2.19.2 - Fix v2.19.1 rehydrate matching the wrong polygon layer\n- rehydrate_from_layers used substring \"Lode Claims\" matching, which\nalso matched the Initial Layout layer because its display name\n(\"Initial Layout [<prefix> Lode Claims]\") repeats the same suffix.\nOn RC-style multi-block projects the matcher picked Initial Layout\nfirst, then skipped every feature for missing fields, leaving\nprocessed_claims at zero and the buttons greyed.\n- Switched to startswith(\"Lode Claims\") so only the actual lode\nclaims layer matches.\n2.19.1 - Auto-rehydrate processed claims/waypoints after plugin reload\n- Plugin reloads (from upgrades) and QGIS restarts wiped the\nin-memory processed_claims and processed_waypoints lists, leaving\nthe wizard auto-resumed at Step 7 but with greyed-out Push and\nGenerate Maps buttons. The data was always available in the\nproject's QGIS layers (Lode Claims, Waypoints, Monuments,\nEndline/Sideline) \u2014 there was just no path to read it back into\nstate without forcing a server re-process\n- New ClaimsWizardState.rehydrate_from_layers() reconstructs both\nlists by walking the existing layers. Called automatically:\n(a) at the end of load_from_qgis_project when completed_steps\nindicates Step 6 has been finished, and\n(b) defensively on Step 6 and Step 7 on_enter when the in-memory\nlist is empty\n- Server-side data is authoritative for any field the rehydrate\npath can't reconstruct (PLSS, deadlines, calculated_acreage,\nstate_requirements_snapshot). The bulk-upsert merges qclaims_data,\nso re-pushing rehydrated claims preserves those server-side values\n- Same idempotent push semantics: re-pushing rehydrated claims is\na no-op against natural-key matched rows\n2.19.0 - Async push, \"Cluster LMs\" option, ID/NM placement fixes\n- Step 7 \"Push & Upload to Server\" now uses the async/poll pattern\nshipped in v2.16-v2.17 for the rest of the long claim-flow calls.\nFor 700+ claim blocks the previous synchronous bulk-upsert pair\n(ClaimStake bulk + LandHolding bulk) tripped Cloudflare's ~100s\norigin-read timeout and the request died at the proxy even though\nthe server was happily processing it\n- New consolidated server endpoint `/api/v2/claims/push-to-server/`\ncombines ClaimStake bulk + LandHolding bulk + document linking\ninto a single async job; progress dialog reports stage\n(pushing_stakes \u2192 pushing_landholdings \u2192 linking_documents \u2192\nfinalizing) with live percentage fed by per-record progress from\nthe server's bulk-upsert mixin\n- Document linking (previously a follow-up call after the push)\nis now folded into the same job \u2014 saves a round-trip and means\nthe success path is one HTTP request from the plugin's POV\n- Step 4 \"LM Corner\" dropdown gains a \"Cluster LMs (smart, ID/NM)\"\noption. When chosen, the server runs the shared-corner clustering\nalgorithm: 4-claim interior intersections cluster all 4 LMs at one\nshared corner so the crew surveys one point instead of four\nscattered ones. Prefers shared corners on public land; if no\ncorner is on public land, slides along an edge to the nearest\npublic-land position\n- Behavior change for ID/NM: explicit corner picks (1-4) are now\nhonored literally \u2014 the server no longer silently overrides the\nuser's choice with the algorithm. Cluster behavior is opt-in via\nthe new dropdown entry. (This was the 2026-05-05 phase-2 work\nthat wasn't actually firing the way users could see; it now does)\n- Backwards compatible: against an older server without the\nconsolidated push endpoint, the plugin transparently falls back\nto the legacy two-call path\n2.18.0 - Sticky monument overrides preserve user-moved LM positions\n- When the user drags a discovery monument in Step 5 (Adjust) and then\ntriggers a server-side regen \u2014 full preview rebuild OR LM-corner\nrotation \u2014 the moved positions are now read from the live monument\nlayer and sent up as monument_overrides in the request body. Server\nhonors the override (lm-placement-improvements server-side change,\n2026-05-05) and the user's move survives the rerun\n- Without this hand-off the algorithm recomputed a fresh LM and the\nuser's positioning was silently clobbered when the new layers were\nwritten back; this was the standing complaint that motivated the\nserver-side override-passthrough work\n- New shared helper processors/monument_overrides.py reads the\nmonuments layer, transforms UTM \u2192 WGS84 via the claims-layer CRS,\nand emits the {claim_name: {lat, lon, easting, northing}} dict\nshape the server's processing_options['monument_overrides']\ncontract expects\n- First-time generation (no monuments layer yet) sends an empty dict\n\u2192 no-op on the server, identical to pre-2.18 behavior\n2.17.0 - Async + progress for the rest of the long claim-flow endpoints\n- Async polling helper (X-Async-Capable: 1 + 202 + poll + progress dialog) is\nnow shared across the plugin: APIClient.post_async_capable handles the full\nhandshake so any caller \u2014 manager method or processor \u2014 can opt into async\nwith one line\n- Applied to: Process Claims (Step 6), Align Corners (Step 6 finalize), Validate\nClaim Grid (Step 6), and Generate Witness Points (Step 7). All now show the\nprogress dialog (stage / current claim / % bar / elapsed / Cancel) and survive\n1000-claim blocks comfortably\n- Pairs with server-side ~3x speed-up of the underlying processor so the typical\n1000-claim run finishes in ~110s server-side\n- Deferred (next release): Generate Documents, Generate Package Maps, and bulk\nClaimStake/LandHolding push \u2014 these need a different shape (chunking with\ncleanup_orphans semantics)\n2.16.1 - Live progress dialog for async claim operations\n- Progress dialog (stage, current claim name, % complete, elapsed time, Cancel button)\nnow appears for the duration of Generate Preview Layers (Step 5) and Update LM\nCorner \u2014 fed by per-claim progress fields the server reports in each poll response,\nso the user sees real progress instead of a frozen wizard\n- Cancel button cleanly abandons polling on the client; the server worker finishes\non its own and the result simply expires from cache (nothing to roll back)\n- Pairs with a server-side ~3x speed-up of the underlying processor (federal-lands\nunion pre-fetch always runs now), so a 714-claim block typically completes in\n~70-80s instead of ~190s \u2014 comfortably within the proxy timeout window\n2.16.0 - Async preview-layer generation for large claim blocks (700+ claims)\n- Plugin now opts into the server's async path on POST .../preview-layers/ and\n.../update-lm-corner-layers/ via X-Async-Capable header \u2014 the server kicks the\nheavy compute onto a background worker, returns 202 + a session id, and the\nplugin polls a status endpoint until the result is ready\n- Side-steps the ~100s Cloudflare origin-read timeout that was returning 502\nBad Gateway to the plugin even though the server was happily computing the\nfull 714-claim result over 3+ minutes server-side\n- Backwards compatible: legacy synchronous responses from older servers (or\nsmall block fast-paths) pass through the polling helper unchanged\n- 14-minute client-side wall-clock cap on polling so a stuck job surfaces a\nclean error instead of hanging forever\n2.15.1 - Long-running request reliability for large claim blocks\n- Set explicit 5-minute network transfer timeout on all API calls so QGIS does not\nabort the read mid-response on long-running endpoints (claims/preview-layers/\nfor 700+ claims, batch sync, etc.) \u2014 prevents the \"Server returned empty\nresponse\" failure mode where the body was truncated by a client-side timeout\n- Surface a real diagnostic error (status code, body length, body snippet) when\nthe server response is not parseable JSON instead of silently returning an\nempty dict \u2014 turns \"Server returned empty response\" into something actionable\n- Configurable via api.transfer_timeout_ms (default 300000)\n2.14.1 - Persistent filing-map annotations\n- Red reference tie line + bearing/distance label now persist as a GeoPackage-backed\nlayer so they remain visible when \"Lock Styles For Layers\" is unchecked in the\nprint layout composer (previously ephemeral memory layer \u2014 vanished on unlock)\n- Corner labels (C1/C2/C3/C4, with LM flag) persist the same way\n- Reference Point marker: when a map is regenerated and no persistent layer exists\nyet, the state reference points are written into the GeoPackage reference_points\ntable and loaded as a real layer \u2014 covers legacy QClaims GeoPackages and any\nwalkthrough that reaches Step 7 without Step 3 having persisted the points\n- Works on both entry paths: walkthrough (Step 7 Generate Maps) and legacy loader\n(one-click \"Load Claims & Generate Maps\" on older GeoPackages)\n2.14.0 - Persistent reference points, map-orientation control, NV legal landscape\n- Reference Points layer is now loaded into the Claims Workflow group on project revisit,\nso it remains visible when \"Lock Styles For Layers\" is toggled in the layout composer\n- Reference Points persist as a real GeoPackage-backed layer (not an ephemeral memory layer),\nso their symbology survives across map regenerations\n- Add Page Orientation dropdown on Step 7: Auto (default), Portrait, Landscape, or Both\n- Field Map and generic Filing Map honor the orientation choice; \"Both\" generates two layouts\nwith \"(Portrait)\"/\"(Landscape)\" suffixes so users can pick whichever fits the claim-block\nplus reference-point extent\n- NV state filing map now ships the 8.5\"x14\" legal sheet in BOTH portrait and landscape\norientations alongside the 36\"x24\" ARCH D sheet (NRS 517.040 does not mandate legal orientation)\n- New template: nv_state_filing_map_legal_landscape.qpt (14\"x8.5\" with vertical title block)\n- AZ state filing map continues to use its fixed template (unchanged)\n2.13.0 - Unified claims loader and AZ filing map polish\n- Claims loader now handles both old QClaims and new geodb-plugin GeoPackage formats\n- Single \"Load Claims & Generate Maps\" button loads either format without re-running the wizard\n- Extract format differences into ClaimsFormat spec so one loader class handles both\n- Build corners from claim polygon vertices (authoritative geometry) instead of corner_points table\n- New format reads reference points from claims_metadata JSON; legacy reads from References table\n- AZ generic Filing Map now reuses the polished AZ state filing map pipeline (same template and output)\n- AZ filing maps use claims-only extent; tie to survey monument conveyed via reference text\n- Add monument-only legend (Location + Endline Monuments) to AZ filing maps\n- Auto-fit variable-length text labels (bearings, monument, reference) so they wrap within the page\n- Scale-bar segment size now adapts to map scale so small claim groups get appropriate 50-250 ft segments\n- Move main scale bar and scale text into the title block so they don't overlap map content\n2.12.0 - Map capture Web Mercator re-render and claims UI streamlining\n- Re-render map captures in EPSG:3857 for better alignment on mobile basemaps\n- Send pixel_width and pixel_height with map capture uploads for server-side georeferencing\n- Merge Auto-Number and Rename Claims into single \"Number & Rename Claims\" button (Step 2 and Order widget)\n2.11.0 - Legacy claims loader, field map tweaks, and staff order improvements\n- Add one-click legacy claims loader: load old QClaims GeoPackages and generate all maps\n- New LegacyClaimsLoader processor reads qclaims_metadata, maps old table names, applies styling\n- Builds processed_claims from legacy corner points, monuments, and endline monuments\n- Parses QSecs/Meridian fields into PLSS dict for filing map labels\n- Creates Claims Waypoints layer with waypoint_type field from old Symbol values\n- Auto-generates field map, filing map, and AZ state filing map from legacy data\n- Remove corner point symbols and C1-C4 labels from field maps (waypoint labels suffice)\n- Resize landscape map template for better label clearance\n- Auto-populate claimant info and monument type from staff order data\n- Pass company address and default monument type through staff orders dialog\n2.10.0 - NV filing maps, document upload, and compatibility fixes\n- Generate dual NV state filing maps: 36\"x24\" ARCH D and 8.5\"x14\" legal size\n- Add claim inset diagram on NV filing maps showing corner numbering and dimensions\n- Filter waypoint labels on field maps: show corner/witness names only (LM symbols unlabeled)\n- Hide LM corner layer for states without separate discovery monuments (ID, NM)\n- Upload documents to claim packages on geodb.io (maps, filing receipts, etc.)\n- List and manage uploaded package documents from Step 7\n- Fix reference points layer creation in storage manager (auto-create table)\n- Add string typeName fallback for QgsField on Mac QGIS builds\n- Fix RuntimeError on deleted Qt C++ objects in step5 layer cleanup and reference map tool\n- Remove plain geodb.zip copy from packaging script (versioned zip only)\n- Multi-line NV filing map title for better readability\n2.9.0 - Claims GeoPackage server integration\n- Merge Push to Server into single Push & Upload button on Step 7\n- Auto-upload claims GeoPackage to server after pushing claims/stakes\n- Link uploaded GeoPackage (ProjectFile) to ClaimPackage on server\n- Save layer styles into GeoPackage before upload\n- Add server GeoPackage dropdown on Step 1 (pull claims GeoPackages from server)\n- Download and load server GeoPackages with metadata and claim_package_id restoration\n- Keep Browse Local and Create New options as fallback\n- Extract shared GeoPackage utilities (style save, download) to utils/gpkg_utils.py\n2.8.3 - Professional filing maps with surveyor's bearings and annotations\n- Add surveyor's bearing notation (N 45\u00b000' W) replacing cardinal directions on all filing maps\n- Add dimension annotations on claim polygon edges (1,500' and 600' labels)\n- Add reference tie line from survey monument to Corner No. 1 with bearing and distance\n- Add corner labels (C1-C4 with LM designation) on filing maps\n- Add reference point marker (red triangle) at survey monument location\n- Differentiate Filing Map from Field Map with metes & bounds text, monument info, and tie text\n- Fix AZ state filing map: add all annotation layers, proper surveyor's notation\n- Fix NV state filing map: add UTM coordinate grid, fix rotated reference label\n- Convert all scale bars from meters to feet (US mining claim standard)\n- Keep user on Step 7 after Finish so Generate Maps button remains accessible\n- Fix map extent to include reference point on filing maps (tie line visibility)\n2.8.2 - UI improvements, map generation, and security cleanup\n- Reorganize Basemaps widget into unified sections (Basemaps, PLSS Grid, Public Lands, MRDS)\n- Consolidate PLSS/Federal Lands streaming controls into Public Lands section\n- Add Federal Lands streaming with color legend (BLM yellow, Forest Service green)\n- Add verbose logging to Federal Lands streaming worker for diagnostics\n- Fix Federal Lands layer geometry type (Polygon to MultiPolygon) for mixed responses\n- Add Generate Maps button to Step 7 (claims print layouts for field and filing use)\n- Add ClaimsMapGenerator processor for print-ready QGIS layouts\n- Centralize all urlopen calls into safe_urlopen() wrapper with scheme validation\n- Eliminates Bandit S310 findings from all call sites (5 files cleaned up)\n2.7.1 - Fix CRS transform crashes and claims wizard Next button\n- Fix QgsCsException crash when BLM/PLSS streaming layers transform extent with wide-extent basemaps\n- Add extent_to_wgs84() utility that clamps to CRS valid bounds before transforming\n- Apply safe transform to all 4 bounding box transform sites (BLM, PLSS, basemaps PLSS/MRDS)\n- Fix Step 6 (Finalize) Next button permanently disabled after processing and doc generation\n- Remove redundant tos_accepted/access_info validation from Step 6 (already validated in Step 1)\n- Persist tos_accepted in GeoPackage metadata for proper resume across sessions\n- Add conflict check before pushing planned samples (warns before overwriting existing records)\n2.7.0 - Claims workflow layer group consistency and auto-resume\n- Unify all claims layer group management under shared utility (get_or_create_claims_group)\n- All wizard steps now use the same \"Claims Workflow [XX Lode Claims]\" group\n- Add Claim Name Prefix field to Step 1 (used for GeoPackage filename and group naming)\n- Auto-suggest GeoPackage filename from prefix (e.g. GE_claims.gpkg)\n- Auto-resume wizard to next incomplete step when reopening a previous project\n- Resume dialog shows completed steps and offers to continue or start from Step 1\n- Step indicators still allow jumping to any completed step\n- Remove duplicate _add_layer_to_claims_group implementations across files\n2.6.2 - Streamline claims wizard finish flow\n- Remove redundant Download Documents button from Step 7\n- Finish button now opens Claim Packages page in browser and returns to Sync Data tab\n2.6.1 - Fix claims wizard step indicator and waypoint layer tracking\n- Fix off-by-one in step indicator (completed steps showed green on wrong step)\n- Fix step indicators not updating to gray when going back invalidates downstream steps\n- Fix step circle showing checkmark instead of number when navigating back to current step\n- Fix connector line coloring between steps\n- Add confirmation dialog when Back button or step click would invalidate completed steps\n- Fix Step 7 waypoints layer fallback picking wrong claim block in multi-block projects\n- Fix Step 6 monument adjustment updating wrong waypoints layer in multi-block projects\n2.6.0 - Code audit, pay-per-claim wizard, and refactoring\n- Add pay-per-claim 3-step wizard (Setup, Layout, Order) with Stripe checkout\n- Dynamic wizard step rebuild based on user access level (enterprise vs pay-per-claim)\n- Fix broken submit_order call in claims_order_widget (migrated to create_checkout_session)\n- Fix Project.company AttributeError in UserContext.to_dict() serialization\n- Fix null_geom_count double-counting geometry parse failures in layer_processor\n- Rename PermissionError to APIPermissionError to avoid shadowing Python built-in\n- Extract shared utilities: geometry.py, crs_utils.py, format_helpers.py\n- Centralize claims endpoint URL building in config.get_claims_url()\n- Fix SQLite connection resource leaks in claims_storage_manager (contextlib.closing)\n- Fix QNetworkReply memory leak in API client timeout path\n- Remove ~15 unused methods and 2 dead modules (api_response.py, photo_cache.py)\n- Replace print() calls with proper logger throughout codebase\n- Add claims_pushed state tracking with double-push warning in Step 7\n- Add layer cleanup on wizard reset and step re-entry\n2.5.0 - Claims Wizard & UI Improvements\n- Fix claims layer ownership tracking to prevent cross-group layer collisions\n- Use session-based layer IDs instead of name matching in Step 5/Step 6\n- Fix combo box signal blocking during refresh to prevent state corruption\n- Add project name suffix to Claims Workflow layer group name\n- Use server-provided sequence_number for location monument naming\n- Style QComboBox dropdown menus across all claims and assay dialogs\n- Add URL scheme validation for BLM and PLSS streaming requests\n2.4.3 - Qt6 Method Compatibility\n- Replace deprecated .exec_() with .exec() across all dialogs and event loops\n- Ensures forward compatibility with Qt6 / QGIS 4.0+\n2.4.2 - Cross-Version Compatibility (QGIS 3.36 / 3.38+ / 4.0)\n- Fix QgsField TypeError across all QGIS versions (3.36, 3.38+, 4.0) with runtime probe\n- Fix Qt enum compatibility for QGIS 4.0 (Qt.DashLine, Qt.Checked, QFrame.HLine, etc.)\n- Fix streaming layer crashes on project switch (wrapped C++ object deleted)\n- Fix PLSS grid streaming checkbox staying disabled after session restore\n- Add URL scheme validation for BLM and PLSS streaming requests (security hardening)\n- Centralized Qt5/Qt6 enum compatibility layer in utils/compat.py\n2.4.1 - Compatibility & Streaming Fixes\n- Add Qt5/Qt6 compatibility layer for QgsField types\n- Improve login error messaging\n- Add BLM claims manager and PLSS streaming manager\n- Basemaps widget and config updates\n2.3.1 - Toolbar Icon Fix\n- Fix missing toolbar icon (Qt resources module was not imported)\n2.3.0 - Claims & Stakes Sync Fix\n- Fix ClaimStakes not linking to ClaimPackage during push\n- Add claim_package field to ClaimStake schema for proper package scoping\n- Stakes now correctly appear under their ClaimPackage on the web dashboard\n2.2.2 - Code Quality & Bug Fixes\n- Fix division by zero when pulling model with no records\n- Remove unused imports and variables across codebase\n- Fix PEP 8 style issues (whitespace, line breaks, f-strings)\n- Pass Bandit security scan and Flake8 quality checks cleanly\n2.2.1 - Project Files & GeoPackage Sync\n- New \"Project Files\" tab with sub-tabs for Map Capture, Upload Files, and GeoPackage Sync\n- Upload georeferenced raster layers from QGIS to geodb.io server\n- GeoPackage sync: push/pull GeoPackage files with embedded styles\n- Improved world file generation with native CRS bounds support\n- Fix HiDPI/Retina display handling for map captures\n- Pre-select active layer in field work dialog\n- Security fixes: SQL injection prevention, URL scheme validation, safe XML parsing\n- Removed deprecated supportsQt6 metadata flag\n- Bug fixes and stability improvements\n2.1.1 - QGIS 4.0 Compatibility & Security Hardening\n- QGIS 4.0 / Qt6 compatibility (supports QGIS 3.0 through 4.99)\n- Security hardening of API client (request retry logic, removed debug exposure)\n- Bi-directional deletion sync with server\n- Deletion conflict detection (local changes vs server deletes)\n- Orphan cleanup for child records\n- Map canvas capture and georeferenced upload\n- GeoPackage storage option for persistent local data\n- Bug fixes and stability improvements\n2.1.0 - Major feature release\n- BC mineral claims workflow with 7-step wizard\n- Two-factor authentication (2FA) support\n- Photo viewer for drill photos and field notes\n- Staff order management interface\n- Basemaps widget for quick layer access\n- Structure model with geological symbology\n- GPX export for GPS devices\n- Fixed heap corruption crashes (QgsBlockingNetworkRequest)\n- Improved cross-platform compatibility\n2.0.0 - Major architectural rebuild\n- Modular design with separation of concerns\n- Improved error handling and logging\n- Progress feedback for long operations\n- Incremental data synchronization\n- Type-safe code with full type hints\n- Comprehensive documentation\n0.1 - Initial release", "external_deps": null, "download_url": "https://plugins.qgis.org/plugins/geodb/version/2.35.2/download/"}