Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/breezy-pans-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xtramaps/legend-symbols-maplibre-svelte": major
---

add svelte component library to create legend symbols for maplibre styles
5 changes: 5 additions & 0 deletions .changeset/jolly-bears-create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xtramaps/legend-symbols-maplibre-react": major
---

add react component library to create legend symbols for maplibre styles
5 changes: 5 additions & 0 deletions .changeset/polite-bobcats-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xtramaps/legend-symbols-maplibre": major
---

add core library to create legend symbols for maplibre styles
5 changes: 5 additions & 0 deletions .changeset/quick-lines-say.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xtramaps/legend-symbols-maplibre-vue": major
---

add vue component library to create legend symbols for maplibre styles
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
release:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
steps:
Expand All @@ -21,10 +22,12 @@ jobs:
registry-url: https://registry.npmjs.org
- run: npm ci
- run: npm run build
- uses: changesets/action@v1
- name: Create Release Pull Request or Publish to npm
uses: changesets/action@v1
with:
publish: npm run release
version: npm run version-packages
commit: "chore: bump package versions"
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
93 changes: 73 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 26 additions & 2 deletions packages/core/legend-symbols-maplibre/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# @xtramaps/legend-symbols-maplibre

Core library for generating legend symbols from MapLibre styles.
Framework-agnostic library for generating legend symbols from MapLibre GL styles. Takes a style layer and produces a plain virtual DOM tree (`{ element, attributes, children }`) that can be rendered by any framework.

Supports `circle`, `line`, `fill`, and `symbol` layer types.

## Install

Expand All @@ -11,9 +13,31 @@ npm install @xtramaps/legend-symbols-maplibre
## Usage

```ts
import { greet } from "@xtramaps/legend-symbols-maplibre";
import { legendSymbol } from "@xtramaps/legend-symbols-maplibre";

const tree = legendSymbol({ zoom: 14, layer: myLayer, sprite: mySpriteData });

// tree is a plain object like:
// { element: "svg", attributes: { viewBox: "0 0 20 20", ... }, children: [...] }
```

### Utilities

```ts
import {
exprHandler,
mapImageToDataURL,
cache,
loadImage,
loadJson,
} from "@xtramaps/legend-symbols-maplibre";
```

- `exprHandler({ zoom, properties })` - Evaluates MapLibre style expressions for a given zoom level and feature properties.
- `mapImageToDataURL(map, icon)` - Extracts an icon from a MapLibre map instance as a data URL.
- `cache` - Simple reference-counted cache for sprite data.
- `loadImage(url, { transformRequest })` / `loadJson(url, { transformRequest })` - Load sprite assets with optional request transformation.

## License

MIT
6 changes: 5 additions & 1 deletion packages/core/legend-symbols-maplibre/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "@xtramaps/legend-symbols-maplibre",
"version": "0.0.1",
"version": "0.0.0-next-20260320165054",
"license": "MIT",
"homepage": "https://github.com/ldproxy/xtramaps/tree/main/packages/core/legend-symbols-maplibre#readme",
"repository": {
"type": "git",
"url": "https://github.com/ldproxy/xtramaps.git",
Expand Down Expand Up @@ -29,5 +30,8 @@
"scripts": {
"build": "vite build",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@maplibre/maplibre-gl-style-spec": "^22.0.0"
}
}
53 changes: 53 additions & 0 deletions packages/core/legend-symbols-maplibre/src/Circle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { SymbolHandlerProps, SymbolTree } from "./types";

export function Circle({ expr, layer }: SymbolHandlerProps): SymbolTree {
const radius = Math.min(expr(layer, "paint", "circle-radius") as number, 8);
const strokeWidth = Math.min(
expr(layer, "paint", "circle-stroke-width") as number,
4,
);
const fillColor = expr(layer, "paint", "circle-color") as string;
const fillOpacity = expr(layer, "paint", "circle-opacity") as number;
const strokeColor = expr(layer, "paint", "circle-stroke-color") as string;
const strokeOpacity = expr(layer, "paint", "circle-stroke-opacity") as number;
const blur = expr(layer, "paint", "circle-blur") as number;

const innerRadius = radius - strokeWidth / 2;

return {
element: "svg",
attributes: {
viewBox: "0 0 20 20",
xmlns: "http://www.w3.org/2000/svg",
style: {
filter: `blur(${blur * innerRadius}px)`,
},
},
children: [
{
element: "circle",
attributes: {
key: "l1",
cx: 10,
cy: 10,
fill: fillColor,
opacity: fillOpacity,
r: innerRadius,
},
},
{
element: "circle",
attributes: {
key: "l2",
cx: 10,
cy: 10,
fill: "transparent",
opacity: strokeOpacity,
r: radius,
"stroke-width": strokeWidth,
stroke: strokeColor,
},
},
],
};
}
31 changes: 31 additions & 0 deletions packages/core/legend-symbols-maplibre/src/Fill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { SymbolHandlerProps, SymbolTree } from "./types";

export function Fill({ image, expr, layer }: SymbolHandlerProps): SymbolTree {
const { url: dataUrl } = image(
expr(layer, "paint", "fill-pattern") as string,
);
const baseStyle: Record<string, unknown> = {
width: "100%",
height: "100%",
opacity: expr(layer, "paint", "fill-opacity"),
};
const style = dataUrl
? {
...baseStyle,
backgroundImage: `url(${dataUrl})`,
backgroundPosition: "top left",
}
: {
...baseStyle,
backgroundColor: expr(layer, "paint", "fill-color"),
backgroundSize: "66% 66%",
backgroundPosition: "center",
};

return {
element: "div",
attributes: {
style,
},
};
}
Loading
Loading