import_osm: add osm_multipolygons
This commit is contained in:
parent
a3ecb3ed5a
commit
2958855a2b
12
db.sql
12
db.sql
|
@ -25,3 +25,15 @@ CREATE TABLE osm_ways (
|
|||
attrs jsonb
|
||||
);
|
||||
CREATE INDEX osm_ways_box_coords ON osm_ways USING GIST (box(polygon(pclose(geo))));
|
||||
|
||||
CREATE TABLE osm_multipolygons (
|
||||
id bigint,
|
||||
attrs jsonb
|
||||
);
|
||||
CREATE TABLE osm_multipolygon_members (
|
||||
id bigint,
|
||||
m_geo polygon,
|
||||
m_role text,
|
||||
m_id bigint
|
||||
);
|
||||
CREATE INDEX osm_ways_box_coords ON osm_ways USING GIST (box(m_geo));
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::sync::Arc;
|
|||
use std::thread;
|
||||
|
||||
use osm_pbf_iter::*;
|
||||
use geo::LineString;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
|
||||
pub struct PrimSource {
|
||||
|
@ -143,7 +144,7 @@ fn main() {
|
|||
println!("{} nodes", node_coords.len());
|
||||
let node_coords = Arc::new(node_coords);
|
||||
|
||||
let mut way_coords: HashMap<i64, Vec<(f64, f64)>> = HashMap::new();
|
||||
let mut way_paths: HashMap<i64, LineString<f64>> = HashMap::new();
|
||||
// phase 2: ways
|
||||
for arg in args().skip(1) {
|
||||
let node_coords = node_coords.clone();
|
||||
|
@ -166,13 +167,15 @@ fn main() {
|
|||
let tags: serde_json::Map<String, serde_json::Value> = way.tags()
|
||||
.map(|(k, v)| (k.to_string(), serde_json::Value::String(v.to_string())))
|
||||
.collect();
|
||||
let points = way.refs()
|
||||
.filter_map(|id| node_coords.get(&id))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
let points = LineString::from(
|
||||
way.refs()
|
||||
.filter_map(|id| node_coords.get(&id))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
tx.execute(
|
||||
"INSERT INTO osm_ways (geo, id, attrs) VALUES ($1, $2, $3)",
|
||||
&[&geo::LineString::from(points.clone()), &(way.id as i64), &serde_json::Value::Object(tags)]
|
||||
&[&points, &(way.id as i64), &serde_json::Value::Object(tags)]
|
||||
).unwrap();
|
||||
res.insert(way.id as i64, points);
|
||||
}
|
||||
|
@ -187,17 +190,85 @@ fn main() {
|
|||
res
|
||||
});
|
||||
for mut res in worker_res {
|
||||
if way_coords.is_empty() {
|
||||
way_coords = res;
|
||||
if way_paths.is_empty() {
|
||||
way_paths = res;
|
||||
} else {
|
||||
// merge
|
||||
for (id, coords) in res.drain() {
|
||||
way_coords.insert(id, coords);
|
||||
way_paths.insert(id, coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let way_coords = Arc::new(way_coords);
|
||||
let way_paths = Arc::new(way_paths);
|
||||
|
||||
// phase 3: rels (TODO)
|
||||
// phase 3: rels
|
||||
for arg in args().skip(1) {
|
||||
let way_paths = way_paths.clone();
|
||||
process_osm(&arg, move |prim_src| {
|
||||
const DB_URL: &str = "host=10.233.1.2 dbname=treeadvisor user=treeadvisor password=123";
|
||||
|
||||
let mut db = postgres::Client::connect(DB_URL, postgres::NoTls)
|
||||
.expect("DB");
|
||||
|
||||
let mut running = true;
|
||||
while running {
|
||||
running = prim_src.recv_primitives(|iter| {
|
||||
let mut tx = db.transaction().unwrap();
|
||||
for primitive in iter {
|
||||
match primitive {
|
||||
Primitive::Node(_) => {}
|
||||
Primitive::Way(_) => {}
|
||||
Primitive::Relation(rel) => {
|
||||
let tags: serde_json::Map<String, serde_json::Value> = rel.tags()
|
||||
.map(|(k, v)| (k.to_string(), serde_json::Value::String(v.to_string())))
|
||||
.collect();
|
||||
let get_members = |target_role| rel.members()
|
||||
.filter_map(|(role, id, member_type)| {
|
||||
if member_type == RelationMemberType::Way && role == target_role {
|
||||
way_paths.get(&(id as i64))
|
||||
.and_then(|path| {
|
||||
if path.is_closed() {
|
||||
Some((id, path))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let outers = get_members("outer");
|
||||
if outers.len() > 0 {
|
||||
tx.execute(
|
||||
"INSERT INTO osm_multipolygons (id, attrs) VALUES ($1, $2)",
|
||||
&[&(rel.id as i64), &serde_json::Value::Object(tags)]
|
||||
).unwrap();
|
||||
|
||||
for (member_id, path) in outers.into_iter() {
|
||||
tx.execute(
|
||||
"INSERT INTO osm_multipolygon_members (id, m_id, m_role, m_geo) VALUES ($1, $2, 'outer', polygon(pclose($3::path)))",
|
||||
&[&(rel.id as i64), &(member_id as i64), &path]
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
let inners = get_members("inner");
|
||||
for (member_id, path) in inners.into_iter() {
|
||||
tx.execute(
|
||||
"INSERT INTO osm_multipolygon_members (id, m_id, m_role, m_geo) VALUES ($1, $2, 'inner', polygon(pclose($3::path)))",
|
||||
&[&(rel.id as i64), &(member_id as i64), &path]
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tx.commit().unwrap();
|
||||
|
||||
true
|
||||
}).unwrap_or(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue