• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 17398457915

02 Sep 2025 08:55AM UTC coverage: 76.739% (-0.01%) from 76.752%
17398457915

Pull #11424

github

web-flow
Merge 78504bea5 into 0b58fee13
Pull Request #11424: Proj4 upgrade and include support for "Grid Based Datum Adjustments" #11423

31401 of 48925 branches covered (64.18%)

12 of 27 new or added lines in 2 files covered. (44.44%)

1 existing line in 1 file now uncovered.

38921 of 50719 relevant lines covered (76.74%)

36.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.62
/web/client/utils/ProjectionUtils.js
1
/*
2
 * Copyright 2023, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
*/
8

9
import Proj4js from 'proj4';
10
import { getConfigProp } from './ConfigUtils';
11
import axios from '../libs/ajax';
12

13
const proj4 = Proj4js;
1✔
14

15
const DEFAULT_PROJECTIONS = {
1✔
16
    'EPSG:3857': {
17
        def: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs',
18
        extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34],
19
        worldExtent: [-180.0, -85.06, 180.0, 85.06]
20
    },
21
    'EPSG:4326': {
22
        def: '+proj=longlat +datum=WGS84 +no_defs +type=crs',
23
        extent: [-180.0, -90.0, 180.0, 90.0],
24
        worldExtent: [-180.0, -90.0, 180.0, 90.0]
25
    }
26
};
27

28
/**
29
 * Registers grid files for coordinate transformations
30
 * @param {object} gridFiles - Object containing grid file definitions
31
 * @param {object} proj4Instance - Proj4 instance
32
 * @return {Promise} Promise that resolves when all grids are registered
33
 */
34
export const registerGridFiles = (gridFiles, proj4Instance) => {
1✔
35
    const gridPromises = Object.entries(gridFiles).map(([gridName, gridInfo]) => {
1✔
36
        return new Promise((resolve) => {
1✔
37
            if (gridInfo.type === 'gsb') {
1!
38
                // GSB files: Load as ArrayBuffer and register directly
39
                axios.get(gridInfo.path, { responseType: 'arraybuffer' })
1✔
40
                    .then(response => {
41
                        proj4Instance.nadgrid(gridName, response.data, {includeErrorFields: false});
1✔
42
                        resolve();
1✔
43
                    })
44
                    .catch(error => {
45
                        // eslint-disable-next-line no-console
NEW
46
                        console.error(`Failed to register grid ${gridName}:`, error);
×
NEW
47
                        resolve(); // Continue with other grids even if one fails
×
48
                    });
49

NEW
50
            } else if (gridInfo.type === 'geotiff') {
×
51
                // GeoTIFF files: Use GeoTIFF.js library
NEW
52
                import('geotiff').then(({ fromUrl }) => {
×
NEW
53
                    return fromUrl(gridInfo.path);
×
54
                }).then(tiff => {
NEW
55
                    return proj4Instance.nadgrid(gridName, tiff).ready;
×
56
                }).then(() => {
57
                    // eslint-disable-next-line no-console
NEW
58
                    console.log("Successfully registered");
×
NEW
59
                    resolve();
×
60
                }).catch(error => {
61
                    // eslint-disable-next-line no-console
NEW
62
                    console.error(`Failed to register grid ${gridName}:`, error);
×
NEW
63
                    resolve(); // Continue with other grids even if one fails
×
64
                });
65
            } else {
66
                // eslint-disable-next-line no-console
NEW
67
                console.warn(`Unknown grid type for ${gridName}: ${gridInfo.type}`);
×
NEW
68
                resolve(); // Unknown grid type, skip
×
69
            }
70
        });
71
    });
72

73
    return Promise.all(gridPromises);
1✔
74
};
75

76
/**
77
 * Returns an object of projections where the key represents the code
78
 * @return {object} projection definitions
79
 */
80
export const getProjections = () => {
1✔
81
    return (getConfigProp('projectionDefs') || [])
383✔
82
        .reduce((acc, { code, ...options }) => ({
2✔
83
            ...acc,
84
            [code]: {
85
                ...options,
86
                proj4Def: { ...proj4.defs(code) }
87
            }
88
        }),
89
        { ...DEFAULT_PROJECTIONS });
90
};
91

92
/**
93
 * Return a projection given a code
94
 * @param {string} code for the projection, default 'EPSG:3857'
95
 * @return {object} projection definition, fallback to default 'EPSG:3857' definition
96
 */
97
export const getProjection = (code = 'EPSG:3857') => {
1!
98
    const projections = getProjections();
361✔
99
    return projections[code] || projections['EPSG:3857'];
361✔
100
};
101

102
/**
103
 * Check if a projection is available
104
 * @param {string} code for the projection
105
 * @return {boolean} true if the projection is available
106
 */
107
export const isProjectionAvailable = (code) => !!getProjections()[code];
20✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc