UNPKG

rlayers

Version:

React Components for OpenLayers

1 lines 5.3 kB
"use strict";(self.webpackChunkrlayers=self.webpackChunkrlayers||[]).push([[6715],{6715:(e,n,t)=>{t.r(n),t.d(n,{default:()=>s});const s="import React, {JSX} from 'react';\nimport {fromLonLat, transform} from 'ol/proj';\nimport {LineString, Point} from 'ol/geom';\nimport {Polyline} from 'ol/format';\nimport 'ol/ol.css';\n\nimport {RMap, ROSM, RLayerVector, RFeature} from 'rlayers';\nimport {RStyle, RCircle, RFill, RStroke} from 'rlayers/style';\n\n// This example uses the free Nominatim service of OpenStreetMap which is subject to very strict usage rules\n// https://operations.osmfoundation.org/policies/nominatim/\n// The address request rate is limited to 1 request per second and they immediately ban you if you exceed this limit\n// There are paid alternatives to this service\nfunction fillAddress(point: Point): Promise<string> {\n if (point === null) return Promise.resolve('');\n const coordsWGS = transform(point.getCoordinates(), 'EPSG:3857', 'EPSG:4326');\n const URL = `https://nominatim.openstreetmap.org/reverse?format=json&lon=${coordsWGS[0]}&lat=${coordsWGS[1]}`;\n return fetch(URL)\n .then((r) => r.json())\n .then((data) => data.display_name)\n .catch((e) => e.message);\n}\n\nconst polyReader = new Polyline();\nfunction parseRoute(routes): LineString {\n if (routes && routes.length > 0) {\n const f = polyReader.readFeature(routes[0].geometry);\n f.getGeometry().transform('EPSG:4326', 'EPSG:3857');\n return f.getGeometry() as LineString;\n }\n return null;\n}\n\nfunction buildRoute(start: Point, finish: Point): Promise<LineString> {\n if (start === null || finish === null) return Promise.resolve(null);\n const startCoords = transform(start.getCoordinates(), 'EPSG:3857', 'EPSG:4326');\n const finishCoords = transform(finish.getCoordinates(), 'EPSG:3857', 'EPSG:4326');\n\n const URL =\n 'https://router.project-osrm.org/route/v1/driving/' +\n `${startCoords[0]},${startCoords[1]};${finishCoords[0]},${finishCoords[1]}`;\n return fetch(URL)\n .then((r) => r.json())\n .then((data) => parseRoute(data.routes));\n}\n\nexport default function Routing(): JSX.Element {\n const [start, setStart] = React.useState(null as Point);\n const [finish, setFinish] = React.useState(null as Point);\n enum Step {\n START = 0,\n FINISH = 1\n }\n const [step, setStep] = React.useState(Step.START);\n const [startAddress, setStartAddress] = React.useState('');\n const [finishAddress, setFinishAddress] = React.useState('');\n const [route, setRoute] = React.useState(null as LineString);\n\n // On start change\n React.useEffect(() => {\n fillAddress(start).then((address) => setStartAddress(address));\n }, [start]);\n\n // On finish change\n React.useEffect(() => {\n fillAddress(finish).then((address) => setFinishAddress(address));\n }, [finish]);\n\n // When either one changes\n React.useEffect(() => {\n buildRoute(start, finish).then((line) => setRoute(line));\n }, [start, finish]);\n\n return (\n <React.Fragment>\n <RMap\n className='example-map'\n initial={{center: fromLonLat([2.364, 48.82]), zoom: 11}}\n onClick={(e) => {\n const coords = e.map.getCoordinateFromPixel(e.pixel);\n if (step === Step.START) {\n setFinish(null);\n setStart(new Point(coords));\n setStep(Step.FINISH);\n } else {\n setFinish(new Point(coords));\n setStep(Step.START);\n }\n }}\n >\n <ROSM />\n <RLayerVector>\n <RStyle>\n <RCircle radius={6}>\n <RFill color='blue' />\n </RCircle>\n </RStyle>\n <RFeature key={0} geometry={start} />\n <RFeature key={1} geometry={finish} />\n <RFeature key={2} geometry={route}>\n <RStyle>\n <RStroke width={3} color='darkgreen' />\n </RStyle>\n </RFeature>\n </RLayerVector>\n </RMap>\n <div className='mx-0 mt-0 mb-3 p-1 w-100 jumbotron shadow shadow'>\n <p>\n <strong>Select {step === Step.START ? 'START' : 'FINISH'} point</strong>\n </p>\n <div className='d-flex mt-2 justify-content-between'>\n {startAddress.length == 0 ? null : (\n <div>\n <strong>From: </strong>\n <em>{startAddress}</em>\n </div>\n )}\n {finishAddress.length == 0 ? null : (\n <div>\n <strong>To: </strong>\n <em>{finishAddress}</em>\n </div>\n )}\n </div>\n </div>\n </React.Fragment>\n );\n}\n"}}]);