├── .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 | 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 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 64 | 65 | 70 | 71 | 72 | 73 | 74 | 75 | 95 | 96 | 101 | 102 | 103 | 104 | 105 | 106 | 126 | 127 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 159 | 160 | 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 | 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 | 23 | 24 | 25 | 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 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | 96 | 97 | 102 | 103 | 104 | 105 | 106 | 107 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | 138 | 158 | 159 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 191 | 192 | 197 | 198 | 199 | 200 | 201 | 202 | 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 | 25 | 26 | 27 | 28 | 29 | 42 | 43 | 44 | 45 | 46 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /data/qmls/point_simple.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /data/qmls/polygon_simple.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /data/qmls/polygon_simple_nostyle.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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