From d0be823cdb51906d49bfecb7cc0e9095b9bed79b Mon Sep 17 00:00:00 2001 From: Roberto Callari <robertocallari89@gmail.com> Date: Mon, 14 Jun 2021 18:27:18 +0200 Subject: [PATCH] messina traffic first commit --- angular.json | 6 +- package-lock.json | 22 +- package.json | 2 + src/app/pages/home/home.component.html | 156 +++++++---- src/app/pages/home/home.component.scss | 3 + .../service/messina-client.service.spec.ts | 16 ++ .../messina/service/messina-client.service.ts | 39 +++ .../messina/traffic/traffic.component.ts | 247 ++++++++++++------ src/assets/config.json | 3 +- src/assets/messina/POIs.json | 27 ++ src/assets/messina/POIs_geojson.json | 36 +++ .../messina/Traffic_GroupByDatetime.json | 238 +++++++++++++++++ src/assets/messina/Traffic_GroupByRoad.json | 81 ++++++ src/assets/messina/stops.json | 32 +++ src/assets/messina/stops_geojson.json | 47 ++++ src/typings.d.ts | 5 + 16 files changed, 823 insertions(+), 137 deletions(-) create mode 100644 src/app/pages/messina/service/messina-client.service.spec.ts create mode 100644 src/app/pages/messina/service/messina-client.service.ts create mode 100644 src/assets/messina/POIs.json create mode 100644 src/assets/messina/POIs_geojson.json create mode 100644 src/assets/messina/Traffic_GroupByDatetime.json create mode 100644 src/assets/messina/Traffic_GroupByRoad.json create mode 100644 src/assets/messina/stops.json create mode 100644 src/assets/messina/stops_geojson.json diff --git a/angular.json b/angular.json index 73654365..87de3191 100644 --- a/angular.json +++ b/angular.json @@ -43,7 +43,8 @@ "node_modules/leaflet/dist/leaflet.css", "node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.carousel.min.css", "node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.theme.default.min.css", - "src/app/@theme/styles/styles.scss" + "src/app/@theme/styles/styles.scss", + "node_modules/leaflet-timedimension/dist/leaflet.timedimension.control.css" ], "scripts": [ "node_modules/pace-js/pace.min.js", @@ -54,7 +55,8 @@ "node_modules/tinymce/plugins/table/plugin.min.js", "node_modules/echarts/dist/echarts.min.js", "node_modules/echarts/dist/extension/bmap.min.js", - "node_modules/chart.js/dist/Chart.min.js" + "node_modules/chart.js/dist/Chart.min.js", + "node_modules/iso8601-js-period/iso8601.js" ], "allowedCommonJsDependencies": [ "angular2-chartjs", diff --git a/package-lock.json b/package-lock.json index 2b444859..512bbba7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11233,6 +11233,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "iso8601-js-period": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/iso8601-js-period/-/iso8601-js-period-0.2.1.tgz", + "integrity": "sha512-iDyz2TQFBd5WhCZjruOwHj01JkQGu7YbVLCVdpA7lCGEcBzE3ffCPAhLh/M8TAp//kCixPpYN4XU54WHCxvD2Q==" + }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -12276,6 +12281,15 @@ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.2.0.tgz", "integrity": "sha512-Bold8phAE6WcRsuwhofrQ7cOK1REFHaYIkKuj7+TBYK3ONKRpGGIb5oXR5akYotFnrWN0TWKh6Svlhflm3dogg==" }, + "leaflet-timedimension": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/leaflet-timedimension/-/leaflet-timedimension-1.1.1.tgz", + "integrity": "sha512-ejXldN94veRsWka1vpC+4rbH+2+3d3ztn2xYx4jcXtjYDrKC/sNnoqCmyH2UEYIy51PI2851aI2k8uGdOEbhlw==", + "requires": { + "iso8601-js-period": "^0.2.1", + "leaflet": "~0.7.4 || ~1" + } + }, "less": { "version": "3.12.2", "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz", @@ -13714,8 +13728,9 @@ "dev": true }, "moment": { - "version": "2.18.1", - "resolved": "" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "morgan": { "version": "1.10.0", @@ -23418,7 +23433,8 @@ }, "ssri": { "version": "6.0.1", - "resolved": "", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { "figgy-pudding": "^3.5.1" diff --git a/package.json b/package.json index f7478844..46ffa936 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,9 @@ "eva-icons": "^1.1.3", "intl": "1.2.5", "ionicons": "2.0.1", + "iso8601-js-period": "^0.2.1", "leaflet": "1.2.0", + "leaflet-timedimension": "^1.1.1", "nebular-icons": "1.1.0", "ng2-ckeditor": "^1.2.9", "ng2-smart-table": "^1.6.0", diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index 9e13193c..a31eec0a 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -1,5 +1,5 @@ <div [ngSwitch]="pilotName"> - + <div *ngSwitchCase="'URBANITE'"> <section class="jumbotron text-center"> <div class="container"> @@ -9,48 +9,109 @@ </p> </div> </section> - - <section> - <div class="container"> - <div class="row d-flex justify-content-between align-items-stretch" > - <mat-card class="col-5"> + + <div class="row d-flex justify-content-around"> + <mat-card class="col-3"> + <mat-card-header> + <mat-card-title>Amsterdam</mat-card-title> + <mat-card-subtitle>Subtitle</mat-card-subtitle> + </mat-card-header> + <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu"> + <mat-card-content> + <p> + The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan. + A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally + bred for hunting. + </p> + </mat-card-content> + </mat-card> + <mat-card class="col-3"> + <mat-card-header> + <mat-card-title>Bilbao</mat-card-title> + <mat-card-subtitle>Dog Breed</mat-card-subtitle> + </mat-card-header> + <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu"> + <mat-card-content> + <p> + The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan. + A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally + bred for hunting. + </p> + </mat-card-content> + </mat-card> + </div> + + <div class="row d-flex justify-content-around"> + <mat-card class="col-3"> + <mat-card-header> + <mat-card-title>Helsinki</mat-card-title> + <mat-card-subtitle>Dog Breed</mat-card-subtitle> + </mat-card-header> + <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu"> + <mat-card-content> + <p> + The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan. + A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally + bred for hunting. + </p> + </mat-card-content> + </mat-card> + + <mat-card class="col-3"> + <mat-card-header> + <mat-card-title>Messina</mat-card-title> + <mat-card-subtitle>Dog Breed</mat-card-subtitle> + </mat-card-header> + <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu"> + <mat-card-content> + <p> + The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan. + A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally + bred for hunting. + </p> + </mat-card-content> + </mat-card> + </div> + + <!-- <section> --> + <!-- <div class="container"> --> + <!-- <div class="row d-flex" > + <mat-card> <mat-card-header> <mat-card-title>What About Urbanite</mat-card-title> </mat-card-header> <mat-card-content class="text-justify"> + <p>In recent years, with the population and size of cities increasing exponentially, transportation has become even more important. + The need for more efficient mobility solutions has been met with a variety of new concepts like sharing vehicles, electric scooters + for rent, and even disruptive start-ups like Uber or Cabify, which are causing a stir with previously used models. + However, such new models are putting public administrations in a challenging situation. The EU-funded URBANITE project aims to develop + a solution that collects and analyses data, that combined with AI, can assist public administrations in policy-related decisions + concerning urban transformation caused by these new transportation and business models. + URBANITE focuses also on social aspects, by analyzing stakeholders’ trust in technologies aiding decision-making.</p> <p> - In recent years, with the population and size of cities increasing exponentially, transportation has become even more important. - The need for more efficient mobility solutions has been met with a variety of new concepts like sharing vehicles, electric scooters - for rent, and even disruptive start-ups like Uber or Cabify, which are causing a stir with previously used models. - However, such new models are putting public administrations in a challenging situation. The EU-funded URBANITE project aims to develop - a solution that collects and analyses data, that combined with AI, can assist public administrations in policy-related decisions - concerning urban transformation caused by these new transportation and business models. - URBANITE focuses also on social aspects, by analyzing stakeholders’ trust in technologies aiding decision-making. - </p> - <p> - Cities are facing a revolution in urban mobility. Emerging start-ups are offering innovative mobility solutions to satisfy - the demand of the growing population, both living or moving into the cities every day. We are moving from the concept of owning - to sharing a vehicle; from using public transport services to moving around with a hop on/off bike or electric scooter; - disruptive start-ups (Uber, Cabify) are shaking up traditionally established business models... - But this innovation is also bringing up unforeseen consequences that public administrations need to manage. - Electric scooters driven in pedestrian areas are posing safety risks and even pedestrian kills; piles of broken bikes - are laying around in streets; protests and strikes by taxi drivers; electric charge points need to coexist with the - growing demand for public parking spaces. It is in this new context that public administrations need means to help them understand - this new scenario, supporting them in making policy–related decisions and predicting eventualities. - There is a need of a platform that can harvest, fuse and curate data from heterogeneous sources, that can extract knowledge to help - in the decision-making processes and simulation of solutions to anticipate behaviours and delimit unforeseen consequences. - Besides, such intelligent platform can foster cross-departmental collaboration by eradicating internal silos. - URBANITE will analyse the impact, trust and attitudes of civil servants, citizens and other stakeholders with respect to the - integration of disruptive technologies such as AI, DSS, big data analytics and predictive algorithms in a data–driven decision-making - process. To this end, URBANITE will provide recommendations, pathways and toolkits (both ICT-based such as data management platform and - DSS, and non-ICT such as co-creation activities and a repository of social-related assets) for city managers. Results will be validated + Cities are facing a revolution in urban mobility. Emerging start-ups are offering innovative mobility solutions to satisfy + the demand of the growing population, both living or moving into the cities every day. We are moving from the concept of owning + to sharing a vehicle; from using public transport services to moving around with a hop on/off bike or electric scooter; + disruptive start-ups (Uber, Cabify) are shaking up traditionally established business models... + But this innovation is also bringing up unforeseen consequences that public administrations need to manage. + Electric scooters driven in pedestrian areas are posing safety risks and even pedestrian kills; piles of broken bikes + are laying around in streets; protests and strikes by taxi drivers; electric charge points need to coexist with the + growing demand for public parking spaces. It is in this new context that public administrations need means to help them understand + this new scenario, supporting them in making policy–related decisions and predicting eventualities. + There is a need of a platform that can harvest, fuse and curate data from heterogeneous sources, that can extract knowledge to help + in the decision-making processes and simulation of solutions to anticipate behaviours and delimit unforeseen consequences. + Besides, such intelligent platform can foster cross-departmental collaboration by eradicating internal silos. + URBANITE will analyse the impact, trust and attitudes of civil servants, citizens and other stakeholders with respect to the + integration of disruptive technologies such as AI, DSS, big data analytics and predictive algorithms in a data–driven decision-making + process. To this end, URBANITE will provide recommendations, pathways and toolkits (both ICT-based such as data management platform and + DSS, and non-ICT such as co-creation activities and a repository of social-related assets) for city managers. Results will be validated in 4 real use cases: Amsterdam, Bilbao, Helsinki and Messina. </p> </mat-card-content> - </mat-card> - - <mat-card class="col-6 h-100"> + </mat-card> --> + + <!-- <mat-card class="col-5 h-100"> <mat-card-content class="text-center"> <owl-carousel-o [options]="customOptions"> <ng-template carouselSlide id="1"><img class="d-block w-100" src="/assets/images/am1.jpg"> @@ -65,28 +126,31 @@ </ng-template> </owl-carousel-o> </mat-card-content> - </mat-card> - </div> - </div> - </section> + </mat-card> --> + <!-- </div> --> + <!-- </div> --> + <!-- </section> + <section> --> + + <!-- </section> --> </div> - - + + <div *ngSwitchCase="'MESSINA'"> {{pilotName}} </div> - - + + <div *ngSwitchCase="'BILBAO'"> {{pilotName}} </div> - - + + <div *ngSwitchCase="'HELSINKI'"> {{pilotName}} </div> - - + + <div *ngSwitchCase="'AMSTERDAM'"> {{pilotName}} </div> diff --git a/src/app/pages/home/home.component.scss b/src/app/pages/home/home.component.scss index e69de29b..515069d5 100644 --- a/src/app/pages/home/home.component.scss +++ b/src/app/pages/home/home.component.scss @@ -0,0 +1,3 @@ +mat-card{ + margin-top: 10px; +} \ No newline at end of file diff --git a/src/app/pages/messina/service/messina-client.service.spec.ts b/src/app/pages/messina/service/messina-client.service.spec.ts new file mode 100644 index 00000000..601a4dca --- /dev/null +++ b/src/app/pages/messina/service/messina-client.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { MessinaClientService } from './messina-client.service'; + +describe('MessinaClientService', () => { + let service: MessinaClientService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(MessinaClientService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/pages/messina/service/messina-client.service.ts b/src/app/pages/messina/service/messina-client.service.ts new file mode 100644 index 00000000..17127b9d --- /dev/null +++ b/src/app/pages/messina/service/messina-client.service.ts @@ -0,0 +1,39 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { ConfigService } from '@ngx-config/core'; +import { Observable, of } from 'rxjs'; + +import messina from '../../../../assets/messina/Traffic_GroupByDatetime.json'; +import poi from '../../../../assets/messina/POIs_geojson.json'; +import stop from '../../../../assets/messina/stops_geojson.json'; + +@Injectable({ + providedIn: 'root' +}) +export class MessinaClientService { + + private apiURL: any; + + constructor(configService: ConfigService,private http:HttpClient) { + this.apiURL = configService.getSettings("messina_api_base_url"); + } + + getTrafficByDateTime(startDateTime:string,endDateTime:string,page:number=0,pageSize?:number): Observable<any> { + //groupBy:string='datetime' + //return this.http.get<any>(`${this.apiURL}/Idra/api/v1/administration/version`); + return of(messina); + } + + getPOI(): Observable<any> { + //groupBy:string='datetime' + //return this.http.get<any>(`${this.apiURL}/Idra/api/v1/administration/version`); + return of(poi); + } + + getStops(): Observable<any> { + //groupBy:string='datetime' + //return this.http.get<any>(`${this.apiURL}/Idra/api/v1/administration/version`); + return of(stop); + } + +} diff --git a/src/app/pages/messina/traffic/traffic.component.ts b/src/app/pages/messina/traffic/traffic.component.ts index 06768134..bbfed444 100644 --- a/src/app/pages/messina/traffic/traffic.component.ts +++ b/src/app/pages/messina/traffic/traffic.component.ts @@ -1,9 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Output } from '@angular/core'; +import { color } from 'd3-color'; import * as L from 'leaflet'; -import AMTram2020 from '../../../../assets/map/am_tram_2020.json'; -import AMTram2020_Stops from '../../../../assets/map/am_tramstop_2020.json'; - +import 'leaflet-timedimension'; +import { MessinaClientService } from '../service/messina-client.service'; @Component({ selector: 'ngx-leaflet', @@ -13,10 +13,12 @@ import AMTram2020_Stops from '../../../../assets/map/am_tramstop_2020.json'; <nb-card class="col-12"> <nb-card-header>Street Traffic</nb-card-header> <nb-card-body> - <div leaflet id="map2" #map2 - [leafletOptions]="options1" - [leafletLayersControl]="layersControl" - [leafletLayers]="layers2"></div> + <div class="map" + leaflet + [leafletOptions]="options" + [leafletLayers]="layers" + [leafletFitBounds]="fitbounds" + ></div> <div class="mt-1"> <p> Real-time data with traffic information on <b>Messina</b>. </p> <p> Input Filters (Limit N-days on UI): <i>StartDateTime</i>, <i>EndDateTime</i></p> @@ -26,96 +28,171 @@ import AMTram2020_Stops from '../../../../assets/map/am_tramstop_2020.json'; </div> `, }) -export class TrafficComponent { +export class TrafficComponent implements OnInit { + + constructor(private messinaClient:MessinaClientService){} - public map1: L.Map; - public map2: L.Map; + geojson:any; + geojsonH:any; + fitbounds=null; + instant=null; + ngOnInit(): void { - icon = new L.Icon({ - iconSize: [25, 41], - iconAnchor: [13, 41], - iconUrl: 'assets/img/markers/marker-icon.png', - iconRetinaUrl: 'assets/img/markers/marker-icon-2x.png', - shadowUrl: 'assets/img/markers/marker-shadow.png' - }); + this.geojson = { + "type":"FeatureCollection", + "features":[] + } - options = { - layers: [ - L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }), - ], - zoom: 9, - center: L.latLng({ lat: 52.372664783594274, lng: 4.8950958251953125 }), - }; + this.geojsonH = { + "type":"FeatureCollection", + "features":[{ + "type": "Feature", + "properties": { + "times":[] + }, + "geometry": { + "type": "LineString", + "coordinates": [] + } + }] + } - layersControl = { - overlays: { - 'Messina Tram - 2020': this.getLayer('Tram 2020',<any>AMTram2020), - 'Messina Tram Stops - 2020': this.getLayer('Stop Tram 2020',<any>AMTram2020_Stops), + //start & end DateTime + this.messinaClient.getTrafficByDateTime(null,null).subscribe(res => { + this.trafficMapConverter(res); + this.displayStops(); + this.displayPOIs(); + }) + } + + private displayStops() { + this.messinaClient.getStops().subscribe(res => { + let stopLayer = L.geoJSON(res['results'], { + pointToLayer: (feature, latlng) => { + let icon= new L.Icon({ + iconSize: [24,36], + iconAnchor: [12,36], + iconUrl: '/assets/img/markers/marker-icon.png', + shadowUrl: '/assets/img/markers/marker-shadow.png' + }) + return L.marker(latlng,{icon:icon}) + } + }); + this.layers.push(stopLayer); + }); + } + + private displayPOIs() { + this.messinaClient.getPOI().subscribe(res => { + let stopLayer = L.geoJSON(res['results'], { + pointToLayer: (feature, latlng) => { + let icon= new L.Icon({ + iconSize: [24,36], + iconAnchor: [12,36], + iconUrl: '/assets/img/markers/marker-icon.png', + shadowUrl: '/assets/img/markers/marker-shadow.png' + }) + return L.marker(latlng,{icon:icon}) + } + }); + this.layers.push(stopLayer); + }); + } + + private trafficMapConverter(messina) { + for (let r in messina['roads']) { + let feature = messina['roads'][r].roadShape; + feature.properties['roadKey'] = r; + this.geojson.features.push(feature); } + + for (let result of messina['results']) { + let millis = new Date(result['datetime']).getTime(); + if (this.geojsonH.features[0].properties.times.indexOf(millis) < 0) { + this.geojsonH.features[0].properties.times.push(millis); + this.geojsonH.features[0].geometry.coordinates.push([15.529174804687498, 38.20365531807149]); + } + for (let d of result['data']) { + for (let f of this.geojson.features) { + if (d.roadKey == f.properties['roadKey']) { + f.properties[millis] = d['JF']; + } + } + } + } + + this.addGeoJSONLayers(this.geojson,this.geojsonH); } - options1 = { + options = { layers: [ - L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' }), + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + { + maxZoom: 15, + attribution: 'Powered by <a href="https://www.geoapify.com/" target="_blank">Geoapify</a> | © OpenStreetMap <a href="https://www.openstreetmap.org/copyright" target="_blank">contributors</a>', + id: 'osm-bright' + }) ], - zoom: 9, - center: L.latLng({ lat: 52.372664783594274, lng: 4.8950958251953125 }), + zoom: 5, + center: L.latLng(41.983994270935625, 12.436523437499998), + timeDimension: true, + timeDimensionControl: true, + timeDimensionControlOptions: { + timeSliderDragUpdate: true, + loopButton: true, + autoPlay: true, + playerOptions: { + transitionTime: 1000, + loop: true + } + } }; - layer = L.marker([52.372664783594274, 4.8950958251953125], { - icon: L.icon({ - iconSize: [25, 41], - iconAnchor: [13, 41], - iconUrl: 'assets/img/markers/marker-icon.png', - iconRetinaUrl: 'assets/img/markers/marker-icon-2x.png', - shadowUrl: 'assets/img/markers/marker-shadow.png' - }) - }).bindPopup("Messina"); - - - layer2 = L.marker([52.372664783594274, 4.8950958251953125], { - icon: L.icon({ - iconSize: [25, 41], - iconAnchor: [13, 41], - iconUrl: 'assets/img/markers/marker-icon.png', - iconRetinaUrl: 'assets/img/markers/marker-icon-2x.png', - shadowUrl: 'assets/img/markers/marker-shadow.png' + layers = []; + + addGeoJSONLayers(dataGeojson,hiddenGeojson) { + let geojsonLayer = L.geoJSON(dataGeojson,{ + style:(feature)=>{ + let v=feature.properties[this.instant]; + let color='green'; + if(v>=2.5 && v<5){ + color='yellow' + }else if(v>=5 && v<7.5){ + color='orange' + }else if(v>=7.5){ + color='red'; + } + return {color:color}; + } }) - }).bindPopup("Messina"); - - - layers = [this.layer]; - layers2 = [this.layer2]; - + + this.layers.push(geojsonLayer) + this.fitbounds = geojsonLayer.getBounds() + + let hiddenLayer = L.timeDimension.layer.geoJson(L.geoJSON(hiddenGeojson,{ + pointToLayer: (feature, latlng) => { + return L.circleMarker(latlng, { + radius: 10.0001, + fillColor: "#ff7800", + color: "#000", + weight: 0, + opacity: 0, + fillOpacity: 0.0001 + }); + } + }), { + updateTimeDimension: true, + duration: 'PT5M', + updateTimeDimensionMode: 'replace', + addlastPoint: true + }).on('timeload',(event)=>{ + this.instant = event.time; + geojsonLayer.eachLayer(l=> geojsonLayer.resetStyle(l)); + }) + + this.layers.push(hiddenLayer); +} - public getLayer(title,l) { - - let layer = L.geoJSON(l, - { - pointToLayer: function (feature, latlng) { - - let icon = L.icon({ - iconSize: [25, 41], - iconAnchor: [13, 41], - iconUrl: 'assets/img/markers/marker-icon.png', - iconRetinaUrl: 'assets/img/markers/marker-icon-2x.png', - shadowUrl: 'assets/img/markers/marker-shadow.png' - }); - let zIndexOffset = 100; - return L.marker(latlng, { icon: icon, zIndexOffset: zIndexOffset, riseOnHover: true, riseOffset: 500 }); - }, - onEachFeature: (feature, layer) => { - let text=""; - for(let p in feature.properties){ - text+=`${p}: ${feature.properties[p]}\n`; - } - layer.bindPopup(text); - } - }) - .on('popupclose', ($event) => { - }) - return layer; - } } diff --git a/src/assets/config.json b/src/assets/config.json index 71e7e42a..4806b2e5 100644 --- a/src/assets/config.json +++ b/src/assets/config.json @@ -25,5 +25,6 @@ ], "enable_demo_pages":false, "pilots":["URBANITE","AMSTERDAM","BILBAO","HELSINKI","MESSINA"], - "default_pilot":"URBANITE" + "default_pilot":"URBANITE", + "messina_api_base_url":"" } \ No newline at end of file diff --git a/src/assets/messina/POIs.json b/src/assets/messina/POIs.json new file mode 100644 index 00000000..3ef38cfa --- /dev/null +++ b/src/assets/messina/POIs.json @@ -0,0 +1,27 @@ +{ + "results": [ + { + "name": "Zanghi Dr. Letterio", + "category": "Medical_Facility", + "type": "Pharmacy", + "location": { + "type": "Point", + "coordinates": [15.54983932, 38.18324646] + } + }, + { + "name": "Zuiki", + "category": "Retail_Services", + "type": "Clothing Store", + "location": { + "type": "Point", + "coordinates": [15.55326244, 38.18506583] + } + } + ], + "total": 2, + "count": 2, + "pageSize": 10, + "page": 1, + "totalPages": 1 +} diff --git a/src/assets/messina/POIs_geojson.json b/src/assets/messina/POIs_geojson.json new file mode 100644 index 00000000..56545b23 --- /dev/null +++ b/src/assets/messina/POIs_geojson.json @@ -0,0 +1,36 @@ +{ + "results": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "Zanghi Dr. Letterio", + "category": "Medical_Facility", + "type": "Pharmacy" + }, + "geometry": { + "type": "Point", + "coordinates": [15.54983932, 38.18324646] + } + }, + { + "type": "Feature", + "properties": { + "name": "Zuiki", + "category": "Retail_Services", + "type": "Clothing Store" + }, + "geometry": { + "type": "Point", + "coordinates": [15.55326244, 38.18506583] + } + } + ] + }, + "total": 2, + "count": 2, + "pageSize": 10, + "page": 1, + "totalPages": 1 +} diff --git a/src/assets/messina/Traffic_GroupByDatetime.json b/src/assets/messina/Traffic_GroupByDatetime.json new file mode 100644 index 00000000..ab71492e --- /dev/null +++ b/src/assets/messina/Traffic_GroupByDatetime.json @@ -0,0 +1,238 @@ +{ + "roads": { + "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+": { + "path": "A20", + "road": "Messina C./Allacciamento Raccordo A20 P.To Messina", + "QD": "+", + "len": 2.04652, + "roadShape": { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 15.536041259765625, + 38.199338565983844 + ], + [ + 15.475616455078125, + 38.08377048360514 + ] + ] + } + } + }, + "Orientale-Sicula_Messina+": { + "path": "Orientale Sicula", + "road": "Messina", + "QD": "+", + "len": 2.04652, + "roadShape": { + "type": "Feature", + "properties": { + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 15.5126953125, + 38.201496974020806 + ], + [ + 15.46600341796875, + 38.12591462924157 + ], + [ + 15.393218994140625, + 38.10754709314396 + ], + [ + 15.408325195312498, + 38.06539235133249 + ], + [ + 15.389099121093752, + 38.0091482264894 + ] + ] + } + } + } + }, + "results": [ + { + "datetime": "2021-06-06T21:23:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 0.07951, + "SP": 79.57, + "SU": 79.57, + "FF": 80, + "CN": 0.89 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 1.07951, + "SP": 89.57, + "SU": 79.57, + "FF": 84, + "CN": 0.89 + } + ] + }, + { + "datetime": "2021-06-06T21:28:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 0, + "SP": 80, + "SU": 103.47, + "FF": 80, + "CN": 0.94 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 1.01, + "SP": 81, + "SU": 107.47, + "FF": 80, + "CN": 0.94 + } + ] + }, + { + "datetime": "2021-06-06T21:33:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 8.07951, + "SP": 79.57, + "SU": 79.57, + "FF": 80, + "CN": 0.89 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 3.07951, + "SP": 89.57, + "SU": 79.57, + "FF": 84, + "CN": 0.89 + } + ] + }, + { + "datetime": "2021-06-06T21:38:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 5.6, + "SP": 80, + "SU": 103.47, + "FF": 80, + "CN": 0.94 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 3.01, + "SP": 81, + "SU": 107.47, + "FF": 80, + "CN": 0.94 + } + ] + }, + { + "datetime": "2021-06-06T21:43:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 6.07951, + "SP": 79.57, + "SU": 79.57, + "FF": 80, + "CN": 0.89 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 1.07951, + "SP": 89.57, + "SU": 79.57, + "FF": 84, + "CN": 0.89 + } + ] + }, + { + "datetime": "2021-06-06T21:48:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 0, + "SP": 80, + "SU": 103.47, + "FF": 80, + "CN": 0.94 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 1.01, + "SP": 81, + "SU": 107.47, + "FF": 80, + "CN": 0.94 + } + ] + }, + { + "datetime": "2021-06-06T21:53:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 3.07951, + "SP": 79.57, + "SU": 79.57, + "FF": 80, + "CN": 0.89 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 6.07951, + "SP": 89.57, + "SU": 79.57, + "FF": 84, + "CN": 0.89 + } + ] + }, + { + "datetime": "2021-06-06T21:58:09.000+00:00", + "data": [ + { + "roadKey": "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+", + "JF": 0, + "SP": 80, + "SU": 103.47, + "FF": 80, + "CN": 0.94 + }, + { + "roadKey": "Orientale-Sicula_Messina+", + "JF": 1.01, + "SP": 81, + "SU": 107.47, + "FF": 80, + "CN": 0.94 + } + ] + } + ], + "total": 6, + "count": 4, + "pageSize": 4, + "page": 1, + "totalPages": 2 +} diff --git a/src/assets/messina/Traffic_GroupByRoad.json b/src/assets/messina/Traffic_GroupByRoad.json new file mode 100644 index 00000000..027a881c --- /dev/null +++ b/src/assets/messina/Traffic_GroupByRoad.json @@ -0,0 +1,81 @@ +{ + "results": { + "A20_Messina-C./Allacciamento-Raccordo-A20-P.To-Messina+": { + "data": [ + { + "datetime": "2021-06-06T21:23:09.000+00:00", + "JF": 0.07951, + "SP": 79.57, + "SU": 79.57, + "FF": 80, + "CN": 0.89 + }, + { + "datetime": "2021-06-06T21:28:09.000+00:00", + "JF": 0, + "SP": 80, + "SU": 103.47, + "FF": 80, + "CN": 0.94 + } + ], + "count": 2, + "path": "A20", + "road": "Messina C./Allacciamento Raccordo A20 P.To Messina", + "QD": "+", + "len": 2.04652, + "roadShape": { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [15.54036, 38.19869], + [15.54018, 38.19861] + ] + } + } + }, + "Orientale-Sicula_Messina+": { + "data": [ + { + "datetime": "2021-06-06T21:23:09.000+00:00", + "JF": 1.07951, + "SP": 89.57, + "SU": 79.57, + "FF": 84, + "CN": 0.89 + }, + { + "datetime": "2021-06-06T21:28:09.000+00:00", + "JF": 1.01, + "SP": 81, + "SU": 107.47, + "FF": 80, + "CN": 0.94 + } + ], + "count": 2, + "path": "Orientale Sicula", + "road": "Messina", + "QD": "+", + "len": 2.04652, + "roadShape": { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [15.53685, 38.1605], + [15.53698, 38.16061] + ] + } + } + } + }, + "total": 6, + "count": 4, + "pageSize": 4, + "page": 1, + "totalPages": 2 +} diff --git a/src/assets/messina/stops.json b/src/assets/messina/stops.json new file mode 100644 index 00000000..ea7230dc --- /dev/null +++ b/src/assets/messina/stops.json @@ -0,0 +1,32 @@ +{ + "results": [ + { + "stop_name": "Via La Farina, ATM", + "stop_times": [ + "04:05:00", + "05:10:00" + ], + "location": { + "type": "Point", + "coordinates": [15.5445, 38.1689] + } + }, + { + "stop_name": "P.zza della Repubblica", + "stop_times": [ + "10:50:00", + "14:10:00", + "20:30:00" + ], + "location": { + "type": "Point", + "coordinates": [15.5603, 38.1862] + } + } + ], + "total": 2, + "count": 2, + "pageSize": 10, + "page": 1, + "totalPages": 1 +} diff --git a/src/assets/messina/stops_geojson.json b/src/assets/messina/stops_geojson.json new file mode 100644 index 00000000..e3d78018 --- /dev/null +++ b/src/assets/messina/stops_geojson.json @@ -0,0 +1,47 @@ +{ + "results": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stop_name": "Via La Farina, ATM", + "stop_times": [ + "04:05:00", + "05:10:00" + ] + }, + "geometry": { + "type": "Point", + "coordinates": [ + 15.5445, + 38.1689 + ] + } + }, + { + "type": "Feature", + "properties": { + "stop_name": "P.zza della Repubblica", + "stop_times": [ + "10:50:00", + "14:10:00", + "20:30:00" + ] + }, + "geometry": { + "type": "Point", + "coordinates": [ + 15.5603, + 38.1862 + ] + } + } + ] + }, + "total": 2, + "count": 2, + "pageSize": 10, + "page": 1, + "totalPages": 1 +} diff --git a/src/typings.d.ts b/src/typings.d.ts index 03eef4f3..ae7cf8d5 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -13,3 +13,8 @@ interface NodeModule { declare var tinymce: any; declare var echarts: any; + +import * as L from 'leaflet'; +declare module 'leaflet' { + var timeDimension: any; +} \ No newline at end of file -- GitLab