From 97b57e0f33f50cd5e1f7dcfeb93d73f0c95614f6 Mon Sep 17 00:00:00 2001 From: Alexander Neer Date: Wed, 9 Feb 2022 06:35:26 +0000 Subject: [PATCH] Update src/app/app.component.ts, src/app/app.component.css, src/app/services/nominatim.service.ts, src/app/services/osrm.service.ts, src/app/services/photon.service.ts, src/app/search/search.component.css, src/app/search/search.component.ts, src/app/interfaces/nominatim.ts, src/app/interfaces/openLayersGeoJSON.ts, src/app/interfaces/osrm.ts, src/app/interfaces/photon.ts, src/app/map/map.component.css, src/app/map/map.component.ts, src/app/route-list/route-list.component.css, src/app/route-list/route-list.component.html, src/app/route-list/route-list.component.ts --- src/app/app.component.css | 4 +- src/app/app.component.ts | 9 +- src/app/interfaces/nominatim.ts | 4 +- src/app/interfaces/openLayersGeoJSON.ts | 10 +- src/app/interfaces/osrm.ts | 14 +-- src/app/interfaces/photon.ts | 50 +++++----- src/app/map/map.component.css | 2 +- src/app/map/map.component.ts | 22 +--- src/app/route-list/route-list.component.css | 35 ++++--- src/app/route-list/route-list.component.html | 4 +- src/app/route-list/route-list.component.ts | 14 ++- src/app/search/search.component.css | 100 +++++++++---------- src/app/search/search.component.ts | 64 ++++++------ src/app/services/nominatim.service.ts | 15 ++- src/app/services/osrm.service.ts | 11 +- src/app/services/photon.service.ts | 15 ++- 16 files changed, 188 insertions(+), 185 deletions(-) diff --git a/src/app/app.component.css b/src/app/app.component.css index a985608..5f31641 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -1,4 +1,4 @@ -header{ +header { background-color: rgb(37, 37, 37); height: 50px; font-size: 15pt; @@ -6,7 +6,7 @@ header{ font-weight: bold; } -header p{ +header p { margin-top: 12px; padding-right: 10px; display:block; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1d5362f..6209614 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,13 +7,12 @@ import { RouteListComponent } from './route-list/route-list.component'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css', '../../node_modules/ol/ol.css'] + styleUrls: [ './app.component.css', '../../node_modules/ol/ol.css' ] }) - - - export class AppComponent { + title = "Street Map"; + @ViewChild('mapRef') mapCompopnent!: MapComponent; @ViewChild('routeListRef') routeListCompopnent!: RouteListComponent; @@ -21,5 +20,5 @@ export class AppComponent { this.mapCompopnent.drawPath($event); this.routeListCompopnent.updateSidebar($event); } -} +} diff --git a/src/app/interfaces/nominatim.ts b/src/app/interfaces/nominatim.ts index 1f59ce9..57c2dc3 100644 --- a/src/app/interfaces/nominatim.ts +++ b/src/app/interfaces/nominatim.ts @@ -1,4 +1,6 @@ -// Nominatim JSON object to TypeScript interface +/** + * Nominatim JSON object to TypeScript interface + */ export interface Nominatim { boundingbox?: Array; category?: string; diff --git a/src/app/interfaces/openLayersGeoJSON.ts b/src/app/interfaces/openLayersGeoJSON.ts index b3d1dbf..f569bef 100644 --- a/src/app/interfaces/openLayersGeoJSON.ts +++ b/src/app/interfaces/openLayersGeoJSON.ts @@ -1,9 +1,9 @@ -interface OpenLayersGeometry{ +interface OpenLayersGeometry { coordinates: Array>; type?: string; } -interface OpenLayersProperties{ +interface OpenLayersProperties { ECO_NAME?: string; BIOME_NAME?: string; REALM?: string; @@ -14,16 +14,16 @@ interface OpenLayersProperties{ COLOR_NNH?: string; } -interface OpenLayersFeature{ +interface OpenLayersFeature { type: string; geometry: OpenLayersGeometry; id: number; properties: OpenLayersProperties; } -export interface OpenLayersGeoJSON{ +export interface OpenLayersGeoJSON { type: string; features: Array; geometry: OpenLayersGeometry; properties: OpenLayersProperties; -} \ No newline at end of file +} diff --git a/src/app/interfaces/osrm.ts b/src/app/interfaces/osrm.ts index 7fd8114..a684089 100644 --- a/src/app/interfaces/osrm.ts +++ b/src/app/interfaces/osrm.ts @@ -1,16 +1,16 @@ -interface OsrmWaypoint{ +interface OsrmWaypoint { hint?: string; distance?: number; location?: Array; name?: string; } -interface OsrmManeuver{ +interface OsrmManeuver { type?: string; modifier?: string; } -export interface OsrmStep{ +export interface OsrmStep { driving_side?: string; duration?: number; distance?: number; @@ -18,7 +18,7 @@ export interface OsrmStep{ maneuver?: OsrmManeuver; } -interface OsrmLeg{ +interface OsrmLeg { steps?: Array; weight?: number; distance?: number; @@ -26,7 +26,7 @@ summary?: string; duration?: number; } -interface OsrmGeometry{ +interface OsrmGeometry { type: GeometryType; coordinates?: Array>; } @@ -35,12 +35,12 @@ enum GeometryType { LINE_STRING = "LineString" } -interface OsrmRoute{ +interface OsrmRoute { legs: Array; geometry: OsrmGeometry; } -export interface Osrm{ +export interface Osrm { code?: string; waypoints?: Array; routes: Array; diff --git a/src/app/interfaces/photon.ts b/src/app/interfaces/photon.ts index 652c545..91d40d6 100644 --- a/src/app/interfaces/photon.ts +++ b/src/app/interfaces/photon.ts @@ -1,32 +1,32 @@ -interface PhotonGeometry{ - coordinates: Array; - type?: string; +interface PhotonGeometry { + coordinates: Array; + type?: string; } -interface PhotonProperties{ - osm_id?: number; - osm_type?: string; - extent?: Array; - country?: string; - osm_key?: "place"; - countrycode?: string; - osm_value?: string; - name?: string; - type?: string; - postcode?: string; - city?: string; - housenumber?: number; - street?: string; - state?: string; +interface PhotonProperties { + osm_id?: number; + osm_type?: string; + extent?: Array; + country?: string; + osm_key?: "place"; + countrycode?: string; + osm_value?: string; + name?: string; + type?: string; + postcode?: string; + city?: string; + housenumber?: number; + street?: string; + state?: string; } -export interface Photon{ - geometry?: PhotonGeometry; - type?: string; - properties: PhotonProperties; +export interface Photon { + properties: PhotonProperties; + geometry?: PhotonGeometry; + type?: string; } -export interface PhotonFeatureCollection{ - features?: Array; - type?: string; +export interface PhotonFeatureCollection { + features?: Array; + type?: string; } diff --git a/src/app/map/map.component.css b/src/app/map/map.component.css index a6c22ec..3d8c5ec 100644 --- a/src/app/map/map.component.css +++ b/src/app/map/map.component.css @@ -1,5 +1,5 @@ -#map{ +#map { width: 100%; height: 100%; } diff --git a/src/app/map/map.component.ts b/src/app/map/map.component.ts index 54cec78..e4eb45c 100644 --- a/src/app/map/map.component.ts +++ b/src/app/map/map.component.ts @@ -20,11 +20,8 @@ import Geometry from 'ol/geom/Geometry'; }) export class MapComponent implements AfterViewInit { - constructor() { } - map: Map; - ngAfterViewInit() { this.map = new Map({ target: 'map', @@ -53,24 +50,15 @@ export class MapComponent implements AfterViewInit { } drawPath(osrm: Osrm): void{ - console.log(osrm) //https://routing.openstreetmap.de/routed-bike/route/v1/driving/8.6042708,53.5151533;13.6887164,51.0491468?overview=false&alternatives=true&steps=true + // https://routing.openstreetmap.de/routed-bike/route/v1/driving/8.6042708,53.5151533;13.6887164,51.0491468?overview=false&alternatives=true&steps=true + console.log(osrm); const coordinates = osrm.routes[0].geometry.coordinates || []; - const f_coordinates: Array> = [] - coordinates.forEach(coordinate => - { - f_coordinates.push(transform(coordinate, 'EPSG:4326', 'EPSG:3857')) - } - ); - - const lineString: LineString = new LineString(f_coordinates); + const fCoordinates: number[][] = coordinates.map(coordinate => (transform(coordinate, 'EPSG:4326', 'EPSG:3857'))); + const lineString: LineString = new LineString(fCoordinates); const feature: Feature = new Feature({ geometry: lineString }); const vectorSource = new VectorSource({ features: [ feature ]}); - - const vectorLayer = new VectorLayer({ - - source: vectorSource, - }); + const vectorLayer = new VectorLayer({ source: vectorSource }); this.map.addLayer(vectorLayer); // this.features = new GeoJSON().readFeatures(new openLayersGeoJSON()) diff --git a/src/app/route-list/route-list.component.css b/src/app/route-list/route-list.component.css index bf45830..eacba19 100644 --- a/src/app/route-list/route-list.component.css +++ b/src/app/route-list/route-list.component.css @@ -1,4 +1,4 @@ -.osrm-route-container{ +.osrm-route-container { position: absolute; right: 0; width:300px; @@ -8,43 +8,42 @@ bottom: 0; color: white; overflow-y: scroll; - } +} - .osrm-route-container h4{ +.osrm-route-container h4 { text-align: center; line-height: 30px; letter-spacing: 1px; padding-top: 0px; margin-top: 2px; - } +} - .route-list{ +.route-list { width: 100%; display: block; font-weight: bold; text-align: left; - } +} - .route-list .route-list-item{ +.route-list .route-list-item { width: 100%; display: block; border-top: 1px solid rgba(255, 255, 255, 0.418); padding-top: 5px; padding-bottom: 5px; +} - } +.route-list .route-list-item div { + width: 100%; + /*background-image: url('/assets/images/turn-left.svg');*/ + background-repeat: no-repeat; + background-size: 35px 35px; + background-position:5px 10px; +} - .route-list .route-list-item div{ - width: 100%; - /*background-image: url('/assets/images/turn-left.svg');*/ - background-repeat: no-repeat; - background-size: 35px 35px; - background-position:5px 10px; - } - - .route-list .route-list-item div p{ +.route-list .route-list-item div p { display: inline-block; text-transform: capitalize; padding-left: 50px; - } +} diff --git a/src/app/route-list/route-list.component.html b/src/app/route-list/route-list.component.html index 0c98761..bcb94a7 100644 --- a/src/app/route-list/route-list.component.html +++ b/src/app/route-list/route-list.component.html @@ -5,12 +5,12 @@
-

{{step.maneuver?.type }} {{step.maneuver?.modifier }}
{{step.name }}

+

{{step.maneuver?.type}} {{step.maneuver?.modifier}}
{{step.name}}

-

{{step.maneuver?.type }} {{step.maneuver?.modifier }}
{{step.name }}

+

{{step.maneuver?.type}} {{step.maneuver?.modifier}}
{{step.name}}

diff --git a/src/app/route-list/route-list.component.ts b/src/app/route-list/route-list.component.ts index 537e288..952eb7e 100644 --- a/src/app/route-list/route-list.component.ts +++ b/src/app/route-list/route-list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; import { Osrm, OsrmStep } from '../interfaces/osrm'; @Component({ @@ -6,17 +6,15 @@ import { Osrm, OsrmStep } from '../interfaces/osrm'; templateUrl: './route-list.component.html', styleUrls: ['./route-list.component.css'] }) -export class RouteListComponent implements OnInit { - routeSteps: Array = [] - constructor() { } +export class RouteListComponent { - ngOnInit(): void { - } + routeSteps: Array = []; updateSidebar(osrm: Osrm): void{ - console.log("updateSidebar") - if(osrm.routes[0].legs[0].steps){ + console.log("updateSidebar"); + if (osrm.routes[0].legs[0].steps) { this.routeSteps = osrm.routes[0].legs[0].steps; } } + } diff --git a/src/app/search/search.component.css b/src/app/search/search.component.css index 33caa27..935dd3c 100644 --- a/src/app/search/search.component.css +++ b/src/app/search/search.component.css @@ -1,68 +1,68 @@ -.searchField{ - display:block; - float:left; - margin-top: 10px; +.searchField { + display:block; + float:left; + margin-top: 10px; } -.searchField input{ - margin-left: 25px; - border: 1px solid white; - border-radius: 3px; - background-color: rgb(253, 253, 253); - height: 20px; - font-size: 13pt; - font-weight: bold; - font-family: 'Roboto'; - padding: 5px; - width: 350px; +.searchField input { + margin-left: 25px; + border: 1px solid white; + border-radius: 3px; + background-color: rgb(253, 253, 253); + height: 20px; + font-size: 13pt; + font-weight: bold; + font-family: 'Roboto'; + padding: 5px; + width: 350px; } .autocomplete { - position: relative; - display: inline-block; - color: black; - } + position: relative; + display: inline-block; + color: black; +} .autocomplete-items { - /*display: block; */ - position: absolute; - border: 1px solid #d4d4d4; - border-bottom: none; - border-top: none; - z-index: 99; - /*position the autocomplete items to be the same width as the container:*/ - top: 100%; - left: 0; - right: 0; - width: 350px; - margin-left: 30px; - margin-top: 5px; + /*display: block; */ + position: absolute; + border: 1px solid #d4d4d4; + border-bottom: none; + border-top: none; + z-index: 99; + /*position the autocomplete items to be the same width as the container:*/ + top: 100%; + left: 0; + right: 0; + width: 350px; + margin-left: 30px; + margin-top: 5px; } - .autocomplete-items div { - padding: 10px; - font-weight: normal; - font-size: 11pt; - cursor: pointer; - background-color: #fff; - border-bottom: 1px solid #d4d4d4; +.autocomplete-items div { + padding: 10px; + font-weight: normal; + font-size: 11pt; + cursor: pointer; + background-color: #fff; + border-bottom: 1px solid #d4d4d4; } -.autocomplete-items div label{ +.autocomplete-items div label { cursor: pointer; } - /*when hovering an item:*/ - .autocomplete-items div:hover { - background-color: #e9e9e9; +/*when hovering an item:*/ +.autocomplete-items div:hover { + background-color: #e9e9e9; } - /*when navigating through the items using the arrow keys:*/ - .autocomplete-active { - background-color: DodgerBlue !important; - color: #ffffff; +/*when navigating through the items using the arrow keys:*/ +.autocomplete-active { + background-color: DodgerBlue !important; + color: #ffffff; } -button{ +button { padding-left: 10px; padding-right: 10px; padding-top: 5px; @@ -75,7 +75,7 @@ button{ font-weight: bold; } -.routeBtn{ +.routeBtn { background-color: #28a745; margin-top: 9px; margin-left: 10px; @@ -85,6 +85,6 @@ button{ cursor:pointer; } -.routeBtn:hover{ +.routeBtn:hover { background-color: #55c56f; } diff --git a/src/app/search/search.component.ts b/src/app/search/search.component.ts index 7ff608a..d0bd172 100644 --- a/src/app/search/search.component.ts +++ b/src/app/search/search.component.ts @@ -12,8 +12,9 @@ import { EventEmitter } from '@angular/core'; templateUrl: './search.component.html', styleUrls: ['./search.component.css'] }) +export class SearchComponent { -export class SearchComponent{ + @Output() emitter = new EventEmitter(); @ViewChild("inputautocompleteList") autocompleteList: ElementRef; nominatimItemsFrom: Nominatim[] = []; @@ -33,8 +34,6 @@ export class SearchComponent{ selectedPhotonFrom: Photon; selectedPhotonTo: Photon; - @Output() emitter = new EventEmitter(); - constructor( private nominatimService: NominatimService, private photonService: PhotonService, @@ -44,19 +43,19 @@ export class SearchComponent{ getFormattedPhotonValue(p: Photon): string{ let formatted: string = ""; - if(p.properties.name){ + if (p.properties.name) { formatted += " " + p.properties.name; } - if(p.properties.housenumber){ + if (p.properties.housenumber) { formatted += " " + p.properties.housenumber; } - if(p.properties.postcode){ + if (p.properties.postcode) { formatted += " " + p.properties.postcode; } - if(p.properties.city){ + if (p.properties.city) { formatted += " " + p.properties.city; } - if(p.properties.countrycode){ + if (p.properties.countrycode) { formatted += " " + p.properties.countrycode; } @@ -65,14 +64,14 @@ export class SearchComponent{ selectPhoton(isFrom: boolean, p: Photon): void{ - if(isFrom){ + if (isFrom) { this.selectedPhotonFrom = p; this.longFrom = p.geometry?.coordinates[0]; this.latFrom = p.geometry?.coordinates[1]; this.inputFromValue = p.properties.name; this.inputFromValue = this.getFormattedPhotonValue(p); this.photonItemsFrom = []; - }else{ + } else { this.selectedPhotonTo = p; this.longTo = p.geometry?.coordinates[0]; this.latTo = p.geometry?.coordinates[1]; @@ -80,10 +79,12 @@ export class SearchComponent{ this.inputToValue = this.getFormattedPhotonValue(p); this.photonItemsTo = []; } - } - // Gets called in "app.component.html" when an input changes its value - getValue(value:string, isFrom: boolean): void{ + + /** + * Gets called in "app.component.html" when an input changes its value + */ + getValue(value: string, isFrom: boolean): void { //this.updateAutoCompleteList([{display_name: 'Hallo'}, {display_name: 'Test2'}], [{display_name: 'Halload'}, {display_name: 'Test4'}]); @@ -99,28 +100,29 @@ export class SearchComponent{ this.photonItemsTo = []; this.photonService.sendQueryRequest(value) - .subscribe((response: PhotonFeatureCollection) => response.features?.forEach(feature => { - if(isFrom){ - this.photonItemsFrom.push(feature); - this.longFrom = this.photonItemsFrom[0].geometry?.coordinates![0]; - this.latFrom = this.photonItemsFrom[0].geometry?.coordinates![1]; - }else{ - this.photonItemsTo.push(feature); - this.longTo = this.photonItemsFrom[0].geometry?.coordinates![0]; - this.latTo = this.photonItemsFrom[0].geometry?.coordinates![1]; - } - })); + .subscribe((response: PhotonFeatureCollection) => response.features?.forEach(feature => { + if (isFrom) { + this.photonItemsFrom.push(feature); + this.longFrom = this.photonItemsFrom[0].geometry?.coordinates![0]; + this.latFrom = this.photonItemsFrom[0].geometry?.coordinates![1]; + } else { + this.photonItemsTo.push(feature); + this.longTo = this.photonItemsFrom[0].geometry?.coordinates![0]; + this.latTo = this.photonItemsFrom[0].geometry?.coordinates![1]; + } + }) + ); } getRoute(): void{ this.osrmService.sendQueryRequest(this.longFrom, this.latFrom, this.longTo, this.latTo) - .subscribe((response: Osrm) => { - this.emitter.emit(response); - /* - this.mapComponent.updateSidebar(response); - this.mapComponent.drawPath(response); - */ - } + .subscribe((response: Osrm) => { + this.emitter.emit(response); + /* + this.mapComponent.updateSidebar(response); + this.mapComponent.drawPath(response); + */ + } ); } } diff --git a/src/app/services/nominatim.service.ts b/src/app/services/nominatim.service.ts index 319b62c..3626aa5 100644 --- a/src/app/services/nominatim.service.ts +++ b/src/app/services/nominatim.service.ts @@ -3,16 +3,21 @@ import { HttpClient } from '@angular/common/http'; import { Nominatim } from '../interfaces/nominatim'; import { Observable } from 'rxjs'; +/** + * communicates with Nominatim (https://nominatim.org/) + */ @Injectable({ providedIn: 'root' }) - -// communicates with Nominatim (https://nominatim.org/) export class NominatimService{ + constructor(private http: HttpClient) { } - // sends a query request to Nominatim and gets response (https://nominatim.org/release-docs/develop/api/Search/) - sendQueryRequest(q: string): Observable { - return this.http.get("https://nominatim.openstreetmap.org/search.php?format=jsonv2&q=" + q); + /** + * sends a query request to Nominatim and gets response (https://nominatim.org/release-docs/develop/api/Search/) + */ + sendQueryRequest(queryString: string): Observable { + return this.http.get("https://nominatim.openstreetmap.org/search.php?format=jsonv2&q=" + queryString); } + } diff --git a/src/app/services/osrm.service.ts b/src/app/services/osrm.service.ts index fbdfadf..e6ce148 100644 --- a/src/app/services/osrm.service.ts +++ b/src/app/services/osrm.service.ts @@ -3,17 +3,22 @@ import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Osrm } from '../interfaces/osrm'; +/** + * http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?overview=false&steps=true&geometries=geojson + */ @Injectable({ providedIn: 'root' }) - -// http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?overview=false&steps=true&geometries=geojson export class OsrmService{ + constructor(private http: HttpClient) { } - // sends a query request to Osrm and gets response (http://project-osrm.org/docs/v5.24.0/api/?language=cURL#table-service) + /** + * sends a query request to Osrm and gets response (http://project-osrm.org/docs/v5.24.0/api/?language=cURL#table-service) + */ sendQueryRequest(longFrom: number, latFrom: number, longTo: number, latTo: number): Observable { console.log("https://routing.openstreetmap.de/routed-bike/route/v1/driving/" + longFrom + "," + latFrom + ";" + longTo + "," + latTo + "?overview=full&alternatives=false&steps=true&geometries=geojson") return this.http.get("https://routing.openstreetmap.de/routed-bike/route/v1/driving/" + longFrom + "," + latFrom + ";" + longTo + "," + latTo + "?overview=full&alternatives=false&steps=true&geometries=geojson"); } + } diff --git a/src/app/services/photon.service.ts b/src/app/services/photon.service.ts index 3e0a3f5..1bcf280 100644 --- a/src/app/services/photon.service.ts +++ b/src/app/services/photon.service.ts @@ -3,16 +3,21 @@ import { HttpClient } from '@angular/common/http'; import { PhotonFeatureCollection } from '../interfaces/photon'; import { Observable } from 'rxjs'; +/** + * Communicates with Photon (https://photon.komoot.io/) + */ @Injectable({ providedIn: 'root' }) - -// communicates with Photon (https://photon.komoot.io/) export class PhotonService{ + constructor(private http: HttpClient) { } - // sends a query request to Photon and gets response (https://photon.komoot.io/) - sendQueryRequest(q: string): Observable { - return this.http.get("https://photon.komoot.io/api/?q=" + q + "&limit=10&zoom=12"); + /** + * Sends a query request to Photon and gets response (https://photon.komoot.io/) + */ + sendQueryRequest(queryString: string): Observable { + return this.http.get("https://photon.komoot.io/api/?q=" + queryString + "&limit=10&zoom=12"); } + }