UNPKG

geostyler-openlayers-parser

Version:

GeoStyler Style Parser implementation for OpenLayers styles

205 lines (204 loc) 7.02 kB
import T from "ol/geom/LineString.js"; class g { /** * Check if the given style contains a graphic stroke in any of its rules. * @param style The style to check. * @returns True if the style contains a graphic stroke, false otherwise. */ static containsGraphicStroke(t) { return t.rules.some( (n) => n.symbolizers?.some( (s) => s.kind === "Line" && s.graphicStroke ) ); } /** * Get the rotation in degrees for a line segment defined by its start and * end coordinates. * @param start The start coordinate of the line segment. * @param end The end coordinate of the line segment. * @returns The rotation in degrees. */ static getSegmentRotation(t, n) { const s = n[0] - t[0], e = n[1] - t[1], i = Math.atan2(e, s), o = 180 / Math.PI; return -i * o; } /** * Get the rotations in degrees for each segment of a LineString geometry. * @param geom The LineString geometry * @returns An array of rotations in degrees for each segment */ static getSegmentRotations(t) { const n = []; return t.forEachSegment((s, e) => { const i = g.getSegmentRotation(s, e); n.push(i); }), n; } /** * Get the total size of a dash pattern in map units. * @param dashArray The dash array in pixels. * @param resolution The map resolution. * @returns The total size of the dash pattern in map units. */ static getPatternSize(t, n) { const s = t.reduce((i, o) => i + o, 0); return n * s; } /** * Get the normalized fractions along the line where each segment ends. * @param geom The LineString geometry * @returns An array of normalized fractions */ static getSegmentFractions(t) { const n = [], s = t.getLength(); let e = 0; return t.forEachSegment((i, o) => { const u = new T([i, o]).getLength() / s; e += u, n.push(e); }), n; } /** * Get the dash array as fractions of the total line length. * @param dashArray The dash array in pixels. * @param resolution The map resolution. * @param lineLength The total length of the line in map units. * @returns An array of fractions representing the dash lengths relative * to the line length. */ static getDashAsFractions(t, n, s) { const e = (i) => i * n / s; return t.map((i) => e(i)); } /** * Get the fractions along the line where ticks should be placed, considering * the symbol size, resolution, and optional dash pattern. * @param geom The LineString geometry * @param symbolSize The size of the symbol in pixels * @param resolution The map resolution * @param dashArray Optional dash array * @param dashOffset Optional dash offset * @returns An array of fractions along the line where ticks should be placed */ static getTickFractions(t, n, s, e, i) { if (n <= 0) return []; const o = t.getLength(), r = n * s / o, c = (i ? i * s : 0) / o; return e && e.length > 0 ? g.getTickFractionsWithDash( e, s, o, r, c ) : g.getTickFractionsWithoutDash( r ); } /** * Helper method to add a tick at the given fraction if it's within valid bounds. * @param ticks Array to add the tick to * @param currentFraction The fraction to potentially add * @returns True if the tick was added and we should continue, false if we've exceeded bounds */ static tryAddTick(t, n, s, e) { return e > 1 ? !1 : (s >= 0 && t.push(n), !0); } /** * Get tick fractions for a line without a dash pattern. * @param symbolSizeFraction The symbol size as a fraction of the line length * @param offsetFraction The offset as a fraction of the line length * @returns An array of fractions along the line where ticks should be placed */ static getTickFractionsWithoutDash(t) { const n = [], s = t / 2; let e = s; for (; ; ) { const i = e + t, o = e - s, r = e + s, c = g.tryAddTick(n, e, o, r); if (e = i, !c) break; } return n; } /** * Get tick fractions for a line with a dash pattern. * @param dashArray The dash array in pixels * @param resolution The map resolution * @param lineLength The total length of the line in map units * @param symbolSizeFraction The symbol size as a fraction of the line length * @param offsetFraction The offset as a fraction of the line length * @returns An array of fractions along the line where ticks should be placed */ static getTickFractionsWithDash(t, n, s, e, i) { const o = t.length % 2 === 0 ? t : [...t, ...t], r = g.getDashAsFractions(o, n, s), c = e / 2, u = []; let a = i + c, l = 0; for (; a <= 1; ) { const S = l % 2 === 1, m = r[l]; if (S) a += m; else { const h = m / e, f = Math.floor(h); for (let p = 0; p < f; p++) { const F = a - c, L = a + c, R = a + e, k = g.tryAddTick(u, a, F, L); if (a = R, !k) return u; } const d = h % 1 * e; a += d; } l = (l + 1) % r.length; } return u; } /** * Process a single LineString geometry to generate graphic stroke styles. * * @param geom The LineString geometry to process * @param symbolSize The size of the symbol in pixels * @param resolution The map resolution * @param dashArray Optional dash array for dashed patterns * @param evaluatedDashOffset Evaluated dash offset value * @param evaluatedSymbolRotation Evaluated symbol rotation in degrees * @param graphicStroke The graphic stroke point symbolizer * @param symbolizerGenerator Function to generate OL styles from a modified graphic stroke * @param PointConstructor Constructor for creating OL Point geometries * @returns Array of OL styles for the graphic stroke */ static processLineStringGraphicStroke(t, n, s, e, i, o, r, c, u) { const a = g.getTickFractions( t, n, s, e, i ), l = g.getSegmentFractions(t), m = g.getSegmentRotations(t).map((h) => { const f = h + o, d = structuredClone(r); return d.rotate = f, c(d); }); return a.map((h) => { const f = t.getCoordinateAt(h), d = new u(f), p = l.findIndex( (L) => h <= L ), F = m[p].clone(); return F.setGeometry(d), F; }); } static getLineStringsFromGeometry(t, n) { if (!t) throw new Error( "GraphicStroke can only be applied to features with geometries" ); if (t instanceof n.LineString) return [t]; if (t instanceof n.MultiLineString) return t.getLineStrings(); if (t instanceof n.Polygon) return t.getLinearRings().map((e) => new n.LineString(e.getCoordinates())); if (t instanceof n.MultiPolygon) return t.getPolygons().flatMap((e) => e.getLinearRings().map((o) => new n.LineString(o.getCoordinates()))); throw new Error( "GraphicStroke can only be applied to (Multi-)LineString or (Multi-)Polygon geometries" ); } } export { g as default };