mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
markers - export as geoJSON
This commit is contained in:
parent
03b5e1d84c
commit
972850e7ad
5 changed files with 122 additions and 46 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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(","));
|
||||||
|
|
|
||||||
|
|
@ -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(() => {
|
||||||
|
|
|
||||||
|
|
@ -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
|
// append battlefield marker
|
||||||
void (function addMarkerSymbol() {
|
const marker = {i, x: this.x, y: this.y, cell: this.cell, icon: "⚔️", type: "battlefields", dy: 52};
|
||||||
if (svg.select("#defs-markers").select("#marker_battlefield").size()) return;
|
pack.markers.push(marker);
|
||||||
const symbol = svg.select("#defs-markers").append("symbol").attr("id", "marker_battlefield").attr("viewBox", "0 0 30 30");
|
const markerHTML = drawMarker(marker);
|
||||||
symbol.append("path").attr("d", "M6,19 l9,10 L24,19").attr("fill", "#000000").attr("stroke", "none");
|
document.getElementById("markers").insertAdjacentHTML("beforeend", markerHTML);
|
||||||
symbol.append("circle").attr("cx", 15).attr("cy", 15).attr("r", 10).attr("fill", "#ffffff").attr("stroke", "#000000").attr("stroke-width", 1);
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue