diff --git a/index.html b/index.html index fff89677..e16d5d0f 100644 --- a/index.html +++ b/index.html @@ -6052,6 +6052,7 @@ +

GeoJSON format is used in GIS tools such as QGIS. Check out diff --git a/modules/io/export.js b/modules/io/export.js index 5cc06069..604a9091 100644 --- a/modules/io/export.js +++ b/modules/io/export.js @@ -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"); } \ No newline at end of file diff --git a/modules/ui/regiments-overview.js b/modules/ui/regiments-overview.js index 63f7d1c9..384c3184 100644 --- a/modules/ui/regiments-overview.js +++ b/modules/ui/regiments-overview.js @@ -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) + ",";