├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── feature_request.yml
└── workflows
│ ├── build-deploy-publish.yml
│ ├── codeql.yml
│ └── pr-build-test.yml
├── .gitignore
├── Community.Blazor.MapLibre.Examples
├── App.razor
├── Community.Blazor.MapLibre.Examples.csproj
├── Layout
│ ├── MainLayout.razor
│ ├── MainLayout.razor.css
│ ├── NavMenu.razor
│ └── NavMenu.razor.css
├── Pages
│ ├── Example.razor
│ ├── Examples
│ │ ├── AddListener.razor
│ │ ├── CreatePopup.razor
│ │ ├── CreatePopup.razor.cs
│ │ ├── FitBounds.razor
│ │ ├── LoadGeoJson.razor
│ │ └── RenderGlobe.razor
│ └── Home.razor
├── Program.cs
├── Properties
│ └── launchSettings.json
├── Shared
│ └── GridCard.razor
├── _Imports.razor
└── wwwroot
│ ├── css
│ ├── app.css
│ └── bootstrap
│ │ ├── bootstrap.min.css
│ │ └── bootstrap.min.css.map
│ ├── favicon.png
│ ├── icon-192.png
│ ├── img
│ └── examples
│ │ ├── basic.png
│ │ ├── fitbounds.png
│ │ ├── geojson.png
│ │ ├── globe.png
│ │ ├── listener.png
│ │ └── popup.png
│ ├── index.html
│ ├── sample-data
│ └── weather.json
│ └── staticwebapp.config.json
├── Community.Blazor.MapLibre.sln
├── Community.Blazor.MapLibre
├── CallbackHandler.cs
├── Community.Blazor.MapLibre.csproj
├── Converter
│ └── OneOfConverter.cs
├── Listener.cs
├── MapLibre.razor
├── MapLibre.razor.cs
├── MapLibre.razor.css
├── MapLibre.razor.js
├── MapOptions.cs
├── Models
│ ├── BulkTransaction.cs
│ ├── Camera
│ │ ├── AnimationOptions.cs
│ │ ├── CameraForBoundsOptions.cs
│ │ ├── CameraOptions.cs
│ │ ├── CenterZoomBearing.cs
│ │ ├── EaseToOptions.cs
│ │ ├── FitBoundOptions.cs
│ │ ├── FlyToOptions.cs
│ │ ├── ICameraOptions.cs
│ │ ├── ICenterZoomBearing.cs
│ │ └── JumpToOptions.cs
│ ├── Control
│ │ ├── ControlPosition.cs
│ │ └── ControlType.cs
│ ├── Event
│ │ ├── EventType.cs
│ │ └── MapMouseEvent.cs
│ ├── Feature
│ │ ├── FeatureCollection.cs
│ │ ├── FeatureFeature.cs
│ │ ├── FeatureIdentifier.cs
│ │ ├── GeometryType.cs
│ │ ├── IFeature.cs
│ │ ├── IGeometry.cs
│ │ ├── LineGeometry.cs
│ │ ├── MultiLineGeometry.cs
│ │ ├── MultiPointGeometry.cs
│ │ ├── MultiPolygonGeometry.cs
│ │ ├── PointGeometry.cs
│ │ └── PolygonGeometry.cs
│ ├── Image
│ │ ├── ImageData.cs
│ │ └── StyleImageMetadata.cs
│ ├── Layers
│ │ ├── BackgroundLayer.cs
│ │ ├── CircleLayer.cs
│ │ ├── FillExtrusionLayer.cs
│ │ ├── FillLayer.cs
│ │ ├── HeatMapLayer.cs
│ │ ├── HillShadeLayer.cs
│ │ ├── Layer.cs
│ │ ├── LayerType.cs
│ │ ├── LineLayer.cs
│ │ ├── RasterLayer.cs
│ │ └── SymbolLayer.cs
│ ├── LngLat.cs
│ ├── LngLatBounds.cs
│ ├── Marker
│ │ ├── Marker.cs
│ │ ├── MarkerAlignment.cs
│ │ ├── MarkerAnchor.cs
│ │ └── MarkerOptions.cs
│ ├── Padding
│ │ └── PaddingOptions.cs
│ ├── PointLike.cs
│ ├── Popup.cs
│ ├── PopupOptions.cs
│ ├── PositionAnchor.cs
│ ├── ProjectionSpecification.cs
│ ├── Sources
│ │ ├── GeoJsonSource.cs
│ │ ├── ISource.cs
│ │ ├── ImageSource.cs
│ │ ├── QuerySourceFeatureOptions.cs
│ │ ├── RasterTileSource.cs
│ │ ├── VectorTileSource.cs
│ │ └── VideoSource.cs
│ ├── Sprite
│ │ └── StyleSetterOptions.cs
│ ├── TextFit.cs
│ ├── Visibility.cs
│ └── WebGLContextAttributes.cs
├── _Imports.razor
└── wwwroot
│ ├── geojson-antimeridian-cut
│ ├── LICENSE
│ ├── cut.js
│ ├── geometry
│ │ ├── features.js
│ │ ├── lines.js
│ │ └── polygons.js
│ └── util.js
│ ├── maplibre-5.3.0.min.css
│ └── maplibre-5.3.0.min.js
├── README.md
├── UNLICENSE
└── global.json
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: File a bug report for Community.Blazor.MapLibre
3 | title: "[BUG]: "
4 | labels: ["bug", "triage"]
5 | assignees: []
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thank you for taking the time to fill out this bug report!
11 |
12 | Please provide as much detail as possible to help us understand and reproduce the issue.
13 |
14 | - type: checkboxes
15 | id: prerequisites
16 | attributes:
17 | label: Prerequisites
18 | description: Before submitting a bug report, please confirm the following
19 | options:
20 | - label: I have checked that this issue has not already been reported
21 | required: true
22 | - label: I have tried clearing browser cache and restarting my application
23 | required: true
24 |
25 | - type: input
26 | id: package-version
27 | attributes:
28 | label: Package Version
29 | description: What version of Community.Blazor.MapLibre are you using?
30 | placeholder: "e.g., 5.3.0-beta.1"
31 | validations:
32 | required: true
33 |
34 | - type: input
35 | id: dotnet-version
36 | attributes:
37 | label: .NET Version
38 | description: Which .NET version are you using?
39 | placeholder: "e.g., .NET 9.0"
40 | validations:
41 | required: true
42 |
43 | - type: input
44 | id: browser
45 | attributes:
46 | label: Browser
47 | description: Which browser are you using (if applicable)?
48 | placeholder: "e.g., Chrome 123, Firefox 102, etc."
49 | validations:
50 | required: false
51 |
52 | - type: textarea
53 | id: what-happened
54 | attributes:
55 | label: What happened?
56 | description: |
57 | Please describe the bug in detail.
58 |
59 | Include any error messages or stack traces if available.
60 | placeholder: A clear and concise description of what the bug is.
61 | validations:
62 | required: true
63 |
64 | - type: textarea
65 | id: expected-behavior
66 | attributes:
67 | label: Expected behavior
68 | description: What did you expect to happen?
69 | placeholder: A clear and concise description of what you expected to happen.
70 | validations:
71 | required: true
72 |
73 | - type: textarea
74 | id: reproduction
75 | attributes:
76 | label: Reproduction steps
77 | description: |
78 | How can we reproduce this issue? Provide a step-by-step guide or a minimal code sample.
79 | placeholder: |
80 | 1. Add MapLibre to the page with '...'
81 | 2. Configure options '...'
82 | 3. Call method '...'
83 | 4. See error
84 | render: markdown
85 | validations:
86 | required: true
87 |
88 | - type: textarea
89 | id: code-sample
90 | attributes:
91 | label: Code Sample
92 | description: |
93 | Please provide a code sample that demonstrates the issue.
94 | This will be automatically formatted into code, so no need for backticks.
95 | render: csharp
96 | validations:
97 | required: false
98 |
99 | - type: textarea
100 | id: additional-info
101 | attributes:
102 | label: Additional Information
103 | description: |
104 | Add any other context about the problem here.
105 | Screenshots, logs, or references to related issues are helpful.
106 | validations:
107 | required: false
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature Request
2 | description: Suggest an idea for Community.Blazor.MapLibre
3 | title: "[FEATURE]: "
4 | labels: ["enhancement"]
5 | assignees: []
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thank you for suggesting a new feature!
11 |
12 | Please provide as much detail as possible to help us understand your idea.
13 |
14 | - type: textarea
15 | id: problem-description
16 | attributes:
17 | label: Is your feature request related to a problem?
18 | description: |
19 | A clear and concise description of what the problem is.
20 | placeholder: |
21 | I'm always frustrated when [...] or I need a way to [...]
22 | validations:
23 | required: false
24 |
25 | - type: textarea
26 | id: solution-description
27 | attributes:
28 | label: Describe the solution you'd like
29 | description: |
30 | A clear and concise description of what you want to happen.
31 |
32 | If you know of similar implementations in other libraries or languages, please reference them.
33 | placeholder: |
34 | I would like to be able to [...] so that [...]
35 | validations:
36 | required: true
37 |
38 | - type: textarea
39 | id: alternatives
40 | attributes:
41 | label: Describe alternatives you've considered
42 | description: |
43 | Have you considered any alternative solutions or workarounds?
44 | placeholder: |
45 | I've tried implementing this with [...] but it doesn't work well because [...]
46 | validations:
47 | required: false
48 |
49 | - type: textarea
50 | id: maplibre-js-reference
51 | attributes:
52 | label: MapLibre JS Reference
53 | description: |
54 | If this feature exists in MapLibre JS, please provide links to the relevant documentation or examples.
55 | placeholder: |
56 | This feature corresponds to [method/property] in MapLibre JS: [link to documentation]
57 | validations:
58 | required: false
59 |
60 | - type: textarea
61 | id: example-usage
62 | attributes:
63 | label: Example Usage
64 | description: |
65 | If possible, provide an example of how you envision using this feature in code.
66 | placeholder: |
67 | ```csharp
68 | // Example of how the feature might be used
69 | var map = new MapLibre();
70 | map.NewFeature(...);
71 | ```
72 | render: markdown
73 | validations:
74 | required: false
75 |
76 | - type: textarea
77 | id: additional-context
78 | attributes:
79 | label: Additional context
80 | description: |
81 | Add any other context, screenshots, diagrams or references about the feature request here.
82 | validations:
83 | required: false
84 |
85 | - type: checkboxes
86 | id: contribution
87 | attributes:
88 | label: Contribution
89 | description: Would you be willing to contribute this feature?
90 | options:
91 | - label: I'm interested in implementing this feature with guidance
--------------------------------------------------------------------------------
/.github/workflows/build-deploy-publish.yml:
--------------------------------------------------------------------------------
1 | name: Build, Test, and Publish Multi-Project Solution
2 |
3 | on:
4 | push:
5 | branches:
6 | - "main"
7 | - "release/*" # For library publishing
8 | workflow_dispatch: # Allow manual triggering of the workflow
9 |
10 | jobs:
11 | # Job 1: Build and Test Both Projects
12 | build:
13 | name: Build, Test, and Package Library
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | # Step 1: Checkout the repository
18 | - name: Checkout repository
19 | uses: actions/checkout@v3
20 |
21 | # Step 2: Setup .NET
22 | - name: Setup .NET
23 | uses: actions/setup-dotnet@v3
24 | with:
25 | dotnet-version: 9.0.x
26 |
27 | # Step 3: Restore dependencies
28 | - name: Restore dependencies
29 | run: dotnet restore
30 |
31 | # Step 4: Build both projects
32 | - name: Build Library and Examples
33 | run: dotnet build --no-restore -c Release /p:ContinuousIntegrationBuild=true
34 |
35 | # Step 5: Test the Library Project (Optional If You Only Want to Test Library)
36 | - name: Test Library
37 | run: dotnet test Community.Blazor.MapLibre/Community.Blazor.MapLibre.csproj --verbosity normal -c Release
38 |
39 | # Step 6: Pack the Library for NuGet
40 | - name: Pack NuGet Library
41 | if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'release'))
42 | run: dotnet pack Community.Blazor.MapLibre/Community.Blazor.MapLibre.csproj -c Release --no-build --output nuget
43 | # Only pack `Community.Blazor.MapLibre.csproj` for NuGet, not the examples
44 |
45 | # Step 7: Upload NuGet packages as artifact
46 | - name: Upload NuGet Artifact
47 | if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'release'))
48 | uses: actions/upload-artifact@v4
49 | with:
50 | name: nuget
51 | path: nuget/
52 |
53 | # Step 8: Prepare Blazor examples for deployment
54 | - name: Publish Blazor Examples
55 | if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'main'))
56 | run: dotnet publish Community.Blazor.MapLibre.Examples/Community.Blazor.MapLibre.Examples.csproj -c Release -o blazor_build_output
57 |
58 | # Step 9: Upload Blazor artifacts for deployment
59 | - name: Upload Blazor Deployment Artifact
60 | if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'main'))
61 | uses: actions/upload-pages-artifact@v3
62 | with:
63 | path: blazor_build_output/wwwroot
64 |
65 | # Job 2: Publish NuGet Package
66 | publish:
67 | name: Publish Library to NuGet
68 | runs-on: ubuntu-latest
69 | needs: [build] # Requires the Build job to complete
70 |
71 | if: >
72 | ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'release'))
73 |
74 | steps:
75 | # Step 1: Download NuGet package artifact from the Build job
76 | - name: Download NuGet Artifact
77 | uses: actions/download-artifact@v4
78 | with:
79 | name: nuget
80 | path: nuget
81 |
82 | # Step 2: Setup .NET in the Publish job
83 | - name: Setup .NET
84 | uses: actions/setup-dotnet@v3
85 | with:
86 | dotnet-version: 9.0.x
87 |
88 | # Step 3: Publish the library to NuGet (using GitHub token or API key)
89 | - name: Publish to NuGet
90 | run: dotnet nuget push nuget/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
91 |
92 | # Job 3: Deploy Blazor Examples
93 | deploy:
94 | name: Deploy Blazor Examples
95 | runs-on: ubuntu-latest
96 | needs: [build] # Requires the Build job to complete
97 |
98 | if: >
99 | ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && startsWith(github.ref_name, 'main'))
100 |
101 | permissions:
102 | pages: write # Grant GitHub Pages deploy permissions
103 | id-token: write # To verify the deployment source
104 |
105 | environment:
106 | name: github-pages
107 | url: ${{ steps.deployment.outputs.page_url }}
108 |
109 | steps:
110 | - name: Deploy to GitHub Pages
111 | id: deployment
112 | uses: actions/deploy-pages@v4
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL Advanced"
13 |
14 | on:
15 | push:
16 | branches: [ "main" ]
17 | pull_request:
18 | branches: [ "main" ]
19 | schedule:
20 | - cron: '42 10 * * 6'
21 |
22 | jobs:
23 | analyze:
24 | name: Analyze (${{ matrix.language }})
25 | # Runner size impacts CodeQL analysis time. To learn more, please see:
26 | # - https://gh.io/recommended-hardware-resources-for-running-codeql
27 | # - https://gh.io/supported-runners-and-hardware-resources
28 | # - https://gh.io/using-larger-runners (GitHub.com only)
29 | # Consider using larger runners or machines with greater resources for possible analysis time improvements.
30 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
31 | permissions:
32 | # required for all workflows
33 | security-events: write
34 |
35 | # required to fetch internal or private CodeQL packs
36 | packages: read
37 |
38 | # only required for workflows in private repositories
39 | actions: read
40 | contents: read
41 |
42 | strategy:
43 | fail-fast: false
44 | matrix:
45 | include:
46 | - language: actions
47 | build-mode: none
48 | - language: csharp
49 | build-mode: none
50 | - language: javascript-typescript
51 | build-mode: none
52 | # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
53 | # Use `c-cpp` to analyze code written in C, C++ or both
54 | # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
55 | # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
56 | # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
57 | # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
58 | # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
59 | # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
60 | steps:
61 | - name: Checkout repository
62 | uses: actions/checkout@v4
63 |
64 | # Add any setup steps before running the `github/codeql-action/init` action.
65 | # This includes steps like installing compilers or runtimes (`actions/setup-node`
66 | # or others). This is typically only required for manual builds.
67 | # - name: Setup runtime (example)
68 | # uses: actions/setup-example@v1
69 |
70 | # Initializes the CodeQL tools for scanning.
71 | - name: Initialize CodeQL
72 | uses: github/codeql-action/init@v3
73 | with:
74 | languages: ${{ matrix.language }}
75 | build-mode: ${{ matrix.build-mode }}
76 | # If you wish to specify custom queries, you can do so here or in a config file.
77 | # By default, queries listed here will override any specified in a config file.
78 | # Prefix the list here with "+" to use these queries and those in the config file.
79 |
80 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
81 | # queries: security-extended,security-and-quality
82 |
83 | # If the analyze step fails for one of the languages you are analyzing with
84 | # "We were unable to automatically build your code", modify the matrix above
85 | # to set the build mode to "manual" for that language. Then modify this step
86 | # to build your code.
87 | # ℹ️ Command-line programs to run using the OS shell.
88 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
89 | - if: matrix.build-mode == 'manual'
90 | shell: bash
91 | run: |
92 | echo 'If you are using a "manual" build mode for one or more of the' \
93 | 'languages you are analyzing, replace this with the commands to build' \
94 | 'your code, for example:'
95 | echo ' make bootstrap'
96 | echo ' make release'
97 | exit 1
98 |
99 | - name: Perform CodeQL Analysis
100 | uses: github/codeql-action/analyze@v3
101 | with:
102 | category: "/language:${{matrix.language}}"
103 |
--------------------------------------------------------------------------------
/.github/workflows/pr-build-test.yml:
--------------------------------------------------------------------------------
1 | name: PR Build and Test
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | - "release/*"
8 |
9 | jobs:
10 | pr-build:
11 | name: Build and Test
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - name: Checkout repository
16 | uses: actions/checkout@v3
17 |
18 | - name: Setup .NET
19 | uses: actions/setup-dotnet@v3
20 | with:
21 | dotnet-version: 9.0.x
22 |
23 | - name: Restore dependencies
24 | run: dotnet restore
25 |
26 | - name: Build projects
27 | run: dotnet build --no-restore -c Release
28 |
29 | - name: Test Library
30 | run: dotnet test Community.Blazor.MapLibre/Community.Blazor.MapLibre.csproj --verbosity normal -c Release
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | /packages/
4 | riderModule.iml
5 | /_ReSharper.Caches/
6 |
7 | .idea/
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/App.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Not found
8 |
9 | Sorry, there's nothing at this address.
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Community.Blazor.MapLibre.Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 | Community.Blazor.MapLibre.Examples.WebAssembly
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Layout/MainLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 |
3 |
6 |
7 |
8 |
11 |
12 |
13 | @Body
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Layout/MainLayout.razor.css:
--------------------------------------------------------------------------------
1 | .page {
2 | position: relative;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | main {
8 | flex: 1;
9 | }
10 |
11 | .sidebar {
12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
13 | }
14 |
15 | .top-row {
16 | background-color: #f7f7f7;
17 | border-bottom: 1px solid #d6d5d5;
18 | justify-content: flex-end;
19 | height: 3.5rem;
20 | display: flex;
21 | align-items: center;
22 | }
23 |
24 | .top-row ::deep a, .top-row ::deep .btn-link {
25 | white-space: nowrap;
26 | margin-left: 1.5rem;
27 | text-decoration: none;
28 | }
29 |
30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
31 | text-decoration: underline;
32 | }
33 |
34 | .top-row ::deep a:first-child {
35 | overflow: hidden;
36 | text-overflow: ellipsis;
37 | }
38 |
39 | @media (max-width: 640.98px) {
40 | .top-row {
41 | justify-content: space-between;
42 | }
43 |
44 | .top-row ::deep a, .top-row ::deep .btn-link {
45 | margin-left: 0;
46 | }
47 | }
48 |
49 | @media (min-width: 641px) {
50 | .page {
51 | flex-direction: row;
52 | }
53 |
54 | .sidebar {
55 | width: 250px;
56 | height: 100vh;
57 | position: sticky;
58 | top: 0;
59 | }
60 |
61 | .top-row {
62 | position: sticky;
63 | top: 0;
64 | z-index: 1;
65 | }
66 |
67 | .top-row.auth ::deep a:first-child {
68 | flex: 1;
69 | text-align: right;
70 | width: 0;
71 | }
72 |
73 | .top-row, article {
74 | padding-left: 2rem !important;
75 | padding-right: 1.5rem !important;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Layout/NavMenu.razor:
--------------------------------------------------------------------------------
1 |
9 |
10 |
22 |
23 | @code {
24 | private bool collapseNavMenu = true;
25 |
26 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
27 |
28 | private void ToggleNavMenu()
29 | {
30 | collapseNavMenu = !collapseNavMenu;
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Layout/NavMenu.razor.css:
--------------------------------------------------------------------------------
1 | .navbar-toggler {
2 | background-color: rgba(255, 255, 255, 0.1);
3 | }
4 |
5 | .top-row {
6 | height: 3.5rem;
7 | background-color: rgba(0,0,0,0.4);
8 | }
9 |
10 | .navbar-brand {
11 | font-size: 1.1rem;
12 | }
13 |
14 | .bi {
15 | display: inline-block;
16 | position: relative;
17 | width: 1.25rem;
18 | height: 1.25rem;
19 | margin-right: 0.75rem;
20 | top: -1px;
21 | background-size: cover;
22 | }
23 |
24 | .bi-house-door-fill-nav-menu {
25 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
26 | }
27 |
28 | .bi-plus-square-fill-nav-menu {
29 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
30 | }
31 |
32 | .bi-list-nested-nav-menu {
33 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
34 | }
35 |
36 | .nav-item {
37 | font-size: 0.9rem;
38 | padding-bottom: 0.5rem;
39 | }
40 |
41 | .nav-item:first-of-type {
42 | padding-top: 1rem;
43 | }
44 |
45 | .nav-item:last-of-type {
46 | padding-bottom: 1rem;
47 | }
48 |
49 | .nav-item ::deep a {
50 | color: #d7d7d7;
51 | border-radius: 4px;
52 | height: 3rem;
53 | display: flex;
54 | align-items: center;
55 | line-height: 3rem;
56 | }
57 |
58 | .nav-item ::deep a.active {
59 | background-color: rgba(255,255,255,0.37);
60 | color: white;
61 | }
62 |
63 | .nav-item ::deep a:hover {
64 | background-color: rgba(255,255,255,0.1);
65 | color: white;
66 | }
67 |
68 | @media (min-width: 641px) {
69 | .navbar-toggler {
70 | display: none;
71 | }
72 |
73 | .collapse {
74 | /* Never collapse the sidebar for wide screens */
75 | display: block;
76 | }
77 |
78 | .nav-scrollable {
79 | /* Allow sidebar to scroll for tall menus */
80 | height: calc(100vh - 3.5rem);
81 | overflow-y: auto;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Example.razor:
--------------------------------------------------------------------------------
1 | @page "/Example"
2 | @using Community.Blazor.MapLibre.Examples.WebAssembly.Shared
3 |
4 | Examples
5 |
6 | This is list of few example usages of the Blazor.MapLibre
7 |
8 |
9 |
10 | @foreach (var item in _samplesList)
11 | {
12 |
16 | }
17 |
18 |
19 |
20 |
21 | @code
22 | {
23 | private readonly List _samplesList =
24 | [
25 | new() { Title = "Load GeoJSON", Url = "Examples/LoadGeoJson", ImageUrl = "/img/examples/geojson.png"},
26 | new() { Title = "Add Listener", Url = "Examples/AddListener", ImageUrl = "/img/examples/listener.png" },
27 | new() { Title = "Fit Bounds", Url = "Examples/FitBounds", ImageUrl = "/img/examples/fitbounds.png" },
28 | new() { Title = "Create Popup", Url = "Examples/CreatePopup", ImageUrl = "/img/examples/popup.png" },
29 | new() { Title = "Render Globe", Url = "Examples/RenderGlobe", ImageUrl = "/img/examples/globe.png" }
30 | ];
31 |
32 | // ExampleItem class to store information
33 | private class MapSampleItem
34 | {
35 | public string Title { get; set; } = string.Empty;
36 | public string Url { get; set; } = string.Empty;
37 | public string ImageUrl { get; set; } = string.Empty;
38 | public string? Class { get; set; }
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/AddListener.razor:
--------------------------------------------------------------------------------
1 | @page "/Examples/AddListener"
2 | @using System.Text.Json
3 | @using Community.Blazor.MapLibre.Models
4 | AddListener
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 | <Map @ref="_map" OnLoad="HandleMapLoad" ></Map>
14 |
15 |
16 |
17 | @code
18 | {
19 | private Map _map { get; set; } = new Map();
20 | private readonly MapOptions _mapOptions = new()
21 | {
22 | Style = "https://demotiles.maplibre.org/style.json"
23 | };
24 | private async Task HandleMapLoad(EventArgs args)
25 | {
26 | // Add map listeners after it has loaded
27 | await _map.AddListener<dynamic>("click", OnClick);
28 | }
29 |
30 | public void OnClick(dynamic eventData)
31 | {
32 | Console.WriteLine(JsonSerializer.Serialize(eventData));
33 | Console.WriteLine("Layer has been clicked");
34 | }
35 | }
36 |
37 |
38 |
39 |
40 |
41 |
42 | @code {
43 | private MapLibre _mapListener { get; set; } = new MapLibre();
44 | private readonly MapOptions _mapOptions = new()
45 | {
46 | Style = "https://demotiles.maplibre.org/style.json"
47 | };
48 | private async Task HandleMapLoadListener(EventArgs args)
49 | {
50 | await _mapListener.AddListener("click", OnClick);
51 | }
52 | public void OnClick(dynamic eventData)
53 | {
54 | Console.WriteLine(JsonSerializer.Serialize(eventData));
55 | Console.WriteLine("Layer has been clicked");
56 | }
57 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/CreatePopup.razor:
--------------------------------------------------------------------------------
1 | @page "/Examples/CreatePopup"
2 | @using Community.Blazor.MapLibre.Models
3 | @using Community.Blazor.MapLibre.Models.Event
4 |
5 | Create Popup
6 |
7 |
12 |
13 |
14 | @code
15 | {
16 | private MapLibre? _map { get; set; }
17 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/CreatePopup.razor.cs:
--------------------------------------------------------------------------------
1 | using Community.Blazor.MapLibre.Models;
2 | using Community.Blazor.MapLibre.Models.Event;
3 |
4 | namespace Community.Blazor.MapLibre.Examples.WebAssembly.Pages.Examples;
5 |
6 | public partial class CreatePopup
7 | {
8 | private readonly MapOptions _mapOptions = new()
9 | {
10 | Style = "https://demotiles.maplibre.org/style.json"
11 | };
12 |
13 | private async Task OnMapLoad(EventArgs args)
14 | {
15 | if (_map is null)
16 | {
17 | return;
18 | }
19 |
20 | await _map.OnClick(null, e => AddPopup(e));
21 |
22 | async void AddPopup(MapMouseEvent evnt)
23 | {
24 | await _map.CreatePopup(new Popup
25 | {
26 | Content = $"""
27 |
28 |
Map clicked
29 |
You clicked the map at {evnt.LngLat.Latitude} {evnt.LngLat.Longitude}
30 |
31 | """,
32 | Coordinates = evnt.LngLat
33 | }, new PopupOptions
34 | {
35 | CloseOnClick = true,
36 | CloseOnMove = true,
37 | FocusAfterOpen = true,
38 | });
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/FitBounds.razor:
--------------------------------------------------------------------------------
1 | @page "/Examples/FitBounds"
2 | @using Community.Blazor.MapLibre.Models
3 | FitBounds
4 |
5 |
6 |
7 |
9 |
10 |
Fit Bounds
11 |
12 |
13 | @code {
14 | private MapLibre _mapListener { get; set; } = new MapLibre();
15 | private readonly MapOptions _mapOptions = new()
16 | {
17 | Style = "https://demotiles.maplibre.org/style.json"
18 | };
19 | private async Task HandleMapLoadListener(EventArgs args)
20 | {
21 | var bounds = new LngLatBounds()
22 | {
23 | Southwest = new LngLat(17.124277, 48.154861),
24 | Northeast = new LngLat(21.262986, 49.059367)
25 | };
26 |
27 | await _mapListener.FitBounds(bounds);
28 | }
29 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/LoadGeoJson.razor:
--------------------------------------------------------------------------------
1 | @page "/Examples/LoadGeoJson"
2 | @using Community.Blazor.MapLibre.Models
3 | @using Community.Blazor.MapLibre.Models.Feature
4 | @using Community.Blazor.MapLibre.Models.Layers
5 | @using Community.Blazor.MapLibre.Models.Sources
6 | LoadGeoJson
7 |
8 |
9 |
10 |
12 |
13 |
Add GEOJson
14 |
15 |
16 |
17 |
18 | <MapLibre @ref="_mapWithGeoJson" Options="_mapWithGeoJsonOptions" OnLoad="HandleMapLoadGeoJson" ></MapLibre>
19 | @@code {
20 | private Map _mapWithGeoJson { get; set; } = new Map();
21 | private readonly MapOptions _mapWithGeoJsonOptions = new MapOptions()
22 | {
23 | Style = "https://demotiles.maplibre.org/style.json",
24 | Center = new LngLat()
25 | {
26 | Latitude = 45.188193,
27 | Longitude = -68.991841
28 | },
29 | Zoom = 4
30 | };
31 | private async Task HandleMapLoadGeoJson(EventArgs args)
32 | {
33 | await _mapWithGeoJson.AddSource("maine", new GeoJsonSource()
34 | {
35 | Data = new FeatureFeature()
36 | {
37 | Geometry = new PolygonFeature()
38 | {
39 | Coordinates =
40 | [
41 | [
42 | [-67.13734351262877, 45.137451890638886],
43 | [-66.96466, 44.8097],
44 | [-68.03252, 44.3252],
45 | [-69.06, 43.98],
46 | [-70.11617, 43.68405],
47 | [-70.64573401557249, 43.090083319667144],
48 | [-70.75102474636725, 43.08003225358635],
49 | [-70.79761105007827, 43.21973948828747],
50 | [-70.98176001655037, 43.36789581966826],
51 | [-70.94416541205806, 43.46633942318431],
52 | [-71.08482, 45.3052400000002],
53 | [-70.6600225491012, 45.46022288673396],
54 | [-70.30495378282376, 45.914794623389355],
55 | [-70.00014034695016, 46.69317088478567],
56 | [-69.23708614772835, 47.44777598732787],
57 | [-68.90478084987546, 47.184794623394396],
58 | [-68.23430497910454, 47.35462921812177],
59 | [-67.79035274928509, 47.066248887716995],
60 | [-67.79141211614706, 45.702585354182816],
61 | [-67.13734351262877, 45.137451890638886],
62 | ]
63 | ]
64 | }
65 | }
66 | });
67 |
68 | await _mapWithGeoJson.AddLayer(new FillLayer()
69 | {
70 | Id = "GeoJsonLayerId",
71 | Source = "maine",
72 | Paint = new FillLayerPaint()
73 | {
74 | FillColor = "#088",
75 | FillOpacity = 0.8
76 | }
77 | });
78 | }
79 | }
80 |
81 |
82 |
83 |
84 |
85 | @code {
86 | private MapLibre _mapWithGeoJson { get; set; } = new MapLibre();
87 | private readonly MapOptions _mapWithGeoJsonOptions = new MapOptions()
88 | {
89 | Style = "https://demotiles.maplibre.org/style.json",
90 | Center = new LngLat
91 | {
92 | Latitude = 45.188193,
93 | Longitude = -68.991841
94 | },
95 | Zoom = 4
96 | };
97 | private async Task HandleMapLoadGeoJson(EventArgs args)
98 | {
99 | await _mapWithGeoJson.AddSource("maine", new GeoJsonSource()
100 | {
101 | Data = new FeatureFeature()
102 | {
103 | Geometry = new PolygonGeometry()
104 | {
105 | Coordinates =
106 | [
107 | [
108 | [-67.13734351262877, 45.137451890638886],
109 | [-66.96466, 44.8097],
110 | [-68.03252, 44.3252],
111 | [-69.06, 43.98],
112 | [-70.11617, 43.68405],
113 | [-70.64573401557249, 43.090083319667144],
114 | [-70.75102474636725, 43.08003225358635],
115 | [-70.79761105007827, 43.21973948828747],
116 | [-70.98176001655037, 43.36789581966826],
117 | [-70.94416541205806, 43.46633942318431],
118 | [-71.08482, 45.3052400000002],
119 | [-70.6600225491012, 45.46022288673396],
120 | [-70.30495378282376, 45.914794623389355],
121 | [-70.00014034695016, 46.69317088478567],
122 | [-69.23708614772835, 47.44777598732787],
123 | [-68.90478084987546, 47.184794623394396],
124 | [-68.23430497910454, 47.35462921812177],
125 | [-67.79035274928509, 47.066248887716995],
126 | [-67.79141211614706, 45.702585354182816],
127 | [-67.13734351262877, 45.137451890638886],
128 | ]
129 | ]
130 | }
131 | }
132 | });
133 |
134 | await _mapWithGeoJson.AddLayer(new FillLayer()
135 | {
136 | Id = "GeoJsonLayerId",
137 | Source = "maine",
138 | Paint = new FillLayerPaint()
139 | {
140 | FillColor = "#088",
141 | FillOpacity = 0.8
142 | }
143 | });
144 | }
145 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Examples/RenderGlobe.razor:
--------------------------------------------------------------------------------
1 | @page "/Examples/RenderGlobe"
2 | @using Community.Blazor.MapLibre.Models
3 |
4 | Render Globe
5 |
6 |
16 |
17 |
18 |
19 | @code {
20 | private MapLibre _mapListener { get; set; } = new MapLibre();
21 |
22 | private readonly MapOptions _mapOptions = new()
23 | {
24 | Style = "https://demotiles.maplibre.org/style.json"
25 | };
26 |
27 |
28 | private async Task OnStyleLoad(EventArgs args)
29 | {
30 | await _mapListener.SetProjection(new ProjectionSpecification()
31 | {
32 | Type = "globe"
33 | });
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Pages/Home.razor:
--------------------------------------------------------------------------------
1 | @page "/"
2 | @using Community.Blazor.MapLibre.Models
3 |
4 | Introduction
5 |
6 | Community.Blazor.Maplibre is a wrapper around MapLibre-GL-JS library
7 |
8 |
9 |
10 |
11 |
13 |
14 |
Basic map
15 |
16 |
17 |
18 | <MapLibre Options="_mapOptions" Class="rounded-top"
19 | Height="300px"></MapLibre>
20 |
21 | @@code
22 | {
23 | private readonly MapOptions _mapOptions = new()
24 | {
25 | Container = "UniqueMapId",
26 | Style = "https://demotiles.maplibre.org/style.json",
27 | Center = new LngLat()
28 | {
29 | Latitude = -2.320679,
30 | Longitude = 112.772537
31 | },
32 | Zoom = 3
33 | };
34 | }
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | @code
43 | {
44 | private readonly MapOptions _mapOptions = new()
45 | {
46 | Container = "UniqueMapId",
47 | Style = "https://demotiles.maplibre.org/style.json",
48 | Center = new LngLat()
49 | {
50 | Latitude = -2.320679,
51 | Longitude = 112.772537
52 | },
53 | Zoom = 3
54 | };
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Components.Web;
2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
3 | using Community.Blazor.MapLibre.Examples.WebAssembly;
4 |
5 | var builder = WebAssemblyHostBuilder.CreateDefault(args);
6 | builder.RootComponents.Add("#app");
7 | builder.RootComponents.Add("head::after");
8 |
9 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
10 |
11 | await builder.Build().RunAsync();
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:20456",
8 | "sslPort": 44353
9 | }
10 | },
11 | "profiles": {
12 | "http": {
13 | "commandName": "Project",
14 | "dotnetRunMessages": true,
15 | "launchBrowser": true,
16 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
17 | "applicationUrl": "http://localhost:5048",
18 | "environmentVariables": {
19 | "ASPNETCORE_ENVIRONMENT": "Development"
20 | }
21 | },
22 | "https": {
23 | "commandName": "Project",
24 | "dotnetRunMessages": true,
25 | "launchBrowser": true,
26 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
27 | "applicationUrl": "https://localhost:7278;http://localhost:5048",
28 | "environmentVariables": {
29 | "ASPNETCORE_ENVIRONMENT": "Development"
30 | }
31 | },
32 | "IIS Express": {
33 | "commandName": "IISExpress",
34 | "launchBrowser": true,
35 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
36 | "environmentVariables": {
37 | "ASPNETCORE_ENVIRONMENT": "Development"
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/Shared/GridCard.razor:
--------------------------------------------------------------------------------
1 | @inject NavigationManager NavigationManager
2 |
3 |
4 |
5 |

6 |
7 |
@Title
8 |
9 |
10 | @code {
11 |
12 | ///
13 | /// The title to be displayed in the card.
14 | ///
15 | [Parameter]
16 | public string? Title { get; set; }
17 |
18 | ///
19 | /// Optional CSS class names. If given, these will be included in the class attribute of the component.
20 | ///
21 | [Parameter]
22 | public virtual string? Class { get; set; } = null;
23 |
24 | [Parameter]
25 | public string ImageUrl { get; set; } = "https://placehold.co/600x200/png";
26 |
27 | ///
28 | /// The target URL for navigation when the card is clicked.
29 | ///
30 | [Parameter]
31 | public string? TargetUrl { get; set; }
32 |
33 | ///
34 | /// Handles the click event on the card and navigates to the specified TargetUrl if it is not null or empty.
35 | ///
36 | private void NavigateToPage()
37 | {
38 | if (!string.IsNullOrEmpty(TargetUrl))
39 | {
40 | NavigationManager.NavigateTo(TargetUrl); // Navigate to the specified URL
41 | }
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using System.Net.Http
2 | @using System.Net.Http.Json
3 | @using Microsoft.AspNetCore.Components.Forms
4 | @using Microsoft.AspNetCore.Components.Routing
5 | @using Microsoft.AspNetCore.Components.Web
6 | @using Microsoft.AspNetCore.Components.Web.Virtualization
7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http
8 | @using Microsoft.JSInterop
9 | @using Community.Blazor.MapLibre.Examples.WebAssembly
10 | @using Community.Blazor.MapLibre.Examples.WebAssembly.Layout
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/css/app.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
3 | }
4 |
5 | h1:focus {
6 | outline: none;
7 | }
8 |
9 | a, .btn-link {
10 | color: #0071c1;
11 | }
12 |
13 | .btn-primary {
14 | color: #fff;
15 | background-color: #1b6ec2;
16 | border-color: #1861ac;
17 | }
18 |
19 | .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
20 | box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
21 | }
22 |
23 | .content {
24 | padding-top: 1.1rem;
25 | }
26 |
27 | .valid.modified:not([type=checkbox]) {
28 | outline: 1px solid #26b050;
29 | }
30 |
31 | .invalid {
32 | outline: 1px solid red;
33 | }
34 |
35 | .validation-message {
36 | color: red;
37 | }
38 |
39 | #blazor-error-ui {
40 | background: lightyellow;
41 | bottom: 0;
42 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
43 | display: none;
44 | left: 0;
45 | padding: 0.6rem 1.25rem 0.7rem 1.25rem;
46 | position: fixed;
47 | width: 100%;
48 | z-index: 1000;
49 | }
50 |
51 | #blazor-error-ui .dismiss {
52 | cursor: pointer;
53 | position: absolute;
54 | right: 0.75rem;
55 | top: 0.5rem;
56 | }
57 |
58 | .blazor-error-boundary {
59 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
60 | padding: 1rem 1rem 1rem 3.7rem;
61 | color: white;
62 | }
63 |
64 | .blazor-error-boundary::after {
65 | content: "An error has occurred."
66 | }
67 |
68 | .loading-progress {
69 | position: relative;
70 | display: block;
71 | width: 8rem;
72 | height: 8rem;
73 | margin: 20vh auto 1rem auto;
74 | }
75 |
76 | .loading-progress circle {
77 | fill: none;
78 | stroke: #e0e0e0;
79 | stroke-width: 0.6rem;
80 | transform-origin: 50% 50%;
81 | transform: rotate(-90deg);
82 | }
83 |
84 | .loading-progress circle:last-child {
85 | stroke: #1b6ec2;
86 | stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
87 | transition: stroke-dasharray 0.05s ease-in-out;
88 | }
89 |
90 | .loading-progress-text {
91 | position: absolute;
92 | text-align: center;
93 | font-weight: bold;
94 | inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
95 | }
96 |
97 | .loading-progress-text:after {
98 | content: var(--blazor-load-percentage-text, "Loading");
99 | }
100 |
101 | code {
102 | color: #c02d76;
103 | }
104 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/favicon.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/icon-192.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/basic.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/fitbounds.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/fitbounds.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/geojson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/geojson.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/globe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/globe.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/listener.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/listener.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/popup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre.Examples/wwwroot/img/examples/popup.png
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Community.Blazor.MapLibre.Examples
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 | An unhandled error has occurred.
32 |
Reload
33 |
🗙
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/sample-data/weather.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "date": "2022-01-06",
4 | "temperatureC": 1,
5 | "summary": "Freezing"
6 | },
7 | {
8 | "date": "2022-01-07",
9 | "temperatureC": 14,
10 | "summary": "Bracing"
11 | },
12 | {
13 | "date": "2022-01-08",
14 | "temperatureC": -13,
15 | "summary": "Freezing"
16 | },
17 | {
18 | "date": "2022-01-09",
19 | "temperatureC": -16,
20 | "summary": "Balmy"
21 | },
22 | {
23 | "date": "2022-01-10",
24 | "temperatureC": -2,
25 | "summary": "Chilly"
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.Examples/wwwroot/staticwebapp.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationFallback": {
3 | "rewrite": "/index.html"
4 | }
5 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Community.Blazor.MapLibre", "Community.Blazor.MapLibre\Community.Blazor.MapLibre.csproj", "{3DA04D2B-0D7F-428F-86B7-C4ACBCE2BA56}"
4 | EndProject
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Community.Blazor.MapLibre.Examples", "Community.Blazor.MapLibre.Examples\Community.Blazor.MapLibre.Examples.csproj", "{44214551-FA9D-4809-87EA-7843BDB18397}"
6 | EndProject
7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "items", "items", "{FB2BD75E-3038-46E3-B3D9-851ADD3E045B}"
8 | ProjectSection(SolutionItems) = preProject
9 | global.json = global.json
10 | README.md = README.md
11 | UNLICENSE = UNLICENSE
12 | EndProjectSection
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{1041976B-4110-4B6A-9130-0144068C0638}"
15 | ProjectSection(SolutionItems) = preProject
16 | .github\workflows\build-deploy-publish.yml = .github\workflows\build-deploy-publish.yml
17 | .github\workflows\pr-build-test.yml = .github\workflows\pr-build-test.yml
18 | .github\workflows\codeql.yml = .github\workflows\codeql.yml
19 | EndProjectSection
20 | EndProject
21 | Global
22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
23 | Debug|Any CPU = Debug|Any CPU
24 | Release|Any CPU = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
27 | {3DA04D2B-0D7F-428F-86B7-C4ACBCE2BA56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {3DA04D2B-0D7F-428F-86B7-C4ACBCE2BA56}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {3DA04D2B-0D7F-428F-86B7-C4ACBCE2BA56}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {3DA04D2B-0D7F-428F-86B7-C4ACBCE2BA56}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {44214551-FA9D-4809-87EA-7843BDB18397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {44214551-FA9D-4809-87EA-7843BDB18397}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {44214551-FA9D-4809-87EA-7843BDB18397}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {44214551-FA9D-4809-87EA-7843BDB18397}.Release|Any CPU.Build.0 = Release|Any CPU
35 | EndGlobalSection
36 | GlobalSection(NestedProjects) = preSolution
37 | {1041976B-4110-4B6A-9130-0144068C0638} = {FB2BD75E-3038-46E3-B3D9-851ADD3E045B}
38 | EndGlobalSection
39 | EndGlobal
40 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/CallbackHandler.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.JSInterop;
2 | using System.Text.Json;
3 |
4 | namespace Community.Blazor.MapLibre;
5 |
6 | ///
7 | /// Represents a callback action to handle JavaScript events in C#.
8 | ///
9 | public class CallbackHandler
10 | {
11 | private readonly IJSObjectReference _jsRuntimeReference;
12 | private readonly string _eventType;
13 | private readonly Delegate _callbackDelegate;
14 | private readonly Type? _argumentType;
15 |
16 | ///
17 | /// Constructor for initializing a callback handler with arguments.
18 | ///
19 | /// Reference to the JavaScript runtime object.
20 | /// Type of the event (e.g., click, drag).
21 | /// The C# delegate to invoke when the event is triggered.
22 | /// The type of the argument expected for the callback delegate.
23 | public CallbackHandler(IJSObjectReference jsRuntimeReference, string eventType, Delegate callbackDelegate, Type argumentType)
24 | {
25 | _jsRuntimeReference = jsRuntimeReference;
26 | _eventType = eventType;
27 | _callbackDelegate = callbackDelegate;
28 | _argumentType = argumentType;
29 | }
30 |
31 | ///
32 | /// Constructor for initializing a callback handler without arguments.
33 | ///
34 | /// Reference to the JavaScript runtime object.
35 | /// Type of the event (e.g., click, drag).
36 | /// The C# delegate to invoke when the event is triggered.
37 | public CallbackHandler(IJSObjectReference jsRuntimeReference, string eventType, Delegate callbackDelegate)
38 | {
39 | _jsRuntimeReference = jsRuntimeReference;
40 | _eventType = eventType;
41 | _callbackDelegate = callbackDelegate;
42 | }
43 |
44 | ///
45 | /// Removes the event listener in JavaScript (placeholder implementation).
46 | ///
47 | public async Task RemoveAsync()
48 | {
49 | await Task.CompletedTask; // Placeholder to maintain async signature.
50 | }
51 |
52 | ///
53 | /// Invokes the callback with arguments from JavaScript.
54 | ///
55 | /// Serialized JSON arguments from JavaScript.
56 | [JSInvokable]
57 | public void Invoke(string args)
58 | {
59 | if (string.IsNullOrWhiteSpace(args) || _argumentType is null)
60 | {
61 | _callbackDelegate.DynamicInvoke(); // Invoke delegate without arguments.
62 | return;
63 | }
64 |
65 | // Deserialize arguments into the expected type.
66 | var deserializedArgs = JsonSerializer.Deserialize(args, _argumentType);
67 |
68 | // Invoke delegate with deserialized arguments.
69 | _callbackDelegate.DynamicInvoke(deserializedArgs);
70 | }
71 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Community.Blazor.MapLibre.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 |
8 | Community.Blazor.MapLibre
9 | 1.0.1
10 | Yet-Another-Solution
11 | C# Wrapper around a MapLibre GL JS library
12 | https://opensource.org/license/unlicense
13 | https://github.com/Yet-another-solution/Blazor.MapLibre
14 | Blazor; MapLibre; Components
15 | https://maplibre.org/img/maplibre-logos/maplibre-logo-square-dark-blue-bg.png
16 | Community.Blazor.MapLibre
17 | README.md
18 |
19 |
20 | true
21 | 1591
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Converter/OneOfConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using System.Text.Json.Nodes;
3 | using System.Text.Json.Serialization;
4 | using OneOf;
5 |
6 | namespace Community.Blazor.MapLibre.Converter;
7 |
8 | public class OneOfJsonConverter : JsonConverter>
9 | {
10 | public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
11 | {
12 | if (reader.TokenType != JsonTokenType.StartArray)
13 | {
14 | var t1 = JsonSerializer.Deserialize(ref reader, options);
15 | return OneOf.FromT0(t1!);
16 | }
17 |
18 | throw new NotImplementedException("This converter is only intended for serialization.");
19 | }
20 |
21 | public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOptions options)
22 | {
23 | value.Switch(
24 | v1 => JsonSerializer.Serialize(writer, v1, options),
25 | v2 => JsonSerializer.Serialize(writer, v2, options)
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Listener.cs:
--------------------------------------------------------------------------------
1 | namespace Community.Blazor.MapLibre;
2 |
3 | ///
4 | /// Represents a listener that handles the removal of a registered event listener.
5 | ///
6 | ///
7 | /// The Listener class provides a mechanism to manage the lifecycle of event listeners associated with a MapLibre map object.
8 | /// It ensures that resources tied to the listener, such as JavaScript event handlers, are properly disposed when no longer needed.
9 | ///
10 | public class Listener(CallbackHandler action) : IDisposable
11 | {
12 | public void Dispose()
13 | {
14 | _ = Remove();
15 | }
16 |
17 | public async Task Remove()
18 | {
19 | await action.RemoveAsync();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/MapLibre.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/MapLibre.razor.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yet-another-solution/Blazor.MapLibre/e3846785432cd92f712aab73cc5b42d52ed37eb9/Community.Blazor.MapLibre/MapLibre.razor.css
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/BulkTransaction.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models;
4 |
5 | ///
6 | /// Represents a bulk transaction to be sent to the MapLibre map.
7 | /// This can be used to send multiple layers and sources to the map in a websocket message.
8 | /// This can be useful to reduce the roundtrip time when adding multiple layers and sources to the map.
9 | ///
10 | public class BulkTransaction
11 | {
12 | public List Transactions { get; } = [];
13 |
14 | public void Add(string eventName, params object?[]? data)
15 | {
16 | Transactions.Add(new Transaction
17 | {
18 | Event = eventName,
19 | Data = data
20 | });
21 | }
22 | }
23 |
24 | public class Transaction
25 | {
26 | [JsonPropertyName("event")]
27 | public required string Event { get; set; }
28 |
29 | [JsonPropertyName("data")]
30 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
31 | public object?[]? Data { get; set; }
32 | }
33 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/AnimationOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Camera;
4 |
5 | ///
6 | /// Defines options common to map movement methods that involve animation, such as Map#panBy and Map#easeTo.
7 | ///
8 | ///
9 | /// Controls the duration and easing function of the animation. All properties are optional.
10 | ///
11 | public interface IAnimationOptions
12 | {
13 | ///
14 | /// Determines whether animation occurs.
15 | ///
16 | ///
17 | /// If set to false, no animation will occur.
18 | ///
19 | bool? Animate { get; set; }
20 |
21 | ///
22 | /// The animation's duration, measured in milliseconds.
23 | ///
24 | double? Duration { get; set; }
25 |
26 | ///
27 | /// A function that takes a time in the range 0..1 and returns a number where 0 is the initial state and 1 is the final state.
28 | ///
29 | Func? Easing { get; set; }
30 |
31 | ///
32 | /// If true, the animation is considered essential and will not be affected by prefers-reduced-motion.
33 | ///
34 | bool? Essential { get; set; }
35 |
36 | ///
37 | /// Determines whether the camera remains at a constant height based on sea level in 3D maps.
38 | ///
39 | ///
40 | /// Defaults to false. If set to true, the zoom level is recalculated after the animation
41 | /// to maintain the correct distance from the camera to the center-coordinate-altitude.
42 | ///
43 | bool? FreezeElevation { get; set; }
44 |
45 | ///
46 | /// The offset of the target center relative to the real map container center at the end of the animation.
47 | ///
48 | PointLike? Offset { get; set; }
49 | }
50 |
51 | public class AnimationOptions : IAnimationOptions
52 | {
53 | ///
54 | [JsonPropertyName("animate")]
55 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
56 | public bool? Animate { get; set; }
57 |
58 | ///
59 | [JsonPropertyName("duration")]
60 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
61 | public double? Duration { get; set; }
62 |
63 | ///
64 | [JsonPropertyName("easing")]
65 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
66 | public Func? Easing { get; set; }
67 |
68 | ///
69 | [JsonPropertyName("essential")]
70 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
71 | public bool? Essential { get; set; }
72 |
73 | ///
74 | [JsonPropertyName("freezeElevation")]
75 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
76 | public bool? FreezeElevation { get; set; }
77 |
78 | ///
79 | [JsonPropertyName("offset")]
80 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
81 | public PointLike? Offset { get; set; }
82 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/CameraForBoundsOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 | using Community.Blazor.MapLibre.Models.Padding;
3 | using OneOf;
4 |
5 | namespace Community.Blazor.MapLibre.Models.Camera;
6 |
7 | public class CameraForBoundsOptions : CameraOptions
8 | {
9 | ///
10 | /// The maximum zoom level to allow when the camera would transition to the specified bounds.
11 | ///
12 | [JsonPropertyName("maxZoom")]
13 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
14 | public decimal? MaxZoom { get; set; }
15 | ///
16 | /// The center of the given bounds relative to the map's center, measured in pixels.
17 | ///
18 | [JsonPropertyName("offset")]
19 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
20 | public PointLike? Offset { get; set; }
21 | ///
22 | /// The amount of padding in pixels to add to the given bounds.
23 | ///
24 | [JsonPropertyName("padding")]
25 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
26 | public OneOf Padding { get; set; }
27 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/CameraOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Camera;
4 |
5 | ///
6 | /// Options controlling the desired location, zoom, bearing, pitch, roll, and elevation of the camera.
7 | /// Used with JumpTo, EaseTo, and FlyTo. All properties are optional;
8 | /// if omitted, the current camera values remain unchanged.
9 | ///
10 | public class CameraOptions : ICameraOptions
11 | {
12 |
13 | //
14 | [JsonPropertyName("center")]
15 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
16 | public LngLat? Center { get; set; }
17 |
18 | //
19 | [JsonPropertyName("zoom")]
20 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
21 | public double? Zoom { get; set; }
22 |
23 | //
24 | [JsonPropertyName("bearing")]
25 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
26 | public double? Bearing { get; set; }
27 |
28 | //
29 | [JsonPropertyName("elevation")]
30 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
31 | public double? Elevation { get; set; }
32 |
33 | //
34 | [JsonPropertyName("pitch")]
35 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
36 | public double? Pitch { get; set; }
37 |
38 | //
39 | [JsonPropertyName("roll")]
40 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
41 | public double? Roll { get; set; }
42 | }
43 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/CenterZoomBearing.cs:
--------------------------------------------------------------------------------
1 | namespace Community.Blazor.MapLibre.Models.Camera;
2 |
3 | public class CenterZoomBearing : ICenterZoomBearing
4 | {
5 | public LngLat? Center { get; set; }
6 | public double? Zoom { get; set; }
7 | public double? Bearing { get; set; }
8 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/EaseToOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 | using Community.Blazor.MapLibre.Models.Padding;
3 | using OneOf;
4 |
5 | namespace Community.Blazor.MapLibre.Models.Camera;
6 |
7 | public class EaseToOptions : IAnimationOptions, ICameraOptions
8 | {
9 |
10 | ///
11 | /// If `zoom` is specified, `around` determines the point around which the zoom is centered.
12 | ///
13 | [JsonPropertyName("animate")]
14 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
15 | public LngLat? Around { get; set; }
16 |
17 | [JsonPropertyName("delayEndEvents")]
18 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
19 | public double? DelayEndEvents { get; set; }
20 |
21 | [JsonPropertyName("easeId")]
22 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
23 | public string? EaseId { get; set; }
24 |
25 | [JsonPropertyName("noMoveStart")]
26 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
27 | public bool? NoMoveStart { get; set; }
28 |
29 | [JsonPropertyName("padding")]
30 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
31 | public OneOf? Padding { get; set; }
32 |
33 | #region IAnimationOptions
34 |
35 | ///
36 | [JsonPropertyName("animate")]
37 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
38 | public bool? Animate { get; set; }
39 |
40 | ///
41 | [JsonPropertyName("duration")]
42 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
43 | public double? Duration { get; set; }
44 |
45 | ///
46 | [JsonPropertyName("easing")]
47 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
48 | public Func? Easing { get; set; }
49 |
50 | ///
51 | [JsonPropertyName("essential")]
52 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
53 | public bool? Essential { get; set; }
54 |
55 | ///
56 | [JsonPropertyName("freezeElevation")]
57 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
58 | public bool? FreezeElevation { get; set; }
59 |
60 | ///
61 | [JsonPropertyName("offset")]
62 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
63 | public PointLike? Offset { get; set; }
64 |
65 | #endregion
66 |
67 | #region ICameraOptions
68 |
69 | ///
70 | [JsonPropertyName("pitch")]
71 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
72 | public double? Pitch { get; set; }
73 |
74 | ///
75 | [JsonPropertyName("roll")]
76 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
77 | public double? Roll { get; set; }
78 |
79 | ///
80 | [JsonPropertyName("elevation")]
81 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
82 | public double? Elevation { get; set; }
83 |
84 | #region ICenterZoomBearing
85 |
86 | ///
87 | public LngLat? Center { get; set; }
88 |
89 | ///
90 | public double? Zoom { get; set; }
91 |
92 | ///
93 | public double? Bearing { get; set; }
94 |
95 | #endregion
96 |
97 | #endregion
98 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/FitBoundOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Camera;
4 |
5 | public class FitBoundOptions : FlyToOptions
6 | {
7 | ///
8 | /// If `true`, the map transitions using {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}.
9 | /// See those functions and {@link AnimationOptions} for information about options available.
10 | /// @defaultValue false
11 | ///
12 | [JsonPropertyName("linear")]
13 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
14 | public bool? Linear { get; set; }
15 |
16 | ///
17 | /// The maximum zoom level to allow when the map view transitions to the specified bounds.
18 | ///
19 | [JsonPropertyName("maxZoom")]
20 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
21 | public double? MaxZoom { get; set; }
22 |
23 | ///
24 | /// The center of the given bounds relative to the map's center, measured in pixels.
25 | ///
26 | [JsonPropertyName("offset")]
27 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
28 | public new PointLike? Offset { get; set; }
29 | }
30 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/FlyToOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Camera;
4 |
5 | public class FlyToOptions : IAnimationOptions, ICameraOptions
6 | {
7 | ///
8 | /// The zooming "curve" that will occur along the flight path.
9 | ///
10 | ///
11 | /// A high value maximizes zooming for an exaggerated animation, while a low value minimizes zooming for an effect closer to Map#easeTo.
12 | /// 1.42 is the average value selected in a user study discussed in van Wijk (2003).
13 | /// A value of Math.Pow(6, 0.25) would be equivalent to the root mean squared average velocity.
14 | /// A value of 1 would produce a circular motion.
15 | ///
16 | [JsonPropertyName("curve")]
17 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
18 | public double? Curve { get; set; }
19 |
20 | ///
21 | /// The animation's maximum duration, measured in milliseconds.
22 | ///
23 | ///
24 | /// If the duration exceeds the maximum duration, it resets to 0.
25 | ///
26 | [JsonPropertyName("maxDuration")]
27 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
28 | public double? MaxDuration { get; set; }
29 |
30 | ///
31 | /// The zero-based zoom level at the peak of the flight path.
32 | ///
33 | ///
34 | /// If options.curve is specified, this option is ignored.
35 | ///
36 | [JsonPropertyName("minZoom")]
37 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
38 | public double? MinZoom { get; set; }
39 |
40 | ///
41 | /// The amount of padding in pixels to add to the given bounds.
42 | ///
43 | [JsonPropertyName("padding")]
44 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
45 | public double? Padding { get; set; }
46 |
47 | ///
48 | /// The average speed of the animation measured in screenfuls per second, assuming a linear timing curve.
49 | ///
50 | ///
51 | /// If options.speed is specified, this option is ignored.
52 | ///
53 | [JsonPropertyName("screenSpeed")]
54 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
55 | public double? ScreenSpeed { get; set; }
56 |
57 | ///
58 | /// The average speed of the animation defined in relation to options.curve.
59 | ///
60 | ///
61 | /// A speed of 1.2 means that the map appears to move along the flight path by 1.2 times options.curve screenfuls every second.
62 | /// A screenful is the map's visible span and does not correspond to a fixed physical distance, but varies by zoom level.
63 | ///
64 | [JsonPropertyName("speed")]
65 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
66 | public double? Speed { get; set; }
67 |
68 | #region Interfaces
69 |
70 | ///
71 | [JsonPropertyName("animate")]
72 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
73 | public bool? Animate { get; set; }
74 |
75 | ///
76 | [JsonPropertyName("duration")]
77 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
78 | public double? Duration { get; set; }
79 |
80 | ///
81 | [JsonPropertyName("easing")]
82 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
83 | public Func? Easing { get; set; }
84 |
85 | ///
86 | [JsonPropertyName("essential")]
87 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
88 | public bool? Essential { get; set; }
89 |
90 | ///
91 | [JsonPropertyName("freezeElevation")]
92 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
93 | public bool? FreezeElevation { get; set; }
94 |
95 | ///
96 | [JsonPropertyName("offset")]
97 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
98 | public PointLike? Offset { get; set; }
99 |
100 | ///
101 | [JsonPropertyName("center")]
102 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
103 | public LngLat? Center { get; set; }
104 |
105 | ///
106 | [JsonPropertyName("zoom")]
107 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
108 | public double? Zoom { get; set; }
109 |
110 | ///
111 | [JsonPropertyName("bearing")]
112 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
113 | public double? Bearing { get; set; }
114 |
115 | ///
116 | [JsonPropertyName("pitch")]
117 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
118 | public double? Pitch { get; set; }
119 |
120 | ///
121 | [JsonPropertyName("roll")]
122 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
123 | public double? Roll { get; set; }
124 |
125 | ///
126 | [JsonPropertyName("elevation")]
127 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
128 | public double? Elevation { get; set; }
129 |
130 | #endregion
131 | }
132 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/ICameraOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Camera;
4 |
5 | ///
6 | /// Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo}, controlling the desired location,
7 | /// zoom, bearing, pitch, and roll of the camera. All properties are optional, and when a property is omitted, the current
8 | /// camera value for that property will remain unchanged.
9 | ///
10 | public interface ICameraOptions : ICenterZoomBearing
11 | {
12 | ///
13 | /// The desired pitch in degrees. The pitch is the angle towards the horizon
14 | /// measured in degrees with a range between 0 and 60 degrees. For example, pitch: 0 provides the appearance
15 | /// of looking straight down at the map, while pitch: 60 tilts the user's perspective towards the horizon.
16 | /// Increasing the pitch value is often used to display 3D objects.
17 | ///
18 | [JsonPropertyName("pitch")]
19 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
20 | public double? Pitch { get; set; }
21 |
22 | ///
23 | /// The desired roll in degrees. The roll is the angle about the camera boresight.
24 | ///
25 | [JsonPropertyName("roll")]
26 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
27 | public double? Roll { get; set; }
28 |
29 | ///
30 | /// The elevation of the center point in meters above sea level.
31 | ///
32 | [JsonPropertyName("elevation")]
33 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
34 | public double? Elevation { get; set; }
35 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/ICenterZoomBearing.cs:
--------------------------------------------------------------------------------
1 | namespace Community.Blazor.MapLibre.Models.Camera;
2 |
3 | ///
4 | /// Holds center, zoom and bearing properties
5 | ///
6 | public interface ICenterZoomBearing
7 | {
8 | ///
9 | /// The desired center.
10 | ///
11 | public LngLat? Center { get; set; }
12 |
13 | ///
14 | /// The desired mercator zoom level.
15 | ///
16 | public double? Zoom { get; set; }
17 |
18 | ///
19 | /// The desired bearing in degrees. The bearing is the compass direction that
20 | /// is "up". For example, `bearing: 90` orients the map so that east is up.
21 | ///
22 | public double? Bearing { get; set; }
23 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Camera/JumpToOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 | using Community.Blazor.MapLibre.Models.Padding;
3 |
4 | namespace Community.Blazor.MapLibre.Models.Camera;
5 |
6 | public class JumpToOptions : CameraOptions
7 | {
8 | ///
9 | /// Dimensions in pixels applied on each side of the viewport for shifting the vanishing point.
10 | ///
11 | [JsonPropertyName("padding")]
12 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
13 | public PaddingOptions? Padding { get; set; }
14 |
15 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Control/ControlPosition.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Control;
4 |
5 | ///
6 | /// A position defintion for the control to be placed, can be in one of the corners of the map. When two or more controls are places in the same location they are stacked toward the center of the map.
7 | ///
8 | public enum ControlPosition
9 | {
10 | [JsonStringEnumMemberName("top-left")]
11 | TopLeft,
12 |
13 | [JsonStringEnumMemberName("top-right")]
14 | TopRight,
15 |
16 | [JsonStringEnumMemberName("bottom-left")]
17 | BottomLeft,
18 |
19 | [JsonStringEnumMemberName("bottom-right")]
20 | BottomRight
21 | }
22 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Control/ControlType.cs:
--------------------------------------------------------------------------------
1 | namespace Community.Blazor.MapLibre.Models.Control;
2 |
3 | public enum ControlType
4 | {
5 | AttributionControl,
6 | FullscreenControl,
7 | GeolocateControl,
8 | GlobeControl,
9 | LogoControl,
10 | NavigationControl,
11 | ScaleControl,
12 | TerrainControl
13 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Event/EventType.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Event;
4 |
5 | public enum EventType
6 | {
7 | [JsonStringEnumMemberName("click")]
8 | Click,
9 |
10 | [JsonStringEnumMemberName("contextmenu")]
11 | ContextMenu,
12 |
13 | [JsonStringEnumMemberName("dblclick")]
14 | DblClick,
15 |
16 | [JsonStringEnumMemberName("mousedown")]
17 | MouseDown,
18 |
19 | [JsonStringEnumMemberName("mouseenter")]
20 | MouseEnter,
21 |
22 | [JsonStringEnumMemberName("mouseleave")]
23 | MouseLeave,
24 |
25 | [JsonStringEnumMemberName("mousemove")]
26 | MouseMove,
27 |
28 | [JsonStringEnumMemberName("mouseout")]
29 | MouseOut,
30 |
31 | [JsonStringEnumMemberName("mouseover")]
32 | MouseOver,
33 |
34 | [JsonStringEnumMemberName("mouseup")]
35 | MouseUp
36 | }
37 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Event/MapMouseEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using System.Text.Json.Serialization;
3 | using Community.Blazor.MapLibre.Models.Feature;
4 |
5 | namespace Community.Blazor.MapLibre.Models.Event;
6 |
7 | public class MapMouseEvent
8 | {
9 | [JsonPropertyName("point")]
10 | public required PointLike Point { get; set; }
11 |
12 | [JsonPropertyName("lngLat")]
13 | public required LngLat LngLat { get; set; }
14 |
15 | [JsonPropertyName("type")]
16 | [JsonConverter(typeof(JsonStringEnumConverter))]
17 | public required EventType Type { get; set; }
18 |
19 | [JsonPropertyName("_defaultPrevented")]
20 | public bool? DefaultPrevented { get; set; }
21 |
22 | /// This is currently a , as we cannot fully deserialize atm.
23 | /// Once layers can be successfully deserialize, this can be changed to .
24 | [JsonPropertyName("features")]
25 | public List Features { get; set; } = [];
26 | }
27 |
28 | public class SimpleFeature
29 | {
30 | [JsonPropertyName("type")]
31 | public required string Type { get; set; }
32 |
33 | [JsonPropertyName("geometry")]
34 | public required IGeometry Geometry { get; set; }
35 |
36 | [JsonPropertyName("properties")]
37 | public Dictionary Properties { get; set; } = [];
38 | }
39 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/FeatureCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class FeatureCollection : IFeature
6 | {
7 | [JsonPropertyName("type")]
8 | public string Type => "FeatureCollection";
9 |
10 | [JsonPropertyName("features")]
11 | public List Features { get; set; } = [];
12 |
13 | ///
14 | ///
15 | ///
16 | public LngLatBounds GetBounds()
17 | {
18 | if (Features.Count == 0)
19 | {
20 | return new LngLatBounds
21 | {
22 | Southwest = new LngLat(0, 0),
23 | Northeast = new LngLat(0, 0)
24 | };
25 | }
26 |
27 | var bounds = Features[0].GetBounds();
28 | for (var i = 1; i < Features.Count; i++)
29 | {
30 | bounds.Extend(Features[i].GetBounds());
31 | }
32 |
33 | return bounds;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/FeatureFeature.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class FeatureFeature : IFeature
6 | {
7 | [JsonPropertyName("type")]
8 | public string Type => "Feature";
9 |
10 | [JsonPropertyName("geometry")]
11 | public required IGeometry Geometry { get; set; }
12 |
13 | [JsonPropertyName("properties")]
14 | public Dictionary? Properties { get; set; }
15 |
16 | ///
17 | ///
18 | ///
19 | public LngLatBounds GetBounds() => Geometry.GetBounds();
20 | }
21 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/FeatureIdentifier.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class FeatureIdentifier
6 | {
7 | ///
8 | /// Unique id of the feature.
9 | ///
10 | [JsonPropertyName("id")]
11 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
12 | public string? Id { get; set; }
13 |
14 | ///
15 | /// The id of the vector or GeoJSON source for the feature.
16 | ///
17 | [JsonPropertyName("source")]
18 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
19 | public string? Source { get; set; }
20 |
21 | ///
22 | /// For vector tile sources, sourceLayer is required.
23 | ///
24 | [JsonPropertyName("sourceLayer")]
25 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
26 | public string? SourceLayer { get; set; }
27 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/GeometryType.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | [JsonConverter(typeof(JsonStringEnumConverter))]
6 | public enum GeometryType
7 | {
8 | [JsonStringEnumMemberName("Point")]
9 | Point,
10 | [JsonStringEnumMemberName("MultiPoint")]
11 | MultiPoint,
12 |
13 | [JsonStringEnumMemberName("LineString")]
14 | Line,
15 | [JsonStringEnumMemberName("MultiLineString")]
16 | MultiLine,
17 |
18 | [JsonStringEnumMemberName("Polygon")]
19 | Polygon,
20 | [JsonStringEnumMemberName("MultiPolygon")]
21 | MultiPolygon
22 | }
23 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/IFeature.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | [JsonDerivedType(typeof(FeatureCollection))]
6 | [JsonDerivedType(typeof(FeatureFeature))]
7 | public interface IFeature
8 | {
9 | [JsonPropertyName("type")]
10 | string Type { get; }
11 |
12 | ///
13 | /// Gets the bounding box of the geometry.
14 | ///
15 | ///
16 | /// A object representing the bounding box of the geometry.
17 | ///
18 | LngLatBounds GetBounds();
19 | }
20 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/IGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | [JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
6 | [JsonDerivedType(typeof(LineGeometry), typeDiscriminator: "LineString")]
7 | [JsonDerivedType(typeof(MultiLineGeometry), typeDiscriminator: "MultiLineString")]
8 | [JsonDerivedType(typeof(MultiPointGeometry), typeDiscriminator: "MultiPoint")]
9 | [JsonDerivedType(typeof(MultiPolygonGeometry), typeDiscriminator: "MultiPolygon")]
10 | [JsonDerivedType(typeof(PointGeometry), typeDiscriminator: "Point")]
11 | [JsonDerivedType(typeof(PolygonGeometry), typeDiscriminator: "Polygon")]
12 | public interface IGeometry
13 | {
14 | [JsonPropertyName("type")]
15 | GeometryType Type { get; }
16 |
17 | ///
18 | /// Gets the bounding box of the geometry.
19 | ///
20 | ///
21 | /// A object representing the bounding box of the geometry.
22 | ///
23 | LngLatBounds GetBounds();
24 | }
25 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/LineGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class LineGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.Line;
9 |
10 | [JsonPropertyName("coordinates")]
11 | public required double[][] Coordinates { get; set; }
12 |
13 | ///
14 | ///
15 | ///
16 | public LngLatBounds GetBounds()
17 | {
18 | if (Coordinates.Length == 0)
19 | {
20 | return new LngLatBounds
21 | {
22 | Southwest = new LngLat(0, 0),
23 | Northeast = new LngLat(0, 0)
24 | };
25 | }
26 |
27 | var minLng = double.MaxValue;
28 | var minLat = double.MaxValue;
29 | var maxLng = double.MinValue;
30 | var maxLat = double.MinValue;
31 |
32 | foreach (var coordinates in Coordinates)
33 | {
34 | minLng = Math.Min(minLng, coordinates[0]);
35 | minLat = Math.Min(minLat, coordinates[1]);
36 | maxLng = Math.Max(maxLng, coordinates[0]);
37 | maxLat = Math.Max(maxLat, coordinates[1]);
38 | }
39 |
40 | return new LngLatBounds
41 | {
42 | Southwest = new LngLat(minLng, minLat),
43 | Northeast = new LngLat(maxLng, maxLat)
44 | };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/MultiLineGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class MultiLineGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.MultiLine;
9 |
10 | ///
11 | ///
12 | ///
13 | public LngLatBounds GetBounds()
14 | {
15 | throw new NotImplementedException();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/MultiPointGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class MultiPointGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.MultiPoint;
9 |
10 | ///
11 | ///
12 | ///
13 | public LngLatBounds GetBounds()
14 | {
15 | throw new NotImplementedException();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/MultiPolygonGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class MultiPolygonGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.MultiPolygon;
9 |
10 | ///
11 | ///
12 | ///
13 | public LngLatBounds GetBounds()
14 | {
15 | throw new NotImplementedException();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/PointGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class PointGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.Point;
9 |
10 | [JsonPropertyName("coordinates")]
11 | public required double[] Coordinates { get; set; }
12 |
13 | ///
14 | ///
15 | ///
16 | public LngLatBounds GetBounds()
17 | {
18 | return new LngLatBounds
19 | {
20 | Southwest = new LngLat(Coordinates[0], Coordinates[1]),
21 | Northeast = new LngLat(Coordinates[0], Coordinates[1])
22 | };
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Feature/PolygonGeometry.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Feature;
4 |
5 | public class PolygonGeometry : IGeometry
6 | {
7 | [JsonPropertyName("type")]
8 | public GeometryType Type => GeometryType.Polygon;
9 |
10 | ///
11 | /// Coordinates of a Polygon are an array of LinearRing coordinate arrays.
12 | /// The first element in the array represents the exterior ring.
13 | /// Any subsequent elements represent interior rings (or holes).
14 | ///
15 | /// No holes:
16 | ///
17 | /// {
18 | /// "type": "Polygon",
19 | /// "coordinates": [
20 | /// [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
21 | /// ]
22 | /// }
23 | ///
24 | ///
25 | ///
26 | /// With holes:
27 | ///
28 | /// {
29 | /// "type": "Polygon",
30 | /// "coordinates": [
31 | /// [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
32 | /// [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
33 | /// ]
34 | /// }
35 | ///
36 | ///
37 | ///
38 | [JsonPropertyName("coordinates")]
39 | public required double[][][] Coordinates { get; set; }
40 |
41 | ///
42 | ///
43 | ///
44 | public LngLatBounds GetBounds()
45 | {
46 | if (Coordinates.Length == 0 || Coordinates[0].Length == 0 || Coordinates[0][0].Length == 0)
47 | {
48 | return new LngLatBounds
49 | {
50 | Southwest = new LngLat(0, 0),
51 | Northeast = new LngLat(0, 0)
52 | };
53 | }
54 |
55 | var minLng = double.MaxValue;
56 | var minLat = double.MaxValue;
57 | var maxLng = double.MinValue;
58 | var maxLat = double.MinValue;
59 |
60 | foreach (var group in Coordinates)
61 | {
62 | foreach (var coordinate in group)
63 | {
64 | var lng = coordinate[0];
65 | var lat = coordinate[1];
66 |
67 | minLng = Math.Min(minLng, lng);
68 | minLat = Math.Min(minLat, lat);
69 | maxLng = Math.Max(maxLng, lng);
70 | maxLat = Math.Max(maxLat, lat);
71 | }
72 | }
73 |
74 | return new LngLatBounds()
75 | {
76 | Northeast = new LngLat(maxLng, maxLat),
77 | Southwest = new LngLat(minLng, minLat)
78 | };
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Image/ImageData.cs:
--------------------------------------------------------------------------------
1 | namespace Community.Blazor.MapLibre.Models.Image;
2 |
3 | public class ImageData
4 | {
5 | public int Width { get; set; }
6 | public int Height { get; set; }
7 | }
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Image/StyleImageMetadata.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Image;
4 |
5 | public class StyleImageMetadata
6 | {
7 | ///
8 | /// Defines the part of the image that can be covered by the content in text-field when icon-text-fit is used.
9 | ///
10 | [JsonPropertyName("content")]
11 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
12 | public double[]? Content { get; set; }
13 |
14 | ///
15 | /// The ratio of pixels in the image to physical pixels on the screen.
16 | ///
17 | [JsonPropertyName("pixelRatio")]
18 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
19 | public double? PixelRatio { get; set; }
20 |
21 | ///
22 | /// Determines whether the image should be interpreted as an SDF (Signed Distance Field) image.
23 | ///
24 | [JsonPropertyName("sdf")]
25 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
26 | public bool? Sdf { get; set; }
27 |
28 | ///
29 | /// Defines the part(s) of the image that can be stretched horizontally when icon-text-fit is used.
30 | ///
31 | [JsonPropertyName("stretchX")]
32 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
33 | public double[][]? StretchX { get; set; }
34 |
35 | ///
36 | /// Defines the part(s) of the image that can be stretched vertically when icon-text-fit is used.
37 | ///
38 | [JsonPropertyName("stretchY")]
39 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
40 | public double[][]? StretchY { get; set; }
41 |
42 | ///
43 | /// Defines constraints on the vertical scaling of the image when icon-text-fit is used.
44 | ///
45 | [JsonPropertyName("textFitHeight")]
46 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
47 | public TextFit? TextFitHeight { get; set; }
48 |
49 | ///
50 | /// Defines constraints on the horizontal scaling of the image when icon-text-fit is used.
51 | ///
52 | [JsonPropertyName("textFitWidth")]
53 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
54 | public TextFit? TextFitWidth { get; set; }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Layers/BackgroundLayer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Layers;
4 |
5 | public class BackgroundLayer : Layer
6 | {
7 | ///
8 | ///
9 | ///
10 | [JsonPropertyName("type")]
11 | [JsonConverter(typeof(JsonStringEnumConverter))]
12 | public override LayerType Type => LayerType.Background;
13 | }
14 |
15 | public class BackgroundLayerLayout;
16 | public class BackgroundLayerPaint;
17 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Layers/CircleLayer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Nodes;
2 | using OneOf;
3 | using System.Text.Json.Serialization;
4 | using Community.Blazor.MapLibre.Converter;
5 |
6 | namespace Community.Blazor.MapLibre.Models.Layers;
7 |
8 | public class CircleLayer : Layer
9 | {
10 | ///
11 | ///
12 | ///
13 | [JsonPropertyName("type")]
14 | [JsonConverter(typeof(JsonStringEnumConverter))]
15 | public override LayerType Type => LayerType.Circle;
16 |
17 | ///
18 | /// Gets or sets the name of the source to be used for this layer.
19 | ///
20 | [JsonPropertyName("source")]
21 | public required string Source { get; set; }
22 |
23 | [JsonPropertyName("circle-sort-key")]
24 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
25 | public double? CircleSortKey { get; set; }
26 |
27 | [JsonPropertyName("visibility")]
28 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
29 | public Visibility? Visibility { get; set; }
30 | }
31 |
32 | public class CircleLayerLayout;
33 |
34 | public class CircleLayerPaint
35 | {
36 | [JsonPropertyName("circle-radius")]
37 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
38 | [JsonConverter(typeof(OneOfJsonConverter))]
39 | public OneOf? CircleRadius { get; set; }
40 |
41 | [JsonPropertyName("circle-color")]
42 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
43 | [JsonConverter(typeof(OneOfJsonConverter))]
44 | public OneOf? CircleColor { get; set; }
45 |
46 | [JsonPropertyName("circle-blur")]
47 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
48 | [JsonConverter(typeof(OneOfJsonConverter))]
49 | public OneOf? CircleBlur { get; set; }
50 |
51 | [JsonPropertyName("circle-opacity")]
52 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
53 | [JsonConverter(typeof(OneOfJsonConverter))]
54 | public OneOf? CircleOpacity { get; set; }
55 |
56 | [JsonPropertyName("circle-translate")]
57 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
58 | [JsonConverter(typeof(OneOfJsonConverter))]
59 | public OneOf? CircleTranslate { get; set; }
60 |
61 | [JsonPropertyName("circle-translate-anchor")]
62 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
63 | [JsonConverter(typeof(OneOfJsonConverter))]
64 | public OneOf? CircleTranslateAnchor { get; set; }
65 |
66 | [JsonPropertyName("circle-pitch-scale")]
67 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
68 | [JsonConverter(typeof(OneOfJsonConverter))]
69 | public OneOf? CirclePitchScale { get; set; }
70 |
71 | [JsonPropertyName("circle-pitch-alignment")]
72 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
73 | [JsonConverter(typeof(OneOfJsonConverter))]
74 | public OneOf? CirclePitchAlignment { get; set; }
75 |
76 | [JsonPropertyName("circle-stroke-width")]
77 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
78 | [JsonConverter(typeof(OneOfJsonConverter))]
79 | public OneOf? CircleStrokeWidth { get; set; }
80 |
81 | [JsonPropertyName("circle-stroke-color")]
82 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
83 | [JsonConverter(typeof(OneOfJsonConverter))]
84 | public OneOf? CircleStrokeColor { get; set; }
85 |
86 | [JsonPropertyName("circle-stroke-opacity")]
87 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
88 | [JsonConverter(typeof(OneOfJsonConverter))]
89 | public OneOf? CircleStrokeOpacity { get; set; }
90 | }
91 |
92 | [JsonConverter(typeof(JsonStringEnumConverter))]
93 | public enum MapViewport
94 | {
95 | [JsonStringEnumMemberName("map")]
96 | Map,
97 |
98 | [JsonStringEnumMemberName("viewport")]
99 | Viewport
100 | }
101 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Layers/FillExtrusionLayer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Community.Blazor.MapLibre.Models.Layers;
4 |
5 | public class FillExtrusionLayer : Layer
6 | {
7 | ///
8 | ///
9 | ///
10 | [JsonPropertyName("type")]
11 | [JsonConverter(typeof(JsonStringEnumConverter))]
12 | public override LayerType Type => LayerType.FillExtrusion;
13 |
14 | ///
15 | /// Gets or sets the name of the source to be used for this layer.
16 | ///
17 | [JsonPropertyName("source")]
18 | public required string Source { get; set; }
19 | }
20 |
21 | public class FillExtrusionLayerLayout;
22 | public class FillExtrusionLayerPaint;
23 |
--------------------------------------------------------------------------------
/Community.Blazor.MapLibre/Models/Layers/FillLayer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Nodes;
2 | using System.Text.Json.Serialization;
3 | using Community.Blazor.MapLibre.Converter;
4 | using OneOf;
5 |
6 | namespace Community.Blazor.MapLibre.Models.Layers;
7 |
8 | public class FillLayer : Layer
9 | {
10 | ///
11 | ///
12 | ///
13 | [JsonPropertyName("type")]
14 | [JsonConverter(typeof(JsonStringEnumConverter))]
15 | public override LayerType Type => LayerType.Fill;
16 |
17 | ///
18 | /// Gets or sets the name of the source to be used for this layer.
19 | ///
20 | [JsonPropertyName("source")]
21 | public required string Source { get; set; }
22 | }
23 |
24 | public class FillLayerLayout
25 | {
26 | ///
27 | /// Determines the rendering order of features based on their sort key.
28 | ///
29 | ///
30 | /// Features are sorted in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.
31 | ///
32 | ///
33 | ///
34 | /// Sort Key
35 | /// Rendering Order
36 | ///
37 | /// -
38 | /// Lower value
39 | /// Feature is drawn first and appears beneath features with a higher sort key.
40 | ///
41 | /// -
42 | /// Higher value
43 | /// Feature is drawn later and appears above features with a lower sort key.
44 | ///
45 | ///
46 | ///
47 | [JsonPropertyName("fill-sort-key")]
48 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
49 | [JsonConverter(typeof(OneOfJsonConverter))]
50 | public OneOf? FillSortKey { get; set; }
51 |
52 | ///
53 | /// Controls whether this layer is displayed.
54 | ///
55 | ///
56 | /// Optional enum. Possible values: visible, none. Defaults to visible.
57 | ///
58 | ///
59 | ///
60 | /// Value
61 | /// Effect
62 | ///
63 | /// -
64 | /// visible
65 | /// The layer is shown.
66 | ///
67 | /// -
68 | /// none
69 | /// The layer is not shown.
70 | ///
71 | ///
72 | ///
73 | [JsonPropertyName("visibility")]
74 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
75 | [JsonConverter(typeof(OneOfJsonConverter))]
76 | public OneOf? Visibility { get; set; }
77 | }
78 |
79 | public class FillLayerPaint
80 | {
81 | ///
82 | /// Determines whether the fill should be antialiased.
83 | ///
84 | ///
85 | /// Optional boolean. Defaults to true.
86 | ///
87 | ///
88 | ///
89 | /// Value
90 | /// Effect
91 | ///
92 | /// -
93 | /// true
94 | /// The fill is antialiased, resulting in smoother edges.
95 | ///
96 | /// -
97 | /// false
98 | /// The fill is not antialiased, which may result in jagged edges.
99 | ///
100 | ///
101 | ///
102 | [JsonPropertyName("fill-antialias")]
103 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
104 | [JsonConverter(typeof(OneOfJsonConverter))]
105 | public OneOf? FillAntialias { get; set; }
106 |
107 | ///
108 | /// Specifies the opacity of the entire fill layer.
109 | ///
110 | ///
111 | /// Optional number in the range [0, 1]. Defaults to 1. Supports feature-state and interpolate expressions. Transitionable.
112 | ///
113 | /// The opacity setting affects both the fill color and the 1px stroke around the fill if the stroke is used.
114 | ///
115 | ///
116 | ///
117 | /// Value
118 | /// Effect
119 | ///
120 | /// -
121 | /// 0
122 | /// The fill layer is fully transparent.
123 | ///
124 | /// -
125 | /// 0.5
126 | /// The fill layer is 50% transparent.
127 | ///
128 | /// -
129 | /// 1
130 | /// The fill layer is fully opaque.
131 | ///
132 | /// -
133 | /// Uses interpolate expressions
134 | /// Allows dynamic adjustments to the fill opacity.
135 | ///
136 | ///
137 | ///
138 | [JsonPropertyName("fill-opacity")]
139 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
140 | [JsonConverter(typeof(OneOfJsonConverter))]
141 | public OneOf? FillOpacity { get; set; }
142 |
143 | ///
144 | /// Defines the color of the filled part of this layer.
145 | ///
146 | ///
147 | /// Optional color. Defaults to #000000. Disabled by fill-pattern. Supports feature-state and interpolate expressions. Transitionable.
148 | ///
149 | /// This color can be specified as rgba with an alpha component, and the color's opacity will not affect the opacity of the 1px stroke if it is used.
150 | ///
151 | ///
152 | ///
153 | /// Value
154 | /// Effect
155 | ///
156 | /// -
157 | /// #000000 (default)
158 | /// The fill color is black.
159 | ///
160 | /// -
161 | /// rgba(r, g, b, a)
162 | /// Specifies a custom color with an optional alpha component for transparency.
163 | ///
164 | /// -
165 | /// Uses interpolate expressions
166 | /// Allows dynamic adjustments to the fill color.
167 | ///
168 | /// -
169 | /// fill-pattern is set
170 | /// The fill color is disabled in favor of a pattern.
171 | ///
172 | ///
173 | ///
174 | [JsonPropertyName("fill-color")]
175 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
176 | [JsonConverter(typeof(OneOfJsonConverter))]
177 | public OneOf? FillColor { get; set; }
178 |
179 | ///
180 | /// Specifies the outline color of the fill.
181 | ///
182 | ///
183 | /// Optional color. Disabled by fill-pattern. Requires fill-antialias to be true. Supports feature-state and interpolate expressions. Transitionable.
184 | ///
185 | /// If unspecified, the outline color matches the value of fill-color.
186 | ///
187 | ///
188 | ///
189 | /// Condition
190 | /// Effect
191 | ///
192 | /// -
193 | /// Value not set
194 | /// Defaults to the value of fill-color.
195 | ///
196 | /// -
197 | /// Custom color set
198 | /// Uses the specified color for the outline.
199 | ///
200 | /// -
201 | /// fill-pattern is set
202 | /// The outline color is disabled.
203 | ///
204 | /// -
205 | /// fill-antialias is false
206 | /// The outline color is not applied.
207 | ///
208 | /// -
209 | /// Uses interpolate expressions
210 | /// Allows dynamic adjustments to the outline color.
211 | ///
212 | ///
213 | ///
214 | [JsonPropertyName("fill-outline-color")]
215 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
216 | [JsonConverter(typeof(OneOfJsonConverter))]
217 | public OneOf? FillOutlineColor { get; set; }
218 |
219 | ///
220 | /// Specifies the geometry's offset in pixels.
221 | ///
222 | ///
223 | /// Optional array. Units are in pixels. Defaults to [0, 0]. Supports interpolate expressions. Transitionable.
224 | ///
225 | /// Values are specified as [x, y], where negative values indicate left and up, respectively.
226 | ///
227 | ///
228 | ///
229 | /// Value
230 | /// Effect
231 | ///
232 | /// -
233 | /// [0, 0] (default)
234 | /// No offset is applied.
235 | ///
236 | /// -
237 | /// [x, y] with positive x
238 | /// Moves the geometry to the right.
239 | ///
240 | /// -
241 | /// [x, y] with negative x
242 | /// Moves the geometry to the left.
243 | ///
244 | /// -
245 | /// [x, y] with positive y
246 | /// Moves the geometry downward.
247 | ///
248 | /// -
249 | /// [x, y] with negative y
250 | /// Moves the geometry upward.
251 | ///
252 | /// -
253 | /// Uses interpolate expressions
254 | /// Allows dynamic adjustments to the offset values.
255 | ///
256 | ///
257 | ///
258 | [JsonPropertyName("fill-translate")]
259 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
260 | [JsonConverter(typeof(OneOfJsonConverter))]
261 | public OneOf? FillTranslate { get; set; }
262 |
263 | ///
264 | /// Controls the frame of reference for fill-translate.
265 | ///
266 | ///
267 | /// Optional enum. Possible values: map, viewport. Defaults to map. Requires fill-translate.
268 | ///
269 | ///
270 | ///
271 | /// Value
272 | /// Effect
273 | ///
274 | /// -
275 | /// map (default)
276 | /// The fill is translated relative to the map.
277 | ///
278 | /// -
279 | /// viewport
280 | /// The fill is translated relative to the viewport.
281 | ///
282 | ///
283 | ///
284 | [JsonPropertyName("fill-translate-anchor")]
285 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
286 | [JsonConverter(typeof(OneOfJsonConverter))]
287 | public OneOf? FillTranslateAnchor { get; set; }
288 |
289 | ///
290 | /// Specifies the name of the image in the sprite to use for drawing image fills.
291 | ///
292 | ///
293 | /// Optional resolvedImage. Transitionable.
294 | ///
295 | /// For seamless patterns, the image width and height must be a power of two (e.g., 2, 4, 8, ..., 512).
296 | /// Note that zoom-dependent expressions will be evaluated only at integer zoom levels.
297 | ///
298 | ///
299 | ///
300 | /// Condition
301 | /// Effect
302 | ///
303 | /// -
304 | /// Image width and height are a power of two
305 | /// Ensures seamless pattern rendering.
306 | ///
307 | /// -
308 | /// Zoom-dependent expressions
309 | /// Evaluated only at integer zoom levels.
310 | ///
311 | ///
312 | ///
313 | [JsonPropertyName("fill-pattern")]
314 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
315 | [JsonConverter(typeof(OneOfJsonConverter