Andy Lee commited on
Commit
c7ab3f4
Β·
2 Parent(s): fc23f51 d79cd74

Merge remote-tracking branch 'origin/main' into qwen

Browse files
.streamlit/secrets.toml ADDED
File without changes
app.py CHANGED
@@ -2,13 +2,19 @@ import streamlit as st
2
  import json
3
  import os
4
  import time
5
- from io import BytesIO
6
- from PIL import Image
7
  from pathlib import Path
8
 
9
- from geo_bot import GeoBot, AGENT_PROMPT_TEMPLATE
10
  from benchmark import MapGuesserBenchmark
11
- from config import MODELS_CONFIG, get_data_paths, SUCCESS_THRESHOLD_KM, get_model_class
 
 
 
 
 
 
 
12
 
13
 
14
  # Simple API key setup
@@ -22,6 +28,24 @@ if "HF_TOKEN" in st.secrets:
22
  os.environ["HF_TOKEN"] = st.secrets["HF_TOKEN"]
23
 
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  def get_available_datasets():
26
  datasets_dir = Path("datasets")
27
  if not datasets_dir.exists():
@@ -36,54 +60,164 @@ def get_available_datasets():
36
 
37
 
38
  # UI Setup
39
- st.set_page_config(page_title="🧠 Omniscient - AI Geographic Analysis", layout="wide")
 
 
40
  st.title("🧠 Omniscient")
41
- st.markdown("### *The all-knowing AI that sees everything, knows everything*")
 
42
 
 
 
 
43
  # Sidebar
44
  with st.sidebar:
45
  st.header("Configuration")
46
 
47
- # Get available datasets and ensure we have a valid default
48
- available_datasets = get_available_datasets()
49
- default_dataset = available_datasets[0] if available_datasets else "default"
50
-
51
- dataset_choice = st.selectbox("Dataset", available_datasets, index=0)
52
- model_choice = st.selectbox("Model", list(MODELS_CONFIG.keys()))
53
- steps_per_sample = st.slider("Max Steps", 3, 20, 10)
54
- temperature = st.slider(
55
- "Temperature",
56
- 0.0,
57
- 2.0,
58
- 0.0,
59
- 0.1,
60
- help="Controls randomness in AI responses. 0.0 = deterministic, higher = more creative",
61
- )
62
 
63
- # Load dataset with error handling
64
- data_paths = get_data_paths(dataset_choice)
65
- try:
66
- with open(data_paths["golden_labels"], "r") as f:
67
- golden_labels = json.load(f).get("samples", [])
68
 
69
- st.info(f"Dataset '{dataset_choice}' has {len(golden_labels)} samples")
70
- if len(golden_labels) == 0:
71
- st.error(f"Dataset '{dataset_choice}' contains no samples!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  st.stop()
73
 
74
- except FileNotFoundError:
75
- st.error(
76
- f"❌ Dataset '{dataset_choice}' not found at {data_paths['golden_labels']}"
77
  )
78
- st.info("πŸ’‘ Available datasets: " + ", ".join(available_datasets))
79
- st.stop()
80
- except Exception as e:
81
- st.error(f"❌ Error loading dataset '{dataset_choice}': {str(e)}")
82
- st.stop()
83
 
84
- num_samples = st.slider(
85
- "Samples to Test", 1, len(golden_labels), min(3, len(golden_labels))
86
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  start_button = st.button("πŸš€ Start", type="primary")
89
 
@@ -93,7 +227,9 @@ if start_button:
93
  config = MODELS_CONFIG[model_choice]
94
  model_class = get_model_class(config["class"])
95
 
96
- benchmark_helper = MapGuesserBenchmark(dataset_name=dataset_choice)
 
 
97
  all_results = []
98
 
99
  progress_bar = st.progress(0)
@@ -106,10 +242,16 @@ if start_button:
106
  ) as bot:
107
  for i, sample in enumerate(test_samples):
108
  st.divider()
109
- st.header(f"Sample {i + 1}/{num_samples} - ID: {sample.get('id', 'N/A')}")
 
 
 
 
 
 
 
110
 
111
- # Load the sample location
112
- bot.controller.load_location_from_data(sample)
113
 
114
  # Create containers for UI updates
115
  sample_container = st.container()
@@ -290,3 +432,11 @@ if start_button:
290
  file_name=f"geo_results_{dataset_choice}_{model_choice}_{num_samples}samples.json",
291
  mime="application/json",
292
  )
 
 
 
 
 
 
 
 
 
2
  import json
3
  import os
4
  import time
5
+ import re
 
6
  from pathlib import Path
7
 
8
+ from geo_bot import GeoBot
9
  from benchmark import MapGuesserBenchmark
10
+ from config import (
11
+ MODELS_CONFIG,
12
+ get_data_paths,
13
+ SUCCESS_THRESHOLD_KM,
14
+ get_model_class,
15
+ DEFAULT_MODEL,
16
+ DEFAULT_TEMPERATURE,
17
+ )
18
 
19
 
20
  # Simple API key setup
 
28
  os.environ["HF_TOKEN"] = st.secrets["HF_TOKEN"]
29
 
30
 
31
+ def convert_google_to_mapcrunch_url(google_url):
32
+ """Convert Google Maps URL to MapCrunch URL format."""
33
+ try:
34
+ # Extract coordinates using regex
35
+ match = re.search(r"@(-?\d+\.\d+),(-?\d+\.\d+)", google_url)
36
+ if not match:
37
+ return None
38
+
39
+ lat, lon = match.groups()
40
+ # MapCrunch format: lat_lon_heading_pitch_zoom
41
+ # Using default values for heading (317.72), pitch (0.86), and zoom (0)
42
+ mapcrunch_url = f"http://www.mapcrunch.com/p/{lat}_{lon}_317.72_0.86_0"
43
+ return mapcrunch_url
44
+ except Exception as e:
45
+ st.error(f"Error converting URL: {str(e)}")
46
+ return None
47
+
48
+
49
  def get_available_datasets():
50
  datasets_dir = Path("datasets")
51
  if not datasets_dir.exists():
 
60
 
61
 
62
  # UI Setup
63
+ st.set_page_config(
64
+ page_title="🧠 Omniscient - Multiturn Geographic Intelligence", layout="wide"
65
+ )
66
  st.title("🧠 Omniscient")
67
+ st.markdown("""
68
+ ### *An all-seeing AI agent for geographic analysis and deduction*
69
 
70
+ Omniscient engages in a multi-turn reasoning process β€” collecting visual clues, asking intelligent questions, and narrowing down locations step by step.
71
+ Whether it's identifying terrain, interpreting signs, or tracing road patterns, this AI agent learns, adapts, and solves like a true geo-detective.
72
+ """)
73
  # Sidebar
74
  with st.sidebar:
75
  st.header("Configuration")
76
 
77
+ # Mode selection
78
+ mode = st.radio("Mode", ["Dataset Mode", "Online Mode"], index=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ if mode == "Dataset Mode":
81
+ # Get available datasets and ensure we have a valid default
82
+ available_datasets = get_available_datasets()
83
+ default_dataset = available_datasets[0] if available_datasets else "default"
 
84
 
85
+ dataset_choice = st.selectbox("Dataset", available_datasets, index=0)
86
+ model_choice = st.selectbox(
87
+ "Model",
88
+ list(MODELS_CONFIG.keys()),
89
+ index=list(MODELS_CONFIG.keys()).index(DEFAULT_MODEL),
90
+ )
91
+ steps_per_sample = st.slider("Max Steps", 1, 20, 10)
92
+ temperature = st.slider(
93
+ "Temperature",
94
+ 0.0,
95
+ 2.0,
96
+ DEFAULT_TEMPERATURE,
97
+ 0.1,
98
+ help="Controls randomness in AI responses. 0.0 = deterministic, higher = more creative",
99
+ )
100
+
101
+ # Load dataset with error handling
102
+ data_paths = get_data_paths(dataset_choice)
103
+ try:
104
+ with open(data_paths["golden_labels"], "r") as f:
105
+ golden_labels = json.load(f).get("samples", [])
106
+
107
+ st.info(f"Dataset '{dataset_choice}' has {len(golden_labels)} samples")
108
+ if len(golden_labels) == 0:
109
+ st.error(f"Dataset '{dataset_choice}' contains no samples!")
110
+ st.stop()
111
+
112
+ except FileNotFoundError:
113
+ st.error(
114
+ f"❌ Dataset '{dataset_choice}' not found at {data_paths['golden_labels']}"
115
+ )
116
+ st.info("πŸ’‘ Available datasets: " + ", ".join(available_datasets))
117
+ st.stop()
118
+ except Exception as e:
119
+ st.error(f"❌ Error loading dataset '{dataset_choice}': {str(e)}")
120
  st.stop()
121
 
122
+ num_samples = st.slider(
123
+ "Samples to Test", 1, len(golden_labels), min(3, len(golden_labels))
 
124
  )
125
+ else: # Online Mode
126
+ st.info("Enter a URL to analyze a specific location")
 
 
 
127
 
128
+ # Add example URLs
129
+ example_google_url = "https://www.google.com/maps/@37.8728123,-122.2445339,3a,75y,3.36h,90t/data=!3m7!1e1!3m5!1s4DTABKOpCL6hdNRgnAHTgw!2e0!6shttps:%2F%2Fstreetviewpixels-pa.googleapis.com%2Fv1%2Fthumbnail%3Fcb_client%3Dmaps_sv.tactile%26w%3D900%26h%3D600%26pitch%3D0%26panoid%3D4DTABKOpCL6hdNRgnAHTgw%26yaw%3D3.3576431!7i13312!8i6656?entry=ttu"
130
+ example_mapcrunch_url = (
131
+ "http://www.mapcrunch.com/p/37.882284_-122.269626_293.91_-6.63_0"
132
+ )
133
+
134
+ # Create tabs for different URL types
135
+ input_tab1, input_tab2 = st.tabs(["Google Maps URL", "MapCrunch URL"])
136
+
137
+ google_url = ""
138
+ mapcrunch_url = ""
139
+ golden_labels = None
140
+ num_samples = None
141
+
142
+ with input_tab1:
143
+ url_col1, url_col2 = st.columns([3, 1])
144
+ with url_col1:
145
+ google_url = st.text_input(
146
+ "Google Maps URL",
147
+ placeholder="https://www.google.com/maps/@37.5851338,-122.1519467,9z?entry=ttu",
148
+ key="google_maps_url",
149
+ )
150
+ st.markdown(
151
+ f"πŸ’‘ **Example Location:** [View in Google Maps]({example_google_url})"
152
+ )
153
+ if google_url:
154
+ mapcrunch_url_converted = convert_google_to_mapcrunch_url(google_url)
155
+ if mapcrunch_url_converted:
156
+ st.success(f"Converted to MapCrunch URL: {mapcrunch_url_converted}")
157
+ try:
158
+ match = re.search(r"@(-?\d+\.\d+),(-?\d+\.\d+)", google_url)
159
+ if not match:
160
+ st.error("Invalid Google Maps URL format")
161
+ st.stop()
162
+
163
+ lat, lon = match.groups()
164
+
165
+ golden_labels = [
166
+ {
167
+ "id": "online",
168
+ "lat": float(lat),
169
+ "lng": float(lon),
170
+ "url": mapcrunch_url_converted,
171
+ }
172
+ ]
173
+ num_samples = 1
174
+ except Exception as e:
175
+ st.error(f"Invalid Google Maps URL format: {str(e)}")
176
+ else:
177
+ st.error("Invalid Google Maps URL format")
178
+
179
+ with input_tab2:
180
+ st.markdown("πŸ’‘ **Example Location:**")
181
+ st.markdown(f"[View in MapCrunch]({example_mapcrunch_url})")
182
+ st.code(example_mapcrunch_url, language="text")
183
+ mapcrunch_url = st.text_input(
184
+ "MapCrunch URL", placeholder=example_mapcrunch_url, key="mapcrunch_url"
185
+ )
186
+ if mapcrunch_url:
187
+ try:
188
+ coords = mapcrunch_url.split("/")[-1].split("_")
189
+ lat, lon = float(coords[0]), float(coords[1])
190
+ golden_labels = [
191
+ {"id": "online", "lat": lat, "lng": lon, "url": mapcrunch_url}
192
+ ]
193
+ num_samples = 1
194
+ except Exception as e:
195
+ st.error(f"Invalid MapCrunch URL format: {str(e)}")
196
+
197
+ # Only stop if neither input is provided
198
+ if not google_url and not mapcrunch_url:
199
+ st.warning(
200
+ "Please enter a Google Maps URL or MapCrunch URL, or use the example above."
201
+ )
202
+ st.stop()
203
+ if golden_labels is None or num_samples is None:
204
+ st.warning("Please enter a valid URL.")
205
+ st.stop()
206
+
207
+ model_choice = st.selectbox(
208
+ "Model",
209
+ list(MODELS_CONFIG.keys()),
210
+ index=list(MODELS_CONFIG.keys()).index(DEFAULT_MODEL),
211
+ )
212
+ steps_per_sample = st.slider("Max Steps", 1, 20, 10)
213
+ temperature = st.slider(
214
+ "Temperature",
215
+ 0.0,
216
+ 2.0,
217
+ DEFAULT_TEMPERATURE,
218
+ 0.1,
219
+ help="Controls randomness in AI responses. 0.0 = deterministic, higher = more creative",
220
+ )
221
 
222
  start_button = st.button("πŸš€ Start", type="primary")
223
 
 
227
  config = MODELS_CONFIG[model_choice]
228
  model_class = get_model_class(config["class"])
229
 
230
+ benchmark_helper = MapGuesserBenchmark(
231
+ dataset_name=dataset_choice if mode == "Dataset Mode" else "online"
232
+ )
233
  all_results = []
234
 
235
  progress_bar = st.progress(0)
 
242
  ) as bot:
243
  for i, sample in enumerate(test_samples):
244
  st.divider()
245
+ st.header(f"Sample {i + 1}/{num_samples}")
246
+
247
+ if mode == "Online Mode":
248
+ # Load the MapCrunch URL directly
249
+ bot.controller.load_url(sample["url"])
250
+ else:
251
+ # Load from dataset as before
252
+ bot.controller.load_location_from_data(sample)
253
 
254
+ bot.controller.setup_clean_environment()
 
255
 
256
  # Create containers for UI updates
257
  sample_container = st.container()
 
432
  file_name=f"geo_results_{dataset_choice}_{model_choice}_{num_samples}samples.json",
433
  mime="application/json",
434
  )
435
+
436
+
437
+ def handle_tab_completion():
438
+ """Handle tab completion for the Google Maps URL input."""
439
+ if st.session_state.google_maps_url == "":
440
+ st.session_state.google_maps_url = (
441
+ "https://www.google.com/maps/@37.5851338,-122.1519467,9z?entry=ttu"
442
+ )
config.py CHANGED
@@ -31,6 +31,10 @@ BENCHMARK_CONFIG = {
31
  # MapCrunch options
32
  MAPCRUNCH_OPTIONS = {}
33
 
 
 
 
 
34
  # Model configurations
35
  MODELS_CONFIG = {
36
  "gpt-4o": {
 
31
  # MapCrunch options
32
  MAPCRUNCH_OPTIONS = {}
33
 
34
+ # Default settings
35
+ DEFAULT_MODEL = "gemini-2.5-pro"
36
+ DEFAULT_TEMPERATURE = 1.0
37
+
38
  # Model configurations
39
  MODELS_CONFIG = {
40
  "gpt-4o": {
datasets/{asia β†’ example}/golden_labels.json RENAMED
File without changes
datasets/example2/golden_labels.json ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "dataset_name": "example2",
4
+ "collection_date": "2025-06-12T15:26:27.073898",
5
+ "collection_options": {}
6
+ },
7
+ "samples": [
8
+ {
9
+ "id": "e958ec37-0b30-4b30-b508-df614acb489f",
10
+ "timestamp": "2025-06-12T15:25:22.208434",
11
+ "lat": 41.52785178236295,
12
+ "lng": 22.061235302695696,
13
+ "address": "Unknown",
14
+ "pano_id": "hB2IrvH7f4iapBJZ_jNMJg",
15
+ "pov": {
16
+ "heading": -201.27999999999997,
17
+ "pitch": 5,
18
+ "zoom": 1.0000039848465483
19
+ },
20
+ "url_slug": "41.527852_22.061235_-201.28_-5.00_0",
21
+ "thumbnail_path": "e958ec37-0b30-4b30-b508-df614acb489f.jpg"
22
+ },
23
+ {
24
+ "id": "8c047700-2775-4161-bfa5-9c5f966ee929",
25
+ "timestamp": "2025-06-12T15:25:25.564230",
26
+ "lat": 35.51112041872643,
27
+ "lng": 138.76733244706546,
28
+ "address": "Unknown",
29
+ "pano_id": "KSCuXhlMyISBw9Poh1hG8w",
30
+ "pov": {
31
+ "heading": 61.72000000000003,
32
+ "pitch": 5,
33
+ "zoom": 1.0000046104496552
34
+ },
35
+ "url_slug": "35.511120_138.767332_61.72_-5.00_0",
36
+ "thumbnail_path": "8c047700-2775-4161-bfa5-9c5f966ee929.jpg"
37
+ },
38
+ {
39
+ "id": "c0beb43d-e95d-4352-9d36-56aa6c903e7d",
40
+ "timestamp": "2025-06-12T15:25:28.972905",
41
+ "lat": 43.42554082467874,
42
+ "lng": -89.09498316077553,
43
+ "address": "Unknown",
44
+ "pano_id": "H3QYXtsn7NBQxjZep7whsQ",
45
+ "pov": {
46
+ "heading": 164.72000000000003,
47
+ "pitch": 5,
48
+ "zoom": 1.0000093225833766
49
+ },
50
+ "url_slug": "43.425541_-89.094983_164.72_-5.00_0",
51
+ "thumbnail_path": "c0beb43d-e95d-4352-9d36-56aa6c903e7d.jpg"
52
+ },
53
+ {
54
+ "id": "f0af2553-81cf-48a7-8557-ed4b437a0c9d",
55
+ "timestamp": "2025-06-12T15:25:32.389314",
56
+ "lat": 47.48390126215672,
57
+ "lng": 34.659670566007904,
58
+ "address": "Unknown",
59
+ "pano_id": "bfFQMztfnvuffg-_9NkXjQ",
60
+ "pov": {
61
+ "heading": -337.28,
62
+ "pitch": 5,
63
+ "zoom": 1.0000017337781582
64
+ },
65
+ "url_slug": "47.483901_34.659671_-337.28_-5.00_0",
66
+ "thumbnail_path": "f0af2553-81cf-48a7-8557-ed4b437a0c9d.jpg"
67
+ },
68
+ {
69
+ "id": "06c2d9c2-f765-4f2b-b9b1-5b93229dc0fc",
70
+ "timestamp": "2025-06-12T15:25:35.813919",
71
+ "lat": -34.63754161327788,
72
+ "lng": 118.09156096189146,
73
+ "address": "Unknown",
74
+ "pano_id": "PzTOFAXRN2xbwgjUqN4bpg",
75
+ "pov": {
76
+ "heading": -148.27999999999997,
77
+ "pitch": 5,
78
+ "zoom": 1.0000041033706084
79
+ },
80
+ "url_slug": "-34.637542_118.091561_-148.28_-5.00_0",
81
+ "thumbnail_path": "06c2d9c2-f765-4f2b-b9b1-5b93229dc0fc.jpg"
82
+ },
83
+ {
84
+ "id": "92beabfc-c50d-421e-a847-fd2cb145aac8",
85
+ "timestamp": "2025-06-12T15:25:39.191588",
86
+ "lat": 64.57213289684468,
87
+ "lng": -21.97630482318329,
88
+ "address": "Unknown",
89
+ "pano_id": "UojsE8YlVZ0N_TsBzTXkHw",
90
+ "pov": {
91
+ "heading": 90.72000000000003,
92
+ "pitch": 5,
93
+ "zoom": 1.0000091919376193
94
+ },
95
+ "url_slug": "64.572133_-21.976305_90.72_-5.00_0",
96
+ "thumbnail_path": "92beabfc-c50d-421e-a847-fd2cb145aac8.jpg"
97
+ },
98
+ {
99
+ "id": "fae54d62-755c-447f-ace2-7d7d9dcbab0a",
100
+ "timestamp": "2025-06-12T15:25:42.516009",
101
+ "lat": 32.34919407912315,
102
+ "lng": -64.71096298763197,
103
+ "address": "Unknown",
104
+ "pano_id": "CAoSF0NJSE0wb2dLRUlDQWdJREV1Tl9YMmdF",
105
+ "pov": {
106
+ "heading": 260.72,
107
+ "pitch": 5,
108
+ "zoom": 1.0000030548533054
109
+ },
110
+ "url_slug": "32.349194_-64.710963_260.72_-5.00_0",
111
+ "thumbnail_path": "fae54d62-755c-447f-ace2-7d7d9dcbab0a.jpg"
112
+ },
113
+ {
114
+ "id": "a086d72f-5c18-4895-a728-4262d565005f",
115
+ "timestamp": "2025-06-12T15:25:45.919449",
116
+ "lat": 34.880191512475136,
117
+ "lng": 138.1990659116743,
118
+ "address": "Unknown",
119
+ "pano_id": "CAoSFkNJSE0wb2dLRUlDQWdJRHE4NDJsWnc.",
120
+ "pov": {
121
+ "heading": 358.72,
122
+ "pitch": 5,
123
+ "zoom": 1.0000054942816385
124
+ },
125
+ "url_slug": "34.880192_138.199066_358.72_-5.00_0",
126
+ "thumbnail_path": "a086d72f-5c18-4895-a728-4262d565005f.jpg"
127
+ },
128
+ {
129
+ "id": "ea8fae71-8acd-4ba5-a016-3fb9d051c8ff",
130
+ "timestamp": "2025-06-12T15:25:49.337047",
131
+ "lat": 22.130721057935787,
132
+ "lng": 113.57874365739633,
133
+ "address": "Unknown",
134
+ "pano_id": "IZjDP8WGT4O3zju2hFiFCg",
135
+ "pov": {
136
+ "heading": -249.27999999999997,
137
+ "pitch": 5,
138
+ "zoom": 1.0000003495222285
139
+ },
140
+ "url_slug": "22.130721_113.578744_-249.28_-5.00_0",
141
+ "thumbnail_path": "ea8fae71-8acd-4ba5-a016-3fb9d051c8ff.jpg"
142
+ },
143
+ {
144
+ "id": "0730a5f2-a68b-4e7a-9f8d-877bd65b04ba",
145
+ "timestamp": "2025-06-12T15:25:52.704884",
146
+ "lat": 18.6634455460649,
147
+ "lng": -96.76220059003958,
148
+ "address": "Unknown",
149
+ "pano_id": "J9ZTNGHVQf4EBW2rCgaHaQ",
150
+ "pov": {
151
+ "heading": -5.279999999999973,
152
+ "pitch": 5,
153
+ "zoom": 1.0000057047491013
154
+ },
155
+ "url_slug": "18.663446_-96.762201_-5.28_-5.00_0",
156
+ "thumbnail_path": "0730a5f2-a68b-4e7a-9f8d-877bd65b04ba.jpg"
157
+ },
158
+ {
159
+ "id": "992ba13b-0ced-4a8f-b8ee-3e2f9ac14464",
160
+ "timestamp": "2025-06-12T15:25:56.187109",
161
+ "lat": 64.51234002155906,
162
+ "lng": -22.13983357174534,
163
+ "address": "Unknown",
164
+ "pano_id": "nayAVqmoufS1IQHDOtXK5g",
165
+ "pov": {
166
+ "heading": 204.72000000000003,
167
+ "pitch": 5,
168
+ "zoom": 1.0000082656900817
169
+ },
170
+ "url_slug": "64.512340_-22.139834_204.72_-5.00_0",
171
+ "thumbnail_path": "992ba13b-0ced-4a8f-b8ee-3e2f9ac14464.jpg"
172
+ },
173
+ {
174
+ "id": "83f086e9-2b3c-47c8-9611-557853313d73",
175
+ "timestamp": "2025-06-12T15:25:59.649986",
176
+ "lat": 49.18855106875811,
177
+ "lng": 18.715493968155048,
178
+ "address": "Unknown",
179
+ "pano_id": "X4_z3fyEkFf1TURoTEtTRw",
180
+ "pov": {
181
+ "heading": -285.28,
182
+ "pitch": 5,
183
+ "zoom": 1.0000014961409551
184
+ },
185
+ "url_slug": "49.188551_18.715494_-285.28_-5.00_0",
186
+ "thumbnail_path": "83f086e9-2b3c-47c8-9611-557853313d73.jpg"
187
+ },
188
+ {
189
+ "id": "11e0d5df-607f-4673-9075-6cb784949469",
190
+ "timestamp": "2025-06-12T15:26:03.006109",
191
+ "lat": 47.566063195512115,
192
+ "lng": 117.66840235174527,
193
+ "address": "Unknown",
194
+ "pano_id": "pmbqMP3wUN-y4UNF29-ijg",
195
+ "pov": {
196
+ "heading": -53.27999999999997,
197
+ "pitch": 5,
198
+ "zoom": 1.0000074643993226
199
+ },
200
+ "url_slug": "47.566063_117.668402_-53.28_-5.00_0",
201
+ "thumbnail_path": "11e0d5df-607f-4673-9075-6cb784949469.jpg"
202
+ },
203
+ {
204
+ "id": "35aad182-1f46-4ded-a7c0-f41663c1dbc6",
205
+ "timestamp": "2025-06-12T15:26:06.382239",
206
+ "lat": 39.85636978265199,
207
+ "lng": 38.22670052745333,
208
+ "address": "Unknown",
209
+ "pano_id": "YX0qC_q239NxWkz2rjYO2A",
210
+ "pov": {
211
+ "heading": 194.72000000000003,
212
+ "pitch": 5,
213
+ "zoom": 1.0000085095965745
214
+ },
215
+ "url_slug": "39.856370_38.226701_194.72_-5.00_0",
216
+ "thumbnail_path": "35aad182-1f46-4ded-a7c0-f41663c1dbc6.jpg"
217
+ },
218
+ {
219
+ "id": "6668b3fd-eefd-4d25-aa4a-7021a19d19c3",
220
+ "timestamp": "2025-06-12T15:26:09.783272",
221
+ "lat": 22.456568266194985,
222
+ "lng": 114.09923601594565,
223
+ "address": "Unknown",
224
+ "pano_id": "DM221xFUpWG9lY53LbL--Q",
225
+ "pov": {
226
+ "heading": -355.28,
227
+ "pitch": 5,
228
+ "zoom": 1.0000096482864165
229
+ },
230
+ "url_slug": "22.456568_114.099236_-355.28_-5.00_0",
231
+ "thumbnail_path": "6668b3fd-eefd-4d25-aa4a-7021a19d19c3.jpg"
232
+ },
233
+ {
234
+ "id": "2df0138c-dacf-4d89-9f23-9b095226f70f",
235
+ "timestamp": "2025-06-12T15:26:13.164542",
236
+ "lat": 38.46383428233303,
237
+ "lng": 35.16450386289184,
238
+ "address": "Unknown",
239
+ "pano_id": "yYdcfT5d7wr1sFM0be7AbQ",
240
+ "pov": {
241
+ "heading": -101.27999999999997,
242
+ "pitch": 5,
243
+ "zoom": 1.0000053534557005
244
+ },
245
+ "url_slug": "38.463834_35.164504_-101.28_-5.00_0",
246
+ "thumbnail_path": "2df0138c-dacf-4d89-9f23-9b095226f70f.jpg"
247
+ },
248
+ {
249
+ "id": "7a1c2e5a-8cde-4a44-9fdb-5142a26a001d",
250
+ "timestamp": "2025-06-12T15:26:16.508455",
251
+ "lat": -6.370108870806767,
252
+ "lng": -76.28528690259334,
253
+ "address": "Unknown",
254
+ "pano_id": "bDGZjPoLOS0J4FaKbCQi3Q",
255
+ "pov": {
256
+ "heading": 13.720000000000027,
257
+ "pitch": 5,
258
+ "zoom": 1.0000056924769267
259
+ },
260
+ "url_slug": "-6.370109_-76.285287_13.72_-5.00_0",
261
+ "thumbnail_path": "7a1c2e5a-8cde-4a44-9fdb-5142a26a001d.jpg"
262
+ },
263
+ {
264
+ "id": "add1ffdf-22ca-4e15-9061-12d4e4b70638",
265
+ "timestamp": "2025-06-12T15:26:19.889548",
266
+ "lat": -31.647905825412163,
267
+ "lng": -60.705529014729464,
268
+ "address": "Unknown",
269
+ "pano_id": "LfewarY8AHpdsRryIvxjVQ",
270
+ "pov": {
271
+ "heading": 169.72000000000003,
272
+ "pitch": 5,
273
+ "zoom": 1.0000043082285572
274
+ },
275
+ "url_slug": "-31.647906_-60.705529_169.72_-5.00_0",
276
+ "thumbnail_path": "add1ffdf-22ca-4e15-9061-12d4e4b70638.jpg"
277
+ },
278
+ {
279
+ "id": "0c93acf3-75cc-43c1-be9e-28e034c139ff",
280
+ "timestamp": "2025-06-12T15:26:23.261201",
281
+ "lat": 43.95405778584408,
282
+ "lng": 22.298469861096923,
283
+ "address": "Unknown",
284
+ "pano_id": "q_NGYfvHdH9mL4cyp3UjEQ",
285
+ "pov": {
286
+ "heading": 305.72,
287
+ "pitch": 5,
288
+ "zoom": 1.0000030120206056
289
+ },
290
+ "url_slug": "43.954058_22.298470_305.72_-5.00_0",
291
+ "thumbnail_path": "0c93acf3-75cc-43c1-be9e-28e034c139ff.jpg"
292
+ },
293
+ {
294
+ "id": "016d1183-d7a6-46a4-98f2-a97f62445b89",
295
+ "timestamp": "2025-06-12T15:26:26.696698",
296
+ "lat": 34.59326187516724,
297
+ "lng": 135.74317546771286,
298
+ "address": "Unknown",
299
+ "pano_id": "iiCKjrr3Zib0M5OYS5BV8g",
300
+ "pov": {
301
+ "heading": -279.28,
302
+ "pitch": 5,
303
+ "zoom": 1.0000047776936738
304
+ },
305
+ "url_slug": "34.593262_135.743175_-279.28_-5.00_0",
306
+ "thumbnail_path": "016d1183-d7a6-46a4-98f2-a97f62445b89.jpg"
307
+ }
308
+ ]
309
+ }
datasets/example3/golden_labels.json ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "dataset_name": "example3",
4
+ "collection_date": "2025-06-12T15:57:06.206331",
5
+ "collection_options": {}
6
+ },
7
+ "samples": [
8
+ {
9
+ "id": "197a5345-a9da-41e1-93c5-b46ad24e5363",
10
+ "timestamp": "2025-06-12T15:56:00.069960",
11
+ "lat": 32.450617168194135,
12
+ "lng": -114.69399063957216,
13
+ "address": "Libramiento Golfo de Sta Clara-Ejido La Islita, San Luis R\u00edo Colorado, Sonora",
14
+ "pano_id": "RwuCf43rrr5vnlEgH7uMHw",
15
+ "pov": {
16
+ "heading": -265.28,
17
+ "pitch": 5,
18
+ "zoom": 1.000000033789912
19
+ },
20
+ "url_slug": "32.450617_-114.693991_-265.28_-5.00_0",
21
+ "thumbnail_path": "197a5345-a9da-41e1-93c5-b46ad24e5363.jpg"
22
+ },
23
+ {
24
+ "id": "66f91dcf-3fe6-4962-bfe6-2de8a349d6f6",
25
+ "timestamp": "2025-06-12T15:56:03.857510",
26
+ "lat": -37.78214235746083,
27
+ "lng": 144.12300194368797,
28
+ "address": "1476 Ballan-Meredith Rd, Morrisons, Victoria",
29
+ "pano_id": "hXyohzqEx6F3Q7eSQ089Mw",
30
+ "pov": {
31
+ "heading": -22.279999999999973,
32
+ "pitch": 5,
33
+ "zoom": 1.0000055105094043
34
+ },
35
+ "url_slug": "-37.782142_144.123002_-22.28_-5.00_0",
36
+ "thumbnail_path": "66f91dcf-3fe6-4962-bfe6-2de8a349d6f6.jpg"
37
+ },
38
+ {
39
+ "id": "7c22a7fc-fa66-40cc-88fd-626b826e14af",
40
+ "timestamp": "2025-06-12T15:56:07.240175",
41
+ "lat": 61.90332655530213,
42
+ "lng": 25.33606097079652,
43
+ "address": "98 Tervaj\u00e4rventie, Central Finland",
44
+ "pano_id": "yYWVkowafmuAlOFKWCV1TA",
45
+ "pov": {
46
+ "heading": 156.72000000000003,
47
+ "pitch": 5,
48
+ "zoom": 1.0000044280956983
49
+ },
50
+ "url_slug": "61.903327_25.336061_156.72_-5.00_0",
51
+ "thumbnail_path": "7c22a7fc-fa66-40cc-88fd-626b826e14af.jpg"
52
+ },
53
+ {
54
+ "id": "0facf8d6-5bcf-41e0-931e-2585e177fb68",
55
+ "timestamp": "2025-06-12T15:56:10.614004",
56
+ "lat": -18.13971017041426,
57
+ "lng": -63.937036497382664,
58
+ "address": "7, Santa Cruz Department",
59
+ "pano_id": "ILV43CvgWyxYt5HTTieZ4Q",
60
+ "pov": {
61
+ "heading": 290.72,
62
+ "pitch": 5,
63
+ "zoom": 1.0000061861010834
64
+ },
65
+ "url_slug": "-18.139710_-63.937036_290.72_-5.00_0",
66
+ "thumbnail_path": "0facf8d6-5bcf-41e0-931e-2585e177fb68.jpg"
67
+ },
68
+ {
69
+ "id": "9b372f4e-ca87-481c-a4d0-c3a6c90dff12",
70
+ "timestamp": "2025-06-12T15:56:14.031494",
71
+ "lat": 39.28408711718923,
72
+ "lng": 22.84441276717771,
73
+ "address": "EO30, Decentralized Administration of Thessaly and Central Greece",
74
+ "pano_id": "TnZ8AiIDWLWyoLMtWvThPg",
75
+ "pov": {
76
+ "heading": -320.28,
77
+ "pitch": 5,
78
+ "zoom": 1.0000078610298728
79
+ },
80
+ "url_slug": "39.284087_22.844413_-320.28_-5.00_0",
81
+ "thumbnail_path": "9b372f4e-ca87-481c-a4d0-c3a6c90dff12.jpg"
82
+ },
83
+ {
84
+ "id": "6558ba29-9edc-4c66-9213-edb82e77cf77",
85
+ "timestamp": "2025-06-12T15:56:17.391786",
86
+ "lat": 57.728373123146845,
87
+ "lng": 11.654417090381687,
88
+ "address": "1 Tjolmenv\u00e4gen, \u00d6cker\u00f6, V\u00e4stra G\u00f6taland County",
89
+ "pano_id": "FUCNS8h6b1KdjbkqekrpKw",
90
+ "pov": {
91
+ "heading": -114.27999999999997,
92
+ "pitch": 5,
93
+ "zoom": 1.0000089987016267
94
+ },
95
+ "url_slug": "57.728373_11.654417_-114.28_-5.00_0",
96
+ "thumbnail_path": "6558ba29-9edc-4c66-9213-edb82e77cf77.jpg"
97
+ },
98
+ {
99
+ "id": "ed167213-4364-40ae-80ee-78bf63480b9c",
100
+ "timestamp": "2025-06-12T15:56:20.754401",
101
+ "lat": -14.333745187624173,
102
+ "lng": -170.720756044093,
103
+ "address": "Rte 014, Tafuna, Western District",
104
+ "pano_id": "bUeapV3I_9VGBhumXlk2Tw",
105
+ "pov": {
106
+ "heading": 151.72000000000003,
107
+ "pitch": 5,
108
+ "zoom": 1.000005537590412
109
+ },
110
+ "url_slug": "-14.333745_-170.720756_151.72_-5.00_0",
111
+ "thumbnail_path": "ed167213-4364-40ae-80ee-78bf63480b9c.jpg"
112
+ },
113
+ {
114
+ "id": "41734c39-d109-4c5c-a939-82fcadfadbdf",
115
+ "timestamp": "2025-06-12T15:56:24.184911",
116
+ "lat": 45.86505410116751,
117
+ "lng": 15.519019308411098,
118
+ "address": "Pokopali\u0161\u010de Bu\u0161e\u010da vas",
119
+ "pano_id": "CAoSFkNJSE0wb2dLRUlDQWdJQ0VpYWVtWlE.",
120
+ "pov": {
121
+ "heading": 326.72,
122
+ "pitch": 5,
123
+ "zoom": 1.0000074031092103
124
+ },
125
+ "url_slug": "45.865054_15.519019_326.72_-5.00_0",
126
+ "thumbnail_path": "41734c39-d109-4c5c-a939-82fcadfadbdf.jpg"
127
+ },
128
+ {
129
+ "id": "04f77afb-4b62-4d27-ae04-69f72b47cd30",
130
+ "timestamp": "2025-06-12T15:56:28.265166",
131
+ "lat": 53.210286076785295,
132
+ "lng": -114.86431799288032,
133
+ "address": "AB-22, Buck Creek, Alberta",
134
+ "pano_id": "RfHJ9zAVgKGNzIAqHfk8rA",
135
+ "pov": {
136
+ "heading": -134.27999999999997,
137
+ "pitch": 5,
138
+ "zoom": 1.0000034294812554
139
+ },
140
+ "url_slug": "53.210286_-114.864318_-134.28_-5.00_0",
141
+ "thumbnail_path": "04f77afb-4b62-4d27-ae04-69f72b47cd30.jpg"
142
+ },
143
+ {
144
+ "id": "e3141a38-fb2d-45a8-8f3a-4c26018720e4",
145
+ "timestamp": "2025-06-12T15:56:31.850499",
146
+ "lat": 57.66292577014665,
147
+ "lng": 27.24427273260464,
148
+ "address": "M\u00f6ldre, V\u00f5ru County",
149
+ "pano_id": "vvKr0wNXF5WfS1lOq1IIxw",
150
+ "pov": {
151
+ "heading": 44.72000000000003,
152
+ "pitch": 5,
153
+ "zoom": 1.000000124614534
154
+ },
155
+ "url_slug": "57.662926_27.244273_44.72_-5.00_0",
156
+ "thumbnail_path": "e3141a38-fb2d-45a8-8f3a-4c26018720e4.jpg"
157
+ },
158
+ {
159
+ "id": "1eea0ce4-3332-4096-982b-37e97772e105",
160
+ "timestamp": "2025-06-12T15:56:35.316086",
161
+ "lat": -3.681535588587605,
162
+ "lng": -80.19932740757173,
163
+ "address": "24250 TU-101, Matapalo, Tumbes",
164
+ "pano_id": "48w450euvqIfAVQ7R3HLng",
165
+ "pov": {
166
+ "heading": 295.72,
167
+ "pitch": 5,
168
+ "zoom": 1.0000097574696656
169
+ },
170
+ "url_slug": "-3.681536_-80.199327_295.72_-5.00_0",
171
+ "thumbnail_path": "1eea0ce4-3332-4096-982b-37e97772e105.jpg"
172
+ },
173
+ {
174
+ "id": "e49be483-24e8-47ef-bf01-77dcfcb5d2d4",
175
+ "timestamp": "2025-06-12T15:56:38.725810",
176
+ "lat": -14.279133596130174,
177
+ "lng": -170.55687001529134,
178
+ "address": "Route 119, Aunu\u02bbu, AS 96799",
179
+ "pano_id": "TpeB7isFtiuumh6Eh15ZcA",
180
+ "pov": {
181
+ "heading": -265.28,
182
+ "pitch": 5,
183
+ "zoom": 1.0000006336487888
184
+ },
185
+ "url_slug": "-14.279134_-170.556870_-265.28_-5.00_0",
186
+ "thumbnail_path": "e49be483-24e8-47ef-bf01-77dcfcb5d2d4.jpg"
187
+ },
188
+ {
189
+ "id": "c5a611d5-29d2-4a83-b00d-1ed7df76869f",
190
+ "timestamp": "2025-06-12T15:56:42.149170",
191
+ "lat": 31.800383498252334,
192
+ "lng": 35.24268946547305,
193
+ "address": "Moqatel, Jerusalem, Jerusalem District",
194
+ "pano_id": "1VidmzHWGOrCkkidLLWF3Q",
195
+ "pov": {
196
+ "heading": -159.27999999999997,
197
+ "pitch": 5,
198
+ "zoom": 1.0000062558576592
199
+ },
200
+ "url_slug": "31.800383_35.242689_-159.28_-5.00_0",
201
+ "thumbnail_path": "c5a611d5-29d2-4a83-b00d-1ed7df76869f.jpg"
202
+ },
203
+ {
204
+ "id": "6dd669f4-2f13-4909-a480-9708a23cd80f",
205
+ "timestamp": "2025-06-12T15:56:45.579437",
206
+ "lat": 51.29578341353695,
207
+ "lng": 12.500988457395495,
208
+ "address": "Thensa",
209
+ "pano_id": "CAoSF0NJSE0wb2dLRUlDQWdJREQyZUtxbVFF",
210
+ "pov": {
211
+ "heading": -42.27999999999997,
212
+ "pitch": 5,
213
+ "zoom": 1.0000073719182492
214
+ },
215
+ "url_slug": "51.295783_12.500988_-42.28_-5.00_0",
216
+ "thumbnail_path": "6dd669f4-2f13-4909-a480-9708a23cd80f.jpg"
217
+ },
218
+ {
219
+ "id": "4f76d721-c2ec-4dc4-9485-e542d70ccf5c",
220
+ "timestamp": "2025-06-12T15:56:48.982692",
221
+ "lat": 58.32519714026791,
222
+ "lng": 26.777231622290483,
223
+ "address": "5 Palupealse, Aardlapalu, Tartu County",
224
+ "pano_id": "WUUzxDv8tWsNfGv28OGIeA",
225
+ "pov": {
226
+ "heading": 206.72000000000003,
227
+ "pitch": 5,
228
+ "zoom": 1.0000007116201164
229
+ },
230
+ "url_slug": "58.325197_26.777232_206.72_-5.00_0",
231
+ "thumbnail_path": "4f76d721-c2ec-4dc4-9485-e542d70ccf5c.jpg"
232
+ },
233
+ {
234
+ "id": "23a2f011-371a-48ed-bed7-254e8beefff3",
235
+ "timestamp": "2025-06-12T15:56:52.355563",
236
+ "lat": 27.53069417681522,
237
+ "lng": 90.1727287722609,
238
+ "address": "Trashigang-Semtokha Hwy, Wangdue Phodrang",
239
+ "pano_id": "1xZ7zVnYVh1f-hN4Xo_xFA",
240
+ "pov": {
241
+ "heading": 304.72,
242
+ "pitch": 5,
243
+ "zoom": 1.0000081048518055
244
+ },
245
+ "url_slug": "27.530694_90.172729_304.72_-5.00_0",
246
+ "thumbnail_path": "23a2f011-371a-48ed-bed7-254e8beefff3.jpg"
247
+ },
248
+ {
249
+ "id": "af61d989-8751-4c07-820c-8b35ffd0f2ae",
250
+ "timestamp": "2025-06-12T15:56:55.722548",
251
+ "lat": 5.287167713224647,
252
+ "lng": 103.06979234400693,
253
+ "address": "Lorong Bunga Raya, Kuala Terengganu, Terengganu",
254
+ "pano_id": "Pktsz31ZAWkJ-R1Ixesabw",
255
+ "pov": {
256
+ "heading": -178.27999999999997,
257
+ "pitch": 5,
258
+ "zoom": 1.0000068048105129
259
+ },
260
+ "url_slug": "5.287168_103.069792_-178.28_-5.00_0",
261
+ "thumbnail_path": "af61d989-8751-4c07-820c-8b35ffd0f2ae.jpg"
262
+ },
263
+ {
264
+ "id": "484ba34d-e072-4cb1-81b8-b1a4af8f36e9",
265
+ "timestamp": "2025-06-12T15:56:59.179328",
266
+ "lat": 45.95418096151833,
267
+ "lng": 5.379404630232549,
268
+ "address": "Amb\u00e9rieu-en-Bugey, Auvergne-Rh\u00f4ne-Alpes",
269
+ "pano_id": "AhkPs6oryerDdiRpLzRrDg",
270
+ "pov": {
271
+ "heading": 90.72000000000003,
272
+ "pitch": 5,
273
+ "zoom": 1.000005463895491
274
+ },
275
+ "url_slug": "45.954181_5.379405_90.72_-5.00_0",
276
+ "thumbnail_path": "484ba34d-e072-4cb1-81b8-b1a4af8f36e9.jpg"
277
+ },
278
+ {
279
+ "id": "720334f9-6332-4438-bcd2-68e0b464bb65",
280
+ "timestamp": "2025-06-12T15:57:02.582946",
281
+ "lat": 25.590547334531223,
282
+ "lng": 55.77315301790442,
283
+ "address": "E311, Al Raafah, Ras Al Khaimah",
284
+ "pano_id": "XNQCCNZ7aSxDPKeOoBaBYA",
285
+ "pov": {
286
+ "heading": 338.72,
287
+ "pitch": 5,
288
+ "zoom": 1.000001329133932
289
+ },
290
+ "url_slug": "25.590547_55.773153_338.72_-5.00_0",
291
+ "thumbnail_path": "720334f9-6332-4438-bcd2-68e0b464bb65.jpg"
292
+ },
293
+ {
294
+ "id": "d19dbe06-9b1a-4639-8d02-b21d2f87e8f4",
295
+ "timestamp": "2025-06-12T15:57:05.925602",
296
+ "lat": 69.97748674684166,
297
+ "lng": 19.105915802473216,
298
+ "address": "32 Fv302, Troms",
299
+ "pano_id": "CLIgvpLaAivFTsJqHVhsZg",
300
+ "pov": {
301
+ "heading": -129.27999999999997,
302
+ "pitch": 5,
303
+ "zoom": 1.0000075163842848
304
+ },
305
+ "url_slug": "69.977487_19.105916_-129.28_-5.00_0",
306
+ "thumbnail_path": "d19dbe06-9b1a-4639-8d02-b21d2f87e8f4.jpg"
307
+ }
308
+ ]
309
+ }
geo_bot.py CHANGED
@@ -6,13 +6,7 @@ from typing import Tuple, List, Optional, Dict, Any, Type
6
 
7
  from PIL import Image
8
  from langchain_core.messages import HumanMessage, BaseMessage
9
- from langchain_core.language_models.chat_models import BaseChatModel
10
- from langchain_openai import ChatOpenAI
11
- from langchain_anthropic import ChatAnthropic
12
- from langchain_google_genai import ChatGoogleGenerativeAI
13
-
14
  from hf_chat import HuggingFaceChat
15
-
16
  from mapcrunch_controller import MapCrunchController
17
 
18
  # The "Golden" Prompt (v7): add more descprtions in context and task
@@ -43,20 +37,20 @@ AGENT_PROMPT_TEMPLATE = """
43
 
44
  4. **Be Decisive:** A unique, definitive clue (full address, rare town name, etc.) β‡’ `GUESS` immediately.
45
 
46
- 5. **Final-Step Rule:** If **Remaining Steps = 1**, you **MUST** `GUESS`.
47
 
48
  ────────────────────────────────
 
 
 
49
  **Action History**
50
  {history_text}
51
 
52
  ────────────────────────────────
53
- **OUTPUT FORMAT**
54
-
55
- Return **one** JSON object wrapped in ```json … ```:
56
-
57
- **JSON Output Format:**
58
- Your response MUST be a valid JSON object wrapped in json ... .
59
- {{"reasoning": "...", "action_details": {{"action": "GUESS", "lat": <float>, "lon": <float>}} }}
60
  """
61
 
62
  BENCHMARK_PROMPT = """
 
6
 
7
  from PIL import Image
8
  from langchain_core.messages import HumanMessage, BaseMessage
 
 
 
 
 
9
  from hf_chat import HuggingFaceChat
 
10
  from mapcrunch_controller import MapCrunchController
11
 
12
  # The "Golden" Prompt (v7): add more descprtions in context and task
 
37
 
38
  4. **Be Decisive:** A unique, definitive clue (full address, rare town name, etc.) β‡’ `GUESS` immediately.
39
 
40
+ 5. **Final-Step Rule:** If **Remaining Steps = 1**, you **MUST** `GUESS` and you should carefully check the image and the surroundings.
41
 
42
  ────────────────────────────────
43
+ **Context & Task:**
44
+ Analyze your full journey history and current view, apply the Core Principles, and decide your next action in the required JSON format.
45
+
46
  **Action History**
47
  {history_text}
48
 
49
  ────────────────────────────────
50
+ **JSON Output Format:**More actions
51
+ Your response MUST be a valid JSON object wrapped in ```json ... ```.
52
+ - For exploration: `{{"reasoning": "...", "action_details": {{"action": "ACTION_NAME"}} }}`
53
+ - For the final guess: `{{"reasoning": "...", "action_details": {{"action": "GUESS", "lat": <float>, "lon": <float>}} }}`
 
 
 
54
  """
55
 
56
  BENCHMARK_PROMPT = """
main.py CHANGED
@@ -1,11 +1,5 @@
1
  import argparse
2
  import json
3
- import random
4
- from typing import Dict, Optional, List
5
-
6
- from langchain_openai import ChatOpenAI
7
- from langchain_anthropic import ChatAnthropic
8
- from langchain_google_genai import ChatGoogleGenerativeAI
9
 
10
  from geo_bot import GeoBot
11
  from benchmark import MapGuesserBenchmark
 
1
  import argparse
2
  import json
 
 
 
 
 
 
3
 
4
  from geo_bot import GeoBot
5
  from benchmark import MapGuesserBenchmark
mapcrunch_controller.py CHANGED
@@ -179,6 +179,22 @@ class MapCrunchController:
179
  base_actions.extend(["MOVE_FORWARD", "MOVE_BACKWARD"])
180
  return base_actions
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  def pan_view(self, direction: str, degrees: int = 45):
183
  """Pans the view using a direct JS call."""
184
  pov = self.driver.execute_script("return window.panorama.getPov();")
@@ -275,3 +291,13 @@ class MapCrunchController:
275
 
276
  def __exit__(self, exc_type, exc_val, exc_tb):
277
  self.close()
 
 
 
 
 
 
 
 
 
 
 
179
  base_actions.extend(["MOVE_FORWARD", "MOVE_BACKWARD"])
180
  return base_actions
181
 
182
+ def get_current_address(self) -> Optional[str]:
183
+ try:
184
+ address_element = self.wait.until(
185
+ EC.visibility_of_element_located(
186
+ (By.CSS_SELECTOR, SELECTORS["address_element"])
187
+ )
188
+ )
189
+ address_text = address_element.text.strip()
190
+ address_title = address_element.get_attribute("title") or ""
191
+ return (
192
+ address_title
193
+ if len(address_title) > len(address_text)
194
+ else address_text
195
+ )
196
+ except Exception:
197
+ return "Stealth Mode"
198
  def pan_view(self, direction: str, degrees: int = 45):
199
  """Pans the view using a direct JS call."""
200
  pov = self.driver.execute_script("return window.panorama.getPov();")
 
291
 
292
  def __exit__(self, exc_type, exc_val, exc_tb):
293
  self.close()
294
+
295
+ def load_url(self, url):
296
+ """Load a specific MapCrunch URL."""
297
+ try:
298
+ self.driver.get(url)
299
+ time.sleep(2) # Wait for the page to load
300
+ return True
301
+ except Exception as e:
302
+ print(f"Error loading URL: {e}")
303
+ return False
requirements.txt CHANGED
@@ -116,6 +116,7 @@ pytweening==1.2.0
116
  pytz==2025.2
117
  pyyaml==6.0.2
118
  pyzmq==26.2.0
 
119
  referencing==0.36.2
120
  regex==2024.9.11
121
  requests==2.32.3
 
116
  pytz==2025.2
117
  pyyaml==6.0.2
118
  pyzmq==26.2.0
119
+ pyperclip==1.8.2
120
  referencing==0.36.2
121
  regex==2024.9.11
122
  requests==2.32.3