Merge branch 'AlexanderNeer-master-patch-12603' into 'master'

Update src/app/app.component.ts, src/app/app.component.css,...

See merge request streetmap1/ts-streetmap!5
This commit is contained in:
Janis Meister
2022-02-09 08:37:16 +00:00
16 changed files with 188 additions and 185 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -1,4 +1,6 @@
// Nominatim JSON object to TypeScript interface
/**
* Nominatim JSON object to TypeScript interface
*/
export interface Nominatim {
boundingbox?: Array<string>;
category?: string;

View File

@@ -1,9 +1,9 @@
interface OpenLayersGeometry{
interface OpenLayersGeometry {
coordinates: Array<Array<number>>;
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<OpenLayersFeature>;
geometry: OpenLayersGeometry;
properties: OpenLayersProperties;
}
}

View File

@@ -1,16 +1,16 @@
interface OsrmWaypoint{
interface OsrmWaypoint {
hint?: string;
distance?: number;
location?: Array<number>;
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<OsrmStep>;
weight?: number;
distance?: number;
@@ -26,7 +26,7 @@ summary?: string;
duration?: number;
}
interface OsrmGeometry{
interface OsrmGeometry {
type: GeometryType;
coordinates?: Array<Array<number>>;
}
@@ -35,12 +35,12 @@ enum GeometryType {
LINE_STRING = "LineString"
}
interface OsrmRoute{
interface OsrmRoute {
legs: Array<OsrmLeg>;
geometry: OsrmGeometry;
}
export interface Osrm{
export interface Osrm {
code?: string;
waypoints?: Array<OsrmWaypoint>;
routes: Array<OsrmRoute>;

View File

@@ -1,32 +1,32 @@
interface PhotonGeometry{
coordinates: Array<number>;
type?: string;
interface PhotonGeometry {
coordinates: Array<number>;
type?: string;
}
interface PhotonProperties{
osm_id?: number;
osm_type?: string;
extent?: Array<number>;
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<number>;
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<Photon>;
type?: string;
export interface PhotonFeatureCollection {
features?: Array<Photon>;
type?: string;
}

View File

@@ -1,5 +1,5 @@
#map{
#map {
width: 100%;
height: 100%;
}

View File

@@ -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<Array<number>> = []
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<Geometry> = 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())

View File

@@ -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;
}
}

View File

@@ -5,12 +5,12 @@
<div *ngFor="let step of this.routeSteps" class="route-list-item" >
<!--Fork-->
<div *ngIf="step.maneuver?.type != 'fork'" style="background-image: url('/assets/images/{{step.maneuver?.modifier }}.svg');">
<p>{{step.maneuver?.type }} {{step.maneuver?.modifier }} <br> {{step.name }}</p>
<p>{{step.maneuver?.type}} {{step.maneuver?.modifier}} <br> {{step.name}}</p>
</div>
<!--Not Fork-->
<div *ngIf="step.maneuver?.type == 'fork'" style="background-image: url('/assets/images/{{step.maneuver?.type }}-{{step.maneuver?.modifier }}.svg');">
<p>{{step.maneuver?.type }} {{step.maneuver?.modifier }} <br> {{step.name }}</p>
<p>{{step.maneuver?.type}} {{step.maneuver?.modifier}} <br> {{step.name}}</p>
</div>
</div>
</div>

View File

@@ -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<OsrmStep> = []
constructor() { }
export class RouteListComponent {
ngOnInit(): void {
}
routeSteps: Array<OsrmStep> = [];
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;
}
}
}

View File

@@ -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;
}

View File

@@ -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<Osrm>();
@ViewChild("inputautocompleteList") autocompleteList: ElementRef;
nominatimItemsFrom: Nominatim[] = [];
@@ -33,8 +34,6 @@ export class SearchComponent{
selectedPhotonFrom: Photon;
selectedPhotonTo: Photon;
@Output() emitter = new EventEmitter<Osrm>();
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 = <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{
} else {
this.selectedPhotonTo = p;
this.longTo = <number>p.geometry?.coordinates[0];
this.latTo = <number>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 = <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];
}
}));
.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(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);
*/
}
);
}
}

View File

@@ -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<Nominatim[]> {
return this.http.get<Nominatim[]>("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<Nominatim[]> {
return this.http.get<Nominatim[]>("https://nominatim.openstreetmap.org/search.php?format=jsonv2&q=" + queryString);
}
}

View File

@@ -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<Osrm> {
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<Osrm>("https://routing.openstreetmap.de/routed-bike/route/v1/driving/" + longFrom + "," + latFrom + ";" + longTo + "," + latTo + "?overview=full&alternatives=false&steps=true&geometries=geojson");
}
}

View File

@@ -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<PhotonFeatureCollection> {
return this.http.get<PhotonFeatureCollection>("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<PhotonFeatureCollection> {
return this.http.get<PhotonFeatureCollection>("https://photon.komoot.io/api/?q=" + queryString + "&limit=10&zoom=12");
}
}