Bläddra i källkod

Gestion du centrage sur la carte lors d'un clic sur une trace et modification des fichiers json qui doivent utiliser des LineString et non pas des MultiLineString pour porter les coordonnées, ce dernier format n'étant pas pris en charge pour le moment.

jeje 6 år sedan
förälder
incheckning
35d0f1eed6

+ 18 - 5
README.md

@@ -42,10 +42,23 @@ A priori, il faudrait pouvoir référencer l'ensemble des traces dans une descri
 * Une entrée vers l'ensemble de mes traces VTT
 * Une entrée vers une présentation plus pro des différents sujets pouvant déboucher sur du business (DIY, services,...)
 
-## Affichage de mes traces
-Pb: le site qui me permet de convertir les fichiers GPX en GeoJson, ne permet pas de convertir plus de 3 fichiers par mois, ce qui est donc assez limitant.
-Une solution viable serait de charger les fichiers GPX et les transformer à la volée, en données GeoJson, exploitables. Ceci semble être possible via la lib MapBox. 
 
-Dans un premier temps et afin de tester cette solution on peut transformer les fichiers GPX en GeoJson, pour les exploiter directement dans le prog.
+## Affichage de mes traces
+###Conversion des fichiers de trace
+Les fichiers sources ont été produit par différents programme et matériel, et nécessite donc une conversion préalable dans un format pivot maitrisé par l'application.
+Pb: le site ayant permis de convertir les fichiers GPX en GeoJson pour débuter les développements, ne permet pas de convertir plus de 3 fichiers par mois, ce qui est donc assez limitant.
+Une solution viable serait de charger les fichiers GPX et les transformer à la volée, en données GeoJson, exploitables. Ceci semble être possible via la lib MapBox.
+ L'objectif ici est bien d'obtenir une solution stable qui fonctionne dans la plupart des cas,
+ en fournissant des fichiers dans un format fixe.
+ 
+ TODO: ajouter une description de la conversion par cette dernière méthode.
+
+####Format json attendu
+* Transformer les fichiers GPX en GeoJson: utiliser des LineString plutôt que des MultiLineString pour porter coordonnées. 
+Les MultiLineString ajoute un niveau supplémentaire non géré actuellement par l'appli qui provoque un dysfonctionnement lors d'un recentrage sur une trace.
+* Utilisation de la description présente dans le fichier Json, pour porter les metadata des traces (coordonnées initiales, libellées, description, date...), ceci afin de pouvoir afficher les repères sur la carte. Un clic sur ces repères permet d'afficher la trace en récupérant le fichier GeoJson (ou dans son format d'origine par la suite).
+
+##TODO
+* Prise en charge de la techno flex pour une meilleure mise en page
+* Puisque les outils de conversion sont payants en ligne pourquoi ne pas proposer une version gratuite sur un nombre limité de format?
 
-A priori, il faudrait pouvoir référencer l'ensemble des traces dans une description Json, afin de contenir l'ensemble des descriptions des traces (coordonnées initiales, libellées, description, date...), ceci afin de pouvoir afficher les repères sur la carte. Un clic sur ces repères permet d'afficher la trace en récupérant le fichier GeoJson (ou dans son format d'origine par la suite).

+ 6 - 0
src/app/app.component.css

@@ -27,3 +27,9 @@
   font-weight: 900;
   padding: 20px 70px 50px;
 }
+
+
+.map {
+  height: 100%;
+  padding: 0;
+}

+ 4 - 58
src/app/vtt-trace/vtt-trace/vtt-trace.component.html

@@ -1,7 +1,7 @@
 
 <mat-card class="card1">
   <mat-card-header>
-    <mat-card-title><h1>My GPS traces referenced on a map.</h1></mat-card-title>
+    <mat-card-title><h1>My VTT GPS traces referenced on a map.</h1></mat-card-title>
   </mat-card-header>
   <hr>
   <mat-card-content>
@@ -9,70 +9,16 @@
       <app-dialog></app-dialog>
       <div leaflet
            style="height: 500px;"
+           (leafletMapReady)="onMapReady($event)"
            [leafletOptions]="options"
            [leafletLayers]="layers"
-           [leafletZoom]="zoom"
-           [leafletCenter]="center"
+           [(leafletZoom)]="zoom"
+           [(leafletCenter)]="center"
            [leafletLayersControl]="layersControl"
            [leafletLayersControlOptions]="layersControlOptions">
 
       </div>
-      <div class="row">
-
-        <!-- Control Form -->
-        <div class="col-sm-12 col-md-6 col-lg-4">
-          angular  data refresh event
-          <form>
-
-            <div class="form-group">
-              <label class="col-form-label">Options:</label>
-              <small class="form-text">{{ optionsSpec | json }}</small>
-            </div>
-
-            <!-- Zoom Levels -->
-            <div class="form-group row">
-              <div class="col-4">
-                <label class="col-form-label float-right">
-                  Zoom
-                </label>
-              </div>
-              <div class="col">
-                <select class="form-control" name="zoom" [(ngModel)]="zoom" required>
-                  <option *ngFor="let z of zoomLevels" [value]="z">{{z}}</option>
-                </select>
-              </div>
-
-              <div class="col-4">
-                <label class="col-form-label float-right">
-                  Latitude
-                </label>
-              </div>
-              <div class="col">
-                <input type="text" class="form-control" name="latitude" [(ngModel)]="latitude" required>
-              </div>
-            </div>
-            <div class="form-group row">
-              <div class="col-4">
-                <label class="col-form-label float-right">
-                  Longitude
-                </label>
-              </div>
-              <div class="col">
-                <input type="text" class="form-control" name="longitude" [(ngModel)]="longitude" required>
-              </div>
-            </div>
-
-            <button type="button"
-                    class="btn btn-primary float-right"
-                    (click)="onApply()">Apply</button>
-
-          </form>
-          {{zoom}}
-        </div>
-
-      </div>
     </div>
-
   </mat-card-content>
 </mat-card>
 

+ 106 - 142
src/app/vtt-trace/vtt-trace/vtt-trace.component.ts

@@ -1,5 +1,8 @@
-import {Component, OnInit} from '@angular/core';
-import {geoJSON, GeoJSON, icon, LatLng, latLng, map, marker, polyline, tileLayer} from 'leaflet';
+import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
+import {
+  geoJSON, GeoJSON, icon, LatLng, latLng, Map, point, marker, polyline, tileLayer,
+  LatLngBoundsExpression, latLngBounds
+} from 'leaflet';
 import {VttTraceWsService} from './vtt-trace-ws.service';
 import {Feature, LineString, MultiLineString, Point} from 'geojson';
 import {VttTraceFormNewTraceComponent} from './vtt-trace.formNewTraceComponent';
@@ -20,6 +23,12 @@ import {VttTraceFormNewTraceComponent} from './vtt-trace.formNewTraceComponent';
 })
 
 export class VttTraceComponent implements OnInit {
+  map: Map;
+  zoom: number;
+  center: LatLng;
+  latitude: number;
+  longitude: number;
+
   // Open Street Map and Open Cycle Map definitions
   LAYER_OCM = {
     id: 'opencyclemap',
@@ -45,19 +54,10 @@ export class VttTraceComponent implements OnInit {
     name: 'Geo JSON Polygon',
     enabled: true,
     layer: geoJSON(
-      ({
-        type: 'Polygon',
-        coordinates: [[
-          [-121.6, 46.87],
-          [-121.5, 46.87],
-          [-121.5, 46.93],
-          [-121.6, 46.87]
-        ]]
-      }) as any,
+      null,
       {style: () => ({color: '#ff7800'})})
   };
 
-
   // Values to bind to Leaflet Directive
   layersControlOptions = {position: 'bottomright'};
   layersControl = {
@@ -66,7 +66,7 @@ export class VttTraceComponent implements OnInit {
       'Open Cycle Map': this.LAYER_OCM.layer
     },
     overlays: {
-      GeoJSON: this.geoJSON.layer
+      'GeoJSON': this.geoJSON.layer
     }
   };
 
@@ -90,21 +90,8 @@ export class VttTraceComponent implements OnInit {
     center: [46, 2]
   };
 
-  // Fields for managing the form inputs and binding to leaflet zoom/center
-  /*
-    model = new LeafletCoreDemoModel(
-      this.optionsSpec.center[0],
-      this.optionsSpec.center[1],
-      this.optionsSpec.zoom
-    );
-  */
-  zoom: number;
-  center: LatLng;
-  latitude: number;
-  longitude: number;
-  zoomLevels: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
-
 
+  // Définitions des layers et options bindés en input avec la map et initialisés avec le contenu de la structure optionSpec
   layers = [];
   options = {
     layers: this.optionsSpec.layers.map((l) => {
@@ -116,126 +103,103 @@ export class VttTraceComponent implements OnInit {
 
   featuresCollection: Array<GeoJSON.Feature<Point>> = [];
 
-  onApply() {
-    this.zoom = this.zoom;
-    this.center = latLng(this.latitude, this.longitude);
-
-    return false;
-  }
-
-  constructor(private vttTraceWs: VttTraceWsService) {
-  }
-
-  ngOnInit() {
-    this.getMarkersObs();
-    // this.layers.push(newMarker); = L.geoJSON().addTo(map);
-    this.addRoute6();
-  }
-
-  private getMarkersObs() {
-    this.vttTraceWs.gettVttRandosDescFromServerObs()
-      .subscribe((response: Array<string>) => {
-        response.forEach(x => {
-          const json = JSON.parse(x);
-          this.addMarker(json);
-          this.featuresCollection.push(json);
-        });
-      });
-  }
+ constructor(private vttTraceWs: VttTraceWsService, private changeDetector: ChangeDetectorRef) {}
 
-  addMarker(feature: Feature<Point>) {
-    const newMarker = marker(
-      [feature.geometry.coordinates[0], feature.geometry.coordinates[1]],
-      {
-        icon: icon({
-          iconSize: [25, 41],
-          iconAnchor: [13, 41],
-          iconUrl: 'assets/marker-icon.png',
-          shadowUrl: 'assets/marker-shadow.png',
-        }),
-        title: '' + feature.properties.fichier
-      }
-    );
-
-    console.log(feature.properties.fichier);
-    // console.log('here' + this);
-    newMarker.bindPopup(feature.properties.name).openPopup();
-    // newMarker.on('click', this.markerOnClick, newMarker);
-    newMarker.on('click', this.markerOnClick, this);
-    this.layers.push(newMarker);
-  }
-
-  markerOnClick(e) {
-    console.log(e.sourceTarget._latlng);
-    const attributes = e.sourceTarget.options;
-    console.log(attributes.title);
-    // do some stuff…
-    // this.addTrace('' + attributes.title);
-    console.log(attributes);
-    this.onApply();
-
-    this.addTrace(attributes.title);
-    this.centerAndZoom(e.sourceTarget._latlng.lat, e.sourceTarget._latlng.lng, 9);
-
-    return true;
-  }
+  ngOnInit(): void {
+  this.getMarkersObs();
+  console.log(this.options);
+  console.log(this.geoJSON);
+  console.log(this.layers);
+  console.log(this.layersControl);
+  console.log(this.layersControlOptions);
+}
 
-  /**
-   * ajout d'une trace à la map, dans le tableau de layers
-   *
-   * TODO: reset layer fonctionne mais doit imérativement avoir réussi à charger la trace demandée avant de tout éffacer
-   * autrement la carte se retrouve vide this.resetLayers();
-   * How to refresh automaticaly the map???
-   * this._onResize();
-   * this.geoJSON.layer.addEventParent(geoJSON.);
-   * @param {string} fileName
-   * @returns {boolean}
-   */
-  addTrace(fileName: string) {
+  // TODO: à voir si utile et pe l'utiliser avec onMapReady
+  // pour obtenir qqch de plus propre et mieux initialisé?
+  onMapReady(map: Map): void {
+  this.map = map;
+}
 
-    this.vttTraceWs.getTraceFromFile(fileName)
-      .subscribe(data => {
-        const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data;
-        console.log(this.geoJSON.layer.addData(featureCollection.features[0].geometry));
+  private getMarkersObs(): void {
+  this.vttTraceWs.gettVttRandosDescFromServerObs()
+    .subscribe((response: Array<string>) => {
+      response.forEach(x => {
+        const json = JSON.parse(x);
+        this.addMarker(json);
+        this.featuresCollection.push(json);
       });
-    return true;
-  }
-
-  centerAndZoom(lat, lng, zoom) {
-    this.zoom = zoom;
-    this.center = latLng(lat, lng);
-    this.zoom = 9;
-    this.latitude = lat;
-    this.longitude = lng;
-
-    return false;
-  }
-
-  addRoute6() {
-    this.vttTraceWs.getMockRoute6()
-      .subscribe(data => {
-        console.log(data);
-        const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data;
-        const g = featureCollection.features[0].geometry.coordinates;
-        console.log(featureCollection.features[0].geometry.coordinates[0]);
-        this.layers.push(polyline(GeoJSON.coordsToLatLngs(g, 1)));
+    });
+}
+
+  addMarker(feature: Feature<Point>): void {
+  const newMarker = marker(
+    [feature.geometry.coordinates[0], feature.geometry.coordinates[1]],
+    {
+      icon: icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: 'assets/marker-icon.png',
+        shadowUrl: 'assets/marker-shadow.png',
+        popupAnchor: [0, -45] // point from which the popup should open relative to the iconAnchor
+      }),
+      title: '' + feature.properties.fichier
+    }
+  );
+
+  console.log(feature.properties.fichier);
+  newMarker.bindPopup(feature.properties.name).openPopup();
+  newMarker.on('click', this.markerOnClick, this);
+  this.layers.push(newMarker);
+}
+
+  markerOnClick(e): boolean {
+  const attributes = e.sourceTarget.options;
+
+  this.addTrace(attributes.title);
+  // TODO utiliser plutôt une méthode fitBounds afin de zoomer au niveau le plus fin autour de la trace
+  //this.centerAndZoom(e.sourceTarget._latlng.lat, e.sourceTarget._latlng.lng, 9);
+
+  // But, it will if we tell Angular to detect changes
+  // See doc API on zone changes: https://github.com/Asymmetrik/ngx-leaflet#api
+  this.changeDetector.detectChanges();
+
+  return true;
+}
+
+  /**
+ * ajout d'une trace à la map, dans le tableau de layers
+ *
+ * TODO: reset layer fonctionne mais doit impérativement avoir réussi à charger la trace demandée avant de tout éffacer
+ * autrement la carte se retrouve vide this.resetLayers();
+ * How to refresh automaticaly the map???
+ * this._onResize();
+ * this.geoJSON.layer.addEventParent(geoJSON.);
+ * @param {string} fileName
+ * @returns {boolean}
+ */
+addTrace(fileName: string): boolean {
+
+  console.log(this.geoJSON.layer)
+  this.geoJSON.layer.clearLayers();
+
+  this.vttTraceWs.getTraceFromFile(fileName)
+    .subscribe(data => {
+      const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data;
+      this.geoJSON.layer.addData(featureCollection.features[0].geometry)
+      //console.log(`featureCollection: ${featureCollection}`);
+      console.log(featureCollection.features[0].geometry.coordinates);
+
+      var coords: number[][]= featureCollection.features[0].geometry.coordinates as number[][];
+      var latlngs = coords.map(x => latLng(x[1], x[0]))
+      // console.log(latlngs);
+      this.map.fitBounds(latLngBounds(latlngs), {
+        padding: point(24, 24),
+        maxZoom: 12,
+        animate: true
       });
-  }
-
-  resetLayers () {
-    console.log('Resetting layers');
-    // console.log(`Here\'s the counter: ${this.counter}`);
-    this.layers = [];
-  }
-
-
-  /*  private showRoute() {
-        this.fitBounds(this.layers.getBounds(), {
-          padding: point(24, 24),
-          maxZoom: 12,
-          animate: true
-        });
-    }*/
+    });
+  return true;
+}
 
 }
 

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 6072 - 5
src/assets/2017-04-16_BormesMimosa.json


+ 2 - 3
src/assets/2018-05-09_PlanDelaTour.json

@@ -18,8 +18,8 @@
         "type": null
       },
       "geometry": {
-        "type": "MultiLineString",
-        "coordinates": [
+        "type": "LineString",
+        "coordinates":
           [
             [
               6.52412,
@@ -746,7 +746,6 @@
               43.272528333333
             ]
           ]
-        ]
       }
     }
   ]