inviton-powerduck 0.0.128 → 0.0.130
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/app/powerduck-system-resources.ts +5 -0
- package/common/localized-value-helper.ts +4 -1
- package/components/datatable/datatable.tsx +34 -5
- package/components/input/gps-bounding-box.tsx +113 -0
- package/components/input/localized-string-wysiwyg.tsx +7 -0
- package/components/input/wysiwig.tsx +23 -0
- package/components/open-street-map/open-street-map.tsx +92 -22
- package/data/bounding-box.ts +6 -0
- package/package.json +1 -1
|
@@ -83,4 +83,9 @@ export interface IPowerduckSystemResources {
|
|
|
83
83
|
signInX: string;
|
|
84
84
|
signInFigma: string;
|
|
85
85
|
signInDribble: string;
|
|
86
|
+
gpsBoundingBoxLabel: string;
|
|
87
|
+
gpsBoundingBoxX1: string;
|
|
88
|
+
gpsBoundingBoxX2: string;
|
|
89
|
+
gpsBoundingBoxY1: string;
|
|
90
|
+
gpsBoundingBoxY2: string;
|
|
86
91
|
}
|
|
@@ -891,7 +891,7 @@ class DataTableComponent extends TsxComponent<DataTableArgs> implements DataTabl
|
|
|
891
891
|
}
|
|
892
892
|
}
|
|
893
893
|
|
|
894
|
-
markSelection(): void {
|
|
894
|
+
markSelection (): void {
|
|
895
895
|
const mySelf = this;
|
|
896
896
|
const escapeRegExp = function (string) {
|
|
897
897
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
@@ -909,26 +909,55 @@ class DataTableComponent extends TsxComponent<DataTableArgs> implements DataTabl
|
|
|
909
909
|
};
|
|
910
910
|
|
|
911
911
|
let regexBuilder = '';
|
|
912
|
-
const markArr
|
|
912
|
+
const markArr = [];
|
|
913
913
|
if (this.filterArr != null) {
|
|
914
914
|
this.filterArr.forEach((filterItem) => {
|
|
915
915
|
if (regexBuilder.length > 0) {
|
|
916
916
|
regexBuilder += '|';
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
+
const columnId = filterItem.PropertyName?.toLowerCase();
|
|
920
|
+
const tds = Array.from($(mySelf.$el).find(`td.dt-col-${columnId}`));
|
|
921
|
+
if (tds == null || tds.length == 0) {
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
|
|
919
925
|
(getValueArr(filterItem) || []).forEach((filterValue) => {
|
|
920
|
-
markArr.push(
|
|
926
|
+
markArr.push({
|
|
927
|
+
value: escapeRegExp(filterValue),
|
|
928
|
+
elements: tds,
|
|
929
|
+
});
|
|
921
930
|
});
|
|
922
931
|
});
|
|
923
932
|
}
|
|
924
933
|
|
|
925
934
|
if (!isNullOrEmpty(this.fullTextQuery)) {
|
|
926
|
-
|
|
935
|
+
const value = escapeRegExp(this.fullTextQuery);
|
|
936
|
+
const tds = Array.from($(mySelf.$el).find(`td`));
|
|
937
|
+
regexBuilder += value;
|
|
938
|
+
|
|
939
|
+
markArr.push({
|
|
940
|
+
value,
|
|
941
|
+
elements: tds,
|
|
942
|
+
});
|
|
927
943
|
}
|
|
928
944
|
|
|
929
945
|
if (DataTableConfig.filterMarking) {
|
|
930
946
|
this.unmarkSelection(() => {
|
|
931
|
-
|
|
947
|
+
for (const item of markArr) {
|
|
948
|
+
this.markInstance.mark(item.value, {
|
|
949
|
+
filter: (node) => {
|
|
950
|
+
const parentTd = $(node).closest('td')[0];
|
|
951
|
+
if (!parentTd) {
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
const matchesColumn = item.elements?.some(el => parentTd?.isEqualNode(el));
|
|
956
|
+
const matchesText = parentTd?.textContent?.toLowerCase().includes(item.value.toLowerCase());
|
|
957
|
+
return matchesColumn && matchesText;
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
}
|
|
932
961
|
});
|
|
933
962
|
}
|
|
934
963
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Component, Prop, toNative } from 'vue-facing-decorator';
|
|
2
|
+
import TsxComponent from '../../app/vuetsx';
|
|
3
|
+
import { ValidationState } from '../../common/static-wrappers/interfaces/validation-interface';
|
|
4
|
+
import BoundingBox from '../../data/bounding-box';
|
|
5
|
+
import FlexContainer from '../form/flex-container';
|
|
6
|
+
import FlexFormItem from '../form/form-item-flex';
|
|
7
|
+
import FormItemWrapper from '../form/form-item-wrapper';
|
|
8
|
+
import OpenStreetMap from '../open-street-map/open-street-map';
|
|
9
|
+
import NumericInput, { NumericInputMode } from './numeric-input';
|
|
10
|
+
import PowerduckState from '../../app/powerduck-state';
|
|
11
|
+
|
|
12
|
+
interface GpsBoundingBoxInputArgs {
|
|
13
|
+
bBoxModel: BoundingBox;
|
|
14
|
+
mandatory?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Component
|
|
18
|
+
class GpsBoundingBoxInputComponent extends TsxComponent<GpsBoundingBoxInputArgs> implements GpsBoundingBoxInputArgs {
|
|
19
|
+
@Prop() bBoxModel: BoundingBox;
|
|
20
|
+
@Prop() mandatory?: boolean;
|
|
21
|
+
|
|
22
|
+
onChange (field: keyof BoundingBox, value: number) {
|
|
23
|
+
if (value) {
|
|
24
|
+
this.bBoxModel[field] = parseFloat(value.toFixed(7));
|
|
25
|
+
} else {
|
|
26
|
+
this.bBoxModel[field] = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
renderInput (
|
|
31
|
+
h: any,
|
|
32
|
+
label: string,
|
|
33
|
+
value: number,
|
|
34
|
+
onChanged?: (value: number) => void,
|
|
35
|
+
showClearValueButton?: boolean,
|
|
36
|
+
validationState?: ValidationState,
|
|
37
|
+
) {
|
|
38
|
+
return (
|
|
39
|
+
<FlexFormItem flexFill={true}>
|
|
40
|
+
<NumericInput
|
|
41
|
+
mandatory={this.mandatory}
|
|
42
|
+
label={label}
|
|
43
|
+
value={value}
|
|
44
|
+
step={0.000001}
|
|
45
|
+
mode={NumericInputMode.Clasic}
|
|
46
|
+
showClearValueButton={showClearValueButton}
|
|
47
|
+
validationState={validationState}
|
|
48
|
+
changed={(e) => {
|
|
49
|
+
if (onChanged != null) {
|
|
50
|
+
onChanged(e);
|
|
51
|
+
}
|
|
52
|
+
}}
|
|
53
|
+
/>
|
|
54
|
+
</FlexFormItem>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render (h) {
|
|
59
|
+
if (!this.bBoxModel) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div>
|
|
65
|
+
<FormItemWrapper label={PowerduckState.getResourceValue('gpsBoundingBoxLabel')} mandatory={this.mandatory}>
|
|
66
|
+
<FlexContainer fullWidthOnMobile={true}>
|
|
67
|
+
<FlexFormItem>
|
|
68
|
+
{this.renderInput(
|
|
69
|
+
h,
|
|
70
|
+
PowerduckState.getResourceValue('gpsBoundingBoxX1'),
|
|
71
|
+
this.bBoxModel.x1,
|
|
72
|
+
e => this.onChange('x1', e),
|
|
73
|
+
)}
|
|
74
|
+
{this.renderInput(
|
|
75
|
+
h,
|
|
76
|
+
PowerduckState.getResourceValue('gpsBoundingBoxX2'),
|
|
77
|
+
this.bBoxModel.x2,
|
|
78
|
+
e => this.onChange('x2', e),
|
|
79
|
+
)}
|
|
80
|
+
</FlexFormItem>
|
|
81
|
+
<FlexFormItem>
|
|
82
|
+
{this.renderInput(
|
|
83
|
+
h,
|
|
84
|
+
PowerduckState.getResourceValue('gpsBoundingBoxY1'),
|
|
85
|
+
this.bBoxModel.y1,
|
|
86
|
+
e => this.onChange('y1', e),
|
|
87
|
+
)}
|
|
88
|
+
{this.renderInput(
|
|
89
|
+
h,
|
|
90
|
+
PowerduckState.getResourceValue('gpsBoundingBoxY2'),
|
|
91
|
+
this.bBoxModel.y2,
|
|
92
|
+
e => this.onChange('y2', e),
|
|
93
|
+
)}
|
|
94
|
+
</FlexFormItem>
|
|
95
|
+
</FlexContainer>
|
|
96
|
+
</FormItemWrapper>
|
|
97
|
+
|
|
98
|
+
<FormItemWrapper label={null} mandatory={false}>
|
|
99
|
+
<div class="rounded">
|
|
100
|
+
<OpenStreetMap
|
|
101
|
+
ref="openStreetMap"
|
|
102
|
+
isCenterHidden={true}
|
|
103
|
+
bBox={this.bBoxModel}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
</FormItemWrapper>
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const GpsBoundingBoxInput = toNative(GpsBoundingBoxInputComponent);
|
|
113
|
+
export default GpsBoundingBoxInput;
|
|
@@ -40,6 +40,7 @@ class LocalizedStringWysiwigComponent extends TsxComponent<LocalizedStringInputA
|
|
|
40
40
|
@Prop() appendClicked: () => void;
|
|
41
41
|
@Prop() prependClicked: () => void;
|
|
42
42
|
currentValue: ILocalizedText = null;
|
|
43
|
+
editorHeight: number = null;
|
|
43
44
|
|
|
44
45
|
raiseChangeEvent(newValue: ILocalizedText): void {
|
|
45
46
|
this.populateValidationDeclaration();
|
|
@@ -59,6 +60,10 @@ class LocalizedStringWysiwigComponent extends TsxComponent<LocalizedStringInputA
|
|
|
59
60
|
this.raiseChangeEvent(value);
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
onEditorResized (height: number): void {
|
|
64
|
+
this.editorHeight = height;
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
getActualValue(lang: Language, value: ILocalizedText): string {
|
|
63
68
|
if (value == null) {
|
|
64
69
|
return null;
|
|
@@ -104,6 +109,8 @@ class LocalizedStringWysiwigComponent extends TsxComponent<LocalizedStringInputA
|
|
|
104
109
|
key={lang.id}
|
|
105
110
|
wrap={false}
|
|
106
111
|
resizable={this.resizable}
|
|
112
|
+
initialHeight={this.editorHeight}
|
|
113
|
+
onResized={this.onEditorResized}
|
|
107
114
|
label={null}
|
|
108
115
|
value={this.getActualValue(lang.id, this.value)}
|
|
109
116
|
changed={(e) => {
|
|
@@ -32,6 +32,8 @@ interface WysiwigEditorArgs extends FormItemWrapperArgs {
|
|
|
32
32
|
useCommonUpload?: boolean;
|
|
33
33
|
uploadPluginArgs?: () => any | any;
|
|
34
34
|
resizable?: boolean;
|
|
35
|
+
initialHeight?: number;
|
|
36
|
+
onResized?: (height: number) => void;
|
|
35
37
|
changed: (newValue: string) => void;
|
|
36
38
|
}
|
|
37
39
|
|
|
@@ -56,6 +58,8 @@ class WysiwigEditorComponent extends TsxComponent<WysiwigEditorArgs> implements
|
|
|
56
58
|
@Prop() appendClicked: () => void;
|
|
57
59
|
@Prop() prependClicked: () => void;
|
|
58
60
|
@Prop() changed: (newValue: string) => void;
|
|
61
|
+
@Prop() initialHeight: number = null;
|
|
62
|
+
@Prop() onResized?: (height: number) => void;
|
|
59
63
|
@Prop({ default: true }) resizable: boolean;
|
|
60
64
|
skipTrigger: boolean = false;
|
|
61
65
|
|
|
@@ -160,6 +164,25 @@ class WysiwigEditorComponent extends TsxComponent<WysiwigEditorArgs> implements
|
|
|
160
164
|
innerEditor.addClass('vertical-resize');
|
|
161
165
|
}
|
|
162
166
|
|
|
167
|
+
if (this.initialHeight) {
|
|
168
|
+
innerEditor.css('height', `${this.initialHeight}px`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let lastNotifiedHeight = this.initialHeight || null;
|
|
172
|
+
if (this.onResized != null && this.resizable) {
|
|
173
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
174
|
+
for (const entry of entries) {
|
|
175
|
+
const height = entry?.contentRect?.height;
|
|
176
|
+
if (height > 0 && (lastNotifiedHeight == null || Math.abs(height - lastNotifiedHeight) > 2)) { // To keep height stable
|
|
177
|
+
lastNotifiedHeight = height;
|
|
178
|
+
this.onResized(height);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
resizeObserver.observe(innerEditor[0]);
|
|
184
|
+
}
|
|
185
|
+
|
|
163
186
|
innerEditor.on('click', (e) => {
|
|
164
187
|
const clickTarget = e.target;
|
|
165
188
|
if (clickTarget != null && clickTarget.nodeName == 'IMG') {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { LGeoJson, LLayerGroup, LMap, LMarker, LTileLayer } from '@vue-leaflet/vue-leaflet';
|
|
1
|
+
import { LGeoJson, LLayerGroup, LMap, LMarker, LPolygon, LTileLayer } from '@vue-leaflet/vue-leaflet';
|
|
2
2
|
import L from 'leaflet';
|
|
3
3
|
import * as LCluster from 'leaflet.markercluster';
|
|
4
4
|
import { Prop, toNative, Watch } from 'vue-facing-decorator';
|
|
5
5
|
import TsxComponent, { Component } from '../../app/vuetsx';
|
|
6
6
|
import { isNullOrEmpty } from '../../common/utils/is-null-or-empty';
|
|
7
7
|
import { ModalUtils } from '../modal/modal-utils';
|
|
8
|
+
import BoundingBox from '../../data/bounding-box';
|
|
8
9
|
import iconUrl from './img/marker-icon.png';
|
|
9
10
|
import GestureHandling from './ts/gesture-handling/gesture-handling';
|
|
10
11
|
import 'leaflet/dist/leaflet.css';
|
|
@@ -57,6 +58,7 @@ interface OpenStreetMapClusterOptions {
|
|
|
57
58
|
interface OpenStreetMapArgs {
|
|
58
59
|
latitude?: string;
|
|
59
60
|
longitude?: string;
|
|
61
|
+
bBox?: BoundingBox;
|
|
60
62
|
name?: string;
|
|
61
63
|
address?: string;
|
|
62
64
|
is16by9?: boolean;
|
|
@@ -75,7 +77,7 @@ interface OpenStreetMapArgs {
|
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export class OpenStreetMapHelper {
|
|
78
|
-
static getMarkerIcon(): L.Icon<L.IconOptions> {
|
|
80
|
+
static getMarkerIcon (): L.Icon<L.IconOptions> {
|
|
79
81
|
return L.icon({
|
|
80
82
|
iconUrl,
|
|
81
83
|
iconAnchor: [
|
|
@@ -109,11 +111,13 @@ export interface GoogleMapRefreshArgs {
|
|
|
109
111
|
'l-marker': LMarker,
|
|
110
112
|
'l-geo-json': LGeoJson,
|
|
111
113
|
'l-layer-group': LLayerGroup,
|
|
114
|
+
'l-polygon': LPolygon,
|
|
112
115
|
},
|
|
113
116
|
})
|
|
114
117
|
export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> implements OpenStreetMapArgs {
|
|
115
118
|
@Prop() latitude!: string;
|
|
116
119
|
@Prop() longitude!: string;
|
|
120
|
+
@Prop() bBox?: BoundingBox;
|
|
117
121
|
@Prop() name!: string;
|
|
118
122
|
@Prop() address!: string;
|
|
119
123
|
@Prop() is16by9!: boolean;
|
|
@@ -132,12 +136,14 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
132
136
|
leafletIcon: any = null;
|
|
133
137
|
markerClusters: LCluster.MarkerClusterGroup = null;
|
|
134
138
|
|
|
135
|
-
mounted() {
|
|
139
|
+
mounted () {
|
|
136
140
|
this.initIcon();
|
|
137
141
|
this.waitForLeaflet().then(() => {
|
|
138
142
|
ModalUtils.handleModalMountDelay(this, () => {
|
|
139
143
|
this.initGestureHandling();
|
|
140
144
|
this.invalidateSize();
|
|
145
|
+
this.onBoundingBoxChanged();
|
|
146
|
+
|
|
141
147
|
if (this.initComplete != null) {
|
|
142
148
|
this.$nextTick(() => {
|
|
143
149
|
this.initComplete(this.getLeaflet(), this.getMap());
|
|
@@ -147,7 +153,15 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
147
153
|
});
|
|
148
154
|
}
|
|
149
155
|
|
|
150
|
-
|
|
156
|
+
@Watch('bBox', { immediate: false, deep: true })
|
|
157
|
+
onBoundingBoxChanged () {
|
|
158
|
+
const bounds = this.getBoundingBoxLatLngBounds();
|
|
159
|
+
if (bounds) {
|
|
160
|
+
this.getLeaflet()?.fitBounds(bounds);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async waitForLeaflet (timeout = 15000, interval = 100) {
|
|
151
165
|
const startTime = Date.now();
|
|
152
166
|
while (!this.getLeaflet()) {
|
|
153
167
|
if (Date.now() - startTime > timeout) {
|
|
@@ -160,25 +174,25 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
160
174
|
return this.getLeaflet();
|
|
161
175
|
}
|
|
162
176
|
|
|
163
|
-
initIcon() {
|
|
177
|
+
initIcon () {
|
|
164
178
|
if (this.leafletIcon == null) {
|
|
165
179
|
this.leafletIcon = OpenStreetMapHelper.getMarkerIcon();
|
|
166
180
|
}
|
|
167
181
|
}
|
|
168
182
|
|
|
169
183
|
@Watch('geoJSON')
|
|
170
|
-
onGeoJsonChanged() {
|
|
184
|
+
onGeoJsonChanged () {
|
|
171
185
|
if (this.geoJSONClustering) {
|
|
172
186
|
this.initCluster();
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
189
|
|
|
176
190
|
@Watch('mapUrl')
|
|
177
|
-
onMapUrlChanged() {
|
|
191
|
+
onMapUrlChanged () {
|
|
178
192
|
this.invalidateSize();
|
|
179
193
|
}
|
|
180
194
|
|
|
181
|
-
initGestureHandling() {
|
|
195
|
+
initGestureHandling () {
|
|
182
196
|
if (this.gestureHandling == true) {
|
|
183
197
|
const leaflet = this.getLeaflet();
|
|
184
198
|
if ((leaflet as any)._gesturesBinder != true) {
|
|
@@ -188,10 +202,10 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
188
202
|
}
|
|
189
203
|
}
|
|
190
204
|
|
|
191
|
-
initCluster() {
|
|
205
|
+
initCluster () {
|
|
192
206
|
this.markerClusters?.clearLayers();
|
|
193
207
|
this.markerClusters = new LCluster.MarkerClusterGroup(this.clusterOptions || {
|
|
194
|
-
iconCreateFunction(cluster) {
|
|
208
|
+
iconCreateFunction (cluster) {
|
|
195
209
|
const html = `<div class="cluster-marker ">${cluster.getChildCount()}<div class="pulse-animation"></div></div>`;
|
|
196
210
|
return L.divIcon({ html, className: 'cluster-icon' });
|
|
197
211
|
},
|
|
@@ -209,7 +223,7 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
209
223
|
}
|
|
210
224
|
}
|
|
211
225
|
|
|
212
|
-
invalidateSize() {
|
|
226
|
+
invalidateSize () {
|
|
213
227
|
const leaflet = this.getLeaflet();
|
|
214
228
|
if (leaflet != null) {
|
|
215
229
|
this.$nextTick(() => {
|
|
@@ -218,41 +232,88 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
218
232
|
}
|
|
219
233
|
}
|
|
220
234
|
|
|
221
|
-
getNumeric(val: string): number {
|
|
235
|
+
getNumeric (val: string): number {
|
|
222
236
|
return Number((val || '').toString().split(',').join(''));
|
|
223
237
|
}
|
|
224
238
|
|
|
225
|
-
getZoomValue(): number {
|
|
239
|
+
getZoomValue (): number {
|
|
226
240
|
if (this.defaultZoom != null) {
|
|
227
241
|
return this.defaultZoom;
|
|
242
|
+
} else if (this.bBox != null) {
|
|
243
|
+
return undefined;
|
|
228
244
|
} else {
|
|
229
245
|
return 16;
|
|
230
246
|
}
|
|
231
247
|
}
|
|
232
248
|
|
|
233
|
-
|
|
249
|
+
getCenter () {
|
|
250
|
+
if (this.bBox != null) {
|
|
251
|
+
const { x1, x2, y1, y2 } = this.bBox;
|
|
252
|
+
const lat = (y1 + y2) / 2;
|
|
253
|
+
const lng = (x1 + x2) / 2;
|
|
254
|
+
return [lat, lng];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const locArr = this.getLocArr();
|
|
258
|
+
return locArr;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
getLocPoint () {
|
|
234
262
|
return {
|
|
235
263
|
lat: this.getNumeric(this.latitude),
|
|
236
264
|
lng: this.getNumeric(this.longitude),
|
|
237
265
|
};
|
|
238
266
|
}
|
|
239
267
|
|
|
240
|
-
getLocArr() {
|
|
268
|
+
getLocArr () {
|
|
241
269
|
return [
|
|
242
270
|
this.getNumeric(this.latitude),
|
|
243
271
|
this.getNumeric(this.longitude),
|
|
244
272
|
];
|
|
245
273
|
}
|
|
246
274
|
|
|
247
|
-
getMap() {
|
|
275
|
+
getMap () {
|
|
248
276
|
return this.$refs.mainMap;
|
|
249
277
|
}
|
|
250
278
|
|
|
251
|
-
getLeaflet() {
|
|
279
|
+
getLeaflet () {
|
|
252
280
|
return (this.getMap() as any)?.leafletObject;
|
|
253
281
|
}
|
|
254
282
|
|
|
255
|
-
|
|
283
|
+
getBoundingBoxCorners () {
|
|
284
|
+
if (!this.bBox) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const { x1, x2, y1, y2 } = this.bBox;
|
|
289
|
+
if ([x1, x2, y1, y2].some(p => p == null)) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const minLat = Math.min(y1, y2);
|
|
294
|
+
const maxLat = Math.max(y1, y2);
|
|
295
|
+
const minLng = Math.min(x1, x2);
|
|
296
|
+
const maxLng = Math.max(x1, x2);
|
|
297
|
+
|
|
298
|
+
return [
|
|
299
|
+
[maxLat, minLng],
|
|
300
|
+
[maxLat, maxLng],
|
|
301
|
+
[minLat, maxLng],
|
|
302
|
+
[minLat, minLng],
|
|
303
|
+
[maxLat, minLng],
|
|
304
|
+
];
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
getBoundingBoxLatLngBounds (): L.LatLngBounds {
|
|
308
|
+
const corners = this.getBoundingBoxCorners();
|
|
309
|
+
if (corners.length < 2) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return L.latLngBounds(corners);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
render (h) {
|
|
256
317
|
if (this.is16by9 == false) {
|
|
257
318
|
return this.renderLeaflet(h, { height: '100%' });
|
|
258
319
|
}
|
|
@@ -270,17 +331,26 @@ export class OpenStreetMapComponent extends TsxComponent<OpenStreetMapArgs> impl
|
|
|
270
331
|
);
|
|
271
332
|
}
|
|
272
333
|
|
|
273
|
-
private renderLeaflet(h, style: object) {
|
|
334
|
+
private renderLeaflet (h, style: object) {
|
|
274
335
|
const locArr = this.getLocArr();
|
|
275
336
|
|
|
276
337
|
return (
|
|
277
|
-
<l-map style={style} zoom={this.getZoomValue()} options={this.mapOptions} maxZoom={this.maxZoom} center={
|
|
338
|
+
<l-map style={style} zoom={this.getZoomValue()} options={this.mapOptions} maxZoom={this.maxZoom} center={this.getCenter()} ref="mainMap">
|
|
278
339
|
<l-tile-layer url={this.mapUrl} options={this.options} noWrap attribution={'© <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors'}></l-tile-layer>
|
|
279
340
|
{!this.isCenterHidden
|
|
280
|
-
|
|
341
|
+
&& <l-marker lat-lng={locArr} icon={this.leafletIcon}></l-marker>}
|
|
281
342
|
|
|
282
343
|
{!isNullOrEmpty(this.geoJSON)
|
|
283
|
-
|
|
344
|
+
&& <l-geo-json ref="geoJson" options={this.geoJSONConfig != null && this.geoJSONConfig} geojson={this.geoJSONClustering ? [] : this.geoJSON}></l-geo-json>}
|
|
345
|
+
|
|
346
|
+
{this.bBox && (
|
|
347
|
+
<l-polygon
|
|
348
|
+
lat-lngs={this.getBoundingBoxCorners()}
|
|
349
|
+
color="blue"
|
|
350
|
+
weight={2}
|
|
351
|
+
fillOpacity={0.1}
|
|
352
|
+
/>
|
|
353
|
+
)}
|
|
284
354
|
|
|
285
355
|
{this.$slots.default?.()}
|
|
286
356
|
</l-map>
|