Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 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 88 89 90 91 92 93 | 12x 12x 4x 67x 56x 4x 15x 5x 5x 15x 4x 1x 11x 11x 52x 11x 44x 11x 11x 11x 10x 1x 38x 11x 11x | import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
/**
* GeoJSON bounding box: [west, south, east, north]
* or [west, south, minZ, east, north, maxZ] (altitudes are preserved)
*/
@Component({
selector: 'formly-field-bbox',
host: { 'class': 'field bbox-field' },
template: `
<div class="form-array">
@for (side of sides; track side.index) {
<input type="number"
class="grow bbox-{{ side.name }}"
step="any"
[min]="side.min"
[max]="side.max"
[placeholder]="side.label"
[attr.aria-label]="side.label"
[id]="side.index ? field.id + '-' + side.name : field.id"
[value]="value(side.index)"
[disabled]="formControl.disabled"
(input)="set(side.index, $any($event.target).value)">
}
</div>
`,
styles: `
.form-array {
min-width: 0;
}
input {
min-width: 0;
width: 80px;
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ReactiveFormsModule],
})
export class FormlyFieldBbox extends FieldType<FieldTypeConfig> {
sides = [
{ index: 0, name: 'west', label: $localize`West`, min: -180, max: 180 },
{ index: 1, name: 'south', label: $localize`South`, min: -90, max: 90 },
{ index: 2, name: 'east', label: $localize`East`, min: -180, max: 180 },
{ index: 3, name: 'north', label: $localize`North`, min: -90, max: 90 },
];
get is3d() {
return this.formControl.value?.length === 6;
}
pos(index: number) {
return this.is3d && index >= 2 ? index + 1 : index;
}
private blank = new Set<number>();
private saved?: (number | null)[];
private blanks() {
if (this.formControl.value !== this.saved) {
this.blank.clear();
this.saved = this.formControl.value;
}
return this.blank;
}
value(index: number) {
if (this.blanks().has(index)) return '';
return this.formControl.value?.[this.pos(index)] ?? '';
}
set(index: number, value: string) {
const blank = this.blanks();
const length = this.is3d ? 6 : 4;
const bbox: (number | null)[] = Array.from({ length }, (_, i) => this.formControl.value?.[i] ?? null);
for (const side of this.sides) {
if (bbox[this.pos(side.index)] === null) blank.add(side.index);
}
const n = parseFloat(value);
bbox[this.pos(index)] = isNaN(n) ? null : n;
if (isNaN(n)) {
blank.add(index);
} else {
blank.delete(index);
}
this.saved = blank.size === this.sides.length ? undefined : bbox.map(b => b ?? 0);
this.formControl.setValue(this.saved);
this.formControl.markAsDirty();
}
}
|