Skip to content
Snippets Groups Projects
Commit 23b85f44 authored by Reinder Kraaij's avatar Reinder Kraaij :eye:
Browse files

Added Geo Information

parent 024dc966
No related branches found
No related tags found
1 merge request!1223Resolve TMSS-2294 "Station info"
Showing
with 21242 additions and 20943 deletions
Source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"jspdf-autotable": "^3.7.0", "jspdf-autotable": "^3.7.0",
"katex": "^0.12.0", "katex": "^0.12.0",
"leaflet": "^1.9.4",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"match-sorter": "^4.2.1", "match-sorter": "^4.2.1",
"moment": "^2.29.4", "moment": "^2.29.4",
...@@ -51,6 +52,8 @@ ...@@ -51,6 +52,8 @@
"react-flatpickr": "^3.10.12", "react-flatpickr": "^3.10.12",
"react-frame-component": "^4.1.2", "react-frame-component": "^4.1.2",
"react-json-to-table": "^0.1.7", "react-json-to-table": "^0.1.7",
"react-leaflet": "^4.2.1",
"react-leaflet-cluster": "^2.1.0",
"react-live-clock": "^6.1.14", "react-live-clock": "^6.1.14",
"react-loader-spinner": "^5.4.5", "react-loader-spinner": "^5.4.5",
"react-moment": "^1.1.3", "react-moment": "^1.1.3",
......
...@@ -70,6 +70,7 @@ class App extends Component { ...@@ -70,6 +70,7 @@ class App extends Component {
{ label: 'Week View', icon: 'pi pi-fw pi-calendar-times', to: '/su/timelineview/week', section: 'su/timelineview/week', isBreadCrumbVisible: false ,isDateTimeVisible:true}, { label: 'Week View', icon: 'pi pi-fw pi-calendar-times', to: '/su/timelineview/week', section: 'su/timelineview/week', isBreadCrumbVisible: false ,isDateTimeVisible:true},
{ label: 'Reports', icon: 'pi pi-fw pi-chart-bar', to: '/reports', section: 'reports', isBreadCrumbVisible: false ,isDateTimeVisible:false}, { label: 'Reports', icon: 'pi pi-fw pi-chart-bar', to: '/reports', section: 'reports', isBreadCrumbVisible: false ,isDateTimeVisible:false},
{ label: 'System Events', icon: 'pi pi-fw pi-bolt', to: '/systemevent/list', section: 'system', isBreadCrumbVisible: false ,isDateTimeVisible:true}, { label: 'System Events', icon: 'pi pi-fw pi-bolt', to: '/systemevent/list', section: 'system', isBreadCrumbVisible: false ,isDateTimeVisible:true},
{ label: 'Stations View', icon: 'pi pi-fw pi-wifi', to: '/station/list', section: 'system', isBreadCrumbVisible: false ,isDateTimeVisible:true},
]; ];
} }
......
...@@ -25,4 +25,5 @@ ...@@ -25,4 +25,5 @@
@import "./customdialog"; @import "./customdialog";
@import "./_buttongroups"; @import "./_buttongroups";
@import "./_actionbar"; @import "./_actionbar";
@import "./station";
// @import "./splitpane"; // @import "./splitpane";
...@@ -36,7 +36,7 @@ $vh: 1vh; ...@@ -36,7 +36,7 @@ $vh: 1vh;
background-color: #f0f0f0; background-color: #f0f0f0;
} }
} }
.timeline-tools { .timeline-tools {
......
.TabStation{
}
.StationTable {
}
.StationListWrap{
display: flex;
}
.GeoMap {
height:calc(#{$vh * 100} - 11.5em);
}
.openlayers-map {
height:calc(#{$vh * 100} - 11.5em);
background-color:yellow;
}
.StationListbox {
height:calc(#{$vh * 100} - 11.5em);
max-height:calc(#{$vh * 100} - 11.5em);
max-width: 100px;;
.p-listbox-list-wrapper{
height:calc(#{$vh * 100} - 11.5em);
max-height:calc(#{$vh * 100} - 11.5em);
}
}
.StationImage{
margin:20px;
box-shadow: rgba(0,0,0,0.2) 0 2px 8px;
width: 100%;
display:table-cell;
vertical-align:middle;
text-align:center
}
.GeoBlock {
height:calc(#{$vh * 100} - 11.5em);
width:100%;
.full-screen-map{
width:100%;
height:100%
}
}
import 'leaflet/dist/leaflet.css'
import {MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
import L from 'leaflet'
import MarkerClusterGroup from "react-leaflet-cluster";
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
iconUrl: require('leaflet/dist/images/marker-icon.png'),
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
});
function StationGeoView(props) {
const {
stations,
} = props
return (
<div className="GeoBlock">
<MapContainer
className="full-screen-map"
center={[52.91512333474063, 6.869839092349391]}
zoom={6}
minZoom={3}
maxZoom={19}
maxBounds={[[-85.06, -180], [85.06, 180]]}
scrollWheelZoom={true}>
<TileLayer
url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{stations.map((station, index) => (
<Marker
key={station.properties['@id']}
position={[station.geometry.coordinates[1], station.geometry.coordinates[0]]}
>
<Popup>
{station.properties.name}
<br />
{station.properties['name:en']}
</Popup>
</Marker>
))}
</MapContainer>
</div>
);
}
export default StationGeoView;
import { TabView,TabPanel } from "primereact/tabview";
import PropTypes from 'prop-types';
import UtilService from "../../services/util.service";
import { ListBox } from 'primereact/listbox';
import {useEffect, useState} from "react";
import StationGeoView from './StationGeoView'
import PageHeader from '../../layout/components/PageHeader';
// see https://react-leaflet.js.org/docs/api-map/
export default function StationView(props) {
const {
title,
location
} = props
const [stations, setStations] = useState()
const [stationsGeo, setStationsGeo] = useState([])
async function fetchStations() {
let stationlist = await UtilService.getStations();
let flatstationList = Object.entries(stationlist)
setStations(flatstationList);
let geostations = MakeGeoJson(stationlist);
setStationsGeo(geostations);
}
function generateGeoJson(station, coordinates) {
let name = station;
let longitude = coordinates.longitude;
let latitude = coordinates.latitude;
return {
type: "Feature",
properties: {
name: name
},
"geometry": {
"type": "Point",
"coordinates": [
longitude,
latitude
]
},
id: name
}
}
function MakeGeoJson(stations) {
let StationgeojsonArray = []
for (var station in stations){
const geostationJson = generateGeoJson(station,stations[station]);
StationgeojsonArray.push(geostationJson);
}
return StationgeojsonArray;
}
useEffect ( () => {
fetchStations();
}, []);
return <>
<PageHeader location={location} title={'Stations - List '}
/>
<TabView>
<TabPanel header="Station List" className="TabStation">
<div className="StationListWrap" >
<ListBox options={stations} optionLabel="0" className="StationListbox"/>
<StationGeoView stations={stationsGeo}></StationGeoView >
</div>
</TabPanel>
<TabPanel header="Geo Plot">
<div className="GeoMap">
<StationGeoView stations={stationsGeo}></StationGeoView >
</div>
</TabPanel>
</TabView>
</>
}
StationView.propTypes = {
title: PropTypes.string,
};
\ No newline at end of file
const icon = L.icon({
iconSize: [25, 41],
iconAnchor: [10, 41],
popupAnchor: [2, -40],
iconUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-icon.png",
shadowUrl: "https://unpkg.com/leaflet@1.7/dist/images/marker-shadow.png"
});
export default icon;
\ No newline at end of file
...@@ -13,6 +13,8 @@ import ViewSchedulingUnit from './Scheduling/ViewSchedulingUnit' ...@@ -13,6 +13,8 @@ import ViewSchedulingUnit from './Scheduling/ViewSchedulingUnit'
import SchedulingUnitCreate from './Scheduling/create'; import SchedulingUnitCreate from './Scheduling/create';
import UserOverView from './User/UserOverView'; import UserOverView from './User/UserOverView';
import EditSchedulingUnit from './Scheduling/edit'; import EditSchedulingUnit from './Scheduling/edit';
import StationView from './Station/StationView'
import StationGeoView from './Station/StationGeoView'
import { CycleList, CycleCreate, CycleView, CycleEdit } from './Cycle'; import { CycleList, CycleCreate, CycleView, CycleEdit } from './Cycle';
import { ReservationCreate, ReservationList, ReservationView, ReservationEdit } from './Reservation'; import { ReservationCreate, ReservationList, ReservationView, ReservationEdit } from './Reservation';
import { SystemEventCreate, SystemEventList, SystemEventView, SystemEventEdit } from './SystemEvent'; import { SystemEventCreate, SystemEventList, SystemEventView, SystemEventEdit } from './SystemEvent';
...@@ -265,6 +267,20 @@ export const routes = [ ...@@ -265,6 +267,20 @@ export const routes = [
title: 'System Event - Edit', title: 'System Event - Edit',
permissions: ['systemevent', 'edit'] permissions: ['systemevent', 'edit']
}, },
{
path: "/station/list",
component: StationView,
name: 'Station List',
title: 'Station List',
permissions: ['systemevent', 'list']
},
{
path: "/station/geo",
component: StationGeoView,
name: 'Station Geo',
title: 'Station Geo',
permissions: ['systemevent', 'list']
},
{ {
component: NotFound, component: NotFound,
name: 'Page Not Found - 404', name: 'Page Not Found - 404',
......
...@@ -91,6 +91,15 @@ const UtilService = { ...@@ -91,6 +91,15 @@ const UtilService = {
console.error(error); console.error(error);
} }
}, },
/** Gets all reservations in the system */
getStations: async () => {
try {
const stations = (await axios.get("/api/util/stations")).data;
return stations;
} catch (error) {
console.error(error);
}
},
/** Gets reservation templates in the system */ /** Gets reservation templates in the system */
getReservationTemplates: async () => { getReservationTemplates: async () => {
try { try {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment