markers - export as geoJSON

This commit is contained in:
Azgaar 2021-09-27 22:47:37 +03:00
parent 03b5e1d84c
commit 972850e7ad
5 changed files with 122 additions and 46 deletions

View file

@ -450,25 +450,21 @@ function saveGeoJSON_Rivers() {
} }
function saveGeoJSON_Markers() { function saveGeoJSON_Markers() {
// TODO: rework for new markers
track("export", "getJSON markers"); track("export", "getJSON markers");
const json = {type: "FeatureCollection", features: []};
markers.selectAll("use").each(function () { const features = pack.markers.map(marker => {
const coordinates = getQGIScoordinates(this.dataset.x, this.dataset.y); const {i, type, icon, x, y, size, fill, stroke, size} = marker;
const id = this.id; const coordinates = getQGIScoordinates(x, y);
const type = this.dataset.id.substring(1); const id = `marker${i}`;
const icon = document.getElementById(type).textContent; const note = notes.find(note => note.id === id);
const note = notes.length ? notes.find(note => note.id === this.id) : null; const properties = {id, type, icon, ...note, size, fill, stroke, size};
const name = note ? note.name : ""; return {type: "Feature", geometry: {type: "Point", coordinates}, properties};
const legend = note ? note.legend : "";
const feature = {type: "Feature", geometry: {type: "Point", coordinates}, properties: {id, type, icon, name, legend}};
json.features.push(feature);
}); });
const name = getFileName("Markers") + ".geojson"; const json = {type: "FeatureCollection", features};
downloadFile(JSON.stringify(json), name, "application/json");
const fileName = getFileName("Markers") + ".geojson";
downloadFile(JSON.stringify(json), fileName, "application/json");
} }
function getCellCoordinates(vertices) { function getCellCoordinates(vertices) {

View file

@ -344,6 +344,7 @@ function parseLoadedData(data) {
pack.religions = data[29] ? JSON.parse(data[29]) : [{i: 0, name: "No religion"}]; pack.religions = data[29] ? JSON.parse(data[29]) : [{i: 0, name: "No religion"}];
pack.provinces = data[30] ? JSON.parse(data[30]) : [0]; pack.provinces = data[30] ? JSON.parse(data[30]) : [0];
pack.rivers = data[32] ? JSON.parse(data[32]) : []; pack.rivers = data[32] ? JSON.parse(data[32]) : [];
pack.markers = data[35] ? JSON.parse(data[35]) : [];
const cells = pack.cells; const cells = pack.cells;
cells.biome = Uint8Array.from(data[16].split(",")); cells.biome = Uint8Array.from(data[16].split(","));

View file

@ -1,5 +1,5 @@
"use strict"; "use strict";
// Functions to save project as .map file // functions to save project as .map file
// prepare map data for saving // prepare map data for saving
function getMapData() { function getMapData() {
@ -9,7 +9,32 @@ function getMapData() {
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator"; const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
const params = [version, license, dateString, seed, graphWidth, graphHeight, mapId].join("|"); const params = [version, license, dateString, seed, graphWidth, graphHeight, mapId].join("|");
const settings = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value, barSizeInput.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate, urbanization, mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(options), mapName.value, +hideLabels.checked, stylePreset.value, +rescaleLabels.checked].join("|"); const settings = [
distanceUnitInput.value,
distanceScaleInput.value,
areaUnit.value,
heightUnit.value,
heightExponentInput.value,
temperatureScale.value,
barSizeInput.value,
barLabel.value,
barBackOpacity.value,
barBackColor.value,
barPosX.value,
barPosY.value,
populationRate,
urbanization,
mapSizeOutput.value,
latitudeOutput.value,
temperatureEquatorOutput.value,
temperaturePoleOutput.value,
precOutput.value,
JSON.stringify(options),
mapName.value,
+hideLabels.checked,
stylePreset.value,
+rescaleLabels.checked
].join("|");
const coords = JSON.stringify(mapCoordinates); const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|"); const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
const notesData = JSON.stringify(notes); const notesData = JSON.stringify(notes);
@ -37,6 +62,7 @@ function getMapData() {
const religions = JSON.stringify(pack.religions); const religions = JSON.stringify(pack.religions);
const provinces = JSON.stringify(pack.provinces); const provinces = JSON.stringify(pack.provinces);
const rivers = JSON.stringify(pack.rivers); const rivers = JSON.stringify(pack.rivers);
const markers = JSON.stringify(pack.markers);
// store name array only if not the same as default // store name array only if not the same as default
const defaultNB = Names.getNameBases(); const defaultNB = Names.getNameBases();
@ -51,7 +77,44 @@ function getMapData() {
const pop = Array.from(pack.cells.pop).map(p => rn(p, 4)); const pop = Array.from(pack.cells.pop).map(p => rn(p, 4));
// data format as below // data format as below
const mapData = [params, settings, coords, biomes, notesData, serializedSVG, gridGeneral, grid.cells.h, grid.cells.prec, grid.cells.f, grid.cells.t, grid.cells.temp, packFeatures, cultures, states, burgs, pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl, pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state, pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces, namesData, rivers, rulersString, fonts].join("\r\n"); const mapData = [
params,
settings,
coords,
biomes,
notesData,
serializedSVG,
gridGeneral,
grid.cells.h,
grid.cells.prec,
grid.cells.f,
grid.cells.t,
grid.cells.temp,
packFeatures,
cultures,
states,
burgs,
pack.cells.biome,
pack.cells.burg,
pack.cells.conf,
pack.cells.culture,
pack.cells.fl,
pop,
pack.cells.r,
pack.cells.road,
pack.cells.s,
pack.cells.state,
pack.cells.religion,
pack.cells.province,
pack.cells.crossroad,
religions,
provinces,
namesData,
rivers,
rulersString,
fonts,
markers
].join("\r\n");
TIME && console.timeEnd("createMapData"); TIME && console.timeEnd("createMapData");
return mapData; return mapData;
} }
@ -97,7 +160,16 @@ function quickSave() {
const saveReminder = function () { const saveReminder = function () {
if (localStorage.getItem("noReminder")) return; if (localStorage.getItem("noReminder")) return;
const message = ["Please don't forget to save your work as a .map file", "Please remember to save work as a .map file", "Saving in .map format will ensure your data won't be lost in case of issues", "Safety is number one priority. Please save the map", "Don't forget to save your map on a regular basis!", "Just a gentle reminder for you to save the map", "Please don't forget to save your progress (saving as .map is the best option)", "Don't want to be reminded about need to save? Press CTRL+Q"]; const message = [
"Please don't forget to save your work as a .map file",
"Please remember to save work as a .map file",
"Saving in .map format will ensure your data won't be lost in case of issues",
"Safety is number one priority. Please save the map",
"Don't forget to save your map on a regular basis!",
"Just a gentle reminder for you to save the map",
"Please don't forget to save your progress (saving as .map is the best option)",
"Don't want to be reminded about need to save? Press CTRL+Q"
];
const interval = 15 * 60 * 1000; // remind every 15 minutes const interval = 15 * 60 * 1000; // remind every 15 minutes
saveReminder.reminder = setInterval(() => { saveReminder.reminder = setInterval(() => {

View file

@ -677,7 +677,22 @@ class Battle {
if (note) { if (note) {
const status = side === "attackers" ? battleStatus[0] : battleStatus[1]; const status = side === "attackers" ? battleStatus[0] : battleStatus[1];
const losses = r.a ? Math.abs(d3.sum(Object.values(r.casualties))) / r.a : 1; const losses = r.a ? Math.abs(d3.sum(Object.values(r.casualties))) / r.a : 1;
const regStatus = losses === 1 ? "is destroyed" : losses > 0.8 ? "is almost completely destroyed" : losses > 0.5 ? "suffered terrible losses" : losses > 0.3 ? "suffered severe losses" : losses > 0.2 ? "suffered heavy losses" : losses > 0.05 ? "suffered significant losses" : losses > 0 ? "suffered unsignificant losses" : "left the battle without loss"; const regStatus =
losses === 1
? "is destroyed"
: losses > 0.8
? "is almost completely destroyed"
: losses > 0.5
? "suffered terrible losses"
: losses > 0.3
? "suffered severe losses"
: losses > 0.2
? "suffered heavy losses"
: losses > 0.05
? "suffered significant losses"
: losses > 0
? "suffered unsignificant losses"
: "left the battle without loss";
const casualties = Object.keys(r.casualties) const casualties = Object.keys(r.casualties)
.map(t => (r.casualties[t] ? `${Math.abs(r.casualties[t])} ${t}` : null)) .map(t => (r.casualties[t] ? `${Math.abs(r.casualties[t])} ${t}` : null))
.filter(c => c); .filter(c => c);
@ -691,41 +706,32 @@ class Battle {
armies.select(`g#${id} > text`).text(Military.getTotal(r)); // update reg box armies.select(`g#${id} > text`).text(Military.getTotal(r)); // update reg box
} }
// TODO: add updated marker const i = last(pack.markers)?.i + 1 || 0;
// append battlefield marker {
void (function addMarkerSymbol() { // append battlefield marker
if (svg.select("#defs-markers").select("#marker_battlefield").size()) return; const marker = {i, x: this.x, y: this.y, cell: this.cell, icon: "⚔️", type: "battlefields", dy: 52};
const symbol = svg.select("#defs-markers").append("symbol").attr("id", "marker_battlefield").attr("viewBox", "0 0 30 30"); pack.markers.push(marker);
symbol.append("path").attr("d", "M6,19 l9,10 L24,19").attr("fill", "#000000").attr("stroke", "none"); const markerHTML = drawMarker(marker);
symbol.append("circle").attr("cx", 15).attr("cy", 15).attr("r", 10).attr("fill", "#ffffff").attr("stroke", "#000000").attr("stroke-width", 1); document.getElementById("markers").insertAdjacentHTML("beforeend", markerHTML);
symbol.append("text").attr("x", "50%").attr("y", "52%").attr("fill", "#000000").attr("stroke", "#3200ff").attr("stroke-width", 0).attr("font-size", "12px").attr("dominant-baseline", "central").text("⚔️"); }
})();
const getSide = (regs, n) => (regs.length > 1 ? `${n ? "regiments" : "forces"} of ${list([...new Set(regs.map(r => pack.states[r.state].name))])}` : getAdjective(pack.states[regs[0].state].name) + " " + regs[0].name); const getSide = (regs, n) =>
regs.length > 1
? `${n ? "regiments" : "forces"} of ${list([...new Set(regs.map(r => pack.states[r.state].name))])}`
: getAdjective(pack.states[regs[0].state].name) + " " + regs[0].name;
const getLosses = casualties => Math.min(rn(casualties * 100), 100); const getLosses = casualties => Math.min(rn(casualties * 100), 100);
const status = battleStatus[+P(0.7)]; const status = battleStatus[+P(0.7)];
const result = `The ${this.getTypeName(this.type)} ended in ${status}`; const result = `The ${this.getTypeName(this.type)} ended in ${status}`;
const legend = `${this.name} took place in ${options.year} ${options.eraShort}. It was fought between ${getSide(this.attackers.regiments, 1)} and ${getSide(this.defenders.regiments, 0)}. ${result}. const legend = `${this.name} took place in ${options.year} ${options.eraShort}. It was fought between ${getSide(this.attackers.regiments, 1)} and ${getSide(
this.defenders.regiments,
0
)}. ${result}.
\r\nAttackers losses: ${getLosses(this.attackers.casualties)}%, defenders losses: ${getLosses(this.defenders.casualties)}%`; \r\nAttackers losses: ${getLosses(this.attackers.casualties)}%, defenders losses: ${getLosses(this.defenders.casualties)}%`;
const id = getNextId("marker"); notes.push({id: `marker${i}`, name: this.name, legend});
notes.push({id, name: this.name, legend});
tip(`${this.name} is over. ${result}`, true, "success", 4000); tip(`${this.name} is over. ${result}`, true, "success", 4000);
markers
.append("use")
.attr("id", id)
.attr("xlink:href", "#marker_battlefield")
.attr("data-id", "#marker_battlefield")
.attr("data-x", this.x)
.attr("data-y", this.y)
.attr("x", this.x - 15)
.attr("y", this.y - 30)
.attr("data-size", 1)
.attr("width", 30)
.attr("height", 30);
$("#battleScreen").dialog("destroy"); $("#battleScreen").dialog("destroy");
this.cleanData(); this.cleanData();
} }

View file

@ -36,6 +36,7 @@ function overviewMarkers() {
if (el.classList.contains("icon-pencil")) return openEditor(i); if (el.classList.contains("icon-pencil")) return openEditor(i);
if (el.classList.contains("locks")) return toggleLockStatus(el, i); if (el.classList.contains("locks")) return toggleLockStatus(el, i);
if (el.classList.contains("icon-trash-empty")) return triggerRemove(i); if (el.classList.contains("icon-trash-empty")) return triggerRemove(i);
// TODO: hidden attribute
} }
function addLines() { function addLines() {