Skip to content

Commit

Permalink
feat: génération de pyramide raster à partir de WMS-Vecteur et public…
Browse files Browse the repository at this point in the history
…ation en WMS-Raster/WMTS (#470, #517)

* refactor: pyramid -> pyramidVector #470

* feat: début formulaire génération de pyramide #470

* feat: ZoomRange utilisant Range de dsfr et possibilité d'avoir un seul des zoom top ou bottom #470 #362

* chore: sauvegarde

* feat: visualisation WMS-Raster #470

* feat: fin de formulaire génération de pyramide raster #470

* feat: publication/modification de pyramide raster en WMS-Raster #470

* feat: publication/modification de pyramide raster en WMTS #470

* feat: ajout bouton pour accéder au form générer pyramide raster #470

* feat: suppr service WMS-raster/WMTS #470

* fix: récup technical_name default values form. WMS-raster/WMTS #470

* fix: publication capabilities et métadonnées WMS-raster/WMTS #470

* fix: correction suite rebase
  • Loading branch information
ocruze authored Dec 13, 2024
1 parent fb07d63 commit 3a6adaf
Show file tree
Hide file tree
Showing 68 changed files with 2,911 additions and 337 deletions.
10 changes: 8 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ HTTPS_PROXY=
# id du processus d'intégration en base
API_ENTREPOT_PROC_INT_VECT_FILES_DB=

# id du processus de génération de pyramide
# id du processus de génération de pyramide vecteur
API_ENTREPOT_PROC_CREATE_VECT_PYR=

# id du processus de génération de pyramide raster
API_ENTREPOT_PROC_CREATE_RAST_PYR=

# Id de la community liee au datastore bac a sable
SANDBOX_COMMUNITY_ID=

Expand All @@ -47,8 +50,11 @@ SANDBOX_SERVICE_ACCOUNT_CLIENT_SECRET=
# id du processus d'intégration en base pour le Bac a sable
SANDBOX_PROC_INT_VECT_FILES_DB=

# id du processus de génération de pyramide pour le Bac a sable
# id du processus de génération de pyramide vecteur pour le Bac a sable
SANDBOX_PROC_CREATE_VECT_PYR=

# id du processus de génération de pyramide raster pour le Bac à sable
SANDBOX_PROC_CREATE_RAST_PYR=

# URL de l'API espace collaboratif
API_ESPACE_COLLABORATIF_URL=
25 changes: 22 additions & 3 deletions assets/@types/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ export enum DatasheetDocumentTypeEnum {

export type DatasheetDetailed = Datasheet & {
vector_db_list: VectorDb[] | undefined;
pyramid_list: Pyramid[] | undefined;
pyramid_vector_list: PyramidVector[] | undefined;
pyramid_raster_list: PyramidRaster[] | undefined;
upload_list: Upload[] | undefined;
service_list: Service[] | undefined;
};
Expand All @@ -108,7 +109,7 @@ export type VectorDb = StoredData & {
};

/** stored_data (donnée stockée) du type ROK4-PYRAMID-VECTOR */
export type Pyramid = StoredData & {
export type PyramidVector = StoredData & {
type: StoredDataPrivateDetailResponseDtoTypeEnum.ROK4PYRAMIDVECTOR;
tags: {
datasheet_name?: string;
Expand All @@ -120,6 +121,18 @@ export type Pyramid = StoredData & {
};
};

/** stored_data (donnée stockée) du type ROK4-PYRAMID-VECTOR */
export type PyramidRaster = StoredData & {
type: StoredDataPrivateDetailResponseDtoTypeEnum.ROK4PYRAMIDRASTER;
tags: {
datasheet_name?: string;
upload_id?: string;
proc_int_id?: string;
vectordb_id?: string;
proc_pyr_creat_id?: string;
};
};

/** upload (livraison) */
export type Upload = UploadPrivateDetailResponseDto & {
tags: {
Expand Down Expand Up @@ -180,7 +193,13 @@ export type TmsMetadata = {
};

/** configuration & offerings */
export type Configuration = ConfigurationDetailResponseDto & { styles?: CartesStyle[] };
export type Configuration = ConfigurationDetailResponseDto & {
styles?: CartesStyle[];
tags: {
datasheet_name?: string;
};
pyramid?: PyramidVector | PyramidRaster;
};

export type Offering = OfferingDetailResponseDto;
export { OfferingStatusEnum } from "./entrepot";
Expand Down
2 changes: 1 addition & 1 deletion assets/components/Layout/DatastoreLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BreadcrumbProps } from "@codegouvfr/react-dsfr/Breadcrumb";
import { useQuery } from "@tanstack/react-query";
import { FC, PropsWithChildren, memo, useMemo } from "react";

import { Datastore } from "../../@types/app";
import type { Datastore } from "../../@types/app";
import { datastoreNavItems } from "../../config/datastoreNavItems";
import api from "../../entrepot/api";
import RQKeys from "../../modules/entrepot/RQKeys";
Expand Down
8 changes: 5 additions & 3 deletions assets/components/Utils/MenuList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type MenuListItem = MenuListItemCommon &

type MenuListProps = {
menuOpenButtonProps?: Omit<ButtonProps, "linkProps" | "onClick" | "type" | "disabled">;
items: MenuListItem[];
items: (MenuListItem | undefined | false)[];
disabled?: boolean;
};

Expand All @@ -48,6 +48,8 @@ const MenuList: FC<MenuListProps> = ({ menuOpenButtonProps, items = [], disabled
setAnchorEl(null);
};

const _items: MenuListItem[] = useMemo(() => items.filter((item) => item !== undefined && item !== false), [items]);

// props du bouton ouvrir menu
const _menuOpenBtnProps = useMemo<ButtonProps>(() => {
const _props: ButtonProps = menuOpenButtonProps ? { ...(menuOpenButtonProps as ButtonProps) } : ({} as ButtonProps);
Expand All @@ -66,7 +68,7 @@ const MenuList: FC<MenuListProps> = ({ menuOpenButtonProps, items = [], disabled
return _props;
}, [menuOpenButtonProps, disabled, isMenuOpen, otherActionsBtnId, otherActionsMenuId]);

const atLeastOneIcon = useMemo<boolean>(() => items.filter((item) => item.iconId !== undefined).length > 0, [items]);
const atLeastOneIcon = useMemo<boolean>(() => _items.filter((item) => item.iconId !== undefined).length > 0, [_items]);

return (
<>
Expand All @@ -91,7 +93,7 @@ const MenuList: FC<MenuListProps> = ({ menuOpenButtonProps, items = [], disabled
}}
>
{disabled === false &&
items.map((item, i) => {
_items.map((item, i) => {
const itemContent = (
<MenuItem
key={i}
Expand Down
1 change: 0 additions & 1 deletion assets/components/Utils/RangeSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const RangeSlider: FC<RangeSliderProps> = (props) => {
value: v,
label: v.toString(),
}))}
getAriaLabel={() => "Minimum distance"}
value={values}
onChange={(_, newValue) => {
if (!Array.isArray(newValue)) {
Expand Down
19 changes: 0 additions & 19 deletions assets/components/Utils/TextWithLink.tsx

This file was deleted.

152 changes: 142 additions & 10 deletions assets/components/Utils/ZoomRange.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
import { fr } from "@codegouvfr/react-dsfr";
import Range, { RangeProps } from "@codegouvfr/react-dsfr/Range";
import { cx } from "@codegouvfr/react-dsfr/tools/cx";
import Map, { type MapOptions } from "ol/Map";
import View, { ViewOptions } from "ol/View";
import { ScaleLine } from "ol/control";
import BaseLayer from "ol/layer/Base";
import TileLayer from "ol/layer/Tile";
import { fromLonLat } from "ol/proj";
import WMTS, { optionsFromCapabilities } from "ol/source/WMTS";
import { FC, memo, useCallback, useEffect, useRef } from "react";
import { FC, memo, ReactNode, useCallback, useEffect, useRef } from "react";
import { symToStr } from "tsafe/symToStr";
import { tss } from "tss-react";

import olDefaults from "../../data/ol-defaults.json";
import useCapabilities from "../../hooks/useCapabilities";
import RangeSlider from "./RangeSlider";

import "../../sass/components/zoom-range.scss";
import imgMapZoomBottom from "../../img/zoom-range/map-zoom-bottom.png";
import imgMapZoomTop from "../../img/zoom-range/map-zoom-top.png";

type ZoomRangeProps = {
min: number;
max: number;
min: RangeProps["min"];
max: RangeProps["min"];
values: number[];
onChange: (values: number[]) => void;
step?: RangeProps["step"];
center?: number[];
mode?: "top" | "bottom" | "both";
overlayContent?: ReactNode;
};

const ZoomRange: FC<ZoomRangeProps> = (props) => {
const { data: capabilities } = useCapabilities();

const { min, max, values, center = olDefaults.center, onChange } = props;
const { min, max, values, center = olDefaults.center, onChange, step, mode = "both", overlayContent } = props;

// References sur les deux cartes
const leftMapRef = useRef<Map>();
Expand Down Expand Up @@ -109,15 +116,140 @@ const ZoomRange: FC<ZoomRangeProps> = (props) => {
rightMapRef.current?.updateSize();
}, [values]);

const handleChange = useCallback(
(newValue: number, zoomType?: "top" | "bottom") => {
switch (zoomType) {
case "top":
onChange([newValue, values[1]]);
break;
case "bottom":
onChange([values[0], newValue]);
break;
default:
onChange([newValue]);
break;
}
},
[onChange, values]
);

const { classes } = useStyles();

return (
<div className={fr.cx("fr-my-2v")}>
<div className="ui-map-zoom-levels">
<div ref={leftMapTargetRef} className="ui-top-zoom-level" />
<div ref={rightMapTargetRef} className="ui-bottom-zoom-level" />
<div className={fr.cx("fr-grid-row")}>
{(mode === "both" || mode === "top") && (
<div className={fr.cx("fr-col", "fr-px-2v")}>
<div ref={leftMapTargetRef} className={cx(classes.map)} />
</div>
)}

{mode !== "both" && (
<div className={cx(fr.cx("fr-col", "fr-px-2v"))}>
<div className={cx(classes.falseMapRoot)}>
<img
src={mode === "top" ? imgMapZoomBottom : imgMapZoomTop}
className={cx(classes.map, classes.falseMapImg)}
alt="Illustration d'une carte fixe"
/>
<div className={cx(classes.falseMapOverlay)}>
{overlayContent && <div className={cx(fr.cx("fr-m-4v", "fr-p-2v"), classes.falseMapOverlayContent)}>{overlayContent}</div>}
</div>
</div>
</div>
)}

{(mode === "both" || mode === "bottom") && (
<div className={fr.cx("fr-col", "fr-px-2v")}>
<div ref={rightMapTargetRef} className={cx(classes.map)} />
</div>
)}
</div>
<RangeSlider min={min} max={max} values={values} onChange={(newValues) => onChange(newValues)} />
<Range
label=" "
min={min}
max={max}
small={true}
step={step}
{...(() => {
switch (mode) {
case "top":
return {
nativeInputProps: {
value: values?.[0] ?? min,
onChange: (e) => {
handleChange(e.currentTarget.valueAsNumber);
},
},
};
case "bottom":
return {
nativeInputProps: {
value: values?.[0] ?? max,
onChange: (e) => {
handleChange(e.currentTarget.valueAsNumber);
},
},
};
case "both":
return {
double: true,
nativeInputProps: [
{
value: values?.[0] ?? min,
onChange: (e) => {
handleChange(e.currentTarget.valueAsNumber, "top");
},
},
{
value: values?.[1] ?? max,
onChange: (e) => {
handleChange(e.currentTarget.valueAsNumber, "bottom");
},
},
],
};
}
})()}
/>
</div>
);
};

ZoomRange.displayName = symToStr({ ZoomRange });

export default memo(ZoomRange);

const useStyles = tss.withName(ZoomRange.displayName).create(() => ({
map: {
height: "300px",
width: "100%",
},
falseMapRoot: {
position: "relative",
display: "inline-block",
width: "100%",
height: "300px",
},
falseMapImg: {
display: "block",
width: "100%",
height: "300px",
},
falseMapOverlay: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.6)",
textAlign: "center",
},
falseMapOverlayContent: {
backgroundColor: fr.colors.decisions.background.default.grey.default,
color: fr.colors.decisions.text.default.grey.default,
},
}));
7 changes: 5 additions & 2 deletions assets/data/ol-defaults.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{
"default_background_layer": "GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2",
"center": [2.35, 48.85],
"center": [
2.35,
48.85
],
"projection": "EPSG:3857",
"zoom": 10,
"zoom_levels": {
"TOP": 0,
"TOP": 1,
"BOTTOM": 18
}
}
6 changes: 4 additions & 2 deletions assets/entrepot/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import community from "./community";
import user from "./user";
import wfs from "./wfs";
import wmsVector from "./wms-vector";
import pyramid from "./pyramid";
import pyramidVector from "./pyramidVector";
import pyramidRaster from "./pyramidRaster";
import service from "./service";
import epsg from "./epsg";
import annexe from "./annexe";
Expand All @@ -31,7 +32,8 @@ const api = {
user,
wfs,
wmsVector,
pyramid,
pyramidVector,
pyramidRaster,
service,
annexe,
style,
Expand Down
Loading

0 comments on commit 3a6adaf

Please sign in to comment.