Skip to content

Commit

Permalink
add a routing example
Browse files Browse the repository at this point in the history
Refs: #16
  • Loading branch information
mmomtchev committed Nov 25, 2021
1 parent 2437762 commit d357beb
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const examples = {
geolocation: {title: 'Geolocation', file: 'Geolocation'},
vectortiles: {title: 'Vector tiles', file: 'VectorTiles'},
reproj: {title: 'Reprojection', file: 'Reprojection'},
routing: {title: 'Routing', file: 'Routing'},
igc: {title: 'Performance', file: 'IGC'}
};

Expand Down
7 changes: 7 additions & 0 deletions examples/IGC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ export default function IGCComp(): JSX.Element {
url='https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png'
attributions='Kartendaten: © OpenStreetMap-Mitwirkende, SRTM | Kartendarstellung: © OpenTopoMap (CC-BY-SA)'
/>
{
// This layer contains the flight paths, we install an `onAddFeature` handler
// to receive all features as their loaded to do additional processing
}
<RLayerVector
zIndex={10}
ref={igcVectorLayer}
Expand Down Expand Up @@ -185,6 +189,9 @@ export default function IGCComp(): JSX.Element {
[igcs, styles.flightPath, styles.flightPath.current[0]]
)}
</RLayerVector>
{
// This layer contains the blue circle (the highlighted section)
}
<RLayerVector zIndex={10} ref={highlightVectorLayer} style={styles.blueCircle}>
{React.useMemo(
() => (
Expand Down
113 changes: 113 additions & 0 deletions examples/Routing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from 'react';
import {fromLonLat, transform} from 'ol/proj';
import {LineString, Point} from 'ol/geom';
import {Feature} from 'ol';
import {Polyline as PolylineFormat} from 'ol/format';
import 'ol/ol.css';

import {RMap, ROSM, RLayerVector, RFeature} from 'rlayers';
import {RStyle, RCircle, RFill, RStroke} from 'rlayers/style';

function fillAddress(coords) {
const coordsWGS = transform(coords, 'EPSG:3857', 'EPSG:4326');
const URL = `http://nominatim.openstreetmap.org/reverse?format=json&lon=${coordsWGS[0]}&lat=${coordsWGS[1]}`;
return fetch(URL)
.then((r) => r.json())
.then((data) => data.display_name);
}

const polyReader = new PolylineFormat();
function parseRoute(routes): LineString {
if (routes.length > 0) {
const f = polyReader.readFeature(routes[0].geometry);
f.getGeometry().transform('EPSG:4326', 'EPSG:3857');
return f.getGeometry();
}
return null;
}

function buildRoute(start: Feature<Point>, finish: Feature<Point>): Promise<LineString> {
const startCoords = transform(start.getGeometry().getCoordinates(), 'EPSG:3857', 'EPSG:4326');
const finishCoords = transform(finish.getGeometry().getCoordinates(), 'EPSG:3857', 'EPSG:4326');

const URL =
'https://router.project-osrm.org/route/v1/driving/' +
`${startCoords[0]},${startCoords[1]};${finishCoords[0]},${finishCoords[1]}`;
return fetch(URL)
.then((r) => r.json())
.then((data) => parseRoute(data.routes));
}

export default function Routing(): JSX.Element {
const [start] = React.useState(new Feature<Point>());
const [finish] = React.useState(new Feature<Point>());
enum Step {
START,
FINISH
}
const [step, setStep] = React.useState(Step.START);
const [startAddress, setStartAddress] = React.useState('');
const [finishAddress, setFinishAddress] = React.useState('');
const [route] = React.useState(new Feature<LineString>());

return (
<React.Fragment>
<RMap
className='example-map'
initial={{center: fromLonLat([2.364, 48.82]), zoom: 11}}
onClick={(e) => {
const coords = e.map.getCoordinateFromPixel(e.pixel);
if (step === Step.START) {
start.setGeometry(new Point(coords));
setStep(Step.FINISH);
fillAddress(coords).then((address) => setStartAddress(address));
route.setGeometry(null);
setFinishAddress('');
finish.setGeometry(null);
} else {
finish.setGeometry(new Point(coords));
setStep(Step.START);
fillAddress(coords).then((address) => setFinishAddress(address));
buildRoute(start, finish).then((line) => route.setGeometry(line));
}
}}
>
<ROSM />
<RLayerVector>
<RStyle>
<RCircle radius={6}>
<RFill color='blue' />
</RCircle>
</RStyle>
<RFeature key={0} feature={start} />
<RFeature key={1} feature={finish} />
</RLayerVector>
<RLayerVector>
<RStyle>
<RStroke width={2} color='green' />
</RStyle>
<RFeature feature={route} />
</RLayerVector>
</RMap>
<div className='mx-0 mt-0 mb-3 p-1 w-100 jumbotron shadow shadow'>
<p>
<strong>Select {step === Step.START ? 'START' : 'FINISH'} point</strong>
</p>
<div className={'d-flex mt-2'}>
{startAddress.length == 0 ? null : (
<div>
<strong>From: </strong>
<em>{startAddress}</em>
</div>
)}
{finishAddress.length == 0 ? null : (
<div>
<strong>To: </strong>
<em>{finishAddress}</em>
</div>
)}
</div>
</div>
</React.Fragment>
);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build:css": "copyfiles -f src/control/layers.css dist/control",
"build:examples": "webpack --mode=production --env production",
"build:doc": "npx styleguidist build",
"dev": "webpack-cli serve --mode=development --env development --open --hot",
"dev": "webpack-cli serve --mode=development --env development --open",
"prod": "webpack-cli serve --mode=production --env production --open",
"doc:watch": "npx styleguidist server",
"doc:publish": "node publish-ghpages.js",
Expand Down

0 comments on commit d357beb

Please sign in to comment.