Skip to content

Instantly share code, notes, and snippets.

@kenji4569
Last active August 23, 2021 15:18
Show Gist options
  • Save kenji4569/bf62af09072af879831119596a6ae491 to your computer and use it in GitHub Desktop.
Save kenji4569/bf62af09072af879831119596a6ae491 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "af64b6f6",
"metadata": {},
"outputs": [],
"source": [
":dep plotters = { git = \"https://github.com/38/plotters\", default_features = true, features = [\"evcxr\"] }\n",
"extern crate plotters;\n",
"use plotters::prelude::*;\n",
"\n",
"// Please invoke evcxr_figure before using osmpbfreader due to a weird initialization probolem\n",
"evcxr_figure((10, 10), |root| {\n",
" root.fill(&BLUE)?;\n",
" Ok(())\n",
"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75bbcc68",
"metadata": {},
"outputs": [],
"source": [
"extern crate osmpbfreader;\n",
"use std::collections::HashMap;\n",
"\n",
"let filename = \"./kanto-latest.osm.pbf\";\n",
"let path = std::path::Path::new(filename);\n",
"let r = std::fs::File::open(&path).unwrap();\n",
"let mut pbf = osmpbfreader::OsmPbfReader::new(r);\n",
"\n",
"let south = 35.67945146006722;\n",
"let west = 139.7654845722708;\n",
"let north = south + 0.006;\n",
"let east = west + 0.006;\n",
"\n",
"fn to_decimicro(x: f32) -> i32 {\n",
" (x * 10000000f32) as i32\n",
"}\n",
"\n",
"let decimicro_south = to_decimicro(south);\n",
"let decimicro_west = to_decimicro(west);\n",
"let decimicro_north = to_decimicro(north);\n",
"let decimicro_east = to_decimicro(east);\n",
"\n",
"type NodeByNodeId = HashMap::<osmpbfreader::NodeId, osmpbfreader::Node>;\n",
"\n",
"let node_by_node_id = pbf.par_iter().filter_map(|obj| {\n",
" match obj.unwrap() {\n",
" osmpbfreader::OsmObj::Node(node) if \n",
" node.decimicro_lat >= decimicro_south && node.decimicro_lat <= decimicro_north &&\n",
" node.decimicro_lon >= decimicro_west && node.decimicro_lon <= decimicro_east=> {\n",
" Some((node.id, node))\n",
" }\n",
" _ => None\n",
" }\n",
"}).collect::<NodeByNodeId>();\n",
"\n",
"pbf.rewind();\n",
"\n",
"let ways = pbf.par_iter().filter_map(|obj| {\n",
" match obj.unwrap() {\n",
" osmpbfreader::OsmObj::Way(way) => {\n",
" let exists = way.nodes.iter().any(|node_id| {\n",
" node_by_node_id.contains_key(&node_id)\n",
" });\n",
" if exists { Some(way) } else { None }\n",
" }\n",
" _ => None\n",
" }\n",
"}).collect::<Vec::<osmpbfreader::Way>>();\n",
"\n",
"println!(\"{} nodes, {} ways\", node_by_node_id.len(), ways.len());"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "daeb6a9f",
"metadata": {},
"outputs": [],
"source": [
"use plotters::coord::types::RangedCoordf32;\n",
"\n",
"fn from_decimicro(x: i32) -> f32 {\n",
" x as f32 / 10000000 as f32\n",
"}\n",
"\n",
"let figure = evcxr_figure((640, 640), |root| {\n",
" root.fill(&WHITE);\n",
" \n",
" let root = root.apply_coord_spec(Cartesian2d::<RangedCoordf32, RangedCoordf32>::new(\n",
" west..east,\n",
" south..north,\n",
" (0..640, 0..640),\n",
" ));\n",
"\n",
" let dot = |x: f32, y: f32| {\n",
" return EmptyElement::at((x, y))\n",
" + Circle::new((0, 0), 3, ShapeStyle::from(&RGBColor(150, 150, 150)).filled());\n",
" };\n",
"\n",
" for node in node_by_node_id.values() {\n",
" root.draw(&dot(\n",
" from_decimicro(node.decimicro_lon), \n",
" north - from_decimicro(node.decimicro_lat) + south))?;\n",
" };\n",
" \n",
" let line = |x1: f32, y1: f32, x2: f32, y2: f32, color:RGBColor | {\n",
" return PathElement::new(vec![(x1, y1), (x2, y2)], &color);\n",
" };\n",
" \n",
" for way in ways.iter() {\n",
" let mut layer = -1;\n",
" for (k, v) in way.tags.iter() {\n",
" if k == \"highway\" {\n",
" if v == \"motorway\" || v == \"trunk\" || v == \"primary\" ||\n",
" v == \"motorway_link\" || v == \"trunk_link\" || v == \"primary_link\" {\n",
" layer = 1;\n",
" } else if v == \"secondary\" || v == \"tertiary\" || \n",
" v == \"secondary_link\" || v == \"tertiary_link\" || \n",
" v == \"unclassified\" || v == \"residential\" || v == \"living_street\" || v == \"service\" {\n",
" layer = 2;\n",
" } else {\n",
" layer = 3;\n",
" }\n",
" }\n",
" }\n",
" \n",
" for w in way.nodes.windows(2) {\n",
" let (prev_node_id, next_node_id) = (w[0], w[1]);\n",
" let prev_node = node_by_node_id.get(&prev_node_id);\n",
" let next_node = node_by_node_id.get(&next_node_id);\n",
"\n",
" if prev_node.is_some() && next_node.is_some() {\n",
" root.draw(&line(\n",
" from_decimicro(prev_node.unwrap().decimicro_lon), \n",
" north - from_decimicro(prev_node.unwrap().decimicro_lat) + south,\n",
" from_decimicro(next_node.unwrap().decimicro_lon), \n",
" north - from_decimicro(next_node.unwrap().decimicro_lat) + south,\n",
" match layer {\n",
" 1 => { RED }\n",
" 2 => { BLUE }\n",
" 3 => { GREEN }\n",
" _ => { RGBColor(200, 200, 200) }\n",
" }\n",
" ))?;\n",
" }\n",
" }\n",
" };\n",
" \n",
" Ok(())\n",
"});\n",
"figure"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Rust",
"language": "rust",
"name": "rust"
},
"language_info": {
"codemirror_mode": "rust",
"file_extension": ".rs",
"mimetype": "text/rust",
"name": "Rust",
"pygment_lexer": "rust",
"version": ""
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment