├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── inspectionProfiles │ └── Project_Default.xml ├── modules.xml ├── vcs.xml └── vue-deck.gl.iml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── .vitepress │ ├── config.mts │ └── theme │ │ ├── index.ts │ │ └── styles.css ├── examples │ ├── arc-layer.md │ ├── column-layer.md │ ├── contour-layer.md │ ├── geojson-layer-paths.md │ ├── grid-layer.md │ ├── hexagon-layer.md │ ├── icon-data │ │ ├── location-icon-atlas.png │ │ └── location-icon-mapping.json │ ├── icon-layer.md │ ├── index.md │ ├── path-layer.md │ ├── point-cloud-layer.md │ ├── polygon-layer.md │ ├── scatterplot-layer.md │ ├── trips-layer.md │ └── wms-layer.md ├── google-maps │ ├── google-basemap.md │ ├── google-overlay.md │ └── index.md ├── guide │ ├── installation.md │ └── introduction.md ├── index.md ├── layers │ ├── arc-layer.md │ ├── column-layer.md │ ├── contour-layer.md │ ├── geojson-layer.md │ ├── grid-layer.md │ ├── hexagon-layer.md │ ├── icon-data │ │ ├── location-icon-atlas.png │ │ └── location-icon-mapping.json │ ├── icon-layer.md │ ├── index.md │ ├── path-layer.md │ ├── point-cloud-layer.md │ ├── polygon-layer.md │ ├── scatterplot-layer.md │ ├── trips-layer.md │ └── wms-layer.md ├── maplibre │ ├── index.md │ ├── mapbox-overlay.md │ └── maplibre-basemap.md └── public │ ├── visgl-logo-light.png │ ├── wakeb-logo-dark-mode.png │ └── wakeb-logo-light-mode.png ├── lerna.json ├── package-lock.json ├── package.json └── packages ├── google-maps ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.json ├── .vscode │ └── extensions.json ├── README.md ├── env.d.ts ├── eslint.config.ts ├── index.html ├── package.json ├── public │ └── favicon.ico ├── src │ ├── components │ │ ├── index.ts │ │ ├── map.component.ts │ │ └── overlay.component.ts │ ├── lib │ │ └── overlay.lib.ts │ ├── main.ts │ ├── shared │ │ └── constants.ts │ ├── types.ts │ └── utils │ │ └── genDeckOpts.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── web-types.config.cjs ├── layers ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.json ├── README.md ├── index.html ├── package.json ├── src │ ├── components │ │ ├── index.ts │ │ └── layers │ │ │ ├── arc.layer.ts │ │ │ ├── column.layer.ts │ │ │ ├── contour.layer.ts │ │ │ ├── geojson.layer.ts │ │ │ ├── grid.layer.ts │ │ │ ├── heatmap.layer.ts │ │ │ ├── hexagon.layer.ts │ │ │ ├── icon.layer.ts │ │ │ ├── path.layer.ts │ │ │ ├── point-cloud.layer.ts │ │ │ ├── polygon.layer.ts │ │ │ ├── scatterplot.layer.ts │ │ │ ├── tile3d.layer.ts │ │ │ ├── trips.layer.ts │ │ │ └── wms.layer.ts │ ├── composables │ │ └── useLayer.ts │ ├── lib │ │ └── layers │ │ │ ├── arc.lib.ts │ │ │ ├── column.lib.ts │ │ │ ├── contour.lib.ts │ │ │ ├── geojson.lib.ts │ │ │ ├── grid.lib.ts │ │ │ ├── heatmap.lib.ts │ │ │ ├── hexagon.lib.ts │ │ │ ├── icon.lib.ts │ │ │ ├── layer.lib.ts │ │ │ ├── path.lib.ts │ │ │ ├── point-cloud.lib.ts │ │ │ ├── polygon.lib.ts │ │ │ ├── scatterplot.lib.ts │ │ │ ├── tile3d.lib.ts │ │ │ ├── trips.lib.ts │ │ │ └── wms.lib.ts │ ├── main.ts │ ├── shared │ │ └── types.ts │ └── utils │ │ └── index.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── web-types.config.cjs ├── maplibre ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.json ├── .vscode │ └── extensions.json ├── README.md ├── env.d.ts ├── eslint.config.ts ├── index.html ├── package.json ├── public │ └── favicon.ico ├── src │ ├── components │ │ ├── index.ts │ │ ├── map.component.ts │ │ └── overlay.component.ts │ ├── lib │ │ ├── map.lib.ts │ │ └── overlay.lib.ts │ ├── main.ts │ ├── shared │ │ └── constants.ts │ ├── types.ts │ └── utils │ │ ├── genDeckOpts.ts │ │ └── isLngLatEqual.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── web-types.config.cjs └── playground ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.json ├── .vscode └── extensions.json ├── README.md ├── env.d.ts ├── eslint.config.ts ├── index.html ├── package.json ├── public └── favicon.ico ├── src ├── App.vue ├── main.ts ├── router │ └── index.js └── views │ ├── ArcLayer.vue │ ├── ColumnLayer.vue │ ├── MaplibreMap.vue │ ├── PointCloudLayer.vue │ ├── google │ ├── GoogleMap.vue │ └── HexagonLayer.vue │ └── maplibre │ ├── ArcLayer.vue │ ├── ArcLayerMigration.vue │ ├── BetaHeatmapLayer.vue │ ├── ColumnLayer.vue │ ├── ContourLayer.vue │ ├── GeojsonLayer.vue │ ├── GeojsonLayerPaths.vue │ ├── GridLayer.vue │ ├── HeatmapLayer.vue │ ├── HexagonLayer.vue │ ├── HexagonLayerRoadSafety.vue │ ├── IconLayer.vue │ ├── PathLayer.vue │ ├── PointCloudLayer.vue │ ├── PolygonLayer.vue │ ├── ScatterplotLayer.vue │ ├── Tile3dLayer.vue │ ├── TripsLayer.vue │ ├── WMSLayer.vue │ └── icon-data │ ├── location-icon-atlas.png │ └── location-icon-mapping.json ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /docs/.vitepress/cache 3 | /docs/.vitepress/dist 4 | /docs/.env 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 16 | 17 | 26 | 27 | 30 | 31 | 38 | 39 | 46 | 47 | 54 | 55 | 60 | 61 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vue-deck.gl.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [v1.0.0-beta.4] - 2025-04-20 2 | 3 | ### ✨ New Features: 4 | 5 | - **Support for New Layers:** 6 | - Introduced declarative support for the following new Deck.gl layer components in `@vue-deckgl-suite/layers`: 7 | - `PolygonLayer`: Enables rendering of polygon-shaped geospatial data. 8 | - `ContourLayer`: Provides support for generating isocontours (contour lines/polygons) from spatial datasets. 9 | - `ScatterplotLayer`: Allows visualization of point data with support for variable point sizes, colors, and interactivity. 10 | - Example-based documentation has been added for each of these layers, demonstrating their usage with `@vue-deckgl-suite/maplibre`. 11 | 12 | --- 13 | 14 | ### 📝 Documentation: 15 | 16 | - **Layer Guides and Examples:** 17 | - Added detailed documentation and examples for the new `PolygonLayer`, `ContourLayer`, and `ScatterplotLayer` in the developer guide. 18 | - Examples utilize both **MapLibre** and **Google Maps** base maps, showcasing flexibility in integration. 19 | 20 | 21 | ## [v1.0.0-beta.3] - 2025-04-16 22 | 23 | ### ✨ New Features: 24 | 25 | - **Google Maps Integration:** 26 | - Added support for Google Maps as a basemap with the new `@vue-deckgl-suite/google-maps` package. 27 | - Introduced Vue components for Google Maps, including: 28 | - `Map`: A Google Maps wrapper with extensive property and event support. 29 | - **Integration Examples:** Showcases layers like `HexagonLayer` and `ArcLayer` with Google Maps as the underlying basemap. 30 | - Support for managing environment-specific settings using a new `__GOOGLE_MAPS_KEY__` definition in the Vite configuration. 31 | 32 | --- 33 | 34 | ### 🔧 Improvements: 35 | 36 | - **Environment Variable Support in Vite Config:** 37 | - Refactored Vite configuration to use `loadEnv`, allowing for easier management of environment-specific variables, especially for keys like Google Maps API. 38 | 39 | - **Documentation Enhancements:** 40 | - Updated READMEs and additional documentation for `@vue-deckgl-suite/google-maps` integration, including: 41 | - Step-by-step installation process. 42 | - Sample usage with both declarative and programmatic approaches. 43 | - Advanced examples of geospatial visualizations using Google Maps and Deck.gl layers. . 44 | 45 | --- 46 | 47 | ## [v1.0.0-beta.2] - 2025-04-12 48 | 49 | ### 🚀 Refactor: Enhanced Deck.gl Layer Management 50 | 51 | #### Highlights: 52 | - **Dynamic Layer Lifecycle Management in `useLayer`** 53 | - Introduced a robust **watcher** to dynamically update Deck.gl layers in response to `props` changes, using deep reactivity. 54 | - Automatically finalizes and disposes of GPU resources when layers are replaced or unmounted, preventing potential memory leaks. 55 | 56 | - **Major Improvements to `overlay.component.ts`:** 57 | - Improved `watch` logic for accurately updating and synchronizing layers across the Deck.gl context. 58 | - Cleanly structured the initialization and des`truction of the MapboxOverlay instance, ensuring stability and reusability. 59 | 60 | #### Advantages for Developers: 61 | - **Simplified Layer Updates:** 62 | Managing reactive props (such as `data` or styling options) is now seamless through the watcher: layers update dynamically without requiring manual intervention. 63 | 64 | - **Enhanced Performance:** 65 | Finalization logic ensures resources are freed up appropriately, reducing GPU memory usage and preventing lingering artifacts. 66 | 67 | - **Cleaner API Usage:** 68 | Developers using the package can benefit from a clear and declarative API for defining and rendering layers, without worrying about setup or teardown details. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Mostafa Gamal - Wakeb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Theme from 'vitepress/theme' 2 | import './styles.css' 3 | 4 | export default Theme -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap'); 2 | 3 | :root:where(:lang(fa)) { 4 | --vp-font-family-base: 5 | 'Vazirmatn', 'Inter', ui-sans-serif, system-ui, sans-serif, 6 | 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; 7 | } 8 | 9 | :root { 10 | --vp-home-hero-name-color: transparent; 11 | --vp-home-hero-name-background: -webkit-linear-gradient( 12 | 120deg, 13 | #bd34fe 30%, 14 | #41d1ff 15 | ); 16 | --vp-home-hero-image-background-image: linear-gradient( 17 | -45deg, 18 | #bd34fe 50%, 19 | #47caff 50% 20 | ); 21 | --vp-home-hero-image-filter: blur(44px); 22 | } 23 | 24 | @media (min-width: 640px) { 25 | :root { 26 | --vp-home-hero-image-filter: blur(56px); 27 | } 28 | } 29 | 30 | @media (min-width: 960px) { 31 | :root { 32 | --vp-home-hero-image-filter: blur(68px); 33 | } 34 | } 35 | 36 | .VPHero .VPImage { 37 | filter: drop-shadow(-2px 4px 6px rgba(0, 0, 0, 0.2)); 38 | padding: 18px; 39 | } 40 | 41 | .content-container { 42 | max-width: 750px !important; 43 | } 44 | 45 | /* used in reference/default-theme-search */ 46 | img[src='/search.png'] { 47 | width: 100%; 48 | aspect-ratio: 1 / 1; 49 | } -------------------------------------------------------------------------------- /docs/examples/column-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Column Layer Example 8 | 9 | Here’s an example that demonstrates the **Column Layer** visualizing aggregated data: 10 | 11 | ```vue 12 | 18 | 19 | 44 | ``` 45 | 46 | 47 | 50 | 59 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /docs/examples/contour-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Contour Layer Example 8 | 9 | Here’s an example that demonstrates how to use the **Contour Layer** to render contours on a map: 10 | 11 | ```vue 12 | 16 | 17 | 45 | 46 | 49 | ``` 50 | 51 | 52 | 53 | 62 | 76 | 77 | 78 | 79 | ```` -------------------------------------------------------------------------------- /docs/examples/icon-data/location-icon-atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/docs/examples/icon-data/location-icon-atlas.png -------------------------------------------------------------------------------- /docs/examples/icon-data/location-icon-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "marker-1": { 3 | "x": 0, 4 | "y": 0, 5 | "width": 128, 6 | "height": 128, 7 | "anchorY": 128 8 | }, 9 | "marker-2": { 10 | "x": 128, 11 | "y": 0, 12 | "width": 128, 13 | "height": 128, 14 | "anchorY": 128 15 | }, 16 | "marker-3": { 17 | "x": 256, 18 | "y": 0, 19 | "width": 128, 20 | "height": 128, 21 | "anchorY": 128 22 | }, 23 | "marker-4": { 24 | "x": 384, 25 | "y": 0, 26 | "width": 128, 27 | "height": 128, 28 | "anchorY": 128 29 | }, 30 | "marker-5": { 31 | "x": 0, 32 | "y": 128, 33 | "width": 128, 34 | "height": 128, 35 | "anchorY": 128 36 | }, 37 | "marker-6": { 38 | "x": 128, 39 | "y": 128, 40 | "width": 128, 41 | "height": 128, 42 | "anchorY": 128 43 | }, 44 | "marker-7": { 45 | "x": 256, 46 | "y": 128, 47 | "width": 128, 48 | "height": 128, 49 | "anchorY": 128 50 | }, 51 | "marker-8": { 52 | "x": 384, 53 | "y": 128, 54 | "width": 128, 55 | "height": 128, 56 | "anchorY": 128 57 | }, 58 | "marker-9": { 59 | "x": 0, 60 | "y": 256, 61 | "width": 128, 62 | "height": 128, 63 | "anchorY": 128 64 | }, 65 | "marker-10": { 66 | "x": 128, 67 | "y": 256, 68 | "width": 128, 69 | "height": 128, 70 | "anchorY": 128 71 | }, 72 | "marker-20": { 73 | "x": 256, 74 | "y": 256, 75 | "width": 128, 76 | "height": 128, 77 | "anchorY": 128 78 | }, 79 | "marker-30": { 80 | "x": 384, 81 | "y": 256, 82 | "width": 128, 83 | "height": 128, 84 | "anchorY": 128 85 | }, 86 | "marker-40": { 87 | "x": 0, 88 | "y": 384, 89 | "width": 128, 90 | "height": 128, 91 | "anchorY": 128 92 | }, 93 | "marker-50": { 94 | "x": 128, 95 | "y": 384, 96 | "width": 128, 97 | "height": 128, 98 | "anchorY": 128 99 | }, 100 | "marker-60": { 101 | "x": 256, 102 | "y": 384, 103 | "width": 128, 104 | "height": 128, 105 | "anchorY": 128 106 | }, 107 | "marker-70": { 108 | "x": 384, 109 | "y": 384, 110 | "width": 128, 111 | "height": 128, 112 | "anchorY": 128 113 | }, 114 | "marker-80": { 115 | "x": 0, 116 | "y": 512, 117 | "width": 128, 118 | "height": 128, 119 | "anchorY": 128 120 | }, 121 | "marker-90": { 122 | "x": 128, 123 | "y": 512, 124 | "width": 128, 125 | "height": 128, 126 | "anchorY": 128 127 | }, 128 | "marker-100": { 129 | "x": 256, 130 | "y": 512, 131 | "width": 128, 132 | "height": 128, 133 | "anchorY": 128 134 | }, 135 | "marker": { 136 | "x": 384, 137 | "y": 512, 138 | "width": 128, 139 | "height": 128, 140 | "anchorY": 128 141 | } 142 | } -------------------------------------------------------------------------------- /docs/examples/icon-layer.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | # Icon Layer Example 13 | 14 | Here’s an example of how to use the **Icon Layer**, rendering icons on a map dynamically: 15 | 16 | ```vue 17 | 26 | 27 | 52 | 53 | 56 | ``` 57 | 58 | 59 | 60 | 69 | 81 | 82 | -------------------------------------------------------------------------------- /docs/examples/index.md: -------------------------------------------------------------------------------- 1 | # Available Examples by Layer 2 | 3 | Explore the interactive examples below to learn how to use different layers in **@vue-deckgl-suite/layers** to build stunning geospatial visualizations. 4 | 5 | ## Layer Examples 6 | 7 | - **[Arc Layer](/examples/arc-layer/):** Draws great arcs (curves) between two points on a map. 8 | - **[GeoJson Layer (Paths)](/examples/geojson-layer-paths/):** Visualizes GeoJSON data with full feature support. 9 | - **[Hexagon Layer](/examples/hexagon-layer/):** Aggregates scattered data points into hexagonal grids. 10 | - **[Grid Layer](/examples/grid-layer/):** Organizes and visualizes points within rectangular grids. 11 | - **[Column Layer](/examples/column-layer/):** Visualizes data as vertical cylinders, useful for 3D geospatial data 12 | representation. 13 | - **[Path Layer](/examples/path-layer/):** Plots point-to-point paths or line segments on a map. 14 | - **[Trips Layer](/examples/trips-layer/):** Animates trips or movement data over time. 15 | - **[Icon Layer](/examples/icon-layer/):** Renders icons or images at specific geospatial positions. 16 | - **[Point Cloud Layer](/examples/point-cloud-layer/):** Renders 3D point clouds, typically used for visualizing large 17 | sets of points in space. 18 | - **[Polygon Layer](/examples/polygon-layer/):** Renders filled or stroked polygons, useful for visualizing areas, 19 | boundaries, or other polygon-based data. 20 | - **[Contour Layer](/examples/contour-layer/):** Generates contour lines or filled contour regions, useful for visualizing 21 | elevation or density data. 22 | - **[Scatterplot Layer](/examples/scatterplot-layer/):** Renders scatter points with options to customize size, color, and 23 | opacity for data visualization. 24 | - **[WMS Layer](/examples/wms-layer/):** Displays map tiles from a Web Map Service endpoint. 25 | 26 | Learn more about each layer by visiting its dedicated page. 27 | 28 | -------------------------------------------------------------------------------- /docs/examples/path-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Path Example 8 | 9 | Here’s an example that demonstrates how to use the **Path Layer** to render paths on a map: 10 | 11 | ```vue 12 | 18 | 19 | 38 | 39 | 42 | ``` 43 | 44 | 45 | 53 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/examples/point-cloud-layer.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # Point Cloud Example 9 | 10 | Here’s an example that demonstrates how to use the **Point Cloud Layer** to render a 3D point cloud on a map: 11 | 12 | ```vue 13 | 20 | 21 | 45 | ``` 46 | 47 | 48 | 49 | 58 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /docs/examples/polygon-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Polygon Layer Example 8 | Here’s an example that demonstrates how to use the **Polygon Layer**: 9 | 10 | --- 11 | 12 | ```vue 13 | 17 | 18 | 41 | 42 | 45 | ``` 46 | 47 | 48 | 51 | 60 | 71 | 72 | -------------------------------------------------------------------------------- /docs/examples/scatterplot-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Scatterplot Layer Example 8 | 9 | Here’s an example that demonstrates how to use the **Scatterplot Layer** to render points on a map: 10 | 11 | ```vue 12 | 16 | 17 | 44 | 45 | 48 | ``` 49 | 50 | 51 | 52 | 61 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /docs/examples/trips-layer.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | # Trips Example 9 | 10 | Here’s an example that demonstrates how to use the **Trips Layer** to render animated trajectories on a map: 11 | 12 | ```vue 13 | 19 | 20 | 38 | 39 | 42 | ``` 43 | 44 | 45 | 46 | 54 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/examples/wms-layer.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | # WMS Layer Example 10 | 11 | Here’s an example that demonstrates how to integrate the **WMS Layer**: 12 | 13 | ```vue 14 | 20 | 21 | 33 | 34 | 37 | ``` 38 | 39 | 40 | 41 | 49 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /docs/google-maps/index.md: -------------------------------------------------------------------------------- 1 | # @vue-deckgl-suite/google-maps 2 | 3 | The `@vue-deckgl-suite/google-maps` package provides powerful Vue components to integrate **Google** maps with **Deck.gl** layers, enabling you to build high-performance interactive geospatial visualizations. These components simplify handling map and GoogleMapsOverlay for your applications, leveraging both **Deck.gl** and **Google** capabilities. 4 | 5 | Developers using only the **`@vue-deckgl-suite/google-maps`** package can define Deck.gl layers as **ES6 class instances** and pass them to the `layers` prop of the `DeckGL` component. This is the default behavior and requires familiarity with the Deck.gl API. 6 | 7 | ## Available Components 8 | 9 | ### 1. **Map** 10 | 11 | The `Map` component allows you to define and configure interactive **Google Maps** with ease. 12 | **[Learn more about the Map component →](./google-basemap/)** 13 | 14 | 15 | 16 | ### 2. **DeckGL** 17 | 18 | The `DeckGL` component enables the integration of **Deck.gl** layers as overlays within a **Google Maps**. 19 | **[Learn more about the DeckGL component →](./google-overlay/)** -------------------------------------------------------------------------------- /docs/guide/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | 4 | ## Introduction 5 | The `@vue-deckgl-suite` is a monorepo containing packages for integrating **Deck.gl** with Vue 3. It provides essential layers (`@vue-deckgl-suite/layers`) and base map integration through a separate basemap provider package, such as `@vue-deckgl-suite/maplibre`. In the future, support for **Google Maps**, **Mapbox**, or **ArcGIS** will be available to suit your specific basemap provider. 6 | ## Prerequisites 7 | Make sure your environment meets the following requirements: 8 | - **Node.js**: >= 18.x 9 | - **npm**: >= 9.x (or use **Yarn** or **pnpm**) 10 | 11 | ## Installation Steps 12 | ### 1. Install Base Packages 13 | First, install the core packages needed for your project. Use `npm`, `yarn`, or `pnpm`: 14 | ``` bash 15 | npm install @vue-deckgl-suite/layers @vue-deckgl-suite/maplibre 16 | ``` 17 | or with Yarn: 18 | ``` bash 19 | yarn add @vue-deckgl-suite/layers @vue-deckgl-suite/maplibre 20 | ``` 21 | or with pnpm: 22 | ``` bash 23 | pnpm add @vue-deckgl-suite/layers @vue-deckgl-suite/maplibre 24 | ``` 25 | ### 2. Install Peer Dependencies 26 | Both packages rely on peer dependencies. Before proceeding, install the following dependencies: 27 | For `@vue-deckgl-suite/layers`: 28 | ``` bash 29 | npm install vue @deck.gl/core @deck.gl/layers @deck.gl/geo-layers @deck.gl/aggregation-layers 30 | ``` 31 | For `@vue-deckgl-suite/maplibre`: 32 | ``` bash 33 | npm install vue @deck.gl/core @deck.gl/mapbox maplibre-gl 34 | ``` 35 | > **Note**: Depending on your basemap provider, replace `maplibre-gl` and `@deck.gl/mapbox` with corresponding dependencies when other basemap packages (e.g., Google Maps, Mapbox, or ArcGIS) are supported in the future. 36 | > 37 | 38 | ### 3. Quick Usage 39 | After installation, import and use the components and basemap provider in your Vue project: 40 | #### Example: Using a Layer with MapLibre 41 | ``` javascript 42 | // main.ts or main.js 43 | import { createApp } from 'vue'; 44 | import App from './App.vue'; 45 | import { Map } from '@vue-deckgl-suite/maplibre'; 46 | import { ArcLayer } from '@vue-deckgl-suite/layers'; 47 | 48 | const app = createApp(App); 49 | 50 | // Register components 51 | app.component('MaplibreMap', Map); 52 | app.component('ArcLayer', ArcLayer); 53 | 54 | app.mount('#app'); 55 | ``` 56 | #### Local Registration in a Vue Component: 57 | ``` javascript 58 | 62 | 63 | 69 | 70 | ``` 71 | Add CSS 72 | ```scss 73 | @import 'maplibre-gl/dist/maplibre-gl.css'; 74 | 75 | ``` 76 | ## Notes 77 | - To switch to a different basemap provider in the future (e.g., Google Maps, Mapbox, or ArcGIS), you will need to install the corresponding provider package instead of `@vue-deckgl-suite/maplibre` and update its dependencies. 78 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # https://vitepress.dev/reference/default-theme-home-page 3 | layout: home 4 | 5 | hero: 6 | name: "@VueDeckglSuite" 7 | text: "A vue wrapper for Deck.gl." 8 | tagline: "Deck.gl meets Vue: Simple geospatial rendering" 9 | image: ./visgl-logo-light.png 10 | actions: 11 | - theme: brand 12 | text: Guide 13 | link: /guide/introduction 14 | - theme: alt 15 | text: Examples 16 | link: /examples 17 | 18 | features: 19 | - icon: 🛠️ 20 | title: Modular Design 21 | details: Use the pieces you need for your project—choose between flexible ES6 instance-based configurations or Vue's declarative syntax. 22 | - icon: 🌍 23 | title: Multi-Basemap Support 24 | details: Seamlessly integrate components for various base map providers like MapLibre and planned compatibility for Google Maps, Mapbox, and beyond.. 25 | 26 | - icon: 🧩 27 | title: Declarative Syntax 28 | details: Simplify layer management by creating Deck.gl layers as Vue child components, aligning with Vue's component-based architecture. 29 | 30 | - icon: 🦾 31 | title: Vue 3 and TypeScript Support 32 | details: Built from the ground up for Vue 3, with full TypeScript support to enhance developer productivity and maintainability. 33 | --- 34 | 35 | -------------------------------------------------------------------------------- /docs/layers/icon-data/location-icon-atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/docs/layers/icon-data/location-icon-atlas.png -------------------------------------------------------------------------------- /docs/layers/icon-data/location-icon-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "marker-1": { 3 | "x": 0, 4 | "y": 0, 5 | "width": 128, 6 | "height": 128, 7 | "anchorY": 128 8 | }, 9 | "marker-2": { 10 | "x": 128, 11 | "y": 0, 12 | "width": 128, 13 | "height": 128, 14 | "anchorY": 128 15 | }, 16 | "marker-3": { 17 | "x": 256, 18 | "y": 0, 19 | "width": 128, 20 | "height": 128, 21 | "anchorY": 128 22 | }, 23 | "marker-4": { 24 | "x": 384, 25 | "y": 0, 26 | "width": 128, 27 | "height": 128, 28 | "anchorY": 128 29 | }, 30 | "marker-5": { 31 | "x": 0, 32 | "y": 128, 33 | "width": 128, 34 | "height": 128, 35 | "anchorY": 128 36 | }, 37 | "marker-6": { 38 | "x": 128, 39 | "y": 128, 40 | "width": 128, 41 | "height": 128, 42 | "anchorY": 128 43 | }, 44 | "marker-7": { 45 | "x": 256, 46 | "y": 128, 47 | "width": 128, 48 | "height": 128, 49 | "anchorY": 128 50 | }, 51 | "marker-8": { 52 | "x": 384, 53 | "y": 128, 54 | "width": 128, 55 | "height": 128, 56 | "anchorY": 128 57 | }, 58 | "marker-9": { 59 | "x": 0, 60 | "y": 256, 61 | "width": 128, 62 | "height": 128, 63 | "anchorY": 128 64 | }, 65 | "marker-10": { 66 | "x": 128, 67 | "y": 256, 68 | "width": 128, 69 | "height": 128, 70 | "anchorY": 128 71 | }, 72 | "marker-20": { 73 | "x": 256, 74 | "y": 256, 75 | "width": 128, 76 | "height": 128, 77 | "anchorY": 128 78 | }, 79 | "marker-30": { 80 | "x": 384, 81 | "y": 256, 82 | "width": 128, 83 | "height": 128, 84 | "anchorY": 128 85 | }, 86 | "marker-40": { 87 | "x": 0, 88 | "y": 384, 89 | "width": 128, 90 | "height": 128, 91 | "anchorY": 128 92 | }, 93 | "marker-50": { 94 | "x": 128, 95 | "y": 384, 96 | "width": 128, 97 | "height": 128, 98 | "anchorY": 128 99 | }, 100 | "marker-60": { 101 | "x": 256, 102 | "y": 384, 103 | "width": 128, 104 | "height": 128, 105 | "anchorY": 128 106 | }, 107 | "marker-70": { 108 | "x": 384, 109 | "y": 384, 110 | "width": 128, 111 | "height": 128, 112 | "anchorY": 128 113 | }, 114 | "marker-80": { 115 | "x": 0, 116 | "y": 512, 117 | "width": 128, 118 | "height": 128, 119 | "anchorY": 128 120 | }, 121 | "marker-90": { 122 | "x": 128, 123 | "y": 512, 124 | "width": 128, 125 | "height": 128, 126 | "anchorY": 128 127 | }, 128 | "marker-100": { 129 | "x": 256, 130 | "y": 512, 131 | "width": 128, 132 | "height": 128, 133 | "anchorY": 128 134 | }, 135 | "marker": { 136 | "x": 384, 137 | "y": 512, 138 | "width": 128, 139 | "height": 128, 140 | "anchorY": 128 141 | } 142 | } -------------------------------------------------------------------------------- /docs/layers/index.md: -------------------------------------------------------------------------------- 1 | # @vue-deckgl-suite/layers 2 | 3 | 4 | When using both **`@vue-deckgl-suite/maplibre`** and **`@vue-deckgl-suite/layers`**, you can define Deck.gl layers as declarative Vue components inside the `DeckGL` overlay. This approach simplifies the integration process and aligns with Vue's component-based design principles. 5 | 6 | ## Example: Declarative Syntax for a Hexagon Layer 7 | 8 | ```vue 9 | 26 | ``` 27 | 28 | In this example: 29 | - The `id` and props like `data`, `get-position`, and `radius` are passed declaratively to the `HexagonLayer` component. 30 | - The declarative syntax improves readability and developer productivity when working within Vue applications. 31 | 32 | 33 | ## Available Layers 34 | 35 | Here is a list of the layers available in `@vue-deckgl-suite/layers`. Each provides unique functionality for various geospatial visualization use cases. 36 | 37 | - **[Arc Layer](/layers/arc-layer/):** Draws great arcs (curves) between two points on a map. 38 | - **[GeoJson Layer](/layers/geojson-layer/):** Visualizes GeoJSON data with full feature support. 39 | - **[Hexagon Layer](/layers/hexagon-layer/):** Aggregates scattered data points into hexagonal grids. 40 | - **[Grid Layer](/layers/grid-layer/):** Organizes and visualizes points within rectangular grids. 41 | - **[Column Layer](/layers/column-layer/):** Visualizes data as vertical cylinders, useful for 3D geospatial data 42 | representation. 43 | - **[Path Layer](/layers/path-layer/):** Plots point-to-point paths or line segments on a map. 44 | - **[Trips Layer](/layers/trips-layer/):** Animates trips or movement data over time. 45 | - **[Icon Layer](/layers/icon-layer/):** Renders icons or images at specific geospatial positions. 46 | - **[Point Cloud Layer](/layers/point-cloud-layer/):** Renders 3D point clouds, typically used for visualizing large 47 | sets of points in space. 48 | - **[Polygon Layer](/layers/polygon-layer/):** Renders filled or stroked polygons, useful for visualizing areas, 49 | boundaries, or other polygon-based data. 50 | - **[Contour Layer](/layers/contour-layer/):** Generates contour lines or filled contour regions, useful for visualizing 51 | elevation or density data. 52 | 53 | - **[Scatterplot Layer](/layers/scatterplot-layer/):** Renders scatter points with options to customize size, color, and 54 | opacity for data visualization. 55 | - **[WMS Layer](/layers/wms-layer/):** Displays map tiles from a Web Map Service endpoint. 56 | 57 | Learn more about each layer by visiting its dedicated page. -------------------------------------------------------------------------------- /docs/maplibre/index.md: -------------------------------------------------------------------------------- 1 | # @vue-deckgl-suite/maplibre 2 | 3 | The `@vue-deckgl-suite/maplibre` package provides powerful Vue components to integrate **MapLibre** maps with **Deck.gl** layers, enabling you to build high-performance interactive geospatial visualizations. These components simplify handling map and MapboxOverlay for your applications, leveraging both **Deck.gl** and **MapLibre** capabilities. 4 | 5 | Developers using only the **`@vue-deckgl-suite/maplibre`** package can define Deck.gl layers as **ES6 class instances** and pass them to the `layers` prop of the `DeckGL` component. This is the default behavior and requires familiarity with the Deck.gl API. 6 | 7 | ## Available Components 8 | 9 | ### 1. **Map** 10 | 11 | The `Map` component allows you to define and configure interactive **MapLibre** maps with ease. 12 | **[Learn more about the Map component →](./maplibre-basemap/)** 13 | 14 | 15 | 16 | ### 2. **DeckGL** 17 | 18 | The `DeckGL` component enables the integration of **Deck.gl** layers as overlays within a **MapLibre** map. 19 | **[Learn more about the DeckGL component →](./mapbox-overlay/)** -------------------------------------------------------------------------------- /docs/public/visgl-logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/docs/public/visgl-logo-light.png -------------------------------------------------------------------------------- /docs/public/wakeb-logo-dark-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/docs/public/wakeb-logo-dark-mode.png -------------------------------------------------------------------------------- /docs/public/wakeb-logo-light-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/docs/public/wakeb-logo-light-mode.png -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/@lerna-lite/cli/schemas/lerna-schema.json", 3 | "version": "0.1.0-alpha.0", 4 | "useWorkspaces": true 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wakeb-geo-suite-monorepo", 3 | "private": true, 4 | "version": "1.0.0-beta.4", 5 | "author": { 6 | "name": "Mostafa Gamal", 7 | "email": "mostafagamal99418@gmail.com" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/MostafaGamalSayed/vue-deck.gl-suite.git" 12 | }, 13 | "type": "module", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@lerna-lite/changed": "^3.12.0", 17 | "@lerna-lite/cli": "^3.12.0", 18 | "@lerna-lite/exec": "^3.12.0", 19 | "@lerna-lite/list": "^3.12.0", 20 | "@lerna-lite/publish": "^3.12.0", 21 | "@lerna-lite/run": "^3.12.0", 22 | "@lerna-lite/watch": "^3.12.0", 23 | "vitepress": "^1.6.3" 24 | }, 25 | "workspaces": [ 26 | "packages/*" 27 | ], 28 | "scripts": { 29 | "docs:dev": "vitepress dev docs", 30 | "docs:build": "vitepress build docs", 31 | "docs:preview": "vitepress preview docs" 32 | } 33 | } -------------------------------------------------------------------------------- /packages/google-maps/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | end_of_line = lf 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /packages/google-maps/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /packages/google-maps/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | 32 | -------------------------------------------------------------------------------- /packages/google-maps/.prettierrc.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "$schema": "https://json.schemastore.org/prettierrc", 4 | "semi": false, 5 | "singleQuote": true, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /packages/google-maps/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "dbaeumer.vscode-eslint", 5 | "EditorConfig.EditorConfig", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/google-maps/README.md: -------------------------------------------------------------------------------- 1 | # @vue-deckgl-suite/maplibre 2 | 3 | The **[@vue-deckgl-suite](https://github.com/MostafaGamalSayed/vue-deck.gl-suite)** monorepo enables seamless integration between **Deck.gl** and Vue-based applications for high-performance geospatial visualizations. Among its modular packages, the `@vue-deckgl-suite/google-maps` package provides powerful Vue components for integrating **Google** maps with Deck.gl layers. 4 | 5 | With this package, developers can: 6 | - Render complex **Deck.gl** visualizations on top of interactive basemaps powered by **Google Maps**. 7 | - Leverage **Vue's declarative syntax** to create clean and scalable geospatial applications. 8 | 9 | --- 10 | 11 | ## Documentation 12 | 13 | Comprehensive documentation, guides, and examples are available at the **[@vue-deckgl-suite documentation →](https://vue-deckgl-suite.wakeb.tech/)**. 14 | 15 | --- 16 | 17 | ## Features 18 | 19 | - 🗺 **Google Basemap Support**: Effortlessly set up basemaps using Google Maps. 20 | - 📊 **Deck.gl Overlays**: Add and manage data visualization layers with full Deck.gl support. 21 | - 🔄 **Declarative or Programmatic Layer Rendering**: Choose between declarative Vue components for layers or programmatic ES6 instances. 22 | 23 | --- 24 | 25 | ## Installation 26 | 27 | ### 1. Install the Package 28 | ```bash 29 | # With npm 30 | npm install @vue-deckgl-suite/google-maps 31 | 32 | # Or with yarn 33 | yarn add @vue-deckgl-suite/google-maps 34 | 35 | # Or with pnpm 36 | pnpm add @vue-deckgl-suite/google-maps 37 | ``` 38 | 39 | ### 2. Install Peer Dependencies 40 | This package requires the following `deck.gl` dependencies: 41 | ```bash 42 | npm install @deck.gl/core @deck.gl/layers @deck.gl/geo-layers @deck.gl/aggregation-layers @deck.gl/google-maps 43 | ``` 44 | 45 | --- 46 | 47 | ## Example Usage 48 | 49 | ### Using Only `@vue-deckgl-suite/google-maps` 50 | ```vue 51 | 67 | 68 | 82 | ``` 83 | 84 | --- 85 | 86 | ### Using `@vue-deckgl-suite/google-maps` with `@vue-deckgl-suite/layers` 87 | By combining `@vue-deckgl-suite/google-maps` with `@vue-deckgl-suite/layers`, you can utilize **Vue's declarative syntax** to define Deck.gl layers as Vue components. This approach simplifies the process of managing and rendering layers. 88 | 89 | ```vue 90 | 94 | 95 | 118 | ``` 119 | 120 | In this example: 121 | - **`Map`**: Provides the basemap using **MapLibre GL**. 122 | - **`ColumnLayer`**: Adds a ColumnLayer layer declaratively through the `@vue-deckgl-suite/layers` package. 123 | - **Props**: The layer component's props map directly to its Deck.gl ES6 API equivalent, making configuration concise and Vue-friendly. 124 | 125 | --- 126 | 127 | With `@vue-deckgl-suite/google-maps` and `@vue-deckgl-suite/layers`, developers can easily build highly interactive and visually dynamic geospatial applications using Vue's declarative component patterns alongside Deck.gl's rendering power. -------------------------------------------------------------------------------- /packages/google-maps/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/google-maps/eslint.config.ts: -------------------------------------------------------------------------------- 1 | import pluginVue from 'eslint-plugin-vue' 2 | import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' 3 | import skipFormatting from '@vue/eslint-config-prettier/skip-formatting' 4 | 5 | // To allow more languages other than `ts` in `.vue` files, uncomment the following lines: 6 | // import { configureVueProject } from '@vue/eslint-config-typescript' 7 | // configureVueProject({ scriptLangs: ['ts', 'tsx'] }) 8 | // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup 9 | 10 | export default defineConfigWithVueTs( 11 | { 12 | name: 'app/files-to-lint', 13 | files: ['**/*.{ts,mts,tsx,vue}'], 14 | }, 15 | 16 | { 17 | name: 'app/files-to-ignore', 18 | ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'], 19 | }, 20 | 21 | pluginVue.configs['flat/essential'], 22 | vueTsConfigs.recommended, 23 | skipFormatting, 24 | ) 25 | -------------------------------------------------------------------------------- /packages/google-maps/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/google-maps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue-deckgl-suite/google-maps", 3 | "description": "A Vue 3 package integrating Deck.gl with Google Maps for geospatial visualizations", 4 | "version": "1.0.0-beta.4", 5 | "author": { 6 | "name": "Mostafa Gamal", 7 | "email": "mostafagamal99418@gmail.com" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/MostafaGamalSayed/vue-deck.gl-suite.git" 12 | }, 13 | "keywords": [ 14 | "deckgl", 15 | "geo-layers", 16 | "aggregation-layers", 17 | "deckgl vue wrapper", 18 | "wrapper", 19 | "google maps", 20 | "google", 21 | "map layers", 22 | "map", 23 | "vue3", 24 | "Vue.js", 25 | "layers", 26 | "components" 27 | ], 28 | "publishConfig": { 29 | "access": "public" 30 | }, 31 | "type": "module", 32 | "main": "dist/vue-deckgl-suite-google-maps.umd.js", 33 | "module": "dist/vue-deckgl-suite-google-maps.es.js", 34 | "types": "dist/main.d.ts", 35 | "web-types": "dist/web-types.json", 36 | "files": [ 37 | "dist/**/*" 38 | ], 39 | "scripts": { 40 | "dev": "vite", 41 | "build": "run-p type-check \"build-only {@}\" --", 42 | "preview": "vite preview", 43 | "build-only": "vite build && vue-docgen-web-types --configFile web-types.config.cjs", 44 | "type-check": "vue-tsc --build", 45 | "lint": "eslint . --fix", 46 | "format": "prettier --write src/" 47 | }, 48 | "dependencies": { 49 | "@googlemaps/js-api-loader": "^1.16.8", 50 | "@googlemaps/markerclusterer": "^2.5.3" 51 | }, 52 | "devDependencies": { 53 | "@deck.gl/core": "^9.1.8", 54 | "@deck.gl/google-maps": "^9.1.8", 55 | "@tsconfig/node22": "^22.0.0", 56 | "@types/node": "^22.13.1", 57 | "@types/google.maps": "^3.58.1", 58 | "@vitejs/plugin-vue": "^5.2.1", 59 | "@vue/eslint-config-prettier": "^10.1.0", 60 | "@vue/eslint-config-typescript": "^14.3.0", 61 | "@vue/tsconfig": "^0.7.0", 62 | "eslint": "^9.18.0", 63 | "eslint-plugin-vue": "^9.32.0", 64 | "jiti": "^2.4.2", 65 | "npm-run-all2": "^7.0.2", 66 | "prettier": "^3.4.2", 67 | "typescript": "~5.7.3", 68 | "vite": "^6.0.11", 69 | "vite-plugin-dts": "^4.5.0", 70 | "vite-plugin-vue-devtools": "^7.7.1", 71 | "vue": "^3.5.13", 72 | "vue-docgen-web-types": "^0.1.8", 73 | "vue-tsc": "^2.2.0" 74 | }, 75 | "peerDependencies": { 76 | "@deck.gl/core": "^9.1.8", 77 | "@deck.gl/google-maps": "^9.1.8", 78 | "vue": "^3.5.13" 79 | }, 80 | "engines": { 81 | "node": ">=18" 82 | }, 83 | "gitHead": "6748997e3584871bafea9f3d997dac136d4e8563" 84 | } 85 | -------------------------------------------------------------------------------- /packages/google-maps/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/packages/google-maps/public/favicon.ico -------------------------------------------------------------------------------- /packages/google-maps/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Map } from './map.component.ts' 2 | export { default as DeckGL } from './overlay.component.ts' 3 | 4 | -------------------------------------------------------------------------------- /packages/google-maps/src/lib/overlay.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { type MapboxOverlayProps } from '@deck.gl/mapbox' 3 | import { Deck } from '@deck.gl/core' 4 | import type { GoogleMapsOverlayProps } from '@deck.gl/google-maps' 5 | 6 | export const overlayProps: ComponentPropsOptions = { 7 | // Add props explicitly defined in MapboxOverlayProps 8 | interleaved: { 9 | type: Boolean as PropType, 10 | default: false, 11 | }, 12 | beforeId: { 13 | type: String as PropType, 14 | default: undefined, 15 | }, 16 | id: { 17 | type: String, 18 | default: 'deckgl-overlay', 19 | }, 20 | /** Additional CSS styles for the canvas. */ 21 | style: { 22 | type: Object as PropType, 23 | default: Deck.defaultProps.style, 24 | }, 25 | 26 | /** Controls the resolution of drawing buffer used for rendering. 27 | * @default `true` (use browser devicePixelRatio) 28 | */ 29 | useDevicePixels: { 30 | type: [Boolean, Number] as PropType, 31 | default: Deck.defaultProps.useDevicePixels, 32 | }, 33 | /** Extra pixels around the pointer to include while picking. 34 | * @default `0` 35 | */ 36 | pickingRadius: { 37 | type: Number as PropType, 38 | default: Deck.defaultProps.pickingRadius, 39 | }, 40 | /** WebGL parameters to be set before each frame is rendered. */ 41 | parameters: { 42 | type: Object as PropType, 43 | default: Deck.defaultProps.parameters, 44 | }, 45 | /** If supplied, will be called before a layer is drawn to determine whether it should be rendered. */ 46 | layerFilter: { 47 | type: Function as unknown as PropType, 48 | default: Deck.defaultProps.layerFilter, 49 | }, 50 | /** 51 | * The array of Layer instances to be rendered. 52 | * Nested arrays are accepted, as well as falsy values (`null`, `false`, `undefined`) 53 | */ 54 | layers: { 55 | type: Array as PropType, 56 | default: Deck.defaultProps.layers, 57 | }, 58 | /** The array of effects to be rendered. A lighting effect will be added if an empty array is supplied. */ 59 | effects: { 60 | type: Array as PropType, 61 | default: Deck.defaultProps.effects, 62 | }, 63 | /** A single View instance, or an array of `View` instances. 64 | * @default `new MapView()` 65 | */ 66 | views: { 67 | type: [Object, Array] as PropType, 68 | default: Deck.defaultProps.views, 69 | }, 70 | /** Allow browser default touch actions. 71 | * @default `'none'` 72 | */ 73 | touchAction: { 74 | type: String as PropType, 75 | default: Deck.defaultProps.touchAction, 76 | }, 77 | /** Set Hammer.js recognizer options for gesture recognition. */ 78 | eventRecognizerOptions: { 79 | type: Object as PropType, 80 | default: Deck.defaultProps.eventRecognizerOptions, 81 | }, 82 | /** A custom callback to retrieve the cursor type. */ 83 | getCursor: { 84 | type: Function as PropType, 85 | default: Deck.defaultProps.getCursor, 86 | }, 87 | /** Callback that takes a hovered-over point and renders a tooltip. */ 88 | getTooltip: { 89 | type: Function as unknown as PropType, 90 | default: Deck.defaultProps.getTooltip, 91 | }, 92 | /** (Debug) Flag to enable WebGL debug mode. Requires importing `@luma.gl/debug`. */ 93 | debug: { 94 | type: Boolean as PropType, 95 | default: Deck.defaultProps.debug, 96 | }, 97 | } 98 | export const overlayPropsKeys: (keyof GoogleMapsOverlayProps)[] = [ 99 | 'interleaved', 100 | 'id', 101 | 'style', 102 | 'useDevicePixels', 103 | 'pickingRadius', 104 | 'parameters', 105 | 'layerFilter', 106 | 'layers', 107 | 'effects', 108 | 'views', 109 | 'touchAction', 110 | 'eventRecognizerOptions', 111 | 'getCursor', 112 | 'getTooltip', 113 | 'debug', 114 | ] 115 | 116 | -------------------------------------------------------------------------------- /packages/google-maps/src/main.ts: -------------------------------------------------------------------------------- 1 | import { type App, type Plugin } from 'vue' 2 | 3 | // Import vue components 4 | import * as components from '@/components' 5 | 6 | // install function executed by Vue.use() 7 | const install: Exclude = function installVueDeckglSuiteGoogleMaps(app: App) { 8 | Object.entries(components).forEach(([componentName, component]) => { 9 | app.component(componentName, component) 10 | }) 11 | } 12 | 13 | // Create module definition for Vue.use() 14 | export default install 15 | 16 | // To allow individual component use, export components 17 | // each can be registered via Vue.component() 18 | export * from '@/components' 19 | -------------------------------------------------------------------------------- /packages/google-maps/src/shared/constants.ts: -------------------------------------------------------------------------------- 1 | import { GoogleMapsOverlay } from '@deck.gl/google-maps' 2 | import type { InjectionKey, Ref } from "vue"; 3 | 4 | export const googleOverlayInstanceSymbol = Symbol('googleOverlayInstanceSymbol') as InjectionKey> 5 | 6 | export const mapSymbol: InjectionKey> = Symbol("map"); 7 | export const apiSymbol: InjectionKey> = Symbol("api"); 8 | 9 | /** 10 | * Utilitary flag for components that need to know the map 11 | * was fully loaded (including its tiles) to decide their behavior 12 | */ 13 | export const mapTilesLoadedSymbol: InjectionKey> = Symbol("mapTilesLoaded"); 14 | 15 | -------------------------------------------------------------------------------- /packages/google-maps/src/types.ts: -------------------------------------------------------------------------------- 1 | export type IControlPosition = keyof typeof google.maps.ControlPosition; 2 | -------------------------------------------------------------------------------- /packages/google-maps/src/utils/genDeckOpts.ts: -------------------------------------------------------------------------------- 1 | export function genDeckOpts(props: Partial, validProps: (keyof T)[]): Partial { 2 | for (const opt of Object.keys(props) as Array) { 3 | if (props[opt] === undefined || !validProps.includes(opt)) { 4 | delete props[opt] 5 | } 6 | } 7 | 8 | return props 9 | } 10 | -------------------------------------------------------------------------------- /packages/google-maps/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.ts"], 4 | "exclude": ["src/**/__tests__/*", "node_modules/**", "dist", "../../node_modules"], 5 | "compilerOptions": { 6 | "baseUrl" : ".", 7 | "target" : "ESNext", 8 | "useDefineForClassFields": true, 9 | "module" : "ESNext", 10 | "moduleResolution" : "Node", 11 | "strict" : true, 12 | "jsx" : "preserve", 13 | "sourceMap" : true, 14 | "resolveJsonModule" : true, 15 | "esModuleInterop" : true, 16 | "isolatedModules" : true, 17 | "newLine" : "lf", 18 | "tsBuildInfoFile" : "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 19 | "skipLibCheck" : true, 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/google-maps/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/google-maps/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/google-maps/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig, type PluginOption } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | import { resolve } from 'path' 7 | import dtsPlugin from 'vite-plugin-dts' 8 | 9 | // https://vite.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | vue() as PluginOption, 13 | dtsPlugin({ 14 | entryRoot: './src', 15 | insertTypesEntry: true, // Ensure types are included in "exports" in package.json 16 | tsconfigPath: './tsconfig.app.json', // Point explicitly to the correct tsconfig 17 | rollupTypes: true, // Use rollup to bundle declaration files 18 | outDir: 'dist', // Place all declarations in the "dist" folder 19 | }) as PluginOption, 20 | vueDevTools() as PluginOption, 21 | ], 22 | resolve: { 23 | alias: { 24 | '@': fileURLToPath(new URL('./src', import.meta.url)) 25 | }, 26 | }, 27 | build: { 28 | lib: { 29 | entry: resolve(__dirname, 'src/main.ts'), 30 | name: 'VueDeckGLSuiteGoogleMaps', 31 | fileName: (format) => `vue-deckgl-suite-google-maps.${format}.js`, 32 | }, 33 | rollupOptions: { 34 | external: [ 35 | 'vue', 36 | '@deck.gl/core', 37 | '@deck.gl/google-maps', 38 | 39 | ], 40 | output: { 41 | globals: { 42 | vue: 'Vue', 43 | } 44 | } 45 | } 46 | } 47 | 48 | }) 49 | -------------------------------------------------------------------------------- /packages/google-maps/web-types.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | componentsRoot: './src/components', 3 | components: '**/[a-zA-Z]*.(component|layer).ts', 4 | } 5 | -------------------------------------------------------------------------------- /packages/layers/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | end_of_line = lf 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /packages/layers/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /packages/layers/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /packages/layers/.prettierrc.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "$schema": "https://json.schemastore.org/prettierrc", 4 | "semi": false, 5 | "singleQuote": true, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /packages/layers/README.md: -------------------------------------------------------------------------------- 1 | # @vue-deckgl-suite/layers 2 | 3 | The **[@vue-deckgl-suite](https://github.com/MostafaGamalSayed/vue-deck.gl-suite)** monorepo is built to provide a seamless integration of **Deck.gl** and **Vue-based applications**, enabling the development of high-performance geospatial visualizations with ease. It consists of a series of modular packages that work together to support various basemaps and visualization use cases. 4 | 5 | The `@vue-deckgl-suite/layers` package introduces **declarative Vue components** for defining and rendering **Deck.gl** layers. This approach simplifies the process of adding complex geospatial visualizations to your Vue applications, aligning closely with Vue's component-based architecture. 6 | 7 | --- 8 | 9 | ## Important Note: Basemap Package Required 10 | 11 | The `@vue-deckgl-suite/layers` package **must be used along with one of the supported basemap packages** to provide a valid context for rendering Deck.gl visualizations. You can choose one of the following basemap packages: 12 | 13 | 1. [`@vue-deckgl-suite/maplibre`](https://vue-deckgl-suite.wakeb.tech/maplibre/): For rendering basemaps using **MapLibre GL**. 14 | 2. [`@vue-deckgl-suite/google-maps`](https://vue-deckgl-suite.wakeb.tech/google-maps/): For rendering basemaps using **Google Maps**. 15 | 16 | Both basemap packages seamlessly integrate with `@vue-deckgl-suite/layers` to provide an easy-to-use and performant geospatial visualization solution. 17 | 18 | --- 19 | 20 | ## Installation 21 | 22 | Install the `@vue-deckgl-suite/layers` package along with a basemap package of your choice. 23 | 24 | ### 1. Install the Layers Package 25 | ```bash 26 | # With npm 27 | npm install @vue-deckgl-suite/layers 28 | 29 | # Or with yarn 30 | yarn add @vue-deckgl-suite/layers 31 | 32 | # Or with pnpm 33 | pnpm add @vue-deckgl-suite/layers 34 | ``` 35 | 36 | ### 2. Install a Basemap Package 37 | You must also install one of the supported basemap packages depending on your project's requirements. 38 | 39 | #### For MapLibre: 40 | ```bash 41 | # With npm 42 | npm install @vue-deckgl-suite/maplibre maplibre-gl 43 | 44 | # Or with yarn 45 | yarn add @vue-deckgl-suite/maplibre maplibre-gl 46 | 47 | # Or with pnpm 48 | pnpm add @vue-deckgl-suite/maplibre maplibre-gl 49 | ``` 50 | 51 | #### For Google Maps: 52 | ```bash 53 | # With npm 54 | npm install @vue-deckgl-suite/google-maps 55 | 56 | # Or with yarn 57 | yarn add @vue-deckgl-suite/google-maps 58 | 59 | # Or with pnpm 60 | pnpm add @vue-deckgl-suite/google-maps 61 | ``` 62 | 63 | ### 3. Install Peer Dependencies 64 | The `@vue-deckgl-suite/layers` package relies on the following `deck.gl` core dependencies: 65 | 66 | ```bash 67 | npm install @deck.gl/core @deck.gl/layers @deck.gl/geo-layers @deck.gl/aggregation-layers 68 | ``` 69 | 70 | --- 71 | 72 | ## Documentation 73 | 74 | For more information about available layers, supported basemaps, and future integrations, refer to the full documentation of the **[@vue-deckgl-suite](https://vue-deckgl-suite.wakeb.tech/)** package. 75 | 76 | --- 77 | 78 | ## Usage Scenarios 79 | 80 | Depending on the combination of packages and the basemap providers used, you can utilize **declarative Vue syntax** to define Deck.gl layers as child components of the `DeckGL` overlay. Example: 81 | 82 | ```vue 83 | 89 | 90 | 115 | ``` 116 | 117 | With this approach, the **`@vue-deckgl-suite/layers`** package simplifies configuration by allowing each layer to be treated as a standalone Vue component. Props passed to each component map directly to Deck.gl class attributes. 118 | 119 | --- 120 | 121 | For more examples and guides, visit the **[official documentation →](https://vue-deckgl-suite.wakeb.tech)**. -------------------------------------------------------------------------------- /packages/layers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/layers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue-deckgl-suite/layers", 3 | "description": "Provides Deck.gl layers as Vue 3 components for creating interactive and high-performance geospatial visualizations.", 4 | "version": "1.0.0-beta.4", 5 | "author": { 6 | "name": "Mostafa Gamal", 7 | "email": "mostafagamal99418@gmail.com" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/MostafaGamalSayed/vue-deck.gl-suite.git" 12 | }, 13 | "keywords": [ 14 | "deckgl", 15 | "geo-layers", 16 | "aggregation-layers", 17 | "deckgl vue wrapper", 18 | "wrapper", 19 | "maplibre", 20 | "map", 21 | "vue3", 22 | "Vue.js", 23 | "layers", 24 | "components" 25 | ], 26 | "publishConfig": { 27 | "access": "public" 28 | }, 29 | "type": "module", 30 | "main": "dist/vue-deckgl-suite-layers.umd.js", 31 | "module": "dist/vue-deckgl-suite-layers.es.js", 32 | "types": "dist/main.d.ts", 33 | "web-types": "dist/web-types.json", 34 | "files": [ 35 | "dist/**/*", 36 | "src/**/*" 37 | ], 38 | "scripts": { 39 | "dev": "vite", 40 | "build": "run-p type-check \"build-only {@}\" --", 41 | "preview": "vite preview", 42 | "build-only": "vite build && vue-docgen-web-types --configFile web-types.config.cjs", 43 | "type-check": "vue-tsc --build", 44 | "lint": "eslint . --fix", 45 | "format": "prettier --write src/" 46 | }, 47 | "devDependencies": { 48 | "@deck.gl/aggregation-layers": "^9.1.8", 49 | "@deck.gl/core": "^9.1.8", 50 | "@deck.gl/geo-layers": "^9.1.8", 51 | "@deck.gl/layers": "^9.1.8", 52 | "@tsconfig/node22": "^22.0.0", 53 | "@types/node": "^22.10.7", 54 | "@vitejs/plugin-vue": "^5.2.1", 55 | "@vue/eslint-config-prettier": "^10.1.0", 56 | "@vue/eslint-config-typescript": "^14.3.0", 57 | "@vue/tsconfig": "^0.7.0", 58 | "eslint": "^9.18.0", 59 | "eslint-plugin-vue": "^9.32.0", 60 | "jiti": "^2.4.2", 61 | "npm-run-all2": "^7.0.2", 62 | "prettier": "^3.4.2", 63 | "typescript": "~5.7.3", 64 | "vite": "^6.0.11", 65 | "vite-plugin-dts": "^4.5.0", 66 | "vite-plugin-vue-devtools": "^7.7.0", 67 | "vue": "^3.5.13", 68 | "vue-docgen-web-types": "^0.1.8", 69 | "vue-tsc": "^2.2.0" 70 | }, 71 | "peerDependencies": { 72 | "@deck.gl/aggregation-layers": "^9.1.3", 73 | "@deck.gl/core": "^9.1.3", 74 | "@deck.gl/geo-layers": "^9.1.3", 75 | "@deck.gl/layers": "^9.1.3", 76 | "vue": "^3.5.13" 77 | }, 78 | "engines": { 79 | "node": ">=18" 80 | }, 81 | "gitHead": "6748997e3584871bafea9f3d997dac136d4e8563" 82 | } 83 | -------------------------------------------------------------------------------- /packages/layers/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ArcLayer } from '@/components/layers/arc.layer.ts' 2 | export { default as ColumnLayer } from '@/components/layers/column.layer.ts' 3 | export { default as GeoJsonLayer } from '@/components/layers/geojson.layer.ts' 4 | export { default as PathLayer } from '@/components/layers/path.layer.ts' 5 | export { default as TripsLayer } from '@/components/layers/trips.layer.ts' 6 | export { default as WMSLayer } from '@/components/layers/wms.layer.ts' 7 | export { default as HexagonLayer } from '@/components/layers/hexagon.layer.ts' 8 | export { default as IconLayer } from '@/components/layers/icon.layer.ts' 9 | export { default as GridLayer } from '@/components/layers/grid.layer.ts' 10 | export { default as PointCloudLayer } from '@/components/layers/point-cloud.layer.ts' 11 | export { default as PolygonLayer } from '@/components/layers/polygon.layer.ts' 12 | export { default as ContourLayer } from '@/components/layers/contour.layer.ts' 13 | export { default as ScatterplotLayer } from '@/components/layers/scatterplot.layer.ts' 14 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/arc.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { arcLayerProps, arcPropsKeys } from '@/lib/layers/arc.lib.ts' 3 | import { ArcLayer, type ArcLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'ArcLayer', 8 | props: { ...arcLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: ArcLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new ArcLayer(opts), // Layer factory function 14 | props, 15 | arcPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/column.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { columnLayerProps, columnPropsKeys } from '@/lib/layers/column.lib.ts' 3 | import { ColumnLayer, type ColumnLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'ColumnLayer', 8 | props: { ...columnLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: ColumnLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new ColumnLayer(opts), // Layer factory function 14 | props, 15 | columnPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/contour.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { contourLayerProps, contourPropsKeys } from '@/lib/layers/contour.lib.ts' 3 | import { ContourLayer, type ContourLayerProps } from '@deck.gl/aggregation-layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'ContourLayer', 8 | props: { ...contourLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: ContourLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new ContourLayer(opts as any), // Layer factory function 14 | props, 15 | contourPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/geojson.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { geoJsonLayerProps, geoJsonPropsKeys } from '@/lib/layers/geojson.lib.ts' 3 | import { GeoJsonLayer, type GeoJsonLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'GeoJsonLayer', 8 | props: { ...geoJsonLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new GeoJsonLayer(opts), // Layer factory function 14 | props as GeoJsonLayerProps, 15 | geoJsonPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/grid.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { gridLayerProps, gridPropsKeys } from '@/lib/layers/grid.lib.ts' 3 | import { GridLayer, type GridLayerProps } from '@deck.gl/aggregation-layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'GridLayer', 8 | props: { ...gridLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: GridLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new GridLayer(opts as any), // Layer factory function 14 | props, 15 | gridPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/heatmap.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { heatmapLayerProps, heatmapPropsKeys } from '@/lib/layers/heatmap.lib.ts' 3 | import { HeatmapLayer, type HeatmapLayerProps } from '@deck.gl/aggregation-layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'HeatmapLayer', 8 | props: { ...heatmapLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: HeatmapLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new HeatmapLayer(opts as any), // Layer factory function 14 | props, 15 | heatmapPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/hexagon.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent, type Ref, ref } from 'vue' 2 | import { hexagonLayerProps, hexagonPropsKeys } from '@/lib/layers/hexagon.lib.ts' 3 | import { HexagonLayer, type HexagonLayerProps } from '@deck.gl/aggregation-layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'HexagonLayer', 8 | props: { ...hexagonLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: HexagonLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new HexagonLayer(opts as any), // Layer factory function 14 | props, 15 | hexagonPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/icon.layer.ts: -------------------------------------------------------------------------------- 1 | import { iconLayerProps, iconPropsKeys } from '@/lib/layers/icon.lib.ts' 2 | import { IconLayer, type IconLayerProps } from '@deck.gl/layers' 3 | import { defineComponent } from 'vue' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'IconLayer', 8 | props: { ...iconLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: IconLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new IconLayer(opts as any), // Layer factory function 14 | props, 15 | iconPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/path.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { pathLayerProps, pathPropsKeys } from '@/lib/layers/path.lib.ts' 3 | import { PathLayer, type PathLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'PathLayer', 8 | props: { ...pathLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: PathLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new PathLayer(opts as any), // Layer factory function 14 | props, 15 | pathPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/point-cloud.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { pointCloudProps, pointCloudPropsKeys } from '@/lib/layers/point-cloud.lib.ts' 3 | import { PointCloudLayer, type PointCloudLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'PointCloudLayer', 8 | props: { ...pointCloudProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: PointCloudLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new PointCloudLayer(opts), // Layer factory function 14 | props, 15 | pointCloudPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/polygon.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { polygonLayerProps, polygonPropsKeys } from '@/lib/layers/polygon.lib.ts' 3 | import { PolygonLayer, type PolygonLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'PolygonLayer', 8 | props: { ...polygonLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: PolygonLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new PolygonLayer(opts), // Layer factory function 14 | props, 15 | polygonPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/scatterplot.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { scatterplotLayerProps, scatterplotPropsKeys } from '@/lib/layers/scatterplot.lib.ts' 3 | import { ScatterplotLayer, type ScatterplotLayerProps } from '@deck.gl/layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'ScatterplotLayer', 8 | props: { ...scatterplotLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: ScatterplotLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new ScatterplotLayer(opts), // Layer factory function 14 | props, 15 | scatterplotPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/tile3d.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { useLayer } from '@/composables/useLayer.ts' 3 | import { tile3DLayerProps, tile3DPropsKeys } from '@/lib/layers/tile3d.lib.ts' 4 | import { type Tile3DLayerProps, Tile3DLayer } from '@deck.gl/geo-layers' 5 | 6 | export default defineComponent({ 7 | name: 'Tile3DLayer', 8 | props: { ...tile3DLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: Tile3DLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new Tile3DLayer(opts as any), // Layer factory function 14 | props, 15 | tile3DPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/trips.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { TripsLayer, type TripsLayerProps } from '@deck.gl/geo-layers' 3 | import { useLayer } from '@/composables/useLayer.ts' 4 | import { tripsLayerProps, tripsPropsKeys } from '@/lib/layers/trips.lib.ts' 5 | 6 | export default defineComponent({ 7 | name: 'TripsLayer', 8 | props: { ...tripsLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: TripsLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new TripsLayer(opts as any), // Layer factory function 14 | props, 15 | tripsPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/components/layers/wms.layer.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import { wmsLayerProps, wmsPropsKeys } from '@/lib/layers/wms.lib.ts' 3 | import { _WMSLayer, type WMSLayerProps } from '@deck.gl/geo-layers' 4 | import { useLayer } from '@/composables/useLayer.ts' 5 | 6 | export default defineComponent({ 7 | name: 'WMSLayer', 8 | props: { ...wmsLayerProps }, 9 | emits: ['hover', 'click', 'drag', 'dragStart', 'dragEnd', 'dataLoad', 'error'], 10 | setup(props: WMSLayerProps, { emit, expose }) { 11 | // Use `useLayer` for layer lifecycle management 12 | const { layer } = useLayer( 13 | (opts) => new _WMSLayer(opts as any), // Layer factory function 14 | props, 15 | wmsPropsKeys, 16 | emit, 17 | ) 18 | 19 | // Expose the layer reference for external use 20 | expose({ layer }) 21 | 22 | return () => [] // Renderless component 23 | }, 24 | }) 25 | -------------------------------------------------------------------------------- /packages/layers/src/composables/useLayer.ts: -------------------------------------------------------------------------------- 1 | import type { Layer } from '@deck.gl/core' 2 | import { inject, markRaw, onUnmounted, ref, type Ref, watch } from 'vue' 3 | import type { DeckLayerProps } from '@/shared/types.ts' 4 | import { genDeckLayerOpts } from '@/utils' 5 | 6 | /** 7 | * A composable function to manage the lifecycle of a reactive Deck.gl layer. 8 | * 9 | * @param {function} layerFactory - A factory function that generates a new Deck.gl `Layer` instance. 10 | * @param props - Reactive props used to configure the `Layer`. 11 | * @param validProps - List of valid prop keys to transform into layer options. 12 | * @param emit - Emit function for Vue component events. 13 | */ 14 | export const useLayer =

( 15 | layerFactory: (options: Partial

) => Layer, 16 | props: P, 17 | validProps: Array, 18 | emit: ( 19 | event: 'click' | 'hover' | 'drag' | 'dragStart' | 'dragEnd' | 'error' | 'dataLoad', 20 | ...args: any[] 21 | ) => void, 22 | ) => { 23 | // References to the current Deck.gl layer and layer management functions 24 | const addLayer = inject('addLayer') as (layer: Layer) => void 25 | const removeLayer = inject('removeLayer') as (layer: Layer) => void 26 | const layer: Ref = ref(null) 27 | 28 | if (!addLayer || !removeLayer) { 29 | throw new Error( 30 | 'DeckGL context is missing. Ensure you are using this within a DeckGL parent component.', 31 | ) 32 | } 33 | 34 | /** 35 | * Create or update the layer based on the current props 36 | */ 37 | const initializeLayer = () => { 38 | const opts: any = genDeckLayerOpts({ ...props }, validProps, emit) 39 | 40 | // Remove the previous layer if it exists from the registered layers of the overlay 41 | if (layer.value) { 42 | removeLayer(layer.value) 43 | layer.value = null 44 | } 45 | 46 | // Create a new layer and register it 47 | layer.value = markRaw(layerFactory(opts)) 48 | addLayer(layer.value) 49 | } 50 | 51 | /** 52 | * Cleanup and finalize the current layer 53 | */ 54 | const destroyLayer = () => { 55 | if (layer.value) { 56 | try { 57 | removeLayer(layer.value) // Remove the layer from Deck.gl 58 | if (layer.value.context) { 59 | layer.value.finalizeState(layer.value.context) // Release GPU memory 60 | } 61 | layer.value = null 62 | } catch (error) { 63 | console.error('Error finalizing layer:', error) 64 | } 65 | } 66 | } 67 | 68 | // Watch for prop changes and update the layer reactively 69 | watch( 70 | props, 71 | () => { 72 | initializeLayer() 73 | }, 74 | { deep: true, immediate: true }, 75 | ) 76 | 77 | // Clean up the layer when the component is unmounted 78 | onUnmounted(destroyLayer) 79 | 80 | return { 81 | layer, 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/arc.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type ArcLayerProps } from '@deck.gl/layers' 4 | 5 | export const arcLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | greatCircle: { 8 | type: Boolean as PropType, 9 | default: false, 10 | }, 11 | numSegments: { 12 | type: Number as PropType, 13 | default: 50, 14 | }, 15 | widthUnits: { 16 | type: String as PropType, 17 | default: 'pixels', 18 | }, 19 | widthScale: { 20 | type: Number as PropType, 21 | default: 1, 22 | }, 23 | widthMinPixels: { 24 | type: Number as PropType, 25 | default: 0, 26 | }, 27 | widthMaxPixels: { 28 | type: Number as PropType, 29 | default: Number.MAX_SAFE_INTEGER, 30 | }, 31 | getSourcePosition: { 32 | type: Function as unknown as PropType, 33 | default: (x: any) => x?.sourcePosition, 34 | }, 35 | getTargetPosition: { 36 | type: Function as unknown as PropType, 37 | default: (x: any) => x?.targetPosition, 38 | }, 39 | getSourceColor: { 40 | type: Function as unknown as PropType, 41 | default: () => [0, 0, 0, 255], 42 | }, 43 | getTargetColor: { 44 | type: Function as unknown as PropType, 45 | default: () => [0, 0, 0, 255], 46 | }, 47 | getWidth: { 48 | type: Number as PropType, 49 | default: 1, 50 | }, 51 | getHeight: { 52 | type: Number as PropType, 53 | default: 1, 54 | }, 55 | getTilt: { 56 | type: Number as PropType, 57 | default: 0, 58 | }, 59 | } 60 | export const arcPropsKeys: (keyof ArcLayerProps)[] = [ 61 | ...baseLayerKeys, 62 | 'greatCircle', 63 | 'numSegments', 64 | 'widthUnits', 65 | 'widthScale', 66 | 'widthMinPixels', 67 | 'widthMaxPixels', 68 | 'getSourcePosition', 69 | 'getTargetPosition', 70 | 'getSourceColor', 71 | 'getTargetColor', 72 | 'getWidth', 73 | 'getHeight', 74 | 'getTilt', 75 | ] 76 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/contour.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type ContourLayerProps } from '@deck.gl/aggregation-layers' 4 | 5 | export const contourLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | cellSize: { 8 | type: Number as PropType, 9 | default: 1000, 10 | }, 11 | gpuAggregation: { 12 | type: Boolean as PropType, 13 | default: true, 14 | }, 15 | aggregation: { 16 | type: String as PropType, 17 | default: 'SUM', 18 | }, 19 | contours: { 20 | type: Array as PropType, 21 | default: () => [{ threshold: 1 }], 22 | }, 23 | getPosition: { 24 | type: Function as unknown as PropType, 25 | default: (object: any) => object?.position, 26 | }, 27 | getWeight: { 28 | type: Function as unknown as PropType, 29 | default: () => 1, 30 | }, 31 | zOffset: { 32 | type: Number as PropType, 33 | default: 0.005, 34 | }, 35 | } 36 | 37 | export const contourPropsKeys: (keyof ContourLayerProps)[] = [ 38 | ...baseLayerKeys, 39 | 'cellSize', 40 | 'gpuAggregation', 41 | 'aggregation', 42 | 'contours', 43 | 'getPosition', 44 | 'getWeight', 45 | 'zOffset', 46 | ] 47 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/grid.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type GridLayerProps } from '@deck.gl/aggregation-layers' 4 | 5 | export const gridLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | gpuAggregation: { 8 | type: Boolean as PropType, 9 | default: false, 10 | }, 11 | colorAggregation: { 12 | type: String as PropType, 13 | default: 'SUM', 14 | }, 15 | elevationAggregation: { 16 | type: String as PropType, 17 | default: 'SUM', 18 | }, 19 | gridAggregator: { 20 | type: Function as unknown as PropType, 21 | default: null, 22 | }, 23 | colorScaleType: { 24 | type: String as PropType, 25 | default: 'quantile', 26 | }, 27 | cellSize: { 28 | type: Number as PropType, 29 | default: 1000, 30 | }, 31 | colorDomain: { 32 | type: Array as unknown as PropType, 33 | default: null, 34 | }, 35 | colorRange: { 36 | type: Array as PropType, 37 | }, 38 | coverage: { 39 | type: Number as PropType, 40 | default: 1, 41 | }, 42 | elevationDomain: { 43 | type: Array as unknown as PropType, 44 | }, 45 | elevationScale: { 46 | type: Number as PropType, 47 | default: 1, 48 | }, 49 | elevationScaleType: { 50 | type: String as PropType, 51 | default: 'linear', 52 | }, 53 | elevationRange: { 54 | type: Array as unknown as PropType, 55 | default: [0, 1000], 56 | }, 57 | extruded: { 58 | type: Boolean as PropType, 59 | default: true, 60 | }, 61 | upperPercentile: { 62 | type: Number as PropType, 63 | default: 100, 64 | }, 65 | lowerPercentile: { 66 | type: Number as PropType, 67 | default: 0, 68 | }, 69 | elevationUpperPercentile: { 70 | type: Number as PropType, 71 | default: 100, 72 | }, 73 | elevationLowerPercentile: { 74 | type: Number as PropType, 75 | default: 0, 76 | }, 77 | getPosition: { 78 | type: Function as unknown as PropType, 79 | default: (x: any) => x?.position, 80 | }, 81 | getColorWeight: { 82 | type: [Function, Number] as PropType, 83 | default: 1, 84 | }, 85 | getColorValue: { 86 | type: Function as unknown as PropType, 87 | default: null, 88 | }, 89 | getElevationWeight: { 90 | type: [Function, Number] as PropType, 91 | default: 1, 92 | }, 93 | getElevationValue: { 94 | type: Function as unknown as PropType, 95 | default: null, 96 | }, 97 | material: { 98 | type: Boolean as PropType, 99 | default: true, 100 | }, 101 | onSetColorDomain: Function as unknown as PropType, 102 | onSetElevationDomain: Function as unknown as PropType, 103 | } 104 | 105 | export const gridPropsKeys: (keyof GridLayerProps)[] = [ 106 | ...baseLayerKeys, 107 | 'gpuAggregation', 108 | 'colorAggregation', 109 | 'elevationAggregation', 110 | 'gridAggregator', 111 | 'colorScaleType', 112 | 'cellSize', 113 | 'colorDomain', 114 | 'colorRange', 115 | 'coverage', 116 | 'elevationDomain', 117 | 'elevationScale', 118 | 'elevationScaleType', 119 | 'elevationRange', 120 | 'extruded', 121 | 'upperPercentile', 122 | 'lowerPercentile', 123 | 'elevationUpperPercentile', 124 | 'elevationLowerPercentile', 125 | 'getPosition', 126 | 'getColorWeight', 127 | 'getColorValue', 128 | 'getElevationWeight', 129 | 'getElevationValue', 130 | 'material', 131 | 'onSetColorDomain', 132 | 'onSetElevationDomain', 133 | ] 134 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/heatmap.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type HeatmapLayerProps } from '@deck.gl/aggregation-layers' 4 | 5 | export const heatmapLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | intensity: { 8 | type: Number as PropType, 9 | default: 1, 10 | }, 11 | radiusPixels: { 12 | type: Number as PropType, 13 | default: 30, 14 | }, 15 | colorRange: { 16 | type: Array as unknown as PropType, 17 | }, 18 | threshold: { 19 | type: Number as PropType, 20 | default: 0.05, 21 | }, 22 | colorDomain: { 23 | type: Array as unknown as PropType, 24 | default: null, 25 | }, 26 | aggregation: { 27 | type: String as PropType, 28 | default: 'SUM', 29 | }, 30 | weightsTextureSize: { 31 | type: Number as PropType, 32 | default: 2048, 33 | }, 34 | debounceTimeout: { 35 | type: Number as PropType, 36 | default: 500, 37 | }, 38 | getPosition: { 39 | type: Function as PropType, 40 | default: (x: any) => x?.position, 41 | }, 42 | getWeight: { 43 | type: [Function, Number] as PropType, 44 | default: 1, 45 | }, 46 | } 47 | 48 | export const heatmapPropsKeys: (keyof HeatmapLayerProps)[] = [ 49 | ...baseLayerKeys, 50 | 'intensity', 51 | 'radiusPixels', 52 | 'colorRange', 53 | 'threshold', 54 | 'colorDomain', 55 | 'aggregation', 56 | 'weightsTextureSize', 57 | 'debounceTimeout', 58 | 'getPosition', 59 | 'getWeight', 60 | ] 61 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/hexagon.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type HexagonLayerProps } from '@deck.gl/aggregation-layers' 4 | 5 | export const hexagonLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | gpuAggregation: { 8 | type: Boolean as PropType, 9 | default: false, 10 | }, 11 | colorAggregation: { 12 | type: String as PropType, 13 | default: 'SUM', 14 | }, 15 | elevationAggregation: { 16 | type: String as PropType, 17 | default: 'SUM', 18 | }, 19 | hexagonAggregator: { 20 | type: Function as unknown as PropType, 21 | default: null, 22 | }, 23 | radius: { 24 | type: Number as PropType, 25 | default: 1000, 26 | }, 27 | elevationScale: { 28 | type: Number as PropType, 29 | default: 1, 30 | }, 31 | coverage: { 32 | type: Number as PropType, 33 | default: 1, 34 | }, 35 | lowerPercentile: { 36 | type: Number as PropType, 37 | default: 0, 38 | }, 39 | upperPercentile: { 40 | type: Number as PropType, 41 | default: 100, 42 | }, 43 | getPosition: { 44 | type: Function as unknown as PropType, 45 | default: (x: any) => x?.position, 46 | }, 47 | getColorWeight: { 48 | type: [Function, Number] as PropType, 49 | default: 1, 50 | }, 51 | getColorValue: { 52 | type: Function as unknown as PropType, 53 | default: null, 54 | }, 55 | colorScaleType: { 56 | type: String as PropType, 57 | default: 'quantile', 58 | }, 59 | colorDomain: { 60 | type: Array as unknown as PropType, 61 | default: null, 62 | }, 63 | colorRange: { 64 | type: Array as unknown as PropType, 65 | }, 66 | elevationScaleType: { 67 | type: String as PropType, 68 | default: 'linear', 69 | }, 70 | elevationDomain: { 71 | type: Array as unknown as PropType, 72 | default: null, 73 | }, 74 | elevationRange: { 75 | type: Array as unknown as PropType, 76 | default: [0, 1000], 77 | }, 78 | elevationUpperPercentile: { 79 | type: Number as PropType, 80 | default: 100, 81 | }, 82 | elevationLowerPercentile: { 83 | type: Number as PropType, 84 | default: 0, 85 | }, 86 | material: { 87 | type: [Object, Boolean] as PropType, 88 | default: true, 89 | }, 90 | extruded: { 91 | type: Boolean as PropType, 92 | default: false, 93 | }, 94 | getElevationWeight: { 95 | type: [Function, Number] as PropType, 96 | default: 1, 97 | }, 98 | } 99 | 100 | export const hexagonPropsKeys: (keyof HexagonLayerProps)[] = [ 101 | ...baseLayerKeys, 102 | 'gpuAggregation', 103 | 'colorAggregation', 104 | 'elevationAggregation', 105 | 'hexagonAggregator', 106 | 'radius', 107 | 'elevationScale', 108 | 'coverage', 109 | 'lowerPercentile', 110 | 'upperPercentile', 111 | 'getPosition', 112 | 'getColorWeight', 113 | 'getColorValue', 114 | 'colorScaleType', 115 | 'colorDomain', 116 | 'colorRange', 117 | 'elevationScaleType', 118 | 'elevationDomain', 119 | 'elevationRange', 120 | 'elevationUpperPercentile', 121 | 'elevationLowerPercentile', 122 | 'material', 123 | 'getElevationWeight', 124 | 'extruded', 125 | ] 126 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/icon.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type IconLayerProps } from '@deck.gl/layers' 4 | 5 | export const iconLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | sizeScale: { 8 | type: Number as PropType, 9 | default: 1, 10 | }, 11 | sizeUnits: { 12 | type: String as PropType, 13 | default: 'meters', 14 | }, 15 | sizeMinPixels: { 16 | type: Number as PropType, 17 | default: 0, 18 | }, 19 | sizeMaxPixels: { 20 | type: Number as PropType, 21 | default: Number.MAX_SAFE_INTEGER, 22 | }, 23 | iconAtlas: { 24 | type: String as PropType, 25 | }, 26 | iconMapping: { 27 | type: [Object, String] as PropType, 28 | }, 29 | billboard: { 30 | type: Boolean as PropType, 31 | default: true, 32 | }, 33 | alphaCutoff: { 34 | type: Number as PropType, 35 | default: 0.5, 36 | }, 37 | loadOptions: { 38 | type: Object as PropType, 39 | }, 40 | textureParameters: { 41 | type: Object as PropType, 42 | }, 43 | getAngle: { 44 | type: [Function, Number] as PropType, 45 | default: 0, 46 | }, 47 | getPosition: { 48 | type: Function as unknown as PropType, 49 | default: (x: any) => x?.position, 50 | }, 51 | getSize: { 52 | type: [Function, Number] as PropType, 53 | default: 1, 54 | }, 55 | getColor: { 56 | type: [Function, Array] as unknown as PropType, 57 | default: [255, 255, 255, 255], 58 | }, 59 | getIcon: { 60 | type: Function as unknown as PropType, 61 | default: (x: any) => x?.icon, 62 | }, 63 | onIconError: { 64 | type: Function as unknown as PropType, 65 | }, 66 | } 67 | 68 | export const iconPropsKeys: (keyof IconLayerProps)[] = [ 69 | ...baseLayerKeys, 70 | 'sizeScale', 71 | 'sizeUnits', 72 | 'sizeMinPixels', 73 | 'sizeMaxPixels', 74 | 'iconAtlas', 75 | 'iconMapping', 76 | 'billboard', 77 | 'alphaCutoff', 78 | 'loadOptions', 79 | 'textureParameters', 80 | 'getAngle', 81 | 'getPosition', 82 | 'getSize', 83 | 'getColor', 84 | 'getIcon', 85 | 'onIconError', 86 | ] 87 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/layer.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { COORDINATE_SYSTEM, type LayerProps } from '@deck.gl/core' 3 | 4 | export const baseLayerProps: ComponentPropsOptions = { 5 | // basic props 6 | id: { 7 | type: String as PropType, 8 | required: true, 9 | }, 10 | data: { 11 | type: [Object, String] as PropType, 12 | }, 13 | visible: { 14 | type: Boolean as PropType, 15 | default: true, 16 | }, 17 | opacity: { 18 | type: Number as PropType, 19 | default: 1, 20 | }, 21 | extensions: { 22 | type: Array as PropType, 23 | }, 24 | 25 | // Interaction Properties 26 | pickable: { 27 | type: Boolean as PropType, 28 | default: false, 29 | }, 30 | highlightColor: { 31 | type: [Array, Function] as PropType, 32 | default: () => [0, 0, 128, 128], 33 | }, 34 | highlightedObjectIndex: { 35 | type: [Number, null] as PropType, 36 | default: null, 37 | }, 38 | autoHighlight: { 39 | type: Boolean as PropType, 40 | default: false, 41 | }, 42 | 43 | // Coordinate System Properties 44 | coordinateSystem: { 45 | type: Number as PropType, 46 | default: COORDINATE_SYSTEM.DEFAULT, 47 | }, 48 | coordinateOrigin: { 49 | type: Array as unknown as PropType, 50 | default: () => [0, 0, 0], 51 | }, 52 | wrapLongitude: { 53 | type: Boolean as PropType, 54 | default: false, 55 | }, 56 | modelMatrix: { 57 | type: Array as unknown as PropType, 58 | default: undefined, 59 | }, 60 | 61 | // data properties 62 | dataComparator: { 63 | type: Function as unknown as PropType, 64 | }, 65 | _dataDiff: { 66 | type: Function as unknown as PropType, 67 | }, 68 | dataTransform: { 69 | type: Function as unknown as PropType, 70 | default: undefined, 71 | }, 72 | positionFormat: { 73 | type: String as PropType, 74 | default: 'XYZ', 75 | }, 76 | colorFormat: { 77 | type: String as PropType, 78 | default: 'RGBA', 79 | }, 80 | numInstances: { 81 | type: Number as PropType, 82 | default: undefined, 83 | }, 84 | updateTriggers: { 85 | type: Object as PropType, 86 | }, 87 | transitions: { 88 | type: Object as PropType, 89 | }, 90 | } 91 | export const baseLayerKeys: (keyof LayerProps)[] = [ 92 | 'id', 93 | 'data', 94 | 'visible', 95 | 'opacity', 96 | 'extensions', 97 | 'pickable', 98 | 'highlightColor', 99 | 'highlightedObjectIndex', 100 | 'autoHighlight', 101 | 'coordinateSystem', 102 | 'coordinateOrigin', 103 | 'wrapLongitude', 104 | 'modelMatrix', 105 | 'dataComparator', 106 | '_dataDiff', 107 | 'dataTransform', 108 | 'positionFormat', 109 | 'colorFormat', 110 | 'numInstances', 111 | 'transitions', 112 | ] 113 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/path.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import type { PathLayerProps } from '@deck.gl/layers' 4 | 5 | export const pathLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | widthUnits: { 8 | type: String as PropType, 9 | default: 'meters', 10 | }, 11 | widthScale: { 12 | type: Number as PropType, 13 | default: 1, 14 | }, 15 | widthMinPixels: { 16 | type: Number as PropType, 17 | default: 0, 18 | }, 19 | widthMaxPixels: { 20 | type: Number as PropType, 21 | default: Number.MAX_SAFE_INTEGER, 22 | }, 23 | jointRounded: { 24 | type: Boolean as PropType, 25 | default: false, 26 | }, 27 | capRounded: { 28 | type: Boolean as PropType, 29 | default: false, 30 | }, 31 | miterLimit: { 32 | type: Number as PropType, 33 | default: 4, 34 | }, 35 | billboard: { 36 | type: Boolean as PropType, 37 | default: false, 38 | }, 39 | _pathType: { 40 | type: String as PropType, 41 | default: null, 42 | }, 43 | getPath: { 44 | type: Function as unknown as PropType, 45 | default: (object: any) => object.path, 46 | }, 47 | getColor: { 48 | type: [Function, Array] as PropType, 49 | default: () => [0, 0, 0, 255], 50 | }, 51 | getWidth: { 52 | type: [Function, Number] as PropType, 53 | default: 1, 54 | }, 55 | } 56 | 57 | export const pathPropsKeys: (keyof PathLayerProps)[] = [ 58 | ...baseLayerKeys, 59 | 'widthUnits', 60 | 'widthScale', 61 | 'widthMinPixels', 62 | 'widthMaxPixels', 63 | 'jointRounded', 64 | 'capRounded', 65 | 'miterLimit', 66 | 'billboard', 67 | '_pathType', 68 | 'getPath', 69 | 'getColor', 70 | 'getWidth', 71 | ] 72 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/point-cloud.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import type { PointCloudLayerProps } from '@deck.gl/layers' 4 | 5 | export const pointCloudProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | /** 8 | * The units of the point size, one of `'meters'`, `'common'`, and `'pixels'`. 9 | * @default 'pixels' 10 | */ 11 | sizeUnits: { 12 | type: String as PropType, 13 | default: 'pixels', 14 | }, 15 | /** 16 | * Global radius of all points, in units specified by `sizeUnits` 17 | * @default 10 18 | */ 19 | pointSize: { 20 | type: Number as PropType, 21 | default: 10, 22 | }, 23 | 24 | /** 25 | * Material settings for lighting effect. 26 | * 27 | * @default true 28 | * @see https://deck.gl/docs/developer-guide/using-lighting 29 | */ 30 | material: { 31 | type: [Boolean, Object] as PropType, 32 | default: true, 33 | }, 34 | /** 35 | * Method called to retrieve the position of each object. 36 | * @default object => object?.position 37 | */ 38 | getPosition: { 39 | type: Function as PropType, 40 | default: (object: { position: any }) => object?.position, 41 | }, 42 | /** 43 | * The normal of each object, in `[nx, ny, nz]`. 44 | * @default [0, 0, 1] 45 | */ 46 | getNormal: { 47 | type: [Function, Array] as unknown as PropType, 48 | default: [0, 0, 1], 49 | }, 50 | /** 51 | * The rgba color is in the format of `[r, g, b, [a]]` 52 | * @default [0, 0, 0, 255] 53 | */ 54 | getColor: { 55 | type: [Function, Array] as unknown as PropType, 56 | default: [0, 0, 0, 255], 57 | }, 58 | } 59 | 60 | export const pointCloudPropsKeys: (keyof PointCloudLayerProps)[] = [ 61 | ...baseLayerKeys, 62 | 'sizeUnits', 63 | 'pointSize', 64 | 'material', 65 | 'getPosition', 66 | 'getNormal', 67 | 'getColor', 68 | ] 69 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/polygon.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type PolygonLayerProps } from '@deck.gl/layers' 4 | 5 | export const polygonLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | stroked: { 8 | type: Boolean as PropType, 9 | default: true, 10 | }, 11 | filled: { 12 | type: Boolean as PropType, 13 | default: true, 14 | }, 15 | extruded: { 16 | type: Boolean as PropType, 17 | default: false, 18 | }, 19 | elevationScale: { 20 | type: Number as PropType, 21 | default: 1, 22 | }, 23 | wireframe: { 24 | type: Boolean as PropType, 25 | default: false, 26 | }, 27 | lineWidthUnits: { 28 | type: String as PropType, 29 | default: 'meters', 30 | }, 31 | lineWidthScale: { 32 | type: Number as PropType, 33 | default: 1, 34 | }, 35 | lineWidthMinPixels: { 36 | type: Number as PropType, 37 | default: 0, 38 | }, 39 | lineWidthMaxPixels: { 40 | type: Number as PropType, 41 | default: Number.MAX_SAFE_INTEGER, 42 | }, 43 | lineJointRounded: { 44 | type: Boolean as PropType, 45 | default: false, 46 | }, 47 | lineMiterLimit: { 48 | type: Number as PropType, 49 | default: 4, 50 | }, 51 | lineDashJustified: { 52 | type: Boolean as PropType, 53 | default: undefined, // Not directly defined 54 | }, 55 | getPolygon: { 56 | type: Function as unknown as PropType, 57 | default: (f: any) => f.polygon, 58 | }, 59 | getFillColor: { 60 | type: [Function, Array] as unknown as PropType, 61 | default: [0, 0, 0, 255], 62 | }, 63 | getLineColor: { 64 | type: [Function, Array] as unknown as PropType, 65 | default: [0, 0, 0, 255], 66 | }, 67 | getLineWidth: { 68 | type: [Function, Number] as unknown as PropType, 69 | default: 1, 70 | }, 71 | getElevation: { 72 | type: [Function, Number] as unknown as PropType, 73 | default: 1000, 74 | }, 75 | material: { 76 | type: [Object, Boolean] as PropType, 77 | default: true, 78 | }, 79 | _normalize: { 80 | type: Boolean as PropType, 81 | default: true, 82 | }, 83 | _windingOrder: { 84 | type: String as PropType, 85 | default: 'CW', 86 | }, 87 | } 88 | 89 | export const polygonPropsKeys: (keyof PolygonLayerProps)[] = [ 90 | ...baseLayerKeys, 91 | 'stroked', 92 | 'filled', 93 | 'extruded', 94 | 'elevationScale', 95 | 'wireframe', 96 | 'lineWidthUnits', 97 | 'lineWidthScale', 98 | 'lineWidthMinPixels', 99 | 'lineWidthMaxPixels', 100 | 'lineJointRounded', 101 | 'lineMiterLimit', 102 | 'lineDashJustified', 103 | 'getPolygon', 104 | 'getFillColor', 105 | 'getLineColor', 106 | 'getLineWidth', 107 | 'getElevation', 108 | 'material', 109 | '_normalize', 110 | '_windingOrder', 111 | ] 112 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/scatterplot.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type ScatterplotLayerProps } from '@deck.gl/layers' 4 | 5 | export const scatterplotLayerProps: ComponentPropsOptions = { 6 | ...baseLayerProps, 7 | radiusUnits: { 8 | type: String as PropType, 9 | default: 'meters', 10 | }, 11 | radiusScale: { 12 | type: Number as PropType, 13 | default: 1, 14 | }, 15 | radiusMinPixels: { 16 | type: Number as PropType, 17 | default: 0, 18 | }, 19 | radiusMaxPixels: { 20 | type: Number as PropType, 21 | default: Number.MAX_SAFE_INTEGER, 22 | }, 23 | lineWidthUnits: { 24 | type: String as PropType, 25 | default: 'meters', 26 | }, 27 | lineWidthScale: { 28 | type: Number as PropType, 29 | default: 1, 30 | }, 31 | lineWidthMinPixels: { 32 | type: Number as PropType, 33 | default: 0, 34 | }, 35 | lineWidthMaxPixels: { 36 | type: Number as PropType, 37 | default: Number.MAX_SAFE_INTEGER, 38 | }, 39 | stroked: { 40 | type: Boolean as PropType, 41 | default: false, 42 | }, 43 | filled: { 44 | type: Boolean as PropType, 45 | default: true, 46 | }, 47 | billboard: { 48 | type: Boolean as PropType, 49 | default: false, 50 | }, 51 | antialiasing: { 52 | type: Boolean as PropType, 53 | default: true, 54 | }, 55 | getPosition: { 56 | type: Function as unknown as PropType, 57 | default: (object: any) => object?.position, 58 | }, 59 | getRadius: { 60 | type: [Function, Number] as unknown as PropType, 61 | default: 1, 62 | }, 63 | getFillColor: { 64 | type: [Function, Array] as unknown as PropType, 65 | default: [0, 0, 0, 255], 66 | }, 67 | getLineColor: { 68 | type: [Function, Array] as unknown as PropType, 69 | default: [0, 0, 0, 255], 70 | }, 71 | getLineWidth: { 72 | type: [Function, Number] as unknown as PropType, 73 | default: 1, 74 | }, 75 | } 76 | 77 | export const scatterplotPropsKeys: (keyof ScatterplotLayerProps)[] = [ 78 | ...baseLayerKeys, 79 | 'radiusUnits', 80 | 'radiusScale', 81 | 'radiusMinPixels', 82 | 'radiusMaxPixels', 83 | 'lineWidthUnits', 84 | 'lineWidthScale', 85 | 'lineWidthMinPixels', 86 | 'lineWidthMaxPixels', 87 | 'stroked', 88 | 'filled', 89 | 'billboard', 90 | 'antialiasing', 91 | 'getPosition', 92 | 'getRadius', 93 | 'getFillColor', 94 | 'getLineColor', 95 | 'getLineWidth', 96 | ] 97 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/tile3d.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import type { Tile3DLayerProps } from '@deck.gl/geo-layers' 4 | import { Tiles3DLoader } from '@loaders.gl/3d-tiles' 5 | 6 | // Define Vue-style props for Tile3DLayer 7 | export const tile3DLayerProps: ComponentPropsOptions = { 8 | ...baseLayerProps, 9 | data: { 10 | type: String as PropType, 11 | default: undefined, 12 | }, 13 | loadOptions: { 14 | type: Object as PropType, 15 | default: undefined, 16 | }, 17 | getPointColor: { 18 | type: [Function, Array] as unknown as PropType, 19 | default: () => [0, 0, 0, 255], 20 | }, 21 | pointSize: { 22 | type: Number as PropType, 23 | default: 1.0, 24 | }, 25 | 26 | loader: { 27 | type: Object as PropType, 28 | default: Tiles3DLoader, 29 | }, 30 | onTilesetLoad: { 31 | type: Function as PropType, 32 | default: undefined, 33 | }, 34 | onTileLoad: { 35 | type: Function as PropType, 36 | default: undefined, 37 | }, 38 | onTileUnload: { 39 | type: Function as PropType, 40 | default: undefined, 41 | }, 42 | onTileError: { 43 | type: Function as PropType, 44 | default: undefined, 45 | }, 46 | _getMeshColor: { 47 | type: Function as PropType, 48 | default: () => [255, 255, 255], 49 | }, 50 | } 51 | 52 | // Define the keys for Tile3DLayer props to simplify further use 53 | export const tile3DPropsKeys: (keyof Tile3DLayerProps)[] = [ 54 | ...baseLayerKeys, 55 | 'data', 56 | 'getPointColor', 57 | 'pointSize', 58 | 'loader', 59 | 'loadOptions', 60 | 'onTilesetLoad', 61 | 'onTileLoad', 62 | 'onTileUnload', 63 | 'onTileError', 64 | '_getMeshColor', 65 | ] 66 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/trips.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import type { TripsLayerProps } from '@deck.gl/geo-layers' 3 | import { pathLayerProps, pathPropsKeys } from '@/lib/layers/path.lib.ts' 4 | 5 | // Define Vue-style props for TripsLayer 6 | export const tripsLayerProps: ComponentPropsOptions = { 7 | ...pathLayerProps, 8 | fadeTrail: { 9 | type: Boolean as PropType, 10 | default: true, 11 | }, 12 | trailLength: { 13 | type: Number as PropType, 14 | default: 120, 15 | }, 16 | currentTime: { 17 | type: Number as PropType, 18 | default: 0, 19 | }, 20 | getTimestamps: { 21 | type: Function as PropType, 22 | default: (d: any) => d.timestamps, 23 | }, 24 | } 25 | 26 | // Define the keys for TripsLayer props to simplify further use 27 | export const tripsPropsKeys: (keyof TripsLayerProps)[] = [ 28 | ...pathPropsKeys, 29 | 'fadeTrail', 30 | 'trailLength', 31 | 'currentTime', 32 | 'getTimestamps', 33 | ] 34 | -------------------------------------------------------------------------------- /packages/layers/src/lib/layers/wms.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { baseLayerKeys, baseLayerProps } from '@/lib/layers/layer.lib.ts' 3 | import { type WMSLayerProps } from '@deck.gl/geo-layers' 4 | 5 | /** Props for customizing the behavior and appearance of the WMS Layer */ 6 | export const wmsLayerProps: ComponentPropsOptions = { 7 | ...baseLayerProps, 8 | data: { 9 | type: [String, Object] as PropType, 10 | required: true, 11 | }, 12 | serviceType: { 13 | type: String as PropType, 14 | default: 'auto', 15 | }, 16 | layers: { 17 | type: Array as PropType, 18 | default: () => [], 19 | }, 20 | srs: { 21 | type: String as PropType, 22 | default: 'auto', 23 | }, 24 | onMetadataLoad: { 25 | type: Function as PropType, 26 | default: () => {}, 27 | }, 28 | onMetadataLoadError: { 29 | type: Function as PropType, 30 | default: (error: Error) => console.error(error), 31 | }, 32 | onImageLoadStart: { 33 | type: Function as PropType, 34 | default: () => {}, 35 | }, 36 | onImageLoad: { 37 | type: Function as PropType, 38 | default: () => {}, 39 | }, 40 | onImageLoadError: { 41 | type: Function as PropType, 42 | default: (requestId: unknown, error: Error) => 43 | console.error('Error loading image:', error, 'Request ID:', requestId), 44 | }, 45 | } 46 | 47 | /** Keys for WMS Layer Props to simplify destructuring or usage */ 48 | export const wmsPropsKeys: (keyof WMSLayerProps)[] = [ 49 | ...baseLayerKeys, 50 | 'data', 51 | 'serviceType', 52 | 'layers', 53 | 'srs', 54 | 'onMetadataLoad', 55 | 'onMetadataLoadError', 56 | 'onImageLoadStart', 57 | 'onImageLoad', 58 | 'onImageLoadError', 59 | ] 60 | -------------------------------------------------------------------------------- /packages/layers/src/main.ts: -------------------------------------------------------------------------------- 1 | import { type App, type Plugin } from 'vue' 2 | 3 | // Import vue components 4 | import * as components from '@/components' 5 | 6 | // install function executed by Vue.use() 7 | const install: Exclude = function installVueDeckglSuiteLayers(app: App) { 8 | Object.entries(components).forEach(([componentName, component]) => { 9 | app.component(componentName, component) 10 | }) 11 | } 12 | 13 | // Create module definition for Vue.use() 14 | export default install 15 | 16 | // To allow individual component use, export components 17 | // each can be registered via Vue.component() 18 | export * from '@/components' 19 | export { genDeckOpts, genDeckLayerOpts } from '@/utils' 20 | -------------------------------------------------------------------------------- /packages/layers/src/shared/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type ArcLayerProps, 3 | type BitmapLayerProps, 4 | type ColumnLayerProps, 5 | type GeoJsonLayerProps, 6 | type IconLayerProps, 7 | type LineLayerProps, 8 | type PathLayerProps, 9 | type PointCloudLayerProps, 10 | type PolygonLayerProps, 11 | type ScatterplotLayerProps, 12 | } from '@deck.gl/layers' 13 | import type { Tile3DLayerProps, WMSLayerProps } from '@deck.gl/geo-layers' 14 | import type { 15 | GridLayerProps, 16 | HeatmapLayerProps, 17 | HexagonLayerProps, 18 | } from '@deck.gl/aggregation-layers' 19 | 20 | /** 21 | * Represents a utility type that excludes specific layer-related event properties from the given type `T`. 22 | * 23 | * The excluded event properties are 'onHover', 'onClick', 'onDrag', 'onDragStart', 24 | * 'onDragEnd', 'onDataLoad', and 'onError'. 25 | * 26 | * This is useful for creating a type that inherits from `T` but does not include these specific events. 27 | * 28 | * @template T The base type from which the properties will be omitted. 29 | */ 30 | export type WithoutLayerEvents = Omit< 31 | T, 32 | 'onHover' | 'onClick' | 'onDrag' | 'onDragStart' | 'onDragEnd' | 'onDataLoad' | 'onError' 33 | > 34 | 35 | /** 36 | * Represents the properties for various Deck.gl layer types without layer event properties. 37 | * 38 | * DeckLayerProps combines the settings for multiple types of layers, excluding the layer-specific events. 39 | * This allows for standardized handling of properties across different types of layers. 40 | * 41 | * The supported layer types include: 42 | * - ArcLayer 43 | * - GeoJsonLayer 44 | * - BitmapLayer 45 | * - ColumnLayer 46 | * - LineLayer 47 | * - PolygonLayer 48 | * - ScatterplotLayer 49 | * - PathLayer 50 | * - IconLayer 51 | * - PointCloudLayer 52 | * - Tile3DLayer 53 | * - WMSLayer 54 | * - HexagonLayer 55 | * - GridLayer 56 | * Each type is represented as a union, enabling flexibility to select properties specific to individual layer types. 57 | */ 58 | export type DeckLayerProps = 59 | | WithoutLayerEvents 60 | | WithoutLayerEvents 61 | | WithoutLayerEvents 62 | | WithoutLayerEvents 63 | | WithoutLayerEvents 64 | | WithoutLayerEvents 65 | | WithoutLayerEvents 66 | | WithoutLayerEvents 67 | | WithoutLayerEvents 68 | | WithoutLayerEvents 69 | | WithoutLayerEvents 70 | | WithoutLayerEvents 71 | | WithoutLayerEvents 72 | | WithoutLayerEvents 73 | | WithoutLayerEvents 74 | -------------------------------------------------------------------------------- /packages/layers/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { DeckLayerProps } from '@/shared/types.ts' 2 | 3 | /** 4 | * Generates an object containing only valid properties from the provided input. 5 | * Filters out properties that are undefined or not included in the list of valid properties. 6 | * 7 | * @param {Partial} props - The input object containing a partial set of properties. 8 | * @param {(keyof T)[]} validProps - An array of keys representing the valid properties. 9 | * @return {Partial} A new object containing only the valid properties from the input. 10 | */ 11 | export function genDeckOpts(props: Partial, validProps: (keyof T)[]): Partial { 12 | for (const opt of Object.keys(props) as Array) { 13 | if (props[opt] === undefined || !validProps.includes(opt)) { 14 | delete props[opt] 15 | } 16 | } 17 | 18 | return props 19 | } 20 | 21 | /** 22 | * Generates a deck.gl layer options object by filtering valid properties and attaching event emitters. 23 | * 24 | * @param {T} props - The properties to be processed for generating the layer options. 25 | * @param {Array} validProps - An array of keys representing valid properties to be included in the layer options. 26 | * @param {(event: 'click' | 'hover' | 'drag' | 'dragStart' | 'dragEnd' | 'error' | 'dataLoad', ...args: any[]) => void} emit - A function to emit events with specified type and arguments. 27 | * @return {Partial} A filtered properties object with added event handler callbacks for the specified events. 28 | */ 29 | export function genDeckLayerOpts( 30 | props: T, 31 | validProps: Array, 32 | emit: ( 33 | event: 'click' | 'hover' | 'drag' | 'dragStart' | 'dragEnd' | 'error' | 'dataLoad', 34 | ...args: any[] 35 | ) => void, 36 | ): Partial { 37 | for (const opt of Object.keys(props) as Array) { 38 | if (props[opt] === undefined || !validProps.includes(opt)) { 39 | delete props[opt] 40 | } 41 | } 42 | 43 | return { 44 | ...props, 45 | onClick: (...args: any[]) => emit('click', ...args), 46 | onHover: (...args: any[]) => emit('hover', ...args), 47 | onDrag: (...args: any[]) => emit('drag', ...args), 48 | onDragStart: (...args: any[]) => emit('dragStart', ...args), 49 | onDragEnd: (...args: any[]) => emit('dragEnd', ...args), 50 | onError: (...args: any[]) => emit('error', ...args), 51 | onDataLoad: (...args: any[]) => emit('dataLoad', ...args), 52 | } 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /packages/layers/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.ts"], 4 | "exclude": ["src/**/__tests__/*", "node_modules/**", "dist", "../../node_modules"], 5 | "compilerOptions": { 6 | "baseUrl" : ".", 7 | "target" : "ESNext", 8 | "useDefineForClassFields": true, 9 | "module" : "ESNext", 10 | "moduleResolution" : "Node", 11 | "strict" : true, 12 | "jsx" : "preserve", 13 | "sourceMap" : true, 14 | "resolveJsonModule" : true, 15 | "esModuleInterop" : true, 16 | "isolatedModules" : true, 17 | "newLine" : "lf", 18 | "tsBuildInfoFile" : "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 19 | "skipLibCheck" : true, 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/layers/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/layers/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/layers/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig, type PluginOption } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | import { resolve } from 'path' 7 | import dtsPlugin from 'vite-plugin-dts' 8 | 9 | // https://vite.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | vue() as PluginOption, 13 | dtsPlugin({ 14 | entryRoot: './src', 15 | insertTypesEntry: true, // Ensure types are included in "exports" in package.json 16 | tsconfigPath: './tsconfig.app.json', // Point explicitly to the correct tsconfig 17 | rollupTypes: true, // Use rollup to bundle declaration files 18 | outDir: 'dist', // Place all declarations in the "dist" folder 19 | }) as PluginOption, 20 | vueDevTools() as PluginOption, 21 | ], 22 | resolve: { 23 | alias: { 24 | '@': fileURLToPath(new URL('./src', import.meta.url)) 25 | }, 26 | }, 27 | build: { 28 | lib: { 29 | entry: resolve(__dirname, 'src/main.ts'), 30 | // Simplified library global name 31 | name: 'VueDeckGLSuiteLayers', 32 | // Dynamically include format in the file name 33 | fileName: (format) => `vue-deckgl-suite-layers.${format}.js`, 34 | }, 35 | rollupOptions: { 36 | external: [ 37 | 'vue', 38 | '@deck.gl/core', 39 | '@deck.gl/layers', 40 | '@deck.gl/geo-layers', 41 | '@deck.gl/aggregation-layers' 42 | ], 43 | output: { 44 | globals: { 45 | vue: 'Vue', 46 | '@deck.gl/core': 'deck', 47 | '@deck.gl/layers': 'deck.layers', 48 | '@deck.gl/geo-layers': 'deck.geo-layers', 49 | '@deck.gl/aggregation-layers': 'deck.aggregation-layers', 50 | }, 51 | }, 52 | } 53 | } 54 | }) 55 | -------------------------------------------------------------------------------- /packages/layers/web-types.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | componentsRoot: './src/components', 3 | components: '**/[a-zA-Z]*.(component|layer).ts', 4 | } 5 | -------------------------------------------------------------------------------- /packages/maplibre/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | end_of_line = lf 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /packages/maplibre/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /packages/maplibre/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /packages/maplibre/.prettierrc.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "$schema": "https://json.schemastore.org/prettierrc", 4 | "semi": false, 5 | "singleQuote": true, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /packages/maplibre/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "dbaeumer.vscode-eslint", 5 | "EditorConfig.EditorConfig", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/maplibre/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/maplibre/eslint.config.ts: -------------------------------------------------------------------------------- 1 | import pluginVue from 'eslint-plugin-vue' 2 | import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' 3 | import skipFormatting from '@vue/eslint-config-prettier/skip-formatting' 4 | 5 | // To allow more languages other than `ts` in `.vue` files, uncomment the following lines: 6 | // import { configureVueProject } from '@vue/eslint-config-typescript' 7 | // configureVueProject({ scriptLangs: ['ts', 'tsx'] }) 8 | // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup 9 | 10 | export default defineConfigWithVueTs( 11 | { 12 | name: 'app/files-to-lint', 13 | files: ['**/*.{ts,mts,tsx,vue}'], 14 | }, 15 | 16 | { 17 | name: 'app/files-to-ignore', 18 | ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'], 19 | }, 20 | 21 | pluginVue.configs['flat/essential'], 22 | vueTsConfigs.recommended, 23 | skipFormatting, 24 | ) 25 | -------------------------------------------------------------------------------- /packages/maplibre/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |

11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/maplibre/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue-deckgl-suite/maplibre", 3 | "description": "A Vue 3 package integrating Deck.gl with MapLibre for geospatial visualizations", 4 | "version": "1.0.0-beta.4", 5 | "author": { 6 | "name": "Mostafa Gamal", 7 | "email": "mostafagamal99418@gmail.com" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/MostafaGamalSayed/vue-deck.gl-suite.git" 12 | }, 13 | "keywords": [ 14 | "deckgl", 15 | "geo-layers", 16 | "aggregation-layers", 17 | "deckgl vue wrapper", 18 | "wrapper", 19 | "maplibre", 20 | "map", 21 | "vue3", 22 | "Vue.js", 23 | "layers", 24 | "components" 25 | ], 26 | "publishConfig": { 27 | "access": "public" 28 | }, 29 | "type": "module", 30 | "main": "dist/vue-deckgl-suite-maplibre.umd.js", 31 | "module": "dist/vue-deckgl-suite-maplibre.es.js", 32 | "types": "dist/main.d.ts", 33 | "web-types": "dist/web-types.json", 34 | "files": [ 35 | "dist/**/*" 36 | ], 37 | "scripts": { 38 | "dev": "vite", 39 | "build": "run-p type-check \"build-only {@}\" --", 40 | "preview": "vite preview", 41 | "build-only": "vite build && vue-docgen-web-types --configFile web-types.config.cjs", 42 | "type-check": "vue-tsc --build", 43 | "lint": "eslint . --fix", 44 | "format": "prettier --write src/" 45 | }, 46 | "devDependencies": { 47 | "@deck.gl/core": "^9.1.8", 48 | "@deck.gl/mapbox": "^9.1.8", 49 | "@tsconfig/node22": "^22.0.0", 50 | "@types/node": "^22.13.1", 51 | "@vitejs/plugin-vue": "^5.2.1", 52 | "@vue/eslint-config-prettier": "^10.1.0", 53 | "@vue/eslint-config-typescript": "^14.3.0", 54 | "@vue/tsconfig": "^0.7.0", 55 | "eslint": "^9.18.0", 56 | "eslint-plugin-vue": "^9.32.0", 57 | "jiti": "^2.4.2", 58 | "maplibre-gl": "^5.1.0", 59 | "npm-run-all2": "^7.0.2", 60 | "prettier": "^3.4.2", 61 | "typescript": "~5.7.3", 62 | "vite": "^6.0.11", 63 | "vite-plugin-dts": "^4.5.0", 64 | "vite-plugin-vue-devtools": "^7.7.1", 65 | "vue": "^3.5.13", 66 | "vue-docgen-web-types": "^0.1.8", 67 | "vue-tsc": "^2.2.0" 68 | }, 69 | "peerDependencies": { 70 | "@deck.gl/core": "^9.1.8", 71 | "@deck.gl/mapbox": "^9.1.8", 72 | "maplibre-gl": "^5.1.0", 73 | "vue": "^3.5.13" 74 | }, 75 | "engines": { 76 | "node": ">=18" 77 | }, 78 | "gitHead": "6748997e3584871bafea9f3d997dac136d4e8563" 79 | } 80 | -------------------------------------------------------------------------------- /packages/maplibre/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/packages/maplibre/public/favicon.ico -------------------------------------------------------------------------------- /packages/maplibre/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Map } from './map.component.ts' 2 | export { default as DeckGL } from './overlay.component.ts' 3 | -------------------------------------------------------------------------------- /packages/maplibre/src/lib/overlay.lib.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentPropsOptions, PropType } from 'vue' 2 | import { type MapboxOverlayProps } from '@deck.gl/mapbox' 3 | import { Deck } from '@deck.gl/core' 4 | 5 | export const overlayProps: ComponentPropsOptions = { 6 | // Add props explicitly defined in MapboxOverlayProps 7 | interleaved: { 8 | type: Boolean as PropType, 9 | default: false, 10 | }, 11 | beforeId: { 12 | type: String as PropType, 13 | default: undefined, 14 | }, 15 | id: { 16 | type: String, 17 | default: 'deckgl-overlay', 18 | }, 19 | /** Additional CSS styles for the canvas. */ 20 | style: { 21 | type: Object as PropType, 22 | default: Deck.defaultProps.style, 23 | }, 24 | 25 | /** Controls the resolution of drawing buffer used for rendering. 26 | * @default `true` (use browser devicePixelRatio) 27 | */ 28 | useDevicePixels: { 29 | type: [Boolean, Number] as PropType, 30 | default: Deck.defaultProps.useDevicePixels, 31 | }, 32 | /** Extra pixels around the pointer to include while picking. 33 | * @default `0` 34 | */ 35 | pickingRadius: { 36 | type: Number as PropType, 37 | default: Deck.defaultProps.pickingRadius, 38 | }, 39 | /** WebGL parameters to be set before each frame is rendered. */ 40 | parameters: { 41 | type: Object as PropType, 42 | default: Deck.defaultProps.parameters, 43 | }, 44 | /** If supplied, will be called before a layer is drawn to determine whether it should be rendered. */ 45 | layerFilter: { 46 | type: Function as unknown as PropType, 47 | default: Deck.defaultProps.layerFilter, 48 | }, 49 | /** 50 | * The array of Layer instances to be rendered. 51 | * Nested arrays are accepted, as well as falsy values (`null`, `false`, `undefined`) 52 | */ 53 | layers: { 54 | type: Array as PropType, 55 | default: Deck.defaultProps.layers, 56 | }, 57 | /** The array of effects to be rendered. A lighting effect will be added if an empty array is supplied. */ 58 | effects: { 59 | type: Array as PropType, 60 | default: Deck.defaultProps.effects, 61 | }, 62 | /** A single View instance, or an array of `View` instances. 63 | * @default `new MapView()` 64 | */ 65 | views: { 66 | type: [Object, Array] as PropType, 67 | default: Deck.defaultProps.views, 68 | }, 69 | /** Allow browser default touch actions. 70 | * @default `'none'` 71 | */ 72 | touchAction: { 73 | type: String as PropType, 74 | default: Deck.defaultProps.touchAction, 75 | }, 76 | /** Set Hammer.js recognizer options for gesture recognition. */ 77 | eventRecognizerOptions: { 78 | type: Object as PropType, 79 | default: Deck.defaultProps.eventRecognizerOptions, 80 | }, 81 | /** A custom callback to retrieve the cursor type. */ 82 | getCursor: { 83 | type: Function as PropType, 84 | default: Deck.defaultProps.getCursor, 85 | }, 86 | /** Callback that takes a hovered-over point and renders a tooltip. */ 87 | getTooltip: { 88 | type: Function as unknown as PropType, 89 | default: Deck.defaultProps.getTooltip, 90 | }, 91 | /** (Debug) Flag to enable WebGL debug mode. Requires importing `@luma.gl/debug`. */ 92 | debug: { 93 | type: Boolean as PropType, 94 | default: Deck.defaultProps.debug, 95 | }, 96 | } 97 | export const overlayPropsKeys: (keyof MapboxOverlayProps)[] = [ 98 | 'interleaved', 99 | 'id', 100 | 'style', 101 | 'useDevicePixels', 102 | 'pickingRadius', 103 | 'parameters', 104 | 'layerFilter', 105 | 'layers', 106 | 'effects', 107 | 'views', 108 | 'touchAction', 109 | 'eventRecognizerOptions', 110 | 'getCursor', 111 | 'getTooltip', 112 | 'debug', 113 | ] 114 | -------------------------------------------------------------------------------- /packages/maplibre/src/main.ts: -------------------------------------------------------------------------------- 1 | import { type App, type Plugin } from 'vue' 2 | 3 | // Import vue components 4 | import * as components from '@/components' 5 | 6 | // install function executed by Vue.use() 7 | const install: Exclude = function installVueDeckglSuiteMaplibre(app: App) { 8 | Object.entries(components).forEach(([componentName, component]) => { 9 | app.component(componentName, component) 10 | }) 11 | } 12 | 13 | // Create module definition for Vue.use() 14 | export default install 15 | 16 | // To allow individual component use, export components 17 | // each can be registered via Vue.component() 18 | export * from '@/components' 19 | -------------------------------------------------------------------------------- /packages/maplibre/src/shared/constants.ts: -------------------------------------------------------------------------------- 1 | import { type InjectionKey, type Ref } from 'vue' 2 | import { MapboxOverlay } from '@deck.gl/mapbox' 3 | 4 | export const mapboxOverlayInstanceSymbol = Symbol('mapboxOverlayInstanceSymbol') as InjectionKey> 5 | -------------------------------------------------------------------------------- /packages/maplibre/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, Ref, ShallowRef, ComponentInternalInstance, Raw } from 'vue' 2 | import type { Map, MapEventType } from 'maplibre-gl' 3 | 4 | export const map = Symbol('map'), 5 | mapSymbol = map as InjectionKey>, 6 | isLoadedSymbol = Symbol('isLoaded') as InjectionKey>, 7 | isInitialized = Symbol('isInitialized'), 8 | isInitializedSymbol = isInitialized as InjectionKey> 9 | 10 | export interface MglEvent { 11 | type: string 12 | component: Raw 13 | map: Map 14 | event: MapEventType[T] 15 | } 16 | -------------------------------------------------------------------------------- /packages/maplibre/src/utils/genDeckOpts.ts: -------------------------------------------------------------------------------- 1 | export function genDeckOpts(props: Partial, validProps: (keyof T)[]): Partial { 2 | for (const opt of Object.keys(props) as Array) { 3 | if (props[opt] === undefined || !validProps.includes(opt)) { 4 | delete props[opt] 5 | } 6 | } 7 | 8 | return props 9 | } 10 | -------------------------------------------------------------------------------- /packages/maplibre/src/utils/isLngLatEqual.ts: -------------------------------------------------------------------------------- 1 | import { type LngLatLike } from 'maplibre-gl' 2 | import pkg from 'maplibre-gl'; 3 | const { LngLat } = pkg; 4 | 5 | export function isLngLatEqual(one: LngLatLike, two: LngLatLike): boolean { 6 | const firstPosition = LngLat.convert(one) 7 | const secondPosition = LngLat.convert(two) 8 | 9 | return firstPosition.lng === secondPosition.lng && firstPosition.lat === secondPosition.lat 10 | } 11 | -------------------------------------------------------------------------------- /packages/maplibre/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.ts"], 4 | "exclude": ["src/**/__tests__/*", "node_modules/**", "dist", "../../node_modules"], 5 | "compilerOptions": { 6 | "baseUrl" : ".", 7 | "target" : "ESNext", 8 | "useDefineForClassFields": true, 9 | "module" : "ESNext", 10 | "moduleResolution" : "Node", 11 | "strict" : true, 12 | "jsx" : "preserve", 13 | "sourceMap" : true, 14 | "resolveJsonModule" : true, 15 | "esModuleInterop" : true, 16 | "isolatedModules" : true, 17 | "newLine" : "lf", 18 | "tsBuildInfoFile" : "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 19 | "skipLibCheck" : true, 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/maplibre/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/maplibre/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/maplibre/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig, type PluginOption } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | import { resolve } from 'path' 7 | import dtsPlugin from 'vite-plugin-dts' 8 | 9 | // https://vite.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | vue() as PluginOption, 13 | dtsPlugin({ 14 | entryRoot: './src', 15 | insertTypesEntry: true, // Ensure types are included in "exports" in package.json 16 | tsconfigPath: './tsconfig.app.json', // Point explicitly to the correct tsconfig 17 | rollupTypes: true, // Use rollup to bundle declaration files 18 | outDir: 'dist', // Place all declarations in the "dist" folder 19 | }) as PluginOption, 20 | vueDevTools() as PluginOption, 21 | ], 22 | resolve: { 23 | alias: { 24 | '@': fileURLToPath(new URL('./src', import.meta.url)) 25 | }, 26 | }, 27 | build: { 28 | lib: { 29 | entry: resolve(__dirname, 'src/main.ts'), 30 | name: 'VueDeckGLSuiteMapLibre', 31 | fileName: (format) => `vue-deckgl-suite-maplibre.${format}.js`, 32 | }, 33 | rollupOptions: { 34 | external: [ 35 | 'vue', 36 | '@deck.gl/core', 37 | '@deck.gl/mapbox', 38 | 'maplibre-gl' 39 | ], 40 | output: { 41 | globals: { 42 | vue: 'Vue', 43 | "maplibre-gl": "maplibregl" 44 | } 45 | } 46 | } 47 | } 48 | 49 | }) 50 | -------------------------------------------------------------------------------- /packages/maplibre/web-types.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | componentsRoot: './src/components', 3 | components: '**/[a-zA-Z]*.(component|layer).ts', 4 | } 5 | -------------------------------------------------------------------------------- /packages/playground/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | end_of_line = lf 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /packages/playground/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /packages/playground/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | 32 | .env -------------------------------------------------------------------------------- /packages/playground/.prettierrc.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "$schema": "https://json.schemastore.org/prettierrc", 4 | "semi": false, 5 | "singleQuote": true, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /packages/playground/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "dbaeumer.vscode-eslint", 5 | "EditorConfig.EditorConfig", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/playground/README.md: -------------------------------------------------------------------------------- 1 | # playground 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). 8 | 9 | ## Type Support for `.vue` Imports in TS 10 | 11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. 12 | 13 | ## Customize configuration 14 | 15 | See [Vite Configuration Reference](https://vite.dev/config/). 16 | 17 | ## Project Setup 18 | 19 | ```sh 20 | npm install 21 | ``` 22 | 23 | ### Compile and Hot-Reload for Development 24 | 25 | ```sh 26 | npm run dev 27 | ``` 28 | 29 | ### Type-Check, Compile and Minify for Production 30 | 31 | ```sh 32 | npm run build 33 | ``` 34 | 35 | ### Lint with [ESLint](https://eslint.org/) 36 | 37 | ```sh 38 | npm run lint 39 | ``` 40 | -------------------------------------------------------------------------------- /packages/playground/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/playground/eslint.config.ts: -------------------------------------------------------------------------------- 1 | import pluginVue from 'eslint-plugin-vue' 2 | import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' 3 | import skipFormatting from '@vue/eslint-config-prettier/skip-formatting' 4 | 5 | // To allow more languages other than `ts` in `.vue` files, uncomment the following lines: 6 | // import { configureVueProject } from '@vue/eslint-config-typescript' 7 | // configureVueProject({ scriptLangs: ['ts', 'tsx'] }) 8 | // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup 9 | 10 | export default defineConfigWithVueTs( 11 | { 12 | name: 'app/files-to-lint', 13 | files: ['**/*.{ts,mts,tsx,vue}'], 14 | }, 15 | 16 | { 17 | name: 'app/files-to-ignore', 18 | ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'], 19 | }, 20 | 21 | pluginVue.configs['flat/essential'], 22 | vueTsConfigs.recommended, 23 | skipFormatting, 24 | ) 25 | -------------------------------------------------------------------------------- /packages/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground", 3 | "version": "1.0.0-beta.4", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "build-only": "vite build", 11 | "type-check": "vue-tsc --build", 12 | "lint": "eslint . --fix", 13 | "format": "prettier --write src/" 14 | }, 15 | "dependencies": { 16 | "@deck.gl/core": "^9.1.8", 17 | "@deck.gl/geo-layers": "^9.1.8", 18 | "@deck.gl/aggregation-layers": "^9.1.8", 19 | "@deck.gl/layers": "^9.1.8", 20 | "@loaders.gl/i3s": "^4.3.3", 21 | "@loaders.gl/csv": "^4.3.3", 22 | "@loaders.gl/json": "^4.3.3", 23 | "@loaders.gl/core": "^4.3.3", 24 | "@vue-deckgl-suite/layers": "*", 25 | "@vue-deckgl-suite/maplibre": "*", 26 | "@vue-deckgl-suite/google-maps": "*", 27 | "popmotion": "^11.0.5", 28 | "vue": "^3.5.13", 29 | "vue-router": "^4.5.0", 30 | "d3-scale": "^4.0.2" 31 | }, 32 | "devDependencies": { 33 | "@tsconfig/node22": "^22.0.0", 34 | "@types/node": "^22.10.7", 35 | "@vitejs/plugin-vue": "^5.2.1", 36 | "@vue/eslint-config-prettier": "^10.1.0", 37 | "@vue/eslint-config-typescript": "^14.3.0", 38 | "@vue/tsconfig": "^0.7.0", 39 | "eslint": "^9.18.0", 40 | "eslint-plugin-vue": "^9.32.0", 41 | "jiti": "^2.4.2", 42 | "npm-run-all2": "^7.0.2", 43 | "prettier": "^3.4.2", 44 | "sass": "^1.84.0", 45 | "typescript": "~5.7.3", 46 | "vite": "^6.0.11", 47 | "vite-plugin-vue-devtools": "^7.7.0", 48 | "vue-tsc": "^2.2.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/playground/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/packages/playground/public/favicon.ico -------------------------------------------------------------------------------- /packages/playground/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /packages/playground/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | // @ts-ignore 3 | import App from './App.vue' 4 | // @ts-ignore 5 | import router from './router/index.js' 6 | 7 | const app = createApp(App) 8 | 9 | app.use(router) 10 | 11 | app.mount('#app') 12 | -------------------------------------------------------------------------------- /packages/playground/src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | 3 | const router = createRouter({ 4 | history: createWebHistory(import.meta.env.BASE_URL), 5 | routes: [ 6 | { 7 | path: '/arc-layer', 8 | name: 'arc-layer', 9 | component: () => import('../views/ArcLayer.vue'), 10 | }, 11 | { 12 | path: '/point-cloud-layer', 13 | name: 'point-cloud-layer', 14 | component: () => import('../views/PointCloudLayer.vue'), 15 | }, 16 | { 17 | path: '/column-layer', 18 | name: 'column-layer', 19 | component: () => import('../views/ColumnLayer.vue'), 20 | }, 21 | { 22 | path: '/maplibre-map', 23 | name: 'maplibre-map', 24 | component: () => import('../views/MaplibreMap.vue'), 25 | }, 26 | { 27 | path: '/maplibre/tiles3d-layer', 28 | name: 'maplibre-tiles3d-layer', 29 | component: () => import('../views/maplibre/Tile3dLayer.vue'), 30 | }, 31 | { 32 | path: '/maplibre/trips-layer', 33 | name: 'maplibre-trips-layer', 34 | component: () => import('../views/maplibre/TripsLayer.vue'), 35 | }, 36 | { 37 | path: '/maplibre/path-layer', 38 | name: 'maplibre-path-layer', 39 | component: () => import('../views/maplibre/PathLayer.vue'), 40 | }, 41 | { 42 | path: '/maplibre/wms-layer', 43 | name: 'maplibre-wms-layer', 44 | component: () => import('../views/maplibre/WMSLayer.vue'), 45 | }, 46 | { 47 | path: '/maplibre/heatmap-layer', 48 | name: 'maplibre-heatmap-layer', 49 | component: () => import('../views/maplibre/HeatmapLayer.vue'), 50 | }, 51 | { 52 | path: '/maplibre/beta-heatmap-layer', 53 | name: 'maplibre-beta-heatmap-layer', 54 | component: () => import('../views/maplibre/BetaHeatmapLayer.vue'), 55 | }, 56 | { 57 | path: '/maplibre/geojson-layer', 58 | name: 'maplibre-geojson-layer', 59 | component: () => import('../views/maplibre/GeojsonLayer.vue'), 60 | }, 61 | { 62 | path: '/maplibre/hexagon-layer', 63 | name: 'maplibre-hexagon-layer', 64 | component: () => import('../views/maplibre/HexagonLayer.vue'), 65 | }, 66 | { 67 | path: '/google/hexagon-layer', 68 | name: 'google-hexagon-layer', 69 | component: () => import('../views/google/HexagonLayer.vue'), 70 | }, 71 | { 72 | path: '/maplibre/road-safety', 73 | name: 'maplibre-road-safety', 74 | component: () => import('../views/maplibre/HexagonLayerRoadSafety.vue'), 75 | }, 76 | 77 | { 78 | path: '/maplibre/icon-layer', 79 | name: 'maplibre-icon-layer', 80 | component: () => import('../views/maplibre/IconLayer.vue'), 81 | }, 82 | { 83 | path: '/maplibre/arc-layer', 84 | name: 'maplibre-arc-layer', 85 | component: () => import('../views/maplibre/ArcLayer.vue'), 86 | }, 87 | { 88 | path: '/maplibre/grid-layer', 89 | name: 'maplibre-grid-layer', 90 | component: () => import('../views/maplibre/GridLayer.vue'), 91 | }, 92 | { 93 | path: '/maplibre/column-layer', 94 | name: 'maplibre-column-layer', 95 | component: () => import('../views/maplibre/ColumnLayer.vue'), 96 | }, 97 | { 98 | path: '/maplibre/point-cloud-layer', 99 | name: 'maplibre-point-cloud-layer', 100 | component: () => import('../views/maplibre/PointCloudLayer.vue'), 101 | }, 102 | 103 | { 104 | path: '/maplibre/polygon-layer', 105 | name: 'maplibre-polygon-layer', 106 | component: () => import('../views/maplibre/PolygonLayer.vue'), 107 | }, 108 | 109 | { 110 | path: '/maplibre/scatterplot-layer', 111 | name: 'maplibre-scatterplot-layer', 112 | component: () => import('../views/maplibre/ScatterplotLayer.vue'), 113 | }, 114 | { 115 | path: '/maplibre/contour-layer', 116 | name: 'maplibre-contour-layer', 117 | component: () => import('../views/maplibre/ContourLayer.vue'), 118 | }, 119 | { 120 | path: '/google/basemap', 121 | name: 'google-basemap', 122 | component: () => import('../views/google/GoogleMap.vue'), 123 | }, 124 | 125 | { 126 | path: '/maplibre/geojson-layer-paths', 127 | name: 'maplibre-geojson-layer-paths', 128 | component: () => import('../views/maplibre/GeojsonLayerPaths.vue'), 129 | }, 130 | 131 | { 132 | path: '/maplibre/arc-layer-migration', 133 | name: 'maplibre-arc-layer-migration', 134 | component: () => import('../views/maplibre/ArcLayerMigration.vue') 135 | } 136 | ], 137 | }) 138 | 139 | export default router 140 | -------------------------------------------------------------------------------- /packages/playground/src/views/ArcLayer.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 44 | -------------------------------------------------------------------------------- /packages/playground/src/views/ColumnLayer.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 34 | -------------------------------------------------------------------------------- /packages/playground/src/views/MaplibreMap.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 69 | 70 | 73 | -------------------------------------------------------------------------------- /packages/playground/src/views/PointCloudLayer.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 34 | -------------------------------------------------------------------------------- /packages/playground/src/views/google/GoogleMap.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /packages/playground/src/views/google/HexagonLayer.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 47 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/ArcLayer.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 47 | 48 | 51 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/ArcLayerMigration.vue: -------------------------------------------------------------------------------- 1 | 77 | 78 | 109 | 110 | 113 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/BetaHeatmapLayer.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | 31 | 34 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/ColumnLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 33 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/ContourLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 33 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/GeojsonLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 34 | 35 | 38 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/GridLayer.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 42 | 43 | 46 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/HeatmapLayer.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/HexagonLayer.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 45 | 46 | 49 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/HexagonLayerRoadSafety.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 107 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/IconLayer.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 50 | 51 | 54 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/PathLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 28 | 29 | 32 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/PointCloudLayer.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 33 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/PolygonLayer.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 30 | 31 | 34 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/ScatterplotLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 31 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/Tile3dLayer.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 49 | 50 | 53 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/TripsLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 26 | 27 | 30 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/WMSLayer.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 20 | 21 | 24 | -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/icon-data/location-icon-atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MostafaGamalSayed/vue-deck.gl-suite/c3c1b9b5ff8145d0399d53bbf0f87195ba1cb9ee/packages/playground/src/views/maplibre/icon-data/location-icon-atlas.png -------------------------------------------------------------------------------- /packages/playground/src/views/maplibre/icon-data/location-icon-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "marker-1": { 3 | "x": 0, 4 | "y": 0, 5 | "width": 128, 6 | "height": 128, 7 | "anchorY": 128 8 | }, 9 | "marker-2": { 10 | "x": 128, 11 | "y": 0, 12 | "width": 128, 13 | "height": 128, 14 | "anchorY": 128 15 | }, 16 | "marker-3": { 17 | "x": 256, 18 | "y": 0, 19 | "width": 128, 20 | "height": 128, 21 | "anchorY": 128 22 | }, 23 | "marker-4": { 24 | "x": 384, 25 | "y": 0, 26 | "width": 128, 27 | "height": 128, 28 | "anchorY": 128 29 | }, 30 | "marker-5": { 31 | "x": 0, 32 | "y": 128, 33 | "width": 128, 34 | "height": 128, 35 | "anchorY": 128 36 | }, 37 | "marker-6": { 38 | "x": 128, 39 | "y": 128, 40 | "width": 128, 41 | "height": 128, 42 | "anchorY": 128 43 | }, 44 | "marker-7": { 45 | "x": 256, 46 | "y": 128, 47 | "width": 128, 48 | "height": 128, 49 | "anchorY": 128 50 | }, 51 | "marker-8": { 52 | "x": 384, 53 | "y": 128, 54 | "width": 128, 55 | "height": 128, 56 | "anchorY": 128 57 | }, 58 | "marker-9": { 59 | "x": 0, 60 | "y": 256, 61 | "width": 128, 62 | "height": 128, 63 | "anchorY": 128 64 | }, 65 | "marker-10": { 66 | "x": 128, 67 | "y": 256, 68 | "width": 128, 69 | "height": 128, 70 | "anchorY": 128 71 | }, 72 | "marker-20": { 73 | "x": 256, 74 | "y": 256, 75 | "width": 128, 76 | "height": 128, 77 | "anchorY": 128 78 | }, 79 | "marker-30": { 80 | "x": 384, 81 | "y": 256, 82 | "width": 128, 83 | "height": 128, 84 | "anchorY": 128 85 | }, 86 | "marker-40": { 87 | "x": 0, 88 | "y": 384, 89 | "width": 128, 90 | "height": 128, 91 | "anchorY": 128 92 | }, 93 | "marker-50": { 94 | "x": 128, 95 | "y": 384, 96 | "width": 128, 97 | "height": 128, 98 | "anchorY": 128 99 | }, 100 | "marker-60": { 101 | "x": 256, 102 | "y": 384, 103 | "width": 128, 104 | "height": 128, 105 | "anchorY": 128 106 | }, 107 | "marker-70": { 108 | "x": 384, 109 | "y": 384, 110 | "width": 128, 111 | "height": 128, 112 | "anchorY": 128 113 | }, 114 | "marker-80": { 115 | "x": 0, 116 | "y": 512, 117 | "width": 128, 118 | "height": 128, 119 | "anchorY": 128 120 | }, 121 | "marker-90": { 122 | "x": 128, 123 | "y": 512, 124 | "width": 128, 125 | "height": 128, 126 | "anchorY": 128 127 | }, 128 | "marker-100": { 129 | "x": 256, 130 | "y": 512, 131 | "width": 128, 132 | "height": 128, 133 | "anchorY": 128 134 | }, 135 | "marker": { 136 | "x": 384, 137 | "y": 512, 138 | "width": 128, 139 | "height": 128, 140 | "anchorY": 128 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /packages/playground/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 7 | 8 | "paths": { 9 | "@/*": ["./src/*"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/playground/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/playground/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig, loadEnv, type PluginOption } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | 7 | // https://vite.dev/config/ 8 | export default defineConfig(({ mode }) => { 9 | const env = loadEnv(mode, process.cwd(), '') 10 | 11 | return { 12 | define: { 13 | __GOOGLE_MAPS_KEY__: JSON.stringify(env), 14 | }, 15 | plugins: [ 16 | vue() as PluginOption, 17 | vueDevTools() as PluginOption, 18 | ], 19 | resolve: { 20 | alias: { 21 | '@': fileURLToPath(new URL('./src', import.meta.url)) 22 | }, 23 | }, 24 | } 25 | }) 26 | --------------------------------------------------------------------------------