Skip to content

Commit

Permalink
JGD2011→WGS 84の変換を加える (#155)
Browse files Browse the repository at this point in the history
JGD2011→WGS 84の変換処理を、仮のTransformerの実装に加えておく。

JGD2011の height(標高、東京湾平均海面)をWGS 84の height(楕円体高)に変換するだけ。
  • Loading branch information
ciscorn authored Jan 8, 2024
1 parent eb90961 commit 62c1696
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 24 deletions.
1 change: 1 addition & 0 deletions nusamai-citygml/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ chrono = { version = "0.4.31", features = ["serde"], default-features = false }
indexmap = { version = "2.1", features = ["serde"] }
macros = { path = "./macros" }
nusamai-geometry = { path = "../nusamai-geometry", features = ["serde"]}
nusamai-projection = { path = "../nusamai-projection"}
quick-xml = "0.31"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0.108", optional = true }
Expand Down
23 changes: 10 additions & 13 deletions nusamai-citygml/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use nusamai_geometry::{MultiLineString, MultiPoint, MultiPolygon};
use nusamai_projection::crs::*;

#[derive(Debug, Clone, Copy)]
pub enum GeometryParseType {
Expand Down Expand Up @@ -35,28 +36,24 @@ pub struct GeometryRefEntry {

pub type GeometryRef = Vec<GeometryRefEntry>;

#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Debug, Default)]
pub enum CRS {
#[default]
WGS84,
JGD2011,
}

/// Geometries in a toplevel city object and its children.
/// Geometries in a city object and all its children.
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Debug, Default)]
pub struct GeometryStore {
pub crs: CRS,
/// EPSG code of the Coordinate Reference System (CRS)
pub epsg: EPSGCode,
/// Shared vertex buffer for all geometries
pub vertices: Vec<[f64; 3]>,
/// All polygons, referenced by `GeometryRef`
pub multipolygon: MultiPolygon<'static, 1, u32>,
/// All line-strings of , referenced by `GeometryRef`
pub multilinestring: MultiLineString<'static, 1, u32>,
/// All points, referenced by `GeometryRef`
pub multipoint: MultiPoint<'static, 1, u32>,
}

/// Store for collecting vertices and polygons from GML.
#[derive(Default)]
pub struct GeometryCollector {
pub(crate) struct GeometryCollector {
pub vertices: indexmap::IndexSet<[u64; 3]>,
pub multipolygon: MultiPolygon<'static, 1, u32>,
pub multilinestring: MultiLineString<'static, 1, u32>,
Expand Down Expand Up @@ -94,7 +91,7 @@ impl GeometryCollector {
]);
}
GeometryStore {
crs: CRS::JGD2011,
epsg: EPSG_JGD2011_GEOGRAPHIC_3D,
vertices,
multipolygon: self.multipolygon,
multilinestring: self.multilinestring,
Expand Down
7 changes: 7 additions & 0 deletions nusamai-projection/src/crs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub type EPSGCode = u16;

pub const EPSG_WGS84_GEOGRAPHIC_2D: EPSGCode = 4326;
pub const EPSG_WGS84_GEOGRAPHIC_3D: EPSGCode = 4979;
pub const EPSG_WGS84_GEOCENTRIC: EPSGCode = 4978;
pub const EPSG_JGD2011_GEOGRAPHIC_2D: EPSGCode = 6668;
pub const EPSG_JGD2011_GEOGRAPHIC_3D: EPSGCode = 6697;
1 change: 1 addition & 0 deletions nusamai-projection/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod cartesian;
pub mod crs;
pub mod ellipsoid;
pub mod error;
pub mod etmerc;
Expand Down
4 changes: 2 additions & 2 deletions nusamai-projection/src/vshift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct JGD2011ToWGS84 {

impl JGD2011ToWGS84 {
/// Create a new instance with the embed geoid model data.
pub fn from_embed_model() -> Self {
pub fn from_embedded_model() -> Self {
const EMBEDDED_MODEL: &[u8] = include_bytes!("../examples/data/gsigeo2011_ver2_2.bin.lz4");
let decompressed = &lz4_flex::decompress_size_prepended(EMBEDDED_MODEL).unwrap();
let mut reader = std::io::Cursor::new(decompressed);
Expand All @@ -31,7 +31,7 @@ mod tests {
#[test]
fn fixtures() {
let (lng_jgd, lat_jgd, elevation) = (138.2839817085188, 37.12378643088312, 0.);
let jgd_to_wgs = JGD2011ToWGS84::from_embed_model();
let jgd_to_wgs = JGD2011ToWGS84::from_embedded_model();
let (lng_wgs, lat_wgs, ellips_height) = jgd_to_wgs.convert(lng_jgd, lat_jgd, elevation);
assert!((ellips_height - 39.47387115961899).abs() < 1e-8);
// (lng, lat) must not change.
Expand Down
1 change: 1 addition & 0 deletions nusamai/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ bincode = "1.3.3"
lz4_flex = "0.11.1"
nusamai-geojson = { path = "../nusamai-geojson" }
nusamai-geometry = { path = "../nusamai-geometry" }
nusamai-projection = { path = "../nusamai-projection" }
geojson = "0.24.1"
serde_json = "1.0.108"
url = "2.5.0"
Expand Down
4 changes: 2 additions & 2 deletions nusamai/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use nusamai::sink::{
use nusamai::sink::{DataSink, DataSinkProvider};
use nusamai::source::citygml::CityGMLSourceProvider;
use nusamai::source::{DataSource, DataSourceProvider};
use nusamai::transform::NoopTransformer;
use nusamai::transform::DummyTransformer;

#[derive(clap::Parser)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -116,7 +116,7 @@ fn run(
sink: Box<dyn DataSink>,
canceller: &mut Arc<Mutex<Canceller>>,
) {
let transformer = Box::new(NoopTransformer {});
let transformer = Box::<DummyTransformer>::default();

Check warning on line 119 in nusamai/src/main.rs

View check run for this annotation

Codecov / codecov/patch

nusamai/src/main.rs#L119

Added line #L119 was not covered by tests

// start the pipeline
let (handle, watcher, inner_canceller) = nusamai::pipeline::run(source, transformer, sink);
Expand Down
3 changes: 2 additions & 1 deletion nusamai/src/sink/geojson/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ mod tests {
use super::*;
use nusamai_citygml::{object::Feature, Value};
use nusamai_geometry::MultiPolygon;
use nusamai_projection::crs::EPSG_JGD2011_GEOGRAPHIC_3D;

#[test]
fn test_toplevel_cityobj_multipolygon() {
Expand All @@ -195,7 +196,7 @@ mod tests {
let mut mpoly = MultiPolygon::<'_, 1, u32>::new();
mpoly.add_exterior([[0], [1], [2], [3], [0]]);
let geometries = nusamai_citygml::GeometryStore {
crs: nusamai_citygml::CRS::WGS84,
epsg: EPSG_JGD2011_GEOGRAPHIC_3D,
vertices,
multipolygon: mpoly,
multilinestring: Default::default(),
Expand Down
29 changes: 25 additions & 4 deletions nusamai/src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
use crate::pipeline::{Feedback, Parcel, Sender, TransformError, Transformer};
use nusamai_projection::crs::*;
use nusamai_projection::vshift::JGD2011ToWGS84;

pub struct NoopTransformer {}
pub struct DummyTransformer {
jgd2wgs: JGD2011ToWGS84,
}

impl Default for DummyTransformer {
fn default() -> Self {
Self {
jgd2wgs: JGD2011ToWGS84::from_embedded_model(),
}
}
}

impl Transformer for NoopTransformer {
impl Transformer for DummyTransformer {
fn transform(
&self,
mut parcel: Parcel,
downstream: &Sender,
feedback: &Feedback,
) -> Result<(), TransformError> {
// swap x and y
// 仮実装
parcel.cityobj.geometries.vertices.iter_mut().for_each(|v| {
(v[0], v[1], v[2]) = (v[1], v[0], v[2]);
// Swap x and y (lat, lng -> lng, lat)
let (lng, lat, height) = (v[1], v[0], v[2]);

// JGD2011 to WGS 84 (elevation to ellipsoidal height)
(v[0], v[1], v[2]) = self.jgd2wgs.convert(lng, lat, height);
});

// Ensure that the original CRS is JGD2011 and the new CRS is WGS 84
assert_eq!(parcel.cityobj.geometries.epsg, EPSG_JGD2011_GEOGRAPHIC_3D);
parcel.cityobj.geometries.epsg = EPSG_WGS84_GEOGRAPHIC_3D;

// Send to the next stage
if downstream.send(parcel).is_err() {
feedback.cancel();
};
Expand Down
4 changes: 2 additions & 2 deletions nusamai/tests/sink.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nusamai::sink::DataSinkProvider;
use nusamai::source::citygml::CityGMLSourceProvider;
use nusamai::source::DataSourceProvider;
use nusamai::transform::NoopTransformer;
use nusamai::transform::DummyTransformer;

use nusamai::sink;

Expand All @@ -16,7 +16,7 @@ pub(crate) fn simple_run_sink<S: DataSinkProvider>(sink_provider: S, output: Opt

let source = source_provider.create(&source_provider.parameters());

let transformer = Box::new(NoopTransformer {});
let transformer = Box::<DummyTransformer>::default();

assert!(!sink_provider.info().name.is_empty());
let mut sink_params = sink_provider.parameters();
Expand Down

0 comments on commit 62c1696

Please sign in to comment.