@panoramax/web-viewer 3.2.3 → 4.0.0-develop-39167b4d
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/.gitlab-ci.yml +13 -6
- package/CHANGELOG.md +53 -1
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +1 -1
- package/build/editor.html +10 -1
- package/build/index.css +12 -12
- package/build/index.css.map +1 -1
- package/build/index.html +1 -1
- package/build/index.js +2126 -14
- package/build/index.js.map +1 -1
- package/build/map.html +1 -1
- package/build/photo.html +1 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-400-normal..woff +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-400-normal..woff2 +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-ext-400-normal..woff +0 -0
- package/build/static/media/atkinson-hyperlegible-next-latin-ext-400-normal..woff2 +0 -0
- package/build/viewer.html +12 -1
- package/build/widgets.html +1 -0
- package/config/jest/mocks.js +201 -0
- package/config/paths.js +2 -0
- package/config/webpack.config.js +52 -0
- package/docs/03_URL_settings.md +14 -16
- package/docs/05_Compatibility.md +59 -76
- package/docs/09_Develop.md +46 -11
- package/docs/90_Releases.md +2 -2
- package/docs/images/class_diagram.drawio +60 -45
- package/docs/images/class_diagram.jpg +0 -0
- package/docs/images/screenshot.jpg +0 -0
- package/docs/index.md +135 -0
- package/docs/reference/components/core/Basic.md +196 -0
- package/docs/reference/components/core/CoverageMap.md +210 -0
- package/docs/reference/components/core/Editor.md +224 -0
- package/docs/reference/components/core/PhotoViewer.md +307 -0
- package/docs/reference/components/core/Viewer.md +350 -0
- package/docs/reference/components/layout/BottomDrawer.md +35 -0
- package/docs/reference/components/layout/CorneredGrid.md +29 -0
- package/docs/reference/components/layout/Mini.md +45 -0
- package/docs/reference/components/layout/Tabs.md +45 -0
- package/docs/reference/components/menus/MapBackground.md +32 -0
- package/docs/reference/components/menus/MapFilters.md +15 -0
- package/docs/reference/components/menus/MapLayers.md +15 -0
- package/docs/reference/components/menus/MapLegend.md +15 -0
- package/docs/reference/components/menus/PictureLegend.md +16 -0
- package/docs/reference/components/menus/PictureMetadata.md +15 -0
- package/docs/reference/components/menus/PlayerOptions.md +15 -0
- package/docs/reference/components/menus/QualityScoreDoc.md +15 -0
- package/docs/reference/components/menus/ReportForm.md +15 -0
- package/docs/reference/components/menus/ShareMenu.md +15 -0
- package/docs/reference/components/ui/Button.md +40 -0
- package/docs/reference/components/ui/ButtonGroup.md +36 -0
- package/docs/reference/components/ui/CopyButton.md +38 -0
- package/docs/reference/components/ui/Grade.md +32 -0
- package/docs/reference/components/ui/LinkButton.md +45 -0
- package/docs/reference/components/ui/ListGroup.md +22 -0
- package/docs/reference/components/ui/Loader.md +56 -0
- package/docs/reference/components/ui/Map.md +239 -0
- package/docs/reference/components/ui/MapMore.md +256 -0
- package/docs/reference/components/ui/Photo.md +385 -0
- package/docs/reference/components/ui/Popup.md +56 -0
- package/docs/reference/components/ui/ProgressBar.md +32 -0
- package/docs/reference/components/ui/QualityScore.md +45 -0
- package/docs/reference/components/ui/SearchBar.md +63 -0
- package/docs/reference/components/ui/TogglableGroup.md +39 -0
- package/docs/reference/components/ui/widgets/GeoSearch.md +32 -0
- package/docs/reference/components/ui/widgets/Legend.md +49 -0
- package/docs/reference/components/ui/widgets/MapFiltersButton.md +33 -0
- package/docs/reference/components/ui/widgets/MapLayersButton.md +15 -0
- package/docs/reference/components/ui/widgets/OSMEditors.md +15 -0
- package/docs/reference/components/ui/widgets/PictureLegendActions.md +32 -0
- package/docs/reference/components/ui/widgets/Player.md +33 -0
- package/docs/reference/components/ui/widgets/Zoom.md +15 -0
- package/docs/reference/utils/API.md +334 -0
- package/docs/reference/utils/InitParameters.md +68 -0
- package/docs/reference/utils/URLHandler.md +107 -0
- package/docs/reference.md +79 -0
- package/docs/shortcuts.md +11 -0
- package/docs/tutorials/aerial_imagery.md +19 -0
- package/docs/tutorials/authentication.md +10 -0
- package/docs/tutorials/custom_widgets.md +59 -0
- package/docs/tutorials/map_style.md +39 -0
- package/docs/tutorials/migrate_v4.md +153 -0
- package/docs/tutorials/synced_coverage.md +43 -0
- package/mkdocs.yml +66 -5
- package/package.json +22 -17
- package/public/editor.html +21 -29
- package/public/index.html +17 -12
- package/public/map.html +19 -18
- package/public/photo.html +55 -0
- package/public/viewer.html +22 -26
- package/public/widgets.html +306 -0
- package/scripts/doc.js +79 -0
- package/src/components/core/Basic.css +48 -0
- package/src/components/core/Basic.js +349 -0
- package/src/components/core/CoverageMap.css +9 -0
- package/src/components/core/CoverageMap.js +139 -0
- package/src/components/core/Editor.css +23 -0
- package/src/components/core/Editor.js +390 -0
- package/src/components/core/PhotoViewer.css +48 -0
- package/src/components/core/PhotoViewer.js +499 -0
- package/src/components/core/Viewer.css +98 -0
- package/src/components/core/Viewer.js +564 -0
- package/src/components/core/index.js +12 -0
- package/src/components/index.js +13 -0
- package/src/components/layout/BottomDrawer.js +257 -0
- package/src/components/layout/CorneredGrid.js +112 -0
- package/src/components/layout/Mini.js +117 -0
- package/src/components/layout/Tabs.js +133 -0
- package/src/components/layout/index.js +9 -0
- package/src/components/menus/MapBackground.js +106 -0
- package/src/components/menus/MapFilters.js +400 -0
- package/src/components/menus/MapLayers.js +143 -0
- package/src/components/menus/MapLegend.js +34 -0
- package/src/components/menus/PictureLegend.js +257 -0
- package/src/components/menus/PictureMetadata.js +317 -0
- package/src/components/menus/PlayerOptions.js +95 -0
- package/src/components/menus/QualityScoreDoc.js +36 -0
- package/src/components/menus/ReportForm.js +133 -0
- package/src/components/menus/Share.js +100 -0
- package/src/components/menus/index.js +15 -0
- package/src/components/styles.js +383 -0
- package/src/components/ui/Button.js +77 -0
- package/src/components/ui/ButtonGroup.css +57 -0
- package/src/components/ui/ButtonGroup.js +68 -0
- package/src/components/ui/CopyButton.js +106 -0
- package/src/components/ui/Grade.js +54 -0
- package/src/components/ui/LinkButton.js +67 -0
- package/src/components/ui/ListGroup.js +66 -0
- package/src/components/ui/Loader.js +203 -0
- package/src/components/{Map.css → ui/Map.css} +5 -17
- package/src/components/{Map.js → ui/Map.js} +148 -156
- package/src/components/ui/MapMore.js +324 -0
- package/src/components/{Photo.css → ui/Photo.css} +6 -6
- package/src/components/{Photo.js → ui/Photo.js} +313 -101
- package/src/components/ui/Popup.js +145 -0
- package/src/components/ui/ProgressBar.js +104 -0
- package/src/components/ui/QualityScore.js +147 -0
- package/src/components/ui/SearchBar.js +367 -0
- package/src/components/ui/TogglableGroup.js +157 -0
- package/src/components/ui/index.js +22 -0
- package/src/components/ui/widgets/GeoSearch.css +21 -0
- package/src/components/ui/widgets/GeoSearch.js +139 -0
- package/src/components/ui/widgets/Legend.js +113 -0
- package/src/components/ui/widgets/MapFiltersButton.js +104 -0
- package/src/components/ui/widgets/MapLayersButton.js +79 -0
- package/src/components/ui/widgets/OSMEditors.js +155 -0
- package/src/components/ui/widgets/PictureLegendActions.js +117 -0
- package/src/components/ui/widgets/Player.css +7 -0
- package/src/components/ui/widgets/Player.js +151 -0
- package/src/components/ui/widgets/Zoom.js +82 -0
- package/src/components/ui/widgets/index.js +13 -0
- package/src/img/loader_base.jpg +0 -0
- package/src/img/panoramax.svg +13 -0
- package/src/img/switch_big.svg +20 -10
- package/src/index.js +7 -9
- package/src/translations/br.json +1 -0
- package/src/translations/da.json +38 -15
- package/src/translations/de.json +5 -3
- package/src/translations/en.json +35 -15
- package/src/translations/eo.json +38 -15
- package/src/translations/es.json +1 -1
- package/src/translations/fr.json +36 -16
- package/src/translations/hu.json +1 -1
- package/src/translations/it.json +39 -16
- package/src/translations/ja.json +182 -1
- package/src/translations/nl.json +106 -6
- package/src/translations/pl.json +1 -1
- package/src/translations/sv.json +182 -0
- package/src/translations/zh_Hant.json +35 -14
- package/src/utils/API.js +109 -49
- package/src/utils/InitParameters.js +388 -0
- package/src/utils/PhotoAdapter.js +1 -0
- package/src/utils/URLHandler.js +362 -0
- package/src/utils/geocoder.js +152 -0
- package/src/utils/{I18n.js → i18n.js} +7 -3
- package/src/utils/index.js +11 -0
- package/src/utils/{Map.js → map.js} +256 -77
- package/src/utils/picture.js +442 -0
- package/src/utils/utils.js +324 -0
- package/src/utils/widgets.js +55 -0
- package/tests/components/core/Basic.test.js +121 -0
- package/tests/components/core/BasicMock.js +25 -0
- package/tests/components/core/CoverageMap.test.js +20 -0
- package/tests/components/core/Editor.test.js +20 -0
- package/tests/components/core/PhotoViewer.test.js +57 -0
- package/tests/components/core/Viewer.test.js +84 -0
- package/tests/components/core/__snapshots__/PhotoViewer.test.js.snap +73 -0
- package/tests/components/core/__snapshots__/Viewer.test.js.snap +145 -0
- package/tests/components/ui/CopyButton.test.js +52 -0
- package/tests/components/ui/Loader.test.js +55 -0
- package/tests/components/{Map.test.js → ui/Map.test.js} +73 -61
- package/tests/components/{Photo.test.js → ui/Photo.test.js} +97 -63
- package/tests/components/ui/Popup.test.js +26 -0
- package/tests/components/ui/QualityScore.test.js +18 -0
- package/tests/components/ui/SearchBar.test.js +110 -0
- package/tests/components/ui/__snapshots__/CopyButton.test.js.snap +33 -0
- package/tests/components/ui/__snapshots__/Loader.test.js.snap +56 -0
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Map.test.js.snap +11 -38
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Photo.test.js.snap +70 -6
- package/tests/components/ui/__snapshots__/Popup.test.js.snap +29 -0
- package/tests/components/ui/__snapshots__/QualityScore.test.js.snap +11 -0
- package/tests/components/ui/__snapshots__/SearchBar.test.js.snap +65 -0
- package/tests/utils/API.test.js +83 -83
- package/tests/utils/InitParameters.test.js +499 -0
- package/tests/utils/URLHandler.test.js +401 -0
- package/tests/utils/__snapshots__/API.test.js.snap +10 -0
- package/tests/utils/__snapshots__/URLHandler.test.js.snap +21 -0
- package/tests/utils/__snapshots__/{Map.test.js.snap → geocoder.test.js.snap} +1 -1
- package/tests/utils/__snapshots__/map.test.js.snap +11 -0
- package/tests/utils/__snapshots__/picture.test.js.snap +327 -0
- package/tests/utils/__snapshots__/widgets.test.js.snap +19 -0
- package/tests/utils/geocoder.test.js +37 -0
- package/tests/utils/{I18n.test.js → i18n.test.js} +8 -8
- package/tests/utils/map.test.js +126 -0
- package/tests/utils/picture.test.js +745 -0
- package/tests/utils/utils.test.js +288 -0
- package/tests/utils/widgets.test.js +31 -0
- package/docs/01_Start.md +0 -149
- package/docs/02_Usage.md +0 -831
- package/docs/04_Advanced_examples.md +0 -216
- package/src/Editor.css +0 -37
- package/src/Editor.js +0 -361
- package/src/StandaloneMap.js +0 -114
- package/src/Viewer.css +0 -203
- package/src/Viewer.js +0 -1246
- package/src/components/CoreView.css +0 -70
- package/src/components/CoreView.js +0 -175
- package/src/components/Loader.css +0 -74
- package/src/components/Loader.js +0 -120
- package/src/img/loader_hd.jpg +0 -0
- package/src/utils/Exif.js +0 -193
- package/src/utils/Utils.js +0 -631
- package/src/utils/Widgets.js +0 -562
- package/src/viewer/URLHash.js +0 -469
- package/src/viewer/Widgets.css +0 -880
- package/src/viewer/Widgets.js +0 -1470
- package/tests/Editor.test.js +0 -126
- package/tests/StandaloneMap.test.js +0 -45
- package/tests/Viewer.test.js +0 -366
- package/tests/__snapshots__/Editor.test.js.snap +0 -298
- package/tests/__snapshots__/StandaloneMap.test.js.snap +0 -30
- package/tests/__snapshots__/Viewer.test.js.snap +0 -195
- package/tests/components/CoreView.test.js +0 -92
- package/tests/components/Loader.test.js +0 -38
- package/tests/components/__snapshots__/Loader.test.js.snap +0 -15
- package/tests/utils/Exif.test.js +0 -124
- package/tests/utils/Map.test.js +0 -113
- package/tests/utils/Utils.test.js +0 -300
- package/tests/utils/Widgets.test.js +0 -107
- package/tests/utils/__snapshots__/Exif.test.js.snap +0 -43
- package/tests/utils/__snapshots__/Utils.test.js.snap +0 -41
- package/tests/utils/__snapshots__/Widgets.test.js.snap +0 -44
- package/tests/viewer/URLHash.test.js +0 -559
- package/tests/viewer/Widgets.test.js +0 -127
- package/tests/viewer/__snapshots__/URLHash.test.js.snap +0 -108
- package/tests/viewer/__snapshots__/Widgets.test.js.snap +0 -403
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import * as utils from "../../src/utils/utils";
|
|
2
|
+
|
|
3
|
+
jest.mock("../../src/utils/map", () => ({
|
|
4
|
+
COLORS_HEX: {
|
|
5
|
+
SELECTED: 0x0000ff,
|
|
6
|
+
}
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe("getGrade", () => {
|
|
10
|
+
it("works with null-like", () => {
|
|
11
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, null)).toBeNull();
|
|
12
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, undefined)).toBeNull();
|
|
13
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, "")).toBeNull();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("works with grade values", () => {
|
|
17
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 0)).toBe(1);
|
|
18
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 5)).toBe(1);
|
|
19
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 12)).toBe(2);
|
|
20
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 25)).toBe(3);
|
|
21
|
+
expect(utils.getGrade(utils.QUALITYSCORE_RES_FLAT_VALUES, 40)).toBe(4);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("getDistance", () => {
|
|
26
|
+
it("works", () => {
|
|
27
|
+
const p1 = [1,1];
|
|
28
|
+
const p2 = [2,2];
|
|
29
|
+
const res = utils.getDistance(p1, p2);
|
|
30
|
+
expect(res).toBe(Math.sqrt(2));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("svgToPSVLink", () => {
|
|
35
|
+
it("works", () => {
|
|
36
|
+
const base64Svg = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxjaXJjbGUgY3g9JzUnIGN5PSc1JyByPSc1JyBmaWxsPScjMDAwJy8+PC9zdmc+";
|
|
37
|
+
const fillColor = "red";
|
|
38
|
+
const result = utils.svgToPSVLink(base64Svg, fillColor);
|
|
39
|
+
|
|
40
|
+
expect(result).toBeInstanceOf(HTMLButtonElement);
|
|
41
|
+
expect(result.classList.contains("pnx-psv-tour-arrows")).toBe(true);
|
|
42
|
+
expect(result.style.color).toBe(fillColor);
|
|
43
|
+
expect(result.querySelector("svg")).not.toBeNull();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("works with invalid input", () => {
|
|
47
|
+
const invalidBase64Svg = "http://test.net/invalid_string";
|
|
48
|
+
const result = utils.svgToPSVLink(invalidBase64Svg, "blue");
|
|
49
|
+
|
|
50
|
+
expect(result).toBeInstanceOf(HTMLImageElement);
|
|
51
|
+
expect(result.src).toBe(invalidBase64Svg);
|
|
52
|
+
expect(result.alt).toBe("");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("getAzimuth", () => {
|
|
57
|
+
it("works with 0 + NE", () => {
|
|
58
|
+
const pointDepart = [0, 0];
|
|
59
|
+
const pointArrivee = [1, 1];
|
|
60
|
+
const azimuth = utils.getAzimuth(pointDepart, pointArrivee);
|
|
61
|
+
expect(azimuth).toBe(45);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("works with 0 + SE", () => {
|
|
65
|
+
const pointDepart = [0, 0];
|
|
66
|
+
const pointArrivee = [1, -1];
|
|
67
|
+
const azimuth = utils.getAzimuth(pointDepart, pointArrivee);
|
|
68
|
+
expect(azimuth).toBe(135);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("works with 0 + N", () => {
|
|
72
|
+
const pointDepart = [0, 0];
|
|
73
|
+
const pointArrivee = [0, 1];
|
|
74
|
+
const azimuth = utils.getAzimuth(pointDepart, pointArrivee);
|
|
75
|
+
expect(azimuth).toBe(0);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("works with 0 + S", () => {
|
|
79
|
+
const pointDepart = [0, 0];
|
|
80
|
+
const pointArrivee = [0, -1];
|
|
81
|
+
const azimuth = utils.getAzimuth(pointDepart, pointArrivee);
|
|
82
|
+
expect(azimuth).toBe(180);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("getRelativeHeading", () => {
|
|
87
|
+
it("should throw an error if no picture selected", () => {
|
|
88
|
+
expect(() => utils.getRelativeHeading()).toThrow("No picture selected");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should calculate relative heading correctly", () => {
|
|
92
|
+
const pictureMetadata = {
|
|
93
|
+
properties: { "view:azimuth": 30 },
|
|
94
|
+
sequence: { prevPic: "prevPictureId", nextPic: "nextPictureId" },
|
|
95
|
+
links: [
|
|
96
|
+
{ nodeId: "prevPictureId", gps: [0, 0] },
|
|
97
|
+
{ nodeId: "nextPictureId", gps: [2, 2] }
|
|
98
|
+
],
|
|
99
|
+
gps: [1, 1]
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
expect(utils.getRelativeHeading(pictureMetadata)).toBe(-15);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("works looking behind", () => {
|
|
106
|
+
const pictureMetadata = {
|
|
107
|
+
properties: { "view:azimuth": 226 },
|
|
108
|
+
sequence: { prevPic: "prevPictureId", nextPic: "nextPictureId" },
|
|
109
|
+
links: [
|
|
110
|
+
{ nodeId: "prevPictureId", gps: [0, 0] },
|
|
111
|
+
{ nodeId: "nextPictureId", gps: [2, 2] }
|
|
112
|
+
],
|
|
113
|
+
gps: [1, 1]
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
expect(utils.getRelativeHeading(pictureMetadata)).toBe(-179);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("works with distorted path", () => {
|
|
120
|
+
const pictureMetadata = {
|
|
121
|
+
properties: { "view:azimuth": 100 },
|
|
122
|
+
sequence: { prevPic: "prevPictureId", nextPic: "nextPictureId" },
|
|
123
|
+
links: [
|
|
124
|
+
{ nodeId: "prevPictureId", gps: [0, 0] },
|
|
125
|
+
{ nodeId: "nextPictureId", gps: [2, 1] }
|
|
126
|
+
],
|
|
127
|
+
gps: [1, 0]
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
expect(utils.getRelativeHeading(pictureMetadata)).toBe(10);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("works without previous link", () => {
|
|
134
|
+
const pictureMetadata = {
|
|
135
|
+
properties: { "view:azimuth": 100 },
|
|
136
|
+
sequence: { nextPic: "nextPictureId" },
|
|
137
|
+
links: [
|
|
138
|
+
{ nodeId: "nextPictureId", gps: [2, 1] }
|
|
139
|
+
],
|
|
140
|
+
gps: [1, 1]
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
expect(utils.getRelativeHeading(pictureMetadata)).toBe(10);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should handle missing prevPic or nextPic", () => {
|
|
147
|
+
const metadataWithoutPrevNext = {
|
|
148
|
+
properties: { "view:azimuth": 30 },
|
|
149
|
+
gps: [0, 0]
|
|
150
|
+
};
|
|
151
|
+
expect(utils.getRelativeHeading(metadataWithoutPrevNext)).toBe(0);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("getSimplifiedAngle", () => {
|
|
156
|
+
it("returns \"N\"", () => {
|
|
157
|
+
expect(utils.getSimplifiedAngle([0, 0], [0, 1])).toBe("N");
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("returns \"ENE\"", () => {
|
|
161
|
+
expect(utils.getSimplifiedAngle([0, 0], [1, 1])).toBe("ENE");
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("returns \"ESE\"", () => {
|
|
165
|
+
expect(utils.getSimplifiedAngle([0, 0], [1, -1])).toBe("ESE");
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("returns \"S\"", () => {
|
|
169
|
+
expect(utils.getSimplifiedAngle([0, 0], [0, -1])).toBe("S");
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("returns \"WNW\"", () => {
|
|
173
|
+
expect(utils.getSimplifiedAngle([0, 0], [-1, 1])).toBe("WNW");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("returns \"WSW\"", () => {
|
|
177
|
+
expect(utils.getSimplifiedAngle([0, 0], [-1, -1])).toBe("WSW");
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe("positionToXYZ", () => {
|
|
182
|
+
it("works with xy", () => {
|
|
183
|
+
const r = utils.positionToXYZ({ pitch: 10, yaw: -5 });
|
|
184
|
+
expect(r).toEqual({ x: -286.4788975654116, y: 572.9577951308232 });
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("works with xyz", () => {
|
|
188
|
+
const r = utils.positionToXYZ({ pitch: 10, yaw: -5 }, 15);
|
|
189
|
+
expect(r).toEqual({ x: -286.4788975654116, y: 572.9577951308232, z: 15 });
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("xyzToPosition", () => {
|
|
194
|
+
it("works with xyz", () => {
|
|
195
|
+
const r = utils.xyzToPosition(-286.4788975654116, 572.9577951308232, 15);
|
|
196
|
+
expect(r).toEqual({ pitch: 10, yaw: -5, zoom: 15 });
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe("josmBboxParameters", () => {
|
|
201
|
+
it("works with null-like", () => {
|
|
202
|
+
expect(utils.josmBboxParameters(null)).toBeNull();
|
|
203
|
+
expect(utils.josmBboxParameters(undefined)).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("works without azimuth", () => {
|
|
207
|
+
const meta = { gps: [2.3522, 48.8566] };
|
|
208
|
+
const result = utils.josmBboxParameters(meta);
|
|
209
|
+
expect(result).toBe("left=2.3522&right=2.3522&top=48.8566&bottom=48.8566&changeset_source=Panoramax");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("works with azimuth = 0", () => {
|
|
213
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 0 } };
|
|
214
|
+
const result = utils.josmBboxParameters(meta);
|
|
215
|
+
expect(result).toBe("left=2.3522&right=2.3524&top=48.8568&bottom=48.8566&changeset_source=Panoramax");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("works with azimuth = 180", () => {
|
|
219
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 180 } };
|
|
220
|
+
const result = utils.josmBboxParameters(meta);
|
|
221
|
+
expect(result).toBe("left=2.352&right=2.3524&top=48.8566&bottom=48.8564&changeset_source=Panoramax");
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("works with azimuth = 90", () => {
|
|
225
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 90 } };
|
|
226
|
+
const result = utils.josmBboxParameters(meta);
|
|
227
|
+
expect(result).toBe("left=2.3522&right=2.3524&top=48.8568&bottom=48.8564&changeset_source=Panoramax");
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("works with azimuth = 270", () => {
|
|
231
|
+
const meta = { gps: [2.3522, 48.8566], properties: { "view:azimuth": 270 } };
|
|
232
|
+
const result = utils.josmBboxParameters(meta);
|
|
233
|
+
expect(result).toBe("left=2.352&right=2.3522&top=48.8568&bottom=48.8564&changeset_source=Panoramax");
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe("getCookie", () => {
|
|
238
|
+
it("should return the value of the specified cookie", () => {
|
|
239
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123");
|
|
240
|
+
expect(utils.getCookie("session")).toBe("abc123");
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("should return null if the cookie is not found", () => {
|
|
244
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123");
|
|
245
|
+
expect(utils.getCookie("user_id")).toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("should return the correct value when multiple cookies are set", () => {
|
|
249
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=abc123; user_id=789; user_name=John");
|
|
250
|
+
expect(utils.getCookie("user_id")).toBe("789");
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("should return null if cookie with the specified name has no value", () => {
|
|
254
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("session=; user_id=789");
|
|
255
|
+
expect(utils.getCookie("session")).toBe("");
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it("should return the correct value when the cookie contains =", () => {
|
|
259
|
+
jest.spyOn(document, "cookie", "get").mockReturnValueOnce("custom_cookie=abc=123");
|
|
260
|
+
expect(utils.getCookie("custom_cookie")).toBe("abc=123");
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe("getUserAccount", () => {
|
|
265
|
+
it("should return an object with user id and name when all cookies are present", () => {
|
|
266
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_id=789; user_name=John");
|
|
267
|
+
expect(utils.getUserAccount()).toEqual({ id: "789", name: "John" });
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("should return null if session cookie is missing", () => {
|
|
271
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("user_id=789; user_name=John");
|
|
272
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should return null if user_id cookie is missing", () => {
|
|
276
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_name=John");
|
|
277
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it("should return null if user_name cookie is missing", () => {
|
|
281
|
+
jest.spyOn(document, "cookie", "get").mockReturnValue("session=abc123; user_id=789");
|
|
282
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it("should return null if all cookies are missing", () => {
|
|
286
|
+
expect(utils.getUserAccount()).toBeNull();
|
|
287
|
+
});
|
|
288
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
|
|
2
|
+
import * as widgets from "../../src/utils/widgets";
|
|
3
|
+
|
|
4
|
+
describe("fa", () => {
|
|
5
|
+
it("works", () => {
|
|
6
|
+
const res = widgets.fa(faChevronDown);
|
|
7
|
+
expect(res).toMatchSnapshot();
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe("createWebComp", () => {
|
|
12
|
+
it("works", () => {
|
|
13
|
+
const tag = "custom-element";
|
|
14
|
+
const props = {
|
|
15
|
+
id: "test-id",
|
|
16
|
+
class: "test-class",
|
|
17
|
+
_customProp: "secret",
|
|
18
|
+
fnDoSomething: jest.fn(),
|
|
19
|
+
onClick: jest.fn(),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const wc = widgets.createWebComp(tag, props);
|
|
23
|
+
|
|
24
|
+
expect(wc).toBeInstanceOf(HTMLElement);
|
|
25
|
+
expect(wc.tagName.toLowerCase()).toBe(tag);
|
|
26
|
+
expect(wc.getAttribute("id")).toBe(props.id);
|
|
27
|
+
expect(wc.getAttribute("class")).toBe(props.class);
|
|
28
|
+
expect(wc._customProp).toBe(props._customProp);
|
|
29
|
+
expect(wc.DoSomething).toBe(props.fnDoSomething);
|
|
30
|
+
});
|
|
31
|
+
});
|
package/docs/01_Start.md
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
# Web viewer documentation
|
|
2
|
-
|
|
3
|
-
Welcome to Panoramax __Web Viewer__ documentation ! It will help you through all phases of setup, run and develop on Panoramax JS pictures viewer.
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-
|
|
7
|
-
!!! note
|
|
8
|
-
|
|
9
|
-
If at some point you're lost or need help, you can contact us through [issues](https://gitlab.com/panoramax/clients/web-viewer/-/issues) or by [email](mailto:panieravide@riseup.net).
|
|
10
|
-
|
|
11
|
-
## Install the viewer
|
|
12
|
-
|
|
13
|
-
Many options are available for installing the viewer.
|
|
14
|
-
|
|
15
|
-
=== ":simple-npm: NPM"
|
|
16
|
-
|
|
17
|
-
Panoramax viewer is available on NPM as [@panoramax/web-viewer](https://www.npmjs.com/package/@panoramax/web-viewer) package.
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install @panoramax/web-viewer
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
If you want the latest version (corresponding to the `develop` git branch), you can use the `develop` NPM dist-tag:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm install @panoramax/web-viewer@develop
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
=== ":material-web: Hosted"
|
|
30
|
-
|
|
31
|
-
You can rely on various providers offering hosted NPM packages, for example JSDelivr.
|
|
32
|
-
|
|
33
|
-
```html
|
|
34
|
-
<!-- You may use another version than 3.0.2, just change the release in URL -->
|
|
35
|
-
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@panoramax/web-viewer@3.0.2/build/index.css" />
|
|
36
|
-
<script src="https://cdn.jsdelivr.net/npm/@panoramax/web-viewer@3.0.2/build/index.js"></script>
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
=== ":material-code-tags: Source code"
|
|
40
|
-
|
|
41
|
-
You can install and use Panoramax web client based on code provided in this repository.
|
|
42
|
-
|
|
43
|
-
This library relies on __Node.js 16__, which should be installed on your computer. Then, you can build the library using these commands:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
git clone https://gitlab.com/panoramax/clients/web-viewer.git
|
|
47
|
-
cd web-viewer/
|
|
48
|
-
npm install
|
|
49
|
-
npm build
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
## Basic usage
|
|
54
|
-
|
|
55
|
-
First, you need to make sure everything is ready to create the viewer:
|
|
56
|
-
|
|
57
|
-
=== ":fontawesome-brands-js: Old-school JS"
|
|
58
|
-
|
|
59
|
-
Make sure to have both JS and CSS code available in your HTML `head` part:
|
|
60
|
-
|
|
61
|
-
```html
|
|
62
|
-
<!-- Change the actual path depending of where you installed the library -->
|
|
63
|
-
<link rel="stylesheet" type="text/css" href="web-viewer/build/index.css" />
|
|
64
|
-
<script src="web-viewer/build/index.js"></script>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
And you also node a `div` somewhere in your HTML:
|
|
68
|
-
|
|
69
|
-
```html
|
|
70
|
-
<div id="viewer" style="width: 500px; height: 300px"></div>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Then, the div is populated with this JavaScript code:
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
let myViewer = new Panoramax.Viewer(
|
|
77
|
-
"viewer", // Div ID
|
|
78
|
-
"https://api.panoramax.xyz/api", // STAC API endpoint
|
|
79
|
-
{ map: true } // Viewer options
|
|
80
|
-
);
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
=== ":fontawesome-brands-node-js: New-style JS"
|
|
84
|
-
|
|
85
|
-
Make sure to import both JS and CSS in your code:
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
import Panoramax from '@panoramax/web-viewer';
|
|
89
|
-
import '@panoramax/web-viewer/build/index.css';
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
And have access in some way to a classic `div` HTML element:
|
|
93
|
-
|
|
94
|
-
```js
|
|
95
|
-
const myDiv = document.getElementById("viewer");
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Then, the div is populated with this JavaScript code:
|
|
99
|
-
|
|
100
|
-
```js
|
|
101
|
-
let myViewer = new Panoramax.Viewer(
|
|
102
|
-
myDiv, // Div Element
|
|
103
|
-
"https://api.panoramax.xyz/api", // STAC API endpoint
|
|
104
|
-
{ map: true } // Viewer options
|
|
105
|
-
);
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Beyond classic viewer, other widgets are available and [can be tested online](https://viewer.geovisio.fr/):
|
|
110
|
-
|
|
111
|
-
__Standalone-map__
|
|
112
|
-
|
|
113
|
-
A simple map for showing coverage only.
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
var myMap = new Panoramax.StandaloneMap(
|
|
117
|
-
"map", // Div ID
|
|
118
|
-
"https://api.panoramax.xyz/api" // STAC API endpoint
|
|
119
|
-
);
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
__Editor__
|
|
123
|
-
|
|
124
|
-
A map and photo viewer, focused on a single sequence, for previewing edits made to it.
|
|
125
|
-
|
|
126
|
-
```js
|
|
127
|
-
var myEditor = new Panoramax.Editor(
|
|
128
|
-
"editor", // Div ID
|
|
129
|
-
"https://api.panoramax.xyz/api", // STAC API endpoint
|
|
130
|
-
{
|
|
131
|
-
selectedSequence: "id-to-an-existing-sequence", // Sequence ID (mandatory)
|
|
132
|
-
selectedPicture: "id-to-a-picture-in-this-sequence" // Picture ID (optional)
|
|
133
|
-
}
|
|
134
|
-
);
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## User interface
|
|
138
|
-
|
|
139
|
-
### Keyboard shortcuts
|
|
140
|
-
|
|
141
|
-
All interactions with the viewer can be done using the mouse, and some can be also done using keyboard.
|
|
142
|
-
|
|
143
|
-
* __Arrows__ (or 2/4/8/6 on keypad): move inside the picture, or move the map
|
|
144
|
-
* __Page up/down__ (or 3/9 on keypad) : go to next or previous picture in sequence
|
|
145
|
-
* __+ / -__ : zoom picture or map in or out
|
|
146
|
-
* __*__ (or 5 on keypad) : move picture or map to its center
|
|
147
|
-
* __Home / ↖️__ (or 7 on keypad) : switch map and picture as main shown component
|
|
148
|
-
* __End__ (or 1 on keypad) : hide minimized map or picture
|
|
149
|
-
* __Space__ : play or pause current sequence
|