resource-download-item.component.ts 9.52 KB
Newer Older
1
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
import { communeInsee } from '../../../../../../assets/resources/commune-insee';
3
import { geosource } from '../../../../../../i18n/traductions';
4
import { IMetadataLink, linkFormats, Metadata } from '../../../../../shared/models';
5
6
import { Format, Projection, Resource } from '../../../../models';
import { DatasetDetailService } from '../../../../services';
7
8
9
10
11
12
13
14

@Component({
  selector: 'app-resource-download-item',
  templateUrl: './resource-download-item.component.html',
  styleUrls: ['./resource-download-item.component.scss']
})
export class ResourceDownloadItemComponent implements OnInit {

15
16
17
  linkFormats = linkFormats;

  @Input() format?: Format;
18
19
  @Input() resource?: Resource;
  @Input() projections?: Projection[];
20
  @Input() metadata?: Metadata;
21
  @Input() link: IMetadataLink;
22
23
  @Input() isQueryable: boolean;
  @Output() saveEvent = new EventEmitter();
24
  @Output() abortEvent = new EventEmitter();
25

26
  abortMessage: string = geosource.downloads.abort;
27
  downloadMessage: string = geosource.downloads.download;
28

29
  _queryableUrl = '';
30

31
32
  isOptionOpen = false;

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  projectionList;
  // Dropdown projection
  dropDownProjectionToggle: false;
  selectedProjection: {
    name: '',
    bbox: any,
  };

  inseeLabel: string;
  // Dropdown insee
  dropDownInseeToggle: false;
  selectedInsee: {
    commune: '',
    insee: '',
  };
  communeInseeList = communeInsee;

50
51
52
53
54
55
56
57
58
59
60
61
  labelLayer = {
    WFS: 'typename',
    WMS: 'layers',
    WCS: 'identifiers',
  };

  labelFormat = {
    WFS: 'outputFormat',
    WMS: 'FORMAT',
    WCS: 'FORMAT',
  };

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  shpProjections = {
    'EPSG:4171': 'EPSG:4171',
    'EPSG:3946': 'EPSG:3946',
    'EPSG:2154': 'EPSG:2154',
    'EPSG:4326': 'EPSG:4326',
    'EPSG:4258': 'EPSG:4258',
  };

  queryableParameters = {
    baseUrl: '',
    baseParameters: '',
    layer: '',
    outputFormat: '',
    outputFormatActive: false,
    projection: '',
    projectionActive: false,
    bbox: '',
    insee: '',
    inseeActive: false,
    numberFeatures: false,
    fromFeature: false,
  };

  constructor(
    private _datasetDetailService: DatasetDetailService,
  ) { }
88
89

  ngOnInit() {
90
91
92
93
    this.initItems();
  }

  initItems() {
94
    // Get projections and set the default one (depending on the resource)
95
96
97
98
99
100
    if (this.resource) {

      this.projectionList = [];
      if (this.resource.type === linkFormats.wms) {
        this.projectionList = this.transformObjectToArray(this.resource.metadataLink.bbox_by_projection);
        this.selectedProjection = this.projectionList[0];
101
      } else if (this.resource.type === linkFormats.wfs && this.resource.metadataLink.projections) {
102
103
104
105
106
        this.resource.metadataLink.projections.forEach((key) => {
          this.projectionList.push({
            name: key,
            bbox: key,
          });
107
        });
108
109
110
111
112
113
114
115
116
        this.selectedProjection = this.projectionList[0];
      } else if (this.resource.type === linkFormats.wcs) {
        this.projectionList = this.transformObjectToArray(this.resource.metadataLink.bbox_by_projection);
        this.selectedProjection = this.projectionList[0];
      } else if (this.resource.type === linkFormats.ws) {
        this.projectionList = this.transformObjectToArray(this.shpProjections);
        this.selectedProjection = this.projectionList[0];
      }

117

118
119
      // Set the insee property label for this dataset
      if (this._datasetDetailService.datasetData[0]) {
120
121
122
123
124
        this.setInseeProperties();
      } else {
        this._datasetDetailService.sampleDataLoaded$.subscribe((data) => {
          this.setInseeProperties();
        });
125
126
127
      }

      this.setProjection(this.selectedProjection);
128
129
    }

130
  }
131
132
133
134
135
136
137
  setInseeProperties ()
  {
    const properties = Object.keys(this._datasetDetailService.datasetData[0].properties);
    this.inseeLabel = properties.find((prop) => { return prop.includes('insee'); });

    this.communeInseeList.sort((a, b) => (a.commune.localeCompare(b.commune)));
  }
138

139
140
141
142
  getFormatName() {
    return this.format ? this.format.name : this.link.formats[0];
  }

143
  get queryableUrl() {
144
145
146
147
148
149
150
151
152
153
154
    let queryableUrl = '';
    if (this.isQueryable) {
      queryableUrl = this.resource.metadataLink.url;
      let layer = '';
      let outputFormat = '';
      if (this.resource.isStandard) {
        layer = `&${this.labelLayer[this.resource.type]}=${this.resource.metadataLink.name}`;
        outputFormat = `&${this.labelFormat[this.resource.type]}=` +
          `${this.format.mapServerType}`;
        const projectionAndBbox = this.getProjectionAndBbox(this.format);

155
156
157
158
159
160
        if (Array.isArray(this.metadata.providers) && this.metadata.providers[0].match(/ATMO/g)) {
          if (this.format.mapServerType.match(/application\/json/)) {
            outputFormat = `&${this.labelFormat[this.resource.type]}=GEOJSON`;
          }
        }

161
162
163
164
165
166
        const baseParameters = this.resource.parametersUrl ? `?${this.resource.parametersUrl}` : '';
        queryableUrl += baseParameters +
          layer +
          outputFormat +
          projectionAndBbox.projection +
          projectionAndBbox.bboxRequest;
167
168
169
170
171
172
173
174
175
176

        // Set the dimension of the image based no the bbox aspect ratio
        if (this.resource.type === linkFormats.wms) {
          const width = 700;
          const longDiff = this.metadata.max_east - this.metadata.max_west;
          const latDiff = this.metadata.max_north - this.metadata.max_south;
          const ratio = longDiff / latDiff;
          const height = Math.round(width * ratio);
          queryableUrl += `&WIDTH=${width}&HEIGHT=${height}`;
        }
177
178
      } else if (this.resource.type === linkFormats.ws) {
        if (this.format.name === 'JSON') {
179
          queryableUrl += `/${this.resource.metadataLink.name}/all.json?maxfeatures=-1`;
180
        } else {
181
182
183
          const projectionAndBbox = this.getProjectionAndBbox(this.format);

          queryableUrl += `/${this.resource.metadataLink.name}.shp?${projectionAndBbox.projection}`;
184
        }
ext.sopra.ncastejon's avatar
ext.sopra.ncastejon committed
185
186
187
      } else if (this.resource.type === linkFormats.kml) {
        queryableUrl += `?${this.resource.parametersUrl}` +
          `&typename=${this.resource.metadataLink.name}`;
188
189
190
191
      }
    } else {
      queryableUrl = this.link.url;
    }
192
    queryableUrl += this.queryableParameters.insee;
193
    return queryableUrl;
194
  }
195

196
  get fileName() {
197
198
199
    return this.resource ? `${this.resource.metadataLink.name}.${this.format.fileExtension}` : this.link.name;
  }

200
201
202
203
204
205
206
207
208
209
210
211
  getProjectionLabel(name: string) {
    const projection = this.projections.find((projection) => {
      return projection.name === name;
    });
    return projection ? `${projection.commonName} (${projection.name})` : name;
  }

  // Set the selected projection and set the queryable parameters
  // depending on the resource
  setProjection(projection) {
    this.selectedProjection = projection;
    this.queryableParameters.projectionActive = true;
212
    // this.updateQueryableUrl();
213
214
215
216
217
  }

  // Set the selected insee and set the queryable parameters
  // depending on the resource
  setInsee(insee) {
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    this.selectedInsee = insee;
    if (!this.selectedInsee || !this.inseeLabel) {
      this.queryableParameters.insee = '';
    } else {
      if (this.resource.type === linkFormats.wfs) {
        this.queryableParameters.insee = '&filter=Filter=<Filter> <PropertyIsLike wildcard="*" ' +
          'singleChar=\'.\' escape=\'_\'> <PropertyName>' +
          `${this.inseeLabel}</PropertyName><Literal>${this.selectedInsee.insee}` +
          '</Literal></PropertyIsLike> </Filter>';
      } else if (this.resource.type === linkFormats.ws) {
        this.queryableParameters.baseUrl = this.resource.metadataLink.name.replace('\/all.json', '');
        const match = (/\/ws\/([^\/]+)/g).exec(this.resource.metadataLink.url);
        const serviceName = match[1] ? match[1] : '';
        this.queryableParameters.insee = `&mask_db=${serviceName}&mask_layer=adr_voie_lieu.adrcommune` +
          `&mask_field=insee&mask_value=${this.selectedInsee.insee}`;
      }
      this.queryableParameters.inseeActive = true;
    }

    this.updateQueryableUrl();
  }

241
242
243
  getProjectionAndBbox(format: Format) {
    let projection = '';
    let bboxRequest = '';
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    if (this.selectedProjection) {

      if (this.resource.type === linkFormats.wfs) {
        projection = `&SRSNAME=${this.selectedProjection.name}`;
      } else if (this.resource.type === linkFormats.wms || this.resource.type === linkFormats.wcs) {
        projection = `&CRS=${this.selectedProjection.name}`;
        const bbox = this.resource.metadataLink.bbox_by_projection[this.selectedProjection.name];
        bboxRequest = `&BBOX=${bbox.minx},` +
          `${bbox.miny},` +
          `${bbox.maxx},` +
          `${bbox.maxy}`;
      } else if (this.resource.type === linkFormats.ws) {
        if (format.name !== 'JSON') {
          projection = `srsname=${this.selectedProjection.name}`;
        }
259
260
261
262
263
264
265
      }
    }

    return {
      projection,
      bboxRequest,
    };
266
  }
267

268
269
270
  // When the user changes parameters (or when view init), we update the url provided
  // to the <a> link
  updateQueryableUrl() {
271
    this._queryableUrl = this.queryableParameters.baseUrl +
272
      this.queryableParameters.baseParameters;
273
    this._queryableUrl += this.queryableParameters.layer +
274
275
276
277
278
279
280
281
282
      this.queryableParameters.outputFormat +
      this.queryableParameters.insee +
      this.queryableParameters.projection +
      this.queryableParameters.bbox
      ;
  }

  transformObjectToArray(object) {
    const array = [];
283
284
285
286
287
288
289
290
291
292
    let keys;

    if (object) {
      keys = Object.keys(object);

      keys.forEach((key) => {
        array.push({
          name: key,
          bbox: object[key],
        });
293
      });
294
295
    }

296
297
298
    return array;
  }

299
}