mapicgc-gl-js 1.0.2 → 1.0.3
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/README.md +35 -1
- package/dist/chunk-efA98nb6-Dfm7IivL.mjs +13 -0
- package/dist/html2canvas-DhrjCa5K-zEqRDH-g.mjs +4024 -0
- package/dist/index.es-D_FsJY9H-CO3QIBGM.mjs +5741 -0
- package/dist/mapicgc-gl-js.css +2 -0
- package/dist/mapicgc-gl.css +1948 -1
- package/dist/mapicgc-gl.js +224 -440
- package/dist/mapicgc-gl.mjs +88130 -5
- package/dist/purify.es-DVGU85zV-CJOZ7ABI.mjs +549 -0
- package/dist/typeof-CTd55yxz-BxqQpTq1.mjs +11 -0
- package/dist/webgl-device-CDzrheIu.mjs +2 -0
- package/dist/webgl-device-DPB4IspV.mjs +5573 -0
- package/package.json +19 -20
- package/src/map/Map.js +33 -3
- package/test/exemples/addMapStyle.html +7 -5
- package/test/vitest/Config.test.js +145 -0
- package/test/vitest/MapFunctions.test.js +971 -0
- package/vite.config.mjs +7 -2
- package/dist/html2canvas.esm-Dmi1NfiH-AQaq32X6.mjs +0 -4534
- package/dist/index-DdkbNQVU.mjs +0 -83555
- package/dist/index.es-CDV9zB2B-CB-dpJjG.mjs +0 -6731
- package/dist/mapicgc-gl.umd.js +0 -4064
- package/dist/purify.es-DHbHSKL1-2rarU4M1.mjs +0 -480
- package/test/vitest/Map.test.js +0 -215
- package/test/vitest/MapStyle.test.js +0 -129
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapicgc-gl-js",
|
|
3
3
|
"homepage": "https://openicgc.github.io/mapicgc-doc/",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"description": "mapicgc-gl-js library",
|
|
6
6
|
"author": "Institut Cartogràfic i Geològic de Catalunya",
|
|
7
7
|
"license": "BSD-3-Clause",
|
|
8
8
|
"type": "commonjs",
|
|
9
|
-
|
|
10
9
|
"keywords": [
|
|
11
10
|
"map",
|
|
12
11
|
"js",
|
|
@@ -43,34 +42,34 @@
|
|
|
43
42
|
"test": "vitest"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
|
-
"@babel/core": "^7.
|
|
47
|
-
"@babel/preset-env": "^7.
|
|
48
|
-
"@rollup/plugin-babel": "^
|
|
49
|
-
"axios": "^1.
|
|
50
|
-
"dotenv": "^17.
|
|
51
|
-
"jest": "30.
|
|
45
|
+
"@babel/core": "^7.29.0",
|
|
46
|
+
"@babel/preset-env": "^7.29.2",
|
|
47
|
+
"@rollup/plugin-babel": "^7.0.0",
|
|
48
|
+
"axios": "^1.14.0",
|
|
49
|
+
"dotenv": "^17.3.1",
|
|
50
|
+
"jest": "30.3.0",
|
|
52
51
|
"jsdoc": "^4.0.5",
|
|
53
|
-
"jsdom": "^
|
|
52
|
+
"jsdom": "^29.0.1",
|
|
54
53
|
"npm-run-all": "^4.1.5",
|
|
55
54
|
"package-json-versionify": "^1.0.4",
|
|
56
55
|
"path": "^0.12.7",
|
|
57
56
|
"rollup-plugin-polyfill": "^4.2.0",
|
|
58
|
-
"ssh2-sftp-client": "^12.
|
|
59
|
-
"vite": "^
|
|
60
|
-
"vite-plugin-node-polyfills": "^0.
|
|
61
|
-
|
|
57
|
+
"ssh2-sftp-client": "^12.1.1",
|
|
58
|
+
"vite": "^8.0.3",
|
|
59
|
+
"vite-plugin-node-polyfills": "^0.26.0",
|
|
60
|
+
"vitest": "^4.1.2",
|
|
62
61
|
"xml2js": "^0.6.2"
|
|
63
62
|
},
|
|
64
63
|
"dependencies": {
|
|
65
|
-
"@deck.gl/core": "^9.2.
|
|
66
|
-
"@deck.gl/geo-layers": "^9.2.
|
|
67
|
-
"@deck.gl/mapbox": "^9.2.
|
|
64
|
+
"@deck.gl/core": "^9.2.11",
|
|
65
|
+
"@deck.gl/geo-layers": "^9.2.11",
|
|
66
|
+
"@deck.gl/mapbox": "^9.2.11",
|
|
68
67
|
"@loaders.gl/3d-tiles": "~4.3.4",
|
|
69
68
|
"@maplibre/maplibre-gl-compare": "^0.5.0",
|
|
70
|
-
"@maplibre/maplibre-gl-geocoder": "^1.9.
|
|
71
|
-
"@watergis/maplibre-gl-export": "^4.1.
|
|
72
|
-
"flatgeobuf": "^4.
|
|
73
|
-
"maplibre-gl": "^5.
|
|
69
|
+
"@maplibre/maplibre-gl-geocoder": "^1.9.4",
|
|
70
|
+
"@watergis/maplibre-gl-export": "^4.1.2",
|
|
71
|
+
"flatgeobuf": "^4.4.0",
|
|
72
|
+
"maplibre-gl": "^5.21.1",
|
|
74
73
|
"utm-latlng": "^1.0.8"
|
|
75
74
|
}
|
|
76
75
|
}
|
package/src/map/Map.js
CHANGED
|
@@ -178,6 +178,7 @@ export default class Map {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
this.map.on("load", () => {
|
|
181
|
+
this.addAttributionControl()
|
|
181
182
|
if (!isRaster && !isRelief) {
|
|
182
183
|
const nameStyle = this.map.getStyle().name;
|
|
183
184
|
const urlName = options.style;
|
|
@@ -2846,14 +2847,43 @@ export default class Map {
|
|
|
2846
2847
|
}
|
|
2847
2848
|
}
|
|
2848
2849
|
/**
|
|
2849
|
-
* Adds an attribution control to the map
|
|
2850
|
+
* Adds an attribution control to the map. Always includes "Fet amb MapICGC" attribution by default.
|
|
2851
|
+
* If additional custom attributions are provided, they will be combined with the default one.
|
|
2850
2852
|
* @function addAttributionControl
|
|
2851
|
-
* @param {Object} options - Options for the attribution control.
|
|
2853
|
+
* @param {Object} [options] - Options for the attribution control.
|
|
2854
|
+
* @param {boolean} [options.compact=true] - If true, the attribution control will be compact.
|
|
2855
|
+
* @param {string|string[]} [options.customAttribution] - Additional custom attribution(s) to display alongside "Fet amb MapICGC".
|
|
2852
2856
|
* @param {string} [position='bottom-right'] - Position to add the control on the map.
|
|
2857
|
+
* @example
|
|
2858
|
+
* // Default usage: shows "Fet amb MapICGC" with compact mode
|
|
2859
|
+
* map.addAttributionControl();
|
|
2860
|
+
*
|
|
2861
|
+
* // With additional custom attribution
|
|
2862
|
+
* map.addAttributionControl({ customAttribution: '© El meu projecte' });
|
|
2863
|
+
*
|
|
2864
|
+
* // With multiple custom attributions
|
|
2865
|
+
* map.addAttributionControl({ customAttribution: ['© Projecte A', '© Projecte B'] });
|
|
2853
2866
|
*/
|
|
2854
2867
|
addAttributionControl(options, position) {
|
|
2855
2868
|
try {
|
|
2856
|
-
|
|
2869
|
+
const mapicgcAttribution = '<a style="font-weight: bold; color: #D97634;" href="https://www.icgc.cat/Eines-i-visors/Recursos-desenvolupadors/Biblioteca-MapICGC-GL-JS/" target="_blank">Fet amb MapICGC</a>';
|
|
2870
|
+
const mergedOptions = Object.assign({}, { compact: true }, options);
|
|
2871
|
+
|
|
2872
|
+
if (mergedOptions.customAttribution) {
|
|
2873
|
+
if (Array.isArray(mergedOptions.customAttribution)) {
|
|
2874
|
+
if (!mergedOptions.customAttribution.includes(mapicgcAttribution)) {
|
|
2875
|
+
mergedOptions.customAttribution = [mapicgcAttribution, ...mergedOptions.customAttribution];
|
|
2876
|
+
}
|
|
2877
|
+
} else {
|
|
2878
|
+
if (mergedOptions.customAttribution !== mapicgcAttribution) {
|
|
2879
|
+
mergedOptions.customAttribution = [mapicgcAttribution, mergedOptions.customAttribution];
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
} else {
|
|
2883
|
+
mergedOptions.customAttribution = mapicgcAttribution;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
this.map.addControl(new maplibregl.AttributionControl(mergedOptions), position);
|
|
2857
2887
|
} catch (error) {
|
|
2858
2888
|
console.error(`Error adding attribution control: ${error.message}`);
|
|
2859
2889
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, expect, test, vi, beforeEach } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Mock axios before importing Config
|
|
4
|
+
vi.mock('axios', () => ({
|
|
5
|
+
default: {
|
|
6
|
+
get: vi.fn(),
|
|
7
|
+
},
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
import axios from 'axios';
|
|
11
|
+
import mapicgcConfig from '../../src/mapicgc-config.json';
|
|
12
|
+
|
|
13
|
+
// Import Config after mocking axios
|
|
14
|
+
import Config from '../../src/constants/ConfigICGC.js';
|
|
15
|
+
|
|
16
|
+
describe('ConfigICGC', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
vi.clearAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('should export a Config class with getConfigICGC static method', () => {
|
|
22
|
+
expect(Config).toBeDefined();
|
|
23
|
+
expect(typeof Config.getConfigICGC).toBe('function');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should return remote config data when API responds successfully', async () => {
|
|
27
|
+
const mockRemoteConfig = {
|
|
28
|
+
Styles: { TOPO: 'https://example.com/topo.json' },
|
|
29
|
+
Layers: { WMS: {} },
|
|
30
|
+
Terrains: {},
|
|
31
|
+
defaultOptions: { mapOptions: {} },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
axios.get.mockResolvedValueOnce({ data: mockRemoteConfig });
|
|
35
|
+
|
|
36
|
+
const result = await Config.getConfigICGC();
|
|
37
|
+
|
|
38
|
+
expect(axios.get).toHaveBeenCalledTimes(1);
|
|
39
|
+
expect(axios.get).toHaveBeenCalledWith(
|
|
40
|
+
'https://eines.icgc.cat/recursos/mapicgc-gl-js/mapicgc-config.json',
|
|
41
|
+
{ timeout: 5000 }
|
|
42
|
+
);
|
|
43
|
+
expect(result).toEqual(mockRemoteConfig);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('should return local mapicgc-config.json when API returns empty data', async () => {
|
|
47
|
+
axios.get.mockResolvedValueOnce({ data: null });
|
|
48
|
+
|
|
49
|
+
const result = await Config.getConfigICGC();
|
|
50
|
+
|
|
51
|
+
expect(result).toEqual(mapicgcConfig);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('should return local mapicgc-config.json when API call fails with network error', async () => {
|
|
55
|
+
axios.get.mockRejectedValueOnce(new Error('Network Error'));
|
|
56
|
+
|
|
57
|
+
const result = await Config.getConfigICGC();
|
|
58
|
+
|
|
59
|
+
expect(result).toEqual(mapicgcConfig);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('should return local mapicgc-config.json when API returns HTTP error', async () => {
|
|
63
|
+
const httpError = new Error('Request failed');
|
|
64
|
+
httpError.response = { data: 'Not Found', status: 404 };
|
|
65
|
+
axios.get.mockRejectedValueOnce(httpError);
|
|
66
|
+
|
|
67
|
+
const result = await Config.getConfigICGC();
|
|
68
|
+
|
|
69
|
+
expect(result).toEqual(mapicgcConfig);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('should return local mapicgc-config.json when server does not respond (timeout)', async () => {
|
|
73
|
+
const timeoutError = new Error('Timeout');
|
|
74
|
+
timeoutError.request = {};
|
|
75
|
+
axios.get.mockRejectedValueOnce(timeoutError);
|
|
76
|
+
|
|
77
|
+
const result = await Config.getConfigICGC();
|
|
78
|
+
|
|
79
|
+
expect(result).toEqual(mapicgcConfig);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('mapicgc-config.json structure', () => {
|
|
84
|
+
test('should have defaultOptions with mapOptions', () => {
|
|
85
|
+
expect(mapicgcConfig.defaultOptions).toBeDefined();
|
|
86
|
+
expect(mapicgcConfig.defaultOptions.mapOptions).toBeDefined();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should have mapOptions with required fields', () => {
|
|
90
|
+
const mapOpts = mapicgcConfig.defaultOptions.mapOptions;
|
|
91
|
+
expect(mapOpts.container).toBeDefined();
|
|
92
|
+
expect(mapOpts.center).toBeDefined();
|
|
93
|
+
expect(mapOpts.zoom).toBeDefined();
|
|
94
|
+
expect(mapOpts.style).toBeDefined();
|
|
95
|
+
expect(mapOpts.maxZoom).toBeDefined();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('should have center coordinates for Catalonia', () => {
|
|
99
|
+
const center = mapicgcConfig.defaultOptions.mapOptions.center;
|
|
100
|
+
// Catalonia approx: lon 0.15-3.33, lat 40.5-42.9
|
|
101
|
+
const lon = center['0'] || center[0];
|
|
102
|
+
const lat = center['1'] || center[1];
|
|
103
|
+
expect(lon).toBeGreaterThan(0);
|
|
104
|
+
expect(lon).toBeLessThan(4);
|
|
105
|
+
expect(lat).toBeGreaterThan(40);
|
|
106
|
+
expect(lat).toBeLessThan(43);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('should have Styles configuration', () => {
|
|
110
|
+
expect(mapicgcConfig.Styles).toBeDefined();
|
|
111
|
+
expect(Array.isArray(mapicgcConfig.Styles) || typeof mapicgcConfig.Styles === 'object').toBe(true);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should have Layers configuration with WMS, Orto, Vector', () => {
|
|
115
|
+
expect(mapicgcConfig.Layers).toBeDefined();
|
|
116
|
+
expect(mapicgcConfig.Layers.WMS).toBeDefined();
|
|
117
|
+
expect(mapicgcConfig.Layers.Orto).toBeDefined();
|
|
118
|
+
expect(mapicgcConfig.Layers.Vector).toBeDefined();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('should have Terrains configuration', () => {
|
|
122
|
+
expect(mapicgcConfig.Terrains).toBeDefined();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('should have geocoder config with pelias URLs', () => {
|
|
126
|
+
const geocoder = mapicgcConfig.defaultOptions.geocoder;
|
|
127
|
+
expect(geocoder).toBeDefined();
|
|
128
|
+
expect(geocoder.peliasUrl1).toBeDefined();
|
|
129
|
+
expect(geocoder.peliasUrl1).toContain('icgc.cat');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('should have logo ICGC options', () => {
|
|
133
|
+
const logo = mapicgcConfig.defaultOptions.logoIcgcOptions;
|
|
134
|
+
expect(logo).toBeDefined();
|
|
135
|
+
expect(logo.logoUrlColor).toBeDefined();
|
|
136
|
+
expect(logo.logoLink).toContain('icgc.cat');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should have map3d options', () => {
|
|
140
|
+
const opts3d = mapicgcConfig.defaultOptions.map3dOptions;
|
|
141
|
+
expect(opts3d).toBeDefined();
|
|
142
|
+
expect(opts3d.exaggeration).toBeDefined();
|
|
143
|
+
expect(opts3d.terrainSource).toBeDefined();
|
|
144
|
+
});
|
|
145
|
+
});
|