Skip to content

Commit

Permalink
wip implement minimum search between coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
testower committed Sep 13, 2023
1 parent e791dc1 commit 933c738
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 36 deletions.
4 changes: 2 additions & 2 deletions client-next/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> asset lives in public/ -->
<link rel="icon" type="image/svg+xml" href="/img/otp-logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OTP debug client (next)</title>
<title>OTP Debug Client</title>
</head>
<body>
<div id="root"></div>
Expand Down
6 changes: 6 additions & 0 deletions client-next/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions client-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
"check-format": "prettier --check \"*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"format": "prettier --write \"*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"check-format": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"preview": "vite preview",
"prebuild": "npm run codegen && npm run lint && npm run check-format",
"predev": "npm run codegen",
"codegen": "graphql-codegen --config codegen.ts"
},
"dependencies": {
"@googlemaps/polyline-codec": "^1.0.28",
"bootstrap": "^5.3.1",
"graphql": "^16.8.0",
"graphql-request": "^6.1.0",
Expand Down
13 changes: 13 additions & 0 deletions client-next/public/img/otp-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions client-next/src/components/DetailsViewContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

export function DetailsViewContainer() {
return (
<section style={{
height: '4rem'
}}>
<section
style={{
height: '4rem',
}}
>
DetailViewContainer
</section>
);
Expand Down
22 changes: 16 additions & 6 deletions client-next/src/components/ItineraryListContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { TripQuery } from '../gql/graphql.ts';
import { Card } from 'react-bootstrap';

export function ItineraryListContainer() {
export function ItineraryListContainer({ tripQueryResult }: { tripQueryResult: TripQuery | null }) {
return (
<section style={{
width: '12rem',
height: "auto"
}}>
ItineraryListContainer
<section
style={{
width: '36rem',
height: 'auto',
}}
>
<h2>Itineraries</h2>
{tripQueryResult &&
tripQueryResult.trip.tripPatterns.map((tripPattern) => (
<Card key={tripPattern.legs.map((leg) => leg.id).join('_')}>
<pre>{JSON.stringify(tripPattern, null, 2)}</pre>
</Card>
))}
</section>
);
}
104 changes: 101 additions & 3 deletions client-next/src/components/MapView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {Map, NavigationControl} from 'react-map-gl';
import { Layer, Map, Marker, NavigationControl, Source } from 'react-map-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { TripQuery, TripQueryVariables } from '../gql/graphql.ts';
import { decode } from '@googlemaps/polyline-codec';

const mapStyle = {
version: 8,
Expand Down Expand Up @@ -27,8 +29,15 @@ const initialViewState = {
longitude: 10.2332855,
zoom: 4,
};
export function MapView() {

export function MapView({
tripQueryVariables,
setTripQueryVariables,
tripQueryResult,
}: {
tripQueryVariables?: TripQueryVariables;
setTripQueryVariables: (variables: TripQueryVariables) => void;
tripQueryResult: TripQuery | null;
}) {
return (
<Map
// @ts-ignore
Expand All @@ -37,8 +46,97 @@ export function MapView() {
mapStyle={mapStyle}
initialViewState={initialViewState}
style={{ width: '100%', height: 'calc(100vh - 184px)' }}
onDblClick={(e) => {
e.preventDefault();
if (!tripQueryVariables?.from.coordinates) {
setTripQueryVariables({
...tripQueryVariables,
from: {
coordinates: {
latitude: e.lngLat.lat,
longitude: e.lngLat.lng,
},
},
to: {
coordinates: {
latitude: 0.0,
longitude: 0.0,
},
},
});
} else {
setTripQueryVariables({
...tripQueryVariables,
to: {
coordinates: {
latitude: e.lngLat.lat,
longitude: e.lngLat.lng,
},
},
});
}
}}
>
<NavigationControl position="top-left" />
{tripQueryVariables?.from.coordinates && (
<Marker
draggable
latitude={tripQueryVariables.from.coordinates?.latitude}
longitude={tripQueryVariables.from.coordinates?.longitude}
onDragEnd={(e) => {
setTripQueryVariables({
...tripQueryVariables,
from: { coordinates: { latitude: e.lngLat.lat, longitude: e.lngLat.lng } },
});
}}
/>
)}
{tripQueryVariables?.to.coordinates && (
<Marker
draggable
latitude={tripQueryVariables.to.coordinates?.latitude}
longitude={tripQueryVariables.to.coordinates?.longitude}
onDragEnd={(e) => {
setTripQueryVariables({
...tripQueryVariables,
to: { coordinates: { latitude: e.lngLat.lat, longitude: e.lngLat.lng } },
});
}}
/>
)}
{tripQueryResult &&
tripQueryResult.trip.tripPatterns[0].legs.map(
(leg) =>
leg.pointsOnLink && (
<Source
key={leg.id}
//id="polylineLayer"
type="geojson"
data={{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: decode(leg.pointsOnLink.points as string, 5).map((value) => value.reverse()),
},
}}
>
<Layer
//id="lineLayer"
type="line"
//source="my-data"
layout={{
'line-join': 'round',
'line-cap': 'round',
}}
paint={{
'line-color': 'rgba(3, 170, 238, 1)',
'line-width': 5,
}}
/>
</Source>
),
)}
</Map>
);
}
7 changes: 5 additions & 2 deletions client-next/src/components/NavBarContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import Container from 'react-bootstrap/Container';
import Navbar from 'react-bootstrap/Navbar';
export function NavBarContainer() {
return (
<Navbar expand="lg" className="bg-body-tertiary">
<Navbar expand="lg" data-bs-theme="light">
<Container>
<Navbar.Brand>OTP debug client (next)</Navbar.Brand>
<Navbar.Brand>
<img alt="" src="/img/otp-logo.svg" width="30" height="30" className="d-inline-block align-top" /> OTP Debug
Client
</Navbar.Brand>
</Container>
</Navbar>
);
Expand Down
66 changes: 58 additions & 8 deletions client-next/src/components/SearchBarContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
import { Button, Form, Stack } from 'react-bootstrap';
import { TripQueryVariables } from '../gql/graphql.ts';

export function SearchBarContainer() {
return (
<section style={{
height: '4rem'
}}>
SearchBarContainer
</section>
);
const COORDINATE_PRECISION = 7;

export function SearchBarContainer({
onRoute,
tripQueryVariables,
}: {
onRoute: () => void;
tripQueryVariables?: TripQueryVariables;
}) {
return (
<section
style={{
height: '5rem',
paddingLeft: '1rem',
}}
>
<Stack direction="horizontal" gap={2}>
<Form.Group>
<Form.Label htmlFor="fromInputField">From</Form.Label>
<Form.Control
type="text"
id="fromInputField"
size="sm"
placeholder="[Click in map]"
value={
tripQueryVariables?.from
? `${tripQueryVariables?.from.coordinates?.latitude.toPrecision(
COORDINATE_PRECISION,
)} ${tripQueryVariables?.from.coordinates?.longitude.toPrecision(COORDINATE_PRECISION)}`
: undefined
}
/>
</Form.Group>
<Form.Group>
<Form.Label htmlFor="toInputField">To</Form.Label>
<Form.Control
type="text"
id="toInputField"
size="sm"
placeholder="[Click in map]"
value={
tripQueryVariables?.to
? `${tripQueryVariables?.to.coordinates?.latitude.toPrecision(
COORDINATE_PRECISION,
)} ${tripQueryVariables?.to.coordinates?.longitude.toPrecision(COORDINATE_PRECISION)}`
: undefined
}
/>
</Form.Group>

<Button variant="primary" onClick={onRoute}>
Route
</Button>
</Stack>
</section>
);
}
18 changes: 15 additions & 3 deletions client-next/src/hooks/useTripQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ const endpoint = `https://api.entur.io/journey-planner/v3/graphql`;
TODO: should live in a separate file, and split into fragments for readability
*/
const query = graphql(`
query trip {
trip(from: { place: "NSR:StopPlace:337" }, to: { place: "NSR:StopPlace:1" }) {
query trip($from: Location!, $to: Location!) {
trip(from: $from, to: $to, numTripPatterns: 1) {
tripPatterns {
aimedStartTime
aimedEndTime
duration
distance
legs {
id
pointsOnLink {
points
}
}
}
}
Expand All @@ -24,7 +31,12 @@ const query = graphql(`

type TripQueryHook = (variables?: TripQueryVariables) => [TripQuery | null, () => Promise<void>];

export const useTripQuery: TripQueryHook = (variables = {}) => {
export const useTripQuery: TripQueryHook = (
variables = {
from: { place: 'NSR:StopPlace:337' },
to: { place: 'NSR:StopPlace:1' },
},
) => {
const [data, setData] = useState<TripQuery | null>(null);
const callback = useCallback(async () => setData(await request(endpoint, query, variables)), [setData, variables]);
return [data, callback];
Expand Down
1 change: 1 addition & 0 deletions client-next/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import 'bootstrap/dist/css/bootstrap.min.css';
import { App } from './screens/App.tsx';
import './style.css';

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
Expand Down
22 changes: 16 additions & 6 deletions client-next/src/screens/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import {Stack} from "react-bootstrap";
import { Stack } from 'react-bootstrap';
import { MapView } from '../components/MapView.tsx';
import { NavBarContainer } from '../components/NavBarContainer.tsx';
import { SearchBarContainer } from '../components/SearchBarContainer.tsx';
import {ItineraryListContainer} from "../components/ItineraryListContainer.tsx";
import {DetailsViewContainer} from "../components/DetailsViewContainer.tsx";
import { ItineraryListContainer } from '../components/ItineraryListContainer.tsx';
import { DetailsViewContainer } from '../components/DetailsViewContainer.tsx';
import { useState } from 'react';
import { TripQueryVariables } from '../gql/graphql.ts';
import { useTripQuery } from '../hooks/useTripQuery.ts';

export function App() {
const [tripQueryVariables, setTripQueryVariables] = useState<TripQueryVariables | undefined>();
const [tripQueryResult, callback] = useTripQuery(tripQueryVariables);

return (
<div className="app">
<NavBarContainer />
<SearchBarContainer />
<SearchBarContainer onRoute={callback} tripQueryVariables={tripQueryVariables} />
<Stack direction="horizontal" gap={0}>
<ItineraryListContainer />
<MapView />
<ItineraryListContainer tripQueryResult={tripQueryResult} />
<MapView
tripQueryResult={tripQueryResult}
tripQueryVariables={tripQueryVariables}
setTripQueryVariables={setTripQueryVariables}
/>
</Stack>
<DetailsViewContainer />
</div>
Expand Down
Loading

0 comments on commit 933c738

Please sign in to comment.