qwc2 2026.7.18 → 2026.7.30
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/components/IdentifyViewer.js +134 -28
- package/components/LayerInfoWindow.js +1 -2
- package/components/LocationRecorder.js +1 -1
- package/components/PickFeature.js +4 -2
- package/components/ResizeableWindow.js +1 -1
- package/components/SearchBox.js +6 -6
- package/components/ServiceInfoWindow.js +5 -18
- package/components/ThemeList.js +1 -2
- package/components/map3d/Map3D.js +23 -2
- package/components/map3d/utils/OrbitControls3D.js +2 -1
- package/components/style/IdentifyViewer.css +29 -0
- package/components/style/ResizeableWindow.css +14 -0
- package/components/widgets/ColorButton.js +38 -30
- package/components/widgets/FeaturesTable.js +369 -0
- package/components/widgets/LayerCatalogWidget.js +14 -6
- package/components/widgets/TextInput.js +4 -5
- package/components/widgets/style/ColorButton.css +15 -4
- package/components/widgets/style/FeaturesTable.css +133 -0
- package/icons/trash_checked.svg +92 -0
- package/package.json +1 -1
- package/plugins/FeatureForm.js +1 -2
- package/plugins/HeightProfile.js +4 -0
- package/plugins/Identify.js +60 -19
- package/plugins/LayerCatalog.js +5 -0
- package/plugins/LayerTree.js +24 -10
- package/plugins/MapCopyright.js +2 -2
- package/plugins/MapExport.js +4 -0
- package/plugins/MapTip.js +2 -4
- package/plugins/Print.js +4 -0
- package/plugins/Routing.js +1 -1
- package/plugins/ServiceInfo.js +109 -0
- package/plugins/TaskButton.js +2 -10
- package/plugins/TopBar.js +1 -1
- package/plugins/VisibilityPreset.js +14 -14
- package/plugins/map3d/Compare3D.js +11 -2
- package/plugins/map3d/Identify3D.js +1 -2
- package/plugins/map3d/MapCopyright3D.js +2 -2
- package/plugins/map3d/Viewshed3D.js +387 -0
- package/plugins/map3d/style/Viewshed3D.css +26 -0
- package/plugins/redlining/RedliningFeatureLabelSupport.js +6 -5
- package/static/translations/bg-BG.json +10 -0
- package/static/translations/ca-ES.json +10 -0
- package/static/translations/cs-CZ.json +10 -0
- package/static/translations/de-CH.json +10 -0
- package/static/translations/de-DE.json +10 -0
- package/static/translations/en-US.json +10 -0
- package/static/translations/es-ES.json +10 -0
- package/static/translations/fi-FI.json +10 -0
- package/static/translations/fr-FR.json +11 -1
- package/static/translations/hu-HU.json +10 -0
- package/static/translations/it-IT.json +10 -0
- package/static/translations/ja-JP.json +10 -0
- package/static/translations/nl-NL.json +10 -0
- package/static/translations/no-NO.json +10 -0
- package/static/translations/pl-PL.json +10 -0
- package/static/translations/pt-BR.json +10 -0
- package/static/translations/pt-PT.json +10 -0
- package/static/translations/ro-RO.json +10 -0
- package/static/translations/ru-RU.json +10 -0
- package/static/translations/sv-SE.json +10 -0
- package/static/translations/tr-TR.json +10 -0
- package/static/translations/tsconfig.json +9 -0
- package/static/translations/uk-UA.json +10 -0
- package/utils/EditingUtils.js +16 -13
- package/utils/LayerUtils.js +3 -2
- package/utils/MiscUtils.js +9 -0
- package/utils/VectorLayerUtils.js +67 -28
- package/utils/expr_grammar/grammar.js +78 -24
- package/utils/expr_grammar/grammar.ne +2 -1
- package/utils/expr_grammar/test.js +6 -0
- package/actions/serviceinfo.js +0 -18
- package/reducers/serviceinfo.js +0 -30
|
@@ -25,7 +25,6 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
25
25
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
26
26
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
27
27
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
28
|
-
import htmlReactParser, { domToReact } from 'html-react-parser';
|
|
29
28
|
/**
|
|
30
29
|
* Copyright 2016-2024 Sourcepole AG
|
|
31
30
|
* All rights reserved.
|
|
@@ -33,11 +32,11 @@ import htmlReactParser, { domToReact } from 'html-react-parser';
|
|
|
33
32
|
* This source code is licensed under the BSD-style license found in the
|
|
34
33
|
* LICENSE file in the root directory of this source tree.
|
|
35
34
|
*/
|
|
35
|
+
import htmlReactParser, { domToReact } from 'html-react-parser';
|
|
36
36
|
import React from 'react';
|
|
37
37
|
import { connect } from 'react-redux';
|
|
38
38
|
import axios from 'axios';
|
|
39
39
|
import clone from 'clone';
|
|
40
|
-
import DOMPurify from 'dompurify';
|
|
41
40
|
import FileSaver from 'file-saver';
|
|
42
41
|
import JSZip from 'jszip';
|
|
43
42
|
import isEmpty from 'lodash.isempty';
|
|
@@ -53,8 +52,11 @@ import LayerUtils from '../utils/LayerUtils';
|
|
|
53
52
|
import LocaleUtils from '../utils/LocaleUtils';
|
|
54
53
|
import MapUtils from '../utils/MapUtils';
|
|
55
54
|
import MiscUtils, { ToggleSet } from '../utils/MiscUtils';
|
|
55
|
+
import { registerPermalinkDataStoreHook, unregisterPermalinkDataStoreHook } from '../utils/PermaLinkUtils';
|
|
56
56
|
import VectorLayerUtils from '../utils/VectorLayerUtils';
|
|
57
57
|
import Icon from './Icon';
|
|
58
|
+
import ButtonBar from './widgets/ButtonBar';
|
|
59
|
+
import FeaturesTable from './widgets/FeaturesTable';
|
|
58
60
|
import NavBar from './widgets/NavBar';
|
|
59
61
|
import Spinner from './widgets/Spinner';
|
|
60
62
|
import ToggleSwitch from './widgets/ToggleSwitch';
|
|
@@ -354,7 +356,16 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
354
356
|
compareEnabled: false,
|
|
355
357
|
multiViewEnabled: false,
|
|
356
358
|
currentPage: 0,
|
|
357
|
-
pageSize: 1
|
|
359
|
+
pageSize: 1,
|
|
360
|
+
tableSelection: {}
|
|
361
|
+
});
|
|
362
|
+
_defineProperty(_this, "storeIdentifyResults", function () {
|
|
363
|
+
return new Promise(function (resolve) {
|
|
364
|
+
return resolve({
|
|
365
|
+
identifyResults: _this.state.resultTree,
|
|
366
|
+
currentResultDisplayMode: _this.props.resultDisplayMode
|
|
367
|
+
});
|
|
368
|
+
});
|
|
358
369
|
});
|
|
359
370
|
_defineProperty(_this, "getCurrentResultFeature", function () {
|
|
360
371
|
var _this$state$resultTre, _this$state$resultTre2, _this$state$resultTre3, _this$state$currentRe;
|
|
@@ -378,7 +389,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
378
389
|
});
|
|
379
390
|
});
|
|
380
391
|
_defineProperty(_this, "setHighlightedFeatures", function (features) {
|
|
381
|
-
if (
|
|
392
|
+
if (isEmpty(features) && _this.props.highlightAllResults) {
|
|
382
393
|
var resultTree = _this.state.selectedLayer !== '' ? _defineProperty({}, _this.state.selectedLayer, _this.state.resultTree[_this.state.selectedLayer]) : _this.state.resultTree;
|
|
383
394
|
features = Object.values(resultTree).flat();
|
|
384
395
|
}
|
|
@@ -672,7 +683,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
672
683
|
});
|
|
673
684
|
} else {
|
|
674
685
|
rows = properties.map(function (attrib) {
|
|
675
|
-
if (_this.props.theme.skipEmptyFeatureAttributes && (feature.properties[attrib] === "" || feature.properties[attrib] === null || feature.properties[attrib] === "NULL")) {
|
|
686
|
+
if ((_this.props.theme.skipEmptyFeatureAttributes || _this.props.skipEmptyFeatureAttributes) && (feature.properties[attrib] === "" || feature.properties[attrib] === null || feature.properties[attrib] === "NULL")) {
|
|
676
687
|
return null;
|
|
677
688
|
}
|
|
678
689
|
return /*#__PURE__*/React.createElement("tr", {
|
|
@@ -790,6 +801,101 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
790
801
|
};
|
|
791
802
|
});
|
|
792
803
|
});
|
|
804
|
+
_defineProperty(_this, "renderResultsTable", function () {
|
|
805
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
806
|
+
className: "identify-results-tables"
|
|
807
|
+
}, Object.entries(_this.state.resultTree).map(function (_ref16) {
|
|
808
|
+
var _ref17 = _slicedToArray(_ref16, 2),
|
|
809
|
+
layerid = _ref17[0],
|
|
810
|
+
features = _ref17[1];
|
|
811
|
+
if (features.length === 0 || _this.state.selectedLayer && layerid !== _this.state.selectedLayer) {
|
|
812
|
+
return null;
|
|
813
|
+
}
|
|
814
|
+
var fields = {};
|
|
815
|
+
features.map(function (feature) {
|
|
816
|
+
Object.entries(feature.properties).map(function (_ref18) {
|
|
817
|
+
var _ref19 = _slicedToArray(_ref18, 2),
|
|
818
|
+
attr = _ref19[0],
|
|
819
|
+
value = _ref19[1];
|
|
820
|
+
if (!(attr in fields)) {
|
|
821
|
+
fields[attr] = {
|
|
822
|
+
id: attr,
|
|
823
|
+
name: attr
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
});
|
|
828
|
+
var haveSel = !isEmpty(_this.state.tableSelection[layerid]);
|
|
829
|
+
var buttons = [{
|
|
830
|
+
key: "Export",
|
|
831
|
+
icon: "export"
|
|
832
|
+
}, {
|
|
833
|
+
key: "Delete",
|
|
834
|
+
icon: haveSel ? "trash_checked" : "trash"
|
|
835
|
+
}];
|
|
836
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
837
|
+
className: "identify-results-table-container",
|
|
838
|
+
key: layerid
|
|
839
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
840
|
+
className: "identify-results-table-titlebar"
|
|
841
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
842
|
+
icon: _this.state.collapsedLayers.has(layerid) ? "expand" : "collapse",
|
|
843
|
+
onClick: function onClick() {
|
|
844
|
+
return _this.setState(function (state) {
|
|
845
|
+
return {
|
|
846
|
+
collapsedLayers: state.collapsedLayers.toggle(layerid)
|
|
847
|
+
};
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
}), /*#__PURE__*/React.createElement("span", null, features[0].layertitle, " (", features.length, ")"), /*#__PURE__*/React.createElement(ButtonBar, {
|
|
851
|
+
buttons: buttons,
|
|
852
|
+
onClick: function onClick(action) {
|
|
853
|
+
return _this.tableAction(layerid, action);
|
|
854
|
+
}
|
|
855
|
+
})), !_this.state.collapsedLayers.has(layerid) ? /*#__PURE__*/React.createElement(FeaturesTable, {
|
|
856
|
+
allowSelectAll: true,
|
|
857
|
+
features: features,
|
|
858
|
+
fields: Object.values(fields),
|
|
859
|
+
hideIdColumn: true,
|
|
860
|
+
highlightFeatures: _this.setHighlightedFeatures,
|
|
861
|
+
selectionChanged: function selectionChanged(sel) {
|
|
862
|
+
return _this.setState(function (state) {
|
|
863
|
+
return {
|
|
864
|
+
tableSelection: _objectSpread(_objectSpread({}, state.tableSelection), {}, _defineProperty({}, layerid, sel))
|
|
865
|
+
};
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
}) : null);
|
|
869
|
+
}));
|
|
870
|
+
});
|
|
871
|
+
_defineProperty(_this, "tableAction", function (layerid, action) {
|
|
872
|
+
if (action === "Export") {
|
|
873
|
+
var features = isEmpty(_this.state.tableSelection[layerid]) ? _this.state.resultTree[layerid] : Object.values(_this.state.tableSelection[layerid]);
|
|
874
|
+
_this["export"]({
|
|
875
|
+
layerid: features
|
|
876
|
+
});
|
|
877
|
+
} else if (action === "Delete") {
|
|
878
|
+
_this.setState(function (state) {
|
|
879
|
+
var tableSelection = state.tableSelection;
|
|
880
|
+
var selection = state.tableSelection[layerid];
|
|
881
|
+
var newLayerResults = !isEmpty(selection) ? state.resultTree[layerid].filter(function (f) {
|
|
882
|
+
return !(f.id in selection);
|
|
883
|
+
}) : [];
|
|
884
|
+
var newResultTree = _objectSpread({}, state.resultTree);
|
|
885
|
+
if (isEmpty(newLayerResults)) {
|
|
886
|
+
delete newResultTree[layerid];
|
|
887
|
+
tableSelection = _objectSpread({}, tableSelection);
|
|
888
|
+
delete tableSelection[layerid];
|
|
889
|
+
} else {
|
|
890
|
+
newResultTree[layerid] = newLayerResults;
|
|
891
|
+
}
|
|
892
|
+
return {
|
|
893
|
+
resultTree: newResultTree,
|
|
894
|
+
tableSelection: tableSelection
|
|
895
|
+
};
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
});
|
|
793
899
|
_defineProperty(_this, "initBody", function (el) {
|
|
794
900
|
if (el) {
|
|
795
901
|
// HACK to trigger an additional repaint, since Safari/Chrome on iOS render the element cut off the first time
|
|
@@ -857,7 +963,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
857
963
|
var haveSettings = Object.values(enabledSettings).find(Boolean) !== undefined;
|
|
858
964
|
return /*#__PURE__*/React.createElement("div", {
|
|
859
965
|
className: "identify-toolbar"
|
|
860
|
-
}, haveSettings ? toggleButton("settingsMenu", "cog", false) : null, _this.state.settingsMenu ? _this.renderSettingsMenu(enabledSettings) : null, _this.props.enableCompare ? toggleButton("compareEnabled", "compare", _this.state.selectedResults.size() < 2, LocaleUtils.tr("identify.compare")) : null, /*#__PURE__*/React.createElement("span", {
|
|
966
|
+
}, haveSettings ? toggleButton("settingsMenu", "cog", false) : null, _this.state.settingsMenu ? _this.renderSettingsMenu(enabledSettings) : null, _this.props.enableCompare && _this.props.resultDisplayMode !== "table" ? toggleButton("compareEnabled", "compare", _this.state.selectedResults.size() < 2, LocaleUtils.tr("identify.compare")) : null, /*#__PURE__*/React.createElement("span", {
|
|
861
967
|
className: "identify-toolbar-spacer"
|
|
862
968
|
}), infoLabel, /*#__PURE__*/React.createElement("span", {
|
|
863
969
|
className: "identify-toolbar-spacer"
|
|
@@ -952,10 +1058,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
952
1058
|
}, /*#__PURE__*/React.createElement("option", {
|
|
953
1059
|
disabled: true,
|
|
954
1060
|
value: ""
|
|
955
|
-
}, LocaleUtils.tr("identify.selectreport")), Object.entries(_this.state.reports).map(function (
|
|
956
|
-
var
|
|
957
|
-
layername =
|
|
958
|
-
reports =
|
|
1061
|
+
}, LocaleUtils.tr("identify.selectreport")), Object.entries(_this.state.reports).map(function (_ref21) {
|
|
1062
|
+
var _ref22 = _slicedToArray(_ref21, 2),
|
|
1063
|
+
layername = _ref22[0],
|
|
1064
|
+
reports = _ref22[1];
|
|
959
1065
|
return reports.map(function (report, idx) {
|
|
960
1066
|
return /*#__PURE__*/React.createElement("option", {
|
|
961
1067
|
key: layername + "::" + idx,
|
|
@@ -1164,12 +1270,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1164
1270
|
return _this.parsedContent(text);
|
|
1165
1271
|
});
|
|
1166
1272
|
_defineProperty(_this, "parsedContent", function (text) {
|
|
1167
|
-
text =
|
|
1168
|
-
ADD_ATTR: ['target'],
|
|
1169
|
-
ADD_TAGS: ["iframe"],
|
|
1170
|
-
FORCE_BODY: true,
|
|
1171
|
-
ALLOW_UNKNOWN_PROTOCOLS: true
|
|
1172
|
-
}).replace(' ', '<br />');
|
|
1273
|
+
text = MiscUtils.sanitizeHtml(text).replace(' ', '<br />');
|
|
1173
1274
|
var options = {
|
|
1174
1275
|
replace: function replace(node) {
|
|
1175
1276
|
if (node.name === "a") {
|
|
@@ -1216,6 +1317,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1216
1317
|
_this.bodyEl = null;
|
|
1217
1318
|
_this.state.exportFormat = !Array.isArray(props.enableExport) ? 'geojson' : props.enableExport[0];
|
|
1218
1319
|
_this.state.multiViewEnabled = props.resultMultiDisplay;
|
|
1320
|
+
registerPermalinkDataStoreHook("identifyresultstate", _this.storeIdentifyResults);
|
|
1219
1321
|
return _this;
|
|
1220
1322
|
}
|
|
1221
1323
|
_inherits(IdentifyViewer, _React$Component);
|
|
@@ -1256,6 +1358,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1256
1358
|
key: "componentWillUnmount",
|
|
1257
1359
|
value: function componentWillUnmount() {
|
|
1258
1360
|
this.props.removeLayer("__identifyviewerhighlight");
|
|
1361
|
+
unregisterPermalinkDataStoreHook("identifyresultstate");
|
|
1259
1362
|
}
|
|
1260
1363
|
}, {
|
|
1261
1364
|
key: "render",
|
|
@@ -1263,10 +1366,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1263
1366
|
var _this2 = this;
|
|
1264
1367
|
var body = null;
|
|
1265
1368
|
var resultTree = this.state.selectedLayer !== '' ? _defineProperty({}, this.state.selectedLayer, this.state.resultTree[this.state.selectedLayer]) : this.state.resultTree;
|
|
1266
|
-
var flatResults = Object.entries(resultTree).map(function (
|
|
1267
|
-
var
|
|
1268
|
-
layerid =
|
|
1269
|
-
features =
|
|
1369
|
+
var flatResults = Object.entries(resultTree).map(function (_ref25) {
|
|
1370
|
+
var _ref26 = _slicedToArray(_ref25, 2),
|
|
1371
|
+
layerid = _ref26[0],
|
|
1372
|
+
features = _ref26[1];
|
|
1270
1373
|
return features.map(function (feature) {
|
|
1271
1374
|
return [layerid, feature];
|
|
1272
1375
|
});
|
|
@@ -1294,10 +1397,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1294
1397
|
} else if (this.props.resultDisplayMode === 'flat') {
|
|
1295
1398
|
body = /*#__PURE__*/React.createElement("div", {
|
|
1296
1399
|
className: "identify-flat-results-list"
|
|
1297
|
-
}, Object.entries(resultTree).map(function (
|
|
1298
|
-
var
|
|
1299
|
-
layerid =
|
|
1300
|
-
features =
|
|
1400
|
+
}, Object.entries(resultTree).map(function (_ref27) {
|
|
1401
|
+
var _ref28 = _slicedToArray(_ref27, 2),
|
|
1402
|
+
layerid = _ref28[0],
|
|
1403
|
+
features = _ref28[1];
|
|
1301
1404
|
return features.map(function (feature) {
|
|
1302
1405
|
return _this2.renderResultAttributes(layerid, feature, 'identify-result-frame');
|
|
1303
1406
|
});
|
|
@@ -1311,10 +1414,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1311
1414
|
body = /*#__PURE__*/React.createElement("div", {
|
|
1312
1415
|
className: "identify-compare-results",
|
|
1313
1416
|
style: _style
|
|
1314
|
-
}, results.map(function (
|
|
1315
|
-
var
|
|
1316
|
-
layerid =
|
|
1317
|
-
feature =
|
|
1417
|
+
}, results.map(function (_ref29) {
|
|
1418
|
+
var _ref30 = _slicedToArray(_ref29, 2),
|
|
1419
|
+
layerid = _ref30[0],
|
|
1420
|
+
feature = _ref30[1];
|
|
1318
1421
|
return _this2.renderResultAttributes(layerid, feature, 'identify-result-frame');
|
|
1319
1422
|
}));
|
|
1320
1423
|
} else if (this.state.currentPage < flatResults.length) {
|
|
@@ -1325,6 +1428,8 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
|
|
|
1325
1428
|
className: "identify-flat-results-list"
|
|
1326
1429
|
}, this.renderResultAttributes(layerid, feature, 'identify-result-frame'));
|
|
1327
1430
|
}
|
|
1431
|
+
} else if (this.props.resultDisplayMode === 'table') {
|
|
1432
|
+
body = this.renderResultsTable();
|
|
1328
1433
|
}
|
|
1329
1434
|
return /*#__PURE__*/React.createElement("div", {
|
|
1330
1435
|
className: "identify-body",
|
|
@@ -1359,6 +1464,7 @@ _defineProperty(IdentifyViewer, "propTypes", {
|
|
|
1359
1464
|
setActiveLayerInfo: PropTypes.func,
|
|
1360
1465
|
showLayerSelector: PropTypes.bool,
|
|
1361
1466
|
showLayerTitles: PropTypes.bool,
|
|
1467
|
+
skipEmptyFeatureAttributes: PropTypes.bool,
|
|
1362
1468
|
theme: PropTypes.object,
|
|
1363
1469
|
zoomToPoint: PropTypes.func
|
|
1364
1470
|
});
|
|
@@ -22,7 +22,6 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
22
22
|
|
|
23
23
|
import React from 'react';
|
|
24
24
|
import { connect } from 'react-redux';
|
|
25
|
-
import DOMPurify from 'dompurify';
|
|
26
25
|
import PropTypes from 'prop-types';
|
|
27
26
|
import { setActiveLayerInfo } from '../actions/layerinfo';
|
|
28
27
|
import ResizeableWindow from '../components/ResizeableWindow';
|
|
@@ -45,7 +44,7 @@ var LayerInfoWindow = /*#__PURE__*/function (_React$Component) {
|
|
|
45
44
|
if (content) {
|
|
46
45
|
return /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, title, ":"), html ? /*#__PURE__*/React.createElement("td", {
|
|
47
46
|
dangerouslySetInnerHTML: {
|
|
48
|
-
__html: MiscUtils.addLinkAnchors(
|
|
47
|
+
__html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(content))
|
|
49
48
|
}
|
|
50
49
|
}) : /*#__PURE__*/React.createElement("td", null, content));
|
|
51
50
|
}
|
|
@@ -45,7 +45,7 @@ var LocationRecorder = /*#__PURE__*/function (_React$Component) {
|
|
|
45
45
|
} else {
|
|
46
46
|
_this.props.drawInteraction.abortDrawing();
|
|
47
47
|
_this.props.drawInteraction.setActive(false);
|
|
48
|
-
// Re-add overlay to map, removed by setActive(false), to ensure traced feature is
|
|
48
|
+
// Re-add overlay to map, removed by setActive(false), to ensure traced feature is visible
|
|
49
49
|
_this.props.drawInteraction.getOverlay().setMap(_this.props.map);
|
|
50
50
|
_this.setState({
|
|
51
51
|
recording: true
|
|
@@ -94,7 +94,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
|
|
|
94
94
|
};
|
|
95
95
|
if (newState.pendingQueries === 0) {
|
|
96
96
|
if (newState.pickResults.length === 1) {
|
|
97
|
-
_this.props.featurePicked(newState.pickResults[0].layer, newState.pickResults[0].feature, newState.pickResults[0].mapName);
|
|
97
|
+
_this.props.featurePicked(newState.pickResults[0].layer, newState.pickResults[0].feature, newState.pickResults[0].mapName, state.mapPos);
|
|
98
98
|
newState.pickResults = null;
|
|
99
99
|
newState.pickGeom = null;
|
|
100
100
|
} else if (newState.pickResults.length === 0) {
|
|
@@ -237,6 +237,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
|
|
|
237
237
|
return {
|
|
238
238
|
pickResults: pickResults,
|
|
239
239
|
clickPos: clickPos,
|
|
240
|
+
mapPos: [maxX, maxY],
|
|
240
241
|
pendingQueries: queryWmsLayers.length,
|
|
241
242
|
reqId: reqId
|
|
242
243
|
};
|
|
@@ -261,7 +262,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
|
|
|
261
262
|
return /*#__PURE__*/React.createElement("div", {
|
|
262
263
|
key: key,
|
|
263
264
|
onClick: function onClick() {
|
|
264
|
-
return _this3.props.featurePicked(entry.layer, entry.feature, entry.mapName);
|
|
265
|
+
return _this3.props.featurePicked(entry.layer, entry.feature, entry.mapName, _this3.state.mapPos);
|
|
265
266
|
},
|
|
266
267
|
onMouseOut: function onMouseOut() {
|
|
267
268
|
return _this3.clearHighlight(key, entry.feature);
|
|
@@ -330,6 +331,7 @@ _defineProperty(PickFeature, "defaultState", {
|
|
|
330
331
|
pickGeom: null,
|
|
331
332
|
pickResults: null,
|
|
332
333
|
clickPos: null,
|
|
334
|
+
mapPos: null,
|
|
333
335
|
highlightedFeature: null,
|
|
334
336
|
pendingQueries: 0,
|
|
335
337
|
reqId: null
|
|
@@ -319,7 +319,7 @@ var ResizeableWindow = /*#__PURE__*/function (_React$Component) {
|
|
|
319
319
|
}, _this.renderTitleBar(), /*#__PURE__*/React.createElement("div", {
|
|
320
320
|
className: "resizeable-window-body"
|
|
321
321
|
}, _this.portalNode ? /*#__PURE__*/React.createElement("div", {
|
|
322
|
-
className: "resizeable-window-portal-container"
|
|
322
|
+
className: "resizeable-window-portal-container resizeable-window-portal-container-detached"
|
|
323
323
|
}, /*#__PURE__*/React.createElement(portals.OutPortal, {
|
|
324
324
|
node: _this.portalNode
|
|
325
325
|
})) : _this.props.children)), _this.state.externalWindow.document.body);
|
package/components/SearchBox.js
CHANGED
|
@@ -36,7 +36,6 @@ import React from 'react';
|
|
|
36
36
|
import { connect } from 'react-redux';
|
|
37
37
|
import axios from 'axios';
|
|
38
38
|
import classnames from 'classnames';
|
|
39
|
-
import DOMPurify from 'dompurify';
|
|
40
39
|
import isEmpty from 'lodash.isempty';
|
|
41
40
|
import pointInPolygon from 'point-in-polygon';
|
|
42
41
|
import polygonIntersectTest from 'polygon-intersect-test';
|
|
@@ -410,7 +409,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
|
|
|
410
409
|
}) : null, /*#__PURE__*/React.createElement("span", {
|
|
411
410
|
className: "searchbox-result-label",
|
|
412
411
|
dangerouslySetInnerHTML: {
|
|
413
|
-
__html:
|
|
412
|
+
__html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
|
|
414
413
|
},
|
|
415
414
|
title: (_result$label = result.label) !== null && _result$label !== void 0 ? _result$label : result.text
|
|
416
415
|
}), result.externalLink ? /*#__PURE__*/React.createElement(Icon, {
|
|
@@ -468,7 +467,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
|
|
|
468
467
|
}) : null, /*#__PURE__*/React.createElement("span", {
|
|
469
468
|
className: "searchbox-result-label",
|
|
470
469
|
dangerouslySetInnerHTML: {
|
|
471
|
-
__html:
|
|
470
|
+
__html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
|
|
472
471
|
},
|
|
473
472
|
title: (_result$label3 = result.label) !== null && _result$label3 !== void 0 ? _result$label3 : result.text
|
|
474
473
|
}), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
|
|
@@ -501,7 +500,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
|
|
|
501
500
|
}) : null), _this.state.activeLayerInfo === key ? /*#__PURE__*/React.createElement("div", {
|
|
502
501
|
className: "searchbox-result-abstract",
|
|
503
502
|
dangerouslySetInnerHTML: {
|
|
504
|
-
__html: MiscUtils.addLinkAnchors(
|
|
503
|
+
__html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(((_result$layer = result.layer) === null || _result$layer === void 0 ? void 0 : _result$layer["abstract"]) || "")) || LocaleUtils.tr("search.nodescription")
|
|
505
504
|
},
|
|
506
505
|
disabled: true,
|
|
507
506
|
key: key + ":abstract",
|
|
@@ -533,13 +532,14 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
|
|
|
533
532
|
}), /*#__PURE__*/React.createElement("span", {
|
|
534
533
|
className: "searchbox-result-label",
|
|
535
534
|
dangerouslySetInnerHTML: {
|
|
536
|
-
__html:
|
|
535
|
+
__html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
|
|
537
536
|
},
|
|
538
537
|
title: (_result$label5 = result.label) !== null && _result$label5 !== void 0 ? _result$label5 : result.text
|
|
539
538
|
}), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
|
|
540
539
|
icon: "plus",
|
|
541
540
|
onClick: function onClick(ev) {
|
|
542
|
-
|
|
541
|
+
MiscUtils.killEvent(ev);
|
|
542
|
+
_this.addThemeLayers(result.layer);
|
|
543
543
|
},
|
|
544
544
|
title: LocaleUtils.tr("themeswitcher.addtotheme")
|
|
545
545
|
}) : null);
|
|
@@ -21,10 +21,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import React from 'react';
|
|
24
|
-
import { connect } from 'react-redux';
|
|
25
|
-
import DOMPurify from 'dompurify';
|
|
26
24
|
import PropTypes from 'prop-types';
|
|
27
|
-
import { setActiveServiceInfo } from '../actions/serviceinfo';
|
|
28
25
|
import ResizeableWindow from '../components/ResizeableWindow';
|
|
29
26
|
import LocaleUtils from '../utils/LocaleUtils';
|
|
30
27
|
import MiscUtils from '../utils/MiscUtils';
|
|
@@ -42,15 +39,12 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
|
|
|
42
39
|
if (content) {
|
|
43
40
|
return /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, title, ":"), html ? /*#__PURE__*/React.createElement("td", {
|
|
44
41
|
dangerouslySetInnerHTML: {
|
|
45
|
-
__html: MiscUtils.addLinkAnchors(
|
|
42
|
+
__html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(content))
|
|
46
43
|
}
|
|
47
44
|
}) : /*#__PURE__*/React.createElement("td", null, content));
|
|
48
45
|
}
|
|
49
46
|
return null;
|
|
50
47
|
});
|
|
51
|
-
_defineProperty(_this, "onClose", function () {
|
|
52
|
-
_this.props.setActiveServiceInfo(null);
|
|
53
|
-
});
|
|
54
48
|
return _this;
|
|
55
49
|
}
|
|
56
50
|
_inherits(ServiceInfoWindow, _React$Component);
|
|
@@ -82,7 +76,7 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
|
|
|
82
76
|
initialX: this.props.layerInfoGeometry.initialX,
|
|
83
77
|
initialY: this.props.layerInfoGeometry.initialY,
|
|
84
78
|
initiallyDocked: this.props.layerInfoGeometry.initiallyDocked,
|
|
85
|
-
onClose: this.onClose,
|
|
79
|
+
onClose: this.props.onClose,
|
|
86
80
|
title: LocaleUtils.tr("serviceinfo.title")
|
|
87
81
|
}, /*#__PURE__*/React.createElement("div", {
|
|
88
82
|
className: "service-info-window-body"
|
|
@@ -98,14 +92,7 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
|
|
|
98
92
|
}(React.Component);
|
|
99
93
|
_defineProperty(ServiceInfoWindow, "propTypes", {
|
|
100
94
|
layerInfoGeometry: PropTypes.object,
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
onClose: PropTypes.func,
|
|
96
|
+
service: PropTypes.object
|
|
103
97
|
});
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
service: state.serviceinfo.service
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
export default connect(selector, {
|
|
110
|
-
setActiveServiceInfo: setActiveServiceInfo
|
|
111
|
-
})(ServiceInfoWindow);
|
|
98
|
+
export default ServiceInfoWindow;
|
package/components/ThemeList.js
CHANGED
|
@@ -29,7 +29,6 @@ import React from 'react';
|
|
|
29
29
|
import { connect } from 'react-redux';
|
|
30
30
|
import axios from 'axios';
|
|
31
31
|
import { remove as removeDiacritics } from 'diacritics';
|
|
32
|
-
import DOMPurify from 'dompurify';
|
|
33
32
|
import isEmpty from 'lodash.isempty';
|
|
34
33
|
import PropTypes from 'prop-types';
|
|
35
34
|
import { setActiveLayerInfo } from '../actions/layerinfo';
|
|
@@ -180,7 +179,7 @@ var ThemeList = /*#__PURE__*/function (_React$Component) {
|
|
|
180
179
|
}, item.description ? /*#__PURE__*/React.createElement("div", {
|
|
181
180
|
className: "theme-item-description",
|
|
182
181
|
dangerouslySetInnerHTML: {
|
|
183
|
-
__html:
|
|
182
|
+
__html: MiscUtils.sanitizeHtml(item.description)
|
|
184
183
|
}
|
|
185
184
|
}) : null, /*#__PURE__*/React.createElement("img", {
|
|
186
185
|
className: "theme-item-thumbnail",
|
|
@@ -148,6 +148,8 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
148
148
|
zoomToObject: function zoomToObject(objectId) {},
|
|
149
149
|
objectIsVisible: function objectIsVisible(objectId) {},
|
|
150
150
|
objectContainsPoints: function objectContainsPoints(object) {},
|
|
151
|
+
addObjectAddedListener: function addObjectAddedListener(callback) {},
|
|
152
|
+
removeObjectAddedListener: function removeObjectAddedListener(callback) {},
|
|
151
153
|
getMap: function getMap() {},
|
|
152
154
|
computeBoundsTree: function computeBoundsTree(object) {},
|
|
153
155
|
setViewToExtent: function setViewToExtent(bounds, angle) {},
|
|
@@ -384,6 +386,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
384
386
|
}
|
|
385
387
|
_this2.computeBoundsTree(scene);
|
|
386
388
|
_this2.instance.notifyChange(tiles);
|
|
389
|
+
_this2.notifyObjectAdded(scene);
|
|
387
390
|
});
|
|
388
391
|
// Show/hide labels when tile visibility changes
|
|
389
392
|
tiles.tiles.addEventListener('tile-visibility-change', function (_ref3) {
|
|
@@ -394,6 +397,9 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
394
397
|
l.labelObject.visible = visible;
|
|
395
398
|
l.labelObject.element.style.display = visible ? 'initial' : 'none';
|
|
396
399
|
});
|
|
400
|
+
if (visible) {
|
|
401
|
+
_this2.notifyObjectAdded(scene);
|
|
402
|
+
}
|
|
397
403
|
});
|
|
398
404
|
tiles.castShadow = true;
|
|
399
405
|
tiles.receiveShadow = true;
|
|
@@ -473,6 +479,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
473
479
|
});
|
|
474
480
|
} else {
|
|
475
481
|
_this2.sceneObjectGroup.add(object);
|
|
482
|
+
_this2.notifyObjectAdded(object);
|
|
476
483
|
callback === null || callback === void 0 || callback();
|
|
477
484
|
}
|
|
478
485
|
_this2.objectMap[objectId] = object;
|
|
@@ -583,7 +590,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
583
590
|
var changed = false;
|
|
584
591
|
if (options.visibility !== prevOptions.visibility || options.opacity !== (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.opacity)) {
|
|
585
592
|
var _objectTree$options$p2;
|
|
586
|
-
//
|
|
593
|
+
// Visible if object is visible and parents also
|
|
587
594
|
var isVisible = options.opacity > 0 && options.visibility;
|
|
588
595
|
for (var curId = options.parent; isVisible && curId !== undefined; curId = objectTree[curId].parent) {
|
|
589
596
|
isVisible && (isVisible = objectTree[curId].visibility);
|
|
@@ -647,6 +654,11 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
647
654
|
}
|
|
648
655
|
});
|
|
649
656
|
});
|
|
657
|
+
_defineProperty(_this2, "notifyObjectAdded", function (obj) {
|
|
658
|
+
_this2.objectAddedListeners.forEach(function (listener) {
|
|
659
|
+
return listener(obj);
|
|
660
|
+
});
|
|
661
|
+
});
|
|
650
662
|
_defineProperty(_this2, "loadTilesetStyle", function (objectId, url) {
|
|
651
663
|
var applyTilesetStyle = function applyTilesetStyle(styleurl) {
|
|
652
664
|
var tiles3d = _this2.objectMap[objectId];
|
|
@@ -690,7 +702,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
690
702
|
var objectTree = _this2.state.sceneContext.objectTree;
|
|
691
703
|
var options = objectTree[objectId];
|
|
692
704
|
var isVisible = options.opacity > 0 && options.visibility;
|
|
693
|
-
for (var curId = options.parent; isVisible && curId !== undefined; curId = objectTree[curId].parent) {
|
|
705
|
+
for (var curId = options.parent; isVisible && curId !== undefined && objectTree[curId]; curId = objectTree[curId].parent) {
|
|
694
706
|
isVisible && (isVisible = objectTree[curId].visibility);
|
|
695
707
|
}
|
|
696
708
|
return isVisible;
|
|
@@ -1302,6 +1314,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
1302
1314
|
_this2.sceneObjectGroup = null;
|
|
1303
1315
|
_this2.objectMap = {};
|
|
1304
1316
|
_this2.tilesetStyles = {};
|
|
1317
|
+
_this2.objectAddedListeners = [];
|
|
1305
1318
|
_this2.state.sceneContext.eventDispatcher = new EventDispatcher();
|
|
1306
1319
|
_this2.state.sceneContext.addLayer = _this2.addLayer;
|
|
1307
1320
|
_this2.state.sceneContext.getLayer = _this2.getLayer;
|
|
@@ -1314,6 +1327,14 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
|
|
|
1314
1327
|
_this2.state.sceneContext.getSceneObject = _this2.getSceneObject;
|
|
1315
1328
|
_this2.state.sceneContext.removeSceneObject = _this2.removeSceneObject;
|
|
1316
1329
|
_this2.state.sceneContext.updateSceneObject = _this2.updateSceneObject;
|
|
1330
|
+
_this2.state.sceneContext.addObjectAddedListener = function (callback) {
|
|
1331
|
+
return _this2.objectAddedListeners.push(callback);
|
|
1332
|
+
};
|
|
1333
|
+
_this2.state.sceneContext.removeObjectAddedListener = function (callback) {
|
|
1334
|
+
_this2.objectAddedListeners = _this2.objectAddedListeners.filter(function (cb) {
|
|
1335
|
+
return cb !== callback;
|
|
1336
|
+
});
|
|
1337
|
+
};
|
|
1317
1338
|
_this2.state.sceneContext.zoomToObject = _this2.zoomToObject;
|
|
1318
1339
|
_this2.state.sceneContext.objectIsVisible = _this2.objectIsVisible;
|
|
1319
1340
|
_this2.state.sceneContext.objectContainsPoints = _this2.objectContainsPoints;
|
|
@@ -79,12 +79,13 @@ var OrbitControls3D = /*#__PURE__*/function (_MapControls) {
|
|
|
79
79
|
key: "disconnect",
|
|
80
80
|
value: function disconnect() {
|
|
81
81
|
this.animationId = null;
|
|
82
|
-
_superPropGet(OrbitControls3D, "disconnect", this, 3)([]);
|
|
83
82
|
this.enabled = false;
|
|
84
83
|
this.sceneContext.scene.view.setControls(null);
|
|
85
84
|
this.domElement.removeEventListener('pointerdown', this.stopAnimations);
|
|
86
85
|
this.domElement.removeEventListener('wheel', this.stopAnimations);
|
|
87
86
|
this.removeEventListener('change', this.updateControlsTarget);
|
|
87
|
+
_superPropGet(OrbitControls3D, "disconnect", this, 3)([]);
|
|
88
|
+
this.domElement = null;
|
|
88
89
|
}
|
|
89
90
|
}, {
|
|
90
91
|
key: "setView",
|
|
@@ -219,3 +219,32 @@ div.identify-body td.identify-attr-spacer {
|
|
|
219
219
|
height: 2px;
|
|
220
220
|
background-color: var(--list-section-bg-color);
|
|
221
221
|
}
|
|
222
|
+
|
|
223
|
+
div.identify-body div.identify-results-tables {
|
|
224
|
+
flex: 1 1 auto;
|
|
225
|
+
overflow-y: auto;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
div.identify-results-table-container {
|
|
229
|
+
padding-bottom: 0.5em;
|
|
230
|
+
border-bottom: 1px solid var(--border-color);
|
|
231
|
+
margin-bottom: 0.5em;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
div.identify-results-table-titlebar {
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
padding: 0.25em;
|
|
238
|
+
gap: 1em;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
div.identify-results-table-titlebar > span:nth-child(2) {
|
|
242
|
+
flex: 1 1 auto;
|
|
243
|
+
font-weight: bold;
|
|
244
|
+
font-size: 110%;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
div.identify-results-table-container > div.featurestable-frame {
|
|
248
|
+
max-height: 15em;
|
|
249
|
+
margin: 0.25em;
|
|
250
|
+
}
|
|
@@ -16,6 +16,16 @@ div.resizeable-window-portal-container > div {
|
|
|
16
16
|
height: 100%;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
div.resizeable-window-portal-container-detached {
|
|
20
|
+
position: fixed;
|
|
21
|
+
left: 0;
|
|
22
|
+
right: 0;
|
|
23
|
+
bottom: 0;
|
|
24
|
+
top: 2.5em;
|
|
25
|
+
padding: 0.25em;
|
|
26
|
+
background-color: var(--container-bg-color);
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
div.resizeable-window-contents {
|
|
20
30
|
display: flex;
|
|
21
31
|
flex-direction: column;
|
|
@@ -37,6 +47,10 @@ div.resizeable-window-minimized {
|
|
|
37
47
|
min-height: 2.5em!important;
|
|
38
48
|
}
|
|
39
49
|
|
|
50
|
+
div.resizeable-window-minimized div.resizeable-window-body {
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
div.resizeable-window-docked-left {
|
|
41
55
|
transform: none!important;
|
|
42
56
|
left: 0!important;
|