Crates.io | street_index |
lib.rs | street_index |
version | 0.1.1 |
source | src |
created_at | 2018-08-04 16:15:45.51687 |
updated_at | 2018-08-08 03:49:44.294683 |
description | street_index is a small utility crate for working with road name / street indexing for cartographic purposes |
homepage | https://github.com/fschutt/street_index |
repository | https://github.com/fschutt/street_index |
max_upload_size | |
id | 77495 |
size | 32,029 |
This library contains utility functions for generating a street index.
How it works is fairly simple: You give it a grid (right now limited
to a rectangular grid) on a page, and add StreetNameRect
s. Each
StreetNameRect
contains the String for the street / road name as well
as the extents of the laid out String on the map.
The Grid
takes care of assigning a grid position to your street name
such as "Canterbury Road => A2"
. Since usually maps have the problem
of having duplicated road names (which is not what you'd want in a street
index), you can create a DeduplicatedRoadNames::from_streets
, which will
deduplicate all road names.
The problem generally arises when street names are ambigouus. For example, a street that appears in two locations on the map (such as a city having the same street name as a neighbouring city). Because of this, street name processing can't be fully automated, since there are always weird edge cases to worry about. However, 90% of roads aren't like that.
Because of this limitation DeduplicatedRoadNames::process()
gives you
two types of roads back: ProcessedRoadName
is for roads that span only
1 or 2 grid cells (i.e. "Canterbury Road" => A9
, "Canterbury Road" => A9-A10
).
In these cases (which cover 90% of street index names), the mapping is not
ambigouus.
UnprocessedRoadName
is for anything else (e.g. "Canterbury Road" => [A9, A10, E1, E2]
.
Usually these roads need to be manually reviewed - it could likely be that
there are two roads "Canterbury Road" => A9-10;E1-E2
, but it could also
be that the road is just one road and part of it is just clipped off the map,
in which case you'd write "Canterbury Road" => A9-E2
.
For cartographic purposes, usually you want the output in CSV format, so
that your graphic designer can paste the street index into InDesign /
Illustrator for the final map layout. Both UnprocessedRoads
and
ProcessedRoads
have a simple .to_csv
function for easy export.
extern crate street_index;
use street_index::prelude::*;
fn main() {
// Create a grid, with the page extensions being 200 x 200 millimeter
// Each cell is 20x20 millimeter large (usually 50x50 is recommended, though)
let mut grid = Grid::new(
Bbox {
width: Millimeter(200.0),
height: Millimeter(200.0)
},
GridConfig {
cell_width: Millimeter(20.0),
cell_height: Millimeter(20.0),
});
// You will have to calculate the street name boundaries yourself, i.e.
// using FreeType or RustType. Often times this will come as a side-effect
// of your map rendering / layouting program.
//
// The position is relative to the top left of the grid.
grid.insert_street(StreetNameRect {
street_name: String::from("Canterbury Road"),
x_from_left: Millimeter(30.0),
width: Millimeter(50.0),
y_from_top: Millimeter(30.0),
height: Millimeter(8.0),
});
// We deduplicate the roads, i.e.:
//
// ```
// "Canterbury Road" => A3
// "Canterbury Road" => A4
// ```
//
// becomes:
//
// ```
// "Canterbury Road" => [A3, A4]
// ```
let deduplicated = DeduplicatedRoads::from_streets(&grid.street_names());
// As described above, we get both processed and unprocessed
// road names back
let (processed, unprocessed) = deduplicated.process();
// In this case, "Canterbury Road" spans from B1-B2, so we get a
// `ProcessedRoad` back, delimited by a TAB character.
//
// You can then write this to a CSV file if you want.
println!("processed:\r\n{}", processed.to_csv("\t"));
println!("unprocessed:\r\n{}", unprocessed.to_csv("\t"));
}
This library is licensed under the MIT license.