diff --git a/src/app/app.component.css b/src/app/app.component.css index d28069b..a985608 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -1,10 +1,9 @@ header{ - background-color: rgb(37, 37, 37); - height: 50px; - font-size: 15pt; - color:white; - font-weight: bold; - + background-color: rgb(37, 37, 37); + height: 50px; + font-size: 15pt; + color:white; + font-weight: bold; } header p{ @@ -13,8 +12,3 @@ header p{ display:block; float:right; } - -#map{ - width: 100%; - height: 100%; -} diff --git a/src/app/app.component.html b/src/app/app.component.html index b78cf35..60c0232 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,6 +1,7 @@
- +

{{title}}

-
\ No newline at end of file + + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index dc78066..1d5362f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,75 +1,25 @@ -import { Component, AfterViewInit, ElementRef, ViewChild} from '@angular/core'; +import { Component, ViewChild, } from '@angular/core'; +import { Osrm } from './interfaces/osrm'; +import { MapComponent } from './map/map.component'; +import { RouteListComponent } from './route-list/route-list.component'; -import { defaults as defaultControls } from 'ol/control'; -import { fromLonLat } from 'ol/proj'; -import Map from 'ol/Map'; -import View from 'ol/View'; -import TileLayer from 'ol/layer/Tile'; -import XYZ from 'ol/source/XYZ'; -import ZoomToExtent from 'ol/control/ZoomToExtent'; - @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css', '../../node_modules/ol/ol.css'] }) -export class AppComponent implements AfterViewInit { + + +export class AppComponent { title = "Street Map"; - map: Map; + @ViewChild('mapRef') mapCompopnent!: MapComponent; + @ViewChild('routeListRef') routeListCompopnent!: RouteListComponent; - @ViewChild("inputautocompleteList") autocompleteList: ElementRef; - - - constructor() { } - - updateAutoCompleteList(): void{ - this.autocompleteList.nativeElement.innerHTML = "Fsd"; - } - - // Gets called in "app.component.html" when an input changes its value - getValue(valueFrom:string, valueTo:string): void{ - console.log("From " + valueFrom + " to " + valueTo); - - /* - this.nominatimService.sendQueryRequest(valueFrom) - .subscribe((response: Nominatim[]) => console.log(response));*/ - - - - - } - - ngOnInit() { - - } - - ngAfterViewInit() { - this.map = new Map({ - target: 'map', - layers: [ - new TileLayer({ - source: new XYZ({ - url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png' - }) - }) - ], - view: new View({ - projection: 'EPSG:3857', - center: fromLonLat([8, 52]), - zoom: 2 - }), - controls: defaultControls().extend([ - new ZoomToExtent({ - extent: [ - 813079.7791264898, 5929220.284081122, - 848966.9639063801, 5936863.986909639 - ] - }) - ]) - }); - setTimeout(() => this.map.updateSize(), 200); - } + onSearchResponse($event: Osrm): void { + this.mapCompopnent.drawPath($event); + this.routeListCompopnent.updateSidebar($event); + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6ce9c83..ec03a98 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,11 +3,15 @@ import { BrowserModule } from '@angular/platform-browser'; import {HttpClientModule} from '@angular/common/http'; import { AppComponent } from './app.component'; import { SearchComponent } from './search/search.component'; +import { MapComponent } from './map/map.component'; +import { RouteListComponent } from './route-list/route-list.component'; @NgModule({ declarations: [ AppComponent, SearchComponent, + MapComponent, + RouteListComponent, ], imports: [ BrowserModule, diff --git a/src/app/interfaces/openLayersGeoJSON.ts b/src/app/interfaces/openLayersGeoJSON.ts new file mode 100644 index 0000000..b3d1dbf --- /dev/null +++ b/src/app/interfaces/openLayersGeoJSON.ts @@ -0,0 +1,29 @@ +interface OpenLayersGeometry{ + coordinates: Array>; + type?: string; +} + +interface OpenLayersProperties{ + ECO_NAME?: string; + BIOME_NAME?: string; + REALM?: string; + NNH?: string; + NNH_NAME?: string; + COLOR?: string; + COLOR_BIO?: string; + COLOR_NNH?: string; +} + +interface OpenLayersFeature{ + type: string; + geometry: OpenLayersGeometry; + id: number; + properties: OpenLayersProperties; +} + +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 new file mode 100644 index 0000000..7fd8114 --- /dev/null +++ b/src/app/interfaces/osrm.ts @@ -0,0 +1,47 @@ +interface OsrmWaypoint{ + hint?: string; + distance?: number; + location?: Array; + name?: string; +} + +interface OsrmManeuver{ + type?: string; + modifier?: string; +} + +export interface OsrmStep{ + driving_side?: string; + duration?: number; + distance?: number; + name?: string; + maneuver?: OsrmManeuver; +} + +interface OsrmLeg{ +steps?: Array; +weight?: number; +distance?: number; +summary?: string; +duration?: number; +} + +interface OsrmGeometry{ + type: GeometryType; + coordinates?: Array>; +} + +enum GeometryType { + LINE_STRING = "LineString" +} + +interface OsrmRoute{ + legs: Array; + geometry: OsrmGeometry; +} + +export interface Osrm{ + code?: string; + waypoints?: Array; + routes: Array; +} diff --git a/src/app/interfaces/photon.ts b/src/app/interfaces/photon.ts index 301025f..652c545 100644 --- a/src/app/interfaces/photon.ts +++ b/src/app/interfaces/photon.ts @@ -15,6 +15,9 @@ interface PhotonProperties{ type?: string; postcode?: string; city?: string; + housenumber?: number; + street?: string; + state?: string; } export interface Photon{ @@ -26,4 +29,4 @@ export interface Photon{ export interface PhotonFeatureCollection{ features?: Array; type?: string; -} \ No newline at end of file +} diff --git a/src/app/map/map.component.css b/src/app/map/map.component.css new file mode 100644 index 0000000..a6c22ec --- /dev/null +++ b/src/app/map/map.component.css @@ -0,0 +1,6 @@ + +#map{ + width: 100%; + height: 100%; +} + diff --git a/src/app/map/map.component.html b/src/app/map/map.component.html new file mode 100644 index 0000000..4fa1fbc --- /dev/null +++ b/src/app/map/map.component.html @@ -0,0 +1 @@ +
diff --git a/src/app/map/map.component.spec.ts b/src/app/map/map.component.spec.ts new file mode 100644 index 0000000..f163147 --- /dev/null +++ b/src/app/map/map.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MapComponent } from './map.component'; + +describe('MapComponent', () => { + let component: MapComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ MapComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MapComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/map/map.component.ts b/src/app/map/map.component.ts new file mode 100644 index 0000000..54cec78 --- /dev/null +++ b/src/app/map/map.component.ts @@ -0,0 +1,89 @@ +import { Component, AfterViewInit } from '@angular/core'; +import { defaults as defaultControls } from 'ol/control'; +import { fromLonLat, transform } from 'ol/proj'; +import Map from 'ol/Map'; +import View from 'ol/View'; +import TileLayer from 'ol/layer/Tile'; +import XYZ from 'ol/source/XYZ'; +import ZoomToExtent from 'ol/control/ZoomToExtent'; +import VectorLayer from 'ol/layer/Vector'; +import VectorSource from 'ol/source/Vector'; +import LineString from 'ol/geom/LineString'; +import { Osrm, OsrmStep } from '../interfaces/osrm'; +import { Feature } from 'ol'; +import Geometry from 'ol/geom/Geometry'; + +@Component({ + selector: 'app-map', + templateUrl: './map.component.html', + styleUrls: ['./map.component.css'] +}) +export class MapComponent implements AfterViewInit { + + constructor() { } + + map: Map; + + + ngAfterViewInit() { + this.map = new Map({ + target: 'map', + layers: [ + new TileLayer({ + source: new XYZ({ + url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png' + }) + }) + ], + view: new View({ + projection: 'EPSG:3857', + center: fromLonLat([8, 52]), + zoom: 2 + }), + controls: defaultControls().extend([ + new ZoomToExtent({ + extent: [ + 813079.7791264898, 5929220.284081122, + 848966.9639063801, 5936863.986909639 + ] + }) + ]) + }); + setTimeout(() => this.map.updateSize(), 200); + } + + 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 + + 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 feature: Feature = new Feature({ geometry: lineString }); + const vectorSource = new VectorSource({ features: [ feature ]}); + + const vectorLayer = new VectorLayer({ + + source: vectorSource, + }); + this.map.addLayer(vectorLayer); + + // this.features = new GeoJSON().readFeatures(new openLayersGeoJSON()) + + /* + this.vectorLayer = new VectorLayer({ + background: '#1a2b39', + source: new VectorSource({ + url: 'http://router.project-osrm.org/route/v1/driving/-1.8744130630953275,52.45318441573963;-1.879401971863028,52.451059431849615;-1.8783612747652496,52.44962092302177;-1.882395317123648,52.44969938835112;-1.8824275036318268,52.452046744809195;-1.8794663448793851,52.45332825709778;-1.8898840446932288,52.454230523991356?overview=full&steps=true&geometries=geojson', + format: new GeoJSON({dataProjection: 'EPSG:4326', featureProjection: "EPSG:3857" }), + }) + }); + + this.map.addLayer(this.vectorLayer);*/ + } +} diff --git a/src/app/route-list/route-list.component.css b/src/app/route-list/route-list.component.css new file mode 100644 index 0000000..bf45830 --- /dev/null +++ b/src/app/route-list/route-list.component.css @@ -0,0 +1,50 @@ +.osrm-route-container{ + position: absolute; + right: 0; + width:300px; + margin-top: 50px; + background-color: rgba(27, 27, 27, 0.801); + top:0; + bottom: 0; + color: white; + overflow-y: scroll; + } + + .osrm-route-container h4{ + text-align: center; + line-height: 30px; + letter-spacing: 1px; + padding-top: 0px; + margin-top: 2px; + } + + .route-list{ + width: 100%; + display: block; + font-weight: bold; + text-align: left; + + } + + .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 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 new file mode 100644 index 0000000..0c98761 --- /dev/null +++ b/src/app/route-list/route-list.component.html @@ -0,0 +1,18 @@ +
+

Your Route Steps

+ +
+
+ +
+

{{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.spec.ts b/src/app/route-list/route-list.component.spec.ts new file mode 100644 index 0000000..76e6d5e --- /dev/null +++ b/src/app/route-list/route-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RouteListComponent } from './route-list.component'; + +describe('RouteListComponent', () => { + let component: RouteListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ RouteListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(RouteListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/route-list/route-list.component.ts b/src/app/route-list/route-list.component.ts new file mode 100644 index 0000000..537e288 --- /dev/null +++ b/src/app/route-list/route-list.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core'; +import { Osrm, OsrmStep } from '../interfaces/osrm'; + +@Component({ + selector: 'app-route-list', + templateUrl: './route-list.component.html', + styleUrls: ['./route-list.component.css'] +}) +export class RouteListComponent implements OnInit { + routeSteps: Array = [] + constructor() { } + + ngOnInit(): void { + } + + updateSidebar(osrm: Osrm): void{ + 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 f39611f..33caa27 100644 --- a/src/app/search/search.component.css +++ b/src/app/search/search.component.css @@ -1,11 +1,3 @@ -#inputFrom:focus + .autocomplete-items-from{ - visibility:visible; -} - -#inputTo:focus + .autocomplete-items-to{ - visibility:visible; -} - .searchField{ display:block; float:left; @@ -22,6 +14,7 @@ font-weight: bold; font-family: 'Roboto'; padding: 5px; + width: 350px; } .autocomplete { @@ -29,9 +22,9 @@ display: inline-block; color: black; } - + .autocomplete-items { - visibility: visible; /* without debugging it should be display:none */ + /*display: block; */ position: absolute; border: 1px solid #d4d4d4; border-bottom: none; @@ -41,27 +34,57 @@ top: 100%; left: 0; right: 0; - width: 210px; + 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; + background-color: #fff; + border-bottom: 1px solid #d4d4d4; +} + +.autocomplete-items div label{ + cursor: pointer; } - /*when hovering an item:*/ .autocomplete-items div:hover { - background-color: #e9e9e9; + background-color: #e9e9e9; } - + /*when navigating through the items using the arrow keys:*/ .autocomplete-active { - background-color: DodgerBlue !important; - color: #ffffff; -} \ No newline at end of file + background-color: DodgerBlue !important; + color: #ffffff; +} + +button{ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; + border-radius: 0; + border: 0; + background-color: transparent; + color: white; + font-size: 13pt; + font-weight: bold; +} + +.routeBtn{ + background-color: #28a745; + margin-top: 9px; + margin-left: 10px; + border-radius: 3px; + transition: 0.1s; + transition-timing-function: linear; + cursor:pointer; +} + +.routeBtn:hover{ + background-color: #55c56f; +} diff --git a/src/app/search/search.component.html b/src/app/search/search.component.html index d512acb..f80e3b3 100644 --- a/src/app/search/search.component.html +++ b/src/app/search/search.component.html @@ -1,29 +1,33 @@ -
-
- - - - -
+
- +
- +
{{ item.display_name }}
+
- {{ item.properties.name }} {{item.properties.postcode}} {{item.properties.city}} {{item.properties.countrycode}} -
+ (click)="selectPhoton(true, item);" > + + + + +
- +
@@ -33,10 +37,20 @@
- {{ item.properties.name }} {{item.properties.postcode}} {{item.properties.city}} {{item.properties.countrycode}} - + + + + +
-
\ No newline at end of file +
+ diff --git a/src/app/search/search.component.ts b/src/app/search/search.component.ts index 2310d5f..7ff608a 100644 --- a/src/app/search/search.component.ts +++ b/src/app/search/search.component.ts @@ -1,8 +1,11 @@ -import { Component, OnInit, ElementRef, ViewChild} from '@angular/core'; +import { Component, ElementRef, Output, ViewChild } from '@angular/core'; import { Nominatim } from '../interfaces/nominatim'; -import { NominatimService } from '../nominatim.service'; +import { NominatimService } from '../services/nominatim.service'; import { Photon, PhotonFeatureCollection } from '../interfaces/photon'; -import { PhotonService } from '../photon.service'; +import { PhotonService } from '../services/photon.service'; +import { OsrmService } from '../services/osrm.service'; +import { Osrm } from '../interfaces/osrm'; +import { EventEmitter } from '@angular/core'; @Component({ selector: 'app-search', @@ -10,7 +13,7 @@ import { PhotonService } from '../photon.service'; styleUrls: ['./search.component.css'] }) -export class SearchComponent implements OnInit { +export class SearchComponent{ @ViewChild("inputautocompleteList") autocompleteList: ElementRef; nominatimItemsFrom: Nominatim[] = []; @@ -30,38 +33,58 @@ export class SearchComponent implements OnInit { selectedPhotonFrom: Photon; selectedPhotonTo: Photon; - constructor(private nominatimService: NominatimService, private photonService: PhotonService) { } + @Output() emitter = new EventEmitter(); + + constructor( + private nominatimService: NominatimService, + private photonService: PhotonService, + private osrmService: OsrmService, + ) { } + + getFormattedPhotonValue(p: Photon): string{ + let formatted: string = ""; + + if(p.properties.name){ + formatted += " " + p.properties.name; + } + if(p.properties.housenumber){ + formatted += " " + p.properties.housenumber; + } + if(p.properties.postcode){ + formatted += " " + p.properties.postcode; + } + if(p.properties.city){ + formatted += " " + p.properties.city; + } + if(p.properties.countrycode){ + formatted += " " + p.properties.countrycode; + } + + return formatted; + } + selectPhoton(isFrom: boolean, p: Photon): void{ if(isFrom){ this.selectedPhotonFrom = p; this.longFrom = p.geometry?.coordinates[0]; this.latFrom = p.geometry?.coordinates[1]; - this.inputFromValue = p.properties.name - - if(p.properties.postcode){ - this.inputFromValue += " " + p.properties.postcode; - } - - if(p.properties.city){ - this.inputFromValue += " " + p.properties.city; - } - - if(p.properties.countrycode){ - this.inputFromValue += " " + p.properties.countrycode; - } - + this.inputFromValue = p.properties.name; + this.inputFromValue = this.getFormattedPhotonValue(p); + this.photonItemsFrom = []; }else{ this.selectedPhotonTo = p; this.longTo = p.geometry?.coordinates[0]; this.latTo = p.geometry?.coordinates[1]; this.inputToValue = p.properties.name + " " + p.properties.countrycode; + this.inputToValue = this.getFormattedPhotonValue(p); + this.photonItemsTo = []; } + } // Gets called in "app.component.html" when an input changes its value - getValue(valueFrom:string, valueTo:string): void{ - console.log("From " + valueFrom + " to " + valueTo); - + getValue(value:string, isFrom: boolean): void{ + //this.updateAutoCompleteList([{display_name: 'Hallo'}, {display_name: 'Test2'}], [{display_name: 'Halload'}, {display_name: 'Test4'}]); /* @@ -71,24 +94,33 @@ export class SearchComponent implements OnInit { this.nominatimService.sendQueryRequest(valueTo) .subscribe((response: Nominatim[]) => this.nominatimItemsTo = response); */ + this.photonItemsFrom = []; this.photonItemsTo = []; - this.photonService.sendQueryRequest(valueFrom) + this.photonService.sendQueryRequest(value) .subscribe((response: PhotonFeatureCollection) => response.features?.forEach(feature => { - this.photonItemsFrom.push(feature); - this.longFrom = this.photonItemsFrom[0].geometry?.coordinates![0]; - this.latFrom = this.photonItemsFrom[0].geometry?.coordinates![1]; - })); - - this.photonService.sendQueryRequest(valueTo) - .subscribe((response: PhotonFeatureCollection) => response.features?.forEach(feature => { - this.photonItemsTo.push(feature); - this.longTo = this.photonItemsTo[0].geometry?.coordinates![0]; - this.latTo = this.photonItemsTo[0].geometry?.coordinates![1]; + 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]; + } })); } - ngOnInit(): void { - } + 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); + */ + } + ); + } } diff --git a/src/app/nominatim.service.spec.ts b/src/app/services/nominatim.service.spec.ts similarity index 100% rename from src/app/nominatim.service.spec.ts rename to src/app/services/nominatim.service.spec.ts diff --git a/src/app/nominatim.service.ts b/src/app/services/nominatim.service.ts similarity index 82% rename from src/app/nominatim.service.ts rename to src/app/services/nominatim.service.ts index c230c35..319b62c 100644 --- a/src/app/nominatim.service.ts +++ b/src/app/services/nominatim.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Nominatim } from './interfaces/nominatim'; +import { Nominatim } from '../interfaces/nominatim'; import { Observable } from 'rxjs'; @Injectable({ @@ -12,7 +12,7 @@ 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 { + sendQueryRequest(q: string): Observable { return this.http.get("https://nominatim.openstreetmap.org/search.php?format=jsonv2&q=" + q); } -} \ No newline at end of file +} diff --git a/src/app/services/open-layers.service.spec.ts b/src/app/services/open-layers.service.spec.ts new file mode 100644 index 0000000..4639485 --- /dev/null +++ b/src/app/services/open-layers.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { OpenLayersService } from './open-layers.service'; + +describe('OpenLayersService', () => { + let service: OpenLayersService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(OpenLayersService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/open-layers.service.ts b/src/app/services/open-layers.service.ts new file mode 100644 index 0000000..d2f5bc7 --- /dev/null +++ b/src/app/services/open-layers.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@angular/core'; +import { OpenLayersGeoJSON } from './interfaces/openlayersGeojson'; + +@Injectable({ + providedIn: 'root' +}) +export class OpenLayersService { + + constructor() { } + +} diff --git a/src/app/services/osrm.service.spec.ts b/src/app/services/osrm.service.spec.ts new file mode 100644 index 0000000..833485d --- /dev/null +++ b/src/app/services/osrm.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { OsrmService } from './osrm.service'; + +describe('OsrmService', () => { + let service: OsrmService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(OsrmService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/osrm.service.ts b/src/app/services/osrm.service.ts new file mode 100644 index 0000000..fbdfadf --- /dev/null +++ b/src/app/services/osrm.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Osrm } from '../interfaces/osrm'; + +@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) + 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/photon.service.spec.ts b/src/app/services/photon.service.spec.ts similarity index 100% rename from src/app/photon.service.spec.ts rename to src/app/services/photon.service.spec.ts diff --git a/src/app/photon.service.ts b/src/app/services/photon.service.ts similarity index 81% rename from src/app/photon.service.ts rename to src/app/services/photon.service.ts index 42aa3b1..3e0a3f5 100644 --- a/src/app/photon.service.ts +++ b/src/app/services/photon.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Photon, PhotonFeatureCollection } from './interfaces/photon'; +import { PhotonFeatureCollection } from '../interfaces/photon'; import { Observable } from 'rxjs'; @Injectable({ @@ -12,7 +12,7 @@ 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"); + sendQueryRequest(q: string): Observable { + return this.http.get("https://photon.komoot.io/api/?q=" + q + "&limit=10&zoom=12"); } -} \ No newline at end of file +} diff --git a/src/assets/images/fork-slight left.svg b/src/assets/images/fork-slight left.svg new file mode 100644 index 0000000..0dd7be8 --- /dev/null +++ b/src/assets/images/fork-slight left.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/assets/images/fork-slight right.svg b/src/assets/images/fork-slight right.svg new file mode 100644 index 0000000..960930b --- /dev/null +++ b/src/assets/images/fork-slight right.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/assets/images/left.svg b/src/assets/images/left.svg new file mode 100644 index 0000000..dfd6b81 --- /dev/null +++ b/src/assets/images/left.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/assets/images/right.svg b/src/assets/images/right.svg new file mode 100644 index 0000000..cb235f8 --- /dev/null +++ b/src/assets/images/right.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/assets/images/slight left.svg b/src/assets/images/slight left.svg new file mode 100644 index 0000000..d3987ae --- /dev/null +++ b/src/assets/images/slight left.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/assets/images/slight right.svg b/src/assets/images/slight right.svg new file mode 100644 index 0000000..bd90e45 --- /dev/null +++ b/src/assets/images/slight right.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/src/assets/images/straight.svg b/src/assets/images/straight.svg new file mode 100644 index 0000000..1d5ff60 --- /dev/null +++ b/src/assets/images/straight.svg @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/styles.css b/src/styles.css index a7dd6ba..a5be714 100644 --- a/src/styles.css +++ b/src/styles.css @@ -14,5 +14,11 @@ body { top:0; bottom:0; right:0; - left:0; + left:0; + overflow: hidden; + background-color: rgb(37, 37, 37); +} + +button{ + outline: 0; }