Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #3

Merged
merged 4 commits into from
Dec 6, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/test_plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Tests for Plugin LandXML to Mesh

on:
push:
paths:
- "landxmlconvertor/**"
- ".github/workflows/test_plugin.yaml"
- "tests/**"

jobs:

Tests-plugin-LandXML-to-Mesh:

runs-on: ubuntu-latest

steps:

- name: Install QGIS
run: |
sudo wget -qO /etc/apt/keyrings/qgis-archive-keyring.gpg https://download.qgis.org/downloads/qgis-archive-keyring.gpg
sudo sh -c 'echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/qgis-archive-keyring.gpg] https://qgis.org/ubuntu `lsb_release -c -s` main" > /etc/apt/sources.list.d/qgis.list'
sudo apt-get update
sudo apt-get install -y qgis

- name: Install Python packages
run: pip install pytest pytest-qgis

- name: Set PYTHONPATH
run: |
echo "PYTHONPATH=/usr/share/qgis/python/plugins:/usr/share/qgis/python:." >> $GITHUB_ENV

- name: Checkout
uses: actions/checkout@v4

- name: Run Tests
run: |
QT_QPA_PLATFORM=offscreen pytest tests -rP -vv -s
2 changes: 1 addition & 1 deletion landxmlconvertor/metadata.txt
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
name=LandXML to Mesh
description=Conversion of LandXML to Mesh and vice versa
about=Conversion of LandXML to Mesh and vice versa
version=0.1.1
version=0.2.0
qgisMinimumVersion=3.32
qgisMaximumVersion=3.99
author=Lutra Consulting
20 changes: 20 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from pathlib import Path

import pytest


@pytest.fixture
def test_data_folder() -> Path:
return Path(__file__).parent / "data"


@pytest.fixture
def test_data_clean(test_data_folder: Path) -> str:
file_path = test_data_folder / "Example_Clean.xml"
return file_path.as_posix()


@pytest.fixture
def test_data_mesh2dm(test_data_folder: Path) -> str:
file_path = test_data_folder / "mesh.2dm"
return file_path.as_posix()
9,959 changes: 9,959 additions & 0 deletions tests/data/3D_modell_underlag_skyfall_20230915.xml

Large diffs are not rendered by default.

627 changes: 627 additions & 0 deletions tests/data/Example_Clean.2dm

Large diffs are not rendered by default.

724 changes: 724 additions & 0 deletions tests/data/Example_Clean.xml

Large diffs are not rendered by default.

724 changes: 724 additions & 0 deletions tests/data/Example_Clean_without_schema.xml

Large diffs are not rendered by default.

66,385 changes: 66,385 additions & 0 deletions tests/data/Total topp.xml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions tests/data/just_xml.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0"?>
<SomeXMLTag >
</SomeXMLTag>
14 changes: 14 additions & 0 deletions tests/data/land_xml_empty_surface.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<LandXML xmlns="http://www.landxml.org/schema/LandXML-1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.landxml.org/schema/LandXML-1.2 http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd" date="2023-05-16" time="09:38:53" version="1.2" language="English" readOnly="false">
<Units>
<Metric areaUnit="squareMeter" linearUnit="meter" volumeUnit="cubicMeter" temperatureUnit="celsius" pressureUnit="milliBars" diameterUnit="millimeter" angularUnit="decimal degrees" directionUnit="decimal degrees"></Metric>
</Units>
<Project name=""></Project>
<Application name="Autodesk Civil 3D" desc="Civil 3D" manufacturer="Autodesk, Inc." version="2023" manufacturerURL="www.autodesk.com/civil" timeStamp=""></Application>
<Surfaces>
<Surface name="A">
<Definition>
</Definition>
</Surface>
</Surfaces>
</LandXML>
10 changes: 10 additions & 0 deletions tests/data/land_xml_no_surface.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<LandXML xmlns="http://www.landxml.org/schema/LandXML-1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.landxml.org/schema/LandXML-1.2 http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd" date="2023-05-16" time="09:38:53" version="1.2" language="English" readOnly="false">
<Units>
<Metric areaUnit="squareMeter" linearUnit="meter" volumeUnit="cubicMeter" temperatureUnit="celsius" pressureUnit="milliBars" diameterUnit="millimeter" angularUnit="decimal degrees" directionUnit="decimal degrees"></Metric>
</Units>
<Project name=""></Project>
<Application name="QGIS" desc="QGIS `LandXML to Mesh` plugin" manufacturer="Lutra Consulting" version="0.1.0" manufacturerURL="https://github.com/lutraconsulting/qgis-landxml-mesh-plugin" timeStamp=""/>
<Surfaces>
</Surfaces>
</LandXML>
10 changes: 10 additions & 0 deletions tests/data/land_xml_with_unsupported_schema.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<LandXML xmlns="http://www.landxml.org/schema/LandXML-99.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Units>
<Metric areaUnit="squareMeter" linearUnit="meter" volumeUnit="cubicMeter" temperatureUnit="celsius" pressureUnit="milliBars" diameterUnit="millimeter" angularUnit="decimal degrees" directionUnit="decimal degrees"></Metric>
</Units>
<Project name=""></Project>
<Application name="QGIS" desc="QGIS `LandXML to Mesh` plugin" manufacturer="Lutra Consulting" version="0.1.0" manufacturerURL="https://github.com/lutraconsulting/qgis-landxml-mesh-plugin" timeStamp=""/>
<Surfaces>
</Surfaces>
</LandXML>
75 changes: 75 additions & 0 deletions tests/data/mesh.2dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
MESH2D
ND 5 148078.62759250728 6399036.784479916 1.850000000093
ND 6 148082.98675852036 6399039.233494343 1.850000000093
ND 7 148087.34592453344 6399041.68250877 1.850000000093
ND 8 148080.09700116375 6399034.168980308 1.850000000093
ND 9 148084.6615133332 6399035.901646255 1.85
ND 10 148089.34240795532 6399037.678490397 1.85
ND 11 148108.66143864905 6399027.491507318 2.511953982525
ND 12 148107.3593426412 6399031.153952006 2.580000000075
ND 13 148101.69546136074 6399037.705265975 2.75
ND 14 148102.24323948892 6399021.4273085 2.450000000186
ND 15 148102.15698069707 6399021.674960053 2.529999999795
ND 16 148099.77542688 6399028.512471762 2.493798009586
ND 17 148086.07886701403 6399031.888634816 2.42326535238
ND 18 148089.73754173145 6399021.018820815 2.580000000075
ND 19 148088.58912520623 6399024.430732224 2.544000000227
ND 20 148080.2600100306 6399017.828774912 2.550399773289
ND 21 148079.1115935077 6399021.240686318 2.622399772983
ND 22 148076.63240992418 6399028.606267165 2.70011600852
ND 23 148101.62448603753 6399037.681346759 2.748598864302
ND 24 148092.07103784243 6399047.263363678 2.748598864302
ND 25 148085.87651587697 6399044.298008379 2.75
ND 26 148077.1581838508 6399039.399979524 2.75
ND 27 148081.5173498639 6399041.848993951 2.75
ND 28 148066.23753649136 6399031.979676245 2.75
ND 29 148067.18595283432 6399025.323899515 2.744212705642
ND 30 148091.67197512323 6399040.193289291 1.85
ND 31 148091.00243782345 6399041.895371813 1.85
ND 32 148077.7835475076 6399034.941537967 1.850000000093
ND 33 148078.22726177424 6399034.141317513 1.850000000093
E3T 1 32 5 26 1
E3T 2 26 5 6 1
E3T 3 8 6 5 1
E3T 4 32 8 5 1
E3T 5 27 6 7 1
E3T 6 9 7 6 1
E3T 7 9 6 8 1
E3T 8 27 26 6 1
E3T 9 7 24 25 1
E3T 10 7 31 24 1
E3T 11 31 7 30 1
E3T 12 30 7 10 1
E3T 13 10 7 9 1
E3T 14 27 7 25 1
E3T 15 33 22 8 1
E3T 16 33 8 32 1
E3T 17 17 9 8 1
E3T 18 22 17 8 1
E3T 19 17 10 9 1
E3T 20 30 10 23 1
E3T 21 23 10 17 1
E3T 22 16 11 12 1
E3T 23 15 14 11 1
E3T 24 16 15 11 1
E3T 25 23 12 13 1
E3T 26 23 16 12 1
E3T 27 24 23 13 1
E3T 28 20 14 18 1
E3T 29 18 14 15 1
E3T 30 18 15 16 1
E3T 31 23 17 16 1
E3T 32 19 18 16 1
E3T 33 19 16 17 1
E3T 34 22 19 17 1
E3T 35 21 18 19 1
E3T 36 21 20 18 1
E3T 37 22 21 19 1
E3T 38 29 20 21 1
E3T 39 29 21 22 1
E3T 40 29 22 28 1
E3T 41 32 28 22 1
E3T 42 33 32 22 1
E3T 43 30 23 24 1
E3T 44 31 30 24 1
E3T 45 32 26 28 1
18 changes: 18 additions & 0 deletions tests/test_2dm_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from landxmlconvertor.classes.mesh2dm_reader import Mesh2DMReader
from landxmlconvertor.classes.mesh_elements import MeshFace, MeshVertex


def test_read(test_data_mesh2dm):
mesh_2d = Mesh2DMReader(test_data_mesh2dm)

assert isinstance(mesh_2d, Mesh2DMReader)
assert all([isinstance(x, MeshVertex) for x in mesh_2d.points])
assert all([isinstance(x, MeshFace) for x in mesh_2d.faces])

assert all([isinstance(x.id, int) for x in mesh_2d.points])
assert all([isinstance(x.x, float) for x in mesh_2d.points])
assert all([isinstance(x.y, float) for x in mesh_2d.points])
assert all([isinstance(x.z, float) for x in mesh_2d.points])

assert all([isinstance(x.id, int) for x in mesh_2d.faces])
assert all([all([isinstance(y, int) for y in x.points_ids]) for x in mesh_2d.faces])
55 changes: 55 additions & 0 deletions tests/test_conversions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import tempfile
from pathlib import Path

import pytest
from qgis.core import QgsCoordinateReferenceSystem, QgsMeshLayer

from landxmlconvertor.classes.landxml_reader import LandXMLReader
from landxmlconvertor.classes.landxml_writer import LandXMLWriter
from landxmlconvertor.classes.mesh2dm_writer import Mesh2DMWriter


@pytest.mark.parametrize(
"filename",
[
("Example_Clean.xml"),
("Example_Clean_without_schema.xml"),
],
)
def test_landxml_to_2dm(test_data_folder, filename):
current_filename = test_data_folder / filename

land_xml = LandXMLReader(current_filename.as_posix())

mesh_2dm_writer = Mesh2DMWriter(land_xml.all_points, land_xml.all_faces)

with tempfile.TemporaryDirectory() as tmpdir:
tmp_2dm_file = Path(tmpdir) / "file.2dm"

mesh_2dm_writer.write(tmp_2dm_file.as_posix())

mesh = QgsMeshLayer(tmp_2dm_file.as_posix(), "layer", "mdal")

assert mesh.dataProvider().vertexCount() == 264
assert mesh.dataProvider().faceCount() == 362


def test_2dm_to_landxml(test_data_folder):
current_filename = test_data_folder / "mesh.2dm"

mesh_2dm = QgsMeshLayer(current_filename.as_posix(), "layer", "mdal")

with tempfile.TemporaryDirectory() as tmpdir:
tmp_landxml_file = Path(tmpdir) / "file.xml"

landxml_writer = LandXMLWriter()
landxml_writer.add_surface(mesh_2dm)
landxml_writer.write(tmp_landxml_file.as_posix())

landxml_reader = LandXMLReader(tmp_landxml_file.as_posix())

assert landxml_reader.namespace_prefix == "LandXML-1.2:"
assert landxml_reader.crs() == QgsCoordinateReferenceSystem()
assert landxml_reader.surface_count == 1
assert len(landxml_reader.all_faces) == 45
assert len(landxml_reader.all_points) == 29
105 changes: 105 additions & 0 deletions tests/test_landxml_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import xml.etree.ElementTree as ET

import pytest
from qgis.core import QgsCoordinateReferenceSystem

from landxmlconvertor.classes.landxml_elements import LandXMLSurface
from landxmlconvertor.classes.landxml_reader import LandXMLReader
from landxmlconvertor.classes.mesh_elements import MeshFace, MeshVertex


@pytest.mark.parametrize(
"filename",
[
("Example_Clean.xml"),
("Example_Clean_without_schema.xml"),
],
)
def test_clean_data(test_data_folder, filename):
current_filename = test_data_folder / filename

land_xml = LandXMLReader(current_filename.as_posix())

assert land_xml.path == current_filename.as_posix()
assert isinstance(land_xml.xml_tree, ET.ElementTree)

assert isinstance(land_xml.xml_root, ET.Element)
assert "LandXML" in land_xml.xml_root.tag

assert land_xml.crs() == QgsCoordinateReferenceSystem()

assert land_xml.surface_count == 3

assert all([isinstance(x, LandXMLSurface) for x in land_xml.surfaces])

assert len(land_xml.get_surface_points(0)) == 29
assert len(land_xml.get_surface_faces(0)) == 45

assert len(land_xml.get_surface_points(1)) == 92
assert len(land_xml.get_surface_faces(1)) == 138

assert len(land_xml.get_surface_points(2)) == 143
assert len(land_xml.get_surface_faces(2)) == 179

assert all([isinstance(x, MeshVertex) for x in land_xml.get_surface_points(0)])
assert all([isinstance(x, MeshFace) for x in land_xml.get_surface_faces(0)])

assert len(land_xml.all_points) == 29 + 92 + 143
assert len(land_xml.all_faces) == 45 + 138 + 179


def test_non_existing_file():
with pytest.raises(FileNotFoundError, match="No such file"):
LandXMLReader("file_that_does_not_exist.xml")


def test_non_LandXML_file(test_data_folder):
filename = test_data_folder / "just_xml.xml"
with pytest.raises(ValueError, match="Not a valid LandXML file"):
LandXMLReader(filename.as_posix())


def test_LandXML_without_surface_1(test_data_folder):
filename = test_data_folder / "land_xml_no_surface.xml"

land_xml = LandXMLReader(filename.as_posix())

assert land_xml.surface_count == 0


def test_LandXML_without_surface_2(test_data_folder):
filename = test_data_folder / "land_xml_empty_surface.xml"

land_xml = LandXMLReader(filename.as_posix())

assert land_xml.surface_count == 1
assert land_xml.surfaces[0].empty()


def test_LandXML_unsupported_schema(test_data_folder):
filename = test_data_folder / "land_xml_with_unsupported_schema.xml"

with pytest.raises(ValueError, match="Unsupported namespace: "):
LandXMLReader(filename.as_posix())


def test_data_1(test_data_folder):
filename = test_data_folder / "Total topp.xml"

landxml_reader = LandXMLReader(filename.as_posix())

assert landxml_reader.crs() == QgsCoordinateReferenceSystem()
assert landxml_reader.surface_count == 1
assert len(landxml_reader.all_faces) == 36093
assert len(landxml_reader.all_points) == 22273


def test_data_2(test_data_folder):
filename = test_data_folder / "3D_modell_underlag_skyfall_20230915.xml"

landxml_reader = LandXMLReader(filename.as_posix())

assert landxml_reader.crs() == QgsCoordinateReferenceSystem("EPSG:3007")
assert landxml_reader.surface_count == 1
assert len(landxml_reader.all_faces) == 6448
assert len(landxml_reader.all_points) == 3330