self drawing and drag gesture testing
This commit is contained in:
parent
1c1f2925cf
commit
6d670afdbf
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -657,9 +657,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-build-tools"
|
name = "glib-build-tools"
|
||||||
version = "0.17.0"
|
version = "0.17.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f8480c9ba9cc06aa8d5baf446037f8dc237bee127e9b62080c4db7e293d8ea0"
|
checksum = "7a65d79efe318ef2cbbbb37032b125866fd82c34ea44c816132621bbc552e716"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-macros"
|
name = "glib-macros"
|
||||||
|
|||||||
@ -23,9 +23,9 @@ ndarray = "0.15.6"
|
|||||||
quadtree_rs = "0.1.2"
|
quadtree_rs = "0.1.2"
|
||||||
proj-sys = "0.23.1"
|
proj-sys = "0.23.1"
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
glib-build-tools = "0.17.0"
|
glib-build-tools = "0.17.0"
|
||||||
# plotters = "0.3.4"
|
|
||||||
|
|
||||||
[dependencies.geo-macros]
|
[dependencies.geo-macros]
|
||||||
path = "geo-macros"
|
path = "geo-macros"
|
||||||
|
|||||||
12
p.py
12
p.py
@ -1,12 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
|
|
||||||
a = np.load("/home/ruomu/Desktop/test.npz")
|
|
||||||
|
|
||||||
b = a['value']
|
|
||||||
lon = a['lon']
|
|
||||||
lat = a['lat']
|
|
||||||
|
|
||||||
a = np.load("/home/ruomu/Desktop/test2.npz")['value']
|
|
||||||
|
|
||||||
|
|
||||||
np.savez("/home/ruomu/Desktop/test2.npz", value=np.max(b,axis=0), lon=lon, lat=lat)
|
|
||||||
19
src/data.rs
19
src/data.rs
@ -25,7 +25,7 @@ pub enum CoordType {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RadarData2d<T, Raw, X = f64, Y = f64>
|
pub struct RadarData2d<T, Raw, X = f64, Y = f64>
|
||||||
where
|
where
|
||||||
T: Num + Clone,
|
T: Num + Clone + PartialEq + PartialOrd,
|
||||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||||
X: Num,
|
X: Num,
|
||||||
Y: Num,
|
Y: Num,
|
||||||
@ -53,7 +53,7 @@ trait MultiDimensionData {}
|
|||||||
|
|
||||||
impl<T, Raw> RadarData2d<T, Raw>
|
impl<T, Raw> RadarData2d<T, Raw>
|
||||||
where
|
where
|
||||||
T: Num + AsPrimitive<f64> + FromPrimitive + Clone + Debug,
|
T: Num + AsPrimitive<f64> + FromPrimitive + Clone + Debug + PartialOrd + PartialEq,
|
||||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||||
{
|
{
|
||||||
fn value_to_owned(self) -> RadarData2d<T, OwnedRepr<T>> {
|
fn value_to_owned(self) -> RadarData2d<T, OwnedRepr<T>> {
|
||||||
@ -198,11 +198,13 @@ fn windowed_sinc(x: f64, y: f64) -> f64 {
|
|||||||
sinc * window
|
sinc * window
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LevelData<T: Num + Clone>(pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>);
|
pub struct LevelData<T: Num + Clone + PartialEq + PartialOrd>(
|
||||||
|
pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>,
|
||||||
|
);
|
||||||
|
|
||||||
impl<T> LevelData<T>
|
impl<T> LevelData<T>
|
||||||
where
|
where
|
||||||
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug + PartialEq + PartialOrd,
|
||||||
{
|
{
|
||||||
fn value(
|
fn value(
|
||||||
level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
|
level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
|
||||||
@ -252,6 +254,7 @@ where
|
|||||||
pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
|
pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
|
||||||
where
|
where
|
||||||
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
||||||
|
T: PartialEq + PartialOrd,
|
||||||
{
|
{
|
||||||
let numerator = 1.0 / levels as f64;
|
let numerator = 1.0 / levels as f64;
|
||||||
(0..levels)
|
(0..levels)
|
||||||
@ -263,6 +266,7 @@ where
|
|||||||
impl<T, Raw> MultiDimensionData for RadarData2d<T, Raw>
|
impl<T, Raw> MultiDimensionData for RadarData2d<T, Raw>
|
||||||
where
|
where
|
||||||
T: Num + Clone,
|
T: Num + Clone,
|
||||||
|
T: PartialEq + PartialOrd,
|
||||||
Raw: ndarray::Data<Elem = T> + Clone + RawDataClone,
|
Raw: ndarray::Data<Elem = T> + Clone + RawDataClone,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -308,6 +312,7 @@ impl Npz {
|
|||||||
impl<T> DataLoader<RadarData2d<T, OwnedRepr<T>>> for Npz
|
impl<T> DataLoader<RadarData2d<T, OwnedRepr<T>>> for Npz
|
||||||
where
|
where
|
||||||
T: Num + Clone + Deserialize,
|
T: Num + Clone + Deserialize,
|
||||||
|
T: PartialEq + PartialOrd,
|
||||||
{
|
{
|
||||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
fn load<P: AsRef<Path>>(&self, path: P) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||||
let mut data: NpzArchive<BufReader<std::fs::File>> = npyz::npz::NpzArchive::open(path)?;
|
let mut data: NpzArchive<BufReader<std::fs::File>> = npyz::npz::NpzArchive::open(path)?;
|
||||||
@ -324,15 +329,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Num + Clone> RadarData2d<T, OwnedRepr<T>> {
|
impl<T: Num + Clone + PartialEq + PartialOrd> RadarData2d<T, OwnedRepr<T>> {
|
||||||
pub fn load<P: AsRef<Path>, M: DataLoader<Self>>(p: P, meth: M) -> Self {
|
pub fn load<P: AsRef<Path>, M: DataLoader<Self>>(p: P, meth: M) -> Self {
|
||||||
meth.load(p).unwrap()
|
meth.load(p).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Radar2d<T: Num + Clone>(pub RadarData2d<T, OwnedRepr<T>>);
|
pub struct Radar2d<T: Num + Clone + PartialEq + PartialOrd>(pub RadarData2d<T, OwnedRepr<T>>);
|
||||||
|
|
||||||
impl<T: Num + Clone> Radar2d<T> {
|
impl<T: Num + Clone + PartialEq + PartialOrd> Radar2d<T> {
|
||||||
pub fn load(
|
pub fn load(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
meth: impl DataLoader<RadarData2d<T, OwnedRepr<T>>>,
|
meth: impl DataLoader<RadarData2d<T, OwnedRepr<T>>>,
|
||||||
|
|||||||
42
src/main.rs
42
src/main.rs
@ -1,26 +1,24 @@
|
|||||||
use geo_types::{MultiPolygon, Polygon};
|
|
||||||
use gtk::builders::DrawingAreaBuilder;
|
|
||||||
use gtk::gdk::Display;
|
use gtk::gdk::Display;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gio, glib, style_context_add_provider_for_display, Application, ApplicationWindow, CssProvider,
|
gio, glib, style_context_add_provider_for_display, Application, ApplicationWindow, CssProvider,
|
||||||
|
GestureDrag,
|
||||||
};
|
};
|
||||||
use gtk::{prelude::*, DrawingArea};
|
use gtk::{prelude::*, DrawingArea};
|
||||||
use painter::wgs84::*;
|
|
||||||
use painter::Painter;
|
|
||||||
// use plotters::prelude::DrawingArea;
|
// use plotters::prelude::DrawingArea;
|
||||||
use window::Window;
|
|
||||||
// mod backend;
|
// mod backend;
|
||||||
mod data;
|
mod data;
|
||||||
mod painter;
|
mod painter;
|
||||||
// mod trees;
|
mod render;
|
||||||
|
mod tree;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
use data::{CoordType, Npz, Radar2d};
|
use data::{CoordType, Npz, Radar2d};
|
||||||
|
use painter::wgs84::{LatLonCoord, Mercator, Range};
|
||||||
|
use painter::Painter;
|
||||||
|
|
||||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||||
|
|
||||||
fn main() -> glib::ExitCode {
|
fn main() -> glib::ExitCode {
|
||||||
gio::resources_register_include!("window.gresource").expect("Failed to register resources");
|
// gio::resources_register_include!("window.gresource").expect("Failed to register resources");
|
||||||
// Create a new application
|
// Create a new application
|
||||||
let app = Application::builder().application_id(APP_ID).build();
|
let app = Application::builder().application_id(APP_ID).build();
|
||||||
|
|
||||||
@ -36,23 +34,33 @@ fn main() -> glib::ExitCode {
|
|||||||
fn build_ui(app: &Application) {
|
fn build_ui(app: &Application) {
|
||||||
// Create a window and set the title
|
// Create a window and set the title
|
||||||
|
|
||||||
let window = Window::new(app);
|
// let window = Window::new(app);
|
||||||
|
|
||||||
|
let window = ApplicationWindow::builder()
|
||||||
|
.application(app)
|
||||||
|
.title("My GTK App")
|
||||||
|
.build();
|
||||||
|
|
||||||
let drawing_area = DrawingArea::new();
|
let drawing_area = DrawingArea::new();
|
||||||
|
let path = "/Users/ruomu/test2.npz";
|
||||||
let path = "/home/ruomu/Desktop/test.npz";
|
|
||||||
|
|
||||||
let data = Radar2d::<i8>::load(path, Npz).unwrap();
|
let data = Radar2d::<i8>::load(path, Npz).unwrap();
|
||||||
|
let gesture = GestureDrag::new();
|
||||||
|
|
||||||
|
// gesture.connect_drag_end(|s, x, y| {
|
||||||
|
// (&drawing_area).queue_draw();
|
||||||
|
// });
|
||||||
|
// drawing_area.add_controller(gesture);
|
||||||
drawing_area.set_draw_func(move |a, b, c, d| {
|
drawing_area.set_draw_func(move |a, b, c, d| {
|
||||||
let projection = Mercator::new();
|
let projection = Mercator::new();
|
||||||
let coord = LatLonCoord::new(None, None, ((0, c), (0, d)), projection);
|
let aa = Range::from((*data.0.dim1.first().unwrap(), *data.0.dim1.last().unwrap()));
|
||||||
let painter: Painter<'_, f64, LatLonCoord<Mercator>> = Painter::new(b, coord, c as u32, c as u32);
|
let ab = Range::from((*data.0.dim2.first().unwrap(), *data.0.dim2.last().unwrap()));
|
||||||
|
|
||||||
|
let coord = LatLonCoord::new(Some(aa), Some(ab), ((0, c), (0, d)), projection);
|
||||||
|
let painter: Painter<'_, f64, LatLonCoord<Mercator>> =
|
||||||
|
Painter::new(b, coord, c as u32, c as u32);
|
||||||
painter.draw_radar_2d(&data.0);
|
painter.draw_radar_2d(&data.0);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
window.set_child(Some(&drawing_area));
|
||||||
// window.set_child(Some(&drawing_area));
|
|
||||||
window.set_default_width(1000);
|
window.set_default_width(1000);
|
||||||
window.set_default_height(800);
|
window.set_default_height(800);
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
pub mod wgs84;
|
pub mod wgs84;
|
||||||
|
|
||||||
pub type ScreenCoord = (i32, i32);
|
pub type ScreenCoord = (f64, f64);
|
||||||
|
|
||||||
pub trait Coord<T: Num> {
|
pub trait Coord<T: Num> {
|
||||||
fn map(&self, axis_1: T, axis_2: T) -> ScreenCoord;
|
fn map(&self, axis_1: T, axis_2: T) -> ScreenCoord;
|
||||||
|
|
||||||
|
fn dim1_range(&self) -> (T, T);
|
||||||
|
fn dim2_range(&self) -> (T, T);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
use super::Coord;
|
use super::Coord;
|
||||||
use geo_macros::Prj;
|
use geo_macros::Prj;
|
||||||
|
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||||
use proj::{Proj, ProjError};
|
use proj::{Proj, ProjError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
type Lat = f64;
|
type Lat = f64;
|
||||||
type Lon = f64;
|
type Lon = f64;
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Range(pub f64, pub f64);
|
pub struct Range(pub f64, pub f64);
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@ -16,15 +18,17 @@ pub enum CoordError {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(f64, f64)> for Range {
|
impl<T: AsPrimitive<f64> + Num> From<(T, T)> for Range {
|
||||||
fn from(value: (f64, f64)) -> Self {
|
fn from(value: (T, T)) -> Self {
|
||||||
|
let value = (value.0.as_(), value.1.as_());
|
||||||
let (_min, _max) = (value.0.min(value.1), value.0.max(value.1));
|
let (_min, _max) = (value.0.min(value.1), value.0.max(value.1));
|
||||||
Self(_min, _max)
|
Self(_min, _max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LatLonCoord<T: ProjectionS> {
|
pub struct LatLonCoord<T: ProjectionS> {
|
||||||
actual: ((i32, i32), (i32, i32)),
|
// actual: ((f64, f64), (f64, f64)),
|
||||||
|
actual: (Range, Range),
|
||||||
logical: (Range, Range),
|
logical: (Range, Range),
|
||||||
pcs: PCS<T>,
|
pcs: PCS<T>,
|
||||||
}
|
}
|
||||||
@ -53,21 +57,50 @@ impl<T: ProjectionS> LatLonCoord<T> {
|
|||||||
lon: Option<Range>,
|
lon: Option<Range>,
|
||||||
lat: Option<Range>,
|
lat: Option<Range>,
|
||||||
actual: ((i32, i32), (i32, i32)),
|
actual: ((i32, i32), (i32, i32)),
|
||||||
|
// actual: (Range, Range),
|
||||||
project: T,
|
project: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let pcs = PCS::new(project, lon, lat);
|
let pcs = PCS::new(project, lon, lat);
|
||||||
let _box = pcs.bbox().unwrap();
|
let _box = pcs.bbox().unwrap();
|
||||||
Self {
|
Self {
|
||||||
actual,
|
actual: (Range::from(actual.0), Range::from(actual.1)),
|
||||||
pcs: pcs,
|
pcs: pcs,
|
||||||
logical: _box,
|
logical: _box,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lon_range(&self) -> Range {
|
||||||
|
self.pcs.lon_range
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lat_range(&self) -> Range {
|
||||||
|
self.pcs.lat_range
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
|
impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
|
||||||
fn map(&self, axis_1: f64, axis_2: f64) -> super::ScreenCoord {
|
fn map(&self, axis_1: f64, axis_2: f64) -> super::ScreenCoord {
|
||||||
(0, 0)
|
let point = self.pcs.map((axis_1, axis_2));
|
||||||
|
let logical_dim1_span = self.logical.0 .1 - self.logical.0 .0;
|
||||||
|
|
||||||
|
let dim1_rate = (point.0 - self.logical.0 .0) / logical_dim1_span;
|
||||||
|
let logical_dim2_span = self.logical.1 .1 - self.logical.1 .0;
|
||||||
|
let dim2_rate = (point.1 - self.logical.1 .0) / logical_dim2_span;
|
||||||
|
|
||||||
|
(
|
||||||
|
(dim1_rate * (self.actual.0 .1 - self.actual.0 .0) as f64) + self.actual.0 .0,
|
||||||
|
(dim2_rate * (self.actual.1 .1 - self.actual.1 .0) as f64) + self.actual.1 .0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dim1_range(&self) -> (f64, f64) {
|
||||||
|
let v = self.lon_range();
|
||||||
|
(v.0, v.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dim2_range(&self) -> (f64, f64) {
|
||||||
|
let v = self.lat_range();
|
||||||
|
(v.0, v.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +190,8 @@ impl Mercator {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
central_lon: 0.0,
|
central_lon: 0.0,
|
||||||
min_latitude: 0.0,
|
min_latitude: -82.0,
|
||||||
max_latitude: 70.0,
|
max_latitude: 82.0,
|
||||||
false_easting: 0.0,
|
false_easting: 0.0,
|
||||||
false_northing: 0.0,
|
false_northing: 0.0,
|
||||||
latitude_true_scale: 0.0,
|
latitude_true_scale: 0.0,
|
||||||
@ -198,7 +231,7 @@ impl ProjectionS for Mercator {
|
|||||||
|
|
||||||
let lat_range = Range {
|
let lat_range = Range {
|
||||||
0: lat_range.0.max(self.min_latitude),
|
0: lat_range.0.max(self.min_latitude),
|
||||||
1: lat_range.0.min(self.max_latitude),
|
1: lat_range.1.min(self.max_latitude),
|
||||||
};
|
};
|
||||||
(lon_range, lat_range)
|
(lon_range, lat_range)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use crate::data::RadarData2d;
|
use crate::{data::RadarData2d, tree::get};
|
||||||
|
|
||||||
use super::coords::{Coord, ScreenCoord};
|
use super::coords::{Coord, ScreenCoord};
|
||||||
use gtk::{cairo::*, gdk::RGBA};
|
use gtk::{
|
||||||
use num_traits::Num;
|
cairo::*,
|
||||||
|
gdk::{builders::RGBABuilder, RGBA},
|
||||||
|
};
|
||||||
|
use num_traits::{FromPrimitive, Num};
|
||||||
pub struct Painter<'a, T: Num, C: Coord<T>> {
|
pub struct Painter<'a, T: Num, C: Coord<T>> {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
@ -33,18 +36,175 @@ impl<'a, T: Num + Clone, C: Coord<T>> Painter<'a, T, C> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_pixel(&self, point: ScreenCoord) {}
|
fn draw_pixel(&self, point: ScreenCoord, color: &RGBA) {
|
||||||
|
self.context
|
||||||
|
.rectangle(f64::from(point.0), f64::from(point.1), 1.0, 1.0);
|
||||||
|
self.set_color(color);
|
||||||
|
|
||||||
fn draw_rect(&self, point: ScreenCoord, width: f64, height: f64) {}
|
self.context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_line(&self, start: ScreenCoord, end: ScreenCoord) {}
|
fn draw_rect(&self, point: ScreenCoord, width: f64, height: f64, color: &RGBA, fill: bool) {
|
||||||
|
self.set_color(color);
|
||||||
|
self.set_stroke_width(1);
|
||||||
|
self.context.rectangle(point.0, point.1, width, height);
|
||||||
|
self.context.fill();
|
||||||
|
// if fill {
|
||||||
|
// self.context.fill();
|
||||||
|
// } else {
|
||||||
|
// self.context.stroke();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_stroke_width(&self, width: u32) {
|
||||||
|
self.context.set_line_width(f64::from(width));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_line(&self, start: ScreenCoord, end: ScreenCoord) {
|
||||||
|
self.set_color(&RGBA::BLACK);
|
||||||
|
self.set_stroke_width(1);
|
||||||
|
self.context.move_to(start.0, start.1);
|
||||||
|
self.context.line_to(end.0, end.1);
|
||||||
|
|
||||||
|
self.context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_path<I: IntoIterator<Item = ScreenCoord>>(&self, path: I) {
|
||||||
|
let mut path = path.into_iter();
|
||||||
|
if let Some((x, y)) = path.next() {
|
||||||
|
self.context.move_to(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x, y) in path {
|
||||||
|
self.context.line_to(x, y);
|
||||||
|
}
|
||||||
|
self.context.stroke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
||||||
pub fn draw_radar_2d<T: Num + Clone, D>(&self, data: &RadarData2d<T, D>)
|
pub fn draw_radar_2d<T: Num + Clone + PartialEq + PartialOrd + FromPrimitive + Copy, D>(
|
||||||
where
|
&self,
|
||||||
|
data: &RadarData2d<T, D>,
|
||||||
|
) where
|
||||||
D: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
D: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||||
{
|
{
|
||||||
|
let levels: Vec<T> = vec![
|
||||||
|
T::from_i8(0).unwrap(),
|
||||||
|
T::from_i8(5).unwrap(),
|
||||||
|
T::from_i8(10).unwrap(),
|
||||||
|
T::from_i8(15).unwrap(),
|
||||||
|
T::from_i8(20).unwrap(),
|
||||||
|
T::from_i8(25).unwrap(),
|
||||||
|
T::from_i8(30).unwrap(),
|
||||||
|
T::from_i8(35).unwrap(),
|
||||||
|
T::from_i8(40).unwrap(),
|
||||||
|
T::from_i8(45).unwrap(),
|
||||||
|
T::from_i8(50).unwrap(),
|
||||||
|
T::from_i8(55).unwrap(),
|
||||||
|
T::from_i8(60).unwrap(),
|
||||||
|
T::from_i8(65).unwrap(),
|
||||||
|
];
|
||||||
|
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(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut polygons: Vec<(shapefile::Polygon, _)> =
|
||||||
|
shapefile::read_as::<_, shapefile::Polygon, shapefile::dbase::Record>(
|
||||||
|
"/Users/ruomu/china/省界_region.shp",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// for (polygon, _) in polygons.into_iter() {
|
||||||
|
// let x_range = polygon.bbox().x_range();
|
||||||
|
// let y_range = polygon.bbox().y_range();
|
||||||
|
|
||||||
|
// let lon_range = self.coord.dim1_range();
|
||||||
|
// let lat_range = self.coord.dim2_range();
|
||||||
|
// }
|
||||||
|
data.data.outer_iter().enumerate().for_each(|(r_num, row)| {
|
||||||
|
row.iter().enumerate().for_each(|(c_num, v)| {
|
||||||
|
let point = self.coord.map(data.dim1[c_num], data.dim2[r_num]);
|
||||||
|
if *v > T::from_i8(-125).unwrap() {
|
||||||
|
let color = get(&levels, &colors, *v);
|
||||||
|
// self.draw_pixel(point, &color);
|
||||||
|
self.draw_rect(point, 1.5, 1.5, &color, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/render/imp.rs
Normal file
43
src/render/imp.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use glib::{ObjectExt, ParamSpec, Properties, Value};
|
||||||
|
use gtk::glib;
|
||||||
|
use gtk::subclass::prelude::*;
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
#[derive(Properties, Default)]
|
||||||
|
#[properties(wrapper_type = super::Render)]
|
||||||
|
pub struct Render {
|
||||||
|
#[property(get, set)]
|
||||||
|
height: Cell<u32>,
|
||||||
|
#[property(get, set)]
|
||||||
|
width: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for Render {
|
||||||
|
const NAME: &'static str = "MyRender";
|
||||||
|
type Type = super::Render;
|
||||||
|
type ParentType = gtk::DrawingArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trait shared by all GObjects
|
||||||
|
impl ObjectImpl for Render {
|
||||||
|
fn properties() -> &'static [ParamSpec] {
|
||||||
|
Self::derived_properties()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {}
|
||||||
|
|
||||||
|
impl DrawingAreaImpl for Render {}
|
||||||
18
src/render/mod.rs
Normal file
18
src/render/mod.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
mod imp;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render {
|
||||||
|
pub fn new(height: u32, width: u32) -> Self {
|
||||||
|
Object::builder()
|
||||||
|
.property("height", height)
|
||||||
|
.property("width", width)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
|
use gtk::gdk::RGBA;
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
use plotters::style::RGBAColor;
|
|
||||||
pub fn get<T>(levels: &Vec<T>, colors: &Vec<RGBAColor>, v: T) -> RGBAColor
|
pub fn get<T>(levels: &Vec<T>, colors: &Vec<RGBA>, v: T) -> RGBA
|
||||||
where
|
where
|
||||||
T: Num + PartialOrd,
|
T: Num + PartialOrd + Copy,
|
||||||
{
|
{
|
||||||
let len = levels.len();
|
let len = levels.len();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user