mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
Add world coordinates to regiment exports for GIS integration
Regiment CSV Export Enhancements: - Add X_World (m) and Y_World (m) columns using meters per pixel conversion - Include both current and base position world coordinates - Rename existing coordinate columns to X_Pixel/Y_Pixel for clarity - Add getMetersPerPixel() helper function supporting km, m, and miles units GeoJSON Regiment Export: - Create new saveGeoJsonRegiments() function in export.js - Export regiments as Point features with Fantasy Map Cartesian coordinates - Include all military unit data, state information, and position metadata - Add regiments button to GeoJSON export UI section This enables direct import of regiment data into QGIS using the custom Fantasy Map Cartesian CRS with proper world coordinate positioning.
This commit is contained in:
parent
83573c8936
commit
11977a42fc
3 changed files with 114 additions and 1 deletions
|
|
@ -814,4 +814,78 @@ function saveGeoJsonBurgs() {
|
|||
|
||||
const fileName = getFileName("Burgs") + ".geojson";
|
||||
downloadFile(JSON.stringify(json), fileName, "application/json");
|
||||
}
|
||||
|
||||
function saveGeoJsonRegiments() {
|
||||
const metersPerPixel = getMetersPerPixel();
|
||||
const allRegiments = [];
|
||||
|
||||
// Collect all regiments from all states
|
||||
for (const s of pack.states) {
|
||||
if (!s.i || s.removed || !s.military.length) continue;
|
||||
for (const r of s.military) {
|
||||
allRegiments.push({regiment: r, state: s});
|
||||
}
|
||||
}
|
||||
|
||||
const features = allRegiments.map(({regiment: r, state: s}) => {
|
||||
const coordinates = getFantasyCoordinates(r.x, r.y, 2);
|
||||
const baseCoordinates = getFantasyCoordinates(r.bx, r.by, 2);
|
||||
|
||||
// Calculate world coordinates same as CSV export
|
||||
const xWorld = r.x * metersPerPixel;
|
||||
const yWorld = -r.y * metersPerPixel;
|
||||
const bxWorld = r.bx * metersPerPixel;
|
||||
const byWorld = -r.by * metersPerPixel;
|
||||
|
||||
// Collect military unit data
|
||||
const units = {};
|
||||
options.military.forEach(u => {
|
||||
units[u.name] = r.u[u.name] || 0;
|
||||
});
|
||||
|
||||
return {
|
||||
type: "Feature",
|
||||
geometry: {type: "Point", coordinates},
|
||||
properties: {
|
||||
id: r.i,
|
||||
name: r.name,
|
||||
icon: r.icon,
|
||||
state: s.name,
|
||||
stateFull: s.fullName,
|
||||
stateId: s.i,
|
||||
units: units,
|
||||
totalUnits: r.a,
|
||||
xWorld: rn(xWorld, 2),
|
||||
yWorld: rn(yWorld, 2),
|
||||
xPixel: r.x,
|
||||
yPixel: r.y,
|
||||
baseXWorld: rn(bxWorld, 2),
|
||||
baseYWorld: rn(byWorld, 2),
|
||||
baseXPixel: r.bx,
|
||||
baseYPixel: r.by,
|
||||
baseCoordinates: baseCoordinates
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const json = {
|
||||
type: "FeatureCollection",
|
||||
features,
|
||||
metadata: {
|
||||
crs: "Fantasy Map Cartesian (meters)",
|
||||
mapName: mapName.value,
|
||||
scale: {
|
||||
distance: distanceScale,
|
||||
unit: distanceUnitInput.value,
|
||||
meters_per_pixel: metersPerPixel
|
||||
},
|
||||
military: {
|
||||
unitTypes: options.military.map(u => u.name)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const fileName = getFileName("Regiments") + ".geojson";
|
||||
downloadFile(JSON.stringify(json), fileName, "application/json");
|
||||
}
|
||||
|
|
@ -193,12 +193,36 @@ function overviewRegiments(state) {
|
|||
toggleAdd();
|
||||
}
|
||||
|
||||
// Helper function to get meters per pixel for world coordinates
|
||||
function getMetersPerPixel() {
|
||||
const unit = distanceUnitInput.value.toLowerCase();
|
||||
|
||||
switch(unit) {
|
||||
case 'km':
|
||||
return distanceScale * 1000;
|
||||
case 'm':
|
||||
case 'meter':
|
||||
case 'meters':
|
||||
return distanceScale;
|
||||
case 'mi':
|
||||
case 'mile':
|
||||
case 'miles':
|
||||
return distanceScale * 1609.34;
|
||||
default:
|
||||
console.warn(`Unknown distance unit: ${unit}, defaulting to km`);
|
||||
return distanceScale * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
function downloadRegimentsData() {
|
||||
// Calculate meters per pixel for world coordinates
|
||||
const metersPerPixel = getMetersPerPixel();
|
||||
|
||||
const units = options.military.map(u => u.name);
|
||||
let data =
|
||||
"State,Id,Icon,Name," +
|
||||
units.map(u => capitalize(u)).join(",") +
|
||||
",X,Y,Latitude,Longitude,Base X,Base Y,Base Latitude,Base Longitude\n"; // headers
|
||||
",X_World (m),Y_World (m),X_Pixel,Y_Pixel,Latitude,Longitude,Base X_World (m),Base Y_World (m),Base X_Pixel,Base Y_Pixel,Base Latitude,Base Longitude\n"; // headers
|
||||
|
||||
for (const s of pack.states) {
|
||||
if (!s.i || s.removed || !s.military.length) continue;
|
||||
|
|
@ -210,11 +234,25 @@ function overviewRegiments(state) {
|
|||
data += r.name + ",";
|
||||
data += units.map(unit => r.u[unit]).join(",") + ",";
|
||||
|
||||
// Add world coordinates in meters
|
||||
const xWorld = r.x * metersPerPixel;
|
||||
const yWorld = -r.y * metersPerPixel; // Negative because Y increases downward
|
||||
data += rn(xWorld, 2) + ",";
|
||||
data += rn(yWorld, 2) + ",";
|
||||
|
||||
// Add pixel coordinates (renamed for clarity)
|
||||
data += r.x + ",";
|
||||
data += r.y + ",";
|
||||
data += getLatitude(r.y, 2) + ",";
|
||||
data += getLongitude(r.x, 2) + ",";
|
||||
|
||||
// Add base world coordinates in meters
|
||||
const bxWorld = r.bx * metersPerPixel;
|
||||
const byWorld = -r.by * metersPerPixel; // Negative because Y increases downward
|
||||
data += rn(bxWorld, 2) + ",";
|
||||
data += rn(byWorld, 2) + ",";
|
||||
|
||||
// Add base pixel coordinates (renamed for clarity)
|
||||
data += r.bx + ",";
|
||||
data += r.by + ",";
|
||||
data += getLatitude(r.by, 2) + ",";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue