update opengl method

This commit is contained in:
sleptworld 2023-06-18 23:48:25 +08:00
parent 0a90e486c3
commit 7e2ef5558a
14 changed files with 742835 additions and 117 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

102
Cargo.lock generated
View File

@ -58,7 +58,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"hermit-abi 0.1.19",
"libc",
"winapi",
]
@ -218,6 +218,7 @@ dependencies = [
"proj-sys",
"quadtree_rs",
"shapefile",
"svg",
"thiserror",
]
@ -290,6 +291,40 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset 0.9.0",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.15"
@ -415,7 +450,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
dependencies = [
"memoffset",
"memoffset 0.8.0",
"rustc_version",
]
@ -836,6 +871,15 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hmac"
version = "0.12.1"
@ -953,6 +997,15 @@ dependencies = [
"autocfg",
]
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -979,6 +1032,7 @@ dependencies = [
"num-integer",
"num-traits",
"rawpointer",
"rayon",
]
[[package]]
@ -1101,6 +1155,16 @@ dependencies = [
"libm",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi 0.2.6",
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.1"
@ -1355,6 +1419,28 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rayon"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@ -1396,6 +1482,12 @@ dependencies = [
"semver",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "1.0.17"
@ -1503,6 +1595,12 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "svg"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d815ad337e8449d2374d4248448645edfe74e699343dd5719139d93fa87112"
[[package]]
name = "syn"
version = "0.15.44"

View File

@ -19,10 +19,11 @@ shapefile = { version = "0.4", features = ["geo-types"] }
thiserror = "1.0.40"
num-traits = "0.2.15"
npyz = { version = "0.8.0", features = ["npz"] }
ndarray = "0.15.6"
ndarray = { version = "0.15.6", features = ["rayon"] }
quadtree_rs = "0.1.2"
proj-sys = "0.23.1"
glib-macros = "0.17.10"
svg = "0.13.1"
[build-dependencies]

View File

@ -0,0 +1,3 @@
use super::RadarData2d;
pub type RadarReflectivity<Raw> = RadarData2d<i8, Raw>;

View File

@ -1,10 +1,12 @@
use ndarray::{s, Array1, Array2, Array3, ArrayBase, Ix1, Ix2, OwnedRepr, RawDataClone};
use ndarray::{s, Array, Array1, Array2, Array3, ArrayBase, Ix1, Ix2, OwnedRepr, RawDataClone};
use npyz::{npz::NpzArchive, Deserialize};
use num_traits::{AsPrimitive, FromPrimitive, Num};
use quadtree_rs::{area::AreaBuilder, Quadtree};
use std::{self, f64::consts::PI, fmt::Debug, io::BufReader, path::Path};
use thiserror::Error;
mod concrete_data;
#[derive(Error, Debug)]
pub enum DataError {
#[error("value")]
@ -16,6 +18,13 @@ pub enum DataError {
},
}
#[derive(PartialEq)]
pub enum Axis {
Asix0,
Axis1,
Axis2,
}
#[derive(Clone, Copy)]
pub enum CoordType {
Polar,
@ -23,20 +32,20 @@ pub enum CoordType {
}
#[derive(Clone)]
pub struct RadarData2d<T, Raw, X = f64, Y = f64>
pub struct RadarData2d<T, Raw, X = f64, Y = f64, I = Ix1>
where
T: Num + Clone + PartialEq + PartialOrd,
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
X: Num,
Y: Num,
{
pub dim1: Array1<X>,
pub dim2: Array1<Y>,
pub dim1: ArrayBase<OwnedRepr<X>, I>,
pub dim2: ArrayBase<OwnedRepr<Y>, I>,
pub data: ArrayBase<Raw, Ix2>,
pub coord_type: CoordType,
}
struct RadarData3d<T, X = f64, Y = f64, Z = f64>
pub struct RadarData3d<T, X = f64, Y = f64, Z = f64>
where
T: Num,
X: Num,
@ -49,7 +58,7 @@ where
pub data: Array3<T>,
}
trait MultiDimensionData {}
pub trait MultiDimensionData {}
impl<T, Raw> RadarData2d<T, Raw>
where
@ -184,6 +193,20 @@ where
});
result
}
pub fn dpi(&self, axis: Axis) {
match self.coord_type {
CoordType::LatLon => {
if axis == Axis::Asix0 {
let mut new_dim1 = Array::zeros(self.dim1.raw_dim());
let a = self.dim1.slice(s![0..3, ..]);
} else if axis == Axis::Asix1 {
} else {
}
}
_ => {}
}
}
}
#[inline]
@ -259,7 +282,7 @@ where
let numerator = 1.0 / levels as f64;
(0..levels)
.into_iter()
.map(|level| LevelData::new(&data.0, level + 1, 1.0 - level as f64 * numerator))
.map(|level| LevelData::new(&data, level + 1, 1.0 - level as f64 * numerator))
.collect()
}
@ -276,7 +299,6 @@ pub trait DataLoader<T: MultiDimensionData> {
}
pub struct Npz;
impl Npz {
#[inline]
fn load_1d<T: Num + Deserialize>(
@ -329,19 +351,10 @@ where
}
}
impl<T: Num + Clone + PartialEq + PartialOrd> RadarData2d<T, OwnedRepr<T>> {
pub fn load<P: AsRef<Path>, M: DataLoader<Self>>(p: P, meth: M) -> Self {
meth.load(p).unwrap()
}
}
pub struct Radar2d<T: Num + Clone + PartialEq + PartialOrd>(pub RadarData2d<T, OwnedRepr<T>>);
pub type Radar2d<T> = RadarData2d<T, OwnedRepr<T>>;
impl<T: Num + Clone + PartialEq + PartialOrd> Radar2d<T> {
pub fn load(
path: impl AsRef<Path>,
meth: impl DataLoader<RadarData2d<T, OwnedRepr<T>>>,
) -> Result<Self, DataError> {
Ok(Radar2d(meth.load(path)?))
pub fn load(path: impl AsRef<Path>, meth: impl DataLoader<Self>) -> Result<Self, DataError> {
Ok(meth.load(path)?)
}
}

View File

@ -4,23 +4,24 @@ use std::time::Duration;
use glib::{timeout_add, timeout_add_local};
use glib_macros::clone;
use gtk::gdk::builders::RGBABuilder;
use gtk::gdk::Display;
use gtk::{
gio, glib, style_context_add_provider_for_display, Application, ApplicationWindow, CssProvider,
GestureDrag,
};
use gtk::{prelude::*, DrawingArea};
// use plotters::prelude::DrawingArea;
// mod backend;
mod data;
mod painter;
mod render;
mod tree;
mod window;
use data::{Npz, Radar2d, RadarData2d};
use ndarray::parallel::prelude::{IntoParallelIterator, ParallelIterator};
use num_traits::{FromPrimitive, Num};
use painter::wgs84::{LatLonCoord, Mercator, ProjectionS, Range};
use painter::{Coord, Painter};
use svg::node::element::Rectangle;
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
@ -28,9 +29,6 @@ fn main() -> glib::ExitCode {
// gio::resources_register_include!("window.gresource").expect("Failed to register resources");
// Create a new application
let app = Application::builder().application_id(APP_ID).build();
app.connect_startup(|_| load_css());
// Connect to "activate" signal of `app`
app.connect_activate(build_ui);
@ -46,48 +44,16 @@ fn build_ui(app: &Application) {
.build();
let drawing_area = DrawingArea::new();
let path = "/home/ruomu/Desktop/test.npz";
let path = "/Users/ruomu/test2.npz";
let data = Radar2d::<i8>::load(path, Npz).unwrap();
let data = Rc::new(RefCell::new(data));
let data3_clone = data.clone();
let projection = Mercator::new();
let aa = Range::from((
*data.borrow().0.dim1.first().unwrap(),
*data.borrow().0.dim1.last().unwrap(),
));
let ab = Range::from((
*data.borrow().0.dim2.first().unwrap(),
*data.borrow().0.dim2.last().unwrap(),
));
let aa = Range::from((*data.dim1.first().unwrap(), *data.dim1.last().unwrap()));
let ab = Range::from((*data.dim2.first().unwrap(), *data.dim2.last().unwrap()));
let coord = LatLonCoord::new(Some(aa), Some(ab), ((0, 1000), (0, 1000)), projection);
let painter = Rc::new(RefCell::new(Painter::new(coord, 1000, 1000)));
let painter_b = painter.clone();
let gesture = GestureDrag::new();
gesture.connect_drag_update(clone!(
@strong drawing_area => move |_, x,y| {
let painter = painter.clone();
painter.borrow_mut().set_shift(x,y);
println!("{:.2},{:.2}",x,y);
}
));
drawing_area.add_controller(gesture);
drawing_area.set_draw_func(move |a, b, c, d| {
painter_b.borrow().draw_radar_2d(b, &data3_clone.borrow().0);
});
timeout_add_local(
Duration::from_micros(1000u64 / 20u64),
clone!(@strong drawing_area => move || {
drawing_area.queue_draw();
Continue(true)
}),
);
let result = data.mapped(&coord);
window.set_child(Some(&drawing_area));
window.set_default_width(1000);
@ -95,15 +61,3 @@ fn build_ui(app: &Application) {
window.present();
}
fn load_css() {
// Load the CSS file and add it to the provider
let provider = CssProvider::new();
provider.load_from_data(include_str!("css/style.css"));
// Add the provider to the default screen
style_context_add_provider_for_display(
&Display::default().expect("Could not connect to a display."),
&provider,
gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
}

View File

@ -1,12 +1,45 @@
use ndarray::{Array2, ViewRepr};
use num_traits::Num;
use crate::data::RadarData2d;
use super::AfterMapping2d;
pub mod wgs84;
pub type ScreenCoord = (f64, f64);
pub trait Coord<T: Num> {
pub trait Coord<T: Num>: Sync + Send {
fn map(&self, axis_1: T, axis_2: T) -> ScreenCoord;
fn dim1_range(&self) -> (T, T);
fn dim2_range(&self) -> (T, T);
}
impl<T, Raw> RadarData2d<T, Raw>
where
T: Num + Clone + PartialEq + PartialOrd,
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
{
pub fn mapped(&self, coord: &impl Coord<f64>) -> AfterMapping2d<T> {
let mesh_dim1_len = self.dim1.len();
let mesh_dim2_len = self.dim2.len();
let mut d1 = Array2::<f64>::zeros((mesh_dim1_len, mesh_dim2_len));
let mut d2 = Array2::<f64>::zeros((mesh_dim1_len, mesh_dim2_len));
self.dim1.iter().enumerate().for_each(|(i, v)| {
self.dim2.iter().enumerate().for_each(|(j, u)| {
let (x, y) = coord.map(*v, *u);
d1[[i, j]] = x;
d2[[i, j]] = y;
});
});
AfterMapping2d {
dim1: d1,
dim2: d2,
data: self.data.view(),
coord_type: self.coord_type.clone(),
}
}
}

View File

@ -40,6 +40,9 @@ struct PCS<T: ProjectionS> {
transformer: Proj,
}
unsafe impl Sync for PCS<Mercator> {}
unsafe impl Send for PCS<Mercator> {}
impl<T: ProjectionS> LatLonCoord<T> {
/// Creates a new `LatLonCoord` instance.
///
@ -69,7 +72,7 @@ impl<T: ProjectionS> LatLonCoord<T> {
}
}
pub fn set_actual(&mut self,actual: ((i32, i32), (i32, i32))) {
pub fn set_actual(&mut self, actual: ((i32, i32), (i32, i32))) {
self.actual = (Range::from(actual.0), Range::from(actual.1));
}
@ -82,6 +85,9 @@ impl<T: ProjectionS> LatLonCoord<T> {
}
}
unsafe impl<T: ProjectionS> Sync for LatLonCoord<T> {}
unsafe impl<T: ProjectionS> Send for LatLonCoord<T> {}
impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
fn map(&self, axis_1: f64, axis_2: f64) -> super::ScreenCoord {
let point = self.pcs.map((axis_1, axis_2));
@ -106,7 +112,6 @@ impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
let v = self.lat_range();
(v.0, v.1)
}
}
#[derive(Clone, Debug)]
@ -118,7 +123,7 @@ pub enum Projection {
}
/// A trait for defining a projection.
pub trait ProjectionS {
pub trait ProjectionS: Sync + Send {
/// Returns a proj-string of the projection.
fn build(&self) -> String;

View File

@ -1,6 +1,27 @@
mod coords;
mod painter;
pub use painter::Painter;
pub use coords::wgs84;
pub use coords::Coord;
pub use coords::Coord;
use ndarray::Ix2;
use ndarray::ViewRepr;
use num_traits::Num;
pub use painter::Painter;
use crate::data::{RadarData2d, RadarData3d};
pub type AfterMapping2d<'a, T> = RadarData2d<T, ViewRepr<&'a T>, f64, f64, Ix2>;
// pub type AfterMapping3d<T, Raw> = RadarData3d<T, Raw, f64, f64, Ix2>;
impl<'a, T> AfterMapping2d<'a, T>
where
T: Num + Clone + PartialEq + PartialOrd,
{
pub fn traverse(&self, mut f: impl FnMut((usize, f64), (usize, f64)) -> ()) {
self.dim1.iter().enumerate().for_each(|(i, v)| {
self.dim2.iter().enumerate().for_each(|(j, u)| {
f((i, *v), (j, *u));
});
});
}
}

View File

@ -5,6 +5,7 @@ use std::{
};
use crate::{data::RadarData2d, tree::get};
use ndarray::parallel::prelude::*;
use super::coords::{Coord, ScreenCoord};
use gtk::{
@ -71,7 +72,7 @@ impl<T: Num + Clone, C: Coord<T>> Painter<T, C> {
// }
}
fn translate(&self,context:&Context) {
fn translate(&self, context: &Context) {
context.translate(self.shift.0, self.shift.1);
}

View File

@ -1,43 +1,30 @@
use glib::{ObjectExt, ParamSpec, Properties, Value};
use gtk::glib;
use gtk::subclass::prelude::*;
use std::cell::Cell;
use std::cell::{Cell, RefCell};
#[derive(Properties, Default)]
#[properties(wrapper_type = super::Render)]
use crate::data::Radar2d;
#[derive(Default)]
pub struct Render {
#[property(get, set)]
height: Cell<u32>,
#[property(get, set)]
width: Cell<u32>,
data: RefCell<Option<Radar2d<i8>>>,
}
#[glib::object_subclass]
impl ObjectSubclass for Render {
const NAME: &'static str = "MyRender";
type Type = super::Render;
type ParentType = gtk::DrawingArea;
type ParentType = gtk::Widget;
}
// Trait shared by all GObjects
impl ObjectImpl for Render {
fn properties() -> &'static [ParamSpec] {
Self::derived_properties()
}
impl ObjectImpl for Render {}
fn set_property(&self, id: usize, value: &Value, pspec: &ParamSpec) {
self.derived_set_property(id, value, pspec)
}
fn property(&self, id: usize, pspec: &ParamSpec) -> Value {
self.derived_property(id, pspec)
}
fn constructed(&self) {
self.parent_constructed();
// Trait shared by all widgets
impl WidgetImpl for Render {
fn snapshot(&self, snapshot: &gtk::Snapshot) {
if let Some(data) = self.data.borrow_mut().take() {}
}
}
// Trait shared by all widgets
impl WidgetImpl for Render {}
impl DrawingAreaImpl for Render {}

View File

@ -3,16 +3,11 @@ use glib::Object;
use gtk::glib;
glib::wrapper! {
pub struct Render(ObjectSubclass<imp::Render>)
@extends gtk::DrawingArea,gtk::Widget,
@implements gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
pub struct Render(ObjectSubclass<imp::Render>) @extends gtk::Widget;
}
impl Render {
pub fn new(height: u32, width: u32) -> Self {
Object::builder()
.property("height", height)
.property("width", width)
.build()
pub fn new() -> Self {
glib::Object::new()
}
}

78
src/utils.rs Normal file
View File

@ -0,0 +1,78 @@
// let levels: Vec<i8> = vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65];
// let colors = vec![
// RGBABuilder::default()
// .red(0 as f32 / 255.0)
// .green(172 as f32 / 255.0)
// .blue(164 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(192 as f32 / 255.0)
// .green(192 as f32 / 255.0)
// .blue(254 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(122 as f32 / 255.0)
// .green(114 as f32 / 255.0)
// .blue(238 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(30 as f32 / 255.0)
// .green(38 as f32 / 255.0)
// .blue(208 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(166 as f32 / 255.0)
// .green(252 as f32 / 255.0)
// .blue(168 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(0 as f32 / 255.0)
// .green(234 as f32 / 255.0)
// .blue(0 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(16 as f32 / 255.0)
// .green(146 as f32 / 255.0)
// .blue(26 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(252 as f32 / 255.0)
// .green(244 as f32 / 255.0)
// .blue(100 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(200 as f32 / 255.0)
// .green(200 as f32 / 255.0)
// .blue(2 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(140 as f32 / 255.0)
// .green(140 as f32 / 255.0)
// .blue(0 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(254 as f32 / 255.0)
// .green(172 as f32 / 255.0)
// .blue(172 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(254 as f32 / 255.0)
// .green(100 as f32 / 255.0)
// .blue(92 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(238 as f32 / 255.0)
// .green(2 as f32 / 255.0)
// .blue(48 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(212 as f32 / 255.0)
// .green(142 as f32 / 255.0)
// .blue(254 as f32 / 255.0)
// .build(),
// RGBABuilder::default()
// .red(170 as f32 / 255.0)
// .green(36 as f32 / 255.0)
// .blue(250 as f32 / 255.0)
// .build(),
// ];

742529
test.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 70 MiB