tangled
alpha
login
or
join now
serendipty01.dev
/
smokesignal
forked from
smokesignal.events/smokesignal
0
fork
atom
The smokesignal.events web application
0
fork
atom
overview
issues
pulls
pipelines
feature: index geo locations
Nick Gerakines
2 months ago
f99cc17b
9048d557
+36
1 changed file
expand all
collapse all
unified
split
src
search_index.rs
+36
src/search_index.rs
···
22
22
Some(cid.to_string())
23
23
}
24
24
25
25
+
/// Extract geo coordinates from a LocationOrRef if it's an InlineGeo variant.
26
26
+
/// Returns None if the location is not a geo type or has invalid coordinates.
27
27
+
fn extract_geo_point(location: &LocationOrRef) -> Option<GeoPoint> {
28
28
+
if let LocationOrRef::InlineGeo(typed_geo) = location {
29
29
+
let geo = &typed_geo.inner;
30
30
+
let lat = geo.latitude.parse::<f64>().ok()?;
31
31
+
let lon = geo.longitude.parse::<f64>().ok()?;
32
32
+
// Validate coordinate ranges
33
33
+
if (-90.0..=90.0).contains(&lat) && (-180.0..=180.0).contains(&lon) {
34
34
+
Some(GeoPoint { lat, lon })
35
35
+
} else {
36
36
+
None
37
37
+
}
38
38
+
} else {
39
39
+
None
40
40
+
}
41
41
+
}
42
42
+
25
43
const INDEX_NAME: &str = "smokesignal-events";
26
44
45
45
+
/// A geographic point for OpenSearch geo_point field.
46
46
+
#[derive(Debug, Serialize, Deserialize, Clone)]
47
47
+
pub struct GeoPoint {
48
48
+
pub lat: f64,
49
49
+
pub lon: f64,
50
50
+
}
51
51
+
27
52
#[derive(Debug, Serialize, Deserialize)]
28
53
pub struct IndexedEvent {
29
54
pub aturi: String,
···
34
59
pub tags: Vec<String>,
35
60
#[serde(default)]
36
61
pub location_cids: Vec<String>,
62
62
+
#[serde(default)]
63
63
+
pub locations_geo: Vec<GeoPoint>,
37
64
pub start_time: Option<String>,
38
65
pub end_time: Option<String>,
39
66
pub created_at: String,
···
280
307
"description": { "type": "text" },
281
308
"tags": { "type": "keyword" },
282
309
"location_cids": { "type": "keyword" },
310
310
+
"locations_geo": { "type": "geo_point" },
283
311
"start_time": { "type": "date" },
284
312
"end_time": { "type": "date" },
285
313
"created_at": { "type": "date" },
···
337
365
.filter_map(generate_location_cid)
338
366
.collect();
339
367
368
368
+
// Extract geo coordinates
369
369
+
let locations_geo: Vec<GeoPoint> = event_record
370
370
+
.locations
371
371
+
.iter()
372
372
+
.filter_map(extract_geo_point)
373
373
+
.collect();
374
374
+
340
375
let mut doc = json!({
341
376
"aturi": event.aturi,
342
377
"did": event.did,
···
345
380
"description": event_record.description,
346
381
"tags": tags,
347
382
"location_cids": location_cids,
383
383
+
"locations_geo": locations_geo,
348
384
"created_at": json!(event_record.created_at),
349
385
"updated_at": json!(chrono::Utc::now())
350
386
});