Commit de5f1a40 authored by Valentin Buck's avatar Valentin Buck
Browse files

Merge branch 'dome' of git.geomar.de:digital-earth/digital-earth-viewer into dome

parents a9119deb bb5cc5e1
......@@ -48,7 +48,7 @@ source_filterkernel = ["filterkernel_source"]
source_time_merging = ["time_merging_source"]
source_k_nearest = ["k_nearest_source"]
source_hierarchical = ["hierarchical_source"]
source_mipmap = ["mipmap_source"]
default_sources = ["source_basic_earth", "source_maptiles", "source_netcdf", "source_odv", "source_currents", "source_turbidity", "source_esri_ascii", "source_csv", "source_test", "source_wms", "source_geoimage", "source_sqlite", "source_remote", "source_geotiff", "source_shapefile", "source_k_nearest", "source_time_merging", "source_filterkernel", "source_hierarchical"]
......@@ -91,6 +91,7 @@ onnx_source = {path = "sources/onnx_source", optional = true}
filterkernel_source = {path = "sources/filterkernel_source", optional = true}
time_merging_source = {path = "sources/time_merging_source", optional = true}
hierarchical_source = {path="sources/hierarchical_source", optional=true}
mipmap_source = {path="sources/mipmap_source", optional=true}
#GUI
alcro = { version = "0.5.3", optional = true }
......
[package]
name = "mipmap_source"
version = "0.1.0"
authors = ["Flemming Stäbler <fstaebler@geomar.de>"]
edition = "2018"
license-file = "../../../LICENSE.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tileserver-model = {path="../../tileserver-model"}
futures = "*"
\ No newline at end of file
//This file is licensed under EUPL v1.2 as part of the Digital Earth Viewer
mod mipmap_source;
pub use mipmap_source::MipmapSource;
\ No newline at end of file
//This file is licensed under EUPL v1.2 as part of the Digital Earth Viewer
use tileserver_model::*;
use futures::future::try_join_all;
pub struct MipmapSource{
layers: Vec<LayerInfo>,
depth: u8,
instance_name: String
}
#[async_trait]
impl SourceInit for MipmapSource{
async fn initialize(settings: SourceConfig, mut source_info: SourceInfo) -> SourceInitResult {
let instance_name = settings.settings.get("instance").map(|s| s.as_str()).ok_or_else(|| "No instance given for derivative source")?;
let layer_name = settings.settings.get("layer").map(|s| s.as_str()).ok_or_else(|| "No layer given for derivative source")?;
let depth: u8 = settings.settings.get("depth").map(|s| s.parse()).ok_or_else(|| "No depth given!")??;
//Get Source Info
let r_source_info = DATAPROVIDER.get().ok_or_else(|| "Could not access dataprovider")?.wait_for_source_info(instance_name.to_string()).await?;
//Find layerinfo
let layers = r_source_info.layers.clone();
for layer in layers.iter(){
source_info.add_layer(layer.clone());
}
Ok((source_info.clone(), Box::new(
MipmapSource{
layers,
depth,
instance_name: instance_name.to_string()
}
)))
}
fn accepts_file(_file: &std::path::Path) -> bool {
false
}
}
#[async_trait]
impl Source for MipmapSource{
async fn sample(&self, query: &SampleQuery) -> SourceResult {
if let Some(layer) = self.layers.iter().find(|layer| layer.name == query.layername){
let my_depth = query.tile.path.len().min(255) as u8;
let other_depth = layer.max_zoom_level;
let provider = DATAPROVIDER.get().ok_or_else(|| "Could not access dataprovider")?;
if my_depth + self.depth < other_depth {
let mut tiles = vec![query.tile.clone()];
for i in 0..(other_depth - my_depth) {
tiles = tiles.into_iter().flat_map(|t| t.split().into_iter()).collect();
}
let geodatas = try_join_all(tiles.into_iter().map(|t| async {
provider.get_geodata(
SampleQuery::new(
self.instance_name.clone(),
query.layername.clone(),
t.clone(),
query.tpage,
query.zpage
),
layer.layer_type
).await.map(|d| (d, t))
})).await?;
if(geodatas.is_empty()){
Ok(None)
}else{
let result_array = match layer.layer_type {
GeoDataType::ColorTiles =>
};
geodatas
.into_iter()
.filter_map(|(g, t)| g.map(|gi| (gi, t)))
.for_each(|(g, t)| {
todo!();
});
todo!()
}
} else {
provider.get_geodata(
SampleQuery::new(
self.instance_name.clone(),
query.layername.clone(),
query.tile.clone(),
query.tpage,
query.zpage
), layer.layer_type).await
}
}else{
Err(format!("Layer {} not found in source", query.layername).into())
}
}
}
/*
if (query.tpage as usize) < layer.timesteps.as_ref().map(|tsteps| tsteps.len()).unwrap_or(1usize){
//Assemble tpages that fit
let request_tpages = layer.timesteps.as_ref().map(|tsteps| {
let maxdate = TimeParser::timestamp_to_naivedatetime(*tsteps.get(query.tpage as usize).unwrap());
let mindate = maxdate - self.maximum_time_distance;
tsteps.iter().enumerate().rev().filter(|(_i,t)| {
let ndt = TimeParser::timestamp_to_naivedatetime(**t);
ndt >= mindate && ndt <= maxdate
}).map(|(i,_t)| i).collect::<Vec<_>>()
}).unwrap_or(vec![0]);
//Request data
let provider = DATAPROVIDER.get().ok_or_else(|| "Could not access dataprovider")?;
let tile = query.tile.clone();
let mut color_array: Option<TileData<Color>> = None;
let mut scalar_array: Option<TileData<Scalar>> = None;
let datatype = layer.layer_type;
let mut more_data_needed = true;
for (index, tpage) in request_tpages.iter().enumerate(){
trace!("Requesting tile {} ({} of {})", tpage, index, request_tpages.len());
let geodata = provider.get_geodata(
SampleQuery::new(
self.instance_name.clone(),
layer.name.clone(),
tile.clone(),
*tpage as u32,
query.zpage
), datatype).await;
match geodata{
Err(e) => return Err(format!("Error sampling dependent source: {:?}", e).into()),
Ok(None) => continue,
Ok(Some(data)) => {
match data{
GeoData::ScalarTiles(scalartile) => {
if let Some(array) = scalar_array.as_mut(){
array.data.par_iter_mut().zip(scalartile.data.par_iter()).for_each(|(original_value, next_value)| {
if original_value.is_nodata(){
*original_value = *next_value;
}
});
}else{
scalar_array = Some(scalartile);
}
if let Some(array) = scalar_array.as_ref(){
more_data_needed = array.data.par_iter().filter(|v| !v.is_nodata()).count() < self.minimum_fill_pixels;
}
},
GeoData::ColorTiles(colortile) => {
if let Some(array) = color_array.as_mut(){
array.data.par_iter_mut().zip(colortile.data.par_iter()).for_each(|(original_value, next_value)| {
if original_value.is_nodata(){
*original_value = *next_value;
}
});
}else{
color_array = Some(colortile);
}
if let Some(array) = color_array.as_ref(){
more_data_needed = array.data.par_iter().filter(|v| !v.is_nodata()).count() < self.minimum_fill_pixels;
}
},
other=> return Err(format!("Unimplemented merging for datatype {:?}", GeoDataType::from(other)).into())
}
}
}
if !more_data_needed {
break;
}
}
match layer.layer_type{
GeoDataType::ScalarTiles => {return Ok(scalar_array.map(|a| GeoData::ScalarTiles(a)))},
GeoDataType::ColorTiles => {return Ok(color_array.map(|a| GeoData::ColorTiles(a)))},
other=> return Err(format!("Unimplemented merging for datatype {:?}", GeoDataType::from(other)).into())
}
}else{
Err(format!("Tpage {} requested but only {} tpages in source", query.tpage, layer.timesteps.as_ref().map(|tsteps| tsteps.len()).unwrap_or(0usize)).into())
}
}else{
Err(format!("Layer {} not found in source", query.layername).into())
}
}
}*/
\ No newline at end of file
......@@ -24,38 +24,10 @@ impl SourceInit for TimeMergingSource{
let maximum_time_distance = chrono::Duration::milliseconds(TimeParser::duration_string_to_milliseconds(&maximum_time_str)?);
//Wait until source available
loop{
let status = DATAPROVIDER.get().ok_or_else(|| "Could not access dataprovider")?.get_source_status(instance_name.to_string()).await?;
if let Some(status) = status{
match status{
SourceStatus::Loading => {
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
continue;
}
SourceStatus::Loaded => {
break;
}
SourceStatus::Error(e) => {
return Err(format!("Required source {} could not be initialized due to error {}", instance_name, e).into());
}
}
}else{
info!("Source {} not registered yet, waiting 10 seconds", instance_name);
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
continue;
//return Err(format!("Source {} was not registered at the time of dependant source initialization", instance_name).into());
}
}
info!("Dependent source initialized");
//Get sourceinfo
let r_source_info = DATAPROVIDER.get().ok_or_else(|| "Could not access dataprovider")?
.get_source_info(instance_name.to_string()).await?
.ok_or_else(|| format!("Source info of required source {} not received", instance_name))?;
.wait_for_source_info(instance_name.to_string()).await?;
//Find layerinfo
......
......@@ -156,7 +156,7 @@ pub async fn initialize_source_constructors() {
make_init_fn!(k_nearest_source::KNearestSource::initialize),
);
#[cfg(feature = "source_shapefile")]
#[cfg(feature = "source_shapefile")]
Registry
.add_source(
"shapefile".to_string(),
......@@ -164,7 +164,7 @@ pub async fn initialize_source_constructors() {
make_init_fn!(shapefile_source::ShapeFileSource::initialize),
);
#[cfg(feature = "source_onnx")]
#[cfg(feature = "source_onnx")]
Registry
.add_source(
"onnx".to_string(),
......@@ -172,27 +172,37 @@ pub async fn initialize_source_constructors() {
make_init_fn!(onnx_source::OnnxSource::initialize),
);
#[cfg(feature = "source_filterkernel")]
#[cfg(feature = "source_filterkernel")]
Registry
.add_source(
"filterkernel".to_string(),
Box::new(filterkernel_source::FilterKernelSource::accepts_file),
make_init_fn!(filterkernel_source::FilterKernelSource::initialize),
);
#[cfg(feature = "source_time_merging")]
Registry
.add_source(
"time_merging".to_string(),
Box::new(time_merging_source::TimeMergingSource::accepts_file),
make_init_fn!(time_merging_source::TimeMergingSource::initialize),
);
#[cfg(feature = "source_hierarchical")]
Registry
.add_source(
"hierarchical".to_string(),
Box::new(hierarchical_source::HierarchicalSource::accepts_file),
make_init_fn!(hierarchical_source::HierarchicalSource::initialize),
);
#[cfg(feature = "source_time_merging")]
Registry
.add_source(
"time_merging".to_string(),
Box::new(time_merging_source::TimeMergingSource::accepts_file),
make_init_fn!(time_merging_source::TimeMergingSource::initialize),
);
#[cfg(feature = "source_hierarchical")]
Registry
.add_source(
"hierarchical".to_string(),
Box::new(hierarchical_source::HierarchicalSource::accepts_file),
make_init_fn!(hierarchical_source::HierarchicalSource::initialize),
);
#[cfg(feature = "source_mipmap")]
Registry
.add_source(
"mipmap".to_string(),
Box::new(mipmap_source::MipmapSource::accepts_file),
make_init_fn!(mipmap_source::MipmapSource::initialize),
);
}
#[cfg(feature = "source_basic_earth")]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment