use std::collections::HashMap;
use std::sync::Arc;
use interstellar::geo::Point;
use interstellar::gremlin::ExecutionResult;
use interstellar::index::IndexBuilder;
use interstellar::storage::Graph;
use interstellar::value::Value;
fn city_props(name: &str, lon: f64, lat: f64) -> HashMap<String, Value> {
let mut m = HashMap::new();
m.insert("name".into(), Value::String(name.into()));
m.insert(
"location".into(),
Value::Point(Point::new(lon, lat).expect("valid coord")),
);
m
}
fn main() {
println!("=== Interstellar Geospatial Quickstart ===\n");
let graph = Arc::new(Graph::new());
let spec = IndexBuilder::vertex()
.label("city")
.property("location")
.rtree()
.build()
.expect("valid index spec");
graph.create_index(spec).expect("index creation failed");
println!("Created R-tree index on city.location\n");
let cities = [
("New York", -74.006, 40.7128),
("Los Angeles", -118.2437, 33.9425),
("Chicago", -87.6298, 41.8781),
("Houston", -95.3698, 29.7604),
("Phoenix", -112.074, 33.4484),
("Philadelphia", -75.1652, 39.9526),
("San Antonio", -98.4936, 29.4241),
("San Diego", -117.1611, 32.7157),
("Dallas", -96.797, 32.7767),
("London", -0.1278, 51.5074),
("Paris", 2.3522, 48.8566),
("Tokyo", 139.6917, 35.6895),
("Sydney", 151.2093, -33.8688),
("São Paulo", -46.6333, -23.5505),
("Mumbai", 72.8777, 19.076),
];
for (name, lon, lat) in &cities {
graph.add_vertex("city", city_props(name, *lon, *lat));
}
println!("Loaded {} cities\n", cities.len());
println!("-- US West cities via Gremlin bbox --\n");
let result = graph
.query(
"g.V().hasLabel('city')\
.has('location', geo_bbox(-125.0, 30.0, -100.0, 50.0))\
.values('name').toList()",
)
.expect("gremlin query failed");
if let ExecutionResult::List(names) = result {
for name in &names {
if let Value::String(s) = name {
println!(" - {s}");
}
}
}
println!("\n-- Cities within 1000 km of London via Gremlin --\n");
let result = graph
.query(
"g.V().hasLabel('city')\
.has('location', geo_within_distance(point(-0.1278, 51.5074), 1000km))\
.values('name').toList()",
)
.expect("gremlin query failed");
if let ExecutionResult::List(names) = result {
for name in &names {
if let Value::String(s) = name {
println!(" - {s}");
}
}
}
println!("\n-- European cities via Gremlin containedBy --\n");
let result = graph
.query(
"g.V().hasLabel('city')\
.has('location', geo_contained_by(polygon([[-10.0, 35.0], [40.0, 35.0], [40.0, 72.0], [-10.0, 72.0], [-10.0, 35.0]])))\
.values('name').toList()",
)
.expect("gremlin query failed");
if let ExecutionResult::List(names) = result {
for name in &names {
if let Value::String(s) = name {
println!(" - {s}");
}
}
}
println!("\n=== Done ===");
}