qwc2
Version:
QGIS Web Client
1,028 lines (1,025 loc) • 61.7 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
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; }
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; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* Copyright 2019-2024 Sourcepole AG
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
import classnames from 'classnames';
import DOMPurify from 'dompurify';
import isEmpty from 'lodash.isempty';
import pointInPolygon from 'point-in-polygon';
import polygonIntersectTest from 'polygon-intersect-test';
import PropTypes from 'prop-types';
import { createSelector } from 'reselect';
import { v4 as uuidv4 } from 'uuid';
import { LayerRole, addLayerFeatures, addThemeSublayer, changeLayerProperty, removeLayer, replacePlaceholderLayer, addLayer } from '../actions/layers';
import { logAction } from '../actions/logging';
import { panTo, zoomToExtent, zoomToPoint } from '../actions/map';
import { setCurrentSearchResult } from '../actions/search';
import { setCurrentTask } from '../actions/task';
import { setCurrentTheme } from '../actions/theme';
import { openExternalUrl, showNotification } from '../actions/windows';
import searchProvidersSelector from '../selectors/searchproviders';
import ConfigUtils from '../utils/ConfigUtils';
import CoordinatesUtils from '../utils/CoordinatesUtils';
import LayerUtils from '../utils/LayerUtils';
import LocaleUtils from '../utils/LocaleUtils';
import MapUtils from '../utils/MapUtils';
import MiscUtils from '../utils/MiscUtils';
import { UrlParams } from '../utils/PermaLinkUtils';
import { FulltextSearch, SearchResultType } from '../utils/SearchProviders';
import ServiceLayerUtils from '../utils/ServiceLayerUtils';
import VectorLayerUtils from '../utils/VectorLayerUtils';
import Icon from './Icon';
import MapSelection from './MapSelection';
import ButtonBar from './widgets/ButtonBar';
import ComboBox from './widgets/ComboBox';
import InputContainer from './widgets/InputContainer';
import NumberInput from './widgets/NumberInput';
import PopupMenu from './widgets/PopupMenu';
import Spinner from './widgets/Spinner';
import './style/SearchBox.css';
var SearchBox = /*#__PURE__*/function (_React$Component) {
function SearchBox(props) {
var _this;
_classCallCheck(this, SearchBox);
_this = _callSuper(this, SearchBox, [props]);
_defineProperty(_this, "state", {
searchText: "",
searchSession: null,
pendingSearches: [],
recentSearches: [],
searchResults: {},
resultsVisible: false,
collapsedSections: {},
expandedLayerGroup: null,
activeLayerInfo: null,
filterOptionsVisible: false,
searchFilterRegions: null,
selectedProvider: "",
filterRegionName: "",
filterGeomType: null,
filterGeometry: null
});
_defineProperty(_this, "loadFilterRegions", function () {
var searchRegions = ConfigUtils.getConfigProp("searchFilterRegions", _this.props.theme);
if (Array.isArray(searchRegions)) {
_this.setState({
searchFilterRegions: searchRegions
});
} else if (typeof searchRegions === 'string') {
axios.get(searchRegions).then(function (response) {
_this.setState({
searchFilterRegions: response.data
});
})["catch"](function () {
_this.setState({
searchFilterRegions: null
});
});
} else {
_this.setState({
searchFilterRegions: null
});
}
});
_defineProperty(_this, "renderFilterOptions", function () {
var _this$state$filterGeo;
if (!_this.state.filterOptionsVisible) {
return null;
}
var providerSelection = /*#__PURE__*/React.createElement(ComboBox, {
onChange: function onChange(value) {
return _this.setState({
selectedProvider: value
});
},
value: _this.state.selectedProvider
}, /*#__PURE__*/React.createElement("div", {
value: ""
}, LocaleUtils.tr("search.all")), Object.entries(_this.props.searchProviders).map(function (_ref) {
var _prov$params, _prov$label;
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
prov = _ref2[1];
return /*#__PURE__*/React.createElement("div", {
key: key,
value: key
}, (prov === null || prov === void 0 || (_prov$params = prov.params) === null || _prov$params === void 0 ? void 0 : _prov$params.title) || ((_prov$label = prov.label) !== null && _prov$label !== void 0 ? _prov$label : LocaleUtils.tr(prov.labelmsgid)));
}));
var searchRegionSelection = null;
if (Array.isArray(_this.state.searchFilterRegions)) {
searchRegionSelection = /*#__PURE__*/React.createElement(ComboBox, {
onChange: function onChange(value) {
return _this.setFilterRegion(value, _this.state.searchFilterRegions);
},
value: _this.state.filterRegionName
}, /*#__PURE__*/React.createElement("div", {
value: ""
}, LocaleUtils.tr("search.none")), _this.state.searchFilterRegions.map(function (group, gidx) {
return [/*#__PURE__*/React.createElement("div", {
"data-group-header": gidx,
key: "group" + gidx
}, group.name)].concat(_toConsumableArray(group.items.map(function (item, idx) {
return /*#__PURE__*/React.createElement("div", {
"data-group": gidx,
key: item.name,
value: gidx + ":" + idx + ":" + item.name
}, item.name);
})));
}));
}
var filterButtons = [{
key: "Polygon",
tooltip: LocaleUtils.tr("redlining.polygon"),
icon: "polygon",
label: LocaleUtils.tr("redlining.polygon")
}, {
key: "Circle",
tooltip: LocaleUtils.tr("redlining.circle"),
icon: "circle",
label: LocaleUtils.tr("redlining.circle")
}];
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-filter-options"
}, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("search.providerselection"), ":"), /*#__PURE__*/React.createElement("td", null, providerSelection)), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("search.limittoarea"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
className: "searchbox-filter-options-geometry controlgroup"
}, /*#__PURE__*/React.createElement(ButtonBar, {
active: _this.state.filterGeomType,
buttons: filterButtons,
onClick: _this.setFilterGeomType
}), searchRegionSelection, /*#__PURE__*/React.createElement("button", {
className: "button",
onClick: _this.clearFilter,
title: LocaleUtils.tr("search.clearfilter")
}, /*#__PURE__*/React.createElement(Icon, {
icon: "clear"
}))))), _this.state.filterGeomType === 'Circle' ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("search.circleradius"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(NumberInput, {
disabled: !_this.state.filterGeometry,
min: 1,
mobile: true,
onChange: _this.setCircleRadius,
suffix: " m",
value: ((_this$state$filterGeo = _this.state.filterGeometry) === null || _this$state$filterGeo === void 0 ? void 0 : _this$state$filterGeo.radius) || 0
}))) : null)));
});
_defineProperty(_this, "setFilterGeomType", function (geomType) {
_this.setState({
filterGeomType: geomType,
filterRegionName: "",
filterGeometry: null
});
});
_defineProperty(_this, "setFilterRegion", function (value, searchRegions) {
if (value) {
var parts = value.split(":");
var item = searchRegions[parts[0]].items[parts[1]];
var geometry = {
type: "Polygon",
coordinates: [item.coordinates]
};
var mapGeometry = VectorLayerUtils.reprojectGeometry(geometry, item.crs, _this.props.map.projection);
_this.setState({
filterGeomType: null,
filterRegionName: value,
filterGeometry: mapGeometry
});
} else {
_this.setState({
filterGeomType: null,
filterRegionName: "",
filterGeometry: null
});
}
});
_defineProperty(_this, "setCircleRadius", function (value) {
_this.setState(function (state) {
return {
filterGeometry: _objectSpread(_objectSpread({}, state.filterGeometry), {}, {
radius: value
})
};
});
});
_defineProperty(_this, "clearFilter", function () {
_this.setState({
filterGeomType: null,
filterRegionName: "",
filterGeometry: null
});
});
_defineProperty(_this, "renderResultsMenu", function () {
if (!_this.state.resultsVisible) {
return false;
}
var children = [_this.renderRecentResults(), _this.renderFilters(), _this.renderResults()].flat(Infinity);
children = children.filter(function (child) {
return !isEmpty(child);
});
if (isEmpty(children)) {
if (isEmpty(_this.state.pendingSearches) && _this.state.searchResults.query_text) {
children = /*#__PURE__*/React.createElement("div", {
className: "searchbox-noresults",
disabled: true,
key: "noresults"
}, LocaleUtils.tr("search.noresults"));
} else {
return null;
}
}
return /*#__PURE__*/React.createElement(PopupMenu, {
anchor: _this.searchBox,
className: "searchbox-results",
onClose: function onClose() {
return _this.setState({
resultsVisible: false
});
},
setMaxWidth: true
}, children);
});
_defineProperty(_this, "renderRecentResults", function () {
var recentSearches = _this.state.recentSearches.filter(function (entry) {
return entry.toLowerCase().includes(_this.state.searchText.toLowerCase());
});
if (isEmpty(recentSearches) || recentSearches.length === 1 && recentSearches[0].toLowerCase() === _this.state.searchText.toLowerCase()) {
return null;
}
return [/*#__PURE__*/React.createElement("div", {
className: "searchbox-results-section-title",
key: "recent",
onClick: function onClick(ev) {
return _this.toggleSection(ev, "recent");
}
}, /*#__PURE__*/React.createElement(Icon, {
icon: _this.isCollapsed("recent") ? "expand" : "collapse"
}), LocaleUtils.tr("search.recent")), !_this.isCollapsed("recent") ? recentSearches.map(function (entry, idx) {
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: "recent:" + idx,
onClick: function onClick() {
return _this.searchTextChanged(entry);
}
}, entry);
}) : null];
});
_defineProperty(_this, "renderFilters", function () {
var filters = Object.entries(_this.state.searchResults).reduce(function (res, _ref3) {
var _ref4 = _slicedToArray(_ref3, 2),
provider = _ref4[0],
results = _ref4[1];
if (isEmpty(results.result_counts) || results.result_counts.length < 2) {
return res;
}
var values = results.result_counts.map(function (entry) {
return [entry.filterword + ": " + _this.state.searchResults.query_text, provider];
});
values.sort(function (a, b) {
return a[0].localeCompare(b[0]);
});
return [].concat(_toConsumableArray(res), _toConsumableArray(values));
}, []);
if (isEmpty(filters)) {
return null;
}
var collapsed = _this.isCollapsed('filter', false);
return [/*#__PURE__*/React.createElement("div", {
className: "searchbox-results-section-title",
key: "filter",
onClick: function onClick(ev) {
return _this.toggleSection(ev, "filter");
}
}, /*#__PURE__*/React.createElement(Icon, {
icon: collapsed ? "expand" : "collapse"
}), LocaleUtils.tr("search.filter")), !collapsed ? filters.map(function (valProv, idx) {
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: "filter:" + idx,
onClick: function onClick() {
return _this.searchTextChanged(valProv[0], true, valProv[1]);
}
}, /*#__PURE__*/React.createElement("span", {
className: "searchbox-result-label"
}, valProv[0]));
}) : null];
});
_defineProperty(_this, "renderResults", function () {
var resultRenderers = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, SearchResultType.PLACE, _this.renderPlaceResult), SearchResultType.THEMELAYER, _this.renderLayerResult), SearchResultType.EXTERNALLAYER, _this.renderLayerResult), SearchResultType.THEME, _this.renderThemeResult), SearchResultType.TASK, _this.renderTaskResult);
var layersBeforePlaces = _this.props.searchOptions.showLayerResultsBeforePlaces;
var priorities = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, SearchResultType.PLACE, layersBeforePlaces ? 0 : 3), SearchResultType.THEMELAYER, layersBeforePlaces ? 2 : 1), SearchResultType.EXTERNALLAYER, layersBeforePlaces ? 3 : 2), SearchResultType.THEME, layersBeforePlaces ? 1 : 0), SearchResultType.TASK, 4);
var results = Object.keys(_this.props.searchProviders).reduce(function (result, provider) {
if (!_this.state.searchResults[provider]) {
return result;
}
return result.concat(_this.state.searchResults[provider].results.map(function (group) {
var _group$type, _group$type2, _group$title, _group$title2;
var sectionId = provider + ":" + group.id;
var moreLabel = null;
if (group.resultCount > 0 && group.resultCount > group.items.length) {
moreLabel = LocaleUtils.tr("search.more", group.resultCount - group.items.length);
} else if (group.resultCount === -1) {
moreLabel = LocaleUtils.tr("search.unknownmore");
}
if (group.items.length === 0) {
return null;
}
var renderer = resultRenderers[(_group$type = group.type) !== null && _group$type !== void 0 ? _group$type : SearchResultType.PLACE];
if (!renderer) {
return null;
}
var priority = priorities[(_group$type2 = group.type) !== null && _group$type2 !== void 0 ? _group$type2 : SearchResultType.PLACE];
return {
priority: priority * 1000000 + (group.priority || 0),
title: (_group$title = group.title) !== null && _group$title !== void 0 ? _group$title : LocaleUtils.tr(group.titlemsgid),
tree: [/*#__PURE__*/React.createElement("div", {
className: "searchbox-results-section-title",
key: sectionId,
onClick: function onClick(ev) {
return _this.toggleSection(ev, sectionId);
}
}, /*#__PURE__*/React.createElement(Icon, {
icon: _this.isCollapsed(sectionId) ? "expand" : "collapse"
}), /*#__PURE__*/React.createElement("span", null, (_group$title2 = group.title) !== null && _group$title2 !== void 0 ? _group$title2 : LocaleUtils.tr(group.titlemsgid))), !_this.isCollapsed(sectionId) ? [group.items.map(function (entry) {
return renderer(provider, group, entry);
}), moreLabel ? /*#__PURE__*/React.createElement("div", {
className: "searchbox-more-results",
disabled: true,
key: sectionId + ":more"
}, moreLabel) : null] : null].flat()
};
}));
}, []).filter(Boolean);
results.sort(function (a, b) {
if (b.priority !== a.priority) {
return b.priority - a.priority;
} else {
return b.title.localeCompare(a.title);
}
});
return isEmpty(results) ? null : results.map(function (entry) {
return entry.tree;
});
});
_defineProperty(_this, "renderPlaceResult", function (provider, group, result) {
var _result$label;
var key = provider + ":" + group.id + ":" + result.id;
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: key,
onClick: function onClick() {
return _this.selectPlaceResult(provider, group, result);
}
}, result.thumbnail ? /*#__PURE__*/React.createElement("img", {
className: "searchbox-result-thumbnail",
onError: function onError(ev) {
return _this.loadFallbackResultImage(ev, group.type);
},
src: result.thumbnail
}) : null, /*#__PURE__*/React.createElement("span", {
className: "searchbox-result-label",
dangerouslySetInnerHTML: {
__html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
},
title: (_result$label = result.label) !== null && _result$label !== void 0 ? _result$label : result.text
}), result.externalLink ? /*#__PURE__*/React.createElement(Icon, {
icon: "info-sign",
onClick: function onClick(ev) {
var _result$label2;
return _this.openUrl(ev, result.externalLink, result.target, (_result$label2 = result.label) !== null && _result$label2 !== void 0 ? _result$label2 : result.text);
}
}) : null);
});
_defineProperty(_this, "renderLayerResult", function (provider, group, result) {
var _result$label3, _result$layer;
var parent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var level = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
var key = provider + ":" + group.id + ":" + result.id;
var addThemes = ConfigUtils.getConfigProp("allowAddingOtherThemes", _this.props.theme);
var icon = null;
if (result.sublayers) {
var toggleLayerGroup = function toggleLayerGroup(ev) {
MiscUtils.killEvent(ev);
_this.setState(function (state) {
return {
expandedLayerGroup: state.expandedLayerGroup === key ? null : key
};
});
};
icon = /*#__PURE__*/React.createElement(Icon, {
icon: _this.state.expandedLayerGroup === key ? "minus" : "plus",
onClick: function onClick(ev) {
return toggleLayerGroup(ev);
}
});
} else if (result.thumbnail) {
icon = /*#__PURE__*/React.createElement("img", {
className: "searchbox-result-thumbnail",
onError: function onError(ev) {
return _this.loadFallbackResultImage(ev, group.type);
},
src: result.thumbnail
});
}
var selectResult = result.theme ? _this.selectThemeResult : _this.selectLayerResult;
return [/*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: key,
onClick: function onClick() {
return selectResult(provider, group, result);
},
style: {
borderLeft: "".concat(level, "em solid transparent")
}
}, icon, result.theme ? /*#__PURE__*/React.createElement(Icon, {
className: "searchbox-result-openicon",
icon: "open"
}) : null, /*#__PURE__*/React.createElement("span", {
className: "searchbox-result-label",
dangerouslySetInnerHTML: {
__html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
},
title: (_result$label3 = result.label) !== null && _result$label3 !== void 0 ? _result$label3 : result.text
}), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
icon: "plus",
onClick: function onClick() {
return _this.selectLayerResult(provider, group, result);
},
title: LocaleUtils.tr("themeswitcher.addtotheme")
}) : null, result.sublayers ? /*#__PURE__*/React.createElement(Icon, {
icon: "group",
onClick: function onClick() {
return _this.selectLayerResult(provider, group, result, true);
},
title: LocaleUtils.tr("importlayer.asgroup")
}) : null, result.info ? /*#__PURE__*/React.createElement(Icon, {
icon: "info-sign",
onClick: function onClick(ev) {
return _this.toggleLayerInfo(ev, provider, group, result, key, parent);
}
}) : null), _this.state.activeLayerInfo === key ? /*#__PURE__*/React.createElement("div", {
className: "searchbox-result-abstract",
dangerouslySetInnerHTML: {
__html: MiscUtils.addLinkAnchors(DOMPurify.sanitize(((_result$layer = result.layer) === null || _result$layer === void 0 ? void 0 : _result$layer["abstract"]) || "")) || LocaleUtils.tr("search.nodescription")
},
disabled: true,
key: key + ":abstract",
style: {
borderLeft: "".concat(level, "em solid transparent")
}
}) : null, _this.state.expandedLayerGroup === key ? result.sublayers.map(function (sublayer) {
return _this.renderLayerResult(provider, group, sublayer, result.id, level + 1);
}) : null].flat();
});
_defineProperty(_this, "renderThemeResult", function (provider, group, result) {
var _result$label4;
var addThemes = ConfigUtils.getConfigProp("allowAddingOtherThemes", _this.props.theme);
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: provider + ":" + group.id + ":" + result.id,
onClick: function onClick() {
return _this.selectThemeResult(provider, group, result);
}
}, result.thumbnail ? /*#__PURE__*/React.createElement("img", {
className: "searchbox-result-thumbnail",
onError: function onError(ev) {
return _this.loadFallbackResultImage(ev, group.type);
},
src: result.thumbnail
}) : null, /*#__PURE__*/React.createElement(Icon, {
className: "searchbox-result-openicon",
icon: "open"
}), /*#__PURE__*/React.createElement("span", {
className: "searchbox-result-label",
dangerouslySetInnerHTML: {
__html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
},
title: (_result$label4 = result.label) !== null && _result$label4 !== void 0 ? _result$label4 : result.text
}), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
icon: "plus",
onClick: function onClick(ev) {
return _this.addThemeLayers(result.layer);
},
title: LocaleUtils.tr("themeswitcher.addtotheme")
}) : null);
});
_defineProperty(_this, "renderTaskResult", function (provider, group, result) {
return /*#__PURE__*/React.createElement("div", {
className: "searchbox-result",
key: provider + ":" + group.id + ":" + result.id,
onClick: function onClick() {
return _this.selectTaskResult(provider, group, result);
}
}, result.task.icon ? /*#__PURE__*/React.createElement(Icon, {
icon: result.task.icon
}) : null, /*#__PURE__*/React.createElement("span", {
className: "searchbox-result-label"
}, result.text));
});
_defineProperty(_this, "selectPlaceResult", function (provider, group, result) {
var resultText = result.text.replace(/<\/?\w+\s*\/?>/g, '');
if (_this.props.searchOptions.showResultInSearchText !== false) {
// Show selected result text in search field
_this.setState({
searchText: resultText,
searchResults: _defineProperty({
query_text: resultText
}, provider, {
results: [_objectSpread(_objectSpread({}, group), {}, {
resultCount: 1,
items: [result]
})],
tot_result_count: 1
})
});
}
_this.updateRecentSearches();
if (result.geometry) {
_this.showResultGeometry(result, {
feature: {
type: "Feature",
geometry: result.geometry
},
crs: result.crs
});
} else if (_this.props.searchProviders[provider].getResultGeometry) {
_this.props.searchProviders[provider].getResultGeometry(result, function (response) {
_this.showResultGeometry(result, response);
}, axios);
} else {
// Display marker
_this.showResultGeometry(result, {
feature: {
type: "Feature",
geometry: {
type: "Point",
coordinates: [result.x, result.y]
}
},
crs: result.crs
});
}
if (result.dataproduct_id) {
var quot = typeof result.id === 'string' ? '"' : '';
var filter = "[[\"".concat(result.id_field_name, "\",\"=\", ").concat(quot).concat(result.id).concat(quot, "]]");
UrlParams.updateParams({
hp: result.dataproduct_id,
hf: filter,
st: resultText
});
} else {
UrlParams.updateParams({
hp: undefined,
hf: undefined,
st: resultText
});
}
_this.props.logAction("SEARCH_TEXT", {
searchText: _this.state.searchText
});
_this.props.logAction("SEARCH_RESULT_SELECTED", {
place: resultText
});
// Enable layer
if (result.layername) {
var path = [];
var sublayer = null;
var layer = _this.props.layers.find(function (l) {
return l.role === LayerRole.THEME && (sublayer = LayerUtils.searchSubLayer(l, 'name', result.layername, path));
});
if (layer && sublayer) {
_this.props.changeLayerProperty(layer.id, "visibility", true, path, 'both');
}
}
});
_defineProperty(_this, "selectLayerResult", function (provider, group, result) {
var asGroup = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (result.layer) {
if (result.theme) {
_this.addThemeLayers(result.layer);
} else if (group.type === SearchResultType.THEMELAYER) {
_this.props.addThemeSublayer(result.layer);
} else if (group.type === SearchResultType.EXTERNALLAYER) {
_this.addExternalLayer(result.layer, asGroup);
}
// Show layer tree to notify user that something has happened
_this.props.setCurrentTask('LayerTree');
} else if (_this.props.searchProviders[provider].getLayerDefinition) {
_this.props.searchProviders[provider].getLayerDefinition(result, function (layer) {
if (layer) {
if (result.theme) {
_this.addThemeLayers(layer);
} else if (group.type === SearchResultType.THEMELAYER) {
_this.props.addThemeSublayer({
sublayers: [layer]
});
} else if (group.type === SearchResultType.EXTERNALLAYER) {
_this.addExternalLayer(layer, asGroup);
}
// Show layer tree to notify user that something has happened
_this.props.setCurrentTask('LayerTree');
}
}, axios);
}
});
_defineProperty(_this, "addExternalLayer", function (entry) {
var asGroup = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (entry.resource) {
var _entry$title;
var params = LayerUtils.splitLayerUrlParam(entry.resource);
// Create placeholder layer
_this.props.addLayer({
id: params.id,
type: "placeholder",
name: params.name,
title: (_entry$title = entry.title) !== null && _entry$title !== void 0 ? _entry$title : params.name,
role: params.USERLAYER,
loading: true
});
ServiceLayerUtils.findLayers(params.type, params.url, [params], _this.props.map.projection, function (id, layer) {
if (layer) {
if (!asGroup) {
layer.sublayers = null;
}
LayerUtils.propagateLayerProperty(layer, "opacity", params.opacity);
_this.props.replacePlaceholderLayer(params.id, layer);
} else {
// eslint-disable-next-line
alert(LocaleUtils.tr("importlayer.addfailed"));
_this.props.removeLayer(params.id);
}
});
} else if (entry.type === "wms" || entry.type === "wfs" || entry.type === "wmts") {
if (asGroup) {
_this.props.addLayer(entry);
} else {
_this.props.addLayer(_objectSpread(_objectSpread({}, entry), {}, {
sublayers: null
}));
}
}
});
_defineProperty(_this, "selectThemeResult", function (provider, group, result) {
_this.props.setCurrentTheme(result.theme, _this.props.themes);
if (_this.props.searchOptions.showLayerAfterChangeTheme) {
_this.props.setCurrentTask('LayerTree');
}
});
_defineProperty(_this, "selectTaskResult", function (provider, group, result) {
if (result.task.url) {
_this.props.openExternalUrl(result.task.url, result.task.target, result.text, result.task.icon);
} else {
_this.props.setCurrentTask(result.task.task || result.task.key, result.task.mode, result.task.mapClickAction || (result.task.identifyEnabled ? "identify" : null));
}
});
_defineProperty(_this, "loadFallbackResultImage", function (ev, type) {
if (type === SearchResultType.PLACE) {
var iconPath = ConfigUtils.getAssetsPath() + '/img/search/';
if (!ev.target.src.endsWith(iconPath + "feature.svg")) {
ev.target.src = iconPath + "feature.svg";
}
} else {
ev.target.style.display = 'none';
}
});
_defineProperty(_this, "toggleLayerInfo", function (ev, provider, group, result, key, parent) {
MiscUtils.killEvent(ev);
var setResultLayerAndActiveInfo = function setResultLayerAndActiveInfo(layer) {
// Embed returned layer into result item, so that layer info is read from item.layer.abstract
_this.setState(function (state) {
return {
searchResults: _objectSpread(_objectSpread({}, state.searchResults), {}, _defineProperty({}, provider, _objectSpread(_objectSpread({}, state.searchResults[provider]), {}, {
results: state.searchResults[provider].results.map(function (g) {
if (g.id === group.id) {
return _objectSpread(_objectSpread({}, g), {}, {
items: g.items.map(function (item) {
if (item.id === result.id) {
return _objectSpread(_objectSpread({}, item), {}, {
layer: layer
});
} else if (item.id === parent) {
return _objectSpread(_objectSpread({}, item), {}, {
sublayers: item.sublayers.map(function (sublayer) {
if (sublayer.id === result.id) {
return _objectSpread(_objectSpread({}, sublayer), {}, {
layer: layer
});
} else {
return sublayer;
}
})
});
} else {
return item;
}
})
});
} else {
return g;
}
})
}))),
activeLayerInfo: key
};
});
};
_this.setState(function (state) {
if (state.activeLayerInfo === key) {
return {
activeLayerInfo: null
};
} else {
if (!result.layer && _this.props.searchProviders[provider].getLayerDefinition) {
_this.props.searchProviders[provider].getLayerDefinition(result, setResultLayerAndActiveInfo, axios);
return {};
} else {
return {
activeLayerInfo: key
};
}
}
});
});
_defineProperty(_this, "toggleSection", function (ev, key) {
MiscUtils.killEvent(ev);
return _this.setState(function (state) {
var _newCollapsedSections;
var newCollapsedSections = _objectSpread({}, state.collapsedSections);
var deflt = _this.props.searchOptions.sectionsDefaultCollapsed || false;
newCollapsedSections[key] = !((_newCollapsedSections = newCollapsedSections[key]) !== null && _newCollapsedSections !== void 0 ? _newCollapsedSections : deflt);
return {
collapsedSections: newCollapsedSections
};
});
});
_defineProperty(_this, "isCollapsed", function (section) {
var _this$state$collapsed;
var deflt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
deflt = deflt !== null && deflt !== void 0 ? deflt : _this.props.searchOptions.sectionsDefaultCollapsed || false;
return (_this$state$collapsed = _this.state.collapsedSections[section]) !== null && _this$state$collapsed !== void 0 ? _this$state$collapsed : deflt;
});
_defineProperty(_this, "toggleFilterOptions", function (visible) {
_this.setState({
filterOptionsVisible: visible
});
});
_defineProperty(_this, "searchTextChanged", function (text) {
var expandSections = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var provider = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (_this.props.layers.find(function (layer) {
return layer.id === 'searchselection';
})) {
_this.props.removeLayer('searchselection');
}
var newState = {
searchText: text,
expandedLayerGroup: null,
activeLayerInfo: null,
pendingSearches: [],
searchSession: null
};
if (expandSections) {
newState.collapsedSections = {};
}
_this.setState(newState);
clearTimeout(_this.searchTimeout);
_this.searchTimeout = setTimeout(function () {
return _this.startSearch(provider);
}, 250);
});
_defineProperty(_this, "onFocus", function () {
if (_this.searchBox && !_this.state.resultsVisible) {
_this.searchBox.select();
}
if (isEmpty(_this.state.searchResults) && _this.props.theme) {
_this.startSearch();
}
if (_this.props.searchOptions.allowSearchFilters) {
_this.toggleFilterOptions(false);
}
});
_defineProperty(_this, "onKeyDown", function (ev) {
if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') {
ev.preventDefault();
_this.setState({
resultsVisible: true
});
}
});
_defineProperty(_this, "clear", function () {
_this.props.setCurrentSearchResult(null);
_this.blur();
_this.setState({
searchText: '',
searchResults: {},
selectedProvider: '',
filterRegionName: "",
filterGeometry: null
});
_this.props.removeLayer('searchselection');
UrlParams.updateParams({
hp: undefined,
hf: undefined,
st: undefined
});
});
_defineProperty(_this, "startSearch", function () {
var _this$state$filterGeo2;
var provider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var uniquePlaceResult = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var availableProviders = _this.props.searchProviders;
var selectedProvider = provider !== null && provider !== void 0 ? provider : _this.state.selectedProvider;
if (selectedProvider) {
availableProviders = _defineProperty({}, selectedProvider, _this.props.searchProviders[selectedProvider]);
}
// eslint-disable-next-line
var searchText = _this.state.searchText.trim();
if (isEmpty(searchText)) {
_this.setState({
searchResults: {}
});
return;
}
var searchSession = uuidv4();
_this.setState({
searchResults: {
query_text: searchText
},
searchSession: searchSession,
pendingSearches: Object.keys(availableProviders)
});
var searchParams = {
mapcrs: _this.props.map.projection,
displaycrs: _this.props.map.displayCrs,
lang: LocaleUtils.lang(),
limit: _this.props.searchOptions.resultLimit,
filterPoly: (_this$state$filterGeo2 = _this.state.filterGeometry) === null || _this$state$filterGeo2 === void 0 || (_this$state$filterGeo2 = _this$state$filterGeo2.coordinates) === null || _this$state$filterGeo2 === void 0 ? void 0 : _this$state$filterGeo2[0],
filterBBox: _this.state.filterGeometry ? VectorLayerUtils.computeFeatureBBox(_this.state.filterGeometry) : null
};
Object.entries(availableProviders).forEach(function (_ref5) {
var _ref6 = _slicedToArray(_ref5, 2),
provKey = _ref6[0],
prov = _ref6[1];
prov.onSearch(searchText, _objectSpread(_objectSpread({
cfgParams: prov.cfgParams
}, prov.params), searchParams), function (response) {
var results = prov.handlesGeomFilter ? response.results : _this.filterProviderResults(response.results);
var totResultCount = results.reduce(function (tot, group) {
var _group$resultCount;
return tot + ((_group$resultCount = group.resultCount) !== null && _group$resultCount !== void 0 ? _group$resultCount : group.items.length);
}, 0);
if (uniquePlaceResult) {
// If looking for unique place result, filter non-place results
results = results.filter(function (group) {
var _group$type3;
return ((_group$type3 = group.type) !== null && _group$type3 !== void 0 ? _group$type3 : SearchResultType.PLACE) === SearchResultType.PLACE;
});
}
_this.setState(function (state) {
if (searchSession !== state.searchSession) {
return {};
}
var searchResults = _objectSpread(_objectSpread({}, state.searchResults), {}, _defineProperty({}, provKey, {
results: results,
result_counts: response.result_counts,
tot_result_count: totResultCount
}));
var newPendingSearches = state.pendingSearches.filter(function (entry) {
return entry !== provKey;
});
if (isEmpty(newPendingSearches) && uniquePlaceResult) {
var providersWithResults = Object.entries(searchResults).filter(function (_ref7) {
var _ref8 = _slicedToArray(_ref7, 2),
_ = _ref8[0],
providerResults = _ref8[1];
return providerResults.tot_result_count > 0;
});
if (providersWithResults.length === 1 && providersWithResults[0][1].tot_result_count === 1) {
var group = providersWithResults[0][1].results[0];
// Avoid warning about setState called in setState
setTimeout(function () {
_this.selectPlaceResult(providersWithResults[0][0], group, group.items[0]);
}, 0);
}
}
return {
resultsVisible: true,
searchResults: searchResults,
pendingSearches: newPendingSearches
};
});
}, axios);
});
});
_defineProperty(_this, "filterProviderResults", function (results) {
if (!_this.state.filterGeometry) {
return results;
}
var filterPolygon = _this.state.filterGeometry.coordinates[0];
return results.map(function (group) {
var _group$type4;
var resultType = (_group$type4 = group.type) !== null && _group$type4 !== void 0 ? _group$type4 : SearchResultType.PLACE;
if (resultType !== SearchResultType.PLACE) {
return group;
}
var newItems = group.items.filter(function (item) {
var _item$crs;
var geometry = null;
var itemCrs = (_item$crs = item.crs) !== null && _item$crs !== void 0 ? _item$crs : _this.props.map.projection;
if (item.geometry) {
geometry = VectorLayerUtils.reprojectGeometry(item.geometry, itemCrs, _this.props.map.projection);
} else {
geometry = {
type: 'Point',
coordinates: CoordinatesUtils.reproject([item.x, item.y], itemCrs, _this.props.map.projection)
};
}
if (geometry.type === 'Polygon') {
return polygonIntersectTest(geometry.coordinates[0], filterPolygon);
} else if (item.bbox) {
var _CoordinatesUtils$rep = CoordinatesUtils.reprojectBbox(item.bbox, itemCrs, _this.props.map.projection),
_CoordinatesUtils$rep2 = _slicedToArray(_CoordinatesUtils$rep, 4),
xmin = _CoordinatesUtils$rep2[0],
ymin = _CoordinatesUtils$rep2[1],
xmax = _CoordinatesUtils$rep2[2],
ymax = _CoordinatesUtils$rep2[3];
return polygonIntersectTest([[xmin, ymin], [xmax, ymin], [xmax, ymax], [xmin, ymax], [xmin, ymin]], filterPolygon);
} else if (geometry.type === 'Point') {
return pointInPolygon(geometry.coordinates, filterPolygon);
}
return true;
});
return newItems.length > 0 ? _objectSpread(_objectSpread({}, group), {}, {
items: newItems
}) : null;
}).filter(Boolean);
});
_defineProperty(_this, "updateRecentSearches", function () {
var text = _this.state.searchResults.query_text;
if (text && !_this.state.recentSearches.includes(text)) {
_this.setState(function (state) {
return {
recentSearches: [text].concat(_toConsumableArray(state.recentSearches.slice(0, 4)))
};
});
}
});
_defineProperty(_this, "blur", function () {
if (_this.searchBox) {
_this.searchBox.blur();
}
});
_defineProperty(_this, "addThemeLayers", function (layer) {
// Check if layer is already in the LayerTree
var sublayers = LayerUtils.getSublayerNames(layer);
var existing = _this.props.layers.find(function (l) {
return l.type === layer.type && l.url === layer.url && !isEmpty(LayerUtils.getSublayerNames(l).filter(function (v) {
return sublayers.includes(v);
}));
});
if (existing) {
var existingLayerName = (layer.sublayers || []).length === 1 ? layer.sublayers[0].title : layer.title;
var text = LocaleUtils.tr("search.existinglayer") + ": " + existingLayerName;
_this.props.showNotification("existinglayer", text);
} else {
_this.props.addLayer(_objectSpread(_objectSpread({}, layer), {}, {
role: LayerRole.USERLAYER
}));
}
if (_this.props.searchOptions.zoomToLayers && layer.bbox) {
_this.props.zoomToExtent(layer.bbox.bounds, layer.bbox.crs);
}
// Show layer tree to notify user that something has happened
_this.props.setCurrentTask('LayerTree');
});
_defineProperty(_this, "showResultGeometry", function (item, response) {
var _response$crs3, _item$bbox, _item$crs4;