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

geosolutions-it / MapStore2 / 17429371957

03 Sep 2025 09:35AM UTC coverage: 76.742% (-0.01%) from 76.752%
17429371957

Pull #11424

github

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

31404 of 48925 branches covered (64.19%)

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

2 existing lines in 2 files now uncovered.

38923 of 50719 relevant lines covered (76.74%)

37.12 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 => {
NEW
45
                        console.error(`Failed to register grid ${gridName}:`, error);
×
NEW
46
                        resolve(); // Continue with other grids even if one fails
×
47
                    });
48

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

70
    return Promise.all(gridPromises);
1✔
71
};
72

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

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

99
/**
100
 * Check if a projection is available
101
 * @param {string} code for the projection
102
 * @return {boolean} true if the projection is available
103
 */
104
export const isProjectionAvailable = (code) => !!getProjections()[code];
19✔
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