Add forensics & analytical geolocation: resection, reverse-heading, horizon, tz-crosscheck, fingerprinting, batch triage/timeline#12
Open
cognis-digital wants to merge 4 commits into
Conversation
…eck, fingerprinting, batch triage/clustering, movement timeline Adds geolens.forensics (offline, stdlib-only) that multiplies the toolkit with defensive analytical geolocation, all additive to the public API: - Geodesy: haversine_km, initial_bearing, destination_point, resection (recover observer position from two landmark bearings, ~metre accuracy) - reverse_heading: true landmark bearing from pixel position + lens FOV (rectilinear projection, correct at frame edges) - Horizon cues: horizon_distance_km, max_visible_distance_km, is_peak_visible (refraction-corrected 'shot from here' falsification test) - timezone_crosscheck: EXIF local clock vs GPS-UTC vs GPS longitude band, flags edited timestamps / transplanted GPS - camera_fingerprint + fingerprint_consistency: tamper/splice signals across an image set (mixed makes, editing software, dimension drift) - cluster_locations + batch_triage: single-linkage spatial clustering, geotagged-vs-scrubbed folder triage - build_timeline + timeline_to_geojson: time-ordered movement timeline with per-leg distance/elapsed/implied-speed, exported as a GeoJSON track New CLI subcommands: resect, heading, horizon, tzcheck, fingerprint, triage, timeline (horizon/tzcheck/fingerprint exit 3 on a detected inconsistency). Two runnable offline demos (21, 22), docs/FORENSICS.md, README + DEMOS updates. Tests: 161 -> 205 (new tests/test_forensics.py + CLI-edge cases).
2 tasks
Demo scripts intentionally print the lat/lon being analyzed — geolocation output, the tool's purpose — which CodeQL's name heuristic misreads as clear-text logging of sensitive data. Analyze geolens/ (the package) and leave demos/tests/ports/integrations out via a codeql-config.yml.
…to user stdout, not a secret sink The py/clear-text-logging-sensitive-data query keys off lat/lon/location variable names and flags the CLI's own output (the product), not any real credential leak. Exclude that single query; all other CodeQL queries run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
geolens.forensics— an offline, standard-library-only layer of defensive analytical geolocation that multiplies what the toolkit can do for verification / OSINT / IR analysts. Everything is additive: the existing public API is unchanged and every new symbol is re-exported from thegeolenspackage.New capabilities
haversine_km,initial_bearing,destination_point, andresection(recover an observer position from two landmarks + the bearing to each; recovers a synthetic observer to within a few metres, with aresidual_kmquality figure).reverse_heading: true bearing to a landmark from its pixel position + lens FOV, using the rectilinear (pinhole) projection so frame edges are handled correctly.horizon_distance_km,max_visible_distance_km,is_peak_visible: refraction-corrected geometry for a "could this peak even be seen from here?" falsification test.timezone_crosscheck: EXIF local clock vs GPS-UTC → implied UTC offset → longitude band; flags an image whose GPS longitude is inconsistent with its own clock (edited timestamp / transplanted GPS).camera_fingerprint,fingerprint_consistency: tamper/splice signals across a set (mixed makes/models, editing-software tag, dimension drift).cluster_locations,batch_triage: single-linkage spatial clustering + geotagged-vs-scrubbed folder triage.build_timeline,timeline_to_geojson: time-ordered timeline with per-leg distance / elapsed / implied speed, exported as a GeoJSONPointseries +LineStringtrack.CLI
New subcommands:
resect,heading,horizon,tzcheck,fingerprint,triage,timeline.horizon/tzcheck/fingerprintexit3on a detected inconsistency (scriptable gate).Demos & docs
demos/21_resection_and_horizon.py— metadata-free geolocation + falsification.demos/22_batch_triage_timeline.py— folder → clusters + movement timeline (GeoJSON) + fingerprint tamper flag.docs/FORENSICS.md; README feature list + demo table +docs/DEMOS.mdupdated.Both demos run offline and exit 0 (
PYTHONUTF8=1on Windows).Tests
python -m pytest -q: 161 → 205 passing (newtests/test_forensics.py+ forensics CLI-edge cases). Resection accuracy, rectilinear reverse-heading, horizon falsification, timezone consistency/spoof detection, fingerprint flags, clustering, and timeline ordering/GeoJSON are all covered.