@geode/opengeodeweb-front 10.40.1-rc.1 → 10.41.0-rc.2
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/.build/shared/utils/file.js +1 -1
- package/.build/shared/utils/response_handlers/load.js +19 -1
- package/app/components/MissingFilesSelector.vue +84 -11
- package/app/components/ObjectSelector.vue +147 -13
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +0 -1
- package/app/components/Viewer/Generic/Model/ComponentPointsOptions.vue +245 -0
- package/app/components/Viewer/Generic/Model/ModelPointsCard.vue +141 -0
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +7 -67
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +2 -40
- package/app/components/csv-preview/CsvSettings.vue +1 -1
- package/app/composables/model_menu_context.ts +101 -0
- package/app/utils/import_workflow.ts +13 -2
- package/internal/stores/data_style/model/blocks/index.ts +4 -0
- package/internal/stores/data_style/model/blocks/points.ts +51 -0
- package/internal/stores/data_style/model/index.ts +6 -0
- package/internal/stores/data_style/model/lines/index.ts +4 -0
- package/internal/stores/data_style/model/lines/points.ts +51 -0
- package/internal/stores/data_style/model/points/component.ts +423 -0
- package/internal/stores/data_style/model/points/size.ts +13 -1
- package/internal/stores/data_style/model/points/visibility.ts +13 -3
- package/internal/stores/data_style/model/surfaces/index.ts +4 -0
- package/internal/stores/data_style/model/surfaces/points.ts +51 -0
- package/internal/utils/upload_file.ts +1 -1
- package/package.json +1 -1
- package/shared/utils/file.ts +1 -1
- package/shared/utils/response_handlers/load.ts +37 -1
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
// oxlint-disable eslint/max-lines
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_NO_DATA_COLOR,
|
|
4
|
+
POINTS_DEFAULT_COLOR,
|
|
5
|
+
POINTS_DEFAULT_SIZE,
|
|
6
|
+
POINTS_DEFAULT_VISIBILITY,
|
|
7
|
+
type RGBAColor,
|
|
8
|
+
} from "@ogw_front/utils/default_styles/constants";
|
|
9
|
+
import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
|
|
10
|
+
import merge from "lodash/merge";
|
|
11
|
+
import { useAttributeTimeStepStyle } from "@ogw_internal/stores/data_style/time_step";
|
|
12
|
+
import { useDataStore } from "@ogw_front/stores/data";
|
|
13
|
+
import { useDataStyleState } from "@ogw_internal/stores/data_style/state";
|
|
14
|
+
import { useModelCommonStyle } from "@ogw_internal/stores/data_style/model/common";
|
|
15
|
+
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
16
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
17
|
+
|
|
18
|
+
// Points of corners are the corners themselves, so only these components get their own points style
|
|
19
|
+
const POINTS_COMPONENT_TYPES = ["Line", "Surface", "Block"] as const;
|
|
20
|
+
type PointsComponentType = (typeof POINTS_COMPONENT_TYPES)[number];
|
|
21
|
+
|
|
22
|
+
const modelSchemas = viewer_schemas.opengeodeweb_viewer.model;
|
|
23
|
+
const COMPONENT_TYPE_KEYS = {
|
|
24
|
+
Line: "lines",
|
|
25
|
+
Surface: "surfaces",
|
|
26
|
+
Block: "blocks",
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
type PointsSchemas =
|
|
30
|
+
(typeof modelSchemas)[(typeof COMPONENT_TYPE_KEYS)[PointsComponentType]]["points"];
|
|
31
|
+
type PointsRequestSchema =
|
|
32
|
+
| PointsSchemas["visibility"]
|
|
33
|
+
| PointsSchemas["size"]
|
|
34
|
+
| PointsSchemas["color"]
|
|
35
|
+
| PointsSchemas["attribute"]["vertex"]["attribute"];
|
|
36
|
+
|
|
37
|
+
function groupBy(componentIds: string[], key: (componentId: string) => string): string[][] {
|
|
38
|
+
const groups: Record<string, string[]> = {};
|
|
39
|
+
for (const componentId of componentIds) {
|
|
40
|
+
const groupKey = key(componentId);
|
|
41
|
+
groups[groupKey] ??= [];
|
|
42
|
+
groups[groupKey].push(componentId);
|
|
43
|
+
}
|
|
44
|
+
return Object.values(groups);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface AttributeStoredConfig {
|
|
48
|
+
minimum: number | undefined;
|
|
49
|
+
maximum: number | undefined;
|
|
50
|
+
colorMap: string | undefined;
|
|
51
|
+
no_data_color: RGBAColor;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface AttributeState {
|
|
55
|
+
name?: string;
|
|
56
|
+
item?: number;
|
|
57
|
+
storedConfigs?: Record<string, { lastItem: number } & Record<string, AttributeStoredConfig>>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface PointsStyle {
|
|
61
|
+
visibility?: boolean;
|
|
62
|
+
size?: number;
|
|
63
|
+
coloring?: {
|
|
64
|
+
active?: string;
|
|
65
|
+
constant?: RGBAColor;
|
|
66
|
+
vertex?: AttributeState;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Return type is inferred, see ModelComponentPointsStyle: signatures live on the functions only
|
|
71
|
+
// oxlint-disable-next-line max-lines-per-function, max-statements, typescript/explicit-function-return-type, typescript/explicit-module-boundary-types
|
|
72
|
+
function useModelComponentPointsStyle(type: PointsComponentType) {
|
|
73
|
+
const dataStore = useDataStore();
|
|
74
|
+
const dataStyleState = useDataStyleState();
|
|
75
|
+
const modelCommonStyle = useModelCommonStyle();
|
|
76
|
+
const viewerStore = useViewerStore();
|
|
77
|
+
const { seriesArrayName } = useAttributeTimeStepStyle();
|
|
78
|
+
const schemas = modelSchemas[COMPONENT_TYPE_KEYS[type]].points;
|
|
79
|
+
|
|
80
|
+
// Without an explicit points style, components follow the model points style
|
|
81
|
+
function pointsStyle(modelId: string, componentId?: string): PointsStyle {
|
|
82
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- points shape is defined by the data style schema.
|
|
83
|
+
const modelPoints = (dataStyleState.getStyle(modelId).points ?? {}) as PointsStyle;
|
|
84
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- points shape is defined by the data style schema.
|
|
85
|
+
const typePoints = dataStyleState.getModelComponentTypeStyle(modelId, type).points as
|
|
86
|
+
| PointsStyle
|
|
87
|
+
| undefined;
|
|
88
|
+
const componentPoints =
|
|
89
|
+
componentId === undefined
|
|
90
|
+
? undefined
|
|
91
|
+
: // oxlint-disable-next-line no-unsafe-type-assertion -- points shape is defined by the data style schema.
|
|
92
|
+
(dataStyleState.getComponentStyle(modelId, componentId).points as
|
|
93
|
+
| PointsStyle
|
|
94
|
+
| undefined);
|
|
95
|
+
return merge(
|
|
96
|
+
{
|
|
97
|
+
visibility: modelPoints.visibility ?? POINTS_DEFAULT_VISIBILITY,
|
|
98
|
+
size: modelPoints.size ?? POINTS_DEFAULT_SIZE,
|
|
99
|
+
coloring: { active: "constant", constant: POINTS_DEFAULT_COLOR },
|
|
100
|
+
},
|
|
101
|
+
typePoints,
|
|
102
|
+
componentPoints,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function vertexAttribute(modelId: string, componentId?: string): AttributeState {
|
|
107
|
+
return pointsStyle(modelId, componentId).coloring?.vertex ?? {};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function pointsVisibility(modelId: string, componentId?: string): boolean {
|
|
111
|
+
return pointsStyle(modelId, componentId).visibility ?? POINTS_DEFAULT_VISIBILITY;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function pointsSize(modelId: string, componentId?: string): number {
|
|
115
|
+
return pointsStyle(modelId, componentId).size ?? POINTS_DEFAULT_SIZE;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function pointsColor(modelId: string, componentId?: string): RGBAColor {
|
|
119
|
+
return pointsStyle(modelId, componentId).coloring?.constant ?? POINTS_DEFAULT_COLOR;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function activeColoring(modelId: string, componentId?: string): string {
|
|
123
|
+
return pointsStyle(modelId, componentId).coloring?.active ?? "constant";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function vertexAttributeName(modelId: string, componentId?: string): string | undefined {
|
|
127
|
+
return vertexAttribute(modelId, componentId).name;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function lastItem(modelId: string, componentId: string | undefined, name?: string): number {
|
|
131
|
+
const { storedConfigs } = vertexAttribute(modelId, componentId);
|
|
132
|
+
return name === undefined ? 0 : (storedConfigs?.[name]?.lastItem ?? 0);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function vertexAttributeItem(modelId: string, componentId?: string): number {
|
|
136
|
+
const { name, item } = vertexAttribute(modelId, componentId);
|
|
137
|
+
return item ?? lastItem(modelId, componentId, name);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function storedConfig(modelId: string, componentId: string | undefined): AttributeStoredConfig {
|
|
141
|
+
const { name, storedConfigs } = vertexAttribute(modelId, componentId);
|
|
142
|
+
const item = vertexAttributeItem(modelId, componentId);
|
|
143
|
+
const config = name === undefined ? undefined : storedConfigs?.[name]?.[item];
|
|
144
|
+
// A stored config may be partial, missing fields fall back to the defaults
|
|
145
|
+
return {
|
|
146
|
+
minimum: undefined,
|
|
147
|
+
maximum: undefined,
|
|
148
|
+
colorMap: undefined,
|
|
149
|
+
no_data_color: DEFAULT_NO_DATA_COLOR,
|
|
150
|
+
...config,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function vertexAttributeRange(
|
|
155
|
+
modelId: string,
|
|
156
|
+
componentId?: string,
|
|
157
|
+
): [number | undefined, number | undefined] {
|
|
158
|
+
const { minimum, maximum } = storedConfig(modelId, componentId);
|
|
159
|
+
return [minimum, maximum];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function vertexAttributeColorMap(modelId: string, componentId?: string): string | undefined {
|
|
163
|
+
return storedConfig(modelId, componentId).colorMap;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function vertexAttributeNoDataColor(modelId: string, componentId?: string): RGBAColor {
|
|
167
|
+
return storedConfig(modelId, componentId).no_data_color;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// The type style is updated too when every component of the type is targeted
|
|
171
|
+
async function mutatePoints(
|
|
172
|
+
modelId: string,
|
|
173
|
+
componentIds: string[],
|
|
174
|
+
values: PointsStyle,
|
|
175
|
+
): Promise<void> {
|
|
176
|
+
const tasks = [
|
|
177
|
+
modelCommonStyle.mutateComponentStyles(modelId, componentIds, { points: values }),
|
|
178
|
+
];
|
|
179
|
+
const totalIds = await dataStore.getMeshComponentGeodeIds(modelId, type);
|
|
180
|
+
if (componentIds.length === totalIds.length) {
|
|
181
|
+
tasks.push(modelCommonStyle.mutateModelComponentTypeStyle(modelId, type, { points: values }));
|
|
182
|
+
}
|
|
183
|
+
await Promise.all(tasks);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function requestPoints(
|
|
187
|
+
modelId: string,
|
|
188
|
+
componentIds: string[],
|
|
189
|
+
schema: PointsRequestSchema,
|
|
190
|
+
values: Record<string, unknown> & { style: PointsStyle },
|
|
191
|
+
): Promise<unknown> {
|
|
192
|
+
if (componentIds.length === 0) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
const block_ids = await dataStore.getMeshComponentsViewerIds(modelId, componentIds);
|
|
196
|
+
if (!block_ids?.length) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const { style, ...params } = values;
|
|
200
|
+
const result = await viewerStore.request(
|
|
201
|
+
// oxlint-disable-next-line no-unsafe-type-assertion, no-unnecessary-type-assertion -- params match the points schema of every component type.
|
|
202
|
+
{ schema, params: { id: modelId, block_ids, ...params } } as Parameters<
|
|
203
|
+
typeof viewerStore.request
|
|
204
|
+
>[0],
|
|
205
|
+
{
|
|
206
|
+
response_function: async () => {
|
|
207
|
+
await mutatePoints(modelId, componentIds, style);
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
);
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function setVisibility(
|
|
215
|
+
modelId: string,
|
|
216
|
+
componentIds: string[],
|
|
217
|
+
visibility: boolean,
|
|
218
|
+
): Promise<unknown> {
|
|
219
|
+
const result = await requestPoints(modelId, componentIds, schemas.visibility, {
|
|
220
|
+
visibility,
|
|
221
|
+
style: { visibility },
|
|
222
|
+
});
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function setSize(modelId: string, componentIds: string[], size: number): Promise<unknown> {
|
|
227
|
+
const result = await requestPoints(modelId, componentIds, schemas.size, {
|
|
228
|
+
size,
|
|
229
|
+
style: { size },
|
|
230
|
+
});
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function setColor(
|
|
235
|
+
modelId: string,
|
|
236
|
+
componentIds: string[],
|
|
237
|
+
color: RGBAColor,
|
|
238
|
+
): Promise<unknown> {
|
|
239
|
+
const result = await requestPoints(modelId, componentIds, schemas.color, {
|
|
240
|
+
color,
|
|
241
|
+
style: { coloring: { active: "constant", constant: color } },
|
|
242
|
+
});
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function applyVertexAttribute(modelId: string, componentIds: string[]): Promise<unknown> {
|
|
247
|
+
const [referenceId] = componentIds;
|
|
248
|
+
const name = vertexAttributeName(modelId, referenceId);
|
|
249
|
+
const item = vertexAttributeItem(modelId, referenceId);
|
|
250
|
+
const { minimum, maximum, colorMap, no_data_color } = storedConfig(modelId, referenceId);
|
|
251
|
+
if (
|
|
252
|
+
name === undefined ||
|
|
253
|
+
minimum === undefined ||
|
|
254
|
+
maximum === undefined ||
|
|
255
|
+
colorMap === undefined
|
|
256
|
+
) {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
const schema = schemas.attribute.vertex.attribute;
|
|
260
|
+
const result = await requestPoints(modelId, componentIds, schema, {
|
|
261
|
+
name: seriesArrayName(modelId, schema.$id, name),
|
|
262
|
+
item,
|
|
263
|
+
points: [...getRGBPointsFromPreset(colorMap)],
|
|
264
|
+
minimum,
|
|
265
|
+
maximum,
|
|
266
|
+
no_data_color,
|
|
267
|
+
style: { coloring: { active: "vertex" } },
|
|
268
|
+
});
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function mutateVertexAttribute(
|
|
273
|
+
modelId: string,
|
|
274
|
+
componentIds: string[],
|
|
275
|
+
values: AttributeState,
|
|
276
|
+
): Promise<void> {
|
|
277
|
+
await mutatePoints(modelId, componentIds, { coloring: { vertex: values } });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async function mutateStoredConfig(
|
|
281
|
+
modelId: string,
|
|
282
|
+
componentIds: string[],
|
|
283
|
+
config: Partial<AttributeStoredConfig>,
|
|
284
|
+
): Promise<void> {
|
|
285
|
+
const name = vertexAttributeName(modelId, componentIds[0]);
|
|
286
|
+
const item = vertexAttributeItem(modelId, componentIds[0]);
|
|
287
|
+
const itemConfigs = { lastItem: item, [item]: config };
|
|
288
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- partial stored config is merged into the existing one.
|
|
289
|
+
const storedConfigs = { [name ?? ""]: itemConfigs } as AttributeState["storedConfigs"];
|
|
290
|
+
await mutateVertexAttribute(modelId, componentIds, { storedConfigs });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async function setActiveColoring(
|
|
294
|
+
modelId: string,
|
|
295
|
+
componentIds: string[],
|
|
296
|
+
activeColoringType: string,
|
|
297
|
+
): Promise<unknown> {
|
|
298
|
+
await mutatePoints(modelId, componentIds, { coloring: { active: activeColoringType } });
|
|
299
|
+
if (activeColoringType === "vertex") {
|
|
300
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
const result = await setColor(modelId, componentIds, pointsColor(modelId, componentIds[0]));
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async function setVertexAttributeName(
|
|
308
|
+
modelId: string,
|
|
309
|
+
componentIds: string[],
|
|
310
|
+
name: string,
|
|
311
|
+
): Promise<unknown> {
|
|
312
|
+
const item = lastItem(modelId, componentIds[0], name);
|
|
313
|
+
await mutateVertexAttribute(modelId, componentIds, { name, item });
|
|
314
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
315
|
+
return result;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async function setVertexAttributeItem(
|
|
319
|
+
modelId: string,
|
|
320
|
+
componentIds: string[],
|
|
321
|
+
item: number,
|
|
322
|
+
): Promise<unknown> {
|
|
323
|
+
await mutateVertexAttribute(modelId, componentIds, { item });
|
|
324
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function setVertexAttributeRange(
|
|
329
|
+
modelId: string,
|
|
330
|
+
componentIds: string[],
|
|
331
|
+
minimum: number,
|
|
332
|
+
maximum: number,
|
|
333
|
+
): Promise<unknown> {
|
|
334
|
+
await mutateStoredConfig(modelId, componentIds, { minimum, maximum });
|
|
335
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
async function setVertexAttributeColorMap(
|
|
340
|
+
modelId: string,
|
|
341
|
+
componentIds: string[],
|
|
342
|
+
colorMap: string | undefined,
|
|
343
|
+
): Promise<unknown> {
|
|
344
|
+
await mutateStoredConfig(modelId, componentIds, { colorMap });
|
|
345
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async function setVertexAttributeNoDataColor(
|
|
350
|
+
modelId: string,
|
|
351
|
+
componentIds: string[],
|
|
352
|
+
no_data_color: RGBAColor,
|
|
353
|
+
): Promise<unknown> {
|
|
354
|
+
await mutateStoredConfig(modelId, componentIds, { no_data_color });
|
|
355
|
+
const result = await applyVertexAttribute(modelId, componentIds);
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
async function styledComponentIds(modelId: string): Promise<string[]> {
|
|
360
|
+
const componentIds = await dataStore.getMeshComponentGeodeIds(modelId, type);
|
|
361
|
+
if (dataStyleState.getModelComponentTypeStyle(modelId, type).points !== undefined) {
|
|
362
|
+
return componentIds;
|
|
363
|
+
}
|
|
364
|
+
return componentIds.filter(
|
|
365
|
+
(componentId) => dataStyleState.getComponentStyle(modelId, componentId).points !== undefined,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// The model points routes override every component, so the explicit points styles follow
|
|
370
|
+
async function mutateStyledPoints(modelId: string, values: PointsStyle): Promise<void> {
|
|
371
|
+
const componentIds = await styledComponentIds(modelId);
|
|
372
|
+
if (componentIds.length > 0) {
|
|
373
|
+
await mutatePoints(modelId, componentIds, values);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Only components with an explicit points style are sent, the others follow the model points
|
|
378
|
+
async function applyPointsStyle(modelId: string): Promise<void> {
|
|
379
|
+
const componentIds = await styledComponentIds(modelId);
|
|
380
|
+
function style(componentId?: string): PointsStyle {
|
|
381
|
+
return pointsStyle(modelId, componentId);
|
|
382
|
+
}
|
|
383
|
+
await Promise.all([
|
|
384
|
+
...groupBy(componentIds, (id) => String(style(id).visibility)).map(async (ids) => {
|
|
385
|
+
await setVisibility(modelId, ids, pointsVisibility(modelId, ids[0]));
|
|
386
|
+
}),
|
|
387
|
+
...groupBy(componentIds, (id) => String(style(id).size)).map(async (ids) => {
|
|
388
|
+
await setSize(modelId, ids, pointsSize(modelId, ids[0]));
|
|
389
|
+
}),
|
|
390
|
+
...groupBy(componentIds, (id) => JSON.stringify(style(id).coloring)).map(async (ids) => {
|
|
391
|
+
await setActiveColoring(modelId, ids, activeColoring(modelId, ids[0]));
|
|
392
|
+
}),
|
|
393
|
+
]);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
visibility: pointsVisibility,
|
|
398
|
+
size: pointsSize,
|
|
399
|
+
color: pointsColor,
|
|
400
|
+
activeColoring,
|
|
401
|
+
vertexAttributeName,
|
|
402
|
+
vertexAttributeItem,
|
|
403
|
+
vertexAttributeRange,
|
|
404
|
+
vertexAttributeColorMap,
|
|
405
|
+
vertexAttributeNoDataColor,
|
|
406
|
+
setVisibility,
|
|
407
|
+
setSize,
|
|
408
|
+
setColor,
|
|
409
|
+
setActiveColoring,
|
|
410
|
+
setVertexAttributeName,
|
|
411
|
+
setVertexAttributeItem,
|
|
412
|
+
setVertexAttributeRange,
|
|
413
|
+
setVertexAttributeColorMap,
|
|
414
|
+
setVertexAttributeNoDataColor,
|
|
415
|
+
mutateStyledPoints,
|
|
416
|
+
applyPointsStyle,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
type ModelComponentPointsStyle = ReturnType<typeof useModelComponentPointsStyle>;
|
|
421
|
+
|
|
422
|
+
export { POINTS_COMPONENT_TYPES, useModelComponentPointsStyle };
|
|
423
|
+
export type { ModelComponentPointsStyle };
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
3
3
|
|
|
4
4
|
// Local imports
|
|
5
|
+
import {
|
|
6
|
+
POINTS_COMPONENT_TYPES,
|
|
7
|
+
useModelComponentPointsStyle,
|
|
8
|
+
} from "@ogw_internal/stores/data_style/model/points/component";
|
|
5
9
|
import { useModelPointsCommonStyle } from "./common";
|
|
6
10
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
7
11
|
|
|
@@ -14,6 +18,9 @@ export function useModelPointsSizeStyle(): {
|
|
|
14
18
|
} {
|
|
15
19
|
const viewerStore = useViewerStore();
|
|
16
20
|
const modelPointsCommonStyle = useModelPointsCommonStyle();
|
|
21
|
+
const componentsPointsStyles = POINTS_COMPONENT_TYPES.map((type) =>
|
|
22
|
+
useModelComponentPointsStyle(type),
|
|
23
|
+
);
|
|
17
24
|
|
|
18
25
|
function modelPointsSize(id: string): number | undefined {
|
|
19
26
|
// oxlint-disable-next-line no-unsafe-type-assertion -- points style values are dynamically typed at runtime.
|
|
@@ -29,7 +36,12 @@ export function useModelPointsSizeStyle(): {
|
|
|
29
36
|
},
|
|
30
37
|
{
|
|
31
38
|
response_function: async () => {
|
|
32
|
-
const mutateResult = await
|
|
39
|
+
const [mutateResult] = await Promise.all([
|
|
40
|
+
modelPointsCommonStyle.mutateModelPointsStyle(id, { size }),
|
|
41
|
+
...componentsPointsStyles.map(async (pointsStyle) => {
|
|
42
|
+
await pointsStyle.mutateStyledPoints(id, { size });
|
|
43
|
+
}),
|
|
44
|
+
]);
|
|
33
45
|
return mutateResult;
|
|
34
46
|
},
|
|
35
47
|
},
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
|
|
3
3
|
|
|
4
4
|
// Local imports
|
|
5
|
+
import {
|
|
6
|
+
POINTS_COMPONENT_TYPES,
|
|
7
|
+
useModelComponentPointsStyle,
|
|
8
|
+
} from "@ogw_internal/stores/data_style/model/points/component";
|
|
5
9
|
import { useModelPointsCommonStyle } from "./common";
|
|
6
10
|
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
7
11
|
|
|
@@ -14,6 +18,9 @@ export function useModelPointsVisibilityStyle(): {
|
|
|
14
18
|
} {
|
|
15
19
|
const viewerStore = useViewerStore();
|
|
16
20
|
const modelPointsCommonStyle = useModelPointsCommonStyle();
|
|
21
|
+
const componentsPointsStyles = POINTS_COMPONENT_TYPES.map((type) =>
|
|
22
|
+
useModelComponentPointsStyle(type),
|
|
23
|
+
);
|
|
17
24
|
|
|
18
25
|
function modelPointsVisibility(id: string): boolean | undefined {
|
|
19
26
|
// oxlint-disable-next-line no-unsafe-type-assertion -- points style values are dynamically typed at runtime.
|
|
@@ -26,9 +33,12 @@ export function useModelPointsVisibilityStyle(): {
|
|
|
26
33
|
{ schema, params },
|
|
27
34
|
{
|
|
28
35
|
response_function: async () => {
|
|
29
|
-
const mutateResult = await
|
|
30
|
-
visibility,
|
|
31
|
-
|
|
36
|
+
const [mutateResult] = await Promise.all([
|
|
37
|
+
modelPointsCommonStyle.mutateModelPointsStyle(id, { visibility }),
|
|
38
|
+
...componentsPointsStyles.map(async (pointsStyle) => {
|
|
39
|
+
await pointsStyle.mutateStyledPoints(id, { visibility });
|
|
40
|
+
}),
|
|
41
|
+
]);
|
|
32
42
|
return mutateResult;
|
|
33
43
|
},
|
|
34
44
|
},
|
|
@@ -4,6 +4,7 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
|
|
|
4
4
|
import { useDataStore } from "@ogw_front/stores/data";
|
|
5
5
|
import { useModelSurfacesColor } from "./color";
|
|
6
6
|
import { useModelSurfacesCommonStyle } from "./common";
|
|
7
|
+
import { useModelSurfacesPointsStyle } from "./points";
|
|
7
8
|
import { useModelSurfacesVisibility } from "./visibility";
|
|
8
9
|
|
|
9
10
|
interface ColorGroup {
|
|
@@ -28,6 +29,7 @@ async function setModelSurfacesDefaultStyle(_id: string): Promise<void> {
|
|
|
28
29
|
type UseModelSurfacesStyleReturn = ReturnType<typeof useModelSurfacesCommonStyle> &
|
|
29
30
|
ReturnType<typeof useModelSurfacesVisibility> &
|
|
30
31
|
ReturnType<typeof useModelSurfacesColor> &
|
|
32
|
+
ReturnType<typeof useModelSurfacesPointsStyle> &
|
|
31
33
|
ReturnType<typeof useModelSurfacesVertexAttribute> &
|
|
32
34
|
ReturnType<typeof useModelSurfacesPolygonAttribute> & {
|
|
33
35
|
applyModelSurfacesStyle: (modelId: string) => Promise<void>;
|
|
@@ -42,6 +44,7 @@ export function useModelSurfacesStyle(): UseModelSurfacesStyleReturn {
|
|
|
42
44
|
const modelColorStyle = useModelSurfacesColor();
|
|
43
45
|
const modelSurfacesVertexAttribute = useModelSurfacesVertexAttribute();
|
|
44
46
|
const modelSurfacesPolygonAttribute = useModelSurfacesPolygonAttribute();
|
|
47
|
+
const modelSurfacesPointsStyle = useModelSurfacesPointsStyle();
|
|
45
48
|
|
|
46
49
|
async function applyModelSurfacesVisibilityStyle(
|
|
47
50
|
modelId: string,
|
|
@@ -264,5 +267,6 @@ export function useModelSurfacesStyle(): UseModelSurfacesStyleReturn {
|
|
|
264
267
|
...modelColorStyle,
|
|
265
268
|
...modelSurfacesVertexAttribute,
|
|
266
269
|
...modelSurfacesPolygonAttribute,
|
|
270
|
+
...modelSurfacesPointsStyle,
|
|
267
271
|
};
|
|
268
272
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ModelComponentPointsStyle,
|
|
3
|
+
useModelComponentPointsStyle,
|
|
4
|
+
} from "@ogw_internal/stores/data_style/model/points/component";
|
|
5
|
+
|
|
6
|
+
interface UseModelSurfacesPointsStyleReturn {
|
|
7
|
+
modelSurfacePointsVisibility: ModelComponentPointsStyle["visibility"];
|
|
8
|
+
modelSurfacePointsSize: ModelComponentPointsStyle["size"];
|
|
9
|
+
modelSurfacePointsColor: ModelComponentPointsStyle["color"];
|
|
10
|
+
modelSurfacePointsActiveColoring: ModelComponentPointsStyle["activeColoring"];
|
|
11
|
+
modelSurfacePointsVertexAttributeName: ModelComponentPointsStyle["vertexAttributeName"];
|
|
12
|
+
modelSurfacePointsVertexAttributeItem: ModelComponentPointsStyle["vertexAttributeItem"];
|
|
13
|
+
modelSurfacePointsVertexAttributeRange: ModelComponentPointsStyle["vertexAttributeRange"];
|
|
14
|
+
modelSurfacePointsVertexAttributeColorMap: ModelComponentPointsStyle["vertexAttributeColorMap"];
|
|
15
|
+
modelSurfacePointsVertexAttributeNoDataColor: ModelComponentPointsStyle["vertexAttributeNoDataColor"];
|
|
16
|
+
setModelSurfacesPointsVisibility: ModelComponentPointsStyle["setVisibility"];
|
|
17
|
+
setModelSurfacesPointsSize: ModelComponentPointsStyle["setSize"];
|
|
18
|
+
setModelSurfacesPointsColor: ModelComponentPointsStyle["setColor"];
|
|
19
|
+
setModelSurfacesPointsActiveColoring: ModelComponentPointsStyle["setActiveColoring"];
|
|
20
|
+
setModelSurfacesPointsVertexAttributeName: ModelComponentPointsStyle["setVertexAttributeName"];
|
|
21
|
+
setModelSurfacesPointsVertexAttributeItem: ModelComponentPointsStyle["setVertexAttributeItem"];
|
|
22
|
+
setModelSurfacesPointsVertexAttributeRange: ModelComponentPointsStyle["setVertexAttributeRange"];
|
|
23
|
+
setModelSurfacesPointsVertexAttributeColorMap: ModelComponentPointsStyle["setVertexAttributeColorMap"];
|
|
24
|
+
setModelSurfacesPointsVertexAttributeNoDataColor: ModelComponentPointsStyle["setVertexAttributeNoDataColor"];
|
|
25
|
+
applyModelSurfacesPointsStyle: ModelComponentPointsStyle["applyPointsStyle"];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useModelSurfacesPointsStyle(): UseModelSurfacesPointsStyleReturn {
|
|
29
|
+
const points = useModelComponentPointsStyle("Surface");
|
|
30
|
+
return {
|
|
31
|
+
modelSurfacePointsVisibility: points.visibility,
|
|
32
|
+
modelSurfacePointsSize: points.size,
|
|
33
|
+
modelSurfacePointsColor: points.color,
|
|
34
|
+
modelSurfacePointsActiveColoring: points.activeColoring,
|
|
35
|
+
modelSurfacePointsVertexAttributeName: points.vertexAttributeName,
|
|
36
|
+
modelSurfacePointsVertexAttributeItem: points.vertexAttributeItem,
|
|
37
|
+
modelSurfacePointsVertexAttributeRange: points.vertexAttributeRange,
|
|
38
|
+
modelSurfacePointsVertexAttributeColorMap: points.vertexAttributeColorMap,
|
|
39
|
+
modelSurfacePointsVertexAttributeNoDataColor: points.vertexAttributeNoDataColor,
|
|
40
|
+
setModelSurfacesPointsVisibility: points.setVisibility,
|
|
41
|
+
setModelSurfacesPointsSize: points.setSize,
|
|
42
|
+
setModelSurfacesPointsColor: points.setColor,
|
|
43
|
+
setModelSurfacesPointsActiveColoring: points.setActiveColoring,
|
|
44
|
+
setModelSurfacesPointsVertexAttributeName: points.setVertexAttributeName,
|
|
45
|
+
setModelSurfacesPointsVertexAttributeItem: points.setVertexAttributeItem,
|
|
46
|
+
setModelSurfacesPointsVertexAttributeRange: points.setVertexAttributeRange,
|
|
47
|
+
setModelSurfacesPointsVertexAttributeColorMap: points.setVertexAttributeColorMap,
|
|
48
|
+
setModelSurfacesPointsVertexAttributeNoDataColor: points.setVertexAttributeNoDataColor,
|
|
49
|
+
applyModelSurfacesPointsStyle: points.applyPointsStyle,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -44,7 +44,7 @@ async function upload_file(
|
|
|
44
44
|
const feedbackStore = useFeedbackStore();
|
|
45
45
|
|
|
46
46
|
if (!(file instanceof File)) {
|
|
47
|
-
throw new
|
|
47
|
+
throw new TypeError("file must be an instance of File");
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const route = schema.$id;
|
package/package.json
CHANGED
package/shared/utils/file.ts
CHANGED
|
@@ -10,7 +10,7 @@ const CHUNK_SIZE_BYTES = CHUNK_SIZE_MEBIBYTES * KIBIBYTES_PER_MEBIBYTE * BYTES_P
|
|
|
10
10
|
function assertFile(file: unknown): asserts file is File {
|
|
11
11
|
consola.debug("[ASSERT_FILE] Asserting file", { file });
|
|
12
12
|
if (!(file instanceof File)) {
|
|
13
|
-
throw new
|
|
13
|
+
throw new TypeError("file must be an instance of File");
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -106,4 +106,40 @@ function resolveAllowedObjects(
|
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
interface FileAllowedObjects {
|
|
110
|
+
readonly filename: string;
|
|
111
|
+
// Loadable types only, sorted by best is_loadable then best object_priority
|
|
112
|
+
readonly candidates: string[];
|
|
113
|
+
readonly selectedGeodeObject: string | undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function sortCandidates(objectMap: AllowedObjectMap): string[] {
|
|
117
|
+
return Object.keys(objectMap)
|
|
118
|
+
.filter((key) => getObject(objectMap, key).is_loadable > 0)
|
|
119
|
+
.toSorted((keyA, keyB) => {
|
|
120
|
+
const objectA = getObject(objectMap, keyA);
|
|
121
|
+
const objectB = getObject(objectMap, keyB);
|
|
122
|
+
if (objectA.is_loadable !== objectB.is_loadable) {
|
|
123
|
+
return objectB.is_loadable - objectA.is_loadable;
|
|
124
|
+
}
|
|
125
|
+
return (objectB.object_priority ?? -Infinity) - (objectA.object_priority ?? -Infinity);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Each file gets its own geode object type; files are no longer required to share one
|
|
130
|
+
function resolveAllowedObjectsPerFile(
|
|
131
|
+
filenames: readonly string[],
|
|
132
|
+
allowedObjectsList: readonly AllowedObjectMap[],
|
|
133
|
+
): FileAllowedObjects[] {
|
|
134
|
+
return filenames.map((filename, index) => {
|
|
135
|
+
const objectMap = allowedObjectsList[index] ?? {};
|
|
136
|
+
return {
|
|
137
|
+
filename,
|
|
138
|
+
candidates: sortCandidates(objectMap),
|
|
139
|
+
selectedGeodeObject: selectGeodeObject(objectMap),
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { resolveAllowedObjects, resolveAllowedObjectsPerFile, getFileExtension };
|
|
145
|
+
export type { FileAllowedObjects };
|