mirror of
https://github.com/DerTyp7/osm-routing-angular.git
synced 2025-11-02 06:02:30 +01:00
Initial Commit
This commit is contained in:
90
src/app/search/search.component.css
Normal file
90
src/app/search/search.component.css
Normal file
@@ -0,0 +1,90 @@
|
||||
.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;
|
||||
}
|
||||
|
||||
.autocomplete {
|
||||
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;
|
||||
}
|
||||
|
||||
.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 {
|
||||
cursor: pointer;
|
||||
}
|
||||
/*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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
56
src/app/search/search.component.html
Normal file
56
src/app/search/search.component.html
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
<div class="searchField">
|
||||
<div class="autocomplete">
|
||||
<input #inputFrom (click)="getValue(inputFrom.value, true)" (change)="getValue(inputFrom.value, true)" type="text" name="inputFrom" id="inputFrom" placeholder="From" value="{{ inputFromValue }}">
|
||||
<div #inputautocompleteList class="autocomplete-items autocomplete-items-from">
|
||||
|
||||
<div *ngFor="let item of nominatimItemsFrom" >
|
||||
{{ item.display_name }}
|
||||
<input type="hidden" value="{{ item.display_name }}">
|
||||
</div>
|
||||
|
||||
<!-- PHOTON -->
|
||||
<div *ngFor="let item of photonItemsFrom"
|
||||
(click)="selectPhoton(true, item);" >
|
||||
<!--IF TYPE == STREET-->
|
||||
<label *ngIf="item.properties.type == 'street'">
|
||||
{{ item.properties.name }} {{item.properties.housenumber}}<br>
|
||||
{{item.properties.postcode}} {{item.properties.city}} {{item.properties.country}}
|
||||
</label>
|
||||
|
||||
<label *ngIf="item.properties.type != 'street'">
|
||||
{{ item.properties.name }} <br>
|
||||
{{item.properties.street}} {{item.properties.housenumber}} {{item.properties.postcode}} {{item.properties.city}} {{item.properties.countrycode}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="autocomplete" id="autocompleteTo">
|
||||
<input #inputTo (click)="getValue(inputTo.value, false)" (change)="getValue(inputTo.value, false)" type="text" name="inputTo" id="inputTo" placeholder="To" value="{{ inputToValue }}">
|
||||
<div #inputautocompleteList class="autocomplete-items autocomplete-items-to">
|
||||
|
||||
<div *ngFor="let item of nominatimItemsTo" >
|
||||
{{ item.display_name }}
|
||||
<input type="hidden" value="{{ item.display_name }}">
|
||||
</div>
|
||||
|
||||
<div *ngFor="let item of photonItemsTo"
|
||||
(click)="selectPhoton(false, item)">
|
||||
<!--IF TYPE == STREET-->
|
||||
<label *ngIf="item.properties.type == 'street'">
|
||||
{{ item.properties.name }} {{item.properties.housenumber}}<br>
|
||||
{{item.properties.postcode}} {{item.properties.city}} {{item.properties.country}}
|
||||
</label>
|
||||
|
||||
<label *ngIf="item.properties.type != 'street'">
|
||||
{{ item.properties.name }} <br>
|
||||
{{item.properties.street}} {{item.properties.housenumber}} {{item.properties.postcode}} {{item.properties.city}} {{item.properties.countrycode}}
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="routeBtn" (click)="getRoute()">Route</button>
|
||||
25
src/app/search/search.component.spec.ts
Normal file
25
src/app/search/search.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchComponent } from './search.component';
|
||||
|
||||
describe('SearchComponent', () => {
|
||||
let component: SearchComponent;
|
||||
let fixture: ComponentFixture<SearchComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SearchComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
128
src/app/search/search.component.ts
Normal file
128
src/app/search/search.component.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { Component, ElementRef, Output, ViewChild } from '@angular/core';
|
||||
import { Nominatim } from '../interfaces/nominatim';
|
||||
import { NominatimService } from '../services/nominatim.service';
|
||||
import { Photon, PhotonFeatureCollection } from '../interfaces/photon';
|
||||
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',
|
||||
templateUrl: './search.component.html',
|
||||
styleUrls: ['./search.component.css']
|
||||
})
|
||||
export class SearchComponent {
|
||||
|
||||
@Output() emitter = new EventEmitter<Osrm>();
|
||||
@ViewChild("inputautocompleteList") autocompleteList: ElementRef;
|
||||
|
||||
nominatimItemsFrom: Nominatim[] = [];
|
||||
nominatimItemsTo: Nominatim[] = [];
|
||||
|
||||
photonItemsFrom: Photon[] = [];
|
||||
photonItemsTo: Photon[] = [];
|
||||
|
||||
inputFromValue: string;
|
||||
inputToValue: string;
|
||||
|
||||
longFrom: number = 0;
|
||||
latFrom: number = 0;
|
||||
longTo: number = 0;
|
||||
latTo: number = 0;
|
||||
|
||||
selectedPhotonFrom: Photon;
|
||||
selectedPhotonTo: Photon;
|
||||
|
||||
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 = <number> p.geometry?.coordinates[0];
|
||||
this.latFrom = <number> p.geometry?.coordinates[1];
|
||||
this.inputFromValue = <string> p.properties.name;
|
||||
this.inputFromValue = this.getFormattedPhotonValue(p);
|
||||
this.photonItemsFrom = [];
|
||||
} else {
|
||||
this.selectedPhotonTo = p;
|
||||
this.longTo = <number>p.geometry?.coordinates[0];
|
||||
this.latTo = <number>p.geometry?.coordinates[1];
|
||||
this.inputToValue = <string> 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(value: string, isFrom: boolean): void {
|
||||
|
||||
//this.updateAutoCompleteList([{display_name: 'Hallo'}, {display_name: 'Test2'}], [{display_name: 'Halload'}, {display_name: 'Test4'}]);
|
||||
|
||||
/*
|
||||
this.nominatimService.sendQueryRequest(valueFrom)
|
||||
.subscribe((response: Nominatim[]) => this.nominatimItemsFrom = response);
|
||||
|
||||
this.nominatimService.sendQueryRequest(valueTo)
|
||||
.subscribe((response: Nominatim[]) => this.nominatimItemsTo = response);
|
||||
*/
|
||||
|
||||
this.photonItemsFrom = [];
|
||||
this.photonItemsTo = [];
|
||||
|
||||
this.photonService.sendQueryRequest(value)
|
||||
.subscribe((response: PhotonFeatureCollection) => response.features?.forEach(feature => {
|
||||
if (isFrom) {
|
||||
this.photonItemsFrom.push(feature);
|
||||
this.longFrom = <number>this.photonItemsFrom[0].geometry?.coordinates![0];
|
||||
this.latFrom = <number>this.photonItemsFrom[0].geometry?.coordinates![1];
|
||||
} else {
|
||||
this.photonItemsTo.push(feature);
|
||||
this.longTo = <number>this.photonItemsFrom[0].geometry?.coordinates![0];
|
||||
this.latTo = <number>this.photonItemsFrom[0].geometry?.coordinates![1];
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getRoute(): void{
|
||||
this.osrmService.sendQueryRequest("https://routing.openstreetmap.de/routed-bike/route/v1/driving/" + this.longFrom + "," + this.latFrom + ";" + this.longTo + "," + this.latTo)
|
||||
.subscribe((response: Osrm) => {
|
||||
this.emitter.emit(response);
|
||||
/*
|
||||
this.mapComponent.updateSidebar(response);
|
||||
this.mapComponent.drawPath(response);
|
||||
*/
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user