User Guide#

In this section, we briefly explain usages of jgdtrans. See API Reference for detail.

Install#

You can install jgdtrans from PyPI:

pip install jgdtrans

This package depends on typing-extensions only, and requires Python >=3.9.

Deserialize par File#

jgdtrans supports deserialization of all kind of Gridded Correction Parameter file (we call it as par file after its file extension) which distributed by the GIAJ as of late 2023, such as TKY2JGD, PatchJGD, PatchJGD(H), HyokoRev, SemiDynaEXE and POS2JGD (geonetF3 and ITRF2014). In this section, we show how to load par file, and serialize and deserialize Transformer obj.

We note that none of par files are included in this package, download them from GIAJ [1].

jgdtrans provides read/load APIs of par file load() and loads() which return a Transformer obj. You need to specify the format of the par file by format argument;

>>> import jgdtrans
>>> with open('SemiDyna2023.par') as fp:
...     tf = jgdtrans.load(fp, format='SemiDynaEXE')
>>> tf
Transformer(unit=5, parameter=<dict (21134 length) at 0x123456789>, description='for [...]')

You can access to header, format and parameter of par file by Transformer.description, Transformer.format and Transformer.parameter attributes respectively.

>>> tf.description
'for SemiDynaEXE    Ver.1.0.0\n[...]\nMeshCode dB(sec)  dL(sec) dH(m)'
>>> tf.format
'SemiDynaEXE'
>>> tf.parameter
{
    36230600: Parameter(
        latitude=-0.05475,
        longitude=0.04,
        altitude=0.07721,
    ),
    # and go on
}

Transformer.parameter is :obj:dict obj, its key is meshcode and the value is a Parameter obj. The entry represents one line of par file’s parameter section.

We note that it fills by 0.0 for altitude of TKY2JGD and PathJGD, and for latitude and longitude of PatchJGD(H) and HyokoRev;

>>> with open('TKY2JGD.par') as fp:
...     tf = jgdtrans.load(fp, format='TKY2JGD')
>>> tf.parameter[46303582]
Parameter(latitude=12.79799, longitude=-8.13354, altitude=0.0)

Such a placeholder (0.0) does not break coordinate transformation, because it becomes the identity transformation on the components whose parameter is zero (we show an example below).

Transformer.to_dict() converts the Transformer (namely, contents of par file) to dict obj and from_dict() is a constructor of Transformer from the dict obj;

>>> tf.to_dict()
{
    'description': 'for SemiDynaEXE    Ver.1.0.0\n[...]\nMeshCode dB(sec)  dL(sec) dH(m)',
    'format': 'SemiDynaEXE',
    'parameter': {
        36230600: {
            'latitude': -0.05475,
            'longitude': 0.04,
            'altitude': 0.07721,
        },
        # and go on
    },
}
>>> jgdtrans.from_dict(tf.to_dict())
Transformer(unit=5, parameter=<dict (21134 length) at 0x987654321>, description='my [...]')

Hence, you can convert data of par file to/from python dict or other serialization format (e.g. JSON).

Coordinate Transformation#

In this section, we describe how perform coordinate transformation with Transformer obj.

Transformer.forward() performs forward transformation, and Transformer.backward() does backward one. These return more precise results than the GIAJ web app/APIs.

>>> tf.forward(36.10377479, 140.087855041, 2.34)
Point(latitude=36.103773017086695, longitude=140.08785924333452, altitude=2.4363138578103)
>>> tf.backward(36.103773017086695, 140.08785924333452, 2.4363138578103)
Point(latitude=36.10377479, longitude=140.087855041, altitude=2.34)

The return value is Point obj. You can access by the attribute to the resulting values, latitude, longitude and altitude;

>>> point = tf.forward(36.10377479, 140.087855041, 2.34)
>>> point.latitude
36.103773017086695
>>> point.longitude
140.08785924333452
>>> point.altitude
2.4363138578103

Point obj is unpackable, because Point is Sequence[flaot] with length 3;

>>> origin = Point(36.10377479, 140.087855041, 2.34)
>>> result = tf.forward(*origin)
>>> tf.backward(*result)
Point(latitude=36.10377479000002, longitude=140.087855041, altitude=2.34)

There is Transformer.transform() which switches forward/backward transformation depending on the backward argument. That is, the following identities hold, for all point which is Point obj, such that;

>>> tf.transform(*point, backward=False) == tf.forward(*point)
True
>>> tf.transform(*point, backward=True) == tf.backward(*point)
True

We note that Transformer.backward() is not exact, but Transformer.backward() ensures that the latitude/longitude error from exact solution is suppressed by Transformer.MAX_ERROR. That is, the error from exact solution is less than \(10^{-9}\) [deg], which is error of GIAJ latitude and longitude parameter. This implies that altitude’s error is (practically) less than \(10^{-5}\) [m], which is error of the GIAJ altitude parameter.

Notes, Transformer.backward() is not compatible to GIAJ web service/APIs. We provide a compatible API, Transformer.backward_compat().

If the parameters are zero transformation becomes identity on such components (e.g. altitude of TKY2JGD and PathJGD, and latitude and longitude of PathJGD(H) and HyokoRev). We show an example of TKY2JGD.par.

>>> tf.forward(36.10377479, 140.087855041, 2.34)
Point(latitude=36.106966279935016, longitude=140.08457686562787, altitude=2.34)

It supports DMS notation (sexadecimal degree) for Transformer I/O in addition to DD notation (decimal degree) .

Point has methods handling DMS notation, Point.from_dms() is a constructor from DMS notation and Point.to_dms() returns self in DMS notation;

>>> Point.from_dms("360613.58925", "1400516.27815", 2.34)
Point(36.10377479166667, 140.08785504166664, 2.34)
>>> Point(36.10377479166667, 140.08785504166664, 2.34).to_dms()
("360613.58925", "1400516.27815", 2.34)

By combining these, it can use DMS notation for I/O of Transformer, for example,

>>> point = Point.from_dms("360613.58925", "1400516.27815", 2.34)
>>> tf.forward(*point).to_dms()
("360613.58286751213", "1400516.293278404", 2.4363138577557226)