diff --git a/docs/examples/deck-arc-layer.vue b/docs/examples/deck-arc-layer.vue
new file mode 100644
index 0000000..54aeda7
--- /dev/null
+++ b/docs/examples/deck-arc-layer.vue
@@ -0,0 +1,50 @@
+// Deck Arc Layer
+//
+// A Deck.gl Arc Layer Example
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/examples/deck-geojson-layer.vue b/docs/examples/deck-geojson-layer.vue
new file mode 100644
index 0000000..ac7d31c
--- /dev/null
+++ b/docs/examples/deck-geojson-layer.vue
@@ -0,0 +1,54 @@
+// Deck Geojson Layer
+//
+// A Deck.gl Geojson Layer Example
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/examples/deck-line-layer.vue b/docs/examples/deck-line-layer.vue
new file mode 100644
index 0000000..6e1efc1
--- /dev/null
+++ b/docs/examples/deck-line-layer.vue
@@ -0,0 +1,101 @@
+// Deck Line Layer
+//
+// A Deck.gl Line Layer Example.
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/examples/deck-polygon-layer.vue b/docs/examples/deck-polygon-layer.vue
new file mode 100644
index 0000000..e2de968
--- /dev/null
+++ b/docs/examples/deck-polygon-layer.vue
@@ -0,0 +1,58 @@
+// Deck Polygon Layer
+//
+// A Deck.gl Polygon Layer Example.
+
+
+
+
+
+
+
+
+
diff --git a/docs/examples/deck-scatteredplot-layer.vue b/docs/examples/deck-scatteredplot-layer.vue
new file mode 100644
index 0000000..aa52df7
--- /dev/null
+++ b/docs/examples/deck-scatteredplot-layer.vue
@@ -0,0 +1,45 @@
+// Deck Scattered Plot Layer
+//
+// A Deck.gl Scattered Plot Layer Example
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/components/deck-layers/arc.layer.ts b/lib/components/deck-layers/arc.layer.ts
new file mode 100644
index 0000000..bdce11e
--- /dev/null
+++ b/lib/components/deck-layers/arc.layer.ts
@@ -0,0 +1,31 @@
+import { defineComponent } from "vue";
+import { ArcLayer, type ArcLayerProps } from "@deck.gl/layers";
+import { useDeckLayer } from "@/lib/composable/useDeckLayer";
+import { type PickingInfo } from "@deck.gl/core";
+import {
+ arcProps,
+ arcPropsKeys,
+ genDeckLayerOpts,
+ type TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+
+/**
+ * Deck.gl Arc Layer
+ *
+ * See the [Deck.gl Arc Layer docs ](https://deck.gl/docs/api-reference/layers/arc-layer)
+ */
+export default defineComponent({
+ name: "MglDeckArcLayer",
+ props: {
+ ...arcProps(),
+ },
+ setup(props) {
+ const opts = { ...props } as ArcLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ };
+ return useDeckLayer(
+ opts,
+ new ArcLayer(genDeckLayerOpts({ ...opts }, arcPropsKeys)),
+ );
+ },
+});
diff --git a/lib/components/deck-layers/geojson.layer.ts b/lib/components/deck-layers/geojson.layer.ts
new file mode 100644
index 0000000..37b9808
--- /dev/null
+++ b/lib/components/deck-layers/geojson.layer.ts
@@ -0,0 +1,32 @@
+import { defineComponent } from "vue";
+import { GeoJsonLayer, type GeoJsonLayerProps } from "@deck.gl/layers";
+import { useDeckLayer } from "@/lib/composable/useDeckLayer";
+import { type PickingInfo } from "@deck.gl/core";
+import {
+ genDeckLayerOpts,
+ geojsonProps,
+ geoJsonPropsKeys,
+ type TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+
+/**
+ * Deck.gl Geojson Layer
+ *
+ * See the [Deck.gl Geojson Layer docs](https://deck.gl/docs/api-reference/layers/geojson-layer)
+ */
+export default defineComponent({
+ name: "MglDeckGeojsonLayer",
+ props: {
+ ...geojsonProps(),
+ },
+ setup(props) {
+ const opts = { ...props } as GeoJsonLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ };
+
+ return useDeckLayer(
+ opts,
+ new GeoJsonLayer(genDeckLayerOpts({ ...opts }, geoJsonPropsKeys)),
+ );
+ },
+});
diff --git a/lib/components/deck-layers/line.layer.ts b/lib/components/deck-layers/line.layer.ts
new file mode 100644
index 0000000..11d564a
--- /dev/null
+++ b/lib/components/deck-layers/line.layer.ts
@@ -0,0 +1,31 @@
+import { defineComponent } from "vue";
+import { LineLayer, type LineLayerProps } from "@deck.gl/layers";
+import { useDeckLayer } from "@/lib/composable/useDeckLayer";
+import { type PickingInfo } from "@deck.gl/core";
+import {
+ genDeckLayerOpts,
+ lineProps,
+ linePropsKeys,
+ type TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+
+/**
+ * Deck.gl Line Layer
+ *
+ * See the [Deck.gl Line Layer docs](https://deck.gl/docs/api-reference/layers/line-layer)
+ */
+export default defineComponent({
+ name: "MglDeckLineLayer",
+ props: {
+ ...lineProps(),
+ },
+ setup(props) {
+ const opts = { ...props } as LineLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ };
+ return useDeckLayer(
+ opts,
+ new LineLayer(genDeckLayerOpts({ ...opts }, linePropsKeys)),
+ );
+ },
+});
diff --git a/lib/components/deck-layers/polygon.layer.ts b/lib/components/deck-layers/polygon.layer.ts
new file mode 100644
index 0000000..2658bab
--- /dev/null
+++ b/lib/components/deck-layers/polygon.layer.ts
@@ -0,0 +1,31 @@
+import { defineComponent } from "vue";
+import { PolygonLayer, type PolygonLayerProps } from "@deck.gl/layers";
+import { useDeckLayer } from "@/lib/composable/useDeckLayer";
+import { type PickingInfo } from "@deck.gl/core";
+import {
+ genDeckLayerOpts,
+ polygonProps,
+ polygonPropsKeys,
+ type TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+
+/**
+ * Deck.gl Polygon Layer
+ *
+ * See the [Deck.gl Polygon Layer docs](https://deck.gl/docs/api-reference/layers/polygon-layer)
+ */
+export default defineComponent({
+ name: "MglDeckPolygonLayer",
+ props: {
+ ...polygonProps(),
+ },
+ setup(props) {
+ const opts = { ...props } as PolygonLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ };
+ return useDeckLayer(
+ opts,
+ new PolygonLayer(genDeckLayerOpts({ ...opts }, polygonPropsKeys)),
+ );
+ },
+});
diff --git a/lib/components/deck-layers/scatteredPlot.layer.ts b/lib/components/deck-layers/scatteredPlot.layer.ts
new file mode 100644
index 0000000..4ab7391
--- /dev/null
+++ b/lib/components/deck-layers/scatteredPlot.layer.ts
@@ -0,0 +1,33 @@
+import { defineComponent } from "vue";
+import { ScatterplotLayer, type ScatterplotLayerProps } from "@deck.gl/layers";
+import { useDeckLayer } from "@/lib/composable/useDeckLayer";
+import { type PickingInfo } from "@deck.gl/core";
+import {
+ genDeckLayerOpts,
+ scatteredPlotProps,
+ scatteredPlotPropsKeys,
+ type TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+
+/**
+ * Deck.gl ScatteredPlot Layer
+ *
+ * See the [Deck.gl ScatteredPlot Layer docs](https://deck.gl/docs/api-reference/layers/scatterplot-layer)
+ */
+export default defineComponent({
+ name: "MglDeckScatteredPlotLayer",
+ props: {
+ ...scatteredPlotProps(),
+ },
+ setup(props) {
+ const opts = { ...props } as ScatterplotLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ };
+ return useDeckLayer(
+ opts,
+ new ScatterplotLayer(
+ genDeckLayerOpts({ ...opts }, scatteredPlotPropsKeys),
+ ),
+ );
+ },
+});
diff --git a/lib/components/index.ts b/lib/components/index.ts
index 4b2f25d..22726ee 100644
--- a/lib/components/index.ts
+++ b/lib/components/index.ts
@@ -24,3 +24,11 @@ export { default as MglHillshadeLayer } from "./layers/hillshade.layer";
export { default as MglLineLayer } from "./layers/line.layer";
export { default as MglRasterLayer } from "./layers/raster.layer";
export { default as MglSymbolLayer } from "./layers/symbol.layer";
+
+// deck layers
+export { default as MglDeckGeojsonLayer } from "./deck-layers/geojson.layer";
+export { default as MglDeckArcLayer } from "./deck-layers/arc.layer";
+export { default as MglDeckLineLayer } from "./deck-layers/line.layer";
+export { default as MglDeckScatteredPlotLayer } from "./deck-layers/scatteredPlot.layer";
+export { default as MglDeckPolygonLayer } from "./deck-layers/polygon.layer";
+
diff --git a/lib/composable/useDeckLayer.ts b/lib/composable/useDeckLayer.ts
new file mode 100644
index 0000000..be813b1
--- /dev/null
+++ b/lib/composable/useDeckLayer.ts
@@ -0,0 +1,55 @@
+import type {
+ DeckLayer,
+ DeckLayerProps,
+ TooltipContent,
+} from "@/lib/lib/deck.layer.lib";
+import {
+ createCommentVNode,
+ inject,
+ onBeforeUnmount,
+ ref,
+ warn,
+ watch,
+} from "vue";
+import { isLoadedSymbol, mapSymbol } from "@/lib/types";
+import { MapboxOverlay } from "@deck.gl/mapbox";
+import type { PickingInfo } from "@deck.gl/core";
+
+export function useDeckLayer(
+ props: DeckLayerProps & {
+ getTooltip?: ((info: PickingInfo) => TooltipContent) | null;
+ },
+ layerConstructor: DeckLayer,
+) {
+ const map = inject(mapSymbol)!;
+ const isLoaded = inject(isLoadedSymbol)!;
+ const overlay = ref();
+
+ if (!map) {
+ warn(`Deck.gl layers require a Deck.gl map instance.`);
+ return;
+ }
+
+ function addLayer() {
+ overlay.value = new MapboxOverlay({
+ layers: [layerConstructor],
+ getTooltip: props.getTooltip
+ ? (f: PickingInfo) => props.getTooltip!(f)
+ : undefined,
+ });
+
+ map.value!.addControl(overlay.value);
+ }
+
+ watch(isLoaded, (il) => {
+ if (il) {
+ addLayer();
+ }
+ });
+
+ onBeforeUnmount(() => {
+ map.value!.removeControl(overlay.value);
+ });
+
+ return () => createCommentVNode(`${props.id} Deck Layer`);
+}
diff --git a/lib/lib/deck.layer.lib.ts b/lib/lib/deck.layer.lib.ts
new file mode 100644
index 0000000..54f825a
--- /dev/null
+++ b/lib/lib/deck.layer.lib.ts
@@ -0,0 +1,890 @@
+import type {
+ ArcLayerProps,
+ GeoJsonLayerProps,
+ BitmapLayerProps,
+ ColumnLayerProps,
+ LineLayerProps,
+ PolygonLayerProps,
+ ScatterplotLayerProps,
+ PathLayerProps,
+ IconLayerProps,
+ ArcLayer,
+ ColumnLayer,
+ GeoJsonLayer,
+ BitmapLayer,
+ LineLayer,
+ PolygonLayer,
+ ScatterplotLayer,
+ PathLayer,
+ IconLayer,
+} from "@deck.gl/layers";
+
+import { type ComponentPropsOptions, type PropType } from "vue";
+import {
+ COORDINATE_SYSTEM,
+ LayerExtension,
+ type PickingInfo,
+ type Color,
+ type Unit,
+ type Position,
+ type LayerProps,
+ type LayerData,
+ type Accessor,
+ type Material, AccessorFunction
+} from "@deck.gl/core";
+import type { MjolnirEvent } from "mjolnir.js";
+import type { Feature, Geometry, Polygon } from "geojson";
+
+export type DeckLayer =
+ | ArcLayer
+ | GeoJsonLayer
+ | BitmapLayer
+ | ColumnLayer
+ | LineLayer
+ | PolygonLayer
+ | ScatterplotLayer
+ | PathLayer
+ | IconLayer;
+
+export type DeckLayerProps =
+ | ArcLayerProps
+ | GeoJsonLayerProps
+ | BitmapLayerProps
+ | ColumnLayerProps
+ | LineLayerProps
+ | PolygonLayerProps
+ | ScatterplotLayerProps
+ | PathLayerProps
+ | IconLayerProps;
+
+export type PointType =
+ | "circle"
+ | "icon"
+ | "text"
+ | "circle+icon"
+ | "circle+text"
+ | "icon+text"
+ | "icon+circle"
+ | "text+circle"
+ | "text+icon";
+
+export type TooltipContent =
+ | null
+ | string
+ | {
+ text?: string;
+ html?: string;
+ className?: string;
+ style?: Partial;
+ };
+
+export const baseLayerProps: ComponentPropsOptions = {
+ // basic props
+ id: {
+ type: String as PropType,
+ required: true,
+ },
+ data: {
+ type: [Object, String] as PropType,
+ },
+ visible: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ opacity: {
+ type: Number as PropType,
+ default: 1,
+ },
+ extensions: {
+ type: Array as PropType,
+ },
+ onError: {
+ type: Function as unknown as PropType<
+ ((error: Error) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+
+ // Interaction Properties
+ pickable: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ onHover: {
+ type: Function as unknown as PropType<
+ ((pickingInfo: PickingInfo, event: MjolnirEvent) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+ onClick: {
+ type: Function as unknown as PropType<
+ ((pickingInfo: PickingInfo, event: MjolnirEvent) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+ onDragStart: {
+ type: Function as unknown as PropType<
+ ((pickingInfo: PickingInfo, event: MjolnirEvent) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+ onDrag: {
+ type: Function as unknown as PropType<
+ ((pickingInfo: PickingInfo, event: MjolnirEvent) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+ onDragEnd: {
+ type: Function as unknown as PropType<
+ ((pickingInfo: PickingInfo, event: MjolnirEvent) => boolean | void) | null
+ >,
+ default: undefined,
+ },
+ highlightColor: {
+ type: [Array, Function] as unknown as PropType<
+ Color | ((pickingInfo: PickingInfo) => void)
+ >,
+ default: () => [0, 0, 128, 128],
+ },
+ highlightedObjectIndex: {
+ type: [Number, null],
+ default: null,
+ },
+ autoHighlight: {
+ type: Boolean,
+ default: false,
+ },
+
+ // Coordinate System Properties
+ coordinateSystem: {
+ type: Number,
+ default: COORDINATE_SYSTEM.DEFAULT,
+ },
+ coordinateOrigin: {
+ type: Array as unknown as PropType<[number, number, number]>,
+ default: () => [0, 0, 0],
+ },
+ wrapLongitude: {
+ type: Boolean,
+ default: false,
+ },
+ modelMatrix: {
+ type: Array as PropType,
+ default: undefined,
+ },
+
+ // data properties
+ dataComparator: {
+ type: Function as unknown as PropType<
+ | (>(
+ newData: LayerDataT,
+ oldData?: LayerDataT,
+ ) => boolean)
+ | null
+ >,
+ },
+ _dataDiff: {
+ type: Function as unknown as PropType<
+ | (>(
+ newData: LayerDataT,
+ oldData?: LayerDataT,
+ ) => { startRow: number; endRow?: number }[])
+ | null
+ >,
+ },
+ dataTransform: {
+ type: Function as unknown as PropType<
+ | (>(
+ data: unknown,
+ previousData?: LayerDataT,
+ ) => LayerDataT)
+ | null
+ >,
+ default: undefined,
+ },
+ positionFormat: {
+ type: String as PropType<"XYZ" | "XY">,
+ default: "XYZ",
+ },
+ colorFormat: {
+ type: String as PropType<"RGBA" | "RGB">,
+ default: "RGBA",
+ },
+ numInstances: {
+ type: Number as PropType,
+ default: undefined,
+ },
+ updateTrigger: {
+ type: Object as PropType>,
+ },
+
+ // custom tooltip prop
+ getTooltip: {
+ type: Function as unknown as PropType<
+ ((info: PickingInfo) => TooltipContent) | null
+ >,
+ },
+};
+export const baseLayerKeys: (keyof LayerProps)[] = [
+ "id",
+ "data",
+ "visible",
+ "opacity",
+ "extensions",
+ "onError",
+ "pickable",
+ "onHover",
+ "onClick",
+ "onDragStart",
+ "onDrag",
+ "onDragEnd",
+ "highlightColor",
+ "highlightedObjectIndex",
+ "autoHighlight",
+ "coordinateSystem",
+ "coordinateOrigin",
+ "wrapLongitude",
+ "modelMatrix",
+ "dataComparator",
+ "_dataDiff",
+ "dataTransform",
+ "positionFormat",
+ "colorFormat",
+ "numInstances",
+];
+
+export function arcProps(): ComponentPropsOptions {
+ return {
+ ...baseLayerProps,
+ greatCircle: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ numSegments: {
+ type: Number as PropType,
+ default: 50,
+ },
+ widthUnits: {
+ type: String as PropType,
+ default: "pixels",
+ },
+ widthScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ widthMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ widthMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ getSourcePosition: {
+ type: Function as unknown as PropType>,
+ default: (object: { sourcePosition: Position }) => object.sourcePosition,
+ },
+ getTargetPosition: {
+ type: Function as unknown as PropType>,
+ default: (object: { targetPosition: Position }) => object.targetPosition,
+ },
+ getSourceColor: {
+ type: Function as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getTargetColor: {
+ type: Function as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getWidth: {
+ type: Number as PropType>,
+ default: 1,
+ },
+ getHeight: {
+ type: Number as PropType>,
+ default: 1,
+ },
+ getTilt: {
+ type: Number as PropType>,
+ default: 0,
+ },
+ };
+}
+export const arcPropsKeys: (keyof ArcLayerProps)[] = [
+ ...baseLayerKeys,
+ "greatCircle",
+ "numSegments",
+ "widthUnits",
+ "widthScale",
+ "widthMinPixels",
+ "widthMaxPixels",
+ "getSourcePosition",
+ "getTargetPosition",
+ "getSourceColor",
+ "getTargetColor",
+ "getWidth",
+ "getHeight",
+ "getTilt",
+];
+
+export function geojsonProps(): ComponentPropsOptions {
+ return {
+ ...baseLayerProps,
+ pointType: {
+ type: String as PropType,
+ default: "circle",
+ },
+ // fill color props
+ filled: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ getFillColor: {
+ type: [Array, Function] as unknown as PropType<
+ Accessor, Color>
+ >,
+ default: () => [0, 0, 0, 255],
+ },
+ // stroke options
+ stroked: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ getLineColor: {
+ type: [Array, Function] as unknown as PropType<
+ Accessor, Color>
+ >,
+ default: () => [0, 0, 0, 255],
+ },
+ getLineWidth: {
+ type: [Number, Function] as PropType<
+ Accessor, number>
+ >,
+ default: 1,
+ },
+ lineWidthUnits: {
+ type: String as PropType,
+ default: "meters",
+ },
+ lineWidthScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ lineWidthMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ lineWidthMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ lineCapRounded: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ lineJointRounded: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ lineMiterLimit: {
+ type: Number as PropType,
+ default: 4,
+ },
+ lineBillboard: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ // 3D options
+ extruded: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ wireframe: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ getElevation: {
+ type: [Number, Function] as PropType<
+ Accessor, number>
+ >,
+ default: 1000,
+ },
+ elevationScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ material: {
+ type: [Boolean, Object] as PropType,
+ default: true,
+ },
+ _full3d: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ getPointRadius: {
+ type: [Number, Function] as PropType<
+ Accessor, number>
+ >,
+ default: 1,
+ },
+ pointRadiusUnits: {
+ type: String as PropType,
+ },
+ pointRadiusScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ pointRadiusMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ pointRadiusMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ pointAntialiasing: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ pointBillboard: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ getText: {
+ type: Function as PropType, unknown>>,
+ default: (f: { properties: { text: unknown } }) => f.properties.text,
+ },
+ getTextColor: {
+ type: [Array, Function] as unknown as PropType<
+ Accessor, Color>
+ >,
+ default: () => [0, 0, 0, 255],
+ },
+ getTextAngle: {
+ type: Number as PropType, number>>,
+ default: 0,
+ },
+
+ getTextSize: {
+ type: Number as PropType, number>>,
+ default: 32,
+ },
+ getTextAnchor: {
+ type: String as PropType, string>>,
+ default: "middle",
+ },
+ getTextAlignmentBaseline: {
+ type: String as PropType, string>>,
+ default: "center",
+ },
+ getTextPixelOffset: {
+ type: [Array, Function] as PropType<
+ Accessor, number[]>
+ >,
+ default: () => [0, 0],
+ },
+ getTextBackgroundColor: {
+ type: [Array, Function] as unknown as PropType<
+ Accessor, Color>
+ >,
+ default: () => [255, 255, 255, 255],
+ },
+ getTextBorderColor: {
+ type: [Array, Function] as unknown as PropType<
+ Accessor, Color>
+ >,
+ default: () => [0, 0, 0, 255],
+ },
+ getTextBorderWidth: {
+ type: Number as PropType, number>>,
+ default: 0,
+ },
+ textSizeUnits: {
+ type: String as PropType,
+ default: "pixels",
+ },
+ textSizeScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ textSizeMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ textSizeMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ textCharacterSet: {
+ type: [String, Array] as PropType,
+ },
+ textFontFamily: {
+ type: String as PropType,
+ default: "Monaco, monospace",
+ },
+ textFontWeight: {
+ type: [Number, String] as PropType,
+ default: "normal",
+ },
+ textLineHeight: {
+ type: Number as PropType,
+ default: 1,
+ },
+ textMaxWidth: {
+ type: Number as PropType,
+ default: -1,
+ },
+ textWordBreak: {
+ type: String as PropType,
+ default: "break-word",
+ },
+ textBackground: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ textBackgroundPadding: {
+ type: Array as PropType,
+ default: () => [0, 0],
+ },
+ textOutlineColor: {
+ type: Array as unknown as PropType,
+ default: () => [0, 0, 0, 255],
+ },
+ textOutlineWidth: {
+ type: Number as PropType,
+ default: 0,
+ },
+ textBillboard: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ textFontSettings: {
+ type: Object,
+ },
+ };
+}
+export const geoJsonPropsKeys: (keyof GeoJsonLayerProps)[] = [
+ ...baseLayerKeys,
+ "pointType",
+ "filled",
+ "getFillColor",
+ "stroked",
+ "getLineColor",
+ "getLineWidth",
+ "lineWidthUnits",
+ "lineWidthScale",
+ "lineWidthMinPixels",
+ "lineWidthMaxPixels",
+ "lineCapRounded",
+ "lineJointRounded",
+ "lineMiterLimit",
+ "lineBillboard",
+ "extruded",
+ "wireframe",
+ "getElevation",
+ "elevationScale",
+ "material",
+ "_full3d",
+ "getPointRadius",
+ "pointRadiusUnits",
+ "pointRadiusScale",
+ "pointRadiusMinPixels",
+ "pointRadiusMaxPixels",
+ "pointAntialiasing",
+ "pointBillboard",
+ "getText",
+ "getTextColor",
+ "getTextAngle",
+ "getTextSize",
+ "getTextAnchor",
+ "getTextAlignmentBaseline",
+ "getTextPixelOffset",
+ "getTextBackgroundColor",
+ "getTextBorderColor",
+ "getTextBorderWidth",
+ "textSizeUnits",
+ "textSizeScale",
+ "textSizeMinPixels",
+ "textSizeMaxPixels",
+ "textCharacterSet",
+ "textFontFamily",
+ "textFontWeight",
+ "textLineHeight",
+ "textMaxWidth",
+ "textWordBreak",
+ "textBackground",
+ "textBackgroundPadding",
+ "textOutlineColor",
+ "textOutlineWidth",
+ "textBillboard",
+ "textFontSettings",
+];
+
+export function lineProps(): ComponentPropsOptions {
+ return {
+ ...baseLayerProps,
+ widthUnits: {
+ type: String as PropType,
+ default: "pixels",
+ },
+
+ widthScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+
+ widthMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+
+ widthMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ getSourcePosition: {
+ type: Function as unknown as PropType>,
+ default: (object: { sourcePosition: Position }) => object.sourcePosition,
+ },
+ getTargetPosition: {
+ type: Function as unknown as PropType>,
+ default: (object: { targetPosition: Position }) => object.targetPosition,
+ },
+
+ getColor: {
+ type: [Function, Array] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getWidth: {
+ type: Number as PropType>,
+ default: 1,
+ },
+ };
+}
+export const linePropsKeys: (keyof LineLayerProps)[] = [
+ ...baseLayerKeys,
+ "widthUnits",
+ "widthScale",
+ "widthMinPixels",
+ "widthMaxPixels",
+ "getSourcePosition",
+ "getTargetPosition",
+ "getColor",
+ "getWidth",
+];
+
+export function scatteredPlotProps(): ComponentPropsOptions {
+ return {
+ ...baseLayerProps,
+ radiusUnits: {
+ type: String as PropType,
+ default: "meters",
+ },
+ radiusScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ lineWidthUnits: {
+ type: String as PropType,
+ default: "meters",
+ },
+ lineWidthScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ filled: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ stroked: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ radiusMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ radiusMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ lineWidthMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ lineWidthMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ billboard: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ antialiasing: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ getPosition: {
+ type: Function as unknown as PropType>,
+ default: (object: { position: Position }) => object.position,
+ },
+ getRadius: {
+ type: [Number, Function] as PropType>,
+ default: 1,
+ },
+ getColor: {
+ type: [Function, Array] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getFillColor: {
+ type: [Array, Function] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getLineColor: {
+ type: [Array, Function] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getLineWidth: {
+ type: [Number, Function] as PropType>,
+ default: 1,
+ },
+ };
+}
+export const scatteredPlotPropsKeys: (keyof ScatterplotLayerProps)[] = [
+ ...baseLayerKeys,
+ "radiusUnits",
+ "radiusScale",
+ "lineWidthUnits",
+ "lineWidthScale",
+ "filled",
+ "stroked",
+ "radiusMinPixels",
+ "radiusMaxPixels",
+ "lineWidthMinPixels",
+ "lineWidthMaxPixels",
+ "billboard",
+ "antialiasing",
+ "getPosition",
+ "getRadius",
+ "getColor",
+ "getFillColor",
+ "getLineColor",
+ "getLineWidth",
+];
+
+export function polygonProps(): ComponentPropsOptions {
+ return {
+ ...baseLayerProps,
+ filled: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ stroked: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ extruded: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ wireframe: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ elevationScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ lineWidthUnits: {
+ type: String as PropType,
+ default: "meters",
+ },
+ lineWidthScale: {
+ type: Number as PropType,
+ default: 1,
+ },
+ lineWidthMinPixels: {
+ type: Number as PropType,
+ default: 0,
+ },
+ lineWidthMaxPixels: {
+ type: Number as PropType,
+ default: Number.MAX_SAFE_INTEGER,
+ },
+ lineJointRounded: {
+ type: Boolean as PropType,
+ default: false,
+ },
+ lineMiterLimit: {
+ type: Number as PropType,
+ default: 4,
+ },
+ material: {
+ type: [Boolean, Object] as PropType,
+ default: true,
+ },
+ _normalize: {
+ type: Boolean as PropType,
+ default: true,
+ },
+ _windingOrder: {
+ type: String as PropType<'CW' | 'CCW'>,
+ default: "CW",
+ },
+ getPolygon: {
+ type: Function as PropType>,
+ default: (object: { polygon: Polygon }) => object.polygon,
+ },
+ getFillColor: {
+ type: [Array, Function] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getLineColor: {
+ type: [Array, Function] as unknown as PropType>,
+ default: () => [0, 0, 0, 255],
+ },
+ getLineWidth: {
+ type: [Number, Function] as PropType>,
+ default: 1,
+ },
+ getElevation: {
+ type: [Number, Function] as PropType>,
+ default: 1000,
+ }
+ };
+}
+export const polygonPropsKeys: (keyof PolygonLayerProps)[] = [
+ ...baseLayerKeys,
+ 'filled',
+ 'stroked',
+ 'extruded',
+ 'wireframe',
+ 'elevationScale',
+ 'lineWidthUnits',
+ 'lineWidthScale',
+ 'lineWidthMinPixels',
+ 'lineWidthMaxPixels',
+ 'lineJointRounded',
+ 'lineMiterLimit',
+ 'material',
+ '_normalize',
+ '_windingOrder',
+ 'getPolygon',
+ 'getFillColor',
+ 'getLineColor',
+ 'getLineWidth',
+ 'getElevation'
+]
+
+export function genDeckLayerOpts(
+ props: T & { getTooltip?: ((info: PickingInfo) => TooltipContent) | null },
+ validProps: Array,
+): Partial {
+ for (const opt of Object.keys(props) as Array) {
+ if (props[opt] === undefined || !validProps.includes(opt)) {
+ delete props[opt];
+ }
+ }
+
+ return props;
+}
diff --git a/package.json b/package.json
index 0e1be77..fb00a2b 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,9 @@
},
"devDependencies": {
"@babel/types": "^7.23.9",
+ "@deck.gl/core": "^9.0.35",
+ "@deck.gl/layers": "^9.0.35",
+ "@deck.gl/mapbox": "^9.0.35",
"@eslint/js": "^9.1.1",
"@indoorequal/vue-maplibre-gl": "workspace:^",
"@maplibre/maplibre-gl-inspect": "^1.7.0",
diff --git a/vite.config.ts b/vite.config.ts
index dc160a0..1c844c7 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -24,7 +24,7 @@ export default defineConfig({
*/`)
],
ssr : {
- external: [ 'vue', 'maplibre-gl', 'geojson' ]
+ external: [ 'vue', 'maplibre-gl', 'geojson', '@deck.gl/core', '@deck.gl/layers', '@deck.gl/mapbox' ]
},
build : {
sourcemap : true,
@@ -39,7 +39,10 @@ export default defineConfig({
external: [
'vue',
'maplibre-gl',
- 'geojson'
+ 'geojson',
+ '@deck.gl/core',
+ '@deck.gl/layers',
+ '@deck.gl/mapbox'
],
output : {
assetFileNames: (assetInfo) => {
@@ -51,7 +54,10 @@ export default defineConfig({
globals: {
vue : 'Vue',
'maplibre-gl': 'maplibregl',
- geojson : 'geojson'
+ geojson : 'geojson',
+ '@deck.gl/core' : 'deckGlCore',
+ '@deck.gl/layers' : 'deckGlLayers',
+ '@deck.gl/mapbox' : 'deckGlMapbox'
},
},
}