Contributing to Total Open Station

Total Open Station is free software, released under the GNU General Public License v3 or (at your option) any later version.

Development is tracked with git. The main development repository is at GitHub where it’s easy to fork the source code.
Experiments are welcome. Git allows for easy branching: you are encouraged to clone our repository and go crazy with new features, formats.

Coding guidelines

We try to follow as much as possible PEP-8

String formatting

A lot of the functionality of Total Open Station is centered around text manipulation, both when parsing input data and exporting to output formats. For this reason the maintainters decided to standardize on usage of string formatting with the aim of making the code more readable and consistent.

In short:

  • use f-strings everywhere in the totalopenstation package
  • the scripts in the scripts directory are the three user-facing programs that need their messages translated (see translations below): use old-style string formatting (also known as %-formatting or printf-style string formatting) for all string formatting in these scripts
  • do not use the str.format() method

F-strings were introduced in Python 3.6, they are faster than other methods and allow writing code that is both more readable and less verbose. However f-strings are not compatible with gettext, the module used for translation.

Translations

Helping

The main tool we use for translating Total Open Station is Transifex.

We are happy to accept translations for Total Open Station. Translations can be easily submitted and reviewed at our Transifex page. Translators get recognition for their valuable work.

If your native language is missing, why don’t you start translating Total Open Station right now?

Releasing

When the release is approaching and the source strings are not going to change, declare string freeze. Source messages should be updated with one of xgettext, pygettext or Babel (with the extract_messages command), producing totalopenstation.pot, e.g.:

xgettext  scripts/*.py -o locale/totalopenstation.pot

The resulting PO template file mut be uploaded to Transifex for translators to work with:

tx push -s

If there is an existing translation, msgmerge or Babel update_catalog should be used to update.

Translators should be invited to submit new translations, either via .po files or Transifex.

When the translation period is over, pull the updated .po files from Transifex with:

tx pull -r totalopenstation.totalopenstation-app -a

and check that the files are updated. Commit new files separately from updates.

If using Babel, compile the translated messages with:

python setup.py compile_catalog -d locale

Using Total Open Station as a library

All the functionality implemented in Total Open Station can be used 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. It is made with Flask 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

General remarks

Adding a new format

There are hundreds of survey data formats out there. One by one, we will get them added into Total Open Station. Here’s a general process that defines some minimum requirements when implementing new formats as input or output.

Documentation

Always write documentation for the format. Add a new document in the docs/input_formats/ directory or amend the docs/output_formats/of_implemented.rst file of the source tree with a bare description, including:

  • raw (polar) or processed (cartesian) format
  • fixed-position based or fluid – this changes the way the parser should work (input format)
  • which devices, manufacturers or software use this format
  • name of contributors
  • reference to the format if available

Shortcomings of Total Open Station that the format exposes shouldn’t be hidden, but rather made explicit both in code and documentation.

Sample data

Never commit support for a new format without including the relevant sample data in the sample_data directory. Generally speaking, sample data files should follow these simple rules:

  • quality is better than quantity, so prefer a smaller file with many different corner cases rather than a larger file with a bulk of ordinary data
  • multiple files are OK, if they serve the purpose of showing different issues with the format
  • files should be named with the same name of the Python module that implements the format, using a .tops extension, like topcon_gts.tops for a format implemented in a module named topcon_gts.py – this will allow for simple automated tests

Code

When you have fulfilled the two previous tasks, you can start writing code (or at least you should pretend doing that). New code is always better than old code, because you have learned better programming techniques, or because you are more confident with Total Open Station. Writing tests for your code isn’t (yet) required, but it’s highly encouraged. Don’t break current practice.

All code implementing new formats should not break the existing API. Changing the API should be done at the scale of the entire library, to take into account the many different needs of each format and parser. The development of Total Open Station is not in a stable shape, so expect the API to change in future versions. However, please understand that a new format parser is not the right place to do that.

Processing data

Total Open Station use GeoJSON as its internal processing data following the RFC 7946 standard.
The library used to handle this format is PyGeoif.

Thus, all data are build around a formats.Feature class.
To be able to evaluate which type of data a formats.Feature holds, a descriptor has been added as a property.
Those descriptors are:

Descriptor Explanation Construction
PT
Simple point
only coordinates
Feature(point,
        desc='PT',
        id=pid,
        point_name=point_name,
        dist_unit=dist_unit,
        attrib=attrib)
PO
Complexe point
all information needed to compute coordinates
Feature(point,
        desc='PO',
        id=pid,
        point_name=point_name,
        angle_unit=angle_unit,
        z_angle_type=z_angle_type,
        dist_unit=dist_unit,
        dist_type=dist_type,
        azimuth=azimuth,
        angle=angle,
        z_angle=z_angle,
        dist=dist,
        th=th,
        ih=ih,
        ppm=ppl,
        prism_constant=prism_constant,
        station_name=station_name,
        attrib=attrib)
ST Station point data
Feature(point,
        desc='ST',
        id=pid,
        point_name=station_name,
        angle_unit=angle_unit,
        dist_unit=dist_unit,
        ih=ih,
        hz0=hz0,
        attrib=attrib)
BS Backsight information
Feature(point,
        desc='BS',
        id=pid,
        point_name=point_name,
        angle_unit=angle_unit,
        circle=circle)

Types of values passed to the formats.Feature class are :

Feature(Point class,
        desc=str,
        id=int,
        point_name=str,
        angle_unit=str,
        z_angle_type=str,
        dist_unit=str,
        dist_type=str,
        angle=float,
        z_angle=float,
        dist=float,
        th=float,
        ih=float,
        hz0=float,
        circle=float,
        ppm=float,
        prism_constant=float,
        station_name=str,
        attrib=list)

Those values are properties of the formats.Feature class.

Modules

For more in-depth knowledge of classes, we encourage reading the code @ Github.

Releasing a new Total Open Station version

Documentation

The documentation is included in the source tree, and is published online at http://totalopenstation.readthedocs.org/.

Manual pages for the three scripts provided with TOPS are not available at the moment.

Release

The version number is declared in totalopenstation/__init__.py and is propagated in other places from there, including setup.py and the “About” dialog.

A source distribution is made using:

python setup.py sdist

A built distribution is made using (e.g. for Windows installer):

python setup.py bdist --formats wininst

We are currently following the Python Packaging User Guide and distributing sources and wheels.

Windows portable app

A portable Windows app is built with PyInstaller. From the root directory of the source repository of Total Open Station:

` python.exe -m venv pyinst-env source pyinst-env/Scripts/activate pip.exe install -e . pip.exe install PyInstaller pyinstaller.exe totalopenstation-gui.spec `

This will create the file dist/totalopenstation.exe, a portable single-file executable that will run from any compatible Windows system, even from USB sticks

Warning

An executable built on 64 bit systems will not run on 32 bit systems