Skip to content

Commit

Permalink
Merge remote-tracking branch 'otp/dev-2.x' into cleanup_filters
Browse files Browse the repository at this point in the history
  • Loading branch information
t2gran committed Jan 19, 2024
2 parents 1198e26 + 323df42 commit 4e4af20
Show file tree
Hide file tree
Showing 104 changed files with 2,353 additions and 1,258 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
OpenTripPlanner (OTP) is an open source multi-modal trip planner, focusing on travel by scheduled
public transportation in combination with bicycling, walking, and mobility services including bike
share and ride hailing. Its server component runs on any platform with a Java virtual machine (
including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed by various
including Linux, Mac, and Windows). It exposes GraphQL APIs that can be accessed by various
clients including open source Javascript components and native mobile applications. It builds its
representation of the transportation network from open data in open standard file formats (primarily
GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate visibility to
Expand Down
56 changes: 28 additions & 28 deletions client-next/package-lock.json

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

2 changes: 1 addition & 1 deletion client-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"bootstrap": "5.3.1",
"graphql": "16.8.0",
"graphql-request": "6.1.0",
"maplibre-gl": "3.3.0",
"maplibre-gl": "3.6.2",
"react": "18.2.0",
"react-bootstrap": "2.8.0",
"react-dom": "18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion client-next/src/components/MapView/ContextMenuPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TripQueryVariables } from '../../gql/graphql.ts';
import { LngLat, Popup } from 'react-map-gl';
import { LngLat, Popup } from 'react-map-gl/maplibre';
import { Button, ButtonGroup } from 'react-bootstrap';

export function ContextMenuPopup({
Expand Down
10 changes: 8 additions & 2 deletions client-next/src/components/MapView/GeometryPropertyPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LngLat, Popup } from 'react-map-gl';
import { LngLat, Popup } from 'react-map-gl/maplibre';
import { Table } from 'react-bootstrap';

export function GeometryPropertyPopup({
Expand All @@ -11,7 +11,13 @@ export function GeometryPropertyPopup({
onClose: () => void;
}) {
return (
<Popup latitude={coordinates.lat} longitude={coordinates.lng} closeButton={true} onClose={() => onClose()}>
<Popup
latitude={coordinates.lat}
longitude={coordinates.lng}
closeButton={true}
onClose={() => onClose()}
maxWidth="350px"
>
<Table bordered>
<tbody>
{Object.entries(properties).map(([key, value]) => (
Expand Down
82 changes: 82 additions & 0 deletions client-next/src/components/MapView/LayerControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type { ControlPosition } from 'react-map-gl';
import { useControl } from 'react-map-gl';
import { IControl, Map } from 'maplibre-gl';

type LayerControlProps = {
position: ControlPosition;
};

/**
* A maplibre control that allows you to switch vector tile layers on and off.
*
* It appears that you cannot use React elements but have to drop down to raw DOM. Please correct
* me if I'm wrong.
*/
class LayerControl implements IControl {
private readonly container: HTMLDivElement = document.createElement('div');

onAdd(map: Map) {
this.container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select';

map.on('load', () => {
// clean on
while (this.container.firstChild) {
this.container.removeChild(this.container.firstChild);
}

const title = document.createElement('h6');
title.textContent = 'Debug layers';
this.container.appendChild(title);

map
.getLayersOrder()
.map((l) => map.getLayer(l))
.filter((s) => s?.type !== 'raster')
.reverse()
.forEach((layer) => {
if (layer) {
const div = document.createElement('div');
const input = document.createElement('input');
input.type = 'checkbox';
input.value = layer.id;
input.id = layer.id;
input.onchange = (e) => {
e.preventDefault();
e.stopPropagation();

if (this.layerVisible(map, layer)) {
map.setLayoutProperty(layer.id, 'visibility', 'none');
} else {
map.setLayoutProperty(layer.id, 'visibility', 'visible');
}
};
input.checked = this.layerVisible(map, layer);
const label = document.createElement('label');
label.textContent = layer.id;
label.htmlFor = layer.id;
div.appendChild(input);
div.appendChild(label);
this.container.appendChild(div);
}
});
});

return this.container;
}

private layerVisible(map: Map, layer: { id: string }) {
return map.getLayoutProperty(layer.id, 'visibility') !== 'none';
}

onRemove() {
this.container.parentNode?.removeChild(this.container);
}
}

export default function DebugLayerControl(props: LayerControlProps) {
useControl(() => new LayerControl(), {
position: props.position,
});

return null;
}
42 changes: 29 additions & 13 deletions client-next/src/components/MapView/MapView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl } from 'react-map-gl';
import {
LngLat,
Map,
MapEvent,
MapGeoJSONFeature,
MapMouseEvent,
NavigationControl,
VectorTileSource,
} from 'react-map-gl/maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';
import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts';
import { NavigationMarkers } from './NavigationMarkers.tsx';
Expand All @@ -7,17 +15,11 @@ import { useMapDoubleClick } from './useMapDoubleClick.ts';
import { useState } from 'react';
import { ContextMenuPopup } from './ContextMenuPopup.tsx';
import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx';

// TODO: this should be configurable
const initialViewState = {
latitude: 60.7554885,
longitude: 10.2332855,
zoom: 4,
};
import DebugLayerControl from './LayerControl.tsx';

const styleUrl = import.meta.env.VITE_DEBUG_STYLE_URL;

type PopupData = { coordinates: LngLat; feature: MapboxGeoJSONFeature };
type PopupData = { coordinates: LngLat; feature: MapGeoJSONFeature };

export function MapView({
tripQueryVariables,
Expand All @@ -36,8 +38,8 @@ export function MapView({
const [showContextPopup, setShowContextPopup] = useState<LngLat | null>(null);
const [showPropsPopup, setShowPropsPopup] = useState<PopupData | null>(null);
const showFeaturePropPopup = (
e: mapboxgl.MapMouseEvent & {
features?: mapboxgl.MapboxGeoJSONFeature[] | undefined;
e: MapMouseEvent & {
features?: MapGeoJSONFeature[] | undefined;
},
) => {
if (e.features) {
Expand All @@ -48,6 +50,17 @@ export function MapView({
setShowPropsPopup({ coordinates: e.lngLat, feature: feature });
}
};
const panToWorldEnvelopeIfRequired = (e: MapEvent) => {
const map = e.target;
// if we are really far zoomed out and show the entire world it means that we are not starting
// in a location selected from the URL hash.
// in such a case we pan to the area that is specified in the tile bounds, which is
// provided by the WorldEnvelopeService
if (map.getZoom() < 2) {
const source = map.getSource('stops') as VectorTileSource;
map.fitBounds(source.bounds, { maxDuration: 50, linear: true });
}
};

return (
<div className="map-container below-content">
Expand All @@ -56,25 +69,28 @@ export function MapView({
mapLib={import('maplibre-gl')}
// @ts-ignore
mapStyle={styleUrl}
initialViewState={initialViewState}
onDblClick={onMapDoubleClick}
onContextMenu={(e) => {
setShowContextPopup(e.lngLat);
}}
interactiveLayerIds={['regular-stop']}
// it's unfortunate that you have to list these layers here.
// maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343
interactiveLayerIds={['regular-stop', 'vertex', 'edge', 'link']}
onClick={showFeaturePropPopup}
// put lat/long in URL and pan to it on page reload
hash={true}
// disable pitching and rotating the map
touchPitch={false}
dragRotate={false}
onLoad={panToWorldEnvelopeIfRequired}
>
<NavigationControl position="top-left" />
<NavigationMarkers
tripQueryVariables={tripQueryVariables}
setTripQueryVariables={setTripQueryVariables}
loading={loading}
/>
<DebugLayerControl position="top-right" />
{tripQueryResult?.trip.tripPatterns.length && (
<LegLines tripPattern={tripQueryResult.trip.tripPatterns[selectedTripPatternIndex] as TripPattern} />
)}
Expand Down
2 changes: 1 addition & 1 deletion client-next/src/components/MapView/useMapDoubleClick.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { TripQueryVariables } from '../../gql/graphql.ts';
import { LngLat, MapLayerMouseEvent } from 'react-map-gl';
import { LngLat, MapLayerMouseEvent } from 'react-map-gl/maplibre';

const setCoordinates = (tripQueryVariables: TripQueryVariables, lngLat: LngLat, key: 'from' | 'to') => ({
...tripQueryVariables,
Expand Down
9 changes: 9 additions & 0 deletions client-next/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,12 @@
font-size: 14px;
padding-left: 2px;
}

/* debug layer selector */

.maplibregl-ctrl-group.layer-select {
padding: 10px;
}
.maplibregl-ctrl-group.layer-select label {
margin-left: 6px;
}
4 changes: 4 additions & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle
- Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605)
- Remove GTFS-RT websocket updater [#5604](https://github.com/opentripplanner/OpenTripPlanner/pull/5604)
- Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602)
- Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652)
- Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581)
- Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582)
- Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629)
[](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE)

## 2.4.0 (2023-09-13)
Expand Down
Loading

0 comments on commit 4e4af20

Please sign in to comment.