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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ jobs:
run: |
rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
7z x ./shapefiles_v1.zip -y
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
7z x ./shapefiles_v2.zip -y
popd

- uses: Swatinem/rust-cache@v2.9.1
Expand Down Expand Up @@ -140,8 +140,8 @@ jobs:

rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
unzip -o ./shapefiles_v1.zip
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
unzip -o ./shapefiles_v2.zip
popd
sudo apt-get update -y
sudo apt-get install -y protobuf-compiler
Expand Down Expand Up @@ -234,8 +234,8 @@ jobs:

rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
unzip -o ./shapefiles_v1.zip
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
unzip -o ./shapefiles_v2.zip
popd
sudo apt-get update -y
sudo apt-get install -y protobuf-compiler
Expand Down Expand Up @@ -305,8 +305,8 @@ jobs:

rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
unzip -o ./shapefiles_v1.zip
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
unzip -o ./shapefiles_v2.zip
popd
sudo apt-get update -y
sudo apt-get install -y protobuf-compiler
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/rendering.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ jobs:

rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
unzip -o ./shapefiles_v1.zip
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
unzip -o ./shapefiles_v2.zip
popd

- name: Get Rust toolchain
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ jobs:

rc alias set yr32srv https://rustfs-s3.yr32.net eewbot-ci "${{ secrets.YR32RUSTFS_EEWBOT_CI_SECRET }}"
pushd assets/shapefile/
rc cp yr32srv/eewbot/shapefiles_v1.zip ./shapefiles_v1.zip
unzip -o ./shapefiles_v1.zip
rc cp yr32srv/eewbot/shapefiles_v2.zip ./shapefiles_v2.zip
unzip -o ./shapefiles_v2.zip
popd
sudo apt-get update -y
sudo apt-get install -y protobuf-compiler
Expand Down
1 change: 1 addition & 0 deletions asset-preprocessor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ mod math;
pub mod parse_lake_shapefile;
pub mod parse_shapefile;
pub mod parse_tsunami_shapefile;
pub mod parse_world_shapefile;
136 changes: 136 additions & 0 deletions asset-preprocessor/src/parse_world_shapefile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#![allow(clippy::type_complexity)]

use std::collections::HashMap;

use shapefile::{Shape, ShapeReader};

use crate::math::*;

const WEB_MERCATOR_MAX_LATITUD: f32 = 85.051_13;

struct VertexBuffer {
buffer: Vec<(Of32, Of32)>,
dict: HashMap<(Of32, Of32), usize>,
}

impl VertexBuffer {
fn new() -> Self {
Self {
buffer: Default::default(),
dict: Default::default(),
}
}

fn insert(&mut self, v: (Of32, Of32)) -> usize {
match self.dict.get(&v) {
Some(index) => *index,
None => {
self.buffer.push(v);
let index = self.buffer.len() - 1;
self.dict.insert(v, index);
index
}
}
}

fn into_buffer(self) -> Vec<(f32, f32)> {
self.buffer.into_iter().map(|(x, y)| (x.0, y.0)).collect()
}
}

/// 極点での発散を避けるため、球面Web Mercatorで一般的に使用される打ち切り緯度 ±85.05113° を、レンダラーの描画上限として採用する。
/// 経度はそのまま返す。
fn clamp_mercator_latitude(point: Point) -> Point {
let latitude = point
.latitude
.0
.clamp(-WEB_MERCATOR_MAX_LATITUD, WEB_MERCATOR_MAX_LATITUD);

Point::new(Of32::from(latitude), point.longitude)
}

struct WorldRings {
rings: Vec<Ring>,
}

impl WorldRings {
fn from_shape(shape: Shape) -> Self {
let Shape::Polygon(polygon) = shape else {
panic!("world shapefile contains a non-Polygon shape");
};

let rings: Vec<_> = polygon
.rings()
.iter()
.map(|ring| Ring::from(ring.points().to_vec()))
.collect();

Self { rings }
}
}

struct Shapefile {
entries: Vec<WorldRings>,
}

impl Shapefile {
fn new() -> Self {
let shp_file = std::fs::File::open("../assets/shapefile/world/world.shp");

let Ok(shp_file) = shp_file else {
panic!(
r#"EEWBot Renderer requirements is not satisfied.

World shape file is not found.
- assets/shapefile/world/world.shp

Please follow:
https://github.com/EEWBot/eew-renderer/wiki#shapefile-%E5%85%A5%E6%89%8B%E5%85%88"#
)
};

let mut shape_reader = ShapeReader::new(shp_file).unwrap();

let entries = shape_reader
.iter_shapes()
.map(|shape| shape.expect("Failed to read a shape from world shapefile"))
.map(WorldRings::from_shape)
.collect();

Self { entries }
}
}

pub fn read() -> (
Vec<(f32, f32)>, // vertices
Vec<u32>, // indices
) {
let shapefile = Shapefile::new();

let mut vertex_buffer = VertexBuffer::new();

let world_indices: Vec<u32> = shapefile
.entries
.iter()
.flat_map(|world_rings| &world_rings.rings)
.flat_map(|ring| ring.triangulate())
.map(clamp_mercator_latitude)
.map(|point| {
u32::try_from(vertex_buffer.insert(point.into()))
.expect("world shapefile has too many vertices")
})
.collect();

let world_vertices = vertex_buffer.into_buffer();

assert!(
!world_vertices.is_empty(),
"world shapefile produced no vertices"
);
assert!(
!world_indices.is_empty(),
"world shapefile produced no indices"
);

(world_vertices, world_indices)
}
2 changes: 2 additions & 0 deletions assets/shapefile/world/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
https://github.com/EEWBot/eew-renderer/wiki に従い、以下のファイルを作成する
- `assets/shapefile/world/world.shp`
8 changes: 7 additions & 1 deletion renderer-assets/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use const_gen::*;
use ordered_float::NotNan;

mod station_codes_parser;
use asset_preprocessor::{parse_lake_shapefile, parse_shapefile, parse_tsunami_shapefile};
use asset_preprocessor::{
parse_lake_shapefile, parse_shapefile, parse_tsunami_shapefile, parse_world_shapefile,
};
use renderer_types::{BoundingBox, GeoDegree, Vertex};

fn main() {
Expand All @@ -15,6 +17,8 @@ fn main() {

let (lake_vertices, lake_indices) = parse_lake_shapefile::read();

let (world_vertices, world_indices) = parse_world_shapefile::read();

let s = std::fs::read_to_string("../assets/intensity_stations.json").unwrap();

#[allow(non_snake_case)]
Expand Down Expand Up @@ -77,6 +81,8 @@ fn main() {
const_declaration!(SCALE_LEVEL_MAP = scale_level_map),
const_declaration!(LAKE_VERTICES = lake_vertices),
const_declaration!(LAKE_INDICES = lake_indices),
const_declaration!(WORLD_VERTICES = world_vertices),
const_declaration!(WORLD_INDICES = world_indices),
const_declaration!(TSUNAMI_VERTICES = tsunami_vertices),
const_declaration!(TSUNAMI_INDICES = tsunami_indices),
const_declaration!(TSUNAMI_AREA_CODE_TO_INTERNAL_CODE = tsunami_area_code_to_internal_code),
Expand Down
12 changes: 12 additions & 0 deletions renderer-assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ pub struct LakeGeometries {
pub indices: &'static [u32],
}

pub struct WorldGeometries {
pub vertices: &'static [(f32, f32)],
pub indices: &'static [u32],
}

pub struct TsunamiGeometries {
pub vertices: &'static [(f32, f32, u16)],
pub indices: &'static [u32],
Expand All @@ -41,6 +46,13 @@ impl QueryInterface {
}
}

pub fn world_geometries() -> WorldGeometries {
WorldGeometries {
vertices: WORLD_VERTICES,
indices: WORLD_INDICES,
}
}

pub fn tsunami_geometries() -> TsunamiGeometries {
TsunamiGeometries {
vertices: TSUNAMI_VERTICES,
Expand Down
21 changes: 21 additions & 0 deletions renderer/src/frame_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,27 @@ pub enum FramePayload {
TsunamiSecond(TsunamiSecondPayload),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MapLayerConfig {
pub world: bool,
pub saibunkuiki_line: bool,
}

impl FramePayload {
pub fn map_layers(&self) -> MapLayerConfig {
match self {
FramePayload::Earthquake(_) => MapLayerConfig {
world: true,
saibunkuiki_line: true,
},
FramePayload::TsunamiFirst(_) | FramePayload::TsunamiSecond(_) => MapLayerConfig {
world: false,
saibunkuiki_line: false,
},
}
}
}

#[derive(Debug)]
pub struct FrameContext {
pub payload: FramePayload,
Expand Down
24 changes: 22 additions & 2 deletions renderer/src/worker/drawer_map.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::frame_context::MapLayerConfig;
use crate::worker::vertex::{BorderLineUniform, MapUniform};
use crate::worker::FrameContext;
use glium::backend::Facade;
Expand All @@ -6,7 +7,7 @@ use std::ops::DerefMut;

pub fn draw<F: ?Sized + Facade, S: ?Sized + Surface>(
frame_context: &FrameContext<F, S>,
has_saibunkuiki: bool,
layers: MapLayerConfig,
) {
let theme = frame_context.theme;
let params = frame_context.draw_parameters;
Expand All @@ -16,6 +17,25 @@ pub fn draw<F: ?Sized + Facade, S: ?Sized + Surface>(
let offset = frame_context.offset.into();
let image_size: [f32; 2] = frame_context.image_size.to_f32().into();

if layers.world {
resources
.shader
.map
.draw(
frame_context.surface.borrow_mut().deref_mut(),
&resources.world.vertex,
&resources.world.index,
&MapUniform {
aspect_ratio,
offset,
zoom: scale,
color: theme.ground_color,
},
params,
)
.unwrap();
}

resources
.shader
.map
Expand Down Expand Up @@ -54,7 +74,7 @@ pub fn draw<F: ?Sized + Facade, S: ?Sized + Surface>(
)
.unwrap();

if has_saibunkuiki {
if layers.saibunkuiki_line {
resources
.shader
.border_line
Expand Down
8 changes: 5 additions & 3 deletions renderer/src/worker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,24 @@ impl ApplicationHandler<Message> for App<'_> {
clear_color[3],
);

let map_layers = request_frame_context.payload.map_layers();

@yanorei32 yanorei32 Jul 19, 2026

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.

本当にここであるべきかについて考えています。
traitで切り出したほうがきれい…?いやそんなことはないか。うーん謎。
まぁ妥当な気もしてきた。

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

ふむー。謎です。


match &request_frame_context.payload {
FramePayload::Earthquake(earthquake) => {
drawer_map::draw(&frame_context, true);
drawer_map::draw(&frame_context, map_layers);
drawer_intensity_icon::draw_all(&frame_context, earthquake);
drawer_epicenter::draw(&frame_context, earthquake);
drawer_overlay::draw(&frame_context, earthquake);
}
FramePayload::TsunamiFirst(tsunami) => {
drawer_map::draw(&frame_context, false);
drawer_map::draw(&frame_context, map_layers);
drawer_tsunami_line::draw(&frame_context, tsunami);
drawer_tsunami_legends::draw(&frame_context, tsunami);
drawer_epicenter::draw(&frame_context, tsunami);
drawer_overlay::draw(&frame_context, tsunami);
}
FramePayload::TsunamiSecond(tsunami) => {
drawer_map::draw(&frame_context, false);
drawer_map::draw(&frame_context, map_layers);
drawer_tsunami_legends::draw(&frame_context, tsunami);
drawer_epicenter::draw(&frame_context, tsunami);
drawer_overlay::draw(&frame_context, tsunami);
Expand Down
Loading
Loading