Giter Site home page Giter Site logo

totalopenstation / totalopenstation Goto Github PK

View Code? Open in Web Editor NEW
67.0 12.0 28.0 1.36 MB

Total Open Station downloads and exports survey data from your total station

Home Page: https://tops.iosa.it/

License: GNU General Public License v3.0

Python 100.00%
python survey gis fieldwork field-survey geospatial geolocation topography python3

totalopenstation's Introduction

Total Open Station

pytest continuous integration

PyPI Read the Docs

Total Open Station is a program for downloading and processing survey data from total station devices.

https://tops.iosa.it/img/totalopenstation-gui.gif

Total Open Station is a good choice if:

  • you work with total stations on GNU/Linux (and MacOS, probably)
  • you work with old devices that are unsupported by vendors
  • you need to process hundreds of data files at once

We think Total Open Station is small but great because:

  • it is free/libre open source software
  • it works on any operating system where Python is available
  • it is designed to support as many devices and formats as possible, all within the same program, opposed to having one program per device
  • it works both on the command line and with a graphical interface

Total Open Station uses a modular structure and keeps the downloading of data logically separated from its processing, thus enabling exporting data to a variety of output formats, even at a later moment. Archiving of raw data is made easy by using plain text files.

Installing

If you're comfortable with the command line:

pip install totalopenstation

Windows users can download the portable app from the GitHub releases page.

GNU/Linux users can find the totalopenstation package in some distributions (OpenSUSE, Debian, Ubuntu). Make sure that python3-tk or python3-tkinter is installed on your system, otherwise install it with your package manager (apt, dnf, pacman).

Documentation

Documentation is online at http://totalopenstation.readthedocs.io/ with an user guide, details on the application structure, supported models and other interesting stuff.

Development

Total Open Station is developed by @steko, @psolyca and other contributors, including translators and providers of sample data. We are not professional software developers but we do our best to follow modern good practice. Feel free to submit a feature request or a pull request on GitHub.

The application icons are copyright by Lapo Calamandrei 2008, under the same license as Total Open Station.

totalopenstation's People

Contributors

alearcteam avatar baswein avatar comradekingu avatar dependabot[bot] avatar enzococca avatar lbartoletti avatar lucabianconi avatar mach0 avatar psolyca avatar steko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

totalopenstation's Issues

save the last values used in the GUI

Currently the GUI user has to type and choose the connection and export options each time s/he uses the program. This is bad.

We shold add a way to save these "last used" values in a configuration file, to be read at each start of the program and, if the case, written when choices are changed.


Error invoking totalopenstation-cli-connector.py

Invoking totalopenstation-cli-connector.py results in an error for me:

[volker@lenovo-muw ~]$ totalopenstation-cli-connector.py
Traceback (most recent call last):
  File "/usr/bin/totalopenstation-cli-connector.py", line 57, in <module>
      modelclass = BUILTIN_INPUT_FORMATS[options.model]
      NameError: name 'BUILTIN_INPUT_FORMATS' is not defined

Submitted by Volker Fröhlich.


Problems with hardcoded sleep time between serial data packets

From https://lists.berlios.de/pipermail/tops-dev/2011-September/000075.html (originally reported by Anna Hodgkinson):

When sending the data (after connecting my total station to the laptop) TOPS sends me a message after 527 bytes saying my download had finished, even though no "end" message had been displayed in the data window. The total station's display is then still saying it's "Downloading Measurements". So, when I hit "connect" again the download continues to download all the data and the "end" message finally is displayed after a while.

This is almost certainly caused by the hard-coded time passed to the time.sleep() call in the download procedure (both in the GUI and command-line program).

Temporary workaround: add an option to adjust this parameter until downloading large datasets works again.

Long-term solution: study the relationship between baudrate and data packets (their size, the sleep time between each other).


Check compatibility with pySerial >= 2.6 on Microsoft Windows

pySerial 2.6 brings a fix for the issue affecting 64-bit systems on Microsoft Windows. Upgrading our requirement to pySerial 2.6 would benefit new users because it doesn't depend anymore on pywin32, so it's one package less that needs to be installed.

Tests can be performed with any version of Total Open Station, because there is no direct relation between versions of the two programs.

The current version of pySerial is now 2.7


Support for Leica DBX format

Most modern Leica total stations use the DBX format as default.

This is a binary format that can be moved from the total station to your PC with the memory card.

Some reverse-engineering will be required. At a first look with //hexdump// & similar tools, the format contains a lot of useless data.


allow options for output formats

Some output formats could be enhanced by allowing the user to specify options that change the output, like:

  • exclude / include Z coordinates (all formats)
  • create separate layers for different features (DXF)
  • use a different separator than default comma (CSV)

and so on.

Options should be defined in the output format classes, but the UI should be able to extract options data from there and give the user the proper ways to edit options (checkbox, radiobutton, etc).


GUI is created only with "Port" label

On a Windows XP SP2 computer, using the precompiled executable the GUI is created only with "Port" label.

This is probably due to some error in the //scan()// function, that is executed right after drawing the "Port" label. Unfortunately no error message is issued.


Switch to Python 3

Once issue #29 has been fixed, all our (small set of) dependencies will be compatible with Python 3. There is no reason to stay with Python 2 when all major GNU/Linux distributions ship also Python 3. The only problems could be on OS X, for which we haven't done any testing so far in any case.

Porting to Python 3 will prove interesting especially in the area of bytes/strings conversion (we download bytes from total stations, usually).

This task is enough for a release on its own, so any other task that is not bug-fixing should be postponed when working at it.


Every desktop application should have a .desktop file

Every desktop application should have a .desktop file, as described in
http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html. Ideally, you'd also include an icon, but that is up to you.
Talking about the icon, the logo is said to be copyrighted. Is it still
distributed by the terms of the GPL?

This could be a simple totalopenstation.desktop:

[Desktop Entry]
Name=Totalopenstation
Comment=Download and process data from total station devices
Exec=totalopenstation-gui
Icon=totalopenstation
Terminal=false
Type=Application
Categories=Utility;Education;Science;Geoscience;Geography;

You can always validate spec files with desktop-file-validate.

Submitted by Volker Fröhlich.


Tests fail with PyPy

We have a small number of unit tests to help with our development. Today I ran the test suite with PyPy and 3 of them failed, all related to the PolarPoint class in formats/polar.py.

[steko@ogma totalopenstation]$ pypy -m unittest discover
EEE...
======================================================================
ERROR: test_points (totalopenstation.tests.test_nikon.TestNikonParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/steko/code/totalopenstation/totalopenstation/tests/test_nikon.py", line 19, in test_points
    self.assertAlmostEqual(self.fp.points[0][1], 8.9092817528619808)
  File "/home/steko/code/totalopenstation/totalopenstation/formats/nikon_raw_v200.py", line 64, in _points
    points.append(p.to_point().tuplepoint)
  File "/home/steko/code/totalopenstation/totalopenstation/formats/polar.py", line 93, in to_point
    self.angle,
AttributeError: PolarPoint instance has no attribute 'angle'

======================================================================
ERROR: test_shorter (totalopenstation.tests.test_nikon.TestNikonParser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/steko/code/totalopenstation/totalopenstation/tests/test_nikon.py", line 22, in test_shorter
    self.assertEqual(self.fp.points[2][4], 'P')
  File "/home/steko/code/totalopenstation/totalopenstation/formats/nikon_raw_v200.py", line 64, in _points
    points.append(p.to_point().tuplepoint)
  File "/home/steko/code/totalopenstation/totalopenstation/formats/polar.py", line 93, in to_point
    self.angle,
AttributeError: PolarPoint instance has no attribute 'angle'

======================================================================
ERROR: test_polar (totalopenstation.tests.test_polar.TestPolar)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/steko/code/totalopenstation/totalopenstation/tests/test_polar.py", line 21, in test_polar
    self.assertEqual(self.p0.to_cartesian(), '100.0,100.0,110.0')
  File "/home/steko/code/totalopenstation/totalopenstation/formats/polar.py", line 80, in to_cartesian
    self.angle,
AttributeError: PolarPoint instance has no attribute 'angle'

----------------------------------------------------------------------
Ran 6 tests in 0.001s

FAILED (errors=3)

TOPS > 0.3 does not start if preferences from 0.3 exist

TOPS 0.3 first introduced user preferences for the GUI, enabling the model and port choice to be saved across session.

Newer (unreleased) versions added more values to the saved choices (e.g. the sleeptime custom option), but if an old file exists without these choices the program will fail to start:

#!pytb

(pyenv)steko@ganymede:~/code/totalopenstation$ totalopenstation-gui.py 
Traceback (most recent call last):
  File "/home/steko/code/totalopenstation/pyenv/bin/totalopenstation-gui.py", line 7, in <module>
    execfile(__file__)
  File "/home/steko/code/totalopenstation/scripts/totalopenstation-gui.py", line 797, in <module>
    Tops = Tops(root)
  File "/home/steko/code/totalopenstation/scripts/totalopenstation-gui.py", line 605, in __init__
    self.option6_value.set(self.upref.getvalue('sleeptime'))
  File "/home/steko/code/totalopenstation/totalopenstation/utils/upref.py", line 86, in getvalue
    return self.get('topsconfig', value)
  File "/usr/lib/python2.7/ConfigParser.py", line 618, in get
    raise NoOptionError(option, section)
ConfigParser.NoOptionError: No option 'sleeptime' in section: 'topsconfig'

An upgrade path must be provided, creating the missing variables when needed.


custom serial connection will fail

There is a bug in totalopenstation-gui.py at line 654 https://github.com/steko/totalopenstation/blob/master/scripts/totalopenstation-gui.py#L654 where the ConnectDialog is called with //conn_string// as an argument, but there is no such variable.

It was left by <>. A working patch is ready to be pushed, that uses

#!python

d = ConnectDialog(self.myParent, str(TOPSerial))

instead.


Clarify license: GPLv3 or GPLv3+

Some files, for instance totalopenstation/models/trimble.py or
totalopenstation/models/leica_tcr_1205.py, claim to be "Under the GNU GPL 3
License", which does not indicate later versions of the GPL are allowed as
well. This is in contrast to files like totalopenstation/output/tops_sql.py,
that clearly allow later versions. Please clarify the licensing issue.

Submitted by Volker Fröhlich.


Add support for RW5 format

RW5 is the format used by Carlson SurvCE.

Specs here http://update.carlsonsw.com/kbase_attach/372/

Supported record types

  • BD Backsight Direct
  • BK Backsight
  • BR Backsight Reverse
  • FD Foresight Direct
  • FR Foresight Reverse
  • GPS GPS Position in Lat(dd.mmss) Lon(dd.mmss - Negative for West) and WGS84 Ellipsoid
  • Elv(meters)
  • JB Job
  • LS Line of Sight
  • MO Mode Setup
  • OC Occupy
  • OF Off Center Shot
  • SP Store Point
  • SS Side Shot
  • TR Traverse
  • -- Note Record

warnings about format strings without named arguments

Running xgettext:

scripts/totalopenstation-cli-parser.py:111: warning: 'msgid' format string with unnamed arguments cannot be properly localized:
                                                     The translator cannot reorder the arguments.
                                                     Please consider using a format string with named arguments,
                                                     and a mapping instead of a tuple for the arguments.
scripts/totalopenstation-cli-parser.py:124: warning: 'msgid' format string with unnamed arguments cannot be properly localized:
                                                     The translator cannot reorder the arguments.
                                                     Please consider using a format string with named arguments,
                                                     and a mapping instead of a tuple for the arguments.

Add some way to automagically find out which format a data file uses

Currently, the user has to tell the program which input format the data use. While this usability problem could partly be mitigated when <<issue 6>> is fixed, this leaves our library without a way to automatically find out which format should be used when parsing data.

A possible approach to this problem would be to write, for each format, two sets of conditions:

  • necessary (evaluated with the all() builtin)
  • sufficient (evaluated with the any() builtin)

These conditions to evaluate could be like:

  • file contains a particular text string at a certain position
  • file contains lines that return True when parsed with the is_point function (but this would be computationally expensive)

Staying on the subject of “computationally expensive”, there would be no use in parsing the same file a dozen of times to obtain the same response. A string could be added to the file, then, in the same fashion as the coding line in Python source files, like:

# -*- tops-format: zeiss_rec_500 -*-

The import routine should first look for this string, and only in case it doesn't find one, parse the full content of the file.

If for some reason parsing data using that format doesn't work, the program should do again an identification process.

While there are some rough corners, having this feature would prove very useful and widen the field of opportunities for Total Open Station to be used in a range of different contexts.


Opening Total Open Station with "custom" model does not show serial parameters

There's a UI bug related to "custom" serial parameters.

If another model is currently selected and the user chooses "custom" from the dropdown menu, 4 entries for the serial parameters appear (and disappear accordingly if the user then switches again to a "known" model).

If "custom" is selected when the program is closed, it gets saved into the user preferences and is selected by default the next time Total Open Station is run. However, in this case, the 4 serial parameters are not shown and, even worst, their value is unset, leading to connection errors.


autosave downloaded data

With the current user interface, it's too easy to lose data just by closing the program window, or importing other data either by downloading or opening an existing file.

We should add an autosave feature. Real-time saving prevents data loss when the program crashes or if the user is forced to stop a transfer before its end.

Downloaded data should be saved in real time on disk to a file (in the .totalopenstation folder. Filenames should just be a timestamp.tops. like autosave201110091504.tops. The most recent file in the folder should be loaded automatically when the program is run the next time.

Files could be also gzipped to save space (but support for loading gzipped files is still missing).


First run fails if .totalopenstation directory exists but .totalopenstation.cfg file doesn't

Testing installation on Windows revealed a bug in upref.py that occurs in certain situations when totalopenstation-gui.py is run for the first time.

(pyenv)steko@ganymede:~/code/totalopenstation$ totalopenstation-gui.py 
Traceback (most recent call last):
  File "/home/steko/code/totalopenstation/pyenv/bin/totalopenstation-gui.py", line 7, in <module>
    execfile(__file__)
  File "/home/steko/code/totalopenstation/scripts/totalopenstation-gui.py", line 719, in <module>
    Tops = Tops(root)
  File "/home/steko/code/totalopenstation/scripts/totalopenstation-gui.py", line 319, in __init__
    self.upref = UserPrefs()
  File "/home/steko/code/totalopenstation/totalopenstation/utils/upref.py", line 54, in __init__
    os.mkdir(os.path.dirname(self.upref))
OSError: [Errno 17] File exists: '/home/steko/.totalopenstation'

This bug is caused by a missing condition handling in the function that creates the configuration file if missing.


do not use exec statements for importing the required modules

Currently, importing the appropriate input and output modules is done with:

  • static dictionaries that provide mappings between UI strings and module names
  • exec statements that do the import based on string formatting

This is rather ugly and unpythonic. It should be done another way. See also <<issue 2>>


Application icons are missing from the repo

We have Freedesktop compatible icons, created in 2008 by Lapo Calamandrei. They are missing from the repo, and the logo is only included in the totalopenstation-gui.py script as an encoded bitmap.

Icons should be added to the repository. It's not clear what is the best path for them.


bug in serial connection GUI code

A recent API change, geared towards splitting completely the serial connection from the parsing of data also at module level, has left the GUI in a broken, inconsistent state.
When clicking on the //Connect// button, this error appears in the console:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1417, in __call__
    return self.func(*args)
  File "./totalopenstation-gui.py", line 655, in connect_action
    mc = iformats.ModelConnector(chosen_port)
AttributeError: 'dict' object has no attribute 'ModelConnector'

Our plan for the serial connection is to get rid of "models" in the code, enable users to define their connection parameters in the GUI (saved in a preferences file), but then this change should be implemented for 0.2.


custom serial connection is handled in a different way, without any reason

There's a huge difference in how we treat custom serial connections vs known models.

This is essentially a relic from the past, and we should get rid of it. The best option is to treat "custom" as the standard type and known models as special cases. The "models" subpackage should be refactored heavily.


Executables missing manpage

A standard install of TOPS brings three executables:

  • usr/bin/totalopenstation-cli-connector
  • usr/bin/totalopenstation-cli-parser
  • usr/bin/totalopenstation-gui

All should have a manpage, as required by policies in most GNU/Linux distributions (e.g. Debian, Fedora). Manpages can be generated using Sphinx setting the man_pages variable in conf.py (see the Sphinx documentation) and using the command:

python setup.py build_sphinx -b man

GUI should enable quicker download procedure

Currently it's up to the user to figure out when downloading has finished, and clicking on a button to finalize the download process. This sucks.

We already have code that detects automatically when there are no more data waiting, and we should put this to work in the GUI. This is apparently difficult to do with the current code layout, and it may be that breaking the (otherwise elegant) separation of logic and interface makes this easier than it is now.

Probably there should be a background process listening and the interface acting on top of that, be it terminal or graphical.

(see also the related <<issue 18>>)


Display downloaded data in realtime

Currently the GUI gives no feedback during the download, and it's not even capable of automatically telling the user that download is done. This makes for a very bad UX.

A good enhancement would be to display in realtime the downloaded data in the large textarea while they get downloaded. This should be dead easy.


StringIO isn't good for performance

Currently our serial download code uses string concatenation to go over data buffers. This is reported to be quite inefficient if compared to e.g. appending to a list or using a bytearray (python 2.6+):
http://www.dabeaz.com/blog/2010/01/few-useful-bytearray-tricks.html

We should evaluate a possible patch to enhance this code.


Add support for binary Leica XCF / DBX format

Leica 1200 series total stations output a file-based raw data format, that is binary (not ASCII) and is recognizable by the presence of an "index" file with the .XCF extension. Other files in the archive correspond to jobs and have file extensions such as .X01, .X02 and so on.

This is a binary, undocumented file format.

Sample files are attached, graciously provided by Anna Hodgkinson (Anna Hodgkinson) and Hannah Petten.

See also:


upgrade internal data types to support LINESTRING features

Our current internal data type is very basic: a list of tuples. Each tuple is a point with a fixed sequence of elements:

(id, x, y, z, desc)

The most important advantage of changing our internal data types will be to enable recording of not just POINT features, but also LINESTRING (that is, polylines).

Furthermore, we should rely on a solid implementation.

The best option we found is GeoJSON. GeoJSON is a simple-features (OGC) compliant format for geospatial data. The geojson library is the reference implementation in pure Python. We should either use directly the reference implementation as a library or write our own data types modelled on that:

  • Point
  • LineString
  • Feature
  • FeatureCollection

See also the __geo_interface__ protocol (GeoJSON compatible).


parse “corrections” in Nikon RAW data format V2.00

The Nikon RAW data format V2.00 can have “corrections” like this one:

SS,55,1.700,6.718,143.6064,104.5304,15:39:06,P
SS,56,1.700,6.734,138.1288,104.4754,15:39:44,P
CO,HT changed at PT=56 Old HT=1.500m
CO,OLD=56 X-3.787 Y5.548 Z-0.543
CO,HT changed at PT=55 Old HT=1.500m
CO,OLD=55 X-4.239 Y5.190 Z-0.548

It shouldn't be too difficult to parse these data rows. An idea would be to store points in a //dict// instead of a //list//, so they can be retrieved (and sorted) by PID (unique Point ID). In that way, changing a point coordinate would just be a matter of

#!python

points[pid]['ht'] = new_value

I'll see if I can provide a patch.


support input formats with raw measurements (polar coordinates)

A large number of common input formats (among them for example the //Nikon RAW format V2.00//) contain data with polar coordinates (angles and inclined distances with respect to the base measurement point) that need to be processed to obtain Northing-Easting-Elevation or XYZ coordinates.
This issue is vital for TOPS development because until we won't be supporting these formats a large adoption of the program is impossible.


Make totalopenstation a Python package

Currently TOPS is not a Python package. This makes distributing very difficult.

create a simple package layout and move all modules that aren't scripts to the totalopenstation package

fix all relative imports

upload on pypi

Eventually, we should also evaluate the idea of having a //iosa// namespace, like

#!python

import iosa.totalopenstation

Issues connecting to the serial port on Windows

Issues connecting to COM ports under Windows have been reported by some users. This is Windows-specific and it's not directly related to TOPS nor Python, but nevertheless leaves users without a clue on how to download data from their total stations.

First of all, we should write a more detailed documentation to help these users.

Secondly, we should catch the specific exceptions that occur with this kind of problem, and give instructions on workarounds.

Finally, we should investigate if we are able to play with serial ports from within Python to prevent this problem at all.


handle more exceptions in GUI

Currently the Tkinter GUI has some bad behavior because of missing handling of exceptions that could be raised with simple operations like

  • cancel a dialog
  • start a task with empty entries

and so on. All possible exceptions should be handled properly and appropriate error/warning messages should be shown by means of Tkinter dialogs.


Menu command "Process data" is broken, raises TypeError in console

SIlently fails in the GUI, outputs this in the console:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib64/python2.7/lib-tk/Tkinter.py", line 1486, in __call__
    return self.func(*args)
TypeError: process_action() takes exactly 2 arguments (1 given)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.