Commit 5dd3f335 authored by Fabien Amarger's avatar Fabien Amarger
Browse files

feat: [localisation] Render a map with the location information

parent 2a74fdcd5035
.leaflet-container {
height: 500px;
width: 100%;
}
......@@ -3,12 +3,18 @@ import * as ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import Badge from 'react-bootstrap/Badge';
import { Map, Marker, Popup, TileLayer } from 'react-leaflet';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { application, implementation, definition } from '@logilab/libview';
import * as $rdf from 'rdflib';
import './localisation.css';
const RDF = $rdf.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
const RDFS = $rdf.Namespace('http://www.w3.org/2000/01/rdf-schema#');
const CULT = $rdf.Namespace('http://graphe-culture.fr/');
const DESCRIPTOR_LOCALISATION: definition.ViewDescriptor = {
identifier: '::Culture::Localisation',
......@@ -27,13 +33,38 @@ const DESCRIPTOR_LOCALISATION: definition.ViewDescriptor = {
interface BienCulturelProps {
typeUris: string[];
label: string;
locationUri: string;
dataFetcher?: implementation.DataFetcher;
}
const BienCulturel: React.FC<BienCulturelProps> = ({ typeUris, label, dataFetcher }) => {
interface BienCulturelInfoProps {
types: string[];
label: string;
}
interface Location {
lat: number;
lng: number;
}
const BienCulturelInfo: React.FC<BienCulturelInfoProps> = ({ types, label }) => (
<>
<h1>{label}</h1>
<h5>
{types.map((typeLabel) => (
<Badge style={{ margin: '5px' }} key={typeLabel} variant="primary">
{typeLabel}
</Badge>
))}
</h5>
</>
);
const BienCulturel: React.FC<BienCulturelProps> = ({ typeUris, label, locationUri, dataFetcher }) => {
const [urisLabel, setUrisLabel] = React.useState<{ uri: string; label: string | null }[]>(
typeUris.map((typeUri) => ({ uri: typeUri, label: null }))
);
const [location, setLocation] = React.useState<Location | null>(null);
React.useEffect(() => {
if (dataFetcher !== undefined) {
Promise.all(
......@@ -54,16 +85,47 @@ const BienCulturel: React.FC<BienCulturelProps> = ({ typeUris, label, dataFetche
}
}, [dataFetcher, typeUris]);
React.useEffect(() => {
if (dataFetcher !== undefined) {
dataFetcher
.fetchDataFromURI(locationUri, {
lat: 'http://www.w3.org/2003/01/geo/wgs84_pos#latitude',
lng: 'http://www.w3.org/2003/01/geo/wgs84_pos#longitude',
})
.then(({ lat, lng }) =>
setLocation({
lat: Number(lat),
lng: Number(lng),
})
);
}
}, [locationUri, dataFetcher]);
const typesLabel = urisLabel.map((uriLabel) => uriLabel.label ?? uriLabel.uri);
let locationComponent = <></>;
if (location !== null) {
L.Icon.Default.imagePath = `${process.env.DOMAIN}/images/`;
const position = { lat: location.lat, lng: location.lng };
locationComponent = (
<Map zoom={13} center={position} style={{ height: '600px' }}>
<TileLayer
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
<BienCulturelInfo types={typesLabel} label={label} />
</Popup>
</Marker>
</Map>
);
}
return (
<>
<h1>{label}</h1>
<h5>
{urisLabel.map((uriLabel) => (
<Badge style={{ margin: '5px' }} key={uriLabel.uri} variant="primary">
{uriLabel.label ?? uriLabel.uri}
</Badge>
))}
</h5>
<BienCulturelInfo types={typesLabel} label={label} />
<div>{locationComponent}</div>
</>
);
};
......@@ -111,6 +173,7 @@ class LocalisationRendering implements implementation.ViewImplementation {
const bienCulturel: BienCulturelProps = {
typeUris: context.each(targetSym, RDF('type')).map((node) => node.value) as string[],
label: context.anyJS(targetSym, RDFS('label')),
locationUri: context.anyJS(targetSym, CULT('aPourLocalisation')).value,
dataFetcher,
};
......
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