``upoints``
===========

Modules for working with points on Earth
----------------------------------------

Introduction
------------

``upoints`` is a collection of `GPL v3`_ licensed modules for working
with points on Earth, or other near spherical objects.  It allows you to
calculate the distance and bearings between points, mangle
xearth_/xplanet_ data files, work with online UK trigpoint databases,
NOAA_'s weather station database and other such location databases.

Previous versions of ``upoints`` were called ``earth_distance``, but the
name was changed as it no longer reflected the majority of uses the
packages was targeted at.

Requirements
------------

``upoints`` does not strictly depend on any modules that aren't included
in Python_'s standard library, and as such should run with Python 2.5 or
newer [#]_.  If ``upoints`` doesn't work with the version of Python you
have installed, drop me a mail_ and I'll endeavour to fix it.

However, ``upoints`` can make use of lxml_ if it is installed on systems
that don't have the ``cElementTree`` module.  If neither
``cElementTree`` nor ``lxml`` are installed it falls back to
``ElementTree``, but will operate much slower on XML data.

The modules have been tested on many UNIX-like systems, including Linux,
Solaris and OS X, but it should work fine on other systems too.  The
modules and scripts contain a large collection of ``doctest`` tests that
can be checked with ``./setup test_code``, and the code examples in the
documentation can be tested with ``./setup test_doc``.

.. [#] If you still use Python v2.4 only small changes are required, for
       example to the base class definitions and the unrolling of
       conditional expressions.

.. [#] Some tests may fail due to rounding errors depending on the
       system the tests are being run on, but such instances should be
       obvious even to the casual user and some effort has been put in
       to reduce the likelihood of such failures.

Example
-------

The simplest way to show how ``upoints`` works is by example, and here
goes:

.. code-block:: pycon

    >>> from upoints import point
    >>> Home = point.Point(52.015, -0.221)
    >>> Telford = point.Point(52.6333, -2.5000)
    >>> print("%d kM, with an initial bearing of %d°"
    ...       % (Home.distance(Telford), Home.bearing(Telford)))
    169 kM, with an initial bearing of 294°

All the class definitions, methods and independent functions contain
hopefully useful usage examples in the docstrings.  The ``html/``
directory contains the preprocessed epydoc_ output for reference.

There is some accompanying text and examples for ``point.py``, formerly
``edist.py``, available in `geolocation and path cross`_.  More examples
are available for ``xearth.py`` in `xearth and path cross`_.  Some
background and more examples for ``trigpoints.py`` is online in
`Trigpointing and point.py`_.  Usage examples for ``cities.py`` is
available in `Cities and cities.py`_.  And finally, `Pythons on
a plane`_ contains information on ``weather_stations.py``.  All the
examples in the ``doc/`` directory can be executed using ``./setup.py
test_doc``.

Thanks
------

The following people have submitted patches, testing and feedback:

    * Cédric Dufour - ``edist.py``'s CSV import, and flight plan output
    * Kelly Turner - Xearth_ import idea, and copious testing
    * Simon Woods - Testing

API Stability
-------------

API stability isn't guaranteed across versions, although frivolous
changes won't be made.

When ``upoints`` 1.0 is released the API will be frozen, and any changes
which aren't backwards compatible will force a major version bump.

Limitations
-----------

The modules assume the caller will take care of significant digits, and
output formatting [#]_.  All results are returned with whatever
precision your Python install or system generates; unintuitive float
representation, rounding errors, warts and all.

The reasoning is simple, the caller should always know what is required
and any heuristics added to the code would be just that -- guesses,
which can and will be wrong.

The ``upoints`` modules do not take flattening in to account, as in
calculations based in most populated areas of the earth the errors
introduced by ignoring the earth's flattening are quite small.  Future
versions may change if the limitation becomes an issue in real use.

Although not really a limitation one should also be careful to use
data sources that are based around the same datum, and even within two
data sources that use the same datum you should make sure they use the
same representations.  It isn't unusual to find data sources from the
USA that specify longitudes west of Greenwich as positive for example.

.. [#] A future release may include more standard output definitions,
       but there is no intention to add "magic" data mangling.

Hacking
-------

Patches are most welcome, but I'd appreciate it if you could follow the
guidelines below to make it easier to integrate your changes.  These are
guidelines however, and as such can be broken if the need arises or you
just want to convince me that your style is better.

  * `PEP 8`_, the style guide, should be followed where possible.
  * While support for Python versions prior to v2.5 may be added in the
    future if such a need were to arise, you are encouraged to use v2.5
    features now.
  * All new classes and methods should be accompanied by new
    ``doctest`` examples, and epydoc_'s epytext formatted descriptions if
    at all possible.
  * Tests *must not* span network boundaries, see ``test.mock`` for
    workarounds.
  * ``doctest`` tests in modules are only for unit testing in general,
    and should not rely on any modules that aren't in Python's standard
    library.
  * Functional tests should be in the ``doc`` directory in
    reStructuredText_ formatted files, with actual tests in ``doctest``
    blocks.  Functional tests can depend on external modules, but they
    must be Open Source.

New examples for the ``doc`` directory are as appreciated as code
changes.

Bugs
----

If you find a bug don't hesitate to drop me a mail_ preferably including
a minimal testcase, or even better a patch!

.. _GPL v3: http://www.gnu.org/licenses/
.. _xearth: http://www.cs.colorado.edu/~tuna/xearth/
.. _xplanet: http://xplanet.sourceforge.net/
.. _Python: http://www.python.org/
.. _epydoc: http://epydoc.sourceforge.net/
.. _geolocation and path cross: doc/geolocation_and_pathcross.html
.. _xearth and path cross: doc/xearth_and_pathcross.html
.. _Trigpointing and point.py: doc/trigpointing_and_point_py.html
.. _Cities and cities.py: doc/python_cities.html
.. _Pythons on a plane: doc/pythons_on_a_plane.html
.. _NOAA: http://weather.noaa.gov/
.. _PEP 8: http://www.python.org/dev/peps/pep-0008/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _mail: jnrowe@ukfsn.org
.. _lxml: http://codespeak.net/lxml/

..
    :vim: set ft=rst ts=2 sw=2 et:

