mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
import {rn} from "/src/utils/numberUtils";
|
|
import {round} from "/src/utils/stringUtils";
|
|
import {byId} from "/src/utils/shorthands";
|
|
|
|
export function drawCoordinates() {
|
|
coordinates.selectAll("*").remove(); // remove every time
|
|
const steps = [0.5, 1, 2, 5, 10, 15, 30]; // possible steps
|
|
const goal = mapCoordinates.lonT / scale / 10;
|
|
const step = steps.reduce((p, c) => (Math.abs(c - goal) < Math.abs(p - goal) ? c : p));
|
|
|
|
const desired = +coordinates.attr("data-size"); // desired label size
|
|
coordinates.attr("font-size", Math.max(rn(desired / scale ** 0.8, 2), 0.1)); // actual label size
|
|
const graticule = d3
|
|
.geoGraticule()
|
|
.extent([
|
|
[mapCoordinates.lonW, mapCoordinates.latN],
|
|
[mapCoordinates.lonE + 0.1, mapCoordinates.latS + 0.1]
|
|
])
|
|
.stepMajor([400, 400])
|
|
.stepMinor([step, step]);
|
|
const projection = d3.geoEquirectangular().fitSize([graphWidth, graphHeight], graticule());
|
|
|
|
const grid = coordinates.append("g").attr("id", "coordinateGrid");
|
|
const labels = coordinates.append("g").attr("id", "coordinateLabels");
|
|
|
|
const p = getViewPoint(scale + desired + 2, scale + desired / 2); // on border point on viexBox
|
|
const data = graticule.lines().map(d => {
|
|
const lat = d.coordinates[0][1] === d.coordinates[1][1]; // check if line is latitude or longitude
|
|
const c = d.coordinates[0];
|
|
const pos = projection(c); // map coordinates
|
|
const [x, y] = lat ? [rn(p.x, 2), rn(pos[1], 2)] : [rn(pos[0], 2), rn(p.y, 2)]; // labels position
|
|
const v = lat ? c[1] : c[0]; // label
|
|
|
|
const text = !v
|
|
? v
|
|
: Number.isInteger(v)
|
|
? lat
|
|
? c[1] < 0
|
|
? -c[1] + "°S"
|
|
: c[1] + "°N"
|
|
: c[0] < 0
|
|
? -c[0] + "°W"
|
|
: c[0] + "°E"
|
|
: "";
|
|
|
|
return {lat, x, y, text};
|
|
});
|
|
|
|
const d = round(d3.geoPath(projection)(graticule()));
|
|
grid.append("path").attr("d", d).attr("vector-effect", "non-scaling-stroke");
|
|
labels
|
|
.selectAll("text")
|
|
.data(data)
|
|
.enter()
|
|
.append("text")
|
|
.attr("x", d => d.x)
|
|
.attr("y", d => d.y)
|
|
.text(d => d.text);
|
|
}
|
|
|
|
// conver svg point into viewBox point
|
|
function getViewPoint(x, y) {
|
|
const view = byId("viewbox");
|
|
const svg = byId("map");
|
|
const pt = svg.createSVGPoint();
|
|
pt.x = x;
|
|
pt.y = y;
|
|
return pt.matrixTransform(view.getScreenCTM().inverse());
|
|
}
|