@orbat-mapper/tactical-map-sheet 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { ControlMeasure, PatternId, TextAmplifiers } from "@orbat-mapper/control-measures";
1
+ import { ControlMeasure, HighlightAppearance, PatternId, TextAmplifiers } from "@orbat-mapper/control-measures";
2
2
  import { PointSymbolOffset, PointSymbolRender } from "@orbat-mapper/tactical-draw";
3
3
 
4
4
  //#region ../../node_modules/.pnpm/@types+geojson@7946.0.16/node_modules/@types/geojson/index.d.ts
@@ -337,6 +337,11 @@ interface MapSheetPortrayalDefaults {
337
337
  readonly min: number;
338
338
  readonly max: number;
339
339
  };
340
+ /**
341
+ * How graphics with `style.highlight` print (ADR-0062). Pass the same value
342
+ * as the on-screen `TacticalDraw` so the sheet matches the map.
343
+ */
344
+ readonly highlightAppearance?: HighlightAppearance;
340
345
  }
341
346
  type MapSheetAuthoredGraphic = ControlMeasure | MapSheetPointSymbol | MapSheetCustomSymbol;
342
347
  interface AuthoredMapSheetGraphic {
@@ -2,7 +2,7 @@ import GeographicLibMgrs from "geographiclib-mgrs";
2
2
  import PolarStereographic from "geographiclib-mgrs/src/polar-stereographic.mjs";
3
3
  import opentype from "opentype.js";
4
4
  import { DEFAULT_LABEL_HEIGHT_CSS_PIXELS, DEFAULT_LABEL_SIZE_CLAMP_CSS_PIXELS, DEFAULT_LINE_CAP, DEFAULT_LINE_JOIN, DEFAULT_PORTRAYAL, DEFAULT_STROKE_DASH_CSS_PIXELS, DEFAULT_STROKE_WIDTH_CSS_PIXELS, getFillPatternDefinition, renderControlMeasure, resolveConstructionMetersPerCssPixel, resolveSymbolColor } from "@orbat-mapper/control-measures";
5
- import { effectivePointSymbolPixelSize, resolveHighlightCasing, resolvePointSymbolOffset, resolveTextAppearance, scalePointSymbolLayout } from "@orbat-mapper/tactical-draw";
5
+ import { effectivePointSymbolPixelSize, highlightBandsInPaintOrder, resolvePointSymbolOffset, resolveTextAppearance, scalePointSymbolLayout } from "@orbat-mapper/tactical-draw";
6
6
  import { SaxesParser } from "saxes";
7
7
  //#region src/projection/geographic-lib.ts
8
8
  const backend = GeographicLibMgrs.UTMUPS;
@@ -684,6 +684,7 @@ function serializeElement(element) {
684
684
  ].join(" ")}"`,
685
685
  ` stroke="${escapeXml(element.strokeColor)}"`,
686
686
  ` stroke-width="${formatDecimal(element.strokeWidthMm)}"`,
687
+ element.strokeOpacity !== void 0 ? ` stroke-opacity="${formatDecimal(element.strokeOpacity)}"` : "",
687
688
  ` stroke-linecap="${element.lineCap}" stroke-linejoin="${element.lineJoin}"`,
688
689
  element.strokeDashMm.length > 0 ? ` stroke-dasharray="${element.strokeDashMm.map(formatDecimal).join(" ")}"` : "",
689
690
  element.fillColor || element.fillPatternId ? ` paint-order="fill stroke"` : "",
@@ -1424,7 +1425,8 @@ function resolvePortrayal(input) {
1424
1425
  lineCap: input?.lineCap ?? DEFAULT_LINE_CAP,
1425
1426
  lineJoin: input?.lineJoin ?? DEFAULT_LINE_JOIN,
1426
1427
  labelHeightCssPixels,
1427
- labelSizeClampCssPixels
1428
+ labelSizeClampCssPixels,
1429
+ highlightAppearance: input?.highlightAppearance
1428
1430
  };
1429
1431
  }
1430
1432
  function toScenePoint(position, context) {
@@ -1500,20 +1502,20 @@ function textFromFeature(feature, portrayal, context, constructionMetersPerCssPi
1500
1502
  };
1501
1503
  }
1502
1504
  /**
1503
- * The Highlight casing beneath each path a highlighted line or area part drew:
1504
- * the same geometry as one solid stroke in the resolved `highlightColor`,
1505
- * `highlightCasingWidth` wide and never filled, so an area is cased along its
1506
- * outline only and a transparent stroke is still cased.
1505
+ * One Highlight band stroked along each path a highlighted line or area part
1506
+ * drew: the same geometry as one solid stroke in the resolved
1507
+ * `highlightColor`, never filled, so an area is cased along its outline only
1508
+ * and a transparent stroke is still cased. Glow bands carry their opacity, so
1509
+ * SVG and PDF print them alike.
1507
1510
  */
1508
- function highlightCasings(feature, parts, portrayal) {
1509
- const casing = resolveHighlightCasing(feature, portrayal.strokeWidthCssPixels);
1510
- if (!casing) return [];
1511
+ function highlightBandPaths(band, parts) {
1511
1512
  return parts.flatMap((part) => part.kind === "path" ? [{
1512
1513
  kind: "path",
1513
1514
  points: part.points,
1514
1515
  ...part.closed ? { closed: true } : {},
1515
- strokeColor: casing.color,
1516
- strokeWidthMm: casing.width * MILLIMETRES_PER_CSS_PIXEL,
1516
+ strokeColor: band.color,
1517
+ strokeWidthMm: band.width * MILLIMETRES_PER_CSS_PIXEL,
1518
+ ...band.opacity < 1 ? { strokeOpacity: band.opacity } : {},
1517
1519
  strokeDashMm: [],
1518
1520
  lineCap: "round",
1519
1521
  lineJoin: "round"
@@ -1695,6 +1697,7 @@ function renderGraphic(layerId, authored, portrayal, context) {
1695
1697
  rendered = renderControlMeasure(graphic, {
1696
1698
  validationMode: "throw",
1697
1699
  graphicsStyle,
1700
+ highlightAppearance: portrayal.highlightAppearance,
1698
1701
  context: {
1699
1702
  groundMetersPerCssPixel: context.groundMetersPerCssPixel,
1700
1703
  labelSizeClampCssPixels: portrayal.labelSizeClampCssPixels,
@@ -1726,7 +1729,7 @@ function renderGraphic(layerId, authored, portrayal, context) {
1726
1729
  throw new Error(`Cannot render Graphic "${graphic.id}": ${String(error)}`, { cause: error });
1727
1730
  }
1728
1731
  });
1729
- const elements = [...featureElements.flatMap((parts, index) => highlightCasings(rendered.features[index], parts, portrayal)), ...featureElements.flat()];
1732
+ const elements = [...highlightBandsInPaintOrder(rendered.features, portrayal.strokeWidthCssPixels).flatMap(({ feature, band }) => highlightBandPaths(band, featureElements[rendered.features.indexOf(feature)])), ...featureElements.flat()];
1730
1733
  if (elements.length === 0 && rendered.features.every((feature) => feature.properties.text !== void 0)) return { warnings: [{
1731
1734
  code: "graphic-hidden",
1732
1735
  layerId,
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as MapSheetPatternIdentity, A as PaperSizeName, B as TacticalMapSheetLayer, C as ResolvedMapSheetRasterTileMetadata, D as ResolvedRegistrationMark, E as MapSheetRegistrationRequest, F as GraphicOutsideFrameWarning, G as MapSheetSymbolSize, H as MapSheetCustomSymbol, I as GraphicRenderWarning, J as MapSheetMetadata, K as VectorSymbolAnchor, L as MapSheetPortrayalDefaults, M as AuthoredMapSheetGraphic, N as GraphicClippedWarning, O as PAPER_SIZES, P as GraphicHiddenWarning, Q as MgrsSnapInterval, R as PointSymbolFallbackWarning, S as ResolvedMapSheetRasterLayerMetadata, T as AuthoredRegistrationMark, U as MapSheetPointSymbol, V as ControlledVectorSymbol, W as MapSheetPointSymbolCapability, X as ResolvedMgrsGridMetadata, Y as MgrsGridOptions, Z as MgrsPrecision, _ as MapSheetRasterLayer, a as ResolvedMapSheetMetadata, b as RasterDpiAnisotropyWarning, c as TacticalMapSheetResources, d as UpsProjection, et as SceneRectangle, f as UtmProjection, g as MapSheetRasterBasemap, h as MapSheetRasterAttribution, i as MapSheetPageInput, it as UtmCrs, j as resolvePaperSize, k as PaperOrientation, l as TacticalMapSheetResult, m as LowRasterDpiWarning, n as CrossZoneFootprintWarning, nt as GridCrs, o as ScaleDeviationWarning, ot as Position, p as createTacticalMapSheet, q as MapSheetMarginaliaOptions, r as MapSheetFontIdentity, rt as UpsCrs, s as TacticalMapSheetRequest, t as CrossProjectionFootprintWarning, tt as GeographicPosition, u as TacticalMapSheetWarning, v as MapSheetRasterTile, w as PrinterCalibrationRequest, x as ResolvedMapSheetRasterBasemapMetadata, y as MapSheetRasterWarning, z as PointSymbolOffsetWarning } from "./create-tactical-map-sheet-ByCfDv0u.mjs";
1
+ import { $ as MapSheetPatternIdentity, A as PaperSizeName, B as TacticalMapSheetLayer, C as ResolvedMapSheetRasterTileMetadata, D as ResolvedRegistrationMark, E as MapSheetRegistrationRequest, F as GraphicOutsideFrameWarning, G as MapSheetSymbolSize, H as MapSheetCustomSymbol, I as GraphicRenderWarning, J as MapSheetMetadata, K as VectorSymbolAnchor, L as MapSheetPortrayalDefaults, M as AuthoredMapSheetGraphic, N as GraphicClippedWarning, O as PAPER_SIZES, P as GraphicHiddenWarning, Q as MgrsSnapInterval, R as PointSymbolFallbackWarning, S as ResolvedMapSheetRasterLayerMetadata, T as AuthoredRegistrationMark, U as MapSheetPointSymbol, V as ControlledVectorSymbol, W as MapSheetPointSymbolCapability, X as ResolvedMgrsGridMetadata, Y as MgrsGridOptions, Z as MgrsPrecision, _ as MapSheetRasterLayer, a as ResolvedMapSheetMetadata, b as RasterDpiAnisotropyWarning, c as TacticalMapSheetResources, d as UpsProjection, et as SceneRectangle, f as UtmProjection, g as MapSheetRasterBasemap, h as MapSheetRasterAttribution, i as MapSheetPageInput, it as UtmCrs, j as resolvePaperSize, k as PaperOrientation, l as TacticalMapSheetResult, m as LowRasterDpiWarning, n as CrossZoneFootprintWarning, nt as GridCrs, o as ScaleDeviationWarning, ot as Position, p as createTacticalMapSheet, q as MapSheetMarginaliaOptions, r as MapSheetFontIdentity, rt as UpsCrs, s as TacticalMapSheetRequest, t as CrossProjectionFootprintWarning, tt as GeographicPosition, u as TacticalMapSheetWarning, v as MapSheetRasterTile, w as PrinterCalibrationRequest, x as ResolvedMapSheetRasterBasemapMetadata, y as MapSheetRasterWarning, z as PointSymbolOffsetWarning } from "./create-tactical-map-sheet-CEQT11I-.mjs";
2
2
 
3
3
  //#region src/mgrs.d.ts
4
4
  interface ProjectedGridCoordinate {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as geographicToMgrs, c as normalizeMgrsReference, d as snapGeographicToMgrs, f as snapProjectedToMgrs, i as resolveMapSheetRasterPlan, l as parseMgrsReference, o as mgrsToGeographic, r as mapSheetRasterPointToGeographic, s as mgrsToProjected, t as createTacticalMapSheet, u as projectedToMgrs } from "./create-tactical-map-sheet-BJLUJ9b5.mjs";
1
+ import { a as geographicToMgrs, c as normalizeMgrsReference, d as snapGeographicToMgrs, f as snapProjectedToMgrs, i as resolveMapSheetRasterPlan, l as parseMgrsReference, o as mgrsToGeographic, r as mapSheetRasterPointToGeographic, s as mgrsToProjected, t as createTacticalMapSheet, u as projectedToMgrs } from "./create-tactical-map-sheet-jY-O7aUB.mjs";
2
2
  //#region src/paper.ts
3
3
  const A0 = Object.freeze({
4
4
  widthMm: 841,
package/dist/pdf.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ResolvedMapSheetMetadata, at as Polygon, c as TacticalMapSheetResources, l as TacticalMapSheetResult, s as TacticalMapSheetRequest, u as TacticalMapSheetWarning } from "./create-tactical-map-sheet-ByCfDv0u.mjs";
1
+ import { a as ResolvedMapSheetMetadata, at as Polygon, c as TacticalMapSheetResources, l as TacticalMapSheetResult, s as TacticalMapSheetRequest, u as TacticalMapSheetWarning } from "./create-tactical-map-sheet-CEQT11I-.mjs";
2
2
 
3
3
  //#region src/pdf.d.ts
4
4
  interface TacticalMapSheetPdfResult {
package/dist/pdf.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as openSansMiddleBaselineOffset, g as openSansCentralBaselineOffset, h as POINTS_PER_MILLIMETRE, m as MILLIMETRES_PER_CSS_PIXEL, n as createTacticalMapSheetDocument, p as formatDecimal } from "./create-tactical-map-sheet-BJLUJ9b5.mjs";
1
+ import { _ as openSansMiddleBaselineOffset, g as openSansCentralBaselineOffset, h as POINTS_PER_MILLIMETRE, m as MILLIMETRES_PER_CSS_PIXEL, n as createTacticalMapSheetDocument, p as formatDecimal } from "./create-tactical-map-sheet-jY-O7aUB.mjs";
2
2
  import { jsPDF } from "jspdf";
3
3
  //#region src/pdf-transparency.ts
4
4
  const FORM_DICTIONARY_MARKER = new TextEncoder().encode("/Subtype /Form\n/BBox");
@@ -571,6 +571,7 @@ function renderElement(pdf, element, formIds) {
571
571
  fill: element.fillColor,
572
572
  stroke: element.strokeColor,
573
573
  strokeWidth: element.strokeWidthMm,
574
+ strokeOpacity: element.strokeOpacity ?? DEFAULT_VECTOR_PAINT.strokeOpacity,
574
575
  lineCap: element.lineCap,
575
576
  lineJoin: element.lineJoin,
576
577
  dash: element.strokeDashMm
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbat-mapper/tactical-map-sheet",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Scale-accurate projected vector tactical map-sheet renderer.",
5
5
  "license": "MIT",
6
6
  "author": "Orbat Mapper",
@@ -30,8 +30,8 @@
30
30
  "jspdf": "4.2.1",
31
31
  "opentype.js": "2.0.0",
32
32
  "saxes": "6.0.0",
33
- "@orbat-mapper/control-measures": "^0.37.0",
34
- "@orbat-mapper/tactical-draw": "^0.21.0"
33
+ "@orbat-mapper/control-measures": "^0.38.0",
34
+ "@orbat-mapper/tactical-draw": "^0.22.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@napi-rs/canvas": "1.0.7",
@@ -45,7 +45,7 @@
45
45
  "typescript": "~5.9.3",
46
46
  "vite": "^8.0.16",
47
47
  "vitest": "^4.1.8",
48
- "@orbat-mapper/point-symbols": "0.2.19"
48
+ "@orbat-mapper/point-symbols": "0.2.20"
49
49
  },
50
50
  "inlinedDependencies": {
51
51
  "@types/geojson": "7946.0.16"