File size: 4,654 Bytes
c590d67 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | from __future__ import annotations
from typing import Any
from urllib.parse import quote
from .evidence import make_evidence
from .models import EvidenceItem, SiteSelection
def build_earth_reference(
selection: SiteSelection,
observation_notes: str,
) -> tuple[dict[str, Any], list[EvidenceItem]]:
"""Create safe external satellite/map reference links without using Google as evidence."""
links: dict[str, str] = {}
evidence: list[EvidenceItem] = []
if selection.anchor_lat is not None and selection.anchor_lon is not None:
lat = f"{selection.anchor_lat:.6f}"
lon = f"{selection.anchor_lon:.6f}"
query = quote(f"{lat},{lon}")
links = {
"Google Maps reference": f"https://www.google.com/maps/search/?api=1&query={query}",
"Google Earth reference": f"https://earth.google.com/web/search/{query}",
"OpenStreetMap reference": f"https://www.openstreetmap.org/?mlat={lat}&mlon={lon}#map=17/{lat}/{lon}",
}
evidence.append(
make_evidence(
category="Satellite / Earth reference",
finding="External map and earth-imagery links were generated for visual reference only.",
source_name="Google Maps / Google Earth / OpenStreetMap links",
source_url=links["OpenStreetMap reference"],
source_type="external visual reference",
resolution_or_scope="anchor coordinate link; no imagery was processed by the app",
confidence="low",
limitation="External imagery may be outdated, cloud affected, differently aligned, or too coarse for plot-level evidence.",
design_implication="Use only to guide manual checking of visible roads, water, vegetation, built forms, and site edges.",
verification_needed="Confirm all visible satellite/map observations through site visit or uploaded KML/CAD/GeoJSON.",
output_label="site_visit_required",
)
)
if observation_notes.strip():
evidence.append(
make_evidence(
category="Satellite / Earth reference",
finding="User supplied satellite/Earth/site-observation notes.",
source_name="User observation",
source_url="",
source_type="user-provided",
resolution_or_scope="editable field/reference note",
confidence="medium",
limitation="Not independently verified by the app.",
design_implication="Use as a draft observation layer and verify with photos, site visit, or source drawings.",
verification_needed="Mark which notes came from Google Earth, site visit, faculty drawing, or local observation.",
output_label="user_input",
)
)
return {
"markdown": earth_reference_markdown(links, observation_notes),
"links": links,
}, evidence
def earth_reference_markdown(links: dict[str, str], observation_notes: str) -> str:
lines = [
"### Satellite / Earth Reference",
"",
"This section is a visual-reference workflow, not a satellite-analysis engine. The app does not extract facts from Google imagery. Use these links and notes to check visible site context, then verify on site.",
"",
]
if links:
lines.append("**External references**")
lines.extend(f"- [{label}]({url})" for label, url in links.items())
lines.append("")
else:
lines.append("- External reference links unavailable because no anchor coordinate is available.")
lines.append("")
lines.extend(
[
"**What to inspect manually**",
"",
"- visible trees and canopy",
"- water bodies, drainage lines, and wet edges",
"- existing structures, compound walls, and open ground",
"- access roads, informal paths, and construction nearby",
"- possible slope/drainage signs, shadowed areas, and surrounding heights",
"",
"**Safety note**",
"",
"- Satellite imagery may be outdated or too coarse for small plots.",
"- Google Earth/Maps references are not legal, cadastral, survey, or engineering evidence.",
"- Use KML/KMZ, CAD/DXF, GeoJSON, survey drawings, photos, and site visit to confirm observations.",
]
)
if observation_notes.strip():
lines.extend(["", "**User observation notes**", "", observation_notes.strip()])
return "\n".join(lines)
|