frontend/src/component/GPS.tsx

117 lines
2.7 KiB
TypeScript

import { Theme } from "@mui/material"
import { withStyles, createStyles, WithTheme, WithStyles } from "@mui/styles";
import React from "react";
import { parseGPS } from "services/google/mapHelpers";
import { geolocate } from "services/google/googleAPI";
import Loader from "common/Loader";
import MapGL from "common/MapGL";
import { pond } from "protobuf-ts/pond";
const styles = (theme: Theme) =>
createStyles({
mapContainer: {
height: "375px",
width: "100%",
padding: theme.spacing(3),
paddingTop: theme.spacing(1),
[theme.breakpoints.up("sm")]: {
height: "475px"
}
}
});
interface Props extends WithStyles<typeof styles>, WithTheme {
data: pond.Measurement[];
}
interface State {
loading: boolean;
coordinates: any[];
}
class GPS extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
loading: false,
coordinates: []
};
}
componentDidMount = () => {
this.parseData();
};
componentDidUpdate = (prevProps: Props) => {
if (this.props.data !== prevProps.data) {
this.parseData();
}
};
parseData = () => {
const { data } = this.props;
this.setState({ loading: true, coordinates: [] });
if (data.length <= 0) {
return;
}
let promises = [];
let timestamps: string[] = [];
let coordinates: any[] = [];
for (let i = 0; i < data.length; i++) {
let e = data[i];
if (e.measurement) {
let ts = e.timestamp;
let gps = e.measurement.gps;
let { request, lat, lng } = parseGPS(gps);
if (request) {
promises.push(geolocate(request));
timestamps.push(ts);
} else if (lat !== 0 && lng !== 0) {
coordinates.push({
timestamp: ts,
latitude: lat,
longitude: lng
});
}
}
}
Promise.all(promises)
.then((responses: any[]) => {
responses.forEach((r, i) => {
coordinates.push({
timestamp: timestamps[i],
latitude: r.data.location.lat,
longitude: r.data.location.lng,
accuracy: r.data.accuracy
});
});
})
.catch((error: any) => {
console.log(error);
})
.finally(() => {
this.setState({ loading: false, coordinates: coordinates });
});
};
render() {
const { coordinates, loading } = this.state;
const { classes } = this.props;
if (loading) {
return <Loader />;
} else {
let paths = new Map().set("path", coordinates);
return (
<div className={classes.mapContainer}>
<MapGL paths={paths} />
</div>
);
}
}
}
export default withStyles(styles, { withTheme: true })(GPS);