namazu-ts 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.js +31375 -6214
- package/dist/client.d.ts +6 -2
- package/dist/node/index.js +29591 -4427
- package/dist/sismomap.d.ts +13 -0
- package/dist/types.d.ts +83 -0
- package/docs/assets/icons.js +1 -1
- package/docs/assets/icons.svg +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Client.html +7 -3
- package/docs/classes/SismoMap.html +11 -5
- package/docs/functions/EventToEventGeoJSON.html +1 -1
- package/docs/functions/createMap.html +1 -1
- package/docs/index.html +2 -1
- package/docs/modules.html +1 -1
- package/docs/types/EventPhases.html +1 -0
- package/docs/types/GeoJSON.html +1 -0
- package/docs/types/InfosPhase.html +14 -0
- package/docs/types/Station.html +3 -0
- package/docs/types/StationGeoJSON.html +3 -0
- package/docs/types/StationPhases.html +1 -0
- package/docs/types/Zone.html +3 -0
- package/docs/types/Zones.html +3 -0
- package/docs/variables/ZoneNames.html +1 -0
- package/docs/variables/eventTypes.html +1 -1
- package/package.json +11 -7
- package/src/client.ts +62 -1
- package/src/maputils.ts +32 -38
- package/src/sismomap.ts +281 -46
- package/src/types.ts +98 -0
package/src/maputils.ts
CHANGED
|
@@ -2,13 +2,7 @@ import maplibregl from 'maplibre-gl';
|
|
|
2
2
|
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
3
3
|
import geojson from 'geojson';
|
|
4
4
|
import { SismoMap } from './sismomap';
|
|
5
|
-
import {
|
|
6
|
-
SisEvent,
|
|
7
|
-
EventFeature,
|
|
8
|
-
EventGeoJSON,
|
|
9
|
-
EventGeojsonDescriptionProperty,
|
|
10
|
-
mapLayers,
|
|
11
|
-
} from './types';
|
|
5
|
+
import { SisEvent, EventFeature, EventGeoJSON } from './types';
|
|
12
6
|
import { isEventGeoJSONProperties } from './utils';
|
|
13
7
|
|
|
14
8
|
/**
|
|
@@ -34,6 +28,8 @@ export async function createMap(
|
|
|
34
28
|
container: containerID,
|
|
35
29
|
style: style,
|
|
36
30
|
center: [0, 0],
|
|
31
|
+
canvasContextAttributes: { antialias: true },
|
|
32
|
+
maxPitch: 60,
|
|
37
33
|
zoom: 1, // Low value at the start so we get a "zoom in" animation when loading
|
|
38
34
|
attributionControl: false,
|
|
39
35
|
});
|
|
@@ -47,11 +43,14 @@ export async function createMap(
|
|
|
47
43
|
|
|
48
44
|
// We use a promise so that people won't use the map before it's fully
|
|
49
45
|
return new Promise<SismoMap>((resolve) => {
|
|
50
|
-
map.once('load', () => {
|
|
46
|
+
smap.map.once('load', () => {
|
|
47
|
+
// We remove these two layers because they're cluttering the visuals
|
|
48
|
+
smap.map.removeLayer('ferry');
|
|
49
|
+
smap.map.removeLayer('boundary_2_maritime');
|
|
51
50
|
// We use that to have a flat map when zooming
|
|
52
51
|
// 5 is the value chosen because it covers all the zones of renass.unistra.franceseisme
|
|
53
52
|
// feel free to change to your liking if needed
|
|
54
|
-
map.setProjection({
|
|
53
|
+
smap.map.setProjection({
|
|
55
54
|
type: ['step', ['zoom'], 'vertical-perspective', 5, 'mercator'],
|
|
56
55
|
});
|
|
57
56
|
|
|
@@ -59,39 +58,34 @@ export async function createMap(
|
|
|
59
58
|
map.fitBounds(bounds);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
)
|
|
61
|
+
let titles = ['event-layer', 'station-layer'];
|
|
62
|
+
titles.forEach((title) => {
|
|
63
|
+
smap.map.on('mouseenter', title, (e) => {
|
|
64
|
+
smap.map.getCanvas().style.cursor = 'pointer';
|
|
65
|
+
if (e.features == undefined) return;
|
|
66
|
+
if (
|
|
67
|
+
!isEventGeoJSONProperties(
|
|
68
|
+
e.features[0].properties as any
|
|
71
69
|
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
);
|
|
76
|
-
console.log(text);
|
|
70
|
+
)
|
|
71
|
+
return;
|
|
72
|
+
let text = JSON.parse(e.features[0].properties.description);
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
// Pretty ugly but as we know, it'll always be a point, we can do it like this
|
|
75
|
+
const feature = e
|
|
76
|
+
.features![0] as geojson.Feature<geojson.Point>;
|
|
77
|
+
const [lng, lat] = feature.geometry.coordinates;
|
|
82
78
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
79
|
+
descPopup
|
|
80
|
+
.setLngLat([lng, lat])
|
|
81
|
+
.setHTML(text[lang])
|
|
82
|
+
.addTo(smap.map);
|
|
83
|
+
});
|
|
84
|
+
smap.map.on('mouseleave', title, () => {
|
|
85
|
+
descPopup.remove();
|
|
86
|
+
smap.map.getCanvas().style.cursor = '';
|
|
87
|
+
});
|
|
93
88
|
});
|
|
94
|
-
|
|
95
89
|
resolve(smap);
|
|
96
90
|
});
|
|
97
91
|
});
|
package/src/sismomap.ts
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import maplibregl from 'maplibre-gl';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
EventGeoJSON,
|
|
4
|
+
EventPhases,
|
|
5
|
+
SisEvent,
|
|
6
|
+
GeoJSON,
|
|
7
|
+
Station,
|
|
8
|
+
StationGeoJSON,
|
|
9
|
+
InfosPhase,
|
|
10
|
+
StationPhases,
|
|
11
|
+
} from './types';
|
|
12
|
+
import { isEventGeoJSON } from './utils';
|
|
13
|
+
import { Client } from './client';
|
|
4
14
|
import { bbox } from '@turf/turf';
|
|
5
15
|
import { EventToEventGeoJSON } from './maputils';
|
|
16
|
+
import { ok, err, Result } from 'neverthrow';
|
|
17
|
+
import * as THREE from 'three';
|
|
18
|
+
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
19
|
+
import * as MTP from '@dvt3d/maplibre-three-plugin';
|
|
6
20
|
|
|
7
21
|
export class SismoMap {
|
|
8
22
|
name: string;
|
|
9
23
|
map: maplibregl.Map;
|
|
10
24
|
descPopup: maplibregl.Popup;
|
|
11
|
-
|
|
25
|
+
_layers: string[];
|
|
26
|
+
_sources: string[];
|
|
27
|
+
_mapscene: MTP.MapScene;
|
|
12
28
|
/**
|
|
13
29
|
* Not meant to use, use createMap instead
|
|
14
30
|
*/
|
|
@@ -20,22 +36,149 @@ export class SismoMap {
|
|
|
20
36
|
this.name = name;
|
|
21
37
|
this.map = map;
|
|
22
38
|
this.descPopup = descPopup;
|
|
39
|
+
this._layers = [];
|
|
40
|
+
this._sources = [];
|
|
41
|
+
this._mapscene = new MTP.MapScene(this.map as any);
|
|
42
|
+
|
|
43
|
+
this._mapscene.addLight(new THREE.AmbientLight(0xffffff, 0.8));
|
|
23
44
|
}
|
|
24
45
|
|
|
25
46
|
/**
|
|
26
47
|
* Removes all user-made layers
|
|
27
48
|
*/
|
|
28
49
|
clear() {
|
|
29
|
-
|
|
30
|
-
if (this.map.getLayer(
|
|
31
|
-
this.map.removeLayer(
|
|
50
|
+
this._layers.forEach((layer: string) => {
|
|
51
|
+
if (this.map.getLayer(layer)) {
|
|
52
|
+
this.map.removeLayer(layer);
|
|
32
53
|
}
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this._sources.forEach((source: string) => {
|
|
57
|
+
if (this.map.getSource(source)) {
|
|
58
|
+
this.map.removeSource(source);
|
|
35
59
|
}
|
|
36
60
|
});
|
|
37
61
|
}
|
|
38
62
|
|
|
63
|
+
async displayStations(
|
|
64
|
+
client: Client,
|
|
65
|
+
event: SisEvent | EventGeoJSON,
|
|
66
|
+
moveView: boolean = true,
|
|
67
|
+
clear: boolean = true,
|
|
68
|
+
stationOnly: boolean = false,
|
|
69
|
+
model3D: boolean = true
|
|
70
|
+
) {
|
|
71
|
+
let eventGeo: EventGeoJSON;
|
|
72
|
+
// Type guard to distincting the overloading cases
|
|
73
|
+
if (isEventGeoJSON(event)) {
|
|
74
|
+
eventGeo = event;
|
|
75
|
+
} else {
|
|
76
|
+
eventGeo = EventToEventGeoJSON(event);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (eventGeo.features.length != 1) {
|
|
80
|
+
return Promise.reject(
|
|
81
|
+
Error(
|
|
82
|
+
'If passing a EventGeoJSON, it should only have one feature'
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!stationOnly) this.displayEvents(eventGeo, false, clear);
|
|
88
|
+
|
|
89
|
+
// I put the await later because it doesn't have dependencies when creating the station,string map
|
|
90
|
+
let phasesPromise = client.getEventPhases(eventGeo);
|
|
91
|
+
let zone = await client.getZoneNameByEvent(eventGeo);
|
|
92
|
+
let stationList = await client.getStationsByZoneName(zone);
|
|
93
|
+
|
|
94
|
+
// We create a map with the stations so our search is o(1) with just a o(n) to create the map
|
|
95
|
+
let stationsMap: Map<string, StationPhases> = new Map<
|
|
96
|
+
string,
|
|
97
|
+
StationPhases
|
|
98
|
+
>();
|
|
99
|
+
stationList.features.forEach((station: Station) => {
|
|
100
|
+
let stationPhase: StationPhases = station as StationPhases;
|
|
101
|
+
stationPhase.properties.phases = [];
|
|
102
|
+
stationsMap.set(stationPhase.properties.stationcode, stationPhase);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
let phases: EventPhases = await phasesPromise;
|
|
106
|
+
let absentStations: InfosPhase[] = [];
|
|
107
|
+
let stationsGeoJSON: StationGeoJSON = {
|
|
108
|
+
type: 'FeatureCollection',
|
|
109
|
+
features: [],
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
phases.forEach((phase: InfosPhase) => {
|
|
113
|
+
let station = stationsMap.get(phase.stationCode);
|
|
114
|
+
if (station == undefined) {
|
|
115
|
+
absentStations.push(phase);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
station?.properties.phases.push(phase);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
stationsMap.forEach((station) => {
|
|
122
|
+
if (station.properties.phases.length == 0) return;
|
|
123
|
+
station.properties.description = {
|
|
124
|
+
fr: station.properties.stationcode,
|
|
125
|
+
en: station.properties.stationcode,
|
|
126
|
+
};
|
|
127
|
+
stationsGeoJSON.features.push(station);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
console.log('Absent stations : ');
|
|
131
|
+
console.log(absentStations);
|
|
132
|
+
|
|
133
|
+
if (model3D) {
|
|
134
|
+
stationsGeoJSON.features.forEach((station: StationPhases) => {
|
|
135
|
+
this.addStation(station.geometry.coordinates);
|
|
136
|
+
});
|
|
137
|
+
if (moveView) {
|
|
138
|
+
this.centerView(stationsGeoJSON);
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
const svgImage = new Image(20, 20);
|
|
142
|
+
const triangleSVG = `
|
|
143
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
|
144
|
+
<polygon points="12,2 22,22 2,22" fill="blue" />
|
|
145
|
+
</svg>`;
|
|
146
|
+
|
|
147
|
+
const encodedSVG = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(triangleSVG)}`;
|
|
148
|
+
|
|
149
|
+
svgImage.src = encodedSVG;
|
|
150
|
+
|
|
151
|
+
svgImage.onload = () => {
|
|
152
|
+
this.map.addImage('triangle', svgImage);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let layerSpec: maplibregl.AddLayerObject = {
|
|
156
|
+
id: 'station-layer',
|
|
157
|
+
source: 'stat',
|
|
158
|
+
|
|
159
|
+
type: 'symbol',
|
|
160
|
+
layout: {
|
|
161
|
+
'icon-image': 'triangle',
|
|
162
|
+
'icon-allow-overlap': true,
|
|
163
|
+
'icon-size': 0.8,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
this.displayGeoJSON(
|
|
169
|
+
stationsGeoJSON,
|
|
170
|
+
'stat',
|
|
171
|
+
layerSpec,
|
|
172
|
+
moveView,
|
|
173
|
+
false
|
|
174
|
+
).isErr()
|
|
175
|
+
)
|
|
176
|
+
return Promise.reject();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return Promise.resolve();
|
|
180
|
+
}
|
|
181
|
+
|
|
39
182
|
/**
|
|
40
183
|
* @param eventOrList Can either be a single Event (via /events API) or a FDSN GeoJSON
|
|
41
184
|
* @param moveView True = The view moves on the events' bounding box while displaying (does not affect user's possible behaviour on the map)
|
|
@@ -48,21 +191,144 @@ export class SismoMap {
|
|
|
48
191
|
) {
|
|
49
192
|
let eventList: EventGeoJSON;
|
|
50
193
|
|
|
51
|
-
// Type guard to
|
|
194
|
+
// Type guard to distincting the overloading cases
|
|
52
195
|
if (isEventGeoJSON(eventOrList)) {
|
|
53
196
|
eventList = eventOrList;
|
|
54
197
|
} else {
|
|
55
198
|
eventList = EventToEventGeoJSON(eventOrList as SisEvent);
|
|
56
199
|
}
|
|
200
|
+
let layerSpec: maplibregl.AddLayerObject = {
|
|
201
|
+
id: 'event-layer',
|
|
202
|
+
source: 'src',
|
|
203
|
+
type: 'circle',
|
|
204
|
+
paint: {
|
|
205
|
+
// Inspired by https://renass.unistra.fr/js/events.js
|
|
206
|
+
'circle-radius': ['*', 8, ['ln', ['+', 1, ['get', 'mag']]]],
|
|
207
|
+
'circle-color': '#B42222',
|
|
208
|
+
'circle-opacity': 0.8,
|
|
209
|
+
'circle-stroke-width': 1,
|
|
210
|
+
'circle-stroke-opacity': 0.9,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
this.displayGeoJSON(eventList, 'src', layerSpec, moveView, clear);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Updates a source by appending new data
|
|
218
|
+
// Take care to add the good type, dangerous function and should be
|
|
219
|
+
private updateSource(sourceName: string, newData: GeoJSON) {
|
|
220
|
+
let source: maplibregl.GeoJSONSource | undefined =
|
|
221
|
+
this.map.getSource(sourceName);
|
|
222
|
+
let data = source?._data.geojson;
|
|
223
|
+
if (data === undefined) return;
|
|
224
|
+
let geojson: GeoJSON = data as GeoJSON;
|
|
225
|
+
|
|
226
|
+
geojson.features = (geojson.features as any).concat(newData.features);
|
|
227
|
+
source?.setData(geojson as any); // It's good but can't do better as stated in line 104
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private centerView(geojson: GeoJSON) {
|
|
231
|
+
if (geojson.features.length == 1) {
|
|
232
|
+
let lng: number = geojson.features[0].geometry.coordinates[0];
|
|
233
|
+
let lat: number = geojson.features[0].geometry.coordinates[1];
|
|
234
|
+
this.map.flyTo({ center: [lng, lat], zoom: 6 });
|
|
235
|
+
} else {
|
|
236
|
+
// Inter-library operability is annoying, this line will always work with the types i'll give it
|
|
237
|
+
// but i'm sorry for the double cast as any, can't do better :(
|
|
238
|
+
let bounds = bbox(geojson as any);
|
|
239
|
+
let margin = [-0.5, -0.5, 0.5, 0.5];
|
|
240
|
+
for (let i = 0; i < 4; i++) {
|
|
241
|
+
bounds[i] += margin[i];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.map.fitBounds(bounds as any);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private displayGeoJSON(
|
|
249
|
+
geojson: GeoJSON,
|
|
250
|
+
sourceName: string,
|
|
251
|
+
layerSpec: maplibregl.AddLayerObject,
|
|
252
|
+
moveView: boolean,
|
|
253
|
+
clear: boolean
|
|
254
|
+
): Result<null, Error> {
|
|
255
|
+
if (geojson.features.length == 0) return ok(null);
|
|
57
256
|
|
|
58
257
|
if (clear) {
|
|
59
258
|
this.clear();
|
|
259
|
+
this.map.addSource(sourceName, {
|
|
260
|
+
type: 'geojson',
|
|
261
|
+
data: geojson as any,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
this.map.addLayer(layerSpec);
|
|
265
|
+
} else if (!clear && !this.map.getSource(sourceName)) {
|
|
266
|
+
this.map.addSource(sourceName, {
|
|
267
|
+
type: 'geojson',
|
|
268
|
+
data: geojson as any,
|
|
269
|
+
});
|
|
270
|
+
this.map.addLayer(layerSpec);
|
|
271
|
+
} else {
|
|
272
|
+
this.updateSource(sourceName, geojson);
|
|
273
|
+
}
|
|
274
|
+
if (moveView) {
|
|
275
|
+
this.centerView(geojson);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
this._sources.push(sourceName);
|
|
279
|
+
this._layers.push(layerSpec.id);
|
|
280
|
+
|
|
281
|
+
return ok(null);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private addStation(coord: number[]) {
|
|
285
|
+
const geometry = new THREE.ConeGeometry(50, 100, 3);
|
|
286
|
+
const material = new THREE.MeshPhongMaterial({
|
|
287
|
+
color: 0x0000ff,
|
|
288
|
+
shininess: 100,
|
|
289
|
+
side: THREE.DoubleSide,
|
|
290
|
+
});
|
|
291
|
+
let cone = new THREE.Mesh(geometry, material);
|
|
292
|
+
|
|
293
|
+
cone = cone.rotateX(THREE.MathUtils.degToRad(90));
|
|
294
|
+
cone.scale.set(50, 50, 50);
|
|
295
|
+
cone.position.y = 50;
|
|
296
|
+
|
|
297
|
+
const scale = MTP.SceneTransform.projectedUnitsPerMeter(48.58);
|
|
298
|
+
const rtcGroup = MTP.Creator.createRTCGroup(
|
|
299
|
+
coord,
|
|
300
|
+
[0, 0, 0],
|
|
301
|
+
[scale, scale, scale]
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
rtcGroup.add(cone);
|
|
305
|
+
this._mapscene.addObject(rtcGroup);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getEventNumber(): Result<number, Error> {
|
|
309
|
+
let source = this.getSourceGeoJSON();
|
|
310
|
+
let length = 0;
|
|
311
|
+
if (source.isErr()) return err(source.error);
|
|
312
|
+
source.map((s: EventGeoJSON) => {
|
|
313
|
+
length = s.features.length;
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
return ok(length);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
getSourceGeoJSON(): Result<EventGeoJSON, Error> {
|
|
320
|
+
let source: maplibregl.GeoJSONSource | undefined =
|
|
321
|
+
this.map.getSource('src');
|
|
322
|
+
let data = source?._data.geojson;
|
|
323
|
+
if (data === undefined) {
|
|
324
|
+
return err(Error('Source not defined yet'));
|
|
60
325
|
}
|
|
61
|
-
|
|
326
|
+
return ok(data as EventGeoJSON);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
62
329
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let eventType: string;
|
|
330
|
+
/*
|
|
331
|
+
let eventType: string;
|
|
66
332
|
let typeName: string;
|
|
67
333
|
if (!isEventGeoJSONProperties(feature.properties)) {
|
|
68
334
|
eventType = feature.properties.eventType;
|
|
@@ -73,36 +339,5 @@ export class SismoMap {
|
|
|
73
339
|
}
|
|
74
340
|
let layerName = eventType == null ? 'event' : eventType;
|
|
75
341
|
if (this.map.getLayer(layerName)) return;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
source: 'src',
|
|
79
|
-
type: 'circle',
|
|
80
|
-
paint: {
|
|
81
|
-
// Inspired by https://renass.unistra.fr/js/events.js
|
|
82
|
-
'circle-radius': ['*', 8, ['ln', ['+', 1, ['get', 'mag']]]],
|
|
83
|
-
'circle-color': '#B42222',
|
|
84
|
-
'circle-opacity': 0.8,
|
|
85
|
-
'circle-stroke-width': 1,
|
|
86
|
-
'circle-stroke-opacity': 0.9,
|
|
87
|
-
},
|
|
88
|
-
filter: ['==', eventType, ['get', typeName]],
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
if (moveView) {
|
|
92
|
-
if (eventList.features.length == 1) {
|
|
93
|
-
let lng: number = eventList.features[0].geometry.coordinates[0];
|
|
94
|
-
let lat: number = eventList.features[0].geometry.coordinates[1];
|
|
95
|
-
this.map.flyTo({ center: [lng, lat], zoom: 6 });
|
|
96
|
-
} else {
|
|
97
|
-
// Inter-library operability is annoying, this line will always work with the types i'll give it
|
|
98
|
-
let bounds = bbox(eventList as any);
|
|
99
|
-
let margin = [-0.5, -0.5, 0.5, 0.5];
|
|
100
|
-
for (let i = 0; i < 4; i++) {
|
|
101
|
-
bounds[i] += margin[i];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.map.fitBounds(bounds as any);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
342
|
+
|
|
343
|
+
*/
|
package/src/types.ts
CHANGED
|
@@ -235,3 +235,101 @@ export type Form = {
|
|
|
235
235
|
groups: QuestionGroup[];
|
|
236
236
|
questions: Question[];
|
|
237
237
|
};
|
|
238
|
+
|
|
239
|
+
export type InfosPhase = {
|
|
240
|
+
time: Date;
|
|
241
|
+
automatic: boolean;
|
|
242
|
+
distance: number;
|
|
243
|
+
azimuth: number;
|
|
244
|
+
arrivalID: number;
|
|
245
|
+
channelCode: string;
|
|
246
|
+
locationCode: string;
|
|
247
|
+
networkCode: string;
|
|
248
|
+
originID: number;
|
|
249
|
+
phaseCode: string;
|
|
250
|
+
pickID: number;
|
|
251
|
+
stationCode: string;
|
|
252
|
+
timeResidual: Date;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export type EventPhases = InfosPhase[];
|
|
256
|
+
|
|
257
|
+
export type Station = {
|
|
258
|
+
properties: {
|
|
259
|
+
networkcode: string;
|
|
260
|
+
networkcolor: string;
|
|
261
|
+
stationcode: string;
|
|
262
|
+
};
|
|
263
|
+
geometry: {
|
|
264
|
+
coordinates: number[];
|
|
265
|
+
crs: {
|
|
266
|
+
properties: {
|
|
267
|
+
name: string;
|
|
268
|
+
};
|
|
269
|
+
type: string;
|
|
270
|
+
};
|
|
271
|
+
type: string;
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export type StationPhases = Station & {
|
|
276
|
+
properties: {
|
|
277
|
+
phases: EventPhases;
|
|
278
|
+
description: {
|
|
279
|
+
en: string;
|
|
280
|
+
fr: string;
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export type StationGeoJSON = {
|
|
286
|
+
type: string;
|
|
287
|
+
features: StationPhases[];
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export const ZoneNames = [
|
|
291
|
+
'la-reunion',
|
|
292
|
+
'france',
|
|
293
|
+
'mayotte',
|
|
294
|
+
'monde',
|
|
295
|
+
'les-antilles',
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
export type Zones = {
|
|
299
|
+
type: string;
|
|
300
|
+
features: Zone[];
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
export type Zone = {
|
|
304
|
+
properties: {
|
|
305
|
+
name: string;
|
|
306
|
+
buffer: number;
|
|
307
|
+
minimal_longitude: number;
|
|
308
|
+
maximal_longitude: number;
|
|
309
|
+
minimal_latitude: number;
|
|
310
|
+
maximal_latitude: number;
|
|
311
|
+
automatic_maximal_depth: number;
|
|
312
|
+
automatic_minimal_magnitude: number;
|
|
313
|
+
automatic_minimal_used_phase_count: number;
|
|
314
|
+
city_form_id: number;
|
|
315
|
+
individual_form_id: number;
|
|
316
|
+
manual_event_types: string[];
|
|
317
|
+
manual_maximal_depth: number;
|
|
318
|
+
manual_minimal_magnitude: number;
|
|
319
|
+
manual_minimal_used_phase_count: number;
|
|
320
|
+
show_automatic: boolean;
|
|
321
|
+
show_manual: boolean;
|
|
322
|
+
};
|
|
323
|
+
geometry: {
|
|
324
|
+
coordinates: number[][][][];
|
|
325
|
+
crs: {
|
|
326
|
+
properties: {
|
|
327
|
+
name: string;
|
|
328
|
+
};
|
|
329
|
+
type: string;
|
|
330
|
+
};
|
|
331
|
+
type: string;
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
export type GeoJSON = EventGeoJSON | StationGeoJSON;
|