bbox_frontend/
endpoints.rs1use crate::{themes_json, MapInventory};
2use actix_web::{
3 web::{self, get, resource},
4 Error, HttpRequest, HttpResponse,
5};
6use bbox_core::endpoints::abs_req_baseurl;
7use bbox_core::static_files::{embedded, embedded_index, EmbedFile};
8use bbox_core::templates::{create_env_embedded, render_endpoint};
9use minijinja::{context, Environment};
10use once_cell::sync::Lazy;
11use rust_embed::RustEmbed;
12use std::path::PathBuf;
13
14#[derive(RustEmbed)]
15#[folder = "templates/"]
16struct Templates;
17
18#[derive(RustEmbed)]
19#[folder = "static/frontend/"]
20struct FrontendStatics;
21
22static TEMPLATES: Lazy<Environment<'static>> = Lazy::new(create_env_embedded::<Templates>);
23
24async fn index(inventory: web::Data<MapInventory>) -> Result<HttpResponse, Error> {
25 let template = TEMPLATES
26 .get_template("index.html")
27 .expect("couln't load template `index.html`");
28 #[cfg(debug_assertions)]
29 let links = vec![
30 "/qgis/helloworld?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-67.593,-176.248,83.621,182.893&CRS=EPSG:4326&WIDTH=515&HEIGHT=217&LAYERS=Country,Hello&STYLES=,&FORMAT=image/png; mode=8bit&DPI=96&TRANSPARENT=TRUE",
31 "/qgis/ne?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-20037508.34278924391,-5966981.031407224014,19750246.20310878009,17477263.06060761213&CRS=EPSG:900913&WIDTH=1399&HEIGHT=824&LAYERS=country&STYLES=&FORMAT=image/png; mode=8bit",
32 "/wms/map/ne?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-20037508.34278924391,-5966981.031407224014,19750246.20310878009,17477263.06060761213&CRS=EPSG:900913&WIDTH=1399&HEIGHT=824&LAYERS=country&STYLES=&FORMAT=image/png; mode=8bit",
33 "/wms/mock/helloworld?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-67.593,-176.248,83.621,182.893&CRS=EPSG:4326&WIDTH=515&HEIGHT=217&LAYERS=Country,Hello&STYLES=,&FORMAT=image/png; mode=8bit&DPI=96&TRANSPARENT=TRUE",
34 ];
35 #[cfg(not(debug_assertions))]
36 let links = Vec::<&str>::new();
37 let index = template
38 .render(
39 context!(cur_menu => "Home", wms_services => &inventory.wms_services, links => links),
40 )
41 .expect("index.hmtl render failed");
42 Ok(HttpResponse::Ok().content_type("text/html").body(index))
43}
44
45#[cfg(feature = "qwc2")]
46#[derive(RustEmbed)]
47#[folder = "static/qwc2/"]
48struct Qwc2Statics;
49
50#[cfg(not(feature = "qwc2"))]
51type Qwc2Statics = bbox_core::static_files::EmptyDir;
52
53async fn qwc2_map(path: web::Path<(String, PathBuf)>) -> Result<EmbedFile, Error> {
54 embedded_index::<Qwc2Statics>(path.1.clone().into()).await
56}
57
58async fn qwc2_themes(
59 inventory: web::Data<MapInventory>,
60 req: HttpRequest,
61) -> Result<HttpResponse, Error> {
62 let json = themes_json(&inventory.wms_services, abs_req_baseurl(&req), None).await;
63 Ok(HttpResponse::Ok().json(json))
64}
65
66async fn qwc2_theme(
67 id: web::Path<String>,
68 inventory: web::Data<MapInventory>,
69 req: HttpRequest,
70) -> Result<HttpResponse, Error> {
71 let json = themes_json(&inventory.wms_services, abs_req_baseurl(&req), Some(&*id)).await;
73 Ok(HttpResponse::Ok().json(json))
74}
75
76#[cfg(feature = "maplibre")]
77#[derive(RustEmbed)]
78#[folder = "static/maplibre/"]
79struct MaplibreStatics;
80
81#[cfg(not(feature = "maplibre"))]
82type MaplibreStatics = bbox_core::static_files::EmptyDir;
83
84#[cfg(feature = "openlayers")]
85#[derive(RustEmbed)]
86#[folder = "static/ol/"]
87struct OlStatics;
88
89#[cfg(not(feature = "openlayers"))]
90type OlStatics = bbox_core::static_files::EmptyDir;
91
92#[cfg(feature = "proj")]
93#[derive(RustEmbed)]
94#[folder = "static/proj/"]
95struct ProjStatics;
96
97#[cfg(not(feature = "proj"))]
98type ProjStatics = bbox_core::static_files::EmptyDir;
99
100#[cfg(feature = "swaggerui")]
101#[derive(RustEmbed)]
102#[folder = "static/swagger/"]
103struct SwaggerStatics;
104
105#[cfg(not(feature = "swaggerui"))]
106type SwaggerStatics = bbox_core::static_files::EmptyDir;
107
108async fn swaggerui_html() -> Result<HttpResponse, Error> {
109 render_endpoint(&TEMPLATES, "swaggerui.html", context!(cur_menu=>"API")).await
110}
111
112#[cfg(feature = "redoc")]
113#[derive(RustEmbed)]
114#[folder = "static/redoc/"]
115struct RedocStatics;
116
117#[cfg(not(feature = "redoc"))]
118type RedocStatics = bbox_core::static_files::EmptyDir;
119
120async fn redoc_html() -> Result<HttpResponse, Error> {
121 render_endpoint(&TEMPLATES, "redoc.html", context!(cur_menu=>"API")).await
122}
123
124async fn scalar_html() -> Result<HttpResponse, Error> {
125 render_endpoint(&TEMPLATES, "scalar.html", context!(cur_menu=>"API")).await
126}
127
128pub fn register(cfg: &mut web::ServiceConfig) {
129 cfg.service(resource("/").route(get().to(index)))
130 .service(
131 resource(r#"/frontend/{filename:.*}"#).route(get().to(embedded::<FrontendStatics>)),
132 )
133 .service(
134 resource(r#"/maplibre/{filename:.*}"#).route(get().to(embedded::<MaplibreStatics>)),
135 )
136 .service(resource(r#"/ol/{filename:.*}"#).route(get().to(embedded::<OlStatics>)))
137 .service(resource(r#"/proj/{filename:.*}"#).route(get().to(embedded::<ProjStatics>)))
138 .service(resource(r#"/swagger/{filename:.*}"#).route(get().to(embedded::<SwaggerStatics>)))
139 .service(resource("/swaggerui.html").route(get().to(swaggerui_html)))
140 .service(resource(r#"/redoc/{filename:.*}"#).route(get().to(embedded::<RedocStatics>)))
141 .service(resource("/redoc.html").route(get().to(redoc_html)))
142 .service(resource("/scalar.html").route(get().to(scalar_html)));
143 if cfg!(feature = "qwc2") {
144 cfg.service(resource("/qwc2/themes.json").route(get().to(qwc2_themes)))
145 .service(resource(r#"/qwc2/{filename:.*}"#).route(get().to(embedded::<Qwc2Statics>)))
146 .service(resource("/qwc2_map/{id}/themes.json").route(get().to(qwc2_theme)))
147 .service(resource(r#"/qwc2_map/{id}/{filename:.*}"#).route(get().to(qwc2_map)));
148 }
149 if cfg!(not(feature = "map-server")) {
150 cfg.app_data(web::Data::new(MapInventory::default()));
151 }
152}