Skip to content

Commit 20935dc

Browse files
committed
feat: add components
1 parent 543e447 commit 20935dc

File tree

5 files changed

+735
-5
lines changed

5 files changed

+735
-5
lines changed

frontend/app/gs-map/gs-map.tsx

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
- Copyright 2022 Sven Loesekann
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
import Map from 'ol/Map';
14+
import OSM from 'ol/source/OSM';
15+
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
16+
import VectorSource from 'ol/source/Vector';
17+
import Point from 'ol/geom/Point';
18+
import Feature from 'ol/Feature';
19+
import View from 'ol/View';
20+
import { MapBrowserEvent, Overlay } from 'ol';
21+
import { fromLonLat } from 'ol/proj';
22+
import myStyle from './gsmap.module.css';
23+
import { Icon, Style } from 'ol/style.js';
24+
import { useEffect } from 'react';
25+
import { nanoid } from 'nanoid';
26+
import { type CenterLocation } from '../model/location';
27+
import { type GsValue } from '../model/gs-point';
28+
29+
interface InputProps {
30+
center: CenterLocation;
31+
gsValues: GsValue[];
32+
}
33+
34+
export default function GsMap(inputProps: InputProps) {
35+
let map: Map;
36+
let currentOverlay: Overlay | null = null;
37+
useEffect(() => {
38+
if (!map) {
39+
// eslint-disable-next-line react-hooks/exhaustive-deps
40+
map = new Map({
41+
layers: [
42+
new TileLayer({
43+
source: new OSM(),
44+
})
45+
],
46+
target: 'map',
47+
view: new View({
48+
center: [0, 0],
49+
zoom: 1,
50+
}),
51+
});
52+
}
53+
const myOverlays = createOverlays();
54+
addClickListener(myOverlays);
55+
map.setView(new View({
56+
center: fromLonLat([inputProps.center.Longitude, inputProps.center.Latitude]),
57+
zoom: 12,
58+
}));
59+
}, []);
60+
61+
function createOverlays(): Overlay[] {
62+
return inputProps.gsValues.map((gsValue, index) => {
63+
const element = document.createElement('div');
64+
element.id = nanoid();
65+
element.innerHTML = `${gsValue.location}<br/>E5: ${gsValue.e5}<br/>E10: ${gsValue.e10}<br/>Diesel: ${gsValue.diesel}`;
66+
const overlay = new Overlay({
67+
element: element,
68+
offset: [-5, 0],
69+
positioning: 'bottom-center',
70+
className: 'ol-tooltip-measure ol-tooltip .ol-tooltip-static'
71+
});
72+
overlay.setPosition(fromLonLat([gsValue.longitude, gsValue.latitude]));
73+
const myStyle = element?.style;
74+
if (!!myStyle) {
75+
myStyle.display = 'block';
76+
}
77+
//map.addOverlay(overlay);
78+
addPins(gsValue, element, index);
79+
return overlay;
80+
});
81+
}
82+
83+
function addPins(gsValue: GsValue, element: HTMLDivElement, index: number) {
84+
const iconFeature = new Feature({
85+
geometry: new Point(fromLonLat([gsValue.longitude, gsValue.latitude])),
86+
ttId: element.id,
87+
ttIndex: index
88+
});
89+
90+
const iconStyle = new Style({
91+
image: new Icon({
92+
anchor: [20, 20],
93+
anchorXUnits: 'pixels',
94+
anchorYUnits: 'pixels',
95+
src: '/public/assets/map-pin.png',
96+
}),
97+
});
98+
iconFeature.setStyle(iconStyle);
99+
const vectorSource = new VectorSource({
100+
features: [iconFeature],
101+
});
102+
103+
const vectorLayer = new VectorLayer({
104+
source: vectorSource,
105+
});
106+
map.addLayer(vectorLayer);
107+
}
108+
109+
function addClickListener(myOverlays: Overlay[]) {
110+
map.on('click', (event: MapBrowserEvent<any>) => {
111+
const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => {
112+
return feature;
113+
});
114+
if (!!currentOverlay) {
115+
map.removeOverlay(currentOverlay);
116+
// eslint-disable-next-line react-hooks/exhaustive-deps
117+
currentOverlay = null;
118+
}
119+
//console.log(feature);
120+
//console.log(feature?.get('ttId') + ' ' + feature?.get('ttIndex'));
121+
if (!!feature?.get('ttIndex')) {
122+
//console.log(myOverlays[feature?.get('ttIndex')]);
123+
// eslint-disable-next-line react-hooks/exhaustive-deps
124+
currentOverlay = myOverlays[feature?.get('ttIndex')];
125+
map.addOverlay(currentOverlay as Overlay);
126+
}
127+
});
128+
}
129+
130+
return (<div className={myStyle.MyStyle}>
131+
<div id="map" className={myStyle.gsMap}></div>
132+
</div>);
133+
134+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
- Copyright 2022 Sven Loesekann
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
@import '../../node_modules/ol/ol.css';
14+
15+
.myStyle {
16+
color: #000;
17+
}
18+
19+
.gsMap {
20+
width: 100%;
21+
height: 500px;
22+
}
23+
24+
25+
.ol-tooltip {
26+
position: relative;
27+
background: #ffcc33;
28+
border-radius: 4px;
29+
color: black;
30+
padding: 4px 8px;
31+
opacity: 0.7;
32+
white-space: nowrap;
33+
font-size: 15px;
34+
}
35+
.ol-tooltip-measure {
36+
opacity: 1;
37+
font-weight: lighter;
38+
}
39+
40+
.ol-tooltip-static {
41+
background-color: #ffcc33;
42+
color: black;
43+
border: 1px solid white;
44+
}
45+
46+
.ol-tooltip-measure:before,
47+
.ol-tooltip-static:before {
48+
border-top: 6px solid #ffcc33;
49+
border-right: 6px solid transparent;
50+
border-left: 6px solid transparent;
51+
content: "";
52+
position: absolute;
53+
bottom: -6px;
54+
margin-left: -7px;
55+
left: 50%;
56+
}
57+
.ol-tooltip-static:before {
58+
border-top-color: #ffcc33;
59+
}
60+

frontend/app/main/main.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as React from 'react';
1414
import { Box, Tab, Tabs } from '@mui/material';
1515
import { useEffect, useState, type SyntheticEvent } from 'react';
1616
import DataTable, { type TableDataRow } from '../data-table/data-table';
17-
//import GsMap from './GsMap';
17+
import GsMap from '../gs-map/gs-map';
1818
import GlobalState from '../GlobalState';
1919
//import styles from './main.module.css';
2020
//import Chart from './Chart';
@@ -143,8 +143,8 @@ export default function Main() {
143143
<Chart timeSlots={avgTimeSlots}></Chart>}
144144
{value === 1 &&
145145
<DataTable diesel='Diesel' e10='E10' e5='E5' location='Location' showAverages={true} time='Time' rows={rows}></DataTable>}
146-
{value === 2 &&
147-
<GsMap gsValues={gsValues} center={globalUserDataState}></GsMap>}
148146
*/}
147+
{value === 2 &&
148+
<GsMap gsValues={gsValues} center={globalUserDataState}></GsMap>}
149149
</Box>);
150150
}

0 commit comments

Comments
 (0)