[Git][debian-gis-team/totalopenstation][upstream] New upstream version 0.7.2
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Fri Jan 2 15:24:59 GMT 2026
Bas Couwenberg pushed to branch upstream at Debian GIS Project / totalopenstation
Commits:
3b8fcb2e by Bas Couwenberg at 2026-01-02T15:57:15+01:00
New upstream version 0.7.2
- - - - -
24 changed files:
- .github/workflows/pyinstaller.yml
- .github/workflows/pytest.yml
- − .travis.yml
- − doc_requirements.txt
- docs/conf.py
- docs/contributing/main.rst
- docs/output_formats/of_implemented.rst
- docs/requirements.txt
- locale/totalopenstation.pot
- + pyproject.toml
- + sample_data/leica_gsi/RILIEVO.gsi
- − setup.py
- totalopenstation-gui.spec
- totalopenstation/__init__.py
- totalopenstation/formats/leica_gsi.py
- totalopenstation/output/__init__.py
- totalopenstation/output/tops_csv.py
- + totalopenstation/scripts/__init__.py
- scripts/totalopenstation-cli-connector.py → totalopenstation/scripts/cli_connector.py
- scripts/totalopenstation-cli-parser.py → totalopenstation/scripts/cli_parser.py
- scripts/totalopenstation-gui.py → totalopenstation/scripts/gui.py
- totalopenstation/tests/test_csv.py
- totalopenstation/tests/test_leica_gsi.py
- tox.ini
Changes:
=====================================
.github/workflows/pyinstaller.yml
=====================================
@@ -13,10 +13,10 @@ jobs:
steps:
- uses: actions/checkout at v2
- - name: Set up Python 3.8
+ - name: Set up Python 3.9
uses: actions/setup-python at v2
with:
- python-version: 3.8
+ python-version: 3.9
- name: Install dependencies and package
run: |
python -m pip install --upgrade pip
=====================================
.github/workflows/pytest.yml
=====================================
@@ -5,36 +5,35 @@ name: pytest
on:
push:
- branches: [ main ]
+ branches: [main]
pull_request:
- branches: [ main ]
+ branches: [main]
jobs:
build:
-
runs-on: ${{ matrix.os }}
strategy:
matrix:
- python-version: ["3.8", "3.9", "3.10", "3.11", "pypy3.8"]
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.10"]
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- - uses: actions/checkout at v3
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python at v4
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install flake8 pytest
- pip install .
- - name: Lint with flake8
- run: |
- # stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- - name: Test with pytest
- run: |
- pytest
+ - uses: actions/checkout at v3
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python at v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install flake8 pytest
+ pip install .
+ - name: Lint with flake8
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ - name: Test with pytest
+ run: |
+ pytest
=====================================
.travis.yml deleted
=====================================
@@ -1,11 +0,0 @@
-language: python
-python:
- - "3.6"
- - "3.7"
- - "3.8"
- - "pypy3"
-# command to install dependencies
-install:
- - pip install .
-# command to run tests
-script: pytest
=====================================
doc_requirements.txt deleted
=====================================
@@ -1,22 +0,0 @@
-alabaster==0.7.10
-Babel==2.5.1
-certifi==2017.7.27.1
-chardet==3.0.4
-docutils==0.14
-idna==2.6
-imagesize==0.7.1
-Jinja2>=2.10.1
-MarkupSafe==1.0
-pudb==2017.1.4
-pygeoif==0.7
-Pygments==2.2.0
-pyserial==3.4
-pytz==2017.2
-requests>=2.20.0
-six==1.11.0
-snowballstemmer==1.2.1
-Sphinx==1.6.4
-sphinxcontrib-websupport==1.0.1
-typing==3.6.2
-urllib3>=1.24.2
-urwid==1.3.1
=====================================
docs/conf.py
=====================================
@@ -52,11 +52,7 @@ master_doc = 'index'
# General information about the project.
project = 'Total Open Station'
-<<<<<<< HEAD
copyright = '2015-2025, Stefano Costa, Damien Gaignon and Luca Bianconi'
-=======
-copyright = '2015-2020, Stefano Costa, Damien Gaignon and Luca Bianconi'
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
author = 'Stefano Costa'
# The version info for the project you're documenting, acts as replacement for
@@ -64,13 +60,9 @@ author = 'Stefano Costa'
# built documents.
#
# The short X.Y version.
-version = '0.5'
+version = '0.7'
# The full version, including alpha/beta/rc tags.
-<<<<<<< HEAD
-release = '0.5.3'
-=======
-release = '0.5.2'
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
+release = '0.7.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -126,11 +118,7 @@ html_theme = 'alabaster'
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
-<<<<<<< HEAD
'github_user': 'totalopenstation',
-=======
- 'github_user': 'steko',
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
'github_repo': 'totalopenstation',
'github_type': 'star',
'github_count': 'true',
=====================================
docs/contributing/main.rst
=====================================
@@ -107,21 +107,6 @@ independently, with the exception of the user interfaces.
In other words, the classes for reading specific formats and those for writing
well-known formats are entirely usable on their own.
-This is a feature.
-
-Example: a web app for converting total station data
-====================================================
-
-If you want to see how to write a web app to convert total station
-data in 50 lines of Python code, check out `TOPS in the Cloud
-<https://bitbucket.org/steko/tops-cloud/overview>`_. It is made with
-`Flask <http://flask.pocoo.org/>`_ and shows how to use Total Open
-Station as a programming library.
-
-.. warning::
- TOPS in the Cloud is not maintained and does not receive security
- updates. Please don't use it in production.
-
==================================
Developing with Total Open Station
==================================
@@ -304,8 +289,8 @@ For more in-depth knowledge of classes, we encourage reading the code @ `Github`
Documentation
=============
-The documentation is included in the source tree, and is published
-online at `http://totalopenstation.readthedocs.org/ <http://totalopenstation.readthedocs.org/>`_.
+The documentation is included in the ``docs`` directory of the source tree, and is published
+online at `http://totalopenstation.readthedocs.io/ <http://totalopenstation.readthedocs.io/>`_.
Manual pages for the three scripts provided with TOPS are not
available at the moment.
@@ -321,12 +306,12 @@ A *source distribution* is made using::
python setup.py sdist
-A *built distribution* is made using (e.g. for Windows installer)::
+A *built distribution* is made using the *wheel* format (this requires the ``wheel`` package)::
- python setup.py bdist --formats wininst
+ python setup.py bdist_wheel
We are currently following the `Python Packaging User Guide
-<https://packaging.python.org/en/latest/distributing.html>`_ and
+<https://packaging.python.org/>`_ and
distributing sources and *wheels*.
Windows portable app
=====================================
docs/output_formats/of_implemented.rst
=====================================
@@ -58,6 +58,13 @@ Yet, this format is not parametric and values return are the following::
PID, type, Point Name, x, y, angle, z_angle, distance, th, ih, circle, station
+Trimble CSV
+-----------
+
+.. versionadded:: 0.7
+
+This module contains also a variant CSV output with the same data columns,
+but in a different order, Trimble CSV (used for LandSurveyCodesImport QGIS plugin)::
======================
:mod:`tops_dat` -- DAT
=====================================
docs/requirements.txt
=====================================
@@ -1,4 +1 @@
Sphinx==8.1.3
-pygeoif==0.7
-pytest==6.2.5
-pyserial==3.5
=====================================
locale/totalopenstation.pot
=====================================
@@ -1,24 +1,14 @@
# SOME DESCRIPTIVE TITLE.
-<<<<<<< HEAD
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-=======
-# Copyright (C) YEAR Stefano Costa
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
-<<<<<<< HEAD
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-09-26 21:28+0200\n"
-=======
-"Project-Id-Version: Total Open Station 0.3.1\n"
-"Report-Msgid-Bugs-To: info at iosa.it\n"
-"POT-Creation-Date: 2015-02-28 22:54+0100\n"
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -27,7 +17,6 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-<<<<<<< HEAD
#: scripts/totalopenstation-cli-connector.py:37
#: scripts/totalopenstation-cli-parser.py:39
msgid "Usage: %prog [option] arg1 [option] arg2 ..."
@@ -52,15 +41,10 @@ msgstr ""
#: scripts/totalopenstation-cli-connector.py:77
#: scripts/totalopenstation-gui.py:727
-=======
-#: scripts/totalopenstation-cli-connector.py:70
-#: scripts/totalopenstation-gui.py:726
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "Error loading the required model module: %s"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-cli-connector.py:86
#, python-format
msgid "Now you can start download from %s device"
@@ -133,34 +117,6 @@ msgid ""
msgstr ""
#: scripts/totalopenstation-cli-parser.py:138
-=======
-#: scripts/totalopenstation-cli-parser.py:36
-msgid "usage: %prog [option] arg1 [option] arg2 ..."
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:44
-msgid "select input FILE (do not specify for stdin)"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:51
-msgid "select output FILE (do not specify for stdout)"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:58
-#: scripts/totalopenstation-cli-parser.py:65
-msgid "select input FORMAT"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:72
-msgid "overwrite existing output file"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:78
-msgid "list the available input and output formats"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:104
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid ""
"\n"
@@ -170,16 +126,11 @@ msgid ""
"%(formats)s"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-cli-parser.py:145
-=======
-#: scripts/totalopenstation-cli-parser.py:111
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "%s is not a valid input format"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-cli-parser.py:155
msgid "Please specify an input format"
msgstr ""
@@ -194,64 +145,28 @@ msgid "No input data!"
msgstr ""
#: scripts/totalopenstation-cli-parser.py:211
-=======
-#: scripts/totalopenstation-cli-parser.py:121
-msgid "Please specify an input format"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:141
-msgid "No input data!"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:161
-#, python-format
-msgid "Downloaded data saved to out file %s"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:165
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "Downloaded data saved to file %s,"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-cli-parser.py:212
msgid "Overwriting the existing file"
-=======
-#: scripts/totalopenstation-cli-parser.py:166
-msgid "overwriting the existing file"
-msgstr ""
-
-#: scripts/totalopenstation-cli-parser.py:168
-msgid "Specified output file already exists\n"
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
msgstr ""
#: scripts/totalopenstation-gui.py:121
msgid ""
"\n"
-<<<<<<< HEAD
"Total Open Station is copyright 2008-2019 Stefano Costa, Damien\n"
"Gaignon, Luca Bianconi and the IOSA project, under the GNU GPL v3\n"
"or any later version.\n"
"\n"
"https://tops.iosa.it/\n"
-=======
-"Total Open Station is copyright 2008-2015 Luca Bianconi, Stefano Costa\n"
-"and the IOSA project, under the GNU GPL v3 or any later version.\n"
-"\n"
-"http://tops.iosa.it/\n"
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
"\n"
"The application logo is copyright 2008 Lapo Calamandrei under the same\n"
"license."
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:155
-=======
-#: scripts/totalopenstation-gui.py:154
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
msgid ""
"\n"
"Press OK when you're ready to download.\n"
@@ -261,7 +176,6 @@ msgid ""
"the total station menu."
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:177
msgid "Waiting for data from device"
msgstr ""
@@ -271,23 +185,11 @@ msgid "Connection initialized with the following parameters:\n"
msgstr ""
#: scripts/totalopenstation-gui.py:180
-=======
-#: scripts/totalopenstation-gui.py:176
-msgid "waiting for data from device"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:177
-msgid "Connection initialized with the following parameters:\n"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:179
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
msgid ""
"\n"
"Start the download procedure on the device.\n"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:181
msgid "Press OK when done."
msgstr ""
@@ -318,52 +220,15 @@ msgid "Import error"
msgstr ""
#: scripts/totalopenstation-gui.py:282
-=======
-#: scripts/totalopenstation-gui.py:180
-msgid "Press OK when done."
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:199
-msgid "Choose output format and destination file"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:200
-msgid "Output format:\n"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:222
-msgid "Input format"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:227 scripts/totalopenstation-gui.py:246
-msgid "choose a format"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:241
-msgid "Output format"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:280 scripts/totalopenstation-gui.py:293
-#: scripts/totalopenstation-gui.py:725
-msgid "Import error"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:281
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "Error loading the required input module: %s"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:295
-=======
-#: scripts/totalopenstation-gui.py:294
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "Error loading the required output module: %s"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:306
msgid "No output file specified"
msgstr ""
@@ -381,31 +246,11 @@ msgid "Connection failed with the following error message:\n"
msgstr ""
#: scripts/totalopenstation-gui.py:326
-=======
-#: scripts/totalopenstation-gui.py:305
-msgid "No output file specified"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:306
-msgid "No processing settings entered!\n"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:323
-msgid "Error"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:324
-msgid "Connection failed with the following error message:\n"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:325
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
msgid ""
"\n"
"Check your connection parameters and try again.\n"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:338
msgid "Cancel"
msgstr ""
@@ -484,72 +329,11 @@ msgid "Welcome to Total Open Station"
msgstr ""
#: scripts/totalopenstation-gui.py:651
-=======
-#: scripts/totalopenstation-gui.py:337
-msgid "Cancel"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:372 scripts/totalopenstation-gui.py:618
-msgid "Connect"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:373 scripts/totalopenstation-gui.py:634
-msgid "Process data"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:375
-msgid "Quit"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:378
-msgid "Open file"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:379 scripts/totalopenstation-gui.py:626
-msgid "Save raw data"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:382
-msgid "About TOPS"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:433
-msgid "Port"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:471
-msgid "Total Station"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:514 scripts/totalopenstation-gui.py:539
-#: scripts/totalopenstation-gui.py:562 scripts/totalopenstation-gui.py:585
-msgid "choose a value"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:533
-msgid "Bytesize"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:556
-msgid "Parity setting"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:579
-msgid "Stop bit"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:602
-msgid "Time lapse between data packets"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:650
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
msgid ""
"Welcome.\n"
"Turn your device on."
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:675
msgid "Do you really want to quit application ?"
msgstr ""
@@ -560,30 +344,15 @@ msgid ""
msgstr ""
#: scripts/totalopenstation-gui.py:751
-=======
-#: scripts/totalopenstation-gui.py:739
-msgid "Waiting for data: please start transfer from your total station menu."
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:750
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid "Downloaded %d bytes"
msgstr ""
-<<<<<<< HEAD
#: scripts/totalopenstation-gui.py:755
msgid "Success!"
msgstr ""
#: scripts/totalopenstation-gui.py:756
-=======
-#: scripts/totalopenstation-gui.py:754
-msgid "Success!"
-msgstr ""
-
-#: scripts/totalopenstation-gui.py:755
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
#, python-format
msgid ""
"Download finished!\n"
=====================================
pyproject.toml
=====================================
@@ -0,0 +1,55 @@
+[build-system]
+requires = ["setuptools >= 77.0.3"]
+build-backend = "setuptools.build_meta"
+
+[project]
+dynamic = ["version", "readme"]
+name = "totalopenstation"
+dependencies = ["pyserial==3.5", "pygeoif==1.4.0"]
+requires-python = ">= 3.9"
+authors = [
+ { name = "Stefano Costa" },
+ { name = "Damien Gaignon" },
+ { name = "Luca Bianconi" },
+]
+description = "Download and export survey data from your total station"
+license = "GPL-3.0"
+keywords = ["survey", "geodimeter", "fieldwork", "format conversion"]
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Environment :: Console",
+ "Environment :: X11 Applications",
+ "Intended Audience :: End Users/Desktop",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3 :: Only",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Topic :: Scientific/Engineering :: GIS",
+]
+
+[project.urls]
+Homepage = "https://tops.iosa.it/"
+Documentation = "https://totalopenstation.readthedocs.io/"
+Repository = "https://github.com/totalopenstation/totalopenstation.git"
+Issues = "https://github.com/totalopenstation/totalopenstation/issues"
+
+[project.scripts]
+totalopenstation-cli-parser = "totalopenstation.scripts.cli_parser:cli_parser"
+totalopenstation-cli-connector = "totalopenstation.scripts.cli_connector:cli_connector"
+
+[project.gui-scripts]
+totalopenstation-gui = "totalopenstation.scripts.gui:gui"
+
+[tool.setuptools.dynamic]
+version = { attr = "totalopenstation.__version__" }
+readme = { file = ["README.rst"] }
+
+[tool.setuptools]
+packages = ["totalopenstation"]
+
+[dependency-groups]
+test = ["pytest>=5.1"]
=====================================
sample_data/leica_gsi/RILIEVO.gsi
=====================================
@@ -0,0 +1 @@
+
110001+00000100 21.102+11545200 22.102+09885300 31..00+00000000 32..00+00000000
110002+00000101 21.102+00000000 22.102+09681000 31..00+00000000 32..00+00000000
110003+00000102 21.102+13247100 22.102+10378200 31..00+00005165 32..00+00005156
110004+00000103 21.102+13603500 22.102+10381400 31..00+00005351 32..00+00005341
110005+00000104 21.102+14438100 22.102+10620800 31..00+00004636 32..00+00004614
110006+00000105 21.102+14579100 22.102+10685200 31..00+00004232 32..00+00004208
110007+00000106 21.102+15288600 22.102+11935000 31..00+00003966 32..00+00003784
110008+00000107 21.102+02838500 22.102+10620000 31..00+00003866 32..00+00003848
110009+00000108 21.102+05895200 22.102+10233100 31..00+00006454 32..00+00006450
110010+00000109 21.102+07337500 22.102+10190100 31..00+00011374 32..00+00011369
110011+00000110 21.102+08174000 22.102+10127600 31..00+00020332 32..00+00020328
110012+00000111 21.102+09088000 22.102+09955300 31..00+00026759 32..00+00026758
110013+00000112 21.102+14020300 22.102+09968000 31..00+00036927 32..00+00036927
110014+00000113 21.102+18508800 22.102+10066300 31..00+00033477 32..00+00033475
110015+00000114 21.102+18689100 22.102+09962400 31..00+00050672 32..00+00050671
110016+00000115 21.102+18446500 22.102+10038200 31..00+00065824 32..00+00065823
110017+00000116 21.102+16740300 22.102+10037300 31..00+00072037 32..00+00072036
110018+00000117 21.102+16672100 22.102+09992200 31..00+00069647 32..00+00069647
110019+00000118 21.102+23066200 22.102+10080900 31..00+00041345 32..00+00041342
110020+00000119 21.102+28207100 22.102+10125200 31..00+00024342 32..00+00024337
110021+00000120 21.102+28333600 22.102+10062400 31..00+00067652 32..00+00067649
110022+00000121 21.102+25011800 22.102+10043700 31..00+00083285 32..00+00083283
110023+00000122 21.102+04392100 22.102+10354100 31..00+00004600 32..00+00004593
\ No newline at end of file
=====================================
setup.py deleted
=====================================
@@ -1,37 +0,0 @@
-from setuptools import setup, find_packages
-
-import totalopenstation
-
-setup(
- name='totalopenstation',
- version=totalopenstation.__version__,
- author='Stefano Costa',
- author_email='steko at iosa.it',
- packages=find_packages(exclude=['ez_setup', 'examples', 'tests', 'gui']),
- scripts=['scripts/totalopenstation-gui.py',
- 'scripts/totalopenstation-cli-parser.py',
- 'scripts/totalopenstation-cli-connector.py'],
- url='https://tops.iosa.it/',
- license='GNU GPLv3',
- description='Download and export survey data from your total station',
- long_description=open('README.rst').read(),
- classifiers=[
- 'Development Status :: 4 - Beta',
- 'Environment :: Console',
- 'Environment :: X11 Applications',
- 'Intended Audience :: End Users/Desktop',
- 'License :: OSI Approved :: GNU General Public License (GPL)',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 3 :: Only',
- 'Programming Language :: Python :: 3.6',
- 'Programming Language :: Python :: 3.7',
- 'Programming Language :: Python :: 3.8',
- 'Topic :: Scientific/Engineering :: GIS',
- ],
- keywords='survey geodimeter',
- install_requires=['pyserial==3.4', 'pygeoif==1.4.0'],
- tests_require=['pytest>=5.1'],
- include_package_data = True,
- zip_safe = False,
-)
=====================================
totalopenstation-gui.spec
=====================================
@@ -1,5 +1,5 @@
# -*- mode: python -*-
-a = Analysis(['scripts/totalopenstation-gui.py'],
+a = Analysis(['./totalopenstation/scripts/gui.py'],
pathex=['.'],
hiddenimports=[
'csv',
@@ -7,6 +7,7 @@ a = Analysis(['scripts/totalopenstation-gui.py'],
'numbers',
'totalopenstation.formats',
'totalopenstation.formats.carlson_rw5',
+ 'totalopenstation.formats.landxml',
'totalopenstation.formats.leica_gsi',
'totalopenstation.formats.leica_tcr_705',
'totalopenstation.formats.leica_tcr_1205',
@@ -22,19 +23,16 @@ a = Analysis(['scripts/totalopenstation-gui.py'],
'totalopenstation.models.leica_tcr_705',
'totalopenstation.models.leica_tcr_1205',
'totalopenstation.models.nikon_npl_350',
-<<<<<<< HEAD
'totalopenstation.models.nikon_npl_322plus',
'totalopenstation.models.trimble',
'totalopenstation.models.topcon_gpt_3005',
-=======
- 'totalopenstation.models.trimble',
->>>>>>> 354729060ded870e76dacc79e3025dafad4e5879
'totalopenstation.models.zeiss_elta_r55',
'totalopenstation.output',
'totalopenstation.output.tops_csv',
'totalopenstation.output.tops_dat',
'totalopenstation.output.tops_dxf',
'totalopenstation.output.tops_geojson',
+ 'totalopenstation.output.tops_landxml',
'totalopenstation.output.tops_sql',
'totalopenstation.output.tops_txt',],
hookspath=None,
=====================================
totalopenstation/__init__.py
=====================================
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-__version__ = '0.5.3'
+__version__ = '0.7.2'
import logging
=====================================
totalopenstation/formats/leica_gsi.py
=====================================
@@ -208,7 +208,15 @@ class FormatParser(Parser):
'data': t[7:],
}
self.tdict[data['wordindex']] = data
-
+
+ if list(self.tdict.keys()) == (['11', '21', '22', '31', '32']):
+ self.tdict['84'] = {'wordindex': '84', 'info': '...0', 'sign': '+', 'data': '00000000'}
+ self.tdict['85'] = {'wordindex': '85', 'info': '...0', 'sign': '+', 'data': '00000000'}
+ self.tdict['86'] = {'wordindex': '86', 'info': '...0', 'sign': '+', 'data': '00000000'}
+ self.tdict['87'] = {'wordindex': '87', 'info': '...0', 'sign': '+', 'data': '00000000'}
+ self.tdict['88'] = {'wordindex': '88', 'info': '...0', 'sign': '+', 'data': '00000000'}
+ logger.info(f"Old GSI version detected, some values have been set to 0 by default")
+ logger.info(f"see https://github.com/totalopenstation/totalopenstation/issues/168")
try:
pid = int(self.tdict['11']['info'])
text = self.tdict['11']['data'].lstrip('0')
=====================================
totalopenstation/output/__init__.py
=====================================
@@ -7,19 +7,19 @@ class Builder:
def __init__(self, data):
"""Init method which **must** be overridden in the child class
to have a working builder.
-
+
Args:
data (:class:`formats.Parser`): A list of :class:`formats.Feature`
"""
self.data = data
-
+
def process(self):
"""Action for building the output string.
-
+
This method **must** be overridden in the child class
to have a working builder.
-
+
Process the input data (processing data).
This is because we want to keep the generation of output separated from
saving it to disk.
@@ -38,5 +38,6 @@ BUILTIN_OUTPUT_FORMATS = {
'dat': ('tops_dat', 'OutputFormat', 'DAT'),
'txt': ('tops_txt', 'OutputFormat', 'Text'),
'geojson': ('tops_geojson', 'OutputFormat', 'GeoJSON'),
- 'landxml': ('tops_landxml', 'OutputFormat', 'LandXML')
+ 'landxml': ('tops_landxml', 'OutputFormat', 'LandXML'),
+ 'trimblecsv': ('tops_csv', 'TrimbleOutputFormat', 'Trimble CSV')
}
=====================================
totalopenstation/output/tops_csv.py
=====================================
@@ -75,3 +75,72 @@ class OutputFormat(Builder):
self.writer.writerow(row)
return self.output.getvalue()
+
+class TrimbleOutputFormat(OutputFormat):
+ """
+ Exports points data in Trimble CSV format,
+ used for LandSurveyCodesImport QGIS plugin.
+
+ ``data`` should be an iterable containing Feature objects.
+ """
+
+ def __init__(self, data):
+ self.data = data
+ self.output = io.StringIO()
+ fieldnames = [
+ "id",
+ "x",
+ "y",
+ "z",
+ "type",
+ "point_name",
+ "angle",
+ "z_angle",
+ "distance",
+ "th",
+ "ih",
+ "circle",
+ "station",
+ ]
+ self.writer = csv.DictWriter(
+ self.output, quoting=csv.QUOTE_NONNUMERIC, fieldnames=fieldnames
+ )
+ self.writer.writeheader()
+
+ def process(self):
+
+ for feature in self.data:
+ row = {
+ "id": feature.id,
+ "type": feature.desc,
+ "x": feature.geometry.x,
+ "y": feature.geometry.y,
+ }
+
+ try: # not all input formats include z coordinates
+ row["z"] = feature.geometry.z
+ except ValueError:
+ row["z"] = ""
+
+ # a few cases with simple yes/no logic
+ for prop in ["point_name", "ih", "circle", "z_angle", "th"]:
+ row[prop] = feature.properties.get(
+ prop, ""
+ ) # empty string as default value
+
+ # not all input formats include azimuth/angle
+ row["angle"] = feature.properties.get(
+ "azimuth", feature.properties.get("angle", "")
+ )
+
+ # not all input formats include distance
+ row["distance"] = feature.properties.get(
+ "slope_dist", feature.properties.get("horizontal_dist", "")
+ )
+
+ # not all input formats include station name
+ row["station"] = feature.properties.get("st_name", "")
+
+ self.writer.writerow(row)
+
+ return self.output.getvalue()
=====================================
totalopenstation/scripts/__init__.py
=====================================
=====================================
scripts/totalopenstation-cli-connector.py → totalopenstation/scripts/cli_connector.py
=====================================
@@ -1,7 +1,7 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# filename: totalopenstation-cli-connector.py
-# Copyright 2021 Stefano Costa <steko at iosa.it>
+# Copyright 2025 Stefano Costa <steko at iosa.it>
# This file is part of Total Open Station.
@@ -34,71 +34,76 @@ from totalopenstation.models import BUILTIN_MODELS
t = gettext.translation('totalopenstation', './locale', fallback=True)
_ = t.gettext
-usage = _("Usage: %prog [option] arg1 [option] arg2 ...")
-
-parser = OptionParser(usage=usage)
-parser.add_option("-m",
- "--model",
- action="store",
- type="string",
- dest="model",
- help=_("Select input MODEL"),
- metavar="MODEL")
-parser.add_option("-p",
- "--port",
- action="store",
- type="string",
- dest="port",
- help=_("Select input SERIAL PORT"),
- metavar="PORT")
-parser.add_option("-o",
- "--outfile",
- action="store",
- type="string",
- dest="outfile",
- help=_("Select output FILE (do not specify for stdout)"),
- metavar="FILE")
-
-(options, args) = parser.parse_args()
-
-if not (options.model and options.port):
- sys.exit(_("Please specify your model and the port to download from"))
-
-modelclass = BUILTIN_MODELS[options.model]
-
-# import input format parser
-if isinstance(modelclass, tuple):
+def cli_connector():
+ usage = _("Usage: %prog [option] arg1 [option] arg2 ...")
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-m",
+ "--model",
+ action="store",
+ type="string",
+ dest="model",
+ help=_("Select input MODEL"),
+ metavar="MODEL")
+ parser.add_option("-p",
+ "--port",
+ action="store",
+ type="string",
+ dest="port",
+ help=_("Select input SERIAL PORT"),
+ metavar="PORT")
+ parser.add_option("-o",
+ "--outfile",
+ action="store",
+ type="string",
+ dest="outfile",
+ help=_("Select output FILE (do not specify for stdout)"),
+ metavar="FILE")
+
+ (options, args) = parser.parse_args()
+
+ if not (options.model and options.port):
+ sys.exit(_("Please specify your model and the port to download from"))
+
+ modelclass = BUILTIN_MODELS[options.model]
+
+ # import input format parser
+ if isinstance(modelclass, tuple):
+ try:
+ # builtin format parser
+ mod, cls, name = modelclass
+ modelclass = getattr(
+ __import__('totalopenstation.models.%s' % mod, None, None, [cls]), cls)
+ except ImportError as msg:
+ sys.exit(_('Error loading the required model module: %s') % msg)
+
+ station = modelclass(options.port)
try:
- # builtin format parser
- mod, cls, name = modelclass
- modelclass = getattr(
- __import__('totalopenstation.models.%s' % mod, None, None, [cls]), cls)
- except ImportError as msg:
- sys.exit(_('Error loading the required model module: %s') % msg)
-
-station = modelclass(options.port)
-try:
- station.close() # sometimes the port will be already open for no reason
- station.open()
-except serial.SerialException as detail:
- sys.exit(detail)
-
-print(_("Now you can start download from %s device") % options.model)
-
-station.start()
-station.dl_started.wait()
-print(_("Download started..."))
-station.dl_finished.wait()
-print(_("Download finished..."))
-result = station.result
-
-if options.outfile:
- if not os.path.exists(options.outfile):
- e = open(options.outfile, "wb")
- e.write(result)
- e.close()
- print(_("Downloaded data saved to out file %s") % options.outfile)
+ station.close() # sometimes the port will be already open for no reason
+ station.open()
+ except serial.SerialException as detail:
+ sys.exit(detail)
+
+ print(_("Now you can start download from %s device") % options.model)
+
+ station.start()
+ station.dl_started.wait()
+ print(_("Download started..."))
+ station.dl_finished.wait()
+ print(_("Download finished..."))
+ result = station.result
+
+ if options.outfile:
+ if not os.path.exists(options.outfile):
+ e = open(options.outfile, "wb")
+ e.write(result)
+ e.close()
+ print(_("Downloaded data saved to out file %s") % options.outfile)
+ else:
+ sys.exit(_("Specified output file already exists\n"))
else:
- sys.exit(_("Specified output file already exists\n"))
-else:
- sys.stdout.write(result)
+ sys.stdout.write(result)
+
+
+if __name__ == '__main__':
+ cli_connector()
=====================================
scripts/totalopenstation-cli-parser.py → totalopenstation/scripts/cli_parser.py
=====================================
@@ -36,149 +36,148 @@ import totalopenstation.output
t = gettext.translation('totalopenstation', './locale', fallback=True)
_ = t.gettext
-usage = _("Usage: %prog [option] arg1 [option] arg2 ...")
-
-parser = OptionParser(usage=usage)
-parser.add_option("-i",
- "--infile",
- action="store",
- type="string",
- dest="infile",
- help=_("Select input FILE (do not specify for stdin)"),
- metavar="FILE")
-parser.add_option("-o",
- "--outfile",
- action="store",
- type="string",
- dest="outfile",
- help=_("Select output FILE (do not specify for stdout)"),
- metavar="FILE")
-parser.add_option("-f",
- "--input-format",
- action="store",
- type="string",
- dest="informat",
- help=_("Select input FORMAT"),
- metavar="FORMAT")
-parser.add_option("--2d",
- action="store_true",
- dest="xy_only",
- help=_("Exclude Z coordinates, output only 2D data"),
- metavar="ONLY2D")
-parser.add_option("-t",
- "--output-format",
- action="store",
- type="string",
- dest="outformat",
- help=_("Select input FORMAT"),
- metavar="FORMAT")
-parser.add_option("-r",
- "--raw",
- action="store_true",
- dest="raw",
- help=_("Enhanced parsed file process"))
-parser.add_option(
- "--overwrite",
- action="store_true",
- dest="overwrite",
- default=False,
- help=_("Overwrite existing output file"))
-parser.add_option(
- "--list",
- action="store_true",
- dest="list",
- default=False,
- help=_("List the available input and output formats"))
-parser.add_option(
- "--log",
- action="store",
- dest="loglevel",
- default="WARNING",
- type="string",
- help=_("Minimum log level"))
-parser.add_option(
- "--logtofile",
- action="store_true",
- dest="logotfile",
- default=False,
- help=_("Log to file"))
-
-
-(options, args) = parser.parse_args()
-
-logger = logging.getLogger()
-logger.setLevel(options.loglevel.upper())
-if options.logotfile:
- handler = logging.FileHandler("tops.log")
-else:
- handler = logging.StreamHandler()
-formatter = logging.Formatter('%(asctime)s -- %(filename)s -- %(levelname)s -- %(funcName)s -- %(message)s')
-handler.setFormatter(formatter)
-logger.addHandler(handler)
-
-def list_formats():
- '''Print a list of the supported input and output formats.'''
-
- mod_string = _("List of supported input formats:\n%s\n") % ('-' * 30)
- for k, v in sorted(totalopenstation.formats.BUILTIN_INPUT_FORMATS.items()):
- mod_string += "%s%s\n" % (k.ljust(20), v[2])
- mod_string += "\n\n"
-
- mod_string += _("List of supported output formats:\n%s\n") % ('-' * 30)
- for k, v in sorted(totalopenstation.output.BUILTIN_OUTPUT_FORMATS.items()):
- mod_string += "%s%s\n" % (k.ljust(20), v[2])
- mod_string += "\n"
- return mod_string
-
-if options.list:
- sys.stdout.write(list_formats())
- sys.exit()
-
-def exit_with_error(message):
- sys.exit(_("\nError:\n%(message)s\n\n%(formats)s") % {'message': message,
- 'formats': list_formats()})
-
-if options.informat:
- try:
- inputclass = totalopenstation.formats.BUILTIN_INPUT_FORMATS[options.informat]
- except KeyError as message:
- exit_with_error(_('%s is not a valid input format') % message)
+def cli_parser():
+ usage = _("Usage: %prog [option] arg1 [option] arg2 ...")
+
+ parser = OptionParser(usage=usage)
+ parser.add_option("-i",
+ "--infile",
+ action="store",
+ type="string",
+ dest="infile",
+ help=_("Select input FILE (do not specify for stdin)"),
+ metavar="FILE")
+ parser.add_option("-o",
+ "--outfile",
+ action="store",
+ type="string",
+ dest="outfile",
+ help=_("Select output FILE (do not specify for stdout)"),
+ metavar="FILE")
+ parser.add_option("-f",
+ "--input-format",
+ action="store",
+ type="string",
+ dest="informat",
+ help=_("Select input FORMAT"),
+ metavar="FORMAT")
+ parser.add_option("--2d",
+ action="store_true",
+ dest="xy_only",
+ help=_("Exclude Z coordinates, output only 2D data"),
+ metavar="ONLY2D")
+ parser.add_option("-t",
+ "--output-format",
+ action="store",
+ type="string",
+ dest="outformat",
+ help=_("Select input FORMAT"),
+ metavar="FORMAT")
+ parser.add_option("-r",
+ "--raw",
+ action="store_true",
+ dest="raw",
+ help=_("Enhanced parsed file process"))
+ parser.add_option(
+ "--overwrite",
+ action="store_true",
+ dest="overwrite",
+ default=False,
+ help=_("Overwrite existing output file"))
+ parser.add_option(
+ "--list",
+ action="store_true",
+ dest="list",
+ default=False,
+ help=_("List the available input and output formats"))
+ parser.add_option(
+ "--log",
+ action="store",
+ dest="loglevel",
+ default="WARNING",
+ type="string",
+ help=_("Minimum log level"))
+ parser.add_option(
+ "--logtofile",
+ action="store_true",
+ dest="logotfile",
+ default=False,
+ help=_("Log to file"))
+
+
+ (options, args) = parser.parse_args()
+
+ logger = logging.getLogger()
+ logger.setLevel(options.loglevel.upper())
+ if options.logotfile:
+ handler = logging.FileHandler("tops.log")
else:
- if isinstance(inputclass, tuple):
- try:
- # builtin format parser
- mod, cls, name = inputclass
- inputclass = getattr(importlib.import_module('totalopenstation.formats.%s' % mod), cls)
- except ImportError as message:
- exit_with_error(message)
-else:
- sys.exit(_("Please specify an input format"))
-
-if options.outformat:
- try:
- outputclass = totalopenstation.output.BUILTIN_OUTPUT_FORMATS[options.outformat]
- except KeyError as message:
- exit_with_error(_('%s is not a valid output format') % message)
- else:
- if isinstance(outputclass, tuple):
- try:
- # builtin output builder
- mod, cls, name = outputclass
- outputclass = getattr(importlib.import_module('totalopenstation.output.%s' % mod), cls)
- except ImportError as message:
- exit_with_error(message)
-
-if options.infile:
- infile = open(options.infile, 'r').read()
-else:
- if sys.stdin.isatty():
- sys.exit(_('No input data!'))
+ handler = logging.StreamHandler()
+ formatter = logging.Formatter('%(asctime)s -- %(filename)s -- %(levelname)s -- %(funcName)s -- %(message)s')
+ handler.setFormatter(formatter)
+ logger.addHandler(handler)
+
+ def list_formats():
+ '''Print a list of the supported input and output formats.'''
+
+ mod_string = _("List of supported input formats:\n%s\n") % ('-' * 30)
+ for k, v in sorted(totalopenstation.formats.BUILTIN_INPUT_FORMATS.items()):
+ mod_string += "%s%s\n" % (k.ljust(20), v[2])
+ mod_string += "\n\n"
+
+ mod_string += _("List of supported output formats:\n%s\n") % ('-' * 30)
+ for k, v in sorted(totalopenstation.output.BUILTIN_OUTPUT_FORMATS.items()):
+ mod_string += "%s%s\n" % (k.ljust(20), v[2])
+ mod_string += "\n"
+ return mod_string
+
+ if options.list:
+ sys.stdout.write(list_formats())
+ sys.exit()
+
+ def exit_with_error(message):
+ sys.exit(_("\nError:\n%(message)s\n\n%(formats)s") % {'message': message,
+ 'formats': list_formats()})
+
+ if options.informat:
+ try:
+ inputclass = totalopenstation.formats.BUILTIN_INPUT_FORMATS[options.informat]
+ except KeyError as message:
+ exit_with_error(_('%s is not a valid input format') % message)
+ else:
+ if isinstance(inputclass, tuple):
+ try:
+ # builtin format parser
+ mod, cls, name = inputclass
+ inputclass = getattr(importlib.import_module('totalopenstation.formats.%s' % mod), cls)
+ except ImportError as message:
+ exit_with_error(message)
else:
- infile = sys.stdin.read()
+ sys.exit(_("Please specify an input format"))
+ if options.outformat:
+ try:
+ outputclass = totalopenstation.output.BUILTIN_OUTPUT_FORMATS[options.outformat]
+ except KeyError as message:
+ exit_with_error(_('%s is not a valid output format') % message)
+ else:
+ if isinstance(outputclass, tuple):
+ try:
+ # builtin output builder
+ mod, cls, name = outputclass
+ outputclass = getattr(importlib.import_module('totalopenstation.output.%s' % mod), cls)
+ except ImportError as message:
+ exit_with_error(message)
+
+ if options.infile:
+ infile = open(options.infile, 'r').read()
+ else:
+ if sys.stdin.isatty():
+ sys.exit(_('No input data!'))
+ else:
+ infile = sys.stdin.read()
-def main(infile):
- '''After setting up all parameters, finally try to process input data.'''
+ # After setting up all parameters, finally try to process input data.
parsed_data = inputclass(infile)
if options.raw:
@@ -216,4 +215,4 @@ def main(infile):
sys.stdout.write(output.process())
if __name__ == '__main__':
- main(infile)
+ cli_parser()
=====================================
scripts/totalopenstation-gui.py → totalopenstation/scripts/gui.py
=====================================
@@ -1,7 +1,7 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# filename: totalopenstation-gui.py
-# Copyright 2008-2019 Stefano Costa <steko at iosa.it>
+# Copyright 2008-2025 Stefano Costa <steko at iosa.it>
# Copyright 2010,2012 Luca Bianconi <luxetluc at yahoo.it>
#
# This file is part of Total Open Station.
@@ -119,7 +119,7 @@ class AboutDialog(tkinter.simpledialog.Dialog):
def body(self, master):
title = "Total Open Station %s" % totalopenstation.__version__
message = _("""
-Total Open Station is copyright 2008-2019 Stefano Costa, Damien
+Total Open Station is copyright 2008-2025 Stefano Costa, Damien
Gaignon, Luca Bianconi and the IOSA project, under the GNU GPL v3
or any later version.
@@ -802,14 +802,14 @@ class Tops:
self.text_area.update_idletasks()
-root = Tk()
-Tops = Tops(root)
+def gui():
+ root = Tk()
+ app = Tops(root)
+ #save user's preferences (model, port and sleeptime if custom model)
-#save user's preferences (model, port and sleeptime if custom model)
-
-atexit.register(Tops.upref.setvalues,
- {'model': Tops.optionMODEL_value.get(),
- 'port': Tops.option1_value.get(),
- 'sleeptime': Tops.option6_value.get(),
- })
+ atexit.register(app.upref.setvalues,
+ {'model': app.optionMODEL_value.get(),
+ 'port': app.option1_value.get(),
+ 'sleeptime': app.option6_value.get(),
+ })
=====================================
totalopenstation/tests/test_csv.py
=====================================
@@ -1,7 +1,7 @@
import unittest
from totalopenstation.formats import Feature, Point
-from totalopenstation.output.tops_csv import OutputFormat
+from totalopenstation.output.tops_csv import OutputFormat, TrimbleOutputFormat
class TestCSVOutput(unittest.TestCase):
@@ -20,3 +20,20 @@ class TestCSVOutput(unittest.TestCase):
def test_output(self):
self.output = OutputFormat(self.data).process()
self.assertEqual(self.output.splitlines()[1], '1,"PT","TEST POINT",12.8,76.3,56.2,"","","","","","",""')
+
+class TestTrimbleCSVOutput(unittest.TestCase):
+
+ def setUp(self):
+ self.data = [
+ Feature(Point(12.8, 76.3, 56.2), desc="PT", point_name="TEST POINT", id=1),
+ Feature(
+ Point(19.8, 26.3, 46.2), desc="PT", point_name="TEST POINT #2", id=2
+ ),
+ ]
+
+ def test_output(self):
+ self.output = TrimbleOutputFormat(self.data).process()
+ self.assertEqual(
+ self.output.splitlines()[1],
+ '1,12.8,76.3,56.2,"PT","TEST POINT","","","","","","",""',
+ )
=====================================
totalopenstation/tests/test_leica_gsi.py
=====================================
@@ -70,3 +70,20 @@ class TestLeicaGSI8Output(BaseTestOutput):
def setup(self):
with open('sample_data/leica_gsi/leica_gsi16_gurob.gsi') as testdata:
self.fp = FormatParser(testdata.read())
+
+
+class TestLeicaGSIOldParser(unittest.TestCase):
+ def setUp(self):
+ with open('sample_data/leica_gsi/RILIEVO.gsi') as testdata:
+ self.fp = FormatParser(testdata.read())
+
+ def test_all_points_processed(self):
+ self.assertEqual(len(self.fp.points), 23)
+
+ def test_values(self):
+ self.assertEqual(self.fp.points[2].id, 3)
+ self.assertEqual(self.fp.points[2].desc, 'PT')
+ self.assertEqual(self.fp.points[2].point_name, '102')
+ self.assertAlmostEqual(self.fp.points[2].geometry.x, 4.49963916)
+ self.assertAlmostEqual(self.fp.points[2].geometry.y, -2.51722711)
+ self.assertAlmostEqual(self.fp.points[2].geometry.z, -0.30665937)
=====================================
tox.ini
=====================================
@@ -1,10 +1,10 @@
[tox]
env_list =
- py38
py39
py310
py311
py312
+ py313
minversion = 4.14.2
[testenv]
View it on GitLab: https://salsa.debian.org/debian-gis-team/totalopenstation/-/commit/3b8fcb2e394dda40dce37b59c8c3e6c562e7cd4c
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/totalopenstation/-/commit/3b8fcb2e394dda40dce37b59c8c3e6c562e7cd4c
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260102/8b1b9f24/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list