
            Layer::geojson_layer_with_path(
                "/Users/tsuki/Downloads/new_zhejiang.json",
                true,
                |_self, c, render, _| {
                    if let Some(json_resources) = _self.get_resources() {
                        if let Resources::GeoJson(geojson) = json_resources.deref() {
                            MapRender::test(&geojson, c, render);
                        }
                    }
                },
            ),
            Layer::new(true, None, |s, c, render, _| {
                if let Some(target) = s.render_target() {
                    if let Ok(_) = c.image_size(target.target) {
                        let (x, y) = target.size(render);
                        let (ox, oy) = target.origin(render);
                        let painter = Paint::image(target.target, ox, oy, x, y, 0.0, 1.0);
                        let mut path = Path::new();
                        path.rect(ox, oy, x, y);
                        c.fill_path(&path, &painter);
                    }
                } else {
                    let renderer = RadarEchoRenderer::new(BoundaryNorm::new(
                        vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
                        vec![
                            Color::rgb(0, 172, 164),
                            Color::rgb(192, 192, 254),
                            Color::rgb(122, 114, 238),
                            Color::rgb(30, 38, 208),
                            Color::rgb(166, 252, 168),
                            Color::rgb(0, 234, 0),
                            Color::rgb(16, 146, 26),
                            Color::rgb(252, 244, 100),
                            Color::rgb(200, 200, 2),
                            Color::rgb(140, 140, 0),
                            Color::rgb(254, 172, 172),
                            Color::rgb(254, 100, 92),
                            Color::rgb(238, 2, 48),
                            Color::rgb(212, 142, 254),
                            Color::rgb(170, 36, 250),
                        ],
                        true,
                    ));
                    let loader = Npz;
                    let data: RadarData2d<i8, OwnedRepr<i8>> = loader
                        .load("/Users/tsuki/projects/radar-g/test2.npz")
                        .unwrap();
                    let img = renderer.render(render, c, &data);
                    if let Ok(_) = c.image_size(img.target) {
                        let (x, y) = img.size(render);
                        let (ox, oy) = img.origin(render);
                        println!("{} {} {} {}", x, y, ox, oy);
                        let painter = Paint::image(img.target, ox, oy, x, y, 0.0, 1.0);
                        let mut path = Path::new();
                        path.rect(ox, oy, x, y);
                        s.set_render_target(img);
                        c.fill_path(&path, &painter);
                        c.flush();
                    }
                }
            }),






############# TEMPLATES ###################
// Monitor::new(
        //     Render::new(
        //         Some(Mapper::new(
        //             Proj::new(Mercator::default().build().as_str()).unwrap(),
        //             (119.539..121.135).into(),
        //             (29.13..30.164).into(),
        //         )),
        //         RenderConfig { padding: [50.0;4] }
        //     )
        // )



// Layer::grid_render_layer_with_path(
        //     "/users/tsuki/projects/radar-g/test2.npz",
        //     Npz,
        //     BoundaryNorm::default(),
        // )



// fn resample(
//     &self,
//     width_rate: f64,
//     height_rate: f64,
//     filter_len: f64,
// ) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
//     let width_rate = width_rate.min(1.0);
//     let height_rate = height_rate.min(1.0);
//     match self.coord_type {
//         CoordType::Polar => Err(DataError::FormatError),
//         CoordType::LatLon => {
//             let width_filtered: ArrayBase<ndarray::OwnedRepr<T>, Ix2> =
//                 Self::_resample(&self.data, width_rate, filter_len);

//             let result: ArrayBase<OwnedRepr<T>, Ix2> =
//                 Self::_resample(&width_filtered.t(), height_rate, filter_len)
//                     .t()
//                     .to_owned();

//             let new_dim1: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
//                 &Array2::from_shape_vec((1, self.dim1.len()), self.dim1.to_vec()).unwrap(),
//                 width_rate,
//                 filter_len,
//             )
//             .slice(s![0, ..])
//             .to_owned();

//             let new_dim2: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
//                 &Array2::from_shape_vec((1, self.dim2.len()), self.dim2.to_vec()).unwrap(),
//                 height_rate,
//                 filter_len,
//             )
//             .slice(s![0, ..])
//             .to_owned();

//             Ok(RadarData2d {
//                 dim1: new_dim1,
//                 dim2: new_dim2,
//                 data: result,
//                 coord_type: self.coord_type.to_owned(),
//             })
//         }
//     }
// }

// fn _resample<'a, V, R: ndarray::Data<Elem = V>>(
//         data: &'a ArrayBase<R, Ix2>,
//         rate: f64,
//         filter_len: f64,
//     ) -> Array2<V>
//     where
//         V: Num + Clone + AsPrimitive<f64> + FromPrimitive,
//     {
//         let ori_width = data.ncols();
//         let ori_height = data.nrows();

//         let new_width = (ori_width as f64 * rate).ceil() as usize;
//         let mut result: Array2<V> = Array2::zeros((ori_height, new_width));
//         (0..ori_height).into_iter().for_each(|height| {
//             for width in 0..new_width {
//                 let center_x = (width as f64 + 0.5) / new_width as f64 * ori_width as f64;
//                 let filter_start = center_x - filter_len / 2.0;
//                 let start_idx = (filter_start - 0.5).ceil() as usize;

//                 let mut value_sum = 0.0;
//                 let mut filter_sum = 0.0;

//                 for i in 0..filter_len as usize {
//                     let input_x = start_idx + i;
//                     let weight = windowed_sinc(
//                         (input_x as f64 + 0.5 - center_x) * rate,
//                         (input_x as f64 + 0.5 - filter_start) / filter_len,
//                     );
//                     value_sum += weight * data[[height, input_x.clamp(0, ori_width - 1)]].as_();
//                     filter_sum += weight;
//                 }

//                 result[[height, width]] = V::from_f64(value_sum / filter_sum).unwrap();
//             }
//         });
//         result
//     }

// pub struct LevelData<T: Num + Clone + PartialEq + PartialOrd>(
//     pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>,
// );

// impl<T> LevelData<T>
// where
//     T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug + PartialEq + PartialOrd,
// {
//     fn value(
//         level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
//         level_num: usize,
//     ) -> Vec<RadarData2d<T, OwnedRepr<T>>> {
//         if level_num == 0 {
//             return level_data;
//         }

//         let mut result: Vec<RadarData2d<T, OwnedRepr<T>>> =
//             Vec::with_capacity(level_data.len() * 4);

//         let results = level_data
//             .iter()
//             .flat_map(|v| v.split().into_iter().map(|x| x.value_to_owned()));

//         result.extend(results);

//         return Self::value(result, level_num - 1);
//     }

//     fn new(data: &RadarData2d<T, OwnedRepr<T>>, level: usize, rate: f64) -> Self {
//         // let rate = 1.0 / level as f64;
//         let resampled = data.resample(rate, rate, 2.0).unwrap();
//         let blocks = Self::value(vec![resampled], level);
//         let mut tree: Quadtree<i64, RadarData2d<T, OwnedRepr<T>>> =
//             quadtree_rs::Quadtree::new(level);

//         blocks.into_iter().for_each(|block| {
//             tree.insert(
//                 AreaBuilder::default()
//                     .anchor(quadtree_rs::point::Point {
//                         x: *block.dim1.first().unwrap() as i64,
//                         y: *block.dim2.first().unwrap() as i64,
//                     })
//                     .dimensions((block.dim1.len() as i64, block.dim2.len() as i64))
//                     .build()
//                     .unwrap(),
//                 block,
//             );
//         });

//         Self(tree)
//     }
// }

// pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
// where
//     T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
//     T: PartialEq + PartialOrd,
// {
//     let numerator = 1.0 / levels as f64;
//     (0..levels)
//         .into_iter()
//         .map(|level| LevelData::new(&data, level + 1, 1.0 - level as f64 * numerator))
//         .collect()
// }





#[inline]
fn windowed_sinc(x: f64, y: f64) -> f64 {
    let x = x * PI;
    let sinc = if x != 0.0 { f64::sin(x) / x } else { 1.0 };
    let window = if 0f64 <= y && y <= 1.0 {
        1.0 - (y - 0.5).abs() * 2.0
    } else {
        0f64
    };
    sinc * window
}

pub enum DownSampleMeth {
    STD,
    MEAN,
    VAR,
}

#[derive(Clone, Copy, Debug)]
pub enum CoordType {
    Polar,
    LatLon,
}


// 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(),
//     ];
