diff --git a/.travis.yml b/.travis.yml
index 1c7ad5e..2ceb70c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,7 @@
matrix:
include:
- language: python
+ name: qgis:latest
python: 3.6
dist: xenial
sudo: true
@@ -14,7 +15,7 @@ matrix:
- pip install flake8 mypy
- flake8 plugin
install:
- - cd docker && docker-compose up -d
+ - cd docker && docker-compose build --build-arg QGIS_TAG=latest && docker-compose up -d
- sleep 10 # This is required to allow xvfb to start
script:
- docker exec -it qgis3 sh -c "qgis_testrunner.sh tests_directory"
@@ -37,6 +38,46 @@ matrix:
tags: true
branch: master-qgis3
+ - language: python
+ name: qgis:release-3_6
+ python: 3.6
+ dist: xenial
+ sudo: true
+ branches:
+ only:
+ - master-qgis3
+ - dev-qgis3
+ services:
+ - docker
+ before_install:
+ - pip install flake8 mypy
+ - flake8 plugin
+ install:
+ - cd docker && docker-compose build --build-arg QGIS_TAG=release-3_6 && docker-compose up -d
+ - sleep 10 # This is required to allow xvfb to start
+ script:
+ - docker exec -it qgis3 sh -c "qgis_testrunner.sh tests_directory"
+ -
+ - language: python
+ name: qgis:release-3_4
+ python: 3.6
+ dist: xenial
+ sudo: true
+ branches:
+ only:
+ - master-qgis3
+ - dev-qgis3
+ services:
+ - docker
+ before_install:
+ - pip install flake8 mypy
+ - flake8 plugin
+ install:
+ - cd docker && docker-compose build --build-arg QGIS_TAG=release-3_4 && docker-compose up -d
+ - sleep 10 # This is required to allow xvfb to start
+ script:
+ - docker exec -it qgis3 sh -c "qgis_testrunner.sh tests_directory"
+
- language: cpp
branches:
only:
diff --git a/README.md b/README.md
index 2ae2656..baa209f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-[![Build Status](https://travis-ci.org/geometalab/Vector-Tiles-Reader-QGIS-Plugin.svg?branch=master)](https://travis-ci.org/geometalab/Vector-Tiles-Reader-QGIS-Plugin)
-[![Coverage Status](https://coveralls.io/repos/github/geometalab/Vector-Tiles-Reader-QGIS-Plugin/badge.svg?branch=HEAD)](https://coveralls.io/github/geometalab/Vector-Tiles-Reader-QGIS-Plugin?branch=HEAD)
+[![Build Status](https://travis-ci.org/geometalab/Vector-Tiles-Reader-QGIS-Plugin.svg?branch=dev-qgis3)](https://travis-ci.org/geometalab/Vector-Tiles-Reader-QGIS-Plugin)
+[![codecov](https://codecov.io/gh/geometalab/Vector-Tiles-Reader-QGIS-Plugin/branch/dev-qgis3/graph/badge.svg)](https://codecov.io/gh/geometalab/Vector-Tiles-Reader-QGIS-Plugin)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
# Vector Tiles Reader QGIS-Plugin
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 318086c..aa2d2a6 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,4 +1,5 @@
-FROM qgis/qgis:latest
+ARG QGIS_TAG
+FROM qgis/qgis:${QGIS_TAG}
MAINTAINER Martin Boos
RUN qgis_setup.sh vector_tiles_reader && \
diff --git a/ext-libs/mapboxstyle2qgis/tests/test_filters.py b/ext-libs/mapboxstyle2qgis/tests/test_filters.py
deleted file mode 100644
index 7993b42..0000000
--- a/ext-libs/mapboxstyle2qgis/tests/test_filters.py
+++ /dev/null
@@ -1,98 +0,0 @@
-import os
-import sys
-sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
-
-from core import get_qgis_rule
-
-
-#region comparision filters
-
-def test_qgis_attribute():
- rule = get_qgis_rule(["<=", "@map_scale", "20000"], escape_result=False)
- assert rule == "@map_scale is not null and @map_scale <= '20000'"
-
-
-def test_eq_filter():
- rule = get_qgis_rule(["==", "class", "address"], escape_result=False)
- assert rule == "\"class\" is not null and \"class\" = 'address'"
-
-
-def test_type_comparision():
- rule = get_qgis_rule(["==", "$type", "Polygon"], escape_result=False)
- assert rule is None
-
-
-def test_neq_filter():
- rule = get_qgis_rule(["!=", "class", "address"], escape_result=False)
- assert rule == "\"class\" is null or \"class\" != 'address'"
-
-
-def test_leq_filter():
- rule = get_qgis_rule(["<=", "class", "address"], escape_result=False)
- assert rule == "\"class\" is not null and \"class\" <= 'address'"
-
-
-def test_eqgt_filter():
- rule = get_qgis_rule([">=", "class", "address"], escape_result=False)
- assert rule == "\"class\" is not null and \"class\" >= 'address'"
-
-
-def test_gt_filter():
- rule = get_qgis_rule([">", "class", "address"], escape_result=False)
- assert rule == "\"class\" is not null and \"class\" > 'address'"
-
-
-def test_lt_filter():
- rule = get_qgis_rule(["<", "class", "address"], escape_result=False)
- assert rule == "\"class\" is not null and \"class\" < 'address'"
-
-#endregion
-
-# region membership filters
-
-
-def test_membership_in():
- expr = get_qgis_rule(["in", "class", "city", "cafe", "poi"], escape_result=False)
- assert expr == "(\"class\" is not null and \"class\" in ('city', 'cafe', 'poi'))"
-
-
-def test_membership_not_in():
- expr = get_qgis_rule(["!in", "class", "city", "cafe", "poi"], escape_result=False)
- assert expr == "(\"class\" is null or \"class\" not in ('city', 'cafe', 'poi'))"
-# endregion
-
-# region existential filters
-
-def test_has():
- expr = get_qgis_rule(["has", "name"], escape_result=False)
- assert expr == "attribute($currentfeature, 'name') is not null"
-
-
-def test_has_not():
- expr = get_qgis_rule(["!has", "name"], escape_result=False)
- assert expr == "attribute($currentfeature, 'name') is null"
-
-# endregion
-
-# region combining filters
-def test_all():
- f1 = ["==", "class", "address"]
- f2 = ["!=", "name", "hello world"]
- f3 = [">=", "height", "123"]
- rule = get_qgis_rule(["all", f1, f2, f3], escape_result=False)
- assert rule == """("class" is not null and "class" = \'address\') and ("name" is null or "name" != \'hello world\') and ("height" is not null and "height" >= \'123\')"""
-
-
-def test_any():
- f1 = ["==", "class", "address"]
- f2 = ["!=", "name", "hello world"]
- rule = get_qgis_rule(["any", f1, f2], escape_result=False)
- assert rule == """"class" is not null and "class" = \'address\' or "name" is null or "name" != \'hello world\'"""
-
-
-def test_none():
- f1 = ["==", "class", "address"]
- f2 = ["!=", "name", "hello world"]
- rule = get_qgis_rule(["none", f1, f2], escape_result=False)
- assert rule == """not "class" is not null and "class" = \'address\' and not "name" is null or "name" != \'hello world\'"""
-# endregion
diff --git a/ext-libs/mapboxstyle2qgis/tests/test_helper.py b/ext-libs/mapboxstyle2qgis/tests/test_helper.py
deleted file mode 100644
index 0ab3d1e..0000000
--- a/ext-libs/mapboxstyle2qgis/tests/test_helper.py
+++ /dev/null
@@ -1,343 +0,0 @@
-from core import get_styles, parse_color, get_qgis_rule, get_background_color, xml_helper, _get_match_expr
-
-
-def test_parse_rgb():
- rgba = parse_color("rgb(1,2,3)")
- assert rgba == "1,2,3,255"
-
-
-def test_parse_rgba():
- rgba = parse_color("rgba(1, 2, 3, 0.5)")
- assert rgba == "1,2,3,128"
-
-
-def test_parse_hsl():
- rgba = parse_color("hsl(28, 76%, 67%)")
- assert rgba == "235,167,107,255"
-
-
-def test_parse_hsla():
- rgba = parse_color("hsla(28, 76%, 67%, 0.5)")
- assert rgba == "235,167,107,128"
-
-
-def test_parse_color_match():
- rgba = parse_color([
- "match",
- [
- "get",
- "type"
- ],
- "Air Transport",
- "#e6e6e6",
- "Education",
- "#f7eaca",
- "hsla(28, 76%, 67%, 0.5)"
- ])
- assert rgba == """if ("type" is not null and "type" = 'Air Transport', '#e6e6e6', if ("type" is not null and "type" = 'Education', '#f7eaca', '235,167,107,128'))"""
-
-
-def test_parse_hex_alpha():
- rgba = parse_color("#ffff0c32")
- assert rgba == "255,255,12,50"
-
-
-def test_parse_hex():
- rgba = parse_color("#ffff0c")
- assert rgba == "#ffff0c"
-
-
-def test_parse_short_hex():
- rgba = parse_color("#abc")
- assert rgba == "170,187,204"
-
-
-def test_line_dasharray():
- style = _get_line_layer({
- "line-color": "#cba",
- "line-dasharray": [
- 1.5,
- 0.75
- ],
- "line-width": {
- "base": 1.2,
- "stops": [
- [
- 15,
- 1.2
- ],
- [
- 20,
- 4
- ]
- ]
- }
- })
- styles = get_styles(style)
-
-
-def test_line_dasharray_multiple():
- layer = _get_line_layer({
- "id": "test",
- "line-dasharray": [
- 5,
- 6,
- 10,
- 11
- ]
- })
- styles = get_styles(layer)
- d = xml_helper._get_line_symbol(0, styles[0])
- a = ""
-
-
-def test_line_cap():
- style = {
- "id": None,
- "type": "line",
- "layout": {
- "line-cap": "round",
- "line-join": "square"
- }
- }
- styles = get_styles(style)
- assert len(styles) == 1
- assert styles[0]["line-join"] == "square"
- assert styles[0]["line-cap"] == "round"
-
-
-def test_stops():
- style = _get_line_layer({
- "line-color": "#9e9cab",
- "line-dasharray": [3, 1, 1, 1],
- "line-width": {
- "base": 1.4,
- "stops": [[4, 0.4], [5, 1], [12, 3]]}
- })
- styles = get_styles(style)
-
-
-def test_zoom_level_zero():
- style = _get_fill_style({
- "fill-opacity": {
- "base": 1,
- "stops": [[0, 0.9], [10, 0.3]]
- }
- })
- styles = get_styles(style)
- assert len(styles) == 2
- assert _are_dicts_equal(styles[0], {
- 'zoom_level': 0,
- 'max_scale_denom': 1000000000,
- 'min_scale_denom': 750000,
- 'fill-color': '0,0,0,0',
- 'fill-opacity': 0.9
- })
-
- assert _are_dicts_equal(styles[1], {
- 'zoom_level': 10,
- 'max_scale_denom': 750000,
- 'min_scale_denom': 1,
- 'fill-color': '0,0,0,0',
- 'fill-opacity': 0.3
- })
-
-
-def test_get_styles_float():
- style = _get_fill_style({
- "fill-opacity": 0.7,
- "fill-color": "#f2eae2",
- })
- styles = get_styles(style)
- assert styles[0] == {
- "fill-color": "#f2eae2",
- "fill-opacity": 0.7,
- "zoom_level": None,
- "min_scale_denom": None,
- "max_scale_denom": None
- }
-
-
-def test_get_background_color():
- layer = """{"layers": [{
- "id": "background",
- "type": "background",
- "paint": {
- "background-color": "#f8f4f0"
- }
- }]}"""
- color = get_background_color(layer)
- assert color == "#f8f4f0"
-
-
-def test_get_styles_simple():
- style = _get_fill_style({
- "fill-outline-color": "#dfdbd7",
- "fill-color": "#f2eae2",
- })
- styles = get_styles(style)
- assert len(styles) == 1
- assert styles[0] == {
- "fill-outline-color": "#dfdbd7",
- "fill-color": "#f2eae2",
- "zoom_level": None,
- "min_scale_denom": None,
- "max_scale_denom": None
- }
-
-
-def test_highway_motorway():
- style = _get_line_layer({
- "line-width": {
- "base": 1.2,
- "stops": [
- [
- 6.5,
- 0
- ],
- [
- 7,
- 0.5
- ],
- [
- 20,
- 18
- ]
- ]
- }
- })
- result = get_styles(style)
- assert len(result) == 2
-
-
-def test_scale():
- style = _get_line_layer({
- "line-width": {
- "stops": [
- [
- 10,
- 0
- ],
- [
- 15,
- 1
- ]
- ]
- }
- })
- styles = get_styles(style)
- assert len(styles) == 1
- assert styles[0]["zoom_level"] == 10
-
-
-def test_get_styles():
- style = _get_fill_style({
- "fill-outline-color": "#dfdbd7",
- "fill-color": "#f2eae2",
- "fill-opacity": {
- "base": 1,
- "stops": [
- [
- 13,
- 0
- ],
- [
- 16,
- 1
- ]
- ]
- }
- })
- styles = get_styles(style)
- assert len(styles) == 2
- styles = sorted(styles, key=lambda s: s["zoom_level"])
- assert _are_dicts_equal(styles[0], {
- 'fill-outline-color': '#dfdbd7',
- 'fill-color': '#f2eae2',
- 'zoom_level': 13,
- 'fill-opacity': 0,
- 'max_scale_denom': 100000,
- 'min_scale_denom': 12500
- })
- assert _are_dicts_equal(styles[1], {
- 'fill-outline-color': '#dfdbd7',
- 'fill-color': '#f2eae2',
- 'zoom_level': 16,
- 'fill-opacity': 1,
- 'max_scale_denom': 12500,
- 'min_scale_denom': 1
- })
-
-
-def test_filter_depth():
- highway_primary_casing = get_qgis_rule(_highway_primary_casing, escape_result=False)
- highway_primary = get_qgis_rule(_highway_primary, escape_result=False)
- assert highway_primary_casing == highway_primary
-
-
-_highway_primary_casing = [
- "all",
- [
- "!in",
- "brunnel",
- "bridge",
- "tunnel"
- ],
- [
- "in",
- "class",
- "primary"
- ]
-]
-
-_highway_primary = [
- "all",
- [
- "==",
- "$type",
- "LineString"
- ],
- [
- "all",
- [
- "!in",
- "brunnel",
- "bridge",
- "tunnel"
- ],
- [
- "in",
- "class",
- "primary"
- ]
- ]
-]
-
-
-def _are_dicts_equal(d1, d2):
- for k in d1:
- if k not in d2:
- raise AssertionError("Key '{}' not in d2: {}".format(k, d2))
- for k in d2:
- if k not in d1:
- raise AssertionError("Key '{}' not in d1: {}".format(k, d1))
- for k in d1:
- if d1[k] != d2[k]:
- raise AssertionError("Key '{}' not equal: {} != {}".format(k, d1[k], d2[k]))
- return True
-
-
-def _get_fill_style(paint):
- return {
- "id": None,
- "type": "fill",
- "paint": paint
- }
-
-
-def _get_line_layer(paint):
- return {
- "id": None,
- "type": "line",
- "paint": paint
- }
diff --git a/ext-libs/mapboxstyle2qgis/tests/test_parser.py b/ext-libs/mapboxstyle2qgis/tests/test_parser.py
deleted file mode 100644
index 8bcbac2..0000000
--- a/ext-libs/mapboxstyle2qgis/tests/test_parser.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import os
-import sys
-import shutil
-import json
-from xml.sax.saxutils import unescape
-sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
-
-from core import *
-from core import _create_icons
-
-
-def test_icon_creation():
- image_data = _load_file(os.path.join(os.path.dirname(__file__), "..", "sample_data", "sprite.png"), binary=True)
- image_data = base64.b64encode(image_data)
- image_definition_data = _load_file(os.path.join(os.path.dirname(__file__), "..", "sample_data", "sprite.json"))
- image_definition_data = json.loads(str(image_definition_data))
- output_directory = os.path.join(os.path.dirname(__file__), "generated")
- _create_icons(image_data, image_definition_data, output_directory=output_directory)
-
-
-def test_generate_qgis():
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "roman_empire.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "osm_bright.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_terrain.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_basic.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "positron.json")
- path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "mapcat.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "new_style.json")
- data = _load_file(path)
- data = json.loads(data)
- output_directory = r"C:\Users\Martin\AppData\Local\Temp\vector_tiles_reader\styles\mapcat"
- if os.path.isdir(output_directory):
- shutil.rmtree(output_directory)
- generate_styles(data, output_directory)
-
-
-def test_generate_local():
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "roman_empire.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "osm_bright.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_terrain.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_basic.json")
- # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "positron.json")
- path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "mapcat.json")
- data = _load_file(path)
- data = json.loads(data)
- output_directory = os.path.join(os.path.dirname(__file__), "generated")
- if os.path.isdir(output_directory):
- shutil.rmtree(output_directory)
- styles = process(data)
- generate_styles(data, output_directory)
-
-
-def test_filter():
- path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "with_filter.json")
- data = _load_file(path)
- style_obj = process(data)
- styles = style_obj["landuse_overlay.polygon.qml"]["styles"]
- assert len(styles) == 1
- assert "rule" in styles[0]
- assert unescape(styles[0]["rule"], entities={""": '"'}) == "\"class\" is not null and \"class\" = \'national_park\'"
-
-
-def _load_file(path, binary=False):
- mode = 'r'
- if binary:
- mode = 'rb'
- with open(path, mode) as f:
- data = f.read()
- return data
diff --git a/metadata.txt b/metadata.txt
index 6737b9f..4e8772b 100644
--- a/metadata.txt
+++ b/metadata.txt
@@ -12,7 +12,7 @@ about=Plugin which reads vector tiles according to Mapbox' Vector Tiles specific
* OpenMapTiles.com with OSM Bright MB GL style (default)
* Nextzen.org
This Python plugin uses prebuilt C++ binaries for performance reasons.
-version=3.0.2
+version=3.0.3
author=Martin Boos
email=geometalab@gmail.com
@@ -22,6 +22,8 @@ email=geometalab@gmail.com
# Uncomment the following line and add your changelog:
changelog=
+ ---3.0.3---
+ * Bugfix: Ensure Python 3.5 string format compatibility
---3.0.2---
* Disconnect internal event at shutdown of reader
---3.0.1---
diff --git a/ext-libs/mapboxstyle2qgis/.gitignore b/plugin/style_converter/.gitignore
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/.gitignore
rename to plugin/style_converter/.gitignore
diff --git a/ext-libs/mapboxstyle2qgis/.travis.yml b/plugin/style_converter/.travis.yml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/.travis.yml
rename to plugin/style_converter/.travis.yml
diff --git a/ext-libs/mapboxstyle2qgis/LICENSE b/plugin/style_converter/LICENSE
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/LICENSE
rename to plugin/style_converter/LICENSE
diff --git a/ext-libs/mapboxstyle2qgis/README.md b/plugin/style_converter/README.md
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/README.md
rename to plugin/style_converter/README.md
diff --git a/ext-libs/mapboxstyle2qgis/__init__.py b/plugin/style_converter/__init__.py
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/__init__.py
rename to plugin/style_converter/__init__.py
diff --git a/ext-libs/mapboxstyle2qgis/core/__init__.py b/plugin/style_converter/core/__init__.py
similarity index 81%
rename from ext-libs/mapboxstyle2qgis/core/__init__.py
rename to plugin/style_converter/core/__init__.py
index 6acd524..5c1371c 100644
--- a/ext-libs/mapboxstyle2qgis/core/__init__.py
+++ b/plugin/style_converter/core/__init__.py
@@ -1,17 +1,22 @@
-import os
-import json
-import copy
-import colorsys
-import urllib
import base64
+import colorsys
+import copy
+import json
+import os
import shutil
from itertools import groupby
+from typing import Dict, Tuple, TypeVar
+
+from qgis.core import QgsExpression
+
+from ...util.network_helper import http_get
+from .data import qgis_functions
from .xml_helper import create_style_file, escape_xml
+StrOrDict = TypeVar("StrOrDict", str, dict)
+
def register_qgis_expressions():
- from qgis.core import QgsExpression
- from .data import qgis_functions
QgsExpression.registerFunction(qgis_functions.get_zoom_for_scale)
QgsExpression.registerFunction(qgis_functions.if_not_exists)
QgsExpression.registerFunction(qgis_functions.interpolate_exp)
@@ -36,10 +41,10 @@ def get_background_color(text):
return bg_color
-def generate_styles(style_json, output_directory, web_request_executor=None):
+def generate_styles(style_json: StrOrDict, output_directory: str) -> None:
"""
* Creates and exports the styles
- :param text:
+ :param style_json:
:param output_directory:
:return:
"""
@@ -49,7 +54,7 @@ def generate_styles(style_json, output_directory, web_request_executor=None):
pass
styles = process(style_json)
write_styles(styles_by_target_layer=styles, output_directory=output_directory)
- create_icons(style=style_json, web_request_executor=web_request_executor, output_directory=output_directory)
+ create_icons(style=style_json, output_directory=output_directory)
def _apply_source_layer(layer, all_layers):
@@ -76,7 +81,7 @@ def _apply_source_layer(layer, all_layers):
def process(style_json):
"""
* Creates the style definitions and returns them mapped by filename
- :param text:
+ :param style_json:
:return:
"""
if not isinstance(style_json, dict):
@@ -103,11 +108,7 @@ def process(style_json):
file_name = "{}{}.qml".format(source_layer, geo_type_name)
if file_name not in styles_by_file_name:
- styles_by_file_name[file_name] = {
- "file_name": file_name,
- "type": layer_type,
- "styles": []
- }
+ styles_by_file_name[file_name] = {"file_name": file_name, "type": layer_type, "styles": []}
qgis_styles = get_styles(l)
filter_expr = None
if "filter" in l:
@@ -122,26 +123,30 @@ def process(style_json):
rule = style["rule"]
name = style["name"]
zoom = style["zoom_level"]
- styles_with_same_target = list(filter(lambda s: s["name"] != name and s["rule"] == rule and zoom and s["zoom_level"] <= zoom, styles[:index]))
- groups_by_name = list(groupby(styles_with_same_target, key=lambda s: s["name"]))
+ styles_with_same_target = list(
+ filter(
+ lambda st: st["name"] != name and st["rule"] == rule and zoom and st["zoom_level"] <= zoom,
+ styles[:index],
+ )
+ )
+ groups_by_name = list(groupby(styles_with_same_target, key=lambda st: st["name"]))
style["rendering_pass"] = len(groups_by_name)
_add_default_transparency_styles(styles_by_file_name)
return styles_by_file_name
-def create_icons(style, web_request_executor, output_directory):
+def create_icons(style, output_directory):
"""
Loads the sprites defined by sprites.json and sprites.data and extracts the specific items by creating
svg icons that clip the defined region (defined in sprites.json) from the sprites.png so that only one icons
remains.
:param style:
- :param web_request_executor:
:param output_directory:
:return:
"""
- image_data, image_definition_data = _load_sprite_data(style, web_request_executor)
+ image_data, image_definition_data = _load_sprite_data(style)
if image_data and image_definition_data:
_create_icons(image_data, image_definition_data, output_directory)
@@ -151,7 +156,7 @@ def _create_icons(image_base64, image_definition_data, output_directory):
if not os.path.isdir(icons_directory):
os.makedirs(icons_directory)
- with open(os.path.join(icons_directory, "sprite.json"), 'w') as f:
+ with open(os.path.join(icons_directory, "sprite.json"), "w") as f:
f.write(json.dumps(image_definition_data))
src_icon_path = os.path.join(os.path.dirname(__file__), "data", "icons", "empty.svg")
@@ -159,63 +164,49 @@ def _create_icons(image_base64, image_definition_data, output_directory):
template_path = os.path.join(os.path.dirname(__file__), "data", "svg_template.svg")
assert os.path.isfile(template_path)
- with open(template_path, 'r') as f:
+ with open(template_path, "r") as f:
template_data = f.read()
for name in image_definition_data:
img_def = image_definition_data[name]
file_name = "{}.svg".format(name)
- svg_data = template_data.format(width=img_def["width"],
- height=img_def["height"],
- x=img_def["x"],
- y=img_def["y"],
- base64_data=image_base64)
+ svg_data = template_data.format(
+ width=img_def["width"], height=img_def["height"], x=img_def["x"], y=img_def["y"], base64_data=image_base64
+ )
target_file = os.path.join(icons_directory, file_name)
- with open(target_file, 'w') as f:
+ with open(target_file, "w") as f:
f.write(svg_data)
-def _load_sprite_data(style, web_request_executor):
- if not web_request_executor:
- web_request_executor = _execute_get_request
-
+def _load_sprite_data(style: dict) -> Tuple:
+ image_data = None
+ image_definition_data = None
if "sprite" in style:
image_url = "{}.png".format(style["sprite"])
image_definitions_url = "{}.json".format(style["sprite"])
if not image_url.startswith("http") or not image_definitions_url.startswith("http"):
return None, None
- image_data = web_request_executor(image_url)
- image_definition_data = web_request_executor(image_definitions_url)
+ _, image_data = http_get(image_url)
+ _, image_definition_data = http_get(image_definitions_url)
if not image_data:
raise "No image found at: {}".format(image_url)
else:
image_data = base64.b64encode(image_data)
+
if not image_definition_data:
raise "No image definitions found at: {}".format(image_definition_data)
else:
image_definition_data = json.loads(str(image_definition_data))
- return image_data, image_definition_data
- return None, None
-
+ return image_data, image_definition_data
-def _execute_get_request(url):
- response = urllib.urlopen(url)
- data = response.read()
- return data
-
-def _add_default_transparency_styles(style_dict):
+def _add_default_transparency_styles(style: dict):
for t in ["point", "linestring", "polygon"]:
file_name = "transparent.{}.qml".format(t)
- style_dict[file_name] = {
- "styles": [],
- "file_name": file_name,
- "layer-transparency": 100,
- "type": None
- }
+ style[file_name] = {"styles": [], "file_name": file_name, "layer-transparency": 100, "type": None}
-def write_styles(styles_by_target_layer, output_directory):
+def write_styles(styles_by_target_layer: Dict[str, dict], output_directory: str) -> None:
"""
Creates the qml files that can be applied to qgis layers.
:param styles_by_target_layer:
@@ -234,31 +225,13 @@ def write_styles(styles_by_target_layer, output_directory):
create_style_file(output_directory=output_directory, layer_style=style)
-_comparision_operators = {
- "match": "=",
- "==": "=",
- "<=": "<=",
- ">=": ">=",
- "<": "<",
- ">": ">",
- "!=": "!="
-}
+_comparision_operators = {"match": "=", "==": "=", "<=": "<=", ">=": ">=", "<": "<", ">": ">", "!=": "!="}
-_combining_operators = {
- "all": "and",
- "any": "or",
- "none": "and not"
-}
+_combining_operators = {"all": "and", "any": "or", "none": "and not"}
-_membership_operators = {
- "in": "in",
- "!in": "not in"
-}
+_membership_operators = {"in": "in", "!in": "not in"}
-_existential_operators = {
- "has": "is not null",
- "!has": "is null"
-}
+_existential_operators = {"has": "is not null", "!has": "is null"}
"""
* the upper bound map scales by zoom level.
@@ -292,7 +265,7 @@ def write_styles(styles_by_target_layer, output_directory):
21: 500,
22: 250,
23: 100,
- 24: 0
+ 24: 0,
}
@@ -303,11 +276,7 @@ def get_styles(layer):
layer_type = layer["type"]
- base_style = {
- "zoom_level": None,
- "min_scale_denom": None,
- "max_scale_denom": None
- }
+ base_style = {"zoom_level": None, "min_scale_denom": None, "max_scale_denom": None}
if layer_id:
base_style["name"] = layer_id
@@ -317,7 +286,9 @@ def get_styles(layer):
all_values = []
if layer_type == "fill":
- all_values.extend(get_properties_values_for_zoom(layer, "paint/fill-color", is_color=True, default="rgba(0,0,0,0)"))
+ all_values.extend(
+ get_properties_values_for_zoom(layer, "paint/fill-color", is_color=True, default="rgba(0,0,0,0)")
+ )
all_values.extend(get_properties_values_for_zoom(layer, "paint/fill-outline-color", is_color=True))
all_values.extend(get_properties_values_for_zoom(layer, "paint/fill-translate"))
all_values.extend(get_properties_values_for_zoom(layer, "paint/fill-opacity"))
@@ -326,7 +297,9 @@ def get_styles(layer):
all_values.extend(get_properties_values_for_zoom(layer, "layout/line-join"))
all_values.extend(get_properties_values_for_zoom(layer, "layout/line-cap"))
all_values.extend(get_properties_values_for_zoom(layer, "paint/line-width", default=0, can_interpolate=True))
- all_values.extend(get_properties_values_for_zoom(layer, "paint/line-color", is_color=True, default="rgba(0,0,0,0)"))
+ all_values.extend(
+ get_properties_values_for_zoom(layer, "paint/line-color", is_color=True, default="rgba(0,0,0,0)")
+ )
all_values.extend(get_properties_values_for_zoom(layer, "paint/line-opacity"))
all_values.extend(get_properties_values_for_zoom(layer, "paint/line-dasharray"))
elif layer_type == "symbol":
@@ -371,13 +344,13 @@ def get_styles(layer):
resulting_styles.append(clone)
styles_backwards = list(reversed(resulting_styles))
for index, s in enumerate(styles_backwards):
- if index < len(resulting_styles)-1:
- next_style = styles_backwards[index+1]
+ if index < len(resulting_styles) - 1:
+ next_style = styles_backwards[index + 1]
for k in s:
if k not in next_style:
next_style[k] = s[k]
- resulting_styles = sorted(resulting_styles, key=lambda s: s["zoom_level"])
+ resulting_styles = sorted(resulting_styles, key=lambda st: st["zoom_level"])
_apply_scale_range(resulting_styles)
return resulting_styles
@@ -397,7 +370,6 @@ def _parse_expr(expr, take=None):
is_data_expression = True if op in data_expression_operators else False
if not is_data_expression:
return ""
- raise RuntimeError("Unknown expression: ", expr)
else:
if op == "get":
assert len(expr) == 2
@@ -427,15 +399,15 @@ def _get_qgis_fields(expr):
if isinstance(expr, list):
# todo: what happens here?
raise RuntimeError("invalid: ", expr)
- return []
values = []
val = None
is_expr = False
+ new_is_expr = False
for s in expr:
if not is_expr:
- new_is_expr = s == '{'
- elif s == '}':
+ new_is_expr = s == "{"
+ elif s == "}":
new_is_expr = False
has_changed = new_is_expr != is_expr
is_expr = new_is_expr
@@ -446,10 +418,7 @@ def _get_qgis_fields(expr):
if has_changed:
continue
if val is None:
- val = {
- "text": "",
- "is_expr": is_expr
- }
+ val = {"text": "", "is_expr": is_expr}
if isinstance(s, list):
raise RuntimeError("Unknown s: ", expr)
val["text"] += s
@@ -475,7 +444,7 @@ def parse_color(color):
elif color.startswith("#"):
color = color.replace("#", "")
if len(color) == 3:
- color = "".join(list(map(lambda c: c+c, color)))
+ color = "".join(list(map(lambda c: c + c, color)))
elif len(color) == 6:
return "#" + color
return ",".join(list(map(lambda v: str(int(v)), bytearray.fromhex(color))))
@@ -487,8 +456,16 @@ def _get_color_string(color):
color = color.lower()
has_alpha = color.startswith("hsla(") or color.startswith("rgba(")
is_hsl = color.startswith("hsl")
- colors = color.replace("hsla(", "").replace("hsl(", "").replace("rgba(", "").replace("rgb(", "").replace(")", "")\
- .replace(" ", "").replace("%", "").split(",")
+ colors = (
+ color.replace("hsla(", "")
+ .replace("hsl(", "")
+ .replace("rgba(", "")
+ .replace("rgb(", "")
+ .replace(")", "")
+ .replace(" ", "")
+ .replace("%", "")
+ .split(",")
+ )
colors = list(map(lambda c: float(c), colors))
a = 1
if has_alpha:
@@ -496,14 +473,14 @@ def _get_color_string(color):
if is_hsl:
h = colors[0] / 360.0
s = colors[1] / 100.0
- l = colors[2] / 100.0
- r, g, b = colorsys.hls_to_rgb(h, l, s)
+ l_value = colors[2] / 100.0
+ r, g, b = colorsys.hls_to_rgb(h, l_value, s)
return ",".join(list(map(lambda c: str(int(round(255.0 * c))), [r, g, b, a])))
else:
r = colors[0]
g = colors[1]
b = colors[2]
- a = round(255.0*a)
+ a = round(255.0 * a)
return ",".join(list(map(lambda c: str(int(c)), [r, g, b, a])))
@@ -516,7 +493,7 @@ def _apply_scale_range(styles):
if index == len(styles) - 1:
min_scale_denom = 1
else:
- zoom_of_next = styles[index+1]["zoom_level"]
+ zoom_of_next = styles[index + 1]["zoom_level"]
min_scale_denom = upper_bound_map_scales_by_zoom_level[zoom_of_next]
s["min_scale_denom"] = min_scale_denom
s["max_scale_denom"] = max_scale_denom
@@ -531,7 +508,9 @@ def _get_property_value(obj, property_path):
return value, property_name
-def get_properties_values_for_zoom(paint, property_path, is_color=False, is_expression=False, can_interpolate=False, default=None, take=None):
+def get_properties_values_for_zoom(
+ paint, property_path, is_color=False, is_expression=False, can_interpolate=False, default=None, take=None
+):
"""
Returns a list of properties (defined by name, zoom_level, value and is_qgis_expr)
If stops are defined, multiple properties will be in the list. One for each zoom-level defined by the stops.
@@ -580,29 +559,27 @@ def get_properties_values_for_zoom(paint, property_path, is_color=False, is_expr
second_value = next_stop[1]
max_scale = upper_bound_map_scales_by_zoom_level[int(lower_zoom)]
min_scale = upper_bound_map_scales_by_zoom_level[int(upper_zoom)]
- value = "interpolate_exp(get_zoom_for_scale(@map_scale), {base}, {min_zoom}, {max_zoom}, {first_value}, {second_value})"\
- .format(min_zoom=int(lower_zoom),
- max_zoom=int(upper_zoom),
- base=base,
- min_scale=min_scale,
- max_scale=max_scale,
- first_value=value,
- second_value=second_value)
- properties.append({
- "name": property_name,
- "zoom_level": int(lower_zoom),
- "value": value,
- "is_qgis_expr": is_qgis_expr})
+ value = (
+ "interpolate_exp(get_zoom_for_scale(@map_scale), {base}, {min_zoom}, {max_zoom}, "
+ "{first_value}, {second_value})".format(
+ min_zoom=int(lower_zoom),
+ max_zoom=int(upper_zoom),
+ base=base,
+ min_scale=min_scale,
+ max_scale=max_scale,
+ first_value=value,
+ second_value=second_value,
+ )
+ )
+ properties.append(
+ {"name": property_name, "zoom_level": int(lower_zoom), "value": value, "is_qgis_expr": is_qgis_expr}
+ )
elif value is not None:
if is_color:
value = parse_color(value)
if is_expression:
value = _parse_expr(value, take=take)
- properties.append({
- "name": property_name,
- "zoom_level": None,
- "value": value,
- "is_qgis_expr": is_expression})
+ properties.append({"name": property_name, "zoom_level": None, "value": value, "is_qgis_expr": is_expression})
return properties
@@ -629,7 +606,7 @@ def get_qgis_rule(mb_filter, escape_result=True, depth=0):
result = _get_comparision_expr(mb_filter)
elif op in _combining_operators:
is_none = op == "none"
- all_exprs = map(lambda f: get_qgis_rule(f, escape_result=False, depth=depth+1), mb_filter[1:])
+ all_exprs = map(lambda f: get_qgis_rule(f, escape_result=False, depth=depth + 1), mb_filter[1:])
all_exprs = list(filter(lambda e: e is not None, all_exprs))
comb_op = _combining_operators[op]
if comb_op == "and" and len(all_exprs) > 1:
@@ -669,11 +646,7 @@ def dumps(self):
assert isinstance(self.else_if, If)
else_dump = self.else_if.dumps()
- return "if ({}, {}, {})".format(
- self.comparision,
- "'{}'".format(self.if_value),
- else_dump
- )
+ return "if ({}, {}, {})".format(self.comparision, "'{}'".format(self.if_value), else_dump)
def __repr__(self):
return self.dumps()
@@ -721,11 +694,11 @@ def _get_comparision_expr(mb_filter):
op = _comparision_operators[mb_filter[0]]
attr = mb_filter[1]
value = mb_filter[2]
- if attr == '$type':
+ if attr == "$type":
return None
attr_in_quotes = not attr.startswith("@")
if attr_in_quotes:
- attr = "\"{}\"".format(attr)
+ attr = '"{}"'.format(attr)
null_allowed = op == "!="
if null_allowed:
null = "{attr} is null or {attr}"
@@ -738,7 +711,7 @@ def _get_comparision_expr(mb_filter):
def _get_membership_expr(mb_filter):
assert mb_filter[0] in _membership_operators
assert len(mb_filter) >= 3
- what = "\"{}\"".format(mb_filter[1])
+ what = '"{}"'.format(mb_filter[1])
op = _membership_operators[mb_filter[0]]
collection = "({})".format(", ".join(list(map(lambda e: "'{}'".format(e), mb_filter[2:]))))
is_not = mb_filter[0].startswith("!")
diff --git a/ext-libs/mapboxstyle2qgis/core/data/__init__.py b/plugin/style_converter/core/data/__init__.py
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/core/data/__init__.py
rename to plugin/style_converter/core/data/__init__.py
diff --git a/ext-libs/mapboxstyle2qgis/core/data/icons/empty.svg b/plugin/style_converter/core/data/icons/empty.svg
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/core/data/icons/empty.svg
rename to plugin/style_converter/core/data/icons/empty.svg
diff --git a/ext-libs/mapboxstyle2qgis/core/data/qgis_functions.py b/plugin/style_converter/core/data/qgis_functions.py
similarity index 82%
rename from ext-libs/mapboxstyle2qgis/core/data/qgis_functions.py
rename to plugin/style_converter/core/data/qgis_functions.py
index 5527d54..b344fbb 100644
--- a/ext-libs/mapboxstyle2qgis/core/data/qgis_functions.py
+++ b/plugin/style_converter/core/data/qgis_functions.py
@@ -3,33 +3,39 @@
last args. Use args=-1 to pass a list of values as arguments
"""
-from qgis.core import *
-from qgis.gui import *
-import os
import json
+import os
+
+# from qgis.core import *
+# from qgis.gui import *
+from qgis.utils import qgsfunction
+
def interpolate(a, b, ratio):
return (a * (1 - ratio)) + (b * ratio)
+
def get_exponential_interpolation_factor(input, base, lower, upper):
difference = upper - lower
progress = input - lower
- if (difference == 0):
+ if difference == 0:
return difference
elif base == 1:
return progress / difference
else:
- ratio = ((base**progress) - 1) / ((base**difference) - 1)
+ ratio = ((base ** progress) - 1) / ((base ** difference) - 1)
return ratio
-@qgsfunction(args='auto', group='Custom')
+
+@qgsfunction(args="auto", group="Custom")
def if_not_exists(file_path, default, feature, parent):
- if os.path.isfile(file_path):
- return file_path
- else:
- return default
+ if os.path.isfile(file_path):
+ return file_path
+ else:
+ return default
+
-@qgsfunction(args='auto', group='Custom')
+@qgsfunction(args="auto", group="Custom")
def interpolate_exp(zoom, base, lower_zoom, upper_zoom, lower_value, upper_value, feature, parent):
ratio = get_exponential_interpolation_factor(zoom, base, lower_zoom, upper_zoom)
return interpolate(lower_value, upper_value, ratio)
@@ -40,14 +46,15 @@ def interpolate_exp(zoom, base, lower_zoom, upper_zoom, lower_value, upper_value
global mvtr_icons_data
mvtr_icons_data = None
-@qgsfunction(args='auto', group='Custom')
+
+@qgsfunction(args="auto", group="Custom")
def get_icon_size(name, icons_directory, feature, parent):
global mvtr_icons_dir
global mvtr_icons_data
if not mvtr_icons_dir or mvtr_icons_dir != icons_directory:
mvtr_icons_dir = icons_directory
- with open(os.path.join(icons_directory, "sprite.json"), 'r') as f:
+ with open(os.path.join(icons_directory, "sprite.json"), "r") as f:
mvtr_icons_data = json.loads(f.read())
size = max(mvtr_icons_data[name]["width"], mvtr_icons_data[name]["height"])
return size
@@ -77,15 +84,17 @@ def get_icon_size(name, icons_directory, feature, parent):
500: 20,
250: 21,
100: 22,
- 0: 23
+ 0: 23,
}
+
def get_zoom(scale, lower_scale, upper_scale, lower_zoom, upper_zoom):
ratio = float(upper_scale - scale) / (upper_scale - lower_scale)
zoom = lower_zoom + (upper_zoom - lower_zoom) * ratio
return zoom
-@qgsfunction(args='auto', group='Custom')
+
+@qgsfunction(args="auto", group="Custom")
def get_zoom_for_scale(scale, feature, parent):
scale = int(scale)
scales_sorted = list(reversed(sorted(_zoom_level_by_lower_scale_bound)))
@@ -96,8 +105,8 @@ def get_zoom_for_scale(scale, feature, parent):
for index, s in enumerate(scales_sorted):
if scale > s:
lower_scale = s
- upper_scale = scales_sorted[index+1]
+ upper_scale = scales_sorted[index + 1]
lower_zoom = _zoom_level_by_lower_scale_bound[upper_scale]
upper_zoom = _zoom_level_by_lower_scale_bound[lower_scale]
break
- return get_zoom(scale, lower_scale, upper_scale, lower_zoom, upper_zoom)
\ No newline at end of file
+ return get_zoom(scale, lower_scale, upper_scale, lower_zoom, upper_zoom)
diff --git a/ext-libs/mapboxstyle2qgis/core/data/qml_template.xml b/plugin/style_converter/core/data/qml_template.xml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/core/data/qml_template.xml
rename to plugin/style_converter/core/data/qml_template.xml
diff --git a/ext-libs/mapboxstyle2qgis/core/data/svg_template.svg b/plugin/style_converter/core/data/svg_template.svg
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/core/data/svg_template.svg
rename to plugin/style_converter/core/data/svg_template.svg
diff --git a/ext-libs/mapboxstyle2qgis/core/xml_helper.py b/plugin/style_converter/core/xml_helper.py
similarity index 80%
rename from ext-libs/mapboxstyle2qgis/core/xml_helper.py
rename to plugin/style_converter/core/xml_helper.py
index 76510a0..ce848ec 100644
--- a/ext-libs/mapboxstyle2qgis/core/xml_helper.py
+++ b/plugin/style_converter/core/xml_helper.py
@@ -2,23 +2,13 @@
import uuid
from xml.sax.saxutils import escape
-_join_styles = {
- None: "round",
- "bevel": "bevel",
- "round": "round",
- "miter": "miter"
-}
+_join_styles = {None: "round", "bevel": "bevel", "round": "round", "miter": "miter"}
-_cap_styles = {
- None: "round",
- "butt": "flat",
- "square": "square",
- "round": "round"
-}
+_cap_styles = {None: "round", "butt": "flat", "square": "square", "round": "round"}
def create_style_file(output_directory, layer_style):
- with open(os.path.join(os.path.dirname(__file__), "data/qml_template.xml"), 'r') as f:
+ with open(os.path.join(os.path.dirname(__file__), "data/qml_template.xml"), "r") as f:
template = f.read()
layer_type = layer_style["type"]
@@ -44,25 +34,28 @@ def create_style_file(output_directory, layer_style):
labeling_rules.append(_get_rule(index, s, rule_content=labeling_settings))
if "icon-image" in s:
rules.append(_get_rule(index, s, rule_content=""))
- icn = _get_icon_symbol(index=index,
- style=s,
- icons_directory=icons_directory,
- icon_expr=s["icon-image"])
+ icn = _get_icon_symbol(index=index, style=s, icons_directory=icons_directory, icon_expr=s["icon-image"])
symbols.append(icn)
rule_string = """
{rules}
- """.format(key=str(uuid.uuid4()), rules="\n".join(rules))
+ """.format(
+ key=str(uuid.uuid4()), rules="\n".join(rules)
+ )
symbol_string = """
{symbols}
- """.format(symbols="\n".join(symbols))
+ """.format(
+ symbols="\n".join(symbols)
+ )
renderer = """
{rules}
{symbols}
- """.format(rules=rule_string, symbols=symbol_string)
+ """.format(
+ rules=rule_string, symbols=symbol_string
+ )
if not rules:
renderer = """"""
@@ -73,16 +66,18 @@ def create_style_file(output_directory, layer_style):
{rules}
- """.format(rules="\n".join(labeling_rules)).replace("$key$", '{' + str(uuid.uuid4()) + '}')
+ """.format(
+ rules="\n".join(labeling_rules)
+ ).replace(
+ "$key$", "{" + str(uuid.uuid4()) + "}"
+ )
- template = template.format(renderer=renderer,
- labeling=labeling_string,
- layer_transparency=layer_transparency)
+ template = template.format(renderer=renderer, labeling=labeling_string, layer_transparency=layer_transparency)
file_path = os.path.join(output_directory, layer_style["file_name"])
if not os.path.isdir(output_directory):
os.makedirs(output_directory)
- with open(file_path, 'w') as f:
+ with open(file_path, "w") as f:
f.write(template)
@@ -104,7 +99,7 @@ def _get_labeling_settings(style):
text_transform = "lower"
else:
raise ValueError("Unknown text_transform '{}'".format(text_transform))
- field_name = '{transform}({field})'.format(transform=text_transform, field=field_name)
+ field_name = "{transform}({field})".format(transform=text_transform, field=field_name)
italic_font = 0
if isinstance(font, list):
@@ -128,10 +123,7 @@ def _get_labeling_settings(style):
# if buffer_size > 0:
# draw_buffer = 1
- label_placement_flags = {
- "line": 9,
- "above": 10
- }
+ # label_placement_flags = {"line": 9, "above": 10}
return """
@@ -149,16 +141,18 @@ def _get_labeling_settings(style):
- """.format(font=font,
- italic_font=italic_font,
- font_size=font_size,
- font_size_expr=font_size_expr,
- field_name=field_name,
- text_color=text_color,
- buffer_size=buffer_size,
- buffer_color=buffer_color,
- font_size_expr_active=font_size_expr_active,
- draw_buffer=draw_buffer)
+ """.format( # noqa
+ font=font,
+ italic_font=italic_font,
+ font_size=font_size,
+ font_size_expr=font_size_expr,
+ field_name=field_name,
+ text_color=text_color,
+ buffer_size=buffer_size,
+ buffer_color=buffer_color,
+ font_size_expr_active=font_size_expr_active,
+ draw_buffer=draw_buffer,
+ )
def _get_icon_symbol(index, style, icons_directory, icon_expr):
@@ -167,8 +161,9 @@ def _get_icon_symbol(index, style, icons_directory, icon_expr):
fallback_path = "'" + os.path.join(icons_directory, "empty.svg'").replace("\\", "/")
svg_expr = "if_not_exists({svg_path}, {fallback_path})".format(svg_path=svg_path, fallback_path=fallback_path)
rendering_pass = _get_value_safe(style, "rendering_pass", 0)
- icon_size_expr = "get_icon_size({icon}, '{icons_dir}')".format(icon=icon_expr,
- icons_dir=icons_directory.replace("\\", "/"))
+ icon_size_expr = "get_icon_size({icon}, '{icons_dir}')".format(
+ icon=icon_expr, icons_dir=icons_directory.replace("\\", "/")
+ )
return """
@@ -198,12 +193,14 @@ def _get_icon_symbol(index, style, icons_directory, icon_expr):
- """.format(description=style["name"],
- opacity=opacity,
- svg_path=svg_expr,
- index=index,
- size=icon_size_expr,
- rendering_pass=rendering_pass)
+ """.format(
+ description=style["name"],
+ opacity=opacity,
+ svg_path=svg_expr,
+ index=index,
+ size=icon_size_expr,
+ rendering_pass=rendering_pass,
+ )
def _get_fill_symbol(index, style, icons_directory):
@@ -219,20 +216,24 @@ def _get_fill_symbol(index, style, icons_directory):
label = "{}-zoom-{}".format(label, style["zoom_level"])
if fill_pattern:
- symbol = _get_fill_pattern_symbol_xml(pattern=fill_pattern,
- label=label,
- index=index,
- opacity=opacity,
- rendering_pass=rendering_pass,
- icons_directory=icons_directory)
+ symbol = _get_fill_pattern_symbol_xml(
+ pattern=fill_pattern,
+ label=label,
+ index=index,
+ opacity=opacity,
+ rendering_pass=rendering_pass,
+ icons_directory=icons_directory,
+ )
else:
- symbol = _get_fill_symbol_xml(fill_color_rgba=fill_color_rgba,
- fill_outline_color_rgba=fill_outline_color_rgba,
- index=index,
- label=label,
- offset=offset,
- opacity=opacity,
- rendering_pass=rendering_pass)
+ symbol = _get_fill_symbol_xml(
+ fill_color_rgba=fill_color_rgba,
+ fill_outline_color_rgba=fill_outline_color_rgba,
+ index=index,
+ label=label,
+ offset=offset,
+ opacity=opacity,
+ rendering_pass=rendering_pass,
+ )
return symbol
@@ -279,11 +280,9 @@ def _get_fill_pattern_symbol_xml(pattern, label, index, opacity, rendering_pass,
- """.format(description=label,
- opacity=opacity,
- index=index,
- svg_path=svg_expr,
- rendering_pass=rendering_pass)
+ """.format(
+ description=label, opacity=opacity, index=index, svg_path=svg_expr, rendering_pass=rendering_pass
+ )
def _get_fill_symbol_xml(fill_color_rgba, fill_outline_color_rgba, index, label, offset, opacity, rendering_pass):
@@ -303,13 +302,15 @@ def _get_fill_symbol_xml(fill_color_rgba, fill_outline_color_rgba, index, label,
- """.format(opacity=opacity,
- index=index,
- fill_color=fill_color_rgba,
- fill_outline_color=fill_outline_color_rgba,
- offset=offset,
- description=label,
- rendering_pass=rendering_pass)
+ """.format(
+ opacity=opacity,
+ index=index,
+ fill_color=fill_color_rgba,
+ fill_outline_color=fill_outline_color_rgba,
+ offset=offset,
+ description=label,
+ rendering_pass=rendering_pass,
+ )
return symbol
@@ -369,19 +370,21 @@ def _get_line_symbol(index, style):
- """.format(index=index,
- width_dd_active=width_dd_active,
- line_width=width,
- line_width_expr=width_expr,
- opacity=opacity,
- line_color=color,
- capstyle=capstyle,
- joinstyle=joinstyle,
- use_custom_dash=use_custom_dash,
- custom_dash=dash_string,
- dash_expr=dash_expr,
- description=label,
- rendering_pass=rendering_passs)
+ """.format(
+ index=index,
+ width_dd_active=width_dd_active,
+ line_width=width,
+ line_width_expr=width_expr,
+ opacity=opacity,
+ line_color=color,
+ capstyle=capstyle,
+ joinstyle=joinstyle,
+ use_custom_dash=use_custom_dash,
+ custom_dash=dash_string,
+ dash_expr=dash_expr,
+ description=label,
+ rendering_pass=rendering_passs,
+ )
return symbol
@@ -419,12 +422,16 @@ def _get_rule(index, style, rule_content):
rule = """
{rule_content}
- """.format(max_denom=max_denom,
- min_denom=min_denom,
- symbol=index,
- label=label,
- filter=rule_filter,
- rule_content=rule_content).replace("$key$", '{' + rule_key + '}')
+ """.format(
+ max_denom=max_denom,
+ min_denom=min_denom,
+ symbol=index,
+ label=label,
+ filter=rule_filter,
+ rule_content=rule_content,
+ ).replace(
+ "$key$", "{" + rule_key + "}"
+ )
return rule
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/basic_v9.json b/plugin/style_converter/sample_data/basic_v9.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/basic_v9.json
rename to plugin/style_converter/sample_data/basic_v9.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/building_opaque.qml b/plugin/style_converter/sample_data/building_opaque.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/building_opaque.qml
rename to plugin/style_converter/sample_data/building_opaque.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/building_transparent.qml b/plugin/style_converter/sample_data/building_transparent.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/building_transparent.qml
rename to plugin/style_converter/sample_data/building_transparent.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/color_as_expr.qml b/plugin/style_converter/sample_data/color_as_expr.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/color_as_expr.qml
rename to plugin/style_converter/sample_data/color_as_expr.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/dash_as_expr.qml b/plugin/style_converter/sample_data/dash_as_expr.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/dash_as_expr.qml
rename to plugin/style_converter/sample_data/dash_as_expr.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/dash_as_value.qml b/plugin/style_converter/sample_data/dash_as_value.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/dash_as_value.qml
rename to plugin/style_converter/sample_data/dash_as_value.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/dash_multiple_patterns.qml b/plugin/style_converter/sample_data/dash_multiple_patterns.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/dash_multiple_patterns.qml
rename to plugin/style_converter/sample_data/dash_multiple_patterns.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/dash_single_pattern.qml b/plugin/style_converter/sample_data/dash_single_pattern.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/dash_single_pattern.qml
rename to plugin/style_converter/sample_data/dash_single_pattern.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/font_size_expr.qml b/plugin/style_converter/sample_data/font_size_expr.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/font_size_expr.qml
rename to plugin/style_converter/sample_data/font_size_expr.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/font_size_mapunits.qml b/plugin/style_converter/sample_data/font_size_mapunits.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/font_size_mapunits.qml
rename to plugin/style_converter/sample_data/font_size_mapunits.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/font_size_points.qml b/plugin/style_converter/sample_data/font_size_points.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/font_size_points.qml
rename to plugin/style_converter/sample_data/font_size_points.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/font_size_value.qml b/plugin/style_converter/sample_data/font_size_value.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/font_size_value.qml
rename to plugin/style_converter/sample_data/font_size_value.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/klokantech_basic.json b/plugin/style_converter/sample_data/klokantech_basic.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/klokantech_basic.json
rename to plugin/style_converter/sample_data/klokantech_basic.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/klokantech_terrain.json b/plugin/style_converter/sample_data/klokantech_terrain.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/klokantech_terrain.json
rename to plugin/style_converter/sample_data/klokantech_terrain.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_default.qml b/plugin/style_converter/sample_data/label_default.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_default.qml
rename to plugin/style_converter/sample_data/label_default.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_styled.qml b/plugin/style_converter/sample_data/label_styled.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_styled.qml
rename to plugin/style_converter/sample_data/label_styled.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_with_description.qml b/plugin/style_converter/sample_data/label_with_description.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_with_description.qml
rename to plugin/style_converter/sample_data/label_with_description.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_with_expression.qml b/plugin/style_converter/sample_data/label_with_expression.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_with_expression.qml
rename to plugin/style_converter/sample_data/label_with_expression.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_with_field.qml b/plugin/style_converter/sample_data/label_with_field.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_with_field.qml
rename to plugin/style_converter/sample_data/label_with_field.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/label_without_description.qml b/plugin/style_converter/sample_data/label_without_description.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/label_without_description.qml
rename to plugin/style_converter/sample_data/label_without_description.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/labels_curved.qml b/plugin/style_converter/sample_data/labels_curved.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/labels_curved.qml
rename to plugin/style_converter/sample_data/labels_curved.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/labels_parallel.qml b/plugin/style_converter/sample_data/labels_parallel.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/labels_parallel.qml
rename to plugin/style_converter/sample_data/labels_parallel.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_rule.qml b/plugin/style_converter/sample_data/line_rule.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_rule.qml
rename to plugin/style_converter/sample_data/line_rule.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_width_pixel.qml b/plugin/style_converter/sample_data/line_width_pixel.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_width_pixel.qml
rename to plugin/style_converter/sample_data/line_width_pixel.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_with_labeling - Copy.qml b/plugin/style_converter/sample_data/line_with_labeling - Copy.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_with_labeling - Copy.qml
rename to plugin/style_converter/sample_data/line_with_labeling - Copy.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_with_labeling.qml b/plugin/style_converter/sample_data/line_with_labeling.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_with_labeling.qml
rename to plugin/style_converter/sample_data/line_with_labeling.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_with_transparency.qml b/plugin/style_converter/sample_data/line_with_transparency.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_with_transparency.qml
rename to plugin/style_converter/sample_data/line_with_transparency.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/line_without_labeling.qml b/plugin/style_converter/sample_data/line_without_labeling.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/line_without_labeling.qml
rename to plugin/style_converter/sample_data/line_without_labeling.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/mapcat.json b/plugin/style_converter/sample_data/mapcat.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/mapcat.json
rename to plugin/style_converter/sample_data/mapcat.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/more_scales.qml b/plugin/style_converter/sample_data/more_scales.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/more_scales.qml
rename to plugin/style_converter/sample_data/more_scales.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/offset_in_map_units.qml b/plugin/style_converter/sample_data/offset_in_map_units.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/offset_in_map_units.qml
rename to plugin/style_converter/sample_data/offset_in_map_units.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/osm_bright.json b/plugin/style_converter/sample_data/osm_bright.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/osm_bright.json
rename to plugin/style_converter/sample_data/osm_bright.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/outline_as_expr.qml b/plugin/style_converter/sample_data/outline_as_expr.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/outline_as_expr.qml
rename to plugin/style_converter/sample_data/outline_as_expr.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/point_layer_transparent.qml b/plugin/style_converter/sample_data/point_layer_transparent.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/point_layer_transparent.qml
rename to plugin/style_converter/sample_data/point_layer_transparent.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/point_layer_visible.qml b/plugin/style_converter/sample_data/point_layer_visible.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/point_layer_visible.qml
rename to plugin/style_converter/sample_data/point_layer_visible.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/polygon_fill_green.qml b/plugin/style_converter/sample_data/polygon_fill_green.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/polygon_fill_green.qml
rename to plugin/style_converter/sample_data/polygon_fill_green.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/polygon_fill_red.qml b/plugin/style_converter/sample_data/polygon_fill_red.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/polygon_fill_red.qml
rename to plugin/style_converter/sample_data/polygon_fill_red.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/polygon_transparent_offset.qml b/plugin/style_converter/sample_data/polygon_transparent_offset.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/polygon_transparent_offset.qml
rename to plugin/style_converter/sample_data/polygon_transparent_offset.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/polygon_two_rules.qml b/plugin/style_converter/sample_data/polygon_two_rules.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/polygon_two_rules.qml
rename to plugin/style_converter/sample_data/polygon_two_rules.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/positron.json b/plugin/style_converter/sample_data/positron.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/positron.json
rename to plugin/style_converter/sample_data/positron.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/rgba.qml b/plugin/style_converter/sample_data/rgba.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/rgba.qml
rename to plugin/style_converter/sample_data/rgba.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/roman_empire.json b/plugin/style_converter/sample_data/roman_empire.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/roman_empire.json
rename to plugin/style_converter/sample_data/roman_empire.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/size_expr.qml b/plugin/style_converter/sample_data/size_expr.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/size_expr.qml
rename to plugin/style_converter/sample_data/size_expr.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/size_fix.qml b/plugin/style_converter/sample_data/size_fix.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/size_fix.qml
rename to plugin/style_converter/sample_data/size_fix.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/sprite.json b/plugin/style_converter/sample_data/sprite.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/sprite.json
rename to plugin/style_converter/sample_data/sprite.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/sprite.png b/plugin/style_converter/sample_data/sprite.png
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/sprite.png
rename to plugin/style_converter/sample_data/sprite.png
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/sprite@2x.png b/plugin/style_converter/sample_data/sprite@2x.png
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/sprite@2x.png
rename to plugin/style_converter/sample_data/sprite@2x.png
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/symbol_level_changed.qml b/plugin/style_converter/sample_data/symbol_level_changed.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/symbol_level_changed.qml
rename to plugin/style_converter/sample_data/symbol_level_changed.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/symbol_level_unchanged.qml b/plugin/style_converter/sample_data/symbol_level_unchanged.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/symbol_level_unchanged.qml
rename to plugin/style_converter/sample_data/symbol_level_unchanged.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/symbol_with_label_and_svg.qml b/plugin/style_converter/sample_data/symbol_with_label_and_svg.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/symbol_with_label_and_svg.qml
rename to plugin/style_converter/sample_data/symbol_with_label_and_svg.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/transportation_name.qml b/plugin/style_converter/sample_data/transportation_name.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/transportation_name.qml
rename to plugin/style_converter/sample_data/transportation_name.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/transportation_name_valid.qml b/plugin/style_converter/sample_data/transportation_name_valid.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/transportation_name_valid.qml
rename to plugin/style_converter/sample_data/transportation_name_valid.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/water_name_italic.qml b/plugin/style_converter/sample_data/water_name_italic.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/water_name_italic.qml
rename to plugin/style_converter/sample_data/water_name_italic.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/water_name_regular.qml b/plugin/style_converter/sample_data/water_name_regular.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/water_name_regular.qml
rename to plugin/style_converter/sample_data/water_name_regular.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/water_pattern.qml b/plugin/style_converter/sample_data/water_pattern.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/water_pattern.qml
rename to plugin/style_converter/sample_data/water_pattern.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/width_as_expression.qml b/plugin/style_converter/sample_data/width_as_expression.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/width_as_expression.qml
rename to plugin/style_converter/sample_data/width_as_expression.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/width_as_value.qml b/plugin/style_converter/sample_data/width_as_value.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/width_as_value.qml
rename to plugin/style_converter/sample_data/width_as_value.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/with_dash.qml b/plugin/style_converter/sample_data/with_dash.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/with_dash.qml
rename to plugin/style_converter/sample_data/with_dash.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/with_filter.json b/plugin/style_converter/sample_data/with_filter.json
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/with_filter.json
rename to plugin/style_converter/sample_data/with_filter.json
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/with_rule.qml b/plugin/style_converter/sample_data/with_rule.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/with_rule.qml
rename to plugin/style_converter/sample_data/with_rule.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/with_scale_min_and_max.qml b/plugin/style_converter/sample_data/with_scale_min_and_max.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/with_scale_min_and_max.qml
rename to plugin/style_converter/sample_data/with_scale_min_and_max.qml
diff --git a/ext-libs/mapboxstyle2qgis/sample_data/with_scale_min_and_max_disabled.qml b/plugin/style_converter/sample_data/with_scale_min_and_max_disabled.qml
similarity index 100%
rename from ext-libs/mapboxstyle2qgis/sample_data/with_scale_min_and_max_disabled.qml
rename to plugin/style_converter/sample_data/with_scale_min_and_max_disabled.qml
diff --git a/plugin/ui/dialogs.py b/plugin/ui/dialogs.py
index efeb241..28f7e59 100644
--- a/plugin/ui/dialogs.py
+++ b/plugin/ui/dialogs.py
@@ -295,8 +295,8 @@ def _load_tiles_for_connection(self):
threshold = 20
if self._nr_of_tiles and self._nr_of_tiles > threshold and not self.options.tile_number_limit():
msg = (
- f"You are about to load {self._nr_of_tiles} tiles. That's a lot and may take some while. Do you "
- f"want to continue? "
+ "You are about to load {} tiles. That's a lot and may take some while."
+ " Do you want to continue?".format(self._nr_of_tiles)
)
reply = QMessageBox.question(self.activateWindow(), "Confirm Load", msg, QMessageBox.Yes, QMessageBox.No)
if reply != QMessageBox.Yes:
diff --git a/plugin/util/network_helper.py b/plugin/util/network_helper.py
index 9be0170..6e91cc0 100644
--- a/plugin/util/network_helper.py
+++ b/plugin/util/network_helper.py
@@ -10,7 +10,7 @@
def url_exists(url: str) -> Tuple[bool, Optional[str], str]:
- reply = get_async_reply(url, head_only=True)
+ reply = http_get_async(url, head_only=True)
while not reply.isFinished():
QApplication.processEvents()
@@ -39,7 +39,7 @@ def url_exists(url: str) -> Tuple[bool, Optional[str], str]:
return success, error, url
-def get_async_reply(url: str, head_only: bool = False) -> QNetworkReply:
+def http_get_async(url: str, head_only: bool = False) -> QNetworkReply:
m = QgsNetworkAccessManager.instance()
req = QNetworkRequest(QUrl(url))
if head_only:
@@ -53,7 +53,7 @@ def load_tiles_async(
urls_with_col_and_row, on_progress_changed: Callable = None, cancelling_func: Callable[[], bool] = None
) -> List:
replies: List[Tuple[QNetworkReply, Tuple[int, int]]] = [
- (get_async_reply(url), (col, row)) for url, col, row in urls_with_col_and_row
+ (http_get_async(url), (col, row)) for url, col, row in urls_with_col_and_row
]
total_nr_of_requests = len(replies)
all_finished = False
@@ -99,8 +99,8 @@ def load_tiles_async(
return all_results
-def load_url(url: str) -> Tuple[int, str]:
- reply = get_async_reply(url)
+def http_get(url: str) -> Tuple[int, str]:
+ reply = http_get_async(url)
while not reply.isFinished():
QApplication.processEvents()
diff --git a/plugin/util/tile_json.py b/plugin/util/tile_json.py
index 2c11024..f3106a6 100644
--- a/plugin/util/tile_json.py
+++ b/plugin/util/tile_json.py
@@ -4,7 +4,7 @@
from typing import List, Optional, Tuple
from .log_helper import critical, debug, info
-from .network_helper import load_url
+from .network_helper import http_get
from .tile_helper import WORLD_BOUNDS, get_tile_bounds
try:
@@ -31,7 +31,7 @@ def load(self) -> bool:
with open(self.url, "r") as f:
data = f.read()
else:
- status, data = load_url(self.url)
+ status, data = http_get(self.url)
self.json = json.loads(data)
if self.json:
debug("TileJSON loaded")
@@ -127,7 +127,7 @@ def max_zoom(self) -> Optional[int]:
def _get_value(self, field_name: str, is_array: bool = False, is_required: bool = False):
if not self.json or (is_required and field_name not in self.json):
- raise RuntimeError(f"The field '{field_name}' is required but not found. This is invalid TileJSON.")
+ raise RuntimeError("The field '{}' is required but not found. This is invalid TileJSON.".format(field_name))
result = None
if field_name in self.json:
@@ -137,7 +137,7 @@ def _get_value(self, field_name: str, is_array: bool = False, is_required: bool
result.extend(result_arr)
if is_required and len(result) == 0:
raise RuntimeError(
- f"The field '{field_name}' is required but is empty. At least one entry is expected."
+ "The field '{}' is required but is empty. At least one entry is expected.".format(field_name)
)
else:
result = self.json[field_name]
diff --git a/plugin/vt_reader.py b/plugin/vt_reader.py
index 2332d16..1fb1886 100644
--- a/plugin/vt_reader.py
+++ b/plugin/vt_reader.py
@@ -524,7 +524,7 @@ def _create_qgis_layers(self, merge_features, apply_styles, clip_tiles):
l.setCustomProperty("VectorTilesReader/is_empty", False)
nr_layers = len(self.feature_collections_by_layer_name_and_geotype)
- self._update_progress(progress=0, max_progress=nr_layers, msg=f"Creating {nr_layers} layers...")
+ self._update_progress(progress=0, max_progress=nr_layers, msg="Creating {} layers...".format(nr_layers))
layer_filter = self._loading_options["layer_filter"]
clipping_bounds = None
@@ -594,9 +594,9 @@ def _create_qgis_layers(self, merge_features, apply_styles, clip_tiles):
if len(new_layers) > 0 and not self.cancel_requested:
self._update_progress(msg="Adding new layers...")
only_layers = list([layer_name_tuple[2] for layer_name_tuple in new_layers])
- info(f"Adding {len(only_layers)} layers to QGIS...")
+ info("Adding {} layers to QGIS...", len(only_layers))
QgsProject.instance().addMapLayers(only_layers, False)
- info(f"Adding {len(new_layers)} new layers to layer group...")
+ info("Adding {} new layers to layer group...", len(new_layers))
for name, geo_type, layer in new_layers:
if self.cancel_requested:
break
@@ -607,7 +607,7 @@ def _create_qgis_layers(self, merge_features, apply_styles, clip_tiles):
conn_name = self.connection()["name"]
styles_folder = get_style_folder(conn_name)
styles = get_styles(conn_name)
- info(f"Applying styles to {len(new_layers)} layers...")
+ info("Applying styles to {} layers...", len(new_layers))
self._update_progress(progress=0, max_progress=len(new_layers), msg="Styling layers...")
for name, geo_type, layer in new_layers:
count += 1
diff --git a/plugin/vtr_plugin.py b/plugin/vtr_plugin.py
index 3f7fffc..8d0addd 100644
--- a/plugin/vtr_plugin.py
+++ b/plugin/vtr_plugin.py
@@ -22,17 +22,17 @@
import traceback
from typing import List, Optional, Tuple
-from mapboxstyle2qgis import core
from PyQt5.QtCore import QObject, QSettings, Qt, QTimer, pyqtSignal
from PyQt5.QtGui import QColor, QIcon
from PyQt5.QtWidgets import QAction, QMenu, QMessageBox, QProgressBar, QPushButton, QToolButton
from qgis.core import QgsApplication, QgsCoordinateReferenceSystem, QgsMapLayer, QgsPointXY, QgsProject, QgsRectangle
from qgis.gui import QgsMessageBarItem
+from .style_converter import core
from .ui.dialogs import AboutDialog, ConnectionsDialog, OptionsGroup
from .util.file_helper import clear_cache, get_icons_directory, get_plugin_directory, get_temp_dir
from .util.log_helper import critical, debug, info
-from .util.network_helper import load_url, url_exists
+from .util.network_helper import http_get, url_exists
from .util.qgis_helper import get_loaded_layers_of_connection
from .util.tile_helper import (
WORLD_BOUNDS,
@@ -101,7 +101,7 @@ def __init__(self, iface, version: Optional[str] = None):
iface.projectRead.connect(self._on_project_change)
QgsProject.instance().layersWillBeRemoved.connect(self._on_remove)
python_version = platform.python_version()
- plugin_version = f" {version}" if version else ""
+ plugin_version = " {}".format(version) if version else ""
info("Vector Tiles Reader{} (Python {})".format(plugin_version, python_version))
self.settings = QSettings("Vector Tile Reader", "vectortilereader")
self._clear_cache_when_version_changed()
@@ -433,12 +433,12 @@ def _create_styles(self, connection: dict):
info("StyleJSON not found. URL invalid? {}", error)
else:
output_directory = get_temp_dir(os.path.join("styles", connection["name"]))
- status, data = load_url(url)
+ status, data = http_get(url)
if status == 200:
try:
core.register_qgis_expressions()
info("Styles will be written to: {}", output_directory)
- core.generate_styles(data, output_directory, web_request_executor=self._load_style_data)
+ core.generate_styles(data, output_directory)
except:
tb = ""
if traceback:
@@ -457,11 +457,6 @@ def _create_styles(self, connection: dict):
else:
info("Loading StyleJSON failed: HTTP status {}", status)
- @staticmethod
- def _load_style_data(url):
- status, data = load_url(url)
- return data
-
def reader_cancelled(self):
info("Loading cancelled")
self._is_loading = False
@@ -488,7 +483,7 @@ def reader_limit_exceeded_message(self, limit: int):
"""
if limit:
self.iface.messageBar().pushWarning(
- "", f"Only {limit} tiles were loaded according to the limit in the options"
+ "", "Only {} tiles were loaded according to the limit in the options".format(limit)
)
def _has_extent_changed(self) -> Tuple[bool, Bounds]:
@@ -660,7 +655,7 @@ def _get_visible_extent_as_tile_bounds(self, zoom: int):
source_crs = self._get_qgis_crs()
if self.connections_dialog.options.ignore_crs_from_metadata():
if source_crs != 3857:
- info(f"Using EPSG:3857 for tile calculation instead of EPSG:{source_crs}")
+ info("Using EPSG:3857 for tile calculation instead of EPSG:{}".format(source_crs))
source_crs = 3857
# the tile bounds returned here must have the same scheme as the source, otherwise thing's get pretty irritating
diff --git a/setup.cfg b/setup.cfg
index e850f65..ec28e7e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -19,7 +19,8 @@ exclude =
ext-libs,
.mypy_cache,
global_map_tiles.py,
- plugin/ui/qt
+ plugin/ui/qt,
+ tests/style_converter_tests
ignore = E722, # do not use bare 'except'
W291, # trailing whitespace,
W503, # line break before binary operator
diff --git a/tests/style_converter_tests/test_filters.py b/tests/style_converter_tests/test_filters.py
new file mode 100644
index 0000000..42111c1
--- /dev/null
+++ b/tests/style_converter_tests/test_filters.py
@@ -0,0 +1,92 @@
+import os
+import sys
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+from qgis.testing import unittest
+
+from plugin.style_converter.core import get_qgis_rule
+
+
+class StyleConverterFilterTests(unittest.TestCase):
+
+ # region comparision filters
+
+ def test_qgis_attribute(self):
+ rule = get_qgis_rule(["<=", "@map_scale", "20000"], escape_result=False)
+ self.assertEqual("@map_scale is not null and @map_scale <= '20000'", rule)
+
+ def test_eq_filter(self):
+ rule = get_qgis_rule(["==", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is not null and \"class\" = 'address'", rule)
+
+ def test_type_comparision(self):
+ rule = get_qgis_rule(["==", "$type", "Polygon"], escape_result=False)
+ self.assertIsNone(rule)
+
+ def test_neq_filter(self):
+ rule = get_qgis_rule(["!=", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is null or \"class\" != 'address'", rule)
+
+ def test_leq_filter(self):
+ rule = get_qgis_rule(["<=", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is not null and \"class\" <= 'address'", rule)
+
+ def test_eqgt_filter(self):
+ rule = get_qgis_rule([">=", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is not null and \"class\" >= 'address'", rule)
+
+ def test_gt_filter(self):
+ rule = get_qgis_rule([">", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is not null and \"class\" > 'address'", rule)
+
+ def test_lt_filter(self):
+ rule = get_qgis_rule(["<", "class", "address"], escape_result=False)
+ self.assertEqual("\"class\" is not null and \"class\" < 'address'", rule)
+
+ # endregion
+
+ # region membership filters
+
+ def test_membership_in(self):
+ expr = get_qgis_rule(["in", "class", "city", "cafe", "poi"], escape_result=False)
+ self.assertEqual("(\"class\" is not null and \"class\" in ('city', 'cafe', 'poi'))", expr)
+
+ def test_membership_not_in(self):
+ expr = get_qgis_rule(["!in", "class", "city", "cafe", "poi"], escape_result=False)
+ self.assertEqual("(\"class\" is null or \"class\" not in ('city', 'cafe', 'poi'))", expr)
+ # endregion
+
+ # region existential filters
+
+ def test_has(self):
+ expr = get_qgis_rule(["has", "name"], escape_result=False)
+ self.assertEqual("attribute($currentfeature, 'name') is not null", expr)
+
+ def test_has_not(self):
+ expr = get_qgis_rule(["!has", "name"], escape_result=False)
+ self.assertEqual("attribute($currentfeature, 'name') is null", expr)
+
+ # endregion
+
+ # region combining filters
+ def test_all(self):
+ f1 = ["==", "class", "address"]
+ f2 = ["!=", "name", "hello world"]
+ f3 = [">=", "height", "123"]
+ rule = get_qgis_rule(["all", f1, f2, f3], escape_result=False)
+ expected = """("class" is not null and "class" = 'address') and ("name" is null or "name" != 'hello world') and ("height" is not null and "height" >= '123')"""
+ self.assertEqual(expected, rule)
+
+ def test_any(self):
+ f1 = ["==", "class", "address"]
+ f2 = ["!=", "name", "hello world"]
+ rule = get_qgis_rule(["any", f1, f2], escape_result=False)
+ expected = """"class" is not null and "class" = \'address\' or "name" is null or "name" != \'hello world\'"""
+ self.assertEqual(expected, rule)
+
+ def test_none(self):
+ f1 = ["==", "class", "address"]
+ f2 = ["!=", "name", "hello world"]
+ rule = get_qgis_rule(["none", f1, f2], escape_result=False)
+ expected = """not "class" is not null and "class" = \'address\' and not "name" is null or "name" != \'hello world\'"""
+ self.assertEqual(expected, rule)
+ # endregion
diff --git a/tests/style_converter_tests/test_helper.py b/tests/style_converter_tests/test_helper.py
new file mode 100644
index 0000000..bb511a3
--- /dev/null
+++ b/tests/style_converter_tests/test_helper.py
@@ -0,0 +1,314 @@
+from plugin.style_converter.core import get_styles, parse_color, get_qgis_rule, get_background_color, xml_helper, _get_match_expr
+from qgis.testing import unittest
+
+
+class StyleConverterHelperTests(unittest.TestCase):
+
+ def test_parse_rgb(self):
+ rgba = parse_color("rgb(1,2,3)")
+ self.assertEqual("1,2,3,255", rgba)
+
+ def test_parse_rgba(self):
+ rgba = parse_color("rgba(1, 2, 3, 0.5)")
+ self.assertEqual("1,2,3,128", rgba)
+
+ def test_parse_hsl(self):
+ rgba = parse_color("hsl(28, 76%, 67%)")
+ self.assertEqual("235,167,107,255", rgba)
+
+ def test_parse_hsla(self):
+ rgba = parse_color("hsla(28, 76%, 67%, 0.5)")
+ self.assertEqual("235,167,107,128", rgba)
+
+ def test_parse_color_match(self):
+ rgba = parse_color([
+ "match",
+ [
+ "get",
+ "type"
+ ],
+ "Air Transport",
+ "#e6e6e6",
+ "Education",
+ "#f7eaca",
+ "hsla(28, 76%, 67%, 0.5)"
+ ])
+ expected = """if ("type" is not null and "type" = 'Air Transport', '#e6e6e6', if ("type" is not null and "type" = 'Education', '#f7eaca', '235,167,107,128'))"""
+ self.assertEqual(expected, rgba)
+
+ def test_parse_hex_alpha(self):
+ rgba = parse_color("#ffff0c32")
+ self.assertEqual("255,255,12,50", rgba)
+
+ def test_parse_hex(self):
+ rgba = parse_color("#ffff0c")
+ self.assertEqual("#ffff0c", rgba)
+
+ def test_parse_short_hex(self):
+ rgba = parse_color("#abc")
+ self.assertEqual("170,187,204", rgba)
+
+ def test_line_dasharray(self):
+ style = _get_line_layer({
+ "line-color": "#cba",
+ "line-dasharray": [
+ 1.5,
+ 0.75
+ ],
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 15,
+ 1.2
+ ],
+ [
+ 20,
+ 4
+ ]
+ ]
+ }
+ })
+ styles = get_styles(style)
+ self.assertTrue(True)
+
+ def test_line_dasharray_multiple(self):
+ layer = _get_line_layer({
+ "id": "test",
+ "line-dasharray": [
+ 5,
+ 6,
+ 10,
+ 11
+ ]
+ })
+ styles = get_styles(layer)
+ d = xml_helper._get_line_symbol(0, styles[0])
+ self.assertTrue(True)
+
+ def test_line_cap(self):
+ style = {
+ "id": None,
+ "type": "line",
+ "layout": {
+ "line-cap": "round",
+ "line-join": "square"
+ }
+ }
+ styles = get_styles(style)
+ self.assertEqual(1, len(styles))
+ self.assertEqual("square", styles[0]["line-join"])
+ self.assertEqual("round", styles[0]["line-cap"])
+
+ def test_stops(self):
+ style = _get_line_layer({
+ "line-color": "#9e9cab",
+ "line-dasharray": [3, 1, 1, 1],
+ "line-width": {
+ "base": 1.4,
+ "stops": [[4, 0.4], [5, 1], [12, 3]]}
+ })
+ styles = get_styles(style)
+ self.assertTrue(True)
+
+ def test_zoom_level_zero(self):
+ style = _get_fill_style({
+ "fill-opacity": {
+ "base": 1,
+ "stops": [[0, 0.9], [10, 0.3]]
+ }
+ })
+ styles = get_styles(style)
+ self.assertEqual(2, len(styles))
+ expected = {
+ 'zoom_level': 0,
+ 'max_scale_denom': 1000000000,
+ 'min_scale_denom': 750000,
+ 'fill-color': '0,0,0,0',
+ 'fill-opacity': 0.9
+ }
+ self.assertDictEqual(expected, styles[0])
+
+ def test_get_styles_float(self):
+ style = _get_fill_style({
+ "fill-opacity": 0.7,
+ "fill-color": "#f2eae2",
+ })
+ styles = get_styles(style)
+ expected = {
+ "fill-color": "#f2eae2",
+ "fill-opacity": 0.7,
+ "zoom_level": None,
+ "min_scale_denom": None,
+ "max_scale_denom": None
+ }
+ self.assertDictEqual(expected, styles[0])
+
+ def test_get_background_color(self):
+ layer = """{"layers": [{
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#f8f4f0"
+ }
+ }]}"""
+ color = get_background_color(layer)
+ self.assertEqual("#f8f4f0", color)
+
+ def test_get_styles_simple(self):
+ style = _get_fill_style({
+ "fill-outline-color": "#dfdbd7",
+ "fill-color": "#f2eae2",
+ })
+ styles = get_styles(style)
+ self.assertEqual(1, len(styles))
+ expected = {
+ "fill-outline-color": "#dfdbd7",
+ "fill-color": "#f2eae2",
+ "zoom_level": None,
+ "min_scale_denom": None,
+ "max_scale_denom": None
+ }
+ self.assertDictEqual(expected, styles[0])
+
+ def test_highway_motorway(self):
+ style = _get_line_layer({
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ })
+ result = get_styles(style)
+ self.assertEqual(2, len(result))
+
+ def test_scale(self):
+ style = _get_line_layer({
+ "line-width": {
+ "stops": [
+ [
+ 10,
+ 0
+ ],
+ [
+ 15,
+ 1
+ ]
+ ]
+ }
+ })
+ styles = get_styles(style)
+ self.assertEqual(1, len(styles))
+ self.assertEqual(10, styles[0]["zoom_level"])
+
+ def test_get_styles(self):
+ style = _get_fill_style({
+ "fill-outline-color": "#dfdbd7",
+ "fill-color": "#f2eae2",
+ "fill-opacity": {
+ "base": 1,
+ "stops": [
+ [
+ 13,
+ 0
+ ],
+ [
+ 16,
+ 1
+ ]
+ ]
+ }
+ })
+ styles = get_styles(style)
+ styles = sorted(styles, key=lambda s: s["zoom_level"])
+ self.assertEqual(2, len(styles))
+ first_expected = {
+ 'fill-outline-color': '#dfdbd7',
+ 'fill-color': '#f2eae2',
+ 'zoom_level': 13,
+ 'fill-opacity': 0,
+ 'max_scale_denom': 100000,
+ 'min_scale_denom': 12500
+ }
+ second_expected = {
+ 'fill-outline-color': '#dfdbd7',
+ 'fill-color': '#f2eae2',
+ 'zoom_level': 16,
+ 'fill-opacity': 1,
+ 'max_scale_denom': 12500,
+ 'min_scale_denom': 1
+ }
+ self.assertDictEqual(first_expected, styles[0])
+ self.assertDictEqual(second_expected, styles[1])
+
+ def test_filter_depth(self):
+ highway_primary_casing = get_qgis_rule(_highway_primary_casing, escape_result=False)
+ highway_primary = get_qgis_rule(_highway_primary, escape_result=False)
+ self.assertEqual(highway_primary, highway_primary_casing)
+
+
+_highway_primary_casing = [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary"
+ ]
+]
+
+_highway_primary = [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary"
+ ]
+ ]
+]
+
+
+def _get_fill_style(paint):
+ return {
+ "id": None,
+ "type": "fill",
+ "paint": paint
+ }
+
+
+def _get_line_layer(paint):
+ return {
+ "id": None,
+ "type": "line",
+ "paint": paint
+ }
diff --git a/tests/style_converter_tests/test_parser.py b/tests/style_converter_tests/test_parser.py
new file mode 100644
index 0000000..eac5994
--- /dev/null
+++ b/tests/style_converter_tests/test_parser.py
@@ -0,0 +1,60 @@
+import os
+import sys
+from qgis.testing import unittest
+import shutil
+import json
+import base64
+from xml.sax.saxutils import unescape
+from plugin.util.file_helper import get_plugin_directory, get_temp_dir
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+
+from plugin.style_converter.core import _create_icons, generate_styles, process
+
+
+class StyleConverterParserTests(unittest.TestCase):
+ sample_data_dir = os.path.join(get_plugin_directory(), "plugin", "style_converter", "sample_data")
+
+ def test_icon_creation(self):
+
+ image_data = self._load_file(os.path.join(self.sample_data_dir, "sprite.png"), binary=True)
+ image_data = base64.b64encode(image_data)
+ image_definition_data = self._load_file(os.path.join(self.sample_data_dir, "sprite.json"))
+ image_definition_data = json.loads(str(image_definition_data))
+ output_directory = get_temp_dir(os.path.join("style_converter_tests", "generated"))
+ _create_icons(image_data, image_definition_data, output_directory=output_directory)
+
+ def test_generate_local(self):
+ # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "roman_empire.json")
+ # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "osm_bright.json")
+ # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_terrain.json")
+ # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "klokantech_basic.json")
+ # path = os.path.join(os.path.dirname(__file__), "..", "sample_data", "positron.json")
+ path = os.path.join(self.sample_data_dir, "mapcat.json")
+ data = self._load_file(path)
+ data = json.loads(data)
+ output_directory = get_temp_dir(os.path.join("style_converter_tests", "generated"))
+ if os.path.isdir(output_directory):
+ shutil.rmtree(output_directory)
+ styles = process(data)
+ generate_styles(data, output_directory)
+ self.assertTrue(True)
+
+ def test_filter(self):
+ path = os.path.join(self.sample_data_dir, "with_filter.json")
+ data = self._load_file(path)
+ style_obj = process(data)
+ styles = style_obj["landuse_overlay.polygon.qml"]["styles"]
+ self.assertEqual(len(styles), 1)
+ self.assertIn("rule", styles[0])
+ res = unescape(styles[0]["rule"], entities={""": '"'})
+ expected = "\"class\" is not null and \"class\" = \'national_park\'"
+ self.assertEqual(expected, res)
+
+ @staticmethod
+ def _load_file(path, binary=False):
+ mode = 'r'
+ if binary:
+ mode = 'rb'
+ with open(path, mode) as f:
+ data = f.read()
+ return data
diff --git a/tests/test_all.py b/tests/test_all.py
index 6542f4e..87ecc62 100644
--- a/tests/test_all.py
+++ b/tests/test_all.py
@@ -19,6 +19,10 @@ def get_tests():
from tests.test_tilejson import TileJsonTests
from tests.test_networkhelper import NetworkHelperTests
+ from tests.style_converter_tests.test_filters import StyleConverterFilterTests
+ from tests.style_converter_tests.test_helper import StyleConverterHelperTests
+ from tests.style_converter_tests.test_parser import StyleConverterParserTests
+
tests = [
unittest.TestLoader().loadTestsFromTestCase(VtrPluginTests),
unittest.TestLoader().loadTestsFromTestCase(MbtileSourceTests),
@@ -28,6 +32,9 @@ def get_tests():
unittest.TestLoader().loadTestsFromTestCase(TileJsonTests),
unittest.TestLoader().loadTestsFromTestCase(NetworkHelperTests),
unittest.TestLoader().loadTestsFromTestCase(VtReaderTests),
+ unittest.TestLoader().loadTestsFromTestCase(StyleConverterFilterTests),
+ unittest.TestLoader().loadTestsFromTestCase(StyleConverterHelperTests),
+ unittest.TestLoader().loadTestsFromTestCase(StyleConverterParserTests),
]
return tests
@@ -41,6 +48,7 @@ def run_all():
"*global_map_tiles*",
"/tests_directory/tests/*",
"/tests_directory/ext-libs/*",
+ "/tests_directory/plugin/ui/qt/*",
# "/tests_directory/vtr_plugin.py", # todo: remove from here when tests exist
]
)