proj4js/scripts/updateDatums.mjs
2025-05-10 12:46:44 +02:00

120 lines
3.6 KiB
JavaScript

import sqlite3 from 'sqlite3';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import datums from '../lib/constants/Datum.js'; // Import the datums object directly
const DATUM_OVERRIDES = {
EPSG_4149: {
towgs84: '674.374,15.056,405.346'
},
EPSG_4267: {
towgs84: '-8.0,160.0,176.0'
},
EPSG_4818: {
towgs84: '589,76,480'
}
};
// Get the current file's directory
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Open proj.db
const dbPath = path.resolve(__dirname, '../proj.db');
const db = new sqlite3.Database(dbPath);
for (const key in datums) {
if (key === datums[key].datumName && datums[datums[key].datumName] === datums[key]) {
delete datums[key];
}
}
const databaseDatumNames = new Set();
// Query proj.db for Helmert transforms with method_code = 9606
db.all(
`SELECT ht.source_crs_auth_name,
ht.source_crs_code,
ht.tx, ht.ty, ht.tz,
ht.rx, ht.ry, ht.rz,
ht.scale_difference,
ht.accuracy,
gd.name AS datum_name,
cv.name AS datum_code,
e.name AS ellipse_name,
ht.method_code
FROM helmert_transformation ht
JOIN crs_view cv
ON ht.source_crs_auth_name = cv.auth_name
AND ht.source_crs_code = cv.code
JOIN geodetic_crs gcrs
ON cv.table_name = 'geodetic_crs'
AND cv.auth_name = gcrs.auth_name
AND cv.code = gcrs.code
JOIN geodetic_datum gd
ON gcrs.datum_auth_name = gd.auth_name
AND gcrs.datum_code = gd.code
JOIN ellipsoid e
ON gd.ellipsoid_auth_name = e.auth_name
AND gd.ellipsoid_code = e.code
WHERE ht.deprecated = 0
AND ht.method_code IN (9606, 9607, 9603)
AND (ht.target_crs_auth_name = 'EPSG' AND ht.target_crs_code IN ('4326', '7019', '4258')) -- WGS84, GRS80, ETRS89
AND cv.type != 'vertical' -- Exclude vertical datums
ORDER BY
ht.accuracy ASC,
CASE ht.method_code
WHEN 9606 THEN 1
WHEN 9607 THEN 2
WHEN 9603 THEN 3
ELSE 4
END ASC`, // Sort by method_code (9606 first, then 9607), then by accuracy`, // Assuming lower accuracy values are better
(err, rows) => {
if (err) {
console.error('Error querying proj.db:', err);
return;
}
rows.forEach((row) => {
const normalizedDatumName = row.datum_name.toLowerCase();
// Skip if the datumName already exists (case-insensitive)
if (databaseDatumNames.has(normalizedDatumName)) {
return;
}
if (row.method_code === 9607 && row.rx) {
row.rx = -row.rx;
row.ry = -row.ry;
row.rz = -row.rz;
}
// Construct the towgs84 string from tx, ty, tz, rx, ry, rz, and scale_difference
const towgs84 = row.rx ? `${row.tx},${row.ty},${row.tz},${row.rx},${row.ry},${row.rz},${row.scale_difference}` : `${row.tx},${row.ty},${row.tz}`;
datums[`${row.source_crs_auth_name}_${row.source_crs_code}`] = {
towgs84
};
databaseDatumNames.add(normalizedDatumName);
});
Object.assign(datums, DATUM_OVERRIDES);
// Write updated datums back to Datum.js
const datumFilePath = path.resolve(__dirname, '../lib/constants/Datum.js');
const updatedContent = `var datums = ${JSON.stringify(datums, null, 2)};\n\n`
+ `for (var key in datums) {\n`
+ ` var datum = datums[key];\n`
+ ` if (!datum.datumName) {\n`
+ ` continue;\n`
+ ` }\n`
+ ` datums[datum.datumName] = datum;\n`
+ `}\n\n`
+ `export default datums;`;
fs.writeFileSync(datumFilePath, updatedContent, 'utf-8');
console.log('Datum.js updated successfully!');
}
);