Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 92 additions & 77 deletions asset-preprocessor/src/parse_shapefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl VertexBuffer {
}

struct Shapefile {
entries: Vec<AreaRings>,
entries: Vec<細分区域Rings>,
}

impl Shapefile {
Expand Down Expand Up @@ -71,32 +71,35 @@ Please follow:
let entries = reader
.iter_shapes_and_records()
.flatten()
.flat_map(|shape_record| AreaRings::try_new(shape_record.0, shape_record.1))
.flat_map(|shape_record| 細分区域Rings::try_new(shape_record.0, shape_record.1))
.collect();

Self { entries }
}
}

struct AreaRings {
area_code: codes::Area,
struct 細分区域Rings {
細分区域: codes::地震情報細分区域,
bounding_box: BoundingBox<GeoDegree>,
rings: Vec<Ring>,
}

impl AreaRings {
impl 細分区域Rings {
fn try_new(shape: Shape, record: Record) -> Option<Self> {
let Shape::Polygon(polygon) = shape else {
return None;
};
let area_code: codes::Area = match record.get("code").unwrap() {

let 細分区域: codes::地震情報細分区域 = match record.get("code").unwrap() {
FieldValue::Character(Some(c)) => match c.parse() {
Ok(c) => c,
Ok(c) => codes::地震情報細分区域(c),
Err(_) => panic!("コワッ…コワれたshapefileきた!"),
},
FieldValue::Character(None) => codes::UNNUMBERED_AREA, // 北方領土・諸外国等がNoneになる

FieldValue::Character(None) => codes::地震情報細分区域::UNNUMBERED, // 北方領土・諸外国等がNoneになる
_ => panic!("知らないshapefileきた?🤔"),
};

let bounding_box = (*polygon.bbox()).into();
let rings = polygon
.rings()
Expand All @@ -105,7 +108,7 @@ impl AreaRings {
.collect();

Some(Self {
area_code,
細分区域,
bounding_box,
rings,
})
Expand All @@ -119,20 +122,20 @@ pub(crate) struct PointReferences<'a> {
impl<'a> PointReferences<'a> {
fn tally_of(
shapefile: &'a Shapefile,
area_to_pref: &'a HashMap<codes::Area, codes::Pref>,
細分区域_to_都道府県等: &'a HashMap<codes::地震情報細分区域, codes::地震情報都道府県等>,
) -> Self {
let mut map: HashMap<Point, PointReference> = HashMap::new();

shapefile.entries.iter().for_each(|area_rings| {
let area_code = area_rings.area_code;
shapefile.entries.iter().for_each(|rings| {
let 細分区域 = rings.細分区域;

area_rings.rings.iter().for_each(|ring| {
rings.rings.iter().for_each(|ring| {
ring.iter_adjacent_points().for_each(|point_set| {
let reference = map
.entry(point_set.current)
.or_insert(PointReference::new(area_to_pref));
.or_insert(PointReference::new(細分区域_to_都道府県等));

reference.mark_area(area_code);
reference.mark_細分区域(細分区域);
reference.mark_point(point_set.previous);
reference.mark_point(point_set.next);
});
Expand All @@ -150,67 +153,74 @@ impl<'a> PointReferences<'a> {
.collect()
}

fn pref_reference_count(&self, line: &Line) -> usize {
fn 都道府県等_reference_count(&self, line: &Line) -> usize {
let first = self.map.get(line.vertices.first().unwrap()).unwrap();
let last = self.map.get(line.vertices.last().unwrap()).unwrap();

first
.pref_references()
.intersection(&last.pref_references())
.都道府県等_references()
.intersection(&last.都道府県等_references())
.count()
}
}

pub(crate) struct PointReference<'a> {
area_to_pref: &'a HashMap<codes::Area, codes::Pref>,
areas: HashSet<codes::Area>,
細分区域_to_都道府県等: &'a HashMap<codes::地震情報細分区域, codes::地震情報都道府県等>,
細分区域s: HashSet<codes::地震情報細分区域>,
adjacent_points: HashSet<Point>,
}

impl<'a> PointReference<'a> {
fn new(area_to_pref: &'a HashMap<codes::Area, codes::Pref>) -> Self {
fn new(
細分区域_to_都道府県等: &'a HashMap<codes::地震情報細分区域, codes::地震情報都道府県等>
) -> Self {
Self {
area_to_pref,
areas: HashSet::new(),
細分区域_to_都道府県等,
細分区域s: HashSet::new(),
adjacent_points: HashSet::new(),
}
}

fn mark_area(&mut self, area: codes::Area) {
self.areas.insert(area);
fn mark_細分区域(&mut self, 細分区域: codes::地震情報細分区域) {
self.細分区域s.insert(細分区域);
}

fn mark_point(&mut self, point: Point) {
self.adjacent_points.insert(point);
}

fn area_references(&self) -> &HashSet<codes::Area> {
&self.areas
fn 細分区域_references(&self) -> &HashSet<codes::地震情報細分区域> {
&self.細分区域s
}

pub(crate) fn pref_references(&self) -> HashSet<codes::Pref> {
let areas = self
.area_references()
pub(crate) fn 都道府県等_references(&self) -> HashSet<codes::地震情報都道府県等> {
let 都道府県等s = self
.細分区域_references()
.iter()
.filter(|a| **a != codes::UNNUMBERED_AREA)
.map(|a| *self.area_to_pref.get(a).unwrap());
HashSet::from_iter(areas)
.filter(|a| **a != codes::地震情報細分区域::UNNUMBERED)
.map(|a| *self.細分区域_to_都道府県等.get(a).unwrap());

HashSet::from_iter(都道府県等s)
}

fn adjacent_points_count(&self) -> usize {
self.adjacent_points.len()
}
}

pub fn read(
#[allow(non_snake_case)] area_code__pref_code: &HashMap<codes::Area, codes::Pref>,
#[allow(non_snake_case)] 細分区域_to_都道府県等: &HashMap<
codes::地震情報細分区域,
codes::地震情報都道府県等,
>,
) -> (
HashMap<codes::Area, BoundingBox<GeoDegree>>, // area_bounding_box
HashMap<codes::Area, Vertex<GeoDegree>>, // area_centers
Vec<(f32, f32)>, // vertex_buffer
Vec<u32>, // map_indices
Vec<Vec<u32>>, // area_lines
Vec<Vec<u32>>, // pref_lines
Vec<(f32, usize)>, // scale_level_map
HashMap<codes::地震情報細分区域, BoundingBox<GeoDegree>>, // area_bounding_box
HashMap<codes::地震情報細分区域, Vertex<GeoDegree>>, // area_centers
Vec<(f32, f32)>, // vertex_buffer
Vec<u32>, // map_indices
Vec<Vec<u32>>, // area_lines
Vec<Vec<u32>>, // pref_lines
Vec<(f32, usize)>, // scale_level_map
) {
let shapefile = Shapefile::new(
"../assets/shapefile/earthquake_detailed/earthquake_detailed_simplified.shp",
Expand All @@ -220,24 +230,27 @@ pub fn read(

// @Siro_256 にゃ~っ…! (ΦωΦ)

let area_centers = calculate_area_centers(&shapefile);
let 細分区域_centers = calculate_細分区域_centers(&shapefile);

let area_bounding_box: HashMap<codes::Area, BoundingBox<GeoDegree>> = shapefile
.entries
.iter()
.filter(|area_rings| area_rings.area_code != codes::UNNUMBERED_AREA)
.map(|area_rings| (area_rings.area_code, area_rings.bounding_box))
.collect();
let 細分区域_bounding_box: HashMap<codes::地震情報細分区域, BoundingBox<GeoDegree>> =
shapefile
.entries
.iter()
.filter(|rings| {
rings.細分区域 != codes::地震情報細分区域::UNNUMBERED
})
.map(|rings| (rings.細分区域, rings.bounding_box))
.collect();

let map_indices = shapefile
.entries
.iter()
.flat_map(|area_rings| &area_rings.rings)
.flat_map(|r| r.triangulate())
.map(|p| vertex_buffer.insert(p.into()) as u32)
.flat_map(|rings| &rings.rings)
.flat_map(|ring| ring.triangulate())
.map(|point| vertex_buffer.insert(point.into()) as u32)
.collect();

let references = PointReferences::tally_of(&shapefile, area_code__pref_code);
let references = PointReferences::tally_of(&shapefile, 細分区域_to_都道府県等);

let rings = shapefile
.entries
Expand All @@ -255,14 +268,14 @@ pub fn read(
.filter_map(|(l, c)| if c > 1 { Some(l) } else { None })
.collect();

let area_lines = lines
let 細分区域_lines = lines
.iter()
.filter(|l| references.pref_reference_count(l) == 1)
.filter(|l| references.都道府県等_reference_count(l) == 1)
.collect_vec();

let pref_lines = lines
let 都道府県等_lines = lines
.iter()
.filter(|l| references.pref_reference_count(l) >= 2)
.filter(|l| references.都道府県等_reference_count(l) >= 2)
.collect_vec();

let lod_details = [
Expand Down Expand Up @@ -308,8 +321,8 @@ pub fn read(
(100.0_f32.powf(0.24), 0.117),
];

let area_lines = gen_lod(&mut vertex_buffer, &lod_details, &area_lines);
let pref_lines = gen_lod(&mut vertex_buffer, &lod_details, &pref_lines);
let 細分区域_lines = gen_lod(&mut vertex_buffer, &lod_details, &細分区域_lines);
let 都道府県等_lines = gen_lod(&mut vertex_buffer, &lod_details, &都道府県等_lines);

let scale_level_map = lod_details
.into_iter()
Expand All @@ -322,12 +335,12 @@ pub fn read(
// (ΦωΦ) < Meow !
{
(
area_bounding_box,
area_centers,
細分区域_bounding_box,
細分区域_centers,
vertex_buffer.into_buffer(),
map_indices,
area_lines,
pref_lines,
細分区域_lines,
都道府県等_lines,
scale_level_map,
)
}
Expand Down Expand Up @@ -400,58 +413,60 @@ fn gen_lod(
.collect()
}

fn calculate_area_centers(shapefile: &Shapefile) -> HashMap<codes::Area, Vertex<GeoDegree>> {
fn calculate_細分区域_centers(
shapefile: &Shapefile,
) -> HashMap<codes::地震情報細分区域, Vertex<GeoDegree>> {
use geo::{
algorithm::{Area, Centroid},
LineString, Polygon,
};

let area_weighted_vectors: HashMap<codes::Area, Vec<(f64, geo::Point)>> = shapefile
let weighted_vectors: HashMap<codes::地震情報細分区域, Vec<(f64, geo::Point)>> = shapefile
.entries
.iter()
.filter(|area_rings| area_rings.area_code != codes::UNNUMBERED_AREA)
.map(|area_rings| {
let area_polygons: Vec<(f64, geo::Point)> = area_rings
.filter(|rings| rings.細分区域 != codes::地震情報細分区域::UNNUMBERED)
.map(|rings| {
let polygons: Vec<(f64, geo::Point)> = rings
.rings
.iter()
.map(|ring| LineString::new(ring.points().iter().map(|p| p.into()).collect_vec()))
.map(|geo_line_string| Polygon::new(geo_line_string, vec![]))
.map(|geo_polygon| (geo_polygon.unsigned_area(), geo_polygon.centroid().unwrap()))
.collect();

(area_rings.area_code, area_polygons)
(rings.細分区域, polygons)
})
.collect();

let area_centers: HashMap<codes::Area, Point> = area_weighted_vectors
let centers: HashMap<codes::地震情報細分区域, Point> = weighted_vectors
.into_iter()
.map(|(area_code, weighted_vectors)| {
let area_weight: f64 = weighted_vectors
.map(|(細分区域, weighted_vectors)| {
let weight: f64 = weighted_vectors
.iter()
.map(|(weight, _vector)| weight)
.sum();

let area_vector: Point = weighted_vectors
let vector: Point = weighted_vectors
.iter()
.map(|(weight, vector)| {
let vector: Point = vector.into();
vector.multiply_by(*weight as f32)
})
.fold(Point::new(0.0.into(), 0.0.into()), |a, b| a + b);

(area_code, area_vector.divide_by(area_weight as f32))
(細分区域, vector.divide_by(weight as f32))
})
.collect();

let area_centers: HashMap<codes::Area, Vertex<GeoDegree>> = area_centers
let centers: HashMap<codes::地震情報細分区域, Vertex<GeoDegree>> = centers
.into_iter()
.map(|(area_code, center)| {
.map(|(code, center)| {
(
area_code,
code,
Vertex::new(center.latitude.into(), center.longitude.into()),
)
})
.collect();

area_centers
centers
}
13 changes: 6 additions & 7 deletions asset-preprocessor/src/parse_tsunami_shapefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl VertexBuffer {

struct AreaLines {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AreaLines -> 津波予報区Lines

lines: Vec<Line>,
tsunami_area_code: codes::TsunamiArea,
津波予報区: codes::津波予報区,
}

impl AreaLines {
Expand All @@ -81,17 +81,16 @@ impl AreaLines {
return None;
};

let tsunami_area_code: codes::TsunamiArea = match record.get("code").unwrap() {
let 津波予報区: codes::津波予報区 = match record.get("code").unwrap() {
FieldValue::Character(Some(c)) => match c.parse() {
Ok(c) => c,
Ok(c) => codes::津波予報区(c),
Err(_) => panic!("Failed to parse code"),
},
FieldValue::Character(None) => panic!("UNNUMBERED_AREA DETECTED!"),
_ => panic!("Failed to get code"),
};

// 帰属未定 (極小の島など)
if tsunami_area_code == 0 {
if 津波予報区 == codes::津波予報区::帰属未定 {
return None;
}

Expand All @@ -103,7 +102,7 @@ impl AreaLines {

Some(Self {
lines,
tsunami_area_code,
津波予報区,
})
}
}
Expand Down Expand Up @@ -167,7 +166,7 @@ pub fn read() -> (
vertex_buffer.insert((
Of32::from(v.longitude),
Of32::from(v.latitude),
tsunami_area_code_buffer.insert(e.tsunami_area_code),
tsunami_area_code_buffer.insert(e.津波予報区.0),
)) as u32
})
.collect();
Expand Down
Loading
Loading