├── .commitlintrc.cjs
├── .eslintignore
├── .eslintrc.cjs
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── question.md
└── workflows
│ ├── commitlint.yml
│ ├── notify-discord.yml
│ ├── on-pull-request.yml
│ ├── on-push-master.yml
│ └── release.yml
├── .gitignore
├── .releaserc
├── .travis.yml
├── .vscode
└── launch.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── data
├── qmls
│ ├── line_simple.qml
│ ├── no_symbolizer.qml
│ ├── point_categories.qml
│ ├── point_external_graphic.qml
│ ├── point_label.qml
│ ├── point_multiple_symbols.qml
│ ├── point_ranges.qml
│ ├── point_rules.qml
│ ├── point_simple.qml
│ ├── polygon_simple.qml
│ ├── polygon_simple_nostyle.qml
│ └── text_text_buffer.qml
├── qmls_old
│ ├── line_simple.qml
│ ├── no_symbolizer.qml
│ ├── point_categories.qml
│ ├── point_external_graphic.qml
│ ├── point_label.qml
│ ├── point_multiple_symbols.qml
│ ├── point_ranges.qml
│ ├── point_rules.qml
│ ├── point_simple.qml
│ ├── polygon_simple.qml
│ ├── polygon_simple_nostyle.qml
│ └── text_text_buffer.qml
└── styles
│ ├── line_simple.ts
│ ├── no_symbolizer.ts
│ ├── point_categories.ts
│ ├── point_external_graphic.ts
│ ├── point_label.ts
│ ├── point_multiple_symbols.ts
│ ├── point_ranges.ts
│ ├── point_rules.ts
│ ├── point_simple.ts
│ ├── polygon_simple.ts
│ ├── polygon_simple_nostyle.ts
│ └── text_text_buffer.ts
├── package-lock.json
├── package.json
├── renovate.json
├── src
├── QGISStyleParser.spec.ts
└── QGISStyleParser.ts
├── tsconfig.json
├── vite.config.ts
└── vitest.config.ts
/.commitlintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional']
3 | };
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # don't ever lint node_modules
2 | node_modules
3 | # don't lint build output (make sure it's set to your correct build folder name)
4 | dist
5 | # don't lint nyc coverage output
6 | coverage
7 | # don't lint browser build output
8 | browser
9 | # don't lint browser build output
10 | build
11 |
12 | .eslintrc.js
13 | *.config.js
14 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: '@terrestris/eslint-config-typescript',
3 | rules: {
4 | camelcase: [
5 | "off",
6 | {
7 | ignoreImports: true
8 | }
9 | ],
10 | '@typescript-eslint/member-ordering': 0
11 | },
12 | overrides: [
13 | {
14 | files: [
15 | "**/*.spec.ts",
16 | "**/*.spec.tsx"
17 | ],
18 | env: {
19 | "jest": true
20 | }
21 | }
22 | ]
23 | };
24 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.qml text eol=lf
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository#about-funding-files
2 | open_collective: geostyler
3 |
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: jansule, KaiVolland
7 |
8 | ---
9 |
10 | # Bug
11 |
12 | **Describe the bug**
13 | A clear and concise description of what the bug is.
14 |
15 | **To Reproduce**
16 | Steps to reproduce the behavior:
17 | 1. Go to '...'
18 | 2. Click on '....'
19 | 3. Scroll down to '....'
20 | 4. See error
21 |
22 | **Expected behavior**
23 | A clear and concise description of what you expected to happen.
24 |
25 | **Screenshots**
26 | If applicable, add screenshots to help explain your problem.
27 |
28 | **Desktop (please complete the following information):**
29 | - OS: [e.g. iOS]
30 | - Browser [e.g. chrome, safari]
31 | - Version [e.g. 22]
32 |
33 | **Smartphone (please complete the following information):**
34 | - Device: [e.g. iPhone6]
35 | - OS: [e.g. iOS8.1]
36 | - Browser [e.g. stock browser, safari]
37 | - Version [e.g. 22]
38 |
39 | **Additional context**
40 | Add any other context about the problem here.
41 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: jansule, KaiVolland
7 |
8 | ---
9 |
10 | # Feature Request
11 |
12 | **Is your feature request related to a problem? Please describe.**
13 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
14 |
15 | **Describe the solution you'd like**
16 | A clear and concise description of what you want to happen.
17 |
18 | **Describe alternatives you've considered**
19 | A clear and concise description of any alternative solutions or features you've considered.
20 |
21 | **Additional context**
22 | Add any other context or screenshots about the feature request here.
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Ask a question related to this project
4 | title: ''
5 | labels: question
6 | assignees: jansule, KaiVolland
7 |
8 | ---
9 |
10 | # Question
11 |
12 |
13 |
14 |
19 |
--------------------------------------------------------------------------------
/.github/workflows/commitlint.yml:
--------------------------------------------------------------------------------
1 | name: Lint Commit Messages
2 | on: [pull_request, push]
3 |
4 | jobs:
5 | commitlint:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v4
9 | with:
10 | fetch-depth: 0
11 | - uses: wagoid/commitlint-github-action@v5
12 | with:
13 | configFile: .commitlintrc.js
14 |
--------------------------------------------------------------------------------
/.github/workflows/notify-discord.yml:
--------------------------------------------------------------------------------
1 | name: Discord notification
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | discord-notification:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Discord notification 📯
12 | env:
13 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
14 | uses: Ilshidur/action-discord@0.3.2
15 | with:
16 | args: '${{ github.event.repository.name }} [${{ github.event.release.tag_name }}](${{ github.event.release.html_url }}) has been released. 🚀'
17 |
--------------------------------------------------------------------------------
/.github/workflows/on-pull-request.yml:
--------------------------------------------------------------------------------
1 | name: Test Pull Request
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | build:
7 | strategy:
8 | matrix:
9 | node-version: [20.x, 22.x]
10 | os: [ubuntu-latest]
11 |
12 | runs-on: ${{ matrix.os }}
13 |
14 | steps:
15 | - name: Checkout sources
16 | uses: actions/checkout@v4
17 |
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 |
23 | - name: Cache Node.js modules 💾
24 | uses: actions/cache@v4
25 | with:
26 | path: ~/.npm
27 | key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
28 | restore-keys: |
29 | ${{ runner.OS }}-node-
30 | ${{ runner.OS }}-
31 |
32 | - name: Install dependencies ⏬
33 | run: npm install
34 |
35 | - name: Lint code 💄
36 | run: npm run lint
37 |
38 | - name: Test code ✅
39 | run: npm run test
40 |
41 | - name: Build artifacts 🏗️
42 | run: npm run build
43 |
--------------------------------------------------------------------------------
/.github/workflows/on-push-master.yml:
--------------------------------------------------------------------------------
1 | name: Test Push to Master
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build:
10 | strategy:
11 | matrix:
12 | node-version: [18.x, 20.x]
13 | os: [ubuntu-latest, windows-latest]
14 |
15 | runs-on: ${{ matrix.os }}]
16 |
17 | steps:
18 | - name: Checkout sources
19 | uses: actions/checkout@v4
20 |
21 | - name: Use Node.js ${{ matrix.node-version }}
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: ${{ matrix.node-version }}
25 |
26 | - name: Cache Node.js modules 💾
27 | uses: actions/cache@v4
28 | with:
29 | path: ~/.npm
30 | key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
31 | restore-keys: |
32 | ${{ runner.OS }}-node-
33 | ${{ runner.OS }}-
34 |
35 | - name: Install dependencies ⏬
36 | run: npm install
37 |
38 | - name: Lint code 💄
39 | run: npm run lint
40 |
41 | - name: Test code ✅
42 | run: npm run test
43 |
44 | - name: Build artifacts 🏗️
45 | run: npm run build
46 |
47 | - name: Publish to coveralls ⭐
48 | # coverage/lcov.info was generated in the previous npm run build step
49 | uses: coverallsapp/github-action@master
50 | with:
51 | github-token: ${{ secrets.GITHUB_TOKEN }}
52 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - next
8 |
9 | jobs:
10 | release:
11 | name: Release
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout sources 🔰
15 | uses: actions/checkout@v4
16 |
17 | - name: Setup Node.js 20 👷🏻
18 | uses: actions/setup-node@v4
19 | with:
20 | node-version: 20
21 |
22 | - name: Prepare git config
23 | run: |
24 | git config user.name "github-actions[bot]"
25 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
26 |
27 | - name: Install dependencies ⏬
28 | run: npm ci
29 |
30 | - name: Build artifacts 🏗️
31 | run: npm run build
32 |
33 | - name: Release 🚀
34 | uses: cycjimmy/semantic-release-action@v4.1.1
35 | id: semantic
36 | env:
37 | GITHUB_TOKEN: ${{ secrets.GH_RELEASE_TOKEN }}
38 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compilation output
4 | /dist
5 |
6 | # dependencies
7 | /node_modules
8 |
9 | # testing
10 | /coverage
11 |
12 | # production
13 | /build
14 | /browser
15 |
16 | # misc
17 | .DS_Store
18 | .env.local
19 | .env.development.local
20 | .env.test.local
21 | .env.production.local
22 |
23 | npm-debug.log*
24 |
--------------------------------------------------------------------------------
/.releaserc:
--------------------------------------------------------------------------------
1 | {
2 | "branches": [
3 | "main",
4 | {
5 | "name": "next",
6 | "prerelease": true
7 | }
8 | ],
9 | "plugins": [
10 | [
11 | "@semantic-release/commit-analyzer",
12 | {
13 | "preset": "conventionalcommits"
14 | }
15 | ],
16 | [
17 | "@semantic-release/release-notes-generator",
18 | {
19 | "preset": "conventionalcommits",
20 | "presetConfig": {
21 | "header": "Changelog of GeoStyler QGIS Parser"
22 | }
23 | }
24 | ],
25 | "@semantic-release/changelog",
26 | "@semantic-release/npm",
27 | [
28 | "@semantic-release/git",
29 | {
30 | "assets": [
31 | "CHANGELOG.md", "package.json", "package-lock.json"
32 | ],
33 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
34 | }
35 | ],
36 | "@semantic-release/github"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "10"
4 | - "12"
5 | script:
6 | - npm run test -- --coverage
7 | cache:
8 | directories:
9 | - node_modules
10 | after_script:
11 | - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
12 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Debug Jest Tests",
6 | "type": "node",
7 | "request": "launch",
8 | "port": 9230,
9 | "runtimeArgs": [
10 | "--inspect-brk=9230",
11 | "${workspaceRoot}/node_modules/.bin/jest",
12 | "--runInBand",
13 | "--watch"
14 | ],
15 | "runtimeExecutable": null,
16 | "console": "integratedTerminal"
17 | },
18 | {
19 | "type": "node",
20 | "request": "launch",
21 | "name": "Debug Jest Tests Windows",
22 | "program": "${workspaceRoot}/node_modules/jest/bin/jest",
23 | "args": [
24 | "-i",
25 | "--watch"
26 | ],
27 | "internalConsoleOptions": "openOnSessionStart",
28 | "console": "integratedTerminal",
29 | "outFiles": [
30 | "${workspaceRoot}/build/dist/**/*"
31 | ]
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [4.0.2](https://github.com/geostyler/geostyler-qgis-parser/compare/v4.0.1...v4.0.2) (2025-03-12)
2 |
3 | ### Bug Fixes
4 |
5 | * **deps:** update dependency core-js to v3.40.0 ([64c340b](https://github.com/geostyler/geostyler-qgis-parser/commit/64c340b4150e6a48e78380b7c3d811967ea3c870))
6 | * **deps:** update dependency geostyler-cql-parser to v4.0.2 ([f9fdf03](https://github.com/geostyler/geostyler-qgis-parser/commit/f9fdf03fcfc4bdfcd0627f323b5417689c9f2719))
7 | * **deps:** update dependency geostyler-style to v10 ([a71c8ce](https://github.com/geostyler/geostyler-qgis-parser/commit/a71c8ce0f5ecf2fca1b063e33d05a4d3dff8e799))
8 |
9 | ## [4.0.1](https://github.com/geostyler/geostyler-qgis-parser/compare/v4.0.0...v4.0.1) (2025-01-14)
10 |
11 | ### Bug Fixes
12 |
13 | * **deps:** update dependency geostyler-cql-parser to v4.0.1 ([619830a](https://github.com/geostyler/geostyler-qgis-parser/commit/619830aa4f7da167b77305255e4ec8c5cc55e90c))
14 | * **deps:** update dependency geostyler-style to v9.2.0 ([bbd8411](https://github.com/geostyler/geostyler-qgis-parser/commit/bbd841174ac2f4714ff8b2202c4746a6a3b4f178))
15 |
16 | ## [3.0.0](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.1.0...v3.0.0) (2024-06-26)
17 |
18 |
19 | ### ⚠ BREAKING CHANGES
20 |
21 | * Switches to esm build and updates base packages.
22 |
23 | ### Bug Fixes
24 |
25 | * fix dependency versions ([ecf3004](https://github.com/geostyler/geostyler-qgis-parser/commit/ecf300440cb90f8ec2e703d4ca4ad9a713807073))
26 |
27 | ## [2.1.0](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.0.1...v2.1.0) (2024-06-25)
28 |
29 |
30 | ### Features
31 |
32 | * prepare next major release ([530fa1e](https://github.com/geostyler/geostyler-qgis-parser/commit/530fa1ee9cde964eec808f543a6661ae4255e051))
33 |
34 |
35 | ### Bug Fixes
36 |
37 | * **deps:** update dependency geostyler-style to v8 ([1469169](https://github.com/geostyler/geostyler-qgis-parser/commit/1469169e3f1f28a23c3f32ebd6c4b398d35d814f))
38 | * fix commitlint ([1e9702d](https://github.com/geostyler/geostyler-qgis-parser/commit/1e9702da04686b845d763e965dbf3a86f60ebe58))
39 | * update cql parser version ([1d80c02](https://github.com/geostyler/geostyler-qgis-parser/commit/1d80c02e1009c3c41b920621054f5712d22bf177))
40 |
41 | ## [2.1.0-next.3](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.1.0-next.2...v2.1.0-next.3) (2024-06-21)
42 |
43 |
44 | ### Bug Fixes
45 |
46 | * fix commitlint ([1e9702d](https://github.com/geostyler/geostyler-qgis-parser/commit/1e9702da04686b845d763e965dbf3a86f60ebe58))
47 |
48 | ## [2.1.0-next.2](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.1.0-next.1...v2.1.0-next.2) (2024-06-21)
49 |
50 |
51 | ### Bug Fixes
52 |
53 | * update cql parser version ([1d80c02](https://github.com/geostyler/geostyler-qgis-parser/commit/1d80c02e1009c3c41b920621054f5712d22bf177))
54 |
55 | ## [2.1.0-next.1](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.0.1...v2.1.0-next.1) (2024-06-20)
56 |
57 |
58 | ### Features
59 |
60 | * prepare next major release ([530fa1e](https://github.com/geostyler/geostyler-qgis-parser/commit/530fa1ee9cde964eec808f543a6661ae4255e051))
61 |
62 |
63 | ### Bug Fixes
64 |
65 | * **deps:** update dependency geostyler-style to v8 ([1469169](https://github.com/geostyler/geostyler-qgis-parser/commit/1469169e3f1f28a23c3f32ebd6c4b398d35d814f))
66 |
67 | ## [2.0.1](https://github.com/geostyler/geostyler-qgis-parser/compare/v2.0.0...v2.0.1) (2024-06-18)
68 |
69 |
70 | ### Bug Fixes
71 |
72 | * **deps:** update dependency @types/lodash to v4.14.197 ([3a25799](https://github.com/geostyler/geostyler-qgis-parser/commit/3a25799c88dd6f5adfa3b093d8f692652b927c95))
73 | * **deps:** update dependency @xmldom/xmldom to v0.8.10 ([0854cef](https://github.com/geostyler/geostyler-qgis-parser/commit/0854cef81de8d174f4ff2da519caf30aefe4825d))
74 | * **deps:** update dependency core-js to v3.37.1 ([3a6dfb5](https://github.com/geostyler/geostyler-qgis-parser/commit/3a6dfb5f11191cb9e16303037662640945f1e167))
75 | * **deps:** update dependency geostyler-cql-parser to v3.0.2 ([56464a9](https://github.com/geostyler/geostyler-qgis-parser/commit/56464a9c5a825e9bad5c60b602d8c64f7b9dcab7))
76 | * **deps:** update dependency xml2js to ^0.5.0 [security] ([55a0888](https://github.com/geostyler/geostyler-qgis-parser/commit/55a0888d7af68ecd48aff98ed8bce537182b2ede))
77 | * **deps:** update dependency xml2js to ^0.6.0 ([52e6bad](https://github.com/geostyler/geostyler-qgis-parser/commit/52e6bad6e82eecccfa33ddbf72068dd0663e17da))
78 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2019, terrestris GmbH & Co. KG
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # geostyler-qgis-parser
2 | [GeoStyler](https://github.com/geostyler/geostyler/) Style Parser implementation for QGIS
3 |
4 | ## Funding & financial sponsorship
5 |
6 | Maintenance and further development of this code can be funded through the
7 | [GeoStyler Open Collective](https://opencollective.com/geostyler). All contributions and
8 | expenses can transparently be reviewed by anyone; you see what we use the donated money for.
9 | Thank you for any financial support you give the GeoStyler project 💞
10 |
11 |
--------------------------------------------------------------------------------
/data/qmls/line_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/data/qmls/no_symbolizer.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/data/qmls/point_categories.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/data/qmls/point_external_graphic.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/data/qmls/point_label.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/data/qmls/point_multiple_symbols.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/data/qmls/point_ranges.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/data/qmls/point_rules.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/data/qmls/point_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/data/qmls/polygon_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/data/qmls/polygon_simple_nostyle.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/data/qmls/text_text_buffer.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/data/qmls_old/line_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/data/qmls_old/no_symbolizer.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/data/qmls_old/point_categories.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/data/qmls_old/point_external_graphic.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/data/qmls_old/point_label.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/data/qmls_old/point_multiple_symbols.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/data/qmls_old/point_ranges.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
--------------------------------------------------------------------------------
/data/qmls_old/point_rules.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/data/qmls_old/point_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/data/qmls_old/polygon_simple.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/data/qmls_old/polygon_simple_nostyle.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/data/qmls_old/text_text_buffer.qml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/data/styles/line_simple.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointSimple: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Line',
9 | color: '#FF00FF',
10 | width: 3,
11 | dasharray: [12, 12],
12 | cap: 'square',
13 | join: 'round',
14 | perpendicularOffset: 2,
15 | opacity: 1
16 | }]
17 | }]
18 | } as Style;
19 |
20 | export default pointSimple;
21 |
--------------------------------------------------------------------------------
/data/styles/no_symbolizer.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointStyledLabel: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | filter: ['>', 'value', 0.1],
8 | symbolizers: []
9 | }]
10 | };
11 |
12 | export default pointStyledLabel;
13 |
--------------------------------------------------------------------------------
/data/styles/point_categories.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointCategories: Style = {
4 | name: 'QGIS Style',
5 | rules: [
6 | {
7 | name: 'Bildpositi = 1',
8 | filter: [
9 | '==',
10 | 'Bildpositi',
11 | '1'
12 | ],
13 | symbolizers: [
14 | {
15 | kind: 'Mark',
16 | wellKnownName: 'circle',
17 | opacity: 1,
18 | color: '#8ADC38',
19 | rotate: 0,
20 | radius: 2,
21 | strokeOpacity: 1,
22 | strokeColor: '#232323',
23 | strokeWidth: 0
24 | }
25 | ]
26 | },
27 | {
28 | name: 'Bildpositi = 2',
29 | filter: [
30 | '==',
31 | 'Bildpositi',
32 | '2'
33 | ],
34 | symbolizers: [
35 | {
36 | kind: 'Mark',
37 | wellKnownName: 'circle',
38 | opacity: 1,
39 | color: '#EA5D5D',
40 | rotate: 0,
41 | radius: 2,
42 | strokeOpacity: 1,
43 | strokeColor: '#232323',
44 | strokeWidth: 0
45 | }
46 | ]
47 | },
48 | {
49 | name: 'Bildpositi = 3',
50 | filter: [
51 | '==',
52 | 'Bildpositi',
53 | '3'
54 | ],
55 | symbolizers: [
56 | {
57 | kind: 'Mark',
58 | wellKnownName: 'circle',
59 | opacity: 1,
60 | color: '#69DBDB',
61 | rotate: 0,
62 | radius: 2,
63 | strokeOpacity: 1,
64 | strokeColor: '#232323',
65 | strokeWidth: 0
66 | }
67 | ]
68 | },
69 | {
70 | name: 'Bildpositi = ',
71 | filter: [
72 | '==',
73 | 'Bildpositi',
74 | ''
75 | ],
76 | symbolizers: [
77 | {
78 | kind: 'Mark',
79 | wellKnownName: 'circle',
80 | opacity: 1,
81 | color: '#9E6ECD',
82 | rotate: 0,
83 | radius: 2,
84 | strokeOpacity: 1,
85 | strokeColor: '#232323',
86 | strokeWidth: 0
87 | }
88 | ]
89 | }
90 | ]
91 | } as Style;
92 |
93 | export default pointCategories;
94 |
--------------------------------------------------------------------------------
/data/styles/point_external_graphic.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointExternalGraphic: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Icon',
9 | color: '#7D8B8F',
10 | size: 69,
11 | opacity: 1,
12 | rotate: 0,
13 | image: 'https://upload.wikimedia.org/wikipedia/commons/6/67/OpenLayers_logo.svg'
14 | }]
15 | }]
16 | } as Style;
17 |
18 | export default pointExternalGraphic;
19 |
--------------------------------------------------------------------------------
/data/styles/point_label.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointStyledLabel: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | filter: ['>', 'value', 0.1],
8 | symbolizers: [{
9 | kind: 'Text',
10 | color: '#000000',
11 | label: '{{locality_name}}',
12 | lineHeight: 1,
13 | font: ['Sans Serif'],
14 | size: 10,
15 | offset: [13, 37]
16 | }]
17 | }]
18 | };
19 |
20 | export default pointStyledLabel;
21 |
--------------------------------------------------------------------------------
/data/styles/point_multiple_symbols.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointMultipleSymbols: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Mark',
9 | wellKnownName: 'square',
10 | color: '#4BFF7E',
11 | radius: 12,
12 | opacity: 1,
13 | rotate: 0,
14 | strokeColor: '#000000',
15 | strokeOpacity: 1,
16 | strokeWidth: 1
17 | }, {
18 | kind: 'Mark',
19 | wellKnownName: 'circle',
20 | color: '#FF0000',
21 | radius: 2,
22 | opacity: 1,
23 | rotate: 0,
24 | strokeColor: '#232323',
25 | strokeOpacity: 1,
26 | strokeWidth: 0
27 | }]
28 | }]
29 | } as Style;
30 |
31 | export default pointMultipleSymbols;
32 |
--------------------------------------------------------------------------------
/data/styles/point_ranges.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointRanges: Style = {
4 | name: 'QGIS Style',
5 | rules: [
6 | {
7 | name: ' 1,0000 - 20,0000 ',
8 | filter: [
9 | '&&',
10 | [
11 | '>=',
12 | 'PlotNr',
13 | '1.000000000000000'
14 | ],
15 | [
16 | '<=',
17 | 'PlotNr',
18 | '20.000000000000000'
19 | ]
20 | ],
21 | symbolizers: [
22 | {
23 | kind: 'Mark',
24 | wellKnownName: 'circle',
25 | opacity: 1,
26 | color: '#FFFFFF',
27 | rotate: 0,
28 | radius: 2,
29 | strokeOpacity: 1,
30 | strokeColor: '#232323',
31 | strokeWidth: 0
32 | }
33 | ]
34 | },
35 | {
36 | name: ' 20,0000 - 39,0000 ',
37 | filter: [
38 | '&&',
39 | [
40 | '>=',
41 | 'PlotNr',
42 | '20.000000000000000'
43 | ],
44 | [
45 | '<=',
46 | 'PlotNr',
47 | '39.000000000000000'
48 | ]
49 | ],
50 | symbolizers: [
51 | {
52 | kind: 'Mark',
53 | wellKnownName: 'circle',
54 | opacity: 1,
55 | color: '#FFBFBF',
56 | rotate: 0,
57 | radius: 2,
58 | strokeOpacity: 1,
59 | strokeColor: '#232323',
60 | strokeWidth: 0
61 | }
62 | ]
63 | },
64 | {
65 | name: ' 39,0000 - 58,0000 ',
66 | filter: [
67 | '&&',
68 | [
69 | '>=',
70 | 'PlotNr',
71 | '39.000000000000000'
72 | ],
73 | [
74 | '<=',
75 | 'PlotNr',
76 | '58.000000000000000'
77 | ]
78 | ],
79 | symbolizers: [
80 | {
81 | kind: 'Mark',
82 | wellKnownName: 'circle',
83 | opacity: 1,
84 | color: '#FF8080',
85 | rotate: 0,
86 | radius: 2,
87 | strokeOpacity: 1,
88 | strokeColor: '#232323',
89 | strokeWidth: 0
90 | }
91 | ]
92 | },
93 | {
94 | name: ' 58,0000 - 77,0000 ',
95 | filter: [
96 | '&&',
97 | [
98 | '>=',
99 | 'PlotNr',
100 | '58.000000000000000'
101 | ],
102 | [
103 | '<=',
104 | 'PlotNr',
105 | '77.000000000000000'
106 | ]
107 | ],
108 | symbolizers: [
109 | {
110 | kind: 'Mark',
111 | wellKnownName: 'circle',
112 | opacity: 1,
113 | color: '#FF4040',
114 | rotate: 0,
115 | radius: 2,
116 | strokeOpacity: 1,
117 | strokeColor: '#232323',
118 | strokeWidth: 0
119 | }
120 | ]
121 | },
122 | {
123 | name: ' 77,0000 - 96,0000 ',
124 | filter: [
125 | '&&',
126 | [
127 | '>=',
128 | 'PlotNr',
129 | '77.000000000000000'
130 | ],
131 | [
132 | '<=',
133 | 'PlotNr',
134 | '96.000000000000000'
135 | ]
136 | ],
137 | symbolizers: [
138 | {
139 | kind: 'Mark',
140 | wellKnownName: 'circle',
141 | opacity: 1,
142 | color: '#FF0000',
143 | rotate: 0,
144 | radius: 2,
145 | strokeOpacity: 1,
146 | strokeColor: '#232323',
147 | strokeWidth: 0
148 | }
149 | ]
150 | }
151 | ]
152 | } as Style;
153 |
154 | export default pointRanges;
155 |
--------------------------------------------------------------------------------
/data/styles/point_rules.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointRules: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | filter: ['==', 'Bildpositi', 1],
7 | name: 'Bildpositi = 1',
8 | scaleDenominator: {
9 | max: 2000,
10 | min: 100
11 | },
12 | symbolizers: [{
13 | color: '#4BFF7E',
14 | kind: 'Mark',
15 | opacity: 1,
16 | radius: 12,
17 | rotate: 0,
18 | strokeColor: '#000000',
19 | strokeOpacity: 1,
20 | strokeWidth: 1,
21 | wellKnownName: 'square'
22 | }]
23 | }, {
24 | filter: ['&&',
25 | ['>', 'Bildpositi', 1],
26 | ['<', 'Bildpositi', 3]
27 | ],
28 | name: 'Bildpositi > 1 AND Bildpositi < 3',
29 | scaleDenominator: {
30 | max: 2000,
31 | min: 100
32 | },
33 | symbolizers: [{
34 | color: '#91522D',
35 | kind: 'Mark',
36 | opacity: 1,
37 | radius: 6,
38 | rotate: 0,
39 | strokeColor: '#232323',
40 | strokeOpacity: 1,
41 | strokeWidth: 1,
42 | wellKnownName: 'circle'
43 | }]
44 | }, {
45 | filter: ['==', 'Bildpositi', 3],
46 | name: 'Bildpositi = 3',
47 | scaleDenominator: {
48 | max: 2000,
49 | min: 100
50 | },
51 | symbolizers: [{
52 | color: '#BEB297',
53 | kind: 'Mark',
54 | opacity: 1,
55 | radius: 6,
56 | rotate: 0,
57 | strokeColor: '#232323',
58 | strokeOpacity: 1,
59 | strokeWidth: 1,
60 | wellKnownName: 'circle'
61 | }]
62 | }]
63 | } as Style;
64 |
65 | export default pointRules;
66 |
--------------------------------------------------------------------------------
/data/styles/point_simple.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const pointSimple: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Mark',
9 | wellKnownName: 'circle',
10 | color: '#BEB297',
11 | radius: 2,
12 | opacity: 1,
13 | rotate: 0,
14 | strokeColor: '#232323',
15 | strokeOpacity: 1,
16 | strokeWidth: 0
17 | }]
18 | }]
19 | } as Style;
20 |
21 | export default pointSimple;
22 |
--------------------------------------------------------------------------------
/data/styles/polygon_simple.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const polygonSimple: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Fill',
9 | color: '#4BFF7E',
10 | outlineColor: '#FF070B',
11 | outlineWidth: 4,
12 | opacity: 0.5,
13 | outlineDasharray: [10, 2]
14 | }]
15 | }]
16 | } as Style;
17 |
18 | export default polygonSimple;
19 |
--------------------------------------------------------------------------------
/data/styles/polygon_simple_nostyle.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const polygonSimpleNoStyle: Style = {
4 | name: 'QGIS Style',
5 | rules: [{
6 | name: 'QGIS Simple Symbol',
7 | symbolizers: [{
8 | kind: 'Fill',
9 | outlineColor: '#FF070B',
10 | outlineWidth: 4,
11 | outlineDasharray: [10, 2]
12 | }]
13 | }]
14 | } as Style;
15 |
16 | export default polygonSimpleNoStyle;
17 |
--------------------------------------------------------------------------------
/data/styles/text_text_buffer.ts:
--------------------------------------------------------------------------------
1 | import { Style } from 'geostyler-style';
2 |
3 | const labelSample: Style = {
4 | name: 'roads_oneways',
5 | rules: [
6 | {
7 | name: '',
8 | scaleDenominator: {
9 | max: 1000
10 | },
11 | symbolizers: [
12 | {
13 | kind: 'Text',
14 | label: 'Sample label',
15 | padding: 0,
16 | font: ['DejaVuSans'],
17 | size: 10.6135611907387,
18 | haloColor: '#fafafa',
19 | haloWidth: 0.7938257993384785
20 | }
21 | ]
22 | }
23 | ]
24 | } as Style;
25 |
26 | export default labelSample;
27 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "geostyler-qgis-parser",
3 | "version": "4.0.2",
4 | "description": "GeoStyler Style Parser implementation for QGIS Style",
5 | "main": "dist/QGISStyleParser.js",
6 | "type": "module",
7 | "files": [
8 | "dist",
9 | "index.d.ts"
10 | ],
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/geostyler/geostyler-qgis-parser.git"
14 | },
15 | "keywords": [
16 | "geostyler",
17 | "parser",
18 | "style",
19 | "qgis",
20 | "qml"
21 | ],
22 | "author": "",
23 | "license": "BSD-2-Clause",
24 | "bugs": {
25 | "url": "https://github.com/geostyler/geostyler/issues"
26 | },
27 | "homepage": "https://github.com/geostyler/geostyler-qgis-parser#readme",
28 | "dependencies": {
29 | "buffer": "^6.0.3",
30 | "color": "^4.2.3",
31 | "core-js": "^3.26.1",
32 | "geostyler-cql-parser": "^4.0.0",
33 | "geostyler-style": "^10.0.0",
34 | "string_decoder": "^1.3.0",
35 | "timers": "^0.1.1",
36 | "xml2js": "^0.6.0"
37 | },
38 | "scripts": {
39 | "build-browser": "vite build",
40 | "build-dist": "tsc",
41 | "build": "npm run build-browser && npm run build-dist",
42 | "lint:test:build": "npm run lint && npm run test && npm run build",
43 | "lint:test": "npm run lint && npm run test",
44 | "lint": "eslint -c .eslintrc.cjs --ext .ts . && tsc --noEmit",
45 | "prepublishOnly": "npm run lint:test:build",
46 | "test-debug": "NODE_OPTIONS=--import=extensionless/register vitest --inspect-brk --no-file-parallelism",
47 | "test-watch": "NODE_OPTIONS=--import=extensionless/register vitest",
48 | "test": "NODE_OPTIONS=--import=extensionless/register vitest run"
49 | },
50 | "devDependencies": {
51 | "@commitlint/cli": "^19.3.0",
52 | "@commitlint/config-conventional": "^19.2.2",
53 | "@semantic-release/changelog": "^6.0.3",
54 | "@semantic-release/git": "^10.0.1",
55 | "@terrestris/eslint-config-typescript": "^3.1.0",
56 | "@types/color": "^3.0.3",
57 | "@types/jest": "^29.2.3",
58 | "@types/node": "^20.1.3",
59 | "@types/xml2js": "^0.4.14",
60 | "@typescript-eslint/eslint-plugin": "^5.44.0",
61 | "@typescript-eslint/parser": "^5.44.0",
62 | "conventional-changelog-conventionalcommits": "^8.0.0",
63 | "eslint": "^8.28.0",
64 | "extensionless": "^1.9.9",
65 | "jest": "^29.3.1",
66 | "semantic-release": "^24.0.0",
67 | "typescript": "^5.4.5",
68 | "vite": "^5.3.1",
69 | "vitest": "^1.6.0"
70 | },
71 | "funding": "https://opencollective.com/geostyler"
72 | }
73 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/QGISStyleParser.spec.ts:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs';
2 | import QGISStyleParser from './QGISStyleParser';
3 | import line_simple from '../data/styles/line_simple';
4 | import point_simple from '../data/styles/point_simple';
5 | import point_multiple_symbols from '../data/styles/point_multiple_symbols';
6 | import point_rules from '../data/styles/point_rules';
7 | import point_categories from '../data/styles/point_categories';
8 | import point_label from '../data/styles/point_label';
9 | import point_ranges from '../data/styles/point_ranges';
10 | import point_external_graphic from '../data/styles/point_external_graphic';
11 | import polygon_simple from '../data/styles/polygon_simple';
12 | import polygon_simple_nostyle from '../data/styles/polygon_simple_nostyle';
13 | import no_symbolizer from '../data/styles/no_symbolizer';
14 | import text_text_buffer from '../data/styles/text_text_buffer';
15 |
16 | it('QGISStyleParser is defined', () => {
17 | expect(QGISStyleParser).toBeDefined();
18 | });
19 |
20 | describe('QMLStyleParser implements StyleParser', () => {
21 | let styleParser: QGISStyleParser;
22 |
23 | beforeEach(() => {
24 | styleParser = (expect.getState().currentTestName.includes('>=3.28.0'))
25 | ? new QGISStyleParser()
26 | : new QGISStyleParser({qgisVersion: '3.22.16-Białowieża'});
27 | });
28 |
29 | const QML_FOLDERS = [
30 | ['>=3.28.0', 'qmls'],
31 | ['<3.28.0', 'qmls_old']
32 | ];
33 |
34 | QML_FOLDERS.forEach(qmlVersionFolder => {
35 | const [qmlVersion, qmlFolder] = qmlVersionFolder;
36 | describe(`#readStyle ${qmlVersion}`, () => {
37 | it('is defined', () => {
38 | expect(styleParser.readStyle).toBeDefined();
39 | });
40 | describe('PointSymbolizer', () => {
41 | it('can read a simple QML PointSymbol', async () => {
42 | expect.assertions(2);
43 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_simple.qml`, 'utf8');
44 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
45 | expect(geoStylerStyle).toBeDefined();
46 | expect(geoStylerStyle).toEqual(point_simple);
47 | });
48 | it('can read a QML PointSymbolizer with an external graphic', async () => {
49 | expect.assertions(2);
50 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_external_graphic.qml`, 'utf8');
51 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
52 | expect(geoStylerStyle).toBeDefined();
53 | expect(geoStylerStyle).toEqual(point_external_graphic);
54 | });
55 | it('can read a QML PointSymbolizer with multiple symbols', async () => {
56 | expect.assertions(2);
57 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_multiple_symbols.qml`, 'utf8');
58 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
59 | expect(geoStylerStyle).toBeDefined();
60 | expect(geoStylerStyle).toEqual(point_multiple_symbols);
61 | });
62 | });
63 | describe('TextSymbolizer', () => {
64 | it('can read some basics of the QML Labeling for Points', async () => {
65 | expect.assertions(2);
66 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_label.qml`, 'utf8');
67 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
68 | expect(geoStylerStyle).toBeDefined();
69 | expect(geoStylerStyle).toEqual(point_label);
70 | });
71 | });
72 | describe('LineSymbolizer', () => {
73 | it('can read a simple QML LineSymbol', async () => {
74 | expect.assertions(2);
75 | const qml = fs.readFileSync(`./data/${qmlFolder}/line_simple.qml`, 'utf8');
76 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
77 | expect(geoStylerStyle).toBeDefined();
78 | expect(geoStylerStyle).toEqual(line_simple);
79 | });
80 | });
81 | describe('FillSymbolizer', () => {
82 | it('can read a simple QML FillSymbol', async () => {
83 | expect.assertions(2);
84 | const qml = fs.readFileSync(`./data/${qmlFolder}/polygon_simple.qml`, 'utf8');
85 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
86 | expect(geoStylerStyle).toBeDefined();
87 | expect(geoStylerStyle).toEqual(polygon_simple);
88 | });
89 | });
90 | describe('FillSymbolizer with no style', () => {
91 | it('can read a simple QML FillSymbol with no style', async () => {
92 | expect.assertions(2);
93 | const qml = fs.readFileSync(`./data/${qmlFolder}/polygon_simple_nostyle.qml`, 'utf8');
94 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
95 | expect(geoStylerStyle).toBeDefined();
96 | expect(geoStylerStyle).toEqual(polygon_simple_nostyle);
97 | });
98 | });
99 | describe('Filter Parsing', () => {
100 | it('can read a rule based QML PointSymbolizer', async () => {
101 | expect.assertions(2);
102 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_rules.qml`, 'utf8');
103 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
104 | expect(geoStylerStyle).toBeDefined();
105 | expect(geoStylerStyle).toEqual(point_rules);
106 | });
107 | it('can read a category based QML PointSymbolizer', async () => {
108 | expect.assertions(2);
109 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_categories.qml`, 'utf8');
110 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
111 | expect(geoStylerStyle).toBeDefined();
112 | expect(geoStylerStyle).toEqual(point_categories);
113 | });
114 | it('can read a range based QML PointSymbolizer', async () => {
115 | expect.assertions(2);
116 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_ranges.qml`, 'utf8');
117 | const { output: geoStylerStyle } = await styleParser.readStyle(qml);
118 | expect(geoStylerStyle).toBeDefined();
119 | expect(geoStylerStyle).toEqual(point_ranges);
120 | });
121 | });
122 | });
123 | });
124 |
125 | QML_FOLDERS.forEach(qmlVersionFolder => {
126 | const [qmlVersion, qmlFolder] = qmlVersionFolder;
127 | describe(`#writeStyle ${qmlVersion}`, () => {
128 | it('is defined', () => {
129 | expect(styleParser.writeStyle).toBeDefined();
130 | });
131 | describe('PointSymbolizer', () => {
132 | it('can write a simple QML PointSymbol', async () => {
133 | expect.assertions(2);
134 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_simple.qml`, 'utf8');
135 | const { output: qgisStyle } = await styleParser.writeStyle(point_simple);
136 | expect(qgisStyle).toBeDefined();
137 | expect(qgisStyle).toEqual(qml.trim());
138 | });
139 | it('can write a QML PointSymbolizer with an external graphic', async () => {
140 | expect.assertions(2);
141 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_external_graphic.qml`, 'utf8');
142 | const { output: qgisStyle } = await styleParser.writeStyle(point_external_graphic);
143 | expect(qgisStyle).toBeDefined();
144 | expect(qgisStyle).toEqual(qml.trim());
145 | });
146 | it('can write a QML PointSymbolizer with multiple symbols', async () => {
147 | expect.assertions(2);
148 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_multiple_symbols.qml`, 'utf8');
149 | const { output: qgisStyle } = await styleParser.writeStyle(point_multiple_symbols);
150 | expect(qgisStyle).toBeDefined();
151 | expect(qgisStyle).toEqual(qml.trim());
152 | });
153 | });
154 | describe('TextSymbolizer', () => {
155 | it('can write some basics of the QML Labeling for Points', async () => {
156 | expect.assertions(2);
157 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_label.qml`, 'utf8');
158 | const { output: qgisStyle } = await styleParser.writeStyle(point_label);
159 | expect(qgisStyle).toBeDefined();
160 | expect(qgisStyle).toEqual(qml.trim());
161 | });
162 | it('can write QML with text-buffer', async () => {
163 | expect.assertions(2);
164 | const qml = fs.readFileSync(`./data/${qmlFolder}/text_text_buffer.qml`, 'utf8');
165 | const { output: qgisStyle } = await styleParser.writeStyle(text_text_buffer);
166 | expect(qgisStyle).toBeDefined();
167 | expect(qgisStyle).toEqual(qml.trim());
168 | });
169 | });
170 | describe('LineSymbolizer', () => {
171 | it('can write a simple QML LineSymbol', async () => {
172 | expect.assertions(2);
173 | const qml = fs.readFileSync(`./data/${qmlFolder}/line_simple.qml`, 'utf8');
174 | const { output: qgisStyle } = await styleParser.writeStyle(line_simple);
175 | expect(qgisStyle).toBeDefined();
176 | expect(qgisStyle).toEqual(qml.trim());
177 | });
178 | });
179 | describe('FillSymbolizer', () => {
180 | it('can write a simple QML FillSymbol', async () => {
181 | expect.assertions(2);
182 | const qml = fs.readFileSync(`./data/${qmlFolder}/polygon_simple.qml`, 'utf8');
183 | const { output: qgisStyle } = await styleParser.writeStyle(polygon_simple);
184 | expect(qgisStyle).toBeDefined();
185 | expect(qgisStyle).toEqual(qml.trim());
186 | });
187 | });
188 | describe('Filter Parsing', () => {
189 | it('can write a rule based QML PointSymbolizer', async () => {
190 | expect.assertions(2);
191 | const qml = fs.readFileSync(`./data/${qmlFolder}/point_rules.qml`, 'utf8');
192 | const { output: qgisStyle } = await styleParser.writeStyle(point_rules);
193 | expect(qgisStyle).toBeDefined();
194 | expect(qgisStyle).toEqual(qml.trim());
195 | });
196 | it('can write QML with no symbolizers', async () => {
197 | expect.assertions(2);
198 | const qml = fs.readFileSync(`./data/${qmlFolder}/no_symbolizer.qml`, 'utf8');
199 | const { output: qgisStyle } = await styleParser.writeStyle(no_symbolizer);
200 | expect(qgisStyle).toBeDefined();
201 | expect(qgisStyle).toEqual(qml.trim());
202 | });
203 | });
204 | });
205 | });
206 | });
207 |
--------------------------------------------------------------------------------
/src/QGISStyleParser.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Filter,
3 | StyleParser,
4 | Style,
5 | Rule,
6 | ScaleDenominator,
7 | PointSymbolizer,
8 | Symbolizer,
9 | IconSymbolizer,
10 | LineSymbolizer,
11 | MarkSymbolizer,
12 | FillSymbolizer,
13 | TextSymbolizer,
14 | WriteStyleResult,
15 | ReadStyleResult,
16 | isGeoStylerFunction
17 | } from 'geostyler-style';
18 |
19 | import { CqlParser } from 'geostyler-cql-parser';
20 | import Color from 'color';
21 |
22 | import {
23 | parseString,
24 | Builder
25 | } from 'xml2js';
26 |
27 | const get = (obj: any, path: any, defaultValue = undefined) => {
28 | const travel = (regexp: RegExp) =>
29 | String.prototype.split
30 | .call(path, regexp)
31 | .filter(Boolean)
32 | .reduce((res: any, key: any) => (res !== null && res !== undefined ? res[key] : res), obj);
33 | const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/);
34 | return result === undefined || result === obj ? defaultValue : result;
35 | };
36 |
37 | export type ConstructorParams = {
38 | qgisVersion?: string;
39 | };
40 |
41 | type SymbolizerMap = {
42 | [key: string]: Symbolizer[];
43 | };
44 |
45 | type LabelMap = {
46 | [filter: string]: TextSymbolizer[];
47 | };
48 |
49 | type QmlProp = {
50 | $: {
51 | k: any;
52 | v: any;
53 | };
54 | };
55 |
56 | type QmlMapOption = {
57 | $: {
58 | type: string;
59 | };
60 | Option: QmlOption[];
61 | };
62 |
63 | type QmlOption = {
64 | $: {
65 | name: string;
66 | value: string;
67 | type: string;
68 | };
69 | };
70 |
71 | type QmlRule = {
72 | $: {
73 | filter?: string;
74 | scalemaxdenom?: number;
75 | scalemindenom?: number;
76 | symbol: string;
77 | key: string;
78 | label: string;
79 | };
80 | };
81 |
82 | type QmlCategory = {
83 | $: {
84 | label: string;
85 | render: string;
86 | symbol: string;
87 | value: string;
88 | };
89 | };
90 |
91 | type QmlRange = {
92 | $: {
93 | upper: string;
94 | lower: string;
95 | label: string;
96 | symbol: string;
97 | render: string;
98 | };
99 | };
100 |
101 | const dot = [2, 2];
102 | const dash = [10, 2];
103 |
104 | const lineStyleDashArrays: { [key: string]: number[] | undefined } = {
105 | solid: undefined,
106 | dot: dot,
107 | dash: dash,
108 | 'dash dot': [...dash, ...dot],
109 | 'dash dot dot': [...dash, ...dot, ...dot]
110 | };
111 |
112 | const AnchorMap = {
113 | left: 'L',
114 | right: 'R',
115 | top: 'T',
116 | bottom: 'B',
117 | 'top-left': 'TL',
118 | 'top-right': 'TR',
119 | 'bottom-left': 'BL',
120 | 'bottom-right': 'BR'
121 | };
122 |
123 | /**
124 | * This parser can be used with the GeoStyler.
125 | * It implements the GeoStyler-Style StyleParser interface.
126 | *
127 | * @class QGISStyleParser
128 | * @implements StyleParser
129 | */
130 | export class QGISStyleParser implements StyleParser {
131 |
132 | cqlParser = new CqlParser();
133 |
134 | /**
135 | * The name of the QGIS Style Parser.
136 | */
137 | public static title = 'QGIS Style Parser';
138 |
139 | title = 'QGIS Style Parser';
140 |
141 | qgisVersion: string;
142 |
143 | // QGIS 3.28 and later use