srmsoumya commited on
Commit
8364f3c
·
1 Parent(s): 3f9d3ae

fix: mixed templates are not generated because of stale parquet files

Browse files
dataset/README.md CHANGED
@@ -63,41 +63,90 @@ gazet-dataset export --config dataset/config.yaml # <1 min
63
  Use this when you need 10 K+ samples or want to use all countries. Modal
64
  distributes generation across many containers in parallel.
65
 
66
- **Step 1 One-time setup**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  ```bash
69
- modal setup # authenticate with Modal (one time)
70
- gazet-dataset modal-upload --config dataset/config.yaml # upload parquet data to Modal volume
71
  ```
72
 
 
 
73
  **Step 2 — Set run name and targets in `config.yaml`**
74
 
75
  ```yaml
76
- run_name: "v1"
77
 
78
  countries:
79
  - all
80
 
81
  sample_targets:
82
- adjacency: 1250
83
- containment: 1250
84
  # ... see config.yaml for all families
85
  ```
86
 
87
  **Step 3 — Run on Modal**
88
 
89
  ```bash
90
- gazet-dataset modal-generate --config dataset/config.yaml
91
  ```
92
 
93
- This builds relations, generates samples, validates, and exports — same as
94
- `full-pipeline` but distributed across 100 cloud containers.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
- If relations are already built from a previous run (same countries, same
97
- template version), skip rebuilding them:
98
 
99
  ```bash
100
- gazet-dataset modal-generate --config dataset/config.yaml --skip-relations
 
101
  ```
102
 
103
  ---
 
63
  Use this when you need 10 K+ samples or want to use all countries. Modal
64
  distributes generation across many containers in parallel.
65
 
66
+ Modal uses two volumes:
67
+
68
+ - `gazet-data` — read-only source parquets (Overture + Natural Earth). Populated
69
+ once by `modal-upload`.
70
+ - `gazet-intermediate` — entity inventories and relation tables built by the
71
+ pipeline. Regenerated on each run.
72
+
73
+ **Step 1 — One-time setup (only first time, or when source parquets change)**
74
+
75
+ ```bash
76
+ modal setup # authenticate
77
+ gazet-dataset modal-upload --config dataset/config.yaml # ~15 min, uploads data/ to gazet-data volume
78
+ ```
79
+
80
+ Verify:
81
 
82
  ```bash
83
+ modal volume ls gazet-data
84
+ # should show: overture/, natural_earth/, natural_earth_geoparquet/
85
  ```
86
 
87
+ Skip this step on subsequent runs — the volume persists across runs.
88
+
89
  **Step 2 — Set run name and targets in `config.yaml`**
90
 
91
  ```yaml
92
+ run_name: "v2" # bump this every time you regenerate from scratch
93
 
94
  countries:
95
  - all
96
 
97
  sample_targets:
98
+ adjacency: 1500
99
+ containment: 1200
100
  # ... see config.yaml for all families
101
  ```
102
 
103
  **Step 3 — Run on Modal**
104
 
105
  ```bash
106
+ gazet-dataset modal-generate --config dataset/config.yaml --fresh
107
  ```
108
 
109
+ This builds inventories + relations, generates samples across ~100 containers,
110
+ validates, and exports. Output lands in `dataset/output/runs/{run_name}/`.
111
+
112
+ Flags:
113
+
114
+ - `--fresh` overwrites `dataset/output/dataset_raw.jsonl` instead of appending.
115
+ - `--skip-inventory` reuses `{divisions_area,natural_earth}_inventory.parquet`
116
+ on the intermediate volume.
117
+ - `--skip-relations` reuses the seven `*_pairs.parquet` / `*_relations.parquet`
118
+ files on the intermediate volume. Only safe when countries and template
119
+ families are unchanged.
120
+
121
+ ### Fresh-start recipe (after template / SQL / prompt changes)
122
+
123
+ Always clear stale state so nothing from the previous run leaks in:
124
+
125
+ ```bash
126
+ # 1. Bump run_name in config.yaml (e.g. v1 -> v2)
127
+
128
+ # 2. Wipe the intermediate volume so inventories and relations are rebuilt
129
+ modal volume ls gazet-intermediate
130
+ # for each file shown:
131
+ modal volume rm gazet-intermediate <filename>
132
+
133
+ # 3. Remove local raw/validated files so nothing gets appended to
134
+ rm -f dataset/output/dataset_raw.jsonl dataset/output/dataset_validated.jsonl
135
+
136
+ # 4. Run the full pipeline
137
+ gazet-dataset modal-generate --config dataset/config.yaml --fresh
138
+ ```
139
+
140
+ You do NOT need to re-run `modal-upload` — source parquets on `gazet-data`
141
+ don't change.
142
+
143
+ ### Faster iteration (same templates, just more samples)
144
 
145
+ If relations + inventories are still valid from a previous run:
 
146
 
147
  ```bash
148
+ gazet-dataset modal-generate --config dataset/config.yaml \
149
+ --skip-inventory --skip-relations --fresh
150
  ```
151
 
152
  ---
dataset/config.yaml CHANGED
@@ -14,21 +14,23 @@ countries:
14
 
15
  # Sample generation targets per family
16
  # Relation limits are auto-calculated from these targets
 
 
17
  sample_targets:
18
  direct_lookup: 500
19
- adjacency: 750
20
  multi_adjacency: 300
21
- containment: 750
22
- intersection: 500
23
- buffer: 500
24
- chained: 750 # coastal / landlocked variants
25
- difference: 300
26
  border_corridor: 300
27
- set_operations: 500
28
- partial_selection: 500
29
- aggregation: 500
30
  window_function: 300
31
- attribute_filter: 300
32
 
33
  # Generation settings
34
  generation:
@@ -60,4 +62,4 @@ modal:
60
  # Run name — used to version exported splits so re-runs never overwrite previous data.
61
  # Change this whenever you regenerate from scratch (e.g. after template changes).
62
  # Exported files land in: output/runs/{run_name}/
63
- run_name: "v1"
 
14
 
15
  # Sample generation targets per family
16
  # Relation limits are auto-calculated from these targets
17
+ # Bumped families with many templates or mixed-source variants so each
18
+ # template_id gets enough coverage after uniform sampling + stratified split.
19
  sample_targets:
20
  direct_lookup: 500
21
+ adjacency: 1500 # 5 templates (adj_01..05)
22
  multi_adjacency: 300
23
+ containment: 1200 # 4 templates (contain_01..04)
24
+ intersection: 1200 # 4 templates (intersect_01..04)
25
+ buffer: 1200 # 5 templates (buffer_01..05)
26
+ chained: 2700 # 9 templates (chained_01..09)
27
+ difference: 900 # 2 templates, one is mixed (diff_02)
28
  border_corridor: 300
29
+ set_operations: 900
30
+ partial_selection: 1500 # 5 templates, one is mixed (partial_05)
31
+ aggregation: 750
32
  window_function: 300
33
+ attribute_filter: 600 # 3 templates (attr_01..03)
34
 
35
  # Generation settings
36
  generation:
 
62
  # Run name — used to version exported splits so re-runs never overwrite previous data.
63
  # Change this whenever you regenerate from scratch (e.g. after template changes).
64
  # Exported files land in: output/runs/{run_name}/
65
+ run_name: "v2"
dataset/scripts/build_relations.py CHANGED
@@ -229,7 +229,6 @@ def compute_cross_source_relations(
229
  'Terrain area', 'Island group', 'Peninsula', 'Strait',
230
  'Reef', 'Range/Mts', 'Depression'
231
  )
232
- LIMIT 500
233
  )
234
  SELECT
235
  d.id AS division_id,
@@ -464,6 +463,19 @@ RELATION_FUNCTIONS = {
464
  "common_neighbor": compute_common_neighbor_pairs,
465
  }
466
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
  def compute_single_relation(
469
  relation_type: str,
@@ -482,7 +494,7 @@ def compute_single_relation(
482
  f"Expected one of {list(RELATION_FUNCTIONS)}"
483
  )
484
  output_dir.mkdir(exist_ok=True, parents=True)
485
- output_path = output_dir / f"{relation_type}_pairs.parquet"
486
  df = _compute_and_save(compute_fn, countries, limit, output_path)
487
  return len(df)
488
 
@@ -511,16 +523,15 @@ def main(countries: list = None, relation_limits: dict = None):
511
  output_dir = Path(__file__).parent.parent / "intermediate"
512
  output_dir.mkdir(exist_ok=True, parents=True)
513
 
514
- # Define all relation tasks.
 
515
  # common_neighbor depends on adjacency_pairs so it runs after adjacency.
516
  tasks = [
517
- ("adjacency", compute_adjacency_pairs, relation_limits['adjacency'], output_dir / "adjacency_pairs.parquet"),
518
- ("containment", compute_containment_pairs, relation_limits['containment'], output_dir / "containment_pairs.parquet"),
519
- ("intersection", compute_intersection_pairs, relation_limits['intersection'], output_dir / "intersection_pairs.parquet"),
520
- ("cross_source", compute_cross_source_relations, relation_limits['cross_source'], output_dir / "cross_source_relations.parquet"),
521
- ("coastal_containment", compute_coastal_containment_pairs, relation_limits['coastal_containment'], output_dir / "coastal_containment_pairs.parquet"),
522
- ("landlocked_containment", compute_landlocked_containment_pairs, relation_limits['landlocked_containment'], output_dir / "landlocked_containment_pairs.parquet"),
523
- ("common_neighbor", compute_common_neighbor_pairs, relation_limits['common_neighbor'], output_dir / "common_neighbor_pairs.parquet"),
524
  ]
525
 
526
  # common_neighbor reads adjacency_pairs.parquet so it must run after
 
229
  'Terrain area', 'Island group', 'Peninsula', 'Strait',
230
  'Reef', 'Range/Mts', 'Depression'
231
  )
 
232
  )
233
  SELECT
234
  d.id AS division_id,
 
463
  "common_neighbor": compute_common_neighbor_pairs,
464
  }
465
 
466
+ # Single source of truth for the on-disk filename for each relation.
467
+ # Both local and Modal paths must use this so the sample generator loads
468
+ # the same file regardless of where the pipeline ran.
469
+ RELATION_FILENAMES = {
470
+ "adjacency": "adjacency_pairs.parquet",
471
+ "containment": "containment_pairs.parquet",
472
+ "intersection": "intersection_pairs.parquet",
473
+ "cross_source": "cross_source_relations.parquet",
474
+ "coastal_containment": "coastal_containment_pairs.parquet",
475
+ "landlocked_containment": "landlocked_containment_pairs.parquet",
476
+ "common_neighbor": "common_neighbor_pairs.parquet",
477
+ }
478
+
479
 
480
  def compute_single_relation(
481
  relation_type: str,
 
494
  f"Expected one of {list(RELATION_FUNCTIONS)}"
495
  )
496
  output_dir.mkdir(exist_ok=True, parents=True)
497
+ output_path = output_dir / RELATION_FILENAMES[relation_type]
498
  df = _compute_and_save(compute_fn, countries, limit, output_path)
499
  return len(df)
500
 
 
523
  output_dir = Path(__file__).parent.parent / "intermediate"
524
  output_dir.mkdir(exist_ok=True, parents=True)
525
 
526
+ # Define all relation tasks. Filenames come from RELATION_FILENAMES so
527
+ # local and Modal pipelines produce identically-named parquet files.
528
  # common_neighbor depends on adjacency_pairs so it runs after adjacency.
529
  tasks = [
530
+ (rel_type, RELATION_FUNCTIONS[rel_type], relation_limits[rel_type], output_dir / RELATION_FILENAMES[rel_type])
531
+ for rel_type in (
532
+ "adjacency", "containment", "intersection", "cross_source",
533
+ "coastal_containment", "landlocked_containment", "common_neighbor",
534
+ )
 
 
535
  ]
536
 
537
  # common_neighbor reads adjacency_pairs.parquet so it must run after
dataset/scripts/export_training_data.py CHANGED
@@ -65,21 +65,26 @@ def stratified_split(
65
  val_ratio: float = 0.1,
66
  seed: int = 42,
67
  ) -> Tuple[List[Dict], List[Dict], List[Dict]]:
68
- """Split stratified by task_family so every family is represented in each split."""
 
 
 
 
69
  random.seed(seed)
70
- by_family: Dict[str, List] = defaultdict(list)
71
  for s in samples:
72
- by_family[s["metadata"]["task_family"]].append(s)
 
73
 
74
  train, val, test = [], [], []
75
- for family_samples in by_family.values():
76
- random.shuffle(family_samples)
77
- n = len(family_samples)
78
  n_train = int(n * train_ratio)
79
  n_val = int(n * val_ratio)
80
- train.extend(family_samples[:n_train])
81
- val.extend(family_samples[n_train : n_train + n_val])
82
- test.extend(family_samples[n_train + n_val :])
83
 
84
  random.shuffle(train)
85
  random.shuffle(val)
 
65
  val_ratio: float = 0.1,
66
  seed: int = 42,
67
  ) -> Tuple[List[Dict], List[Dict], List[Dict]]:
68
+ """Split stratified by template_id so every template is represented in each split.
69
+
70
+ Stratifying by task_family let rare template variants (e.g. partial_05,
71
+ diff_02) land entirely in train and never appear in val/test.
72
+ """
73
  random.seed(seed)
74
+ by_tpl: Dict[str, List] = defaultdict(list)
75
  for s in samples:
76
+ key = s["metadata"].get("template_id") or s["metadata"].get("task_family", "unknown")
77
+ by_tpl[key].append(s)
78
 
79
  train, val, test = [], [], []
80
+ for tpl_samples in by_tpl.values():
81
+ random.shuffle(tpl_samples)
82
+ n = len(tpl_samples)
83
  n_train = int(n * train_ratio)
84
  n_val = int(n * val_ratio)
85
+ train.extend(tpl_samples[:n_train])
86
+ val.extend(tpl_samples[n_train : n_train + n_val])
87
+ test.extend(tpl_samples[n_train + n_val :])
88
 
89
  random.shuffle(train)
90
  random.shuffle(val)
dataset/scripts/generate_samples.py CHANGED
@@ -1378,18 +1378,26 @@ def prepare_work_items(
1378
  """
1379
  work_items = []
1380
  sample_counter = start_counter
1381
-
1382
  for family, target_count in target_counts.items():
1383
  if target_count == 0:
1384
  continue
1385
-
1386
  family_templates = [t for t in TEMPLATES if t.family == family]
1387
  if not family_templates:
1388
  print(f"No templates found for {family}, skipping...")
1389
  continue
1390
-
1391
- for _ in range(target_count * retry_multiplier):
1392
- template = random.choice(family_templates)
 
 
 
 
 
 
 
 
1393
  template_dict = {
1394
  'template_id': template.template_id,
1395
  'family': template.family,
@@ -1402,14 +1410,15 @@ def prepare_work_items(
1402
  'requires_buffer': template.requires_buffer,
1403
  'requires_aggregation': template.requires_aggregation
1404
  }
1405
- work_items.append((
1406
- family,
1407
- template_dict,
1408
- f"sample_{sample_counter:06d}",
1409
- intermediate_dir_str,
1410
- ))
1411
- sample_counter += 1
1412
-
 
1413
  random.shuffle(work_items)
1414
  return work_items
1415
 
 
1378
  """
1379
  work_items = []
1380
  sample_counter = start_counter
1381
+
1382
  for family, target_count in target_counts.items():
1383
  if target_count == 0:
1384
  continue
1385
+
1386
  family_templates = [t for t in TEMPLATES if t.family == family]
1387
  if not family_templates:
1388
  print(f"No templates found for {family}, skipping...")
1389
  continue
1390
+
1391
+ # Distribute target evenly across templates so every template_id gets
1392
+ # a guaranteed share. Uniform random choice previously let rare
1393
+ # variants like partial_05 / diff_02 get under-represented or dropped
1394
+ # entirely when their mixed-source branch hit transient failures.
1395
+ n_tpl = len(family_templates)
1396
+ per_tpl = target_count // n_tpl
1397
+ remainder = target_count % n_tpl
1398
+
1399
+ for i, template in enumerate(family_templates):
1400
+ count = per_tpl + (1 if i < remainder else 0)
1401
  template_dict = {
1402
  'template_id': template.template_id,
1403
  'family': template.family,
 
1410
  'requires_buffer': template.requires_buffer,
1411
  'requires_aggregation': template.requires_aggregation
1412
  }
1413
+ for _ in range(count * retry_multiplier):
1414
+ work_items.append((
1415
+ family,
1416
+ template_dict,
1417
+ f"sample_{sample_counter:06d}",
1418
+ intermediate_dir_str,
1419
+ ))
1420
+ sample_counter += 1
1421
+
1422
  random.shuffle(work_items)
1423
  return work_items
1424
 
dataset/scripts/sql_templates.py CHANGED
@@ -81,19 +81,19 @@ TEMPLATES = [
81
  " WHERE id = '{anchor_id}'"
82
  ),
83
  question_hints=[
84
- "Show me {anchor_name}",
85
- "Get the boundary of {anchor_name}",
86
- "Find {anchor_name}",
87
- "Where is {anchor_name}?",
88
- "Give me the outline of {anchor_name}",
89
- "Display {anchor_name} on a map",
90
- "What does {anchor_name} look like?",
91
- "I need the shape of {anchor_name}",
92
- "Pull up {anchor_name}",
93
- "Can you show {anchor_name}?",
94
- "Map of {anchor_name}",
95
  "{anchor_name} boundary",
96
- "Locate {anchor_name} for me",
97
  ],
98
  ),
99
 
@@ -110,18 +110,18 @@ TEMPLATES = [
110
  " WHERE id = '{anchor_id}'"
111
  ),
112
  question_hints=[
113
- "Show me the {anchor_name}",
114
- "Get {anchor_name}",
115
- "Find the {anchor_name}",
116
- "Where is the {anchor_name}?",
117
- "Show the extent of the {anchor_name}",
118
- "Give me the geometry of the {anchor_name}",
119
- "Display the {anchor_name}",
120
- "Pull up the {anchor_name}",
121
- "I want to see the {anchor_name}",
122
- "Map the {anchor_name}",
123
- "How big is the {anchor_name}?",
124
- "Outline of the {anchor_name}",
125
  ],
126
  ),
127
 
@@ -144,15 +144,15 @@ TEMPLATES = [
144
  " AND ST_Touches(a.geometry, b.geometry)"
145
  ),
146
  question_hints=[
147
- "Which regions border {anchor_name}?",
148
- "What administrative units touch {anchor_name}?",
149
- "List all places adjacent to {anchor_name}",
150
- "What shares a border with {anchor_name}?",
151
- "Neighbours of {anchor_name}",
152
- "What is adjacent to {anchor_name}?",
153
- "What surrounds {anchor_name}?",
154
- "Places next to {anchor_name}",
155
- "Everything bordering {anchor_name}",
156
  ],
157
  ),
158
 
@@ -175,13 +175,13 @@ TEMPLATES = [
175
  " AND ST_Touches(a.geometry, b.geometry)"
176
  ),
177
  question_hints=[
178
- "Which {target_subtype}s border {anchor_name}?",
179
- "What {target_subtype}s share a border with {anchor_name}?",
180
  "{target_subtype}s that touch {anchor_name}",
181
- "Neighbouring {target_subtype}s of {anchor_name}",
182
- "Which {target_subtype}s are adjacent to {anchor_name}?",
183
  "{target_subtype}s along the {anchor_name} border",
184
- "Find {target_subtype}s next to {anchor_name}",
185
  ],
186
  ),
187
 
@@ -203,15 +203,15 @@ TEMPLATES = [
203
  " AND ST_Touches(a.geometry, n.geometry)"
204
  ),
205
  question_hints=[
206
- "Which seas touch {anchor_name}?",
207
- "What seas border {anchor_name}?",
208
- "Which bodies of water is {anchor_name} adjacent to?",
209
- "What ocean or sea borders {anchor_name}?",
210
- "Which oceans touch {anchor_name}?",
211
- "What coastline does {anchor_name} have?",
212
- "Which water bodies does {anchor_name} border?",
213
- "Does {anchor_name} have access to the sea?",
214
- "What ocean is {anchor_name} on?",
215
  ],
216
  ),
217
 
@@ -238,11 +238,11 @@ TEMPLATES = [
238
  " AND ST_Touches(c.geometry, b.geometry)"
239
  ),
240
  question_hints=[
241
- "Which regions border both {anchor_1_name} and {anchor_2_name}?",
242
- "What places touch both {anchor_1_name} and {anchor_2_name}?",
243
- "Regions adjacent to both {anchor_1_name} and {anchor_2_name}",
244
- "What lies between {anchor_1_name} and {anchor_2_name}?",
245
- "Common neighbours of {anchor_1_name} and {anchor_2_name}",
246
  ],
247
  ),
248
 
@@ -267,13 +267,13 @@ TEMPLATES = [
267
  " AND ST_Within(b.geometry, a.geometry)"
268
  ),
269
  question_hints=[
270
- "What {target_subtype}s are in {anchor_name}?",
271
- "Which {target_subtype}s fall within {anchor_name}?",
272
- "List all {target_subtype}s inside {anchor_name}",
273
  "{target_subtype}s contained by {anchor_name}",
274
- "All {target_subtype}s within the boundaries of {anchor_name}",
275
  "{target_subtype}s of {anchor_name}",
276
- "Show every {target_subtype} in {anchor_name}",
277
  ],
278
  ),
279
 
@@ -296,13 +296,13 @@ TEMPLATES = [
296
  " AND ST_Contains(b.geometry, a.geometry)"
297
  ),
298
  question_hints=[
299
- "What country contains {anchor_name}?",
300
- "Which country is {anchor_name} in?",
301
- "What country does {anchor_name} belong to?",
302
- "Which nation contains {anchor_name}?",
303
  "{anchor_name} is part of which country?",
304
- "Where does {anchor_name} fall geographically?",
305
- "What country is {anchor_name} located in?",
306
  ],
307
  ),
308
 
@@ -324,12 +324,12 @@ TEMPLATES = [
324
  " AND ST_Within(b.geometry, a.geometry)"
325
  ),
326
  question_hints=[
327
- "Which {target_subtype}s are in the {anchor_name}?",
328
- "What {target_subtype}s fall within the {anchor_name}?",
329
  "{target_subtype}s inside the {anchor_name}",
330
- "Administrative {target_subtype}s within the {anchor_name}",
331
- "All regions contained by the {anchor_name}",
332
- "What {target_subtype}s does the {anchor_name} contain?",
333
  "{target_subtype}s covered by the {anchor_name}",
334
  ],
335
  ),
@@ -355,12 +355,12 @@ TEMPLATES = [
355
  " AND ST_Intersects(b.geometry, a.geometry)"
356
  ),
357
  question_hints=[
358
- "Which {target_subtype}s intersect {anchor_name}?",
359
- "What {target_subtype}s overlap with {anchor_name}?",
360
  "{target_subtype}s that cross into {anchor_name}",
361
- "Which {target_subtype}s overlap {anchor_name}?",
362
  "{target_subtype}s partially inside {anchor_name}",
363
- "What {target_subtype}s extend into {anchor_name}?",
364
  ],
365
  ),
366
 
@@ -382,15 +382,15 @@ TEMPLATES = [
382
  " AND ST_Intersects(b.geometry, a.geometry)"
383
  ),
384
  question_hints=[
385
- "Which countries intersect the {anchor_name}?",
386
- "What countries does the {anchor_name} pass through?",
387
- "Countries that overlap with the {anchor_name}",
388
- "Which countries touch the {anchor_name}?",
389
- "Nations intersected by the {anchor_name}",
390
- "Which nations does the {anchor_name} cross?",
391
- "Countries along the {anchor_name}",
392
- "What countries does the {anchor_name} cover?",
393
- "Countries that the {anchor_name} spans across",
394
  ],
395
  ),
396
 
@@ -418,13 +418,13 @@ TEMPLATES = [
418
  " AND ST_Intersects(b.geometry, a.geom)"
419
  ),
420
  question_hints=[
421
- "What is within {buffer_km} km of {anchor_name}?",
422
- "Administrative units within {buffer_km} km of {anchor_name}",
423
- "Features within a {buffer_km} km radius of {anchor_name}",
424
- "Places within {buffer_km} kilometers of {anchor_name}",
425
  "{buffer_km} km buffer around {anchor_name}",
426
- "What falls within {buffer_km} km of {anchor_name}?",
427
- "Everything within {buffer_km} km of {anchor_name}",
428
  ],
429
  ),
430
 
@@ -448,12 +448,12 @@ TEMPLATES = [
448
  " AND ST_Intersects(b.geometry, a.geom)"
449
  ),
450
  question_hints=[
451
- "What is within {buffer_m} meters of {anchor_name}?",
452
- "Features within {buffer_m} m of {anchor_name}",
453
- "Places within {buffer_m} metres of {anchor_name}",
454
  "{buffer_m} meter buffer around {anchor_name}",
455
- "What falls within {buffer_m} m of {anchor_name}?",
456
- "Administrative units within {buffer_m} metres of {anchor_name}",
457
  ],
458
  ),
459
 
@@ -476,12 +476,12 @@ TEMPLATES = [
476
  " WHERE ST_Intersects(b.geometry, a.geom)"
477
  ),
478
  question_hints=[
479
- "What administrative units are within {buffer_km} km of the {anchor_name}?",
480
- "Countries within {buffer_km} km of the {anchor_name}",
481
- "Regions within {buffer_km} km of the {anchor_name}",
482
- "What falls within {buffer_km} km of the {anchor_name}?",
483
- "Administrative divisions within a {buffer_km} km radius of the {anchor_name}",
484
- "Places within {buffer_km} kilometers of the {anchor_name}",
485
  ],
486
  ),
487
 
@@ -504,9 +504,9 @@ TEMPLATES = [
504
  " WHERE ST_Intersects(b.geometry, a.geom)"
505
  ),
506
  question_hints=[
507
- "What is within {buffer_m} meters of the {anchor_name}?",
508
- "Administrative units within {buffer_m} m of the {anchor_name}",
509
- "Places within {buffer_m} metres of the {anchor_name}",
510
  "{buffer_m} meter buffer around the {anchor_name}",
511
  ],
512
  ),
@@ -538,13 +538,13 @@ TEMPLATES = [
538
  " )"
539
  ),
540
  question_hints=[
541
- "Coastal {target_subtype}s of {anchor_name}",
542
  "{target_subtype}s in {anchor_name} with sea access",
543
- "Which {target_subtype}s in {anchor_name} are on the coast?",
544
- "Seaside {target_subtype}s within {anchor_name}",
545
  "{target_subtype}s in {anchor_name} bordering the sea",
546
- "Oceanfront {target_subtype}s in {anchor_name}",
547
- "Which {target_subtype}s in {anchor_name} have a coastline?",
548
  ],
549
  ),
550
 
@@ -571,12 +571,12 @@ TEMPLATES = [
571
  " )"
572
  ),
573
  question_hints=[
574
- "Landlocked {target_subtype}s in {anchor_name}",
575
- "Which {target_subtype}s in {anchor_name} have no sea access?",
576
  "{target_subtype}s in {anchor_name} that are landlocked",
577
  "{target_subtype}s in {anchor_name} with no coastline",
578
- "Which {target_subtype}s within {anchor_name} are landlocked?",
579
- "Interior {target_subtype}s of {anchor_name} with no ocean border",
580
  ],
581
  ),
582
 
@@ -606,7 +606,7 @@ TEMPLATES = [
606
  "{target_subtype}s in {anchor_name} on a terrain feature or island",
607
  "{target_subtype}s of {anchor_name} on a peninsula or island group",
608
  "{target_subtype}s within {anchor_name} on notable landforms",
609
- "Island and peninsula {target_subtype}s of {anchor_name}",
610
  ],
611
  ),
612
 
@@ -633,12 +633,12 @@ TEMPLATES = [
633
  question_hints=[
634
  "{anchor_1_name} excluding {anchor_2_name}",
635
  "{anchor_1_name} minus {anchor_2_name}",
636
- "The part of {anchor_1_name} that is not in {anchor_2_name}",
637
  "{anchor_1_name} without the {anchor_2_name} area",
638
- "Remove {anchor_2_name} from {anchor_1_name}",
639
  "{anchor_1_name} with {anchor_2_name} cut out",
640
- "Subtract {anchor_2_name} from {anchor_1_name}",
641
- "What is left of {anchor_1_name} after removing {anchor_2_name}?",
642
  ],
643
  ),
644
 
@@ -660,12 +660,13 @@ TEMPLATES = [
660
  " WHERE ST_Intersects(a.geometry, b.geometry)"
661
  ),
662
  question_hints=[
663
- "The part of {anchor_name} outside the {clip_feature_name}",
664
  "{anchor_name} excluding the {clip_feature_name}",
665
  "{anchor_name} minus the {clip_feature_name}",
666
- "The land area of {anchor_name} not covered by the {clip_feature_name}",
667
  "{anchor_name} with the {clip_feature_name} removed",
668
- "What remains of {anchor_name} after removing the {clip_feature_name}?",
 
669
  ],
670
  ),
671
 
@@ -697,11 +698,11 @@ TEMPLATES = [
697
  ),
698
  question_hints=[
699
  "{buffer_km} km zone along the border between {anchor_1_name} and {anchor_2_name}",
700
- "The {buffer_km} km border corridor between {anchor_1_name} and {anchor_2_name}",
701
- "Area within {buffer_km} km of the {anchor_1_name}-{anchor_2_name} border",
702
- "The region straddling the border of {anchor_1_name} and {anchor_2_name} within {buffer_km} km",
703
  "{buffer_km} km on either side of the {anchor_1_name} and {anchor_2_name} border",
704
- "Buffer the {anchor_1_name}-{anchor_2_name} boundary by {buffer_km} km",
705
  ],
706
  ),
707
 
@@ -723,11 +724,11 @@ TEMPLATES = [
723
  " WHERE id IN ('{anchor_id_1}', '{anchor_id_2}')"
724
  ),
725
  question_hints=[
726
- "The combined area of {anchor_1_name} and {anchor_2_name}",
727
- "Union of {anchor_1_name} and {anchor_2_name}",
728
- "Merge {anchor_1_name} and {anchor_2_name}",
729
  "{anchor_1_name} and {anchor_2_name} together",
730
- "Combined geometry of {anchor_1_name} and {anchor_2_name}",
731
  ],
732
  ),
733
 
@@ -744,12 +745,12 @@ TEMPLATES = [
744
  " WHERE id IN ('{anchor_id_1}', '{anchor_id_2}', '{anchor_id_3}')"
745
  ),
746
  question_hints=[
747
- "Show me {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
748
- "The combined area of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
749
- "Union of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
750
- "Merge {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
751
  "{anchor_1_name}, {anchor_2_name} and {anchor_3_name} together",
752
- "Display {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
753
  ],
754
  ),
755
 
@@ -769,10 +770,10 @@ TEMPLATES = [
769
  ),
770
  question_hints=[
771
  "{target_subtype}s of {anchor_1_name} and {anchor_2_name}",
772
- "All {target_subtype}s in {anchor_1_name} and {anchor_2_name}",
773
- "Show {target_subtype}s across {anchor_1_name} and {anchor_2_name}",
774
  "{target_subtype}s belonging to {anchor_1_name} and {anchor_2_name}",
775
- "List {target_subtype}s in both {anchor_1_name} and {anchor_2_name}",
776
  ],
777
  ),
778
 
@@ -792,9 +793,9 @@ TEMPLATES = [
792
  ),
793
  question_hints=[
794
  "{target_subtype}s of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
795
- "All {target_subtype}s in {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
796
- "Show {target_subtype}s across {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
797
- "List {target_subtype}s in {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
798
  ],
799
  ),
800
 
@@ -816,11 +817,11 @@ TEMPLATES = [
816
  " AND ST_Within(b.geometry, a.geometry)"
817
  ),
818
  question_hints=[
819
- "Merge all {target_subtype}s in {anchor_name} into one geometry",
820
- "Combined geometry of all {target_subtype}s in {anchor_name}",
821
- "Union of all {target_subtype}s within {anchor_name}",
822
- "All {target_subtype}s of {anchor_name} merged together",
823
- "The overall extent of {target_subtype}s in {anchor_name}",
824
  ],
825
  ),
826
 
@@ -848,10 +849,11 @@ TEMPLATES = [
848
  " FROM a, clip"
849
  ),
850
  question_hints=[
851
- "The northern half of {anchor_name}",
852
- "Northern part of {anchor_name}",
853
- "The top half of {anchor_name}",
854
- "Northern portion of {anchor_name}",
 
855
  ],
856
  ),
857
 
@@ -876,10 +878,11 @@ TEMPLATES = [
876
  " FROM a, clip"
877
  ),
878
  question_hints=[
879
- "The southern half of {anchor_name}",
880
- "Southern part of {anchor_name}",
881
- "The bottom half of {anchor_name}",
882
- "Southern portion of {anchor_name}",
 
883
  ],
884
  ),
885
 
@@ -904,10 +907,10 @@ TEMPLATES = [
904
  " FROM a, clip"
905
  ),
906
  question_hints=[
907
- "The eastern half of {anchor_name}",
908
- "Eastern part of {anchor_name}",
909
- "The right half of {anchor_name}",
910
- "Eastern portion of {anchor_name}",
911
  ],
912
  ),
913
 
@@ -932,10 +935,10 @@ TEMPLATES = [
932
  " FROM a, clip"
933
  ),
934
  question_hints=[
935
- "The western half of {anchor_name}",
936
- "Western part of {anchor_name}",
937
- "The left half of {anchor_name}",
938
- "Western portion of {anchor_name}",
939
  ],
940
  ),
941
 
@@ -957,10 +960,16 @@ TEMPLATES = [
957
  " WHERE ST_Intersects(a.g1, b.g2)"
958
  ),
959
  question_hints=[
960
- "The part of {anchor_name} that overlaps the {clip_feature_name}",
961
  "{anchor_name} within the {clip_feature_name}",
962
- "The portion of {anchor_name} inside the {clip_feature_name}",
963
- "Clip {anchor_name} to the {clip_feature_name}",
 
 
 
 
 
 
964
  ],
965
  ),
966
 
@@ -989,12 +998,12 @@ TEMPLATES = [
989
  " LIMIT {top_n}"
990
  ),
991
  question_hints=[
992
- "Top {top_n} largest {target_subtype}s in {anchor_name}",
993
- "Biggest {top_n} {target_subtype}s in {anchor_name}",
994
  "{top_n} largest {target_subtype}s inside {anchor_name}",
995
- "The {top_n} biggest {target_subtype}s within {anchor_name}",
996
- "Largest {target_subtype} in {anchor_name}",
997
- "Which {target_subtype} in {anchor_name} has the most area?",
998
  ],
999
  ),
1000
 
@@ -1020,12 +1029,12 @@ TEMPLATES = [
1020
  " LIMIT {top_n}"
1021
  ),
1022
  question_hints=[
1023
- "Top {top_n} smallest {target_subtype}s in {anchor_name}",
1024
- "Smallest {top_n} {target_subtype}s in {anchor_name}",
1025
  "{top_n} smallest {target_subtype}s inside {anchor_name}",
1026
- "The {top_n} tiniest {target_subtype}s within {anchor_name}",
1027
- "Smallest {target_subtype} in {anchor_name}",
1028
- "Which {target_subtype} in {anchor_name} has the least area?",
1029
  ],
1030
  ),
1031
 
@@ -1048,12 +1057,12 @@ TEMPLATES = [
1048
  " LIMIT {top_n}"
1049
  ),
1050
  question_hints=[
1051
- "Top {top_n} largest {target_subtype}s in {anchor_name}",
1052
  "{top_n} biggest {target_subtype}s in {anchor_name}",
1053
- "Largest {top_n} {target_subtype}s in {anchor_name}",
1054
- "The {top_n} largest {target_subtype}s in {anchor_name}",
1055
- "Biggest {target_subtype} in {anchor_name}",
1056
- "Which {target_subtype} in {anchor_name} is the largest?",
1057
  ],
1058
  ),
1059
 
@@ -1076,12 +1085,12 @@ TEMPLATES = [
1076
  " LIMIT {top_n}"
1077
  ),
1078
  question_hints=[
1079
- "Top {top_n} smallest {target_subtype}s in {anchor_name}",
1080
  "{top_n} smallest {target_subtype}s in {anchor_name}",
1081
- "Smallest {top_n} {target_subtype}s in {anchor_name}",
1082
- "The {top_n} smallest {target_subtype}s in {anchor_name}",
1083
- "Smallest {target_subtype} in {anchor_name}",
1084
- "Which {target_subtype} in {anchor_name} is the smallest?",
1085
  ],
1086
  ),
1087
 
@@ -1111,10 +1120,10 @@ TEMPLATES = [
1111
  " WHERE rn = 1"
1112
  ),
1113
  question_hints=[
1114
- "The largest {target_subtype} in each region of {anchor_name}",
1115
- "Biggest {target_subtype} per region in {anchor_name}",
1116
- "Largest {target_subtype} for every region of {anchor_name}",
1117
- "The biggest {target_subtype} in each province of {anchor_name}",
1118
  ],
1119
  ),
1120
 
@@ -1141,10 +1150,10 @@ TEMPLATES = [
1141
  " WHERE rn = 1"
1142
  ),
1143
  question_hints=[
1144
- "The smallest {target_subtype} in each region of {anchor_name}",
1145
- "Smallest {target_subtype} per region in {anchor_name}",
1146
- "Tiniest {target_subtype} for every region of {anchor_name}",
1147
- "The smallest {target_subtype} in each province of {anchor_name}",
1148
  ],
1149
  ),
1150
 
@@ -1167,11 +1176,11 @@ TEMPLATES = [
1167
  " AND subtype = '{target_subtype}'"
1168
  ),
1169
  question_hints=[
1170
- "Island territories of {anchor_name}",
1171
- "Overseas island {target_subtype}s belonging to {anchor_name}",
1172
- "Which islands are part of {anchor_name}?",
1173
- "Land territories of {anchor_name}",
1174
- "Island possessions of {anchor_name}",
1175
  "{anchor_name}'s island {target_subtype}s",
1176
  ],
1177
  ),
@@ -1192,10 +1201,10 @@ TEMPLATES = [
1192
  " AND subtype = '{target_subtype}'"
1193
  ),
1194
  question_hints=[
1195
- "Territorial {target_subtype}s of {anchor_name}",
1196
- "Official territorial divisions of {anchor_name}",
1197
- "Recognised territorial {target_subtype}s belonging to {anchor_name}",
1198
- "Which territorial regions does {anchor_name} have?",
1199
  ],
1200
  ),
1201
 
@@ -1215,10 +1224,10 @@ TEMPLATES = [
1215
  " AND is_land = TRUE"
1216
  ),
1217
  question_hints=[
1218
- "Land-based {target_subtype}s of {anchor_name}",
1219
  "{target_subtype}s on the mainland of {anchor_name}",
1220
- "All {target_subtype}s on land in {anchor_name}",
1221
- "Non-island {target_subtype}s of {anchor_name}",
1222
  ],
1223
  ),
1224
 
@@ -1244,14 +1253,14 @@ TEMPLATES = [
1244
  " AND ST_Intersects(a.geometry, n.geometry)"
1245
  ),
1246
  question_hints=[
1247
- "What rivers or lakes are in {anchor_name}?",
1248
- "Natural water features of {anchor_name}",
1249
- "Which rivers flow through {anchor_name}?",
1250
- "Lakes and rivers within {anchor_name}",
1251
- "Water features inside {anchor_name}",
1252
- "What bodies of water cross {anchor_name}?",
1253
- "Rivers of {anchor_name}",
1254
- "Show me the lakes in {anchor_name}",
1255
  ],
1256
  ),
1257
 
@@ -1273,14 +1282,14 @@ TEMPLATES = [
1273
  " AND ST_Intersects(a.geometry, n.geometry)"
1274
  ),
1275
  question_hints=[
1276
- "What mountain ranges are in {anchor_name}?",
1277
- "Terrain features of {anchor_name}",
1278
- "Which mountain ranges cross {anchor_name}?",
1279
- "Landforms inside {anchor_name}",
1280
- "Peninsulas and ranges in {anchor_name}",
1281
- "Geographic features within {anchor_name}",
1282
- "Mountains of {anchor_name}",
1283
- "What terrain does {anchor_name} contain?",
1284
  ],
1285
  ),
1286
 
@@ -1308,13 +1317,13 @@ TEMPLATES = [
1308
  " AND ST_Intersects(b.geometry, a.geometry)"
1309
  ),
1310
  question_hints=[
1311
- "Which regions does the {anchor_name} pass through?",
1312
- "What administrative regions overlap with the {anchor_name}?",
1313
- "Regions that the {anchor_name} crosses",
1314
- "Administrative areas intersected by the {anchor_name}",
1315
- "What provinces does the {anchor_name} span?",
1316
- "Regions along the {anchor_name}",
1317
- "Which provinces overlap the {anchor_name}?",
1318
  ],
1319
  ),
1320
 
@@ -1335,12 +1344,12 @@ TEMPLATES = [
1335
  " WHERE ST_Intersects(n.geometry, a.geometry)"
1336
  ),
1337
  question_hints=[
1338
- "What natural features intersect {anchor_name}?",
1339
- "Natural earth features that overlap {anchor_name}",
1340
- "Which geographic features cross {anchor_name}?",
1341
- "Everything from natural earth that touches {anchor_name}",
1342
- "What geographic features does {anchor_name} contain?",
1343
- "Natural features within or crossing {anchor_name}",
1344
  ],
1345
  ),
1346
 
@@ -1371,13 +1380,13 @@ TEMPLATES = [
1371
  " )"
1372
  ),
1373
  question_hints=[
1374
- "Riverside {target_subtype}s in {anchor_name}",
1375
  "{target_subtype}s in {anchor_name} near a river or lake",
1376
- "Which {target_subtype}s in {anchor_name} are on a waterway?",
1377
- "Lakeside or riverside {target_subtype}s within {anchor_name}",
1378
  "{target_subtype}s in {anchor_name} that touch a river",
1379
- "Which {target_subtype}s in {anchor_name} are on a lake?",
1380
- "Waterfront {target_subtype}s of {anchor_name}",
1381
  ],
1382
  ),
1383
 
@@ -1404,10 +1413,10 @@ TEMPLATES = [
1404
  " )"
1405
  ),
1406
  question_hints=[
1407
- "Mountain {target_subtype}s in {anchor_name}",
1408
  "{target_subtype}s in {anchor_name} on a mountain range",
1409
- "Which {target_subtype}s in {anchor_name} are in the mountains?",
1410
- "Highland {target_subtype}s within {anchor_name}",
1411
  "{target_subtype}s of {anchor_name} in mountainous terrain",
1412
  "{target_subtype}s in {anchor_name} near a mountain range",
1413
  ],
@@ -1440,13 +1449,13 @@ TEMPLATES = [
1440
  " )"
1441
  ),
1442
  question_hints=[
1443
- "Coastal {target_subtype}s of {anchor_name}",
1444
- "Which districts of {anchor_name} are on the coast?",
1445
  "{target_subtype}s in {anchor_name} that border the sea",
1446
- "Seaside {target_subtype}s within {anchor_name}",
1447
  "{target_subtype}s of {anchor_name} with ocean access",
1448
- "Which {target_subtype}s in {anchor_name} touch the sea?",
1449
- "Maritime {target_subtype}s of {anchor_name}",
1450
  ],
1451
  ),
1452
 
@@ -1473,12 +1482,12 @@ TEMPLATES = [
1473
  " )"
1474
  ),
1475
  question_hints=[
1476
- "Landlocked {target_subtype}s of {anchor_name}",
1477
- "Which districts of {anchor_name} have no coastline?",
1478
- "Interior {target_subtype}s within {anchor_name}",
1479
  "{target_subtype}s in {anchor_name} with no sea access",
1480
- "Non-coastal {target_subtype}s of {anchor_name}",
1481
- "Inland {target_subtype}s of {anchor_name}",
1482
  ],
1483
  ),
1484
 
@@ -1505,12 +1514,12 @@ TEMPLATES = [
1505
  " )"
1506
  ),
1507
  question_hints=[
1508
- "Riverside {target_subtype}s of {anchor_name}",
1509
- "Which districts of {anchor_name} have a river or lake?",
1510
  "{target_subtype}s in {anchor_name} on a waterway",
1511
- "Lakeside {target_subtype}s within {anchor_name}",
1512
  "{target_subtype}s of {anchor_name} along a river",
1513
- "Which {target_subtype}s in {anchor_name} border a lake?",
1514
  ],
1515
  ),
1516
 
@@ -1537,12 +1546,12 @@ TEMPLATES = [
1537
  " )"
1538
  ),
1539
  question_hints=[
1540
- "Mountain {target_subtype}s of {anchor_name}",
1541
- "Which districts of {anchor_name} are in the mountains?",
1542
  "{target_subtype}s in {anchor_name} on a mountain range",
1543
- "Highland {target_subtype}s within {anchor_name}",
1544
  "{target_subtype}s of {anchor_name} in mountainous terrain",
1545
- "Which {target_subtype}s in {anchor_name} have mountain ranges?",
1546
  ],
1547
  ),
1548
 
@@ -1568,13 +1577,13 @@ TEMPLATES = [
1568
  " AND ST_Intersects(b.geometry, a.geometry)"
1569
  ),
1570
  question_hints=[
1571
- "Which countries border the {anchor_name}?",
1572
- "What countries are along the {anchor_name}?",
1573
- "Countries surrounding the {anchor_name}",
1574
- "Nations on the {anchor_name}",
1575
- "Which countries touch the {anchor_name}?",
1576
- "Countries with coastline on the {anchor_name}",
1577
- "What nations lie on the {anchor_name}?",
1578
  ],
1579
  ),
1580
 
@@ -1601,11 +1610,11 @@ TEMPLATES = [
1601
  " WHERE ST_Intersects(n.geometry, a.geom)"
1602
  ),
1603
  question_hints=[
1604
- "Natural features within {buffer_km} km of the {anchor_name}",
1605
- "What is within {buffer_km} km of the {anchor_name}?",
1606
- "Geographic features near the {anchor_name} within {buffer_km} km",
1607
- "Everything within {buffer_km} km of the {anchor_name}",
1608
- "What natural features are close to the {anchor_name}?",
1609
  "{buffer_km} km radius around the {anchor_name}",
1610
  ],
1611
  ),
 
81
  " WHERE id = '{anchor_id}'"
82
  ),
83
  question_hints=[
84
+ "show me {anchor_name}",
85
+ "get the boundary of {anchor_name}",
86
+ "find {anchor_name}",
87
+ "where is {anchor_name}?",
88
+ "outline of {anchor_name}",
89
+ "map {anchor_name}",
90
+ "what does {anchor_name} look like",
91
+ "i need the shape of {anchor_name}",
92
+ "pull up {anchor_name}",
93
+ "can you show {anchor_name}",
94
+ "map of {anchor_name}",
95
  "{anchor_name} boundary",
96
+ "locate {anchor_name}",
97
  ],
98
  ),
99
 
 
110
  " WHERE id = '{anchor_id}'"
111
  ),
112
  question_hints=[
113
+ "show me the {anchor_name}",
114
+ "get the {anchor_name}",
115
+ "find the {anchor_name}",
116
+ "where is the {anchor_name}?",
117
+ "extent of the {anchor_name}",
118
+ "geometry of the {anchor_name}",
119
+ "display the {anchor_name}",
120
+ "pull up the {anchor_name}",
121
+ "i want to see the {anchor_name}",
122
+ "map the {anchor_name}",
123
+ "how big is the {anchor_name}?",
124
+ "outline of the {anchor_name}",
125
  ],
126
  ),
127
 
 
144
  " AND ST_Touches(a.geometry, b.geometry)"
145
  ),
146
  question_hints=[
147
+ "which regions border {anchor_name}?",
148
+ "what places touch {anchor_name}",
149
+ "list everything adjacent to {anchor_name}",
150
+ "what shares a border with {anchor_name}",
151
+ "neighbours of {anchor_name}",
152
+ "what's next to {anchor_name}",
153
+ "what surrounds {anchor_name}?",
154
+ "places next to {anchor_name}",
155
+ "everything bordering {anchor_name}",
156
  ],
157
  ),
158
 
 
175
  " AND ST_Touches(a.geometry, b.geometry)"
176
  ),
177
  question_hints=[
178
+ "which {target_subtype}s border {anchor_name}?",
179
+ "what {target_subtype}s share a border with {anchor_name}",
180
  "{target_subtype}s that touch {anchor_name}",
181
+ "neighbouring {target_subtype}s of {anchor_name}",
182
+ "which {target_subtype}s are adjacent to {anchor_name}?",
183
  "{target_subtype}s along the {anchor_name} border",
184
+ "find {target_subtype}s next to {anchor_name}",
185
  ],
186
  ),
187
 
 
203
  " AND ST_Touches(a.geometry, n.geometry)"
204
  ),
205
  question_hints=[
206
+ "which seas touch {anchor_name}?",
207
+ "what seas border {anchor_name}?",
208
+ "which bodies of water is {anchor_name} next to?",
209
+ "what ocean or sea borders {anchor_name}",
210
+ "which oceans touch {anchor_name}?",
211
+ "what coastline does {anchor_name} have?",
212
+ "which water bodies does {anchor_name} border?",
213
+ "does {anchor_name} have sea access?",
214
+ "what ocean is {anchor_name} on?",
215
  ],
216
  ),
217
 
 
238
  " AND ST_Touches(c.geometry, b.geometry)"
239
  ),
240
  question_hints=[
241
+ "which regions border both {anchor_1_name} and {anchor_2_name}?",
242
+ "what places touch both {anchor_1_name} and {anchor_2_name}?",
243
+ "regions adjacent to both {anchor_1_name} and {anchor_2_name}",
244
+ "what lies between {anchor_1_name} and {anchor_2_name}?",
245
+ "common neighbours of {anchor_1_name} and {anchor_2_name}",
246
  ],
247
  ),
248
 
 
267
  " AND ST_Within(b.geometry, a.geometry)"
268
  ),
269
  question_hints=[
270
+ "what {target_subtype}s are in {anchor_name}?",
271
+ "which {target_subtype}s fall within {anchor_name}?",
272
+ "list all {target_subtype}s inside {anchor_name}",
273
  "{target_subtype}s contained by {anchor_name}",
274
+ "all {target_subtype}s within {anchor_name}",
275
  "{target_subtype}s of {anchor_name}",
276
+ "show every {target_subtype} in {anchor_name}",
277
  ],
278
  ),
279
 
 
296
  " AND ST_Contains(b.geometry, a.geometry)"
297
  ),
298
  question_hints=[
299
+ "what country contains {anchor_name}?",
300
+ "which country is {anchor_name} in?",
301
+ "what country does {anchor_name} belong to?",
302
+ "which nation contains {anchor_name}?",
303
  "{anchor_name} is part of which country?",
304
+ "where is {anchor_name}",
305
+ "what country is {anchor_name} in",
306
  ],
307
  ),
308
 
 
324
  " AND ST_Within(b.geometry, a.geometry)"
325
  ),
326
  question_hints=[
327
+ "which {target_subtype}s are in the {anchor_name}?",
328
+ "what {target_subtype}s fall within the {anchor_name}?",
329
  "{target_subtype}s inside the {anchor_name}",
330
+ "admin {target_subtype}s within the {anchor_name}",
331
+ "all regions inside the {anchor_name}",
332
+ "what {target_subtype}s does the {anchor_name} contain?",
333
  "{target_subtype}s covered by the {anchor_name}",
334
  ],
335
  ),
 
355
  " AND ST_Intersects(b.geometry, a.geometry)"
356
  ),
357
  question_hints=[
358
+ "which {target_subtype}s intersect {anchor_name}?",
359
+ "what {target_subtype}s overlap with {anchor_name}?",
360
  "{target_subtype}s that cross into {anchor_name}",
361
+ "which {target_subtype}s overlap {anchor_name}?",
362
  "{target_subtype}s partially inside {anchor_name}",
363
+ "what {target_subtype}s extend into {anchor_name}?",
364
  ],
365
  ),
366
 
 
382
  " AND ST_Intersects(b.geometry, a.geometry)"
383
  ),
384
  question_hints=[
385
+ "which countries does the {anchor_name} pass through?",
386
+ "what countries does the {anchor_name} cross?",
387
+ "countries that overlap the {anchor_name}",
388
+ "which countries touch the {anchor_name}?",
389
+ "nations intersected by the {anchor_name}",
390
+ "which nations does the {anchor_name} cross?",
391
+ "countries along the {anchor_name}",
392
+ "what countries does the {anchor_name} cover?",
393
+ "countries the {anchor_name} spans across",
394
  ],
395
  ),
396
 
 
418
  " AND ST_Intersects(b.geometry, a.geom)"
419
  ),
420
  question_hints=[
421
+ "what's within {buffer_km} km of {anchor_name}?",
422
+ "admin units within {buffer_km} km of {anchor_name}",
423
+ "features within a {buffer_km} km radius of {anchor_name}",
424
+ "places within {buffer_km} kilometers of {anchor_name}",
425
  "{buffer_km} km buffer around {anchor_name}",
426
+ "what falls within {buffer_km} km of {anchor_name}?",
427
+ "everything within {buffer_km} km of {anchor_name}",
428
  ],
429
  ),
430
 
 
448
  " AND ST_Intersects(b.geometry, a.geom)"
449
  ),
450
  question_hints=[
451
+ "what's within {buffer_m} meters of {anchor_name}?",
452
+ "features within {buffer_m} m of {anchor_name}",
453
+ "places within {buffer_m} metres of {anchor_name}",
454
  "{buffer_m} meter buffer around {anchor_name}",
455
+ "what falls within {buffer_m} m of {anchor_name}?",
456
+ "admin units within {buffer_m} metres of {anchor_name}",
457
  ],
458
  ),
459
 
 
476
  " WHERE ST_Intersects(b.geometry, a.geom)"
477
  ),
478
  question_hints=[
479
+ "what admin units are within {buffer_km} km of the {anchor_name}?",
480
+ "countries within {buffer_km} km of the {anchor_name}",
481
+ "regions within {buffer_km} km of the {anchor_name}",
482
+ "what falls within {buffer_km} km of the {anchor_name}?",
483
+ "admin divisions within a {buffer_km} km radius of the {anchor_name}",
484
+ "places within {buffer_km} kilometers of the {anchor_name}",
485
  ],
486
  ),
487
 
 
504
  " WHERE ST_Intersects(b.geometry, a.geom)"
505
  ),
506
  question_hints=[
507
+ "what's within {buffer_m} meters of the {anchor_name}?",
508
+ "admin units within {buffer_m} m of the {anchor_name}",
509
+ "places within {buffer_m} metres of the {anchor_name}",
510
  "{buffer_m} meter buffer around the {anchor_name}",
511
  ],
512
  ),
 
538
  " )"
539
  ),
540
  question_hints=[
541
+ "coastal {target_subtype}s of {anchor_name}",
542
  "{target_subtype}s in {anchor_name} with sea access",
543
+ "which {target_subtype}s in {anchor_name} are on the coast?",
544
+ "seaside {target_subtype}s within {anchor_name}",
545
  "{target_subtype}s in {anchor_name} bordering the sea",
546
+ "oceanfront {target_subtype}s in {anchor_name}",
547
+ "which {target_subtype}s in {anchor_name} have a coastline?",
548
  ],
549
  ),
550
 
 
571
  " )"
572
  ),
573
  question_hints=[
574
+ "landlocked {target_subtype}s in {anchor_name}",
575
+ "which {target_subtype}s in {anchor_name} have no sea access?",
576
  "{target_subtype}s in {anchor_name} that are landlocked",
577
  "{target_subtype}s in {anchor_name} with no coastline",
578
+ "which {target_subtype}s within {anchor_name} are landlocked?",
579
+ "interior {target_subtype}s of {anchor_name} with no ocean border",
580
  ],
581
  ),
582
 
 
606
  "{target_subtype}s in {anchor_name} on a terrain feature or island",
607
  "{target_subtype}s of {anchor_name} on a peninsula or island group",
608
  "{target_subtype}s within {anchor_name} on notable landforms",
609
+ "island and peninsula {target_subtype}s of {anchor_name}",
610
  ],
611
  ),
612
 
 
633
  question_hints=[
634
  "{anchor_1_name} excluding {anchor_2_name}",
635
  "{anchor_1_name} minus {anchor_2_name}",
636
+ "the part of {anchor_1_name} that is not in {anchor_2_name}",
637
  "{anchor_1_name} without the {anchor_2_name} area",
638
+ "remove {anchor_2_name} from {anchor_1_name}",
639
  "{anchor_1_name} with {anchor_2_name} cut out",
640
+ "subtract {anchor_2_name} from {anchor_1_name}",
641
+ "what's left of {anchor_1_name} after removing {anchor_2_name}?",
642
  ],
643
  ),
644
 
 
660
  " WHERE ST_Intersects(a.geometry, b.geometry)"
661
  ),
662
  question_hints=[
663
+ "the part of {anchor_name} outside the {clip_feature_name}",
664
  "{anchor_name} excluding the {clip_feature_name}",
665
  "{anchor_name} minus the {clip_feature_name}",
666
+ "parts of {anchor_name} not covered by the {clip_feature_name}",
667
  "{anchor_name} with the {clip_feature_name} removed",
668
+ "what's left of {anchor_name} after removing the {clip_feature_name}?",
669
+ "show me {anchor_name} excluding the {clip_feature_name}",
670
  ],
671
  ),
672
 
 
698
  ),
699
  question_hints=[
700
  "{buffer_km} km zone along the border between {anchor_1_name} and {anchor_2_name}",
701
+ "the {buffer_km} km border corridor between {anchor_1_name} and {anchor_2_name}",
702
+ "area within {buffer_km} km of the {anchor_1_name}-{anchor_2_name} border",
703
+ "the region straddling the border of {anchor_1_name} and {anchor_2_name} within {buffer_km} km",
704
  "{buffer_km} km on either side of the {anchor_1_name} and {anchor_2_name} border",
705
+ "buffer the {anchor_1_name}-{anchor_2_name} boundary by {buffer_km} km",
706
  ],
707
  ),
708
 
 
724
  " WHERE id IN ('{anchor_id_1}', '{anchor_id_2}')"
725
  ),
726
  question_hints=[
727
+ "the combined area of {anchor_1_name} and {anchor_2_name}",
728
+ "union of {anchor_1_name} and {anchor_2_name}",
729
+ "merge {anchor_1_name} and {anchor_2_name}",
730
  "{anchor_1_name} and {anchor_2_name} together",
731
+ "combined geometry of {anchor_1_name} and {anchor_2_name}",
732
  ],
733
  ),
734
 
 
745
  " WHERE id IN ('{anchor_id_1}', '{anchor_id_2}', '{anchor_id_3}')"
746
  ),
747
  question_hints=[
748
+ "show me {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
749
+ "the combined area of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
750
+ "union of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
751
+ "merge {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
752
  "{anchor_1_name}, {anchor_2_name} and {anchor_3_name} together",
753
+ "display {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
754
  ],
755
  ),
756
 
 
770
  ),
771
  question_hints=[
772
  "{target_subtype}s of {anchor_1_name} and {anchor_2_name}",
773
+ "all {target_subtype}s in {anchor_1_name} and {anchor_2_name}",
774
+ "show {target_subtype}s across {anchor_1_name} and {anchor_2_name}",
775
  "{target_subtype}s belonging to {anchor_1_name} and {anchor_2_name}",
776
+ "list {target_subtype}s in both {anchor_1_name} and {anchor_2_name}",
777
  ],
778
  ),
779
 
 
793
  ),
794
  question_hints=[
795
  "{target_subtype}s of {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
796
+ "all {target_subtype}s in {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
797
+ "show {target_subtype}s across {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
798
+ "list {target_subtype}s in {anchor_1_name}, {anchor_2_name} and {anchor_3_name}",
799
  ],
800
  ),
801
 
 
817
  " AND ST_Within(b.geometry, a.geometry)"
818
  ),
819
  question_hints=[
820
+ "merge all {target_subtype}s in {anchor_name} into one geometry",
821
+ "combined geometry of all {target_subtype}s in {anchor_name}",
822
+ "union of all {target_subtype}s within {anchor_name}",
823
+ "all {target_subtype}s of {anchor_name} merged together",
824
+ "the overall extent of {target_subtype}s in {anchor_name}",
825
  ],
826
  ),
827
 
 
849
  " FROM a, clip"
850
  ),
851
  question_hints=[
852
+ "the northern half of {anchor_name}",
853
+ "northern part of {anchor_name}",
854
+ "the top half of {anchor_name}",
855
+ "northern portion of {anchor_name}",
856
+ "upper half of {anchor_name}",
857
  ],
858
  ),
859
 
 
878
  " FROM a, clip"
879
  ),
880
  question_hints=[
881
+ "the southern half of {anchor_name}",
882
+ "southern part of {anchor_name}",
883
+ "the bottom half of {anchor_name}",
884
+ "southern portion of {anchor_name}",
885
+ "lower half of {anchor_name}",
886
  ],
887
  ),
888
 
 
907
  " FROM a, clip"
908
  ),
909
  question_hints=[
910
+ "the eastern half of {anchor_name}",
911
+ "eastern part of {anchor_name}",
912
+ "the right half of {anchor_name}",
913
+ "eastern portion of {anchor_name}",
914
  ],
915
  ),
916
 
 
935
  " FROM a, clip"
936
  ),
937
  question_hints=[
938
+ "the western half of {anchor_name}",
939
+ "western part of {anchor_name}",
940
+ "the left half of {anchor_name}",
941
+ "western portion of {anchor_name}",
942
  ],
943
  ),
944
 
 
960
  " WHERE ST_Intersects(a.g1, b.g2)"
961
  ),
962
  question_hints=[
963
+ "the part of {anchor_name} that overlaps the {clip_feature_name}",
964
  "{anchor_name} within the {clip_feature_name}",
965
+ "the portion of {anchor_name} inside the {clip_feature_name}",
966
+ "part of the {clip_feature_name} in {anchor_name}",
967
+ "part of {anchor_name} in the {clip_feature_name}",
968
+ "clip {anchor_name} to the {clip_feature_name}",
969
+ "{anchor_name} clipped to the {clip_feature_name}",
970
+ "{clip_feature_name} inside {anchor_name}",
971
+ "parts of {anchor_name} covered by the {clip_feature_name}",
972
+ "show me where {anchor_name} and the {clip_feature_name} overlap",
973
  ],
974
  ),
975
 
 
998
  " LIMIT {top_n}"
999
  ),
1000
  question_hints=[
1001
+ "top {top_n} largest {target_subtype}s in {anchor_name}",
1002
+ "biggest {top_n} {target_subtype}s in {anchor_name}",
1003
  "{top_n} largest {target_subtype}s inside {anchor_name}",
1004
+ "the {top_n} biggest {target_subtype}s within {anchor_name}",
1005
+ "largest {target_subtype} in {anchor_name}",
1006
+ "which {target_subtype} in {anchor_name} has the most area?",
1007
  ],
1008
  ),
1009
 
 
1029
  " LIMIT {top_n}"
1030
  ),
1031
  question_hints=[
1032
+ "top {top_n} smallest {target_subtype}s in {anchor_name}",
1033
+ "smallest {top_n} {target_subtype}s in {anchor_name}",
1034
  "{top_n} smallest {target_subtype}s inside {anchor_name}",
1035
+ "the {top_n} tiniest {target_subtype}s within {anchor_name}",
1036
+ "smallest {target_subtype} in {anchor_name}",
1037
+ "which {target_subtype} in {anchor_name} has the least area?",
1038
  ],
1039
  ),
1040
 
 
1057
  " LIMIT {top_n}"
1058
  ),
1059
  question_hints=[
1060
+ "top {top_n} largest {target_subtype}s in {anchor_name}",
1061
  "{top_n} biggest {target_subtype}s in {anchor_name}",
1062
+ "largest {top_n} {target_subtype}s in {anchor_name}",
1063
+ "the {top_n} largest {target_subtype}s in {anchor_name}",
1064
+ "biggest {target_subtype} in {anchor_name}",
1065
+ "which {target_subtype} in {anchor_name} is the largest?",
1066
  ],
1067
  ),
1068
 
 
1085
  " LIMIT {top_n}"
1086
  ),
1087
  question_hints=[
1088
+ "top {top_n} smallest {target_subtype}s in {anchor_name}",
1089
  "{top_n} smallest {target_subtype}s in {anchor_name}",
1090
+ "smallest {top_n} {target_subtype}s in {anchor_name}",
1091
+ "the {top_n} smallest {target_subtype}s in {anchor_name}",
1092
+ "smallest {target_subtype} in {anchor_name}",
1093
+ "which {target_subtype} in {anchor_name} is the smallest?",
1094
  ],
1095
  ),
1096
 
 
1120
  " WHERE rn = 1"
1121
  ),
1122
  question_hints=[
1123
+ "the largest {target_subtype} in each region of {anchor_name}",
1124
+ "biggest {target_subtype} per region in {anchor_name}",
1125
+ "largest {target_subtype} for every region of {anchor_name}",
1126
+ "the biggest {target_subtype} in each province of {anchor_name}",
1127
  ],
1128
  ),
1129
 
 
1150
  " WHERE rn = 1"
1151
  ),
1152
  question_hints=[
1153
+ "the smallest {target_subtype} in each region of {anchor_name}",
1154
+ "smallest {target_subtype} per region in {anchor_name}",
1155
+ "tiniest {target_subtype} for every region of {anchor_name}",
1156
+ "the smallest {target_subtype} in each province of {anchor_name}",
1157
  ],
1158
  ),
1159
 
 
1176
  " AND subtype = '{target_subtype}'"
1177
  ),
1178
  question_hints=[
1179
+ "island territories of {anchor_name}",
1180
+ "overseas island {target_subtype}s belonging to {anchor_name}",
1181
+ "which islands are part of {anchor_name}?",
1182
+ "land territories of {anchor_name}",
1183
+ "island possessions of {anchor_name}",
1184
  "{anchor_name}'s island {target_subtype}s",
1185
  ],
1186
  ),
 
1201
  " AND subtype = '{target_subtype}'"
1202
  ),
1203
  question_hints=[
1204
+ "territorial {target_subtype}s of {anchor_name}",
1205
+ "official territorial divisions of {anchor_name}",
1206
+ "recognised territorial {target_subtype}s belonging to {anchor_name}",
1207
+ "which territorial regions does {anchor_name} have?",
1208
  ],
1209
  ),
1210
 
 
1224
  " AND is_land = TRUE"
1225
  ),
1226
  question_hints=[
1227
+ "land-based {target_subtype}s of {anchor_name}",
1228
  "{target_subtype}s on the mainland of {anchor_name}",
1229
+ "all {target_subtype}s on land in {anchor_name}",
1230
+ "non-island {target_subtype}s of {anchor_name}",
1231
  ],
1232
  ),
1233
 
 
1253
  " AND ST_Intersects(a.geometry, n.geometry)"
1254
  ),
1255
  question_hints=[
1256
+ "what rivers or lakes are in {anchor_name}?",
1257
+ "natural water features of {anchor_name}",
1258
+ "which rivers flow through {anchor_name}?",
1259
+ "lakes and rivers within {anchor_name}",
1260
+ "water features inside {anchor_name}",
1261
+ "what bodies of water cross {anchor_name}?",
1262
+ "rivers of {anchor_name}",
1263
+ "show me the lakes in {anchor_name}",
1264
  ],
1265
  ),
1266
 
 
1282
  " AND ST_Intersects(a.geometry, n.geometry)"
1283
  ),
1284
  question_hints=[
1285
+ "what mountain ranges are in {anchor_name}?",
1286
+ "terrain features of {anchor_name}",
1287
+ "which mountain ranges cross {anchor_name}?",
1288
+ "landforms inside {anchor_name}",
1289
+ "peninsulas and ranges in {anchor_name}",
1290
+ "geographic features within {anchor_name}",
1291
+ "mountains of {anchor_name}",
1292
+ "what terrain does {anchor_name} contain?",
1293
  ],
1294
  ),
1295
 
 
1317
  " AND ST_Intersects(b.geometry, a.geometry)"
1318
  ),
1319
  question_hints=[
1320
+ "which regions does the {anchor_name} pass through?",
1321
+ "what admin regions overlap with the {anchor_name}?",
1322
+ "regions that the {anchor_name} crosses",
1323
+ "admin areas intersected by the {anchor_name}",
1324
+ "what provinces does the {anchor_name} span?",
1325
+ "regions along the {anchor_name}",
1326
+ "which provinces overlap the {anchor_name}?",
1327
  ],
1328
  ),
1329
 
 
1344
  " WHERE ST_Intersects(n.geometry, a.geometry)"
1345
  ),
1346
  question_hints=[
1347
+ "what natural features intersect {anchor_name}?",
1348
+ "natural features that overlap {anchor_name}",
1349
+ "which geographic features cross {anchor_name}?",
1350
+ "everything natural that touches {anchor_name}",
1351
+ "what geographic features does {anchor_name} contain?",
1352
+ "natural features within or crossing {anchor_name}",
1353
  ],
1354
  ),
1355
 
 
1380
  " )"
1381
  ),
1382
  question_hints=[
1383
+ "riverside {target_subtype}s in {anchor_name}",
1384
  "{target_subtype}s in {anchor_name} near a river or lake",
1385
+ "which {target_subtype}s in {anchor_name} are on a waterway?",
1386
+ "lakeside or riverside {target_subtype}s within {anchor_name}",
1387
  "{target_subtype}s in {anchor_name} that touch a river",
1388
+ "which {target_subtype}s in {anchor_name} are on a lake?",
1389
+ "waterfront {target_subtype}s of {anchor_name}",
1390
  ],
1391
  ),
1392
 
 
1413
  " )"
1414
  ),
1415
  question_hints=[
1416
+ "mountain {target_subtype}s in {anchor_name}",
1417
  "{target_subtype}s in {anchor_name} on a mountain range",
1418
+ "which {target_subtype}s in {anchor_name} are in the mountains?",
1419
+ "highland {target_subtype}s within {anchor_name}",
1420
  "{target_subtype}s of {anchor_name} in mountainous terrain",
1421
  "{target_subtype}s in {anchor_name} near a mountain range",
1422
  ],
 
1449
  " )"
1450
  ),
1451
  question_hints=[
1452
+ "coastal {target_subtype}s of {anchor_name}",
1453
+ "which districts of {anchor_name} are on the coast?",
1454
  "{target_subtype}s in {anchor_name} that border the sea",
1455
+ "seaside {target_subtype}s within {anchor_name}",
1456
  "{target_subtype}s of {anchor_name} with ocean access",
1457
+ "which {target_subtype}s in {anchor_name} touch the sea?",
1458
+ "maritime {target_subtype}s of {anchor_name}",
1459
  ],
1460
  ),
1461
 
 
1482
  " )"
1483
  ),
1484
  question_hints=[
1485
+ "landlocked {target_subtype}s of {anchor_name}",
1486
+ "which districts of {anchor_name} have no coastline?",
1487
+ "interior {target_subtype}s within {anchor_name}",
1488
  "{target_subtype}s in {anchor_name} with no sea access",
1489
+ "non-coastal {target_subtype}s of {anchor_name}",
1490
+ "inland {target_subtype}s of {anchor_name}",
1491
  ],
1492
  ),
1493
 
 
1514
  " )"
1515
  ),
1516
  question_hints=[
1517
+ "riverside {target_subtype}s of {anchor_name}",
1518
+ "which districts of {anchor_name} have a river or lake?",
1519
  "{target_subtype}s in {anchor_name} on a waterway",
1520
+ "lakeside {target_subtype}s within {anchor_name}",
1521
  "{target_subtype}s of {anchor_name} along a river",
1522
+ "which {target_subtype}s in {anchor_name} border a lake?",
1523
  ],
1524
  ),
1525
 
 
1546
  " )"
1547
  ),
1548
  question_hints=[
1549
+ "mountain {target_subtype}s of {anchor_name}",
1550
+ "which districts of {anchor_name} are in the mountains?",
1551
  "{target_subtype}s in {anchor_name} on a mountain range",
1552
+ "highland {target_subtype}s within {anchor_name}",
1553
  "{target_subtype}s of {anchor_name} in mountainous terrain",
1554
+ "which {target_subtype}s in {anchor_name} have mountain ranges?",
1555
  ],
1556
  ),
1557
 
 
1577
  " AND ST_Intersects(b.geometry, a.geometry)"
1578
  ),
1579
  question_hints=[
1580
+ "which countries border the {anchor_name}?",
1581
+ "what countries are along the {anchor_name}?",
1582
+ "countries surrounding the {anchor_name}",
1583
+ "nations on the {anchor_name}",
1584
+ "which countries touch the {anchor_name}?",
1585
+ "countries with coastline on the {anchor_name}",
1586
+ "what nations lie on the {anchor_name}?",
1587
  ],
1588
  ),
1589
 
 
1610
  " WHERE ST_Intersects(n.geometry, a.geom)"
1611
  ),
1612
  question_hints=[
1613
+ "natural features within {buffer_km} km of the {anchor_name}",
1614
+ "what's within {buffer_km} km of the {anchor_name}?",
1615
+ "geographic features near the {anchor_name} within {buffer_km} km",
1616
+ "everything within {buffer_km} km of the {anchor_name}",
1617
+ "what natural features are close to the {anchor_name}?",
1618
  "{buffer_km} km radius around the {anchor_name}",
1619
  ],
1620
  ),