qwc2 2025.10.9 → 2025.10.14
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/actions/display.js +30 -1
- package/actions/editing.js +22 -1
- package/actions/layerinfo.js +13 -1
- package/actions/layers.js +213 -3
- package/actions/localConfig.js +58 -1
- package/actions/locale.js +21 -1
- package/actions/locate.js +26 -1
- package/actions/logging.js +10 -1
- package/actions/map.js +105 -2
- package/actions/measurement.js +12 -1
- package/actions/processNotifications.js +37 -1
- package/actions/redlining.js +18 -1
- package/actions/redliningPick.js +12 -1
- package/actions/search.js +12 -1
- package/actions/serviceinfo.js +12 -1
- package/actions/task.js +55 -3
- package/actions/theme.js +339 -19
- package/actions/windows.js +164 -5
- package/components/AppMenu.js +435 -3
- package/components/AttributeForm.js +928 -32
- package/components/AttributeTableWidget.js +1105 -13
- package/components/AutoEditForm.js +189 -3
- package/components/CoordinateDisplayer.js +78 -2
- package/components/EditComboField.js +190 -6
- package/components/EditUploadField.js +315 -3
- package/components/ExportSelection.js +203 -2
- package/components/FullscreenSwitcher.js +90 -3
- package/components/Icon.js +81 -2
- package/components/IdentifyViewer.js +1161 -6
- package/components/ImportLayer.js +718 -20
- package/components/LayerInfoWindow.js +145 -2
- package/components/LinkFeatureForm.js +246 -5
- package/components/MapButton.js +88 -2
- package/components/MapSelection.js +287 -8
- package/components/MessageBar.js +68 -2
- package/components/NumericInputWindow.js +359 -2
- package/components/PickFeature.js +266 -2
- package/components/PluginsContainer.js +227 -8
- package/components/PrintSelection.js +620 -49
- package/components/ProcessNotifications.js +104 -2
- package/components/QtDesignerForm.js +1137 -18
- package/components/ResizeableWindow.js +591 -8
- package/components/SearchBox.js +1307 -20
- package/components/ServiceInfoWindow.js +107 -2
- package/components/SideBar.js +204 -4
- package/components/StandardApp.js +381 -20
- package/components/Swipeable.js +15 -1
- package/components/TaskBar.js +85 -2
- package/components/ThemeLayersListWindow.js +216 -4
- package/components/ThemeList.js +381 -7
- package/components/Toolbar.js +106 -2
- package/components/WindowManager.js +178 -2
- package/components/map/OlLayer.js +257 -6
- package/components/map/OlMap.js +405 -5
- package/components/map/layers/BingLayer.js +31 -2
- package/components/map/layers/GoogleLayer.js +222 -19
- package/components/map/layers/GraticuleLayer.js +21 -1
- package/components/map/layers/ImageLayer.js +15 -1
- package/components/map/layers/MVTLayer.js +52 -2
- package/components/map/layers/OSMLayer.js +24 -2
- package/components/map/layers/OverlayLayer.js +55 -3
- package/components/map/layers/VectorLayer.js +173 -8
- package/components/map/layers/WFSLayer.js +220 -6
- package/components/map/layers/WMSLayer.js +180 -6
- package/components/map/layers/WMTSLayer.js +67 -3
- package/components/map/layers/XYZLayer.js +24 -2
- package/components/map/layers/index.js +28 -1
- package/components/map3d/EditDataset3D.js +190 -3
- package/components/map3d/HeightProfile3D.js +402 -3
- package/components/map3d/ImportObjects3D.js +162 -2
- package/components/map3d/Map3D.js +1304 -38
- package/components/map3d/MapControls3D.js +392 -7
- package/components/map3d/SearchField3D.js +183 -11
- package/components/map3d/View3DSwitcher.js +98 -2
- package/components/map3d/drawtool/CreateTool3D.js +174 -4
- package/components/map3d/drawtool/EditTool3D.js +590 -6
- package/components/map3d/drawtool/NumericInput3D.js +336 -4
- package/components/map3d/layers/GeoTIFFLayer3D.js +15 -1
- package/components/map3d/layers/VectorLayer3D.js +53 -2
- package/components/map3d/layers/WFSLayer3D.js +109 -3
- package/components/map3d/layers/WMSLayer3D.js +70 -2
- package/components/map3d/layers/WMTSLayer3D.js +27 -3
- package/components/map3d/layers/index.js +14 -1
- package/components/map3d/utils/FirstPersonControls3D.js +423 -16
- package/components/map3d/utils/MiscUtils3D.js +221 -13
- package/components/map3d/utils/OrbitControls3D.js +176 -5
- package/components/map3d/utils/Tiles3DStyle.js +238 -9
- package/components/share/ShareLink.js +54 -2
- package/components/share/ShareQRCode.js +62 -2
- package/components/share/ShareSocials.js +125 -3
- package/components/timeline/FixedTimeline.js +236 -5
- package/components/timeline/InfiniteTimeline.js +347 -8
- package/components/timeline/TimelineFeaturesSlider.js +439 -5
- package/components/widgets/AccordeonWidget.js +96 -2
- package/components/widgets/ButtonBar.js +124 -2
- package/components/widgets/ColorButton.js +201 -3
- package/components/widgets/ComboBox.js +166 -2
- package/components/widgets/CopyButton.js +110 -2
- package/components/widgets/DateTimeInput.js +100 -3
- package/components/widgets/EditableSelect.js +230 -3
- package/components/widgets/FileSelector.js +128 -4
- package/components/widgets/Input.js +124 -2
- package/components/widgets/InputContainer.js +96 -2
- package/components/widgets/LayerCatalogWidget.js +219 -3
- package/components/widgets/MenuButton.js +157 -1
- package/components/widgets/ModalDialog.js +64 -2
- package/components/widgets/NavBar.js +119 -2
- package/components/widgets/NumberInput.js +226 -4
- package/components/widgets/PopupMenu.js +72 -1
- package/components/widgets/Primitives.js +6 -1
- package/components/widgets/ReCaptchaWidget.js +55 -1
- package/components/widgets/SearchWidget.js +255 -2
- package/components/widgets/Spinner.js +44 -2
- package/components/widgets/SuggestionInput.js +77 -2
- package/components/widgets/TextInput.js +308 -2
- package/components/widgets/ToggleSwitch.js +85 -2
- package/components/widgets/VectorLayerPicker.js +85 -3
- package/libs/openlayers.js +225 -5
- package/package.json +1 -1
- package/plugins/API.js +358 -15
- package/plugins/AttributeTable.js +109 -3
- package/plugins/Authentication.js +130 -5
- package/plugins/BackgroundSwitcher.js +218 -4
- package/plugins/Bookmark.js +289 -3
- package/plugins/BottomBar.js +298 -4
- package/plugins/CookiePopup.js +67 -3
- package/plugins/Cyclomedia.js +442 -5
- package/plugins/Editing.js +497 -9
- package/plugins/FeatureForm.js +366 -4
- package/plugins/FeatureSearch.js +458 -3
- package/plugins/GeometryDigitizer.js +664 -7
- package/plugins/HeightProfile.js +763 -15
- package/plugins/Help.js +102 -3
- package/plugins/HomeButton.js +80 -3
- package/plugins/Identify.js +543 -5
- package/plugins/LayerCatalog.js +215 -4
- package/plugins/LayerTree.js +1194 -6
- package/plugins/LocateButton.js +94 -3
- package/plugins/Map.js +320 -16
- package/plugins/MapCompare.js +94 -3
- package/plugins/MapCopyright.js +127 -5
- package/plugins/MapExport.js +613 -20
- package/plugins/MapFilter.js +868 -12
- package/plugins/MapInfoTooltip.js +277 -3
- package/plugins/MapLegend.js +253 -4
- package/plugins/MapTip.js +290 -4
- package/plugins/Measure.js +220 -4
- package/plugins/NewsPopup.js +137 -3
- package/plugins/OverviewMap.js +167 -7
- package/plugins/Panoramax.js +340 -2
- package/plugins/Portal.js +199 -4
- package/plugins/Print.js +1231 -15
- package/plugins/Redlining.js +750 -6
- package/plugins/Reports.js +332 -3
- package/plugins/Routing.js +1278 -15
- package/plugins/ScratchDrawing.js +173 -5
- package/plugins/Settings.js +241 -4
- package/plugins/Share.js +198 -3
- package/plugins/StartupMarker.js +84 -4
- package/plugins/TaskButton.js +88 -3
- package/plugins/ThemeSwitcher.js +164 -4
- package/plugins/TimeManager.js +971 -10
- package/plugins/TopBar.js +300 -7
- package/plugins/TourGuide.js +213 -2
- package/plugins/ValueTool.js +419 -4
- package/plugins/View3D.js +519 -14
- package/plugins/ZoomButtons.js +165 -3
- package/plugins/map/EditingSupport.js +199 -7
- package/plugins/map/LocateSupport.js +260 -4
- package/plugins/map/MeasurementSupport.js +216 -8
- package/plugins/map/RedliningPickSupport.js +201 -7
- package/plugins/map/RedliningSupport.js +726 -17
- package/plugins/map/SnapInteraction.js +101 -1
- package/plugins/map/SnapSupport.js +210 -2
- package/plugins/map/SnappingSupport.js +356 -17
- package/plugins/map3d/BackgroundSwitcher3D.js +44 -3
- package/plugins/map3d/BottomBar3D.js +118 -3
- package/plugins/map3d/Compare3D.js +422 -8
- package/plugins/map3d/Draw3D.js +353 -6
- package/plugins/map3d/ExportObjects3D.js +393 -18
- package/plugins/map3d/HideObjects3D.js +313 -12
- package/plugins/map3d/Identify3D.js +283 -12
- package/plugins/map3d/LayerTree3D.js +323 -3
- package/plugins/map3d/MapCopyright3D.js +128 -5
- package/plugins/map3d/MapExport3D.js +590 -10
- package/plugins/map3d/MapLight3D.js +553 -6
- package/plugins/map3d/Measure3D.js +571 -20
- package/plugins/map3d/OverviewMap3D.js +169 -3
- package/plugins/map3d/Settings3D.js +73 -3
- package/plugins/map3d/TopBar3D.js +207 -9
- package/plugins/redlining/RedliningBufferSupport.js +206 -3
- package/reducers/display.js +34 -2
- package/reducers/editing.js +68 -3
- package/reducers/index.js +9 -1
- package/reducers/layerinfo.js +26 -2
- package/reducers/layers.js +456 -9
- package/reducers/localConfig.js +122 -2
- package/reducers/locale.js +38 -2
- package/reducers/locate.js +40 -2
- package/reducers/map.js +176 -5
- package/reducers/measurement.js +42 -2
- package/reducers/processNotifications.js +49 -2
- package/reducers/redlining.js +50 -2
- package/reducers/redliningPick.js +27 -2
- package/reducers/search.js +20 -1
- package/reducers/serviceinfo.js +25 -2
- package/reducers/task.js +45 -2
- package/reducers/theme.js +51 -2
- package/reducers/windows.js +203 -2
- package/scripts/dist.sh +1 -1
- package/scripts/gen-plugin-docs.js +152 -2
- package/scripts/makeIconkit.js +85 -6
- package/scripts/themesConfig.js +742 -40
- package/scripts/updateTranslations.js +251 -10
- package/selectors/searchproviders.js +44 -2
- package/stores/StandardStore.js +42 -2
- package/utils/ConfigUtils.js +84 -3
- package/utils/CoordinatesUtils.js +234 -23
- package/utils/DxfUtils.js +237 -11
- package/utils/EditingInterface.js +421 -87
- package/utils/EditingUtils.js +357 -13
- package/utils/ElevationInterface.js +83 -22
- package/utils/FeatureStyles.js +429 -5
- package/utils/IdentifyUtils.js +443 -7
- package/utils/ImageEditor.js +79 -9
- package/utils/LayerUtils.js +1516 -50
- package/utils/LocaleUtils.js +117 -7
- package/utils/MapUtils.js +241 -59
- package/utils/MeasureUtils.js +323 -2
- package/utils/MiscUtils.js +189 -11
- package/utils/PermaLinkUtils.js +429 -6
- package/utils/PluginStore.js +27 -1
- package/utils/ResourceRegistry.js +15 -1
- package/utils/RoutingInterface.js +307 -7
- package/utils/SearchProviders.js +722 -19
- package/utils/ServiceLayerUtils.js +669 -14
- package/utils/Signal.js +32 -2
- package/utils/ThemeUtils.js +341 -7
- package/utils/VectorLayerUtils.js +589 -15
- package/utils/expr_grammar/grammar.js +2239 -2
- package/utils/expr_grammar/test.js +65 -3
package/utils/LocaleUtils.js
CHANGED
|
@@ -5,10 +5,120 @@
|
|
|
5
5
|
*
|
|
6
6
|
* This source code is licensed under the BSD-style license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import axios from 'axios';
|
|
11
|
+
import deepmerge from 'deepmerge';
|
|
12
|
+
import StandardApp from '../components/StandardApp';
|
|
13
|
+
import ConfigUtils from './ConfigUtils';
|
|
14
|
+
var themeTranslationCache = {};
|
|
15
|
+
var LocaleUtils = {
|
|
16
|
+
loadLocale: function loadLocale(lang, fallbackLangData) {
|
|
17
|
+
return new Promise(function (resolve) {
|
|
18
|
+
var loadLang = null;
|
|
19
|
+
var availableLanguages = process.env.AvailableLanguages;
|
|
20
|
+
if (availableLanguages.indexOf(lang) !== -1) {
|
|
21
|
+
// Exact match: lang-REGION
|
|
22
|
+
loadLang = lang;
|
|
23
|
+
} else if (availableLanguages.indexOf(lang.slice(0, 2)) !== -1) {
|
|
24
|
+
// Exact match: lang
|
|
25
|
+
loadLang = lang.slice(0, 2);
|
|
26
|
+
} else {
|
|
27
|
+
// Try match lang-<OTHER_REGION>
|
|
28
|
+
loadLang = availableLanguages.find(function (lc) {
|
|
29
|
+
return lc.slice(0, 2) === lang.slice(0, 2);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
var config = {
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
},
|
|
36
|
+
data: {}
|
|
37
|
+
};
|
|
38
|
+
var translationsPath = ConfigUtils.getTranslationsPath();
|
|
39
|
+
var resolveLang = function resolveLang(locale, messages) {
|
|
40
|
+
if (ConfigUtils.getConfigProp("loadTranslationOverrides")) {
|
|
41
|
+
axios.get(translationsPath + '/' + locale + '_overrides.json', config).then(function (response) {
|
|
42
|
+
var overrideMessages = response.data.messages;
|
|
43
|
+
resolve({
|
|
44
|
+
locale: locale,
|
|
45
|
+
messages: deepmerge(messages, overrideMessages)
|
|
46
|
+
});
|
|
47
|
+
})["catch"](function () {
|
|
48
|
+
resolve({
|
|
49
|
+
locale: locale,
|
|
50
|
+
messages: messages
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
resolve({
|
|
55
|
+
locale: locale,
|
|
56
|
+
messages: messages
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
if (!loadLang) {
|
|
61
|
+
// eslint-disable-next-line
|
|
62
|
+
console.warn("No suitable translations available for " + lang + ", defaulting to " + fallbackLangData.locale);
|
|
63
|
+
resolveLang(fallbackLangData.locale, fallbackLangData.messages);
|
|
64
|
+
} else {
|
|
65
|
+
axios.get(translationsPath + '/' + loadLang + '.json', config).then(function (response) {
|
|
66
|
+
resolveLang(loadLang, response.data.messages);
|
|
67
|
+
})["catch"](function () {
|
|
68
|
+
// eslint-disable-next-line
|
|
69
|
+
console.warn("Failed to load translations for " + loadLang + ", defaulting to " + fallbackLangData.locale);
|
|
70
|
+
resolveLang(fallbackLangData.locale, fallbackLangData.messages);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
tr: function tr(key) {
|
|
76
|
+
var state = StandardApp.store.getState();
|
|
77
|
+
var text = key in state.locale.messages ? state.locale.messages[key] || state.locale.fallbackMessages[key] || key : key;
|
|
78
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
79
|
+
if (args.length > 0) {
|
|
80
|
+
return text.replace(/{(\d+)}/g, function (match, number) {
|
|
81
|
+
return typeof args[number] !== 'undefined' ? args[number] : match;
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
return text;
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
// Just a stub to make updateTranslations pick up the msgId
|
|
88
|
+
trmsg: function trmsg(key) {
|
|
89
|
+
return key;
|
|
90
|
+
},
|
|
91
|
+
trWithFallback: function trWithFallback(key, fallback) {
|
|
92
|
+
var state = StandardApp.store.getState();
|
|
93
|
+
return state.locale.messages[key] || fallback;
|
|
94
|
+
},
|
|
95
|
+
lang: function lang() {
|
|
96
|
+
var state = StandardApp.store.getState();
|
|
97
|
+
return state.locale.current;
|
|
98
|
+
},
|
|
99
|
+
toLocaleFixed: function toLocaleFixed(number, decimals) {
|
|
100
|
+
if (ConfigUtils.getConfigProp("localeAwareNumbers")) {
|
|
101
|
+
return number.toLocaleString(LocaleUtils.lang(), {
|
|
102
|
+
minimumFractionDigits: decimals,
|
|
103
|
+
maximumFractionDigits: decimals
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
return number.toFixed(decimals);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
loadThemeTranslations: function loadThemeTranslations(serviceUrl) {
|
|
110
|
+
return new Promise(function (resolve) {
|
|
111
|
+
if (serviceUrl in themeTranslationCache) {
|
|
112
|
+
resolve(themeTranslationCache[serviceUrl]);
|
|
113
|
+
} else {
|
|
114
|
+
axios.get(serviceUrl + "?SERVICE=GetTranslations&LANG=" + LocaleUtils.lang()).then(function (response) {
|
|
115
|
+
themeTranslationCache[serviceUrl] = response.data;
|
|
116
|
+
resolve(response.data);
|
|
117
|
+
})["catch"](function (e) {
|
|
118
|
+
resolve({});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
export default LocaleUtils;
|
package/utils/MapUtils.js
CHANGED
|
@@ -5,62 +5,244 @@
|
|
|
5
5
|
*
|
|
6
6
|
* This source code is licensed under the BSD-style license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import isEmpty from 'lodash.isempty';
|
|
11
|
+
import ConfigUtils from './ConfigUtils';
|
|
12
|
+
import CoordinatesUtils from './CoordinatesUtils';
|
|
13
|
+
import { UrlParams } from './PermaLinkUtils';
|
|
14
|
+
var DEFAULT_SCREEN_DPI = 96;
|
|
15
|
+
var METERS_PER_UNIT = {
|
|
16
|
+
'm': 1,
|
|
17
|
+
'degrees': 111194.87428468118,
|
|
18
|
+
'ft': 0.3048,
|
|
19
|
+
'us-ft': 1200 / 3937
|
|
20
|
+
};
|
|
21
|
+
var hooks = {};
|
|
22
|
+
var MapUtils = {
|
|
23
|
+
GET_PIXEL_FROM_COORDINATES_HOOK: 'GET_PIXEL_FROM_COORDINATES_HOOK',
|
|
24
|
+
GET_COORDINATES_FROM_PIXEL_HOOK: 'GET_COORDINATES_FROM_PIXEL_HOOK',
|
|
25
|
+
GET_SNAPPED_COORDINATES_FROM_PIXEL_HOOK: 'GET_SNAPPED_COORDINATES_FROM_PIXEL_HOOK',
|
|
26
|
+
GET_NATIVE_LAYER: 'GET_NATIVE_LAYER',
|
|
27
|
+
ADD_POINTER_MOVE_LISTENER: 'ADD_POINTER_MOVE_LISTENER',
|
|
28
|
+
REMOVE_POINTER_MOVE_LISTENER: 'REMOVE_POINTER_MOVE_LISTENER',
|
|
29
|
+
GET_MAP: 'GET_MAP',
|
|
30
|
+
registerHook: function registerHook(name, hook) {
|
|
31
|
+
hooks[name] = hook;
|
|
32
|
+
},
|
|
33
|
+
getHook: function getHook(name) {
|
|
34
|
+
return hooks[name];
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* @param dpi {number} dot per inch resolution
|
|
38
|
+
* @return {number} dot per meter resolution
|
|
39
|
+
*/
|
|
40
|
+
dpi2dpm: function dpi2dpm(dpi) {
|
|
41
|
+
return (dpi || DEFAULT_SCREEN_DPI) * (100 / 2.54);
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* @param dpi {number} screen resolution in dots per inch.
|
|
45
|
+
* @param projection {string} map projection.
|
|
46
|
+
* @return {number} dots per map unit.
|
|
47
|
+
*/
|
|
48
|
+
dpi2dpu: function dpi2dpu(dpi, projection) {
|
|
49
|
+
var units = CoordinatesUtils.getUnits(projection);
|
|
50
|
+
return METERS_PER_UNIT[units] * MapUtils.dpi2dpm(dpi);
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* Get a list of scales for each zoom level of the Google Mercator.
|
|
54
|
+
* @param minZoom {number} min zoom level.
|
|
55
|
+
* @param maxZoom {number} max zoom level.
|
|
56
|
+
* @return {array} a list of scale for each zoom level in the given interval.
|
|
57
|
+
*/
|
|
58
|
+
getGoogleMercatorScales: function getGoogleMercatorScales(minZoom, maxZoom) {
|
|
59
|
+
var dpi = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_SCREEN_DPI;
|
|
60
|
+
// Google mercator params
|
|
61
|
+
var RADIUS = 6378137;
|
|
62
|
+
var TILE_WIDTH = 256;
|
|
63
|
+
var ZOOM_FACTOR = 2;
|
|
64
|
+
var retval = [];
|
|
65
|
+
for (var l = minZoom; l <= maxZoom; l++) {
|
|
66
|
+
retval.push(2 * Math.PI * RADIUS / (TILE_WIDTH * Math.pow(ZOOM_FACTOR, l) / MapUtils.dpi2dpm(dpi)));
|
|
67
|
+
}
|
|
68
|
+
return retval;
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* @param scales {array} list of scales.
|
|
72
|
+
* @param projection {string} map projection.
|
|
73
|
+
* @param dpi {number} screen resolution in dots per inch.
|
|
74
|
+
* @return {array} a list of resolutions corresponding to the given scales, projection and dpi.
|
|
75
|
+
*/
|
|
76
|
+
getResolutionsForScales: function getResolutionsForScales(scales, projection) {
|
|
77
|
+
var dpi = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_SCREEN_DPI;
|
|
78
|
+
var dpu = MapUtils.dpi2dpu(dpi, projection);
|
|
79
|
+
var resolutions = scales.map(function (scale) {
|
|
80
|
+
return scale / dpu;
|
|
81
|
+
});
|
|
82
|
+
return resolutions;
|
|
83
|
+
},
|
|
84
|
+
/**
|
|
85
|
+
* Calculates the best fitting zoom level for the given extent.
|
|
86
|
+
*
|
|
87
|
+
* @param extent {Array} [minx, miny, maxx, maxy]
|
|
88
|
+
* @param resolutions {Array} The list of available map resolutions
|
|
89
|
+
* @param mapSize {Object} current size of the map.
|
|
90
|
+
* @param minZoom {number} min zoom level.
|
|
91
|
+
* @param maxZoom {number} max zoom level.
|
|
92
|
+
* @param dpi {number} screen resolution in dot per inch.
|
|
93
|
+
* @return {Number} the zoom level fitting th extent
|
|
94
|
+
*/
|
|
95
|
+
getZoomForExtent: function getZoomForExtent(extent, resolutions, mapSize, minZoom, maxZoom) {
|
|
96
|
+
var wExtent = extent[2] - extent[0];
|
|
97
|
+
var hExtent = extent[3] - extent[1];
|
|
98
|
+
var xResolution = Math.abs(wExtent / mapSize.width);
|
|
99
|
+
var yResolution = Math.abs(hExtent / mapSize.height);
|
|
100
|
+
var extentResolution = Math.max(xResolution, yResolution);
|
|
101
|
+
var zoom = this.computeZoom(resolutions, extentResolution);
|
|
102
|
+
if (ConfigUtils.getConfigProp("allowFractionalZoom") === true) {
|
|
103
|
+
return Math.max(minZoom, Math.min(zoom, maxZoom));
|
|
104
|
+
} else {
|
|
105
|
+
return Math.max(minZoom, Math.min(Math.round(zoom), maxZoom));
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
/**
|
|
109
|
+
* Calculates the extent for the provided center and zoom level
|
|
110
|
+
* @param center {Array} [x, y]
|
|
111
|
+
* @param zoom {number} The zoom level
|
|
112
|
+
* @param resolutions {Array} The list of map resolutions
|
|
113
|
+
* @param mapSize {Object} The current size of the map
|
|
114
|
+
*/
|
|
115
|
+
getExtentForCenterAndZoom: function getExtentForCenterAndZoom(center, zoom, resolutions, mapSize) {
|
|
116
|
+
if (ConfigUtils.getConfigProp("allowFractionalZoom") !== true) {
|
|
117
|
+
zoom = Math.round(zoom);
|
|
118
|
+
}
|
|
119
|
+
var width = this.computeForZoom(resolutions, zoom) * mapSize.width;
|
|
120
|
+
var height = this.computeForZoom(resolutions, zoom) * mapSize.height;
|
|
121
|
+
return [center[0] - 0.5 * width, center[1] - 0.5 * height, center[0] + 0.5 * width, center[1] + 0.5 * height];
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Transform width and height specified in meters to the units of the specified projection
|
|
125
|
+
*
|
|
126
|
+
* @param projection {string} projection.
|
|
127
|
+
* @param center {Array} Center of extent in EPSG:4326 coordinates.
|
|
128
|
+
* @param width {number} Width in meters.
|
|
129
|
+
* @param height {number} Height in meters.
|
|
130
|
+
*/
|
|
131
|
+
transformExtent: function transformExtent(projection, center, width, height) {
|
|
132
|
+
var units = CoordinatesUtils.getUnits(projection);
|
|
133
|
+
if (units === 'ft') {
|
|
134
|
+
return {
|
|
135
|
+
width: width / METERS_PER_UNIT.ft,
|
|
136
|
+
height: height / METERS_PER_UNIT.ft
|
|
137
|
+
};
|
|
138
|
+
} else if (units === 'us-ft') {
|
|
139
|
+
return {
|
|
140
|
+
width: width / METERS_PER_UNIT['us-ft'],
|
|
141
|
+
height: height / METERS_PER_UNIT['us-ft']
|
|
142
|
+
};
|
|
143
|
+
} else if (units === 'degrees') {
|
|
144
|
+
// https://en.wikipedia.org/wiki/Geographic_coordinate_system#Length_of_a_degree
|
|
145
|
+
var phi = center[1] / 180 * Math.PI;
|
|
146
|
+
var latPerM = 111132.92 - 559.82 * Math.cos(2 * phi) + 1.175 * Math.cos(4 * phi) - 0.0023 * Math.cos(6 * phi);
|
|
147
|
+
var lonPerM = 111412.84 * Math.cos(phi) - 93.5 * Math.cos(3 * phi) + 0.118 * Math.cos(5 * phi);
|
|
148
|
+
return {
|
|
149
|
+
width: width / lonPerM,
|
|
150
|
+
height: height / latPerM
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
width: width,
|
|
155
|
+
height: height
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Compute the scale or resolution matching a (possibly fractional) zoom level.
|
|
160
|
+
*
|
|
161
|
+
* @param list {Array} List of scales or resolutions.
|
|
162
|
+
* @param zoomLevel (number) Zoom level (integer or fractional).
|
|
163
|
+
* @return Scale of resolution matching zoomLevel
|
|
164
|
+
*/
|
|
165
|
+
computeForZoom: function computeForZoom(list, zoomLevel) {
|
|
166
|
+
if (ConfigUtils.getConfigProp("allowFractionalZoom") !== true) {
|
|
167
|
+
return list[Math.min(list.length - 1, Math.round(zoomLevel))];
|
|
168
|
+
}
|
|
169
|
+
zoomLevel = Math.max(zoomLevel, 0);
|
|
170
|
+
var upper = Math.ceil(zoomLevel);
|
|
171
|
+
var lower = Math.floor(zoomLevel);
|
|
172
|
+
if (upper >= list.length) {
|
|
173
|
+
return list[list.length - 1];
|
|
174
|
+
}
|
|
175
|
+
var frac = zoomLevel - lower;
|
|
176
|
+
return list[lower] * (1 - frac) + list[upper] * frac;
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* Compute the (possibly fractional) zoom level matching the specified scale or resolution.
|
|
180
|
+
*
|
|
181
|
+
* @param list {Array} List of scales or resolutions.
|
|
182
|
+
* @param value (number) Scale or resolution.
|
|
183
|
+
* @return Zoom level matching the specified scale or resolution.
|
|
184
|
+
*/
|
|
185
|
+
computeZoom: function computeZoom(list, value) {
|
|
186
|
+
if (ConfigUtils.getConfigProp("allowFractionalZoom") === true) {
|
|
187
|
+
var index = 0;
|
|
188
|
+
for (var i = 1; i < list.length - 1; ++i) {
|
|
189
|
+
if (value <= list[i]) {
|
|
190
|
+
index = i;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return index + (value - list[index]) / (list[index + 1] - list[index]);
|
|
194
|
+
} else {
|
|
195
|
+
var closestVal = Math.abs(value - list[0]);
|
|
196
|
+
var closestIdx = 0;
|
|
197
|
+
for (var _i = 1; _i < list.length; ++_i) {
|
|
198
|
+
var currVal = Math.abs(value - list[_i]);
|
|
199
|
+
if (currVal < closestVal) {
|
|
200
|
+
closestVal = currVal;
|
|
201
|
+
closestIdx = _i;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return closestIdx;
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
/**
|
|
208
|
+
* Convert degrees to radians
|
|
209
|
+
* @param degrees {number}
|
|
210
|
+
* @return {number} in radians
|
|
211
|
+
*/
|
|
212
|
+
degreesToRadians: function degreesToRadians(degrees) {
|
|
213
|
+
var pi = Math.PI;
|
|
214
|
+
return degrees * (pi / 180);
|
|
215
|
+
},
|
|
216
|
+
updateMapUrlParams: function updateMapUrlParams(state) {
|
|
217
|
+
var newParams = {};
|
|
218
|
+
var positionFormat = ConfigUtils.getConfigProp("urlPositionFormat");
|
|
219
|
+
var positionCrs = ConfigUtils.getConfigProp("urlPositionCrs") || state.projection;
|
|
220
|
+
var prec = CoordinatesUtils.getPrecision(positionCrs);
|
|
221
|
+
if (positionFormat === "centerAndZoom") {
|
|
222
|
+
var center = CoordinatesUtils.reproject(state.center, state.projection, positionCrs);
|
|
223
|
+
var scale = Math.round(MapUtils.computeForZoom(state.scales, state.zoom));
|
|
224
|
+
Object.assign(newParams, {
|
|
225
|
+
c: center.map(function (x) {
|
|
226
|
+
return x.toFixed(prec);
|
|
227
|
+
}).join(","),
|
|
228
|
+
s: scale
|
|
229
|
+
});
|
|
230
|
+
} else {
|
|
231
|
+
var bounds = CoordinatesUtils.reprojectBbox(state.bbox.bounds, state.projection, positionCrs);
|
|
232
|
+
Object.assign(newParams, {
|
|
233
|
+
e: bounds.map(function (x) {
|
|
234
|
+
return x.toFixed(prec);
|
|
235
|
+
}).join(",")
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (positionCrs !== state.projection) {
|
|
239
|
+
Object.assign(newParams, {
|
|
240
|
+
crs: positionCrs
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (!isEmpty(newParams)) {
|
|
244
|
+
UrlParams.updateParams(newParams);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
export default MapUtils;
|