Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-ideal bearing and DNP, and wrong offset calculations #9

Open
prayerful007 opened this issue Sep 10, 2020 · 4 comments
Open

Non-ideal bearing and DNP, and wrong offset calculations #9

prayerful007 opened this issue Sep 10, 2020 · 4 comments

Comments

@prayerful007
Copy link

prayerful007 commented Sep 10, 2020

Hi, I have realized that you have calculated bearing and DNP non-ideally, and offsets wrongly.

You have treated all the 'bands' as precise numbers by adding 0.5, which is not ideal, as the band was there to allow buffering when mapping the OpenLR code to a map, where the target map may differ from the source map (which the OpenLR codes were encoded from).

Below are calculations by decoding "CwEbJx48NiKaN/J7BMIibQEC"
For example, a DNP is stored by 8 bits, so a total of 256 bands are available for the defined max length 15,000 meters. Hence each band is 15000/256 = 58.59375 meters.
The DNP byte of this OpenLR is "0b00110111" (55th band), is actually a distance between 58.59375 * 55 and 58.59375 * 56, which is >=3222 m and < 3281 m (rounded)
You gave a precise middle number 58.59375 * (55 +0.5 ) = 3252 m.
This 3252 m is the middle between 3222 and 3281, which is not ideal.

Moreover, this approach should not be applied to the calculation of the offsets.
Offsets are not 'bands', they are the actual fraction of the referred road distance, stored in 8 bits.
So you should not add 0.5 to the offset fraction
Furthermore, you used the higher value of the distance band in your calculation, making the result wrong.

The negative offset coefficient is stored as 2 (0b00000010), which is the fraction of the total distance = 2/256 = 0.0078125,
The correct negative offset is a distance between 0.0078125 * 3222 and 0.0078125 * 3281, which is >= 25.17 m and <25.63 m
By using your calculation, you used: (2 +0.5 )/256 * 3281 = 32 m, which is wrong.

The correct positive offset is a distance between 0.00390625 * 3222 and 0.00390625 * 3281, which is >= 12.59 m and <12.81 m
Your result is 19 m, which is wrong.

@aksakalli
Copy link
Collaborator

aksakalli commented Sep 16, 2020

Hi, Indeed DNP is not scalar value but a range. I find adding 0.5 to the index not so intuitive as well. To be honest, the python implementation and all the test cases are following the reference java implementation. Do you think CwEbJx48NiKaN/J7BMIibQEC gives different value than the reference implementation? If not we better inform the reference implementation project with this issue.

@guyanf
Copy link
Contributor

guyanf commented Jul 15, 2021

Hi

May be adding 0.5 is not the best way. but it is appropriate now.

Sometimes the dnp is very small, may be only 20 meters(inner arc of road cross), then the dnp will differ greatly.
I don't have a good idea.

@prayerful007
Copy link
Author

Hi,
Yes I think adding 0.5 to the band number is appropriate for now.
In this case: "CwEbJx48NiKaN/J7BMIibQEC", DNP is in band 55 and 56 (>=3222 m and < 3281 m (rounded))
The middle number between 3222 and 3281 is 58.59375 * (55 +0.5 ) = 3252 m.

--- However the offset is wrong ---
The offset should be the middle number multiplied by the offset coefficient.
Pos offset coefficient = 2
=> Pos offset = 2/256 * 3252 = 25.41 m.
Neg offset coefficient = 1
=> Neg offset = 1/256 * 3252 = 12.7 m.

The offset coefficient cannot add 0.5
(2 +0.5 )/256 * 3281 = 32 m, is wrong.

@davidniedzielski-tomtom

Offsets are not 'bands', they are the actual fraction of the referred road distance, stored in 8 bits.

That is not correct. In the binary representation, offsets are intervals because of the floor function in Eq 8 on page 52 of the OpenLR white paper. One cannot represent an arbitrary floating point ratio of the offset to the LRP->LRP path length (both of which are known to the encoder) using eight bits. The true offset is first divided by the actual path length and then scaled by 256. The floor function is applied to this result to obtain a value representable in 8 bits (and accuracy is therefore lost). Figure 22 on the aforementioned page illustrates how the length of the offset intervals varies according to the inter-LRP length.

Using your example, the encoded value of negative offset in "CwEbJx48NiKaN/J7BMIibQEC" is 2, while the encoded DNP is 55 (as you correctly noted). Thus, the decoder knows only that the true DNP is greater than or equal to 55 * (15000/256) ~= 3222.7 and strictly less than 56 * (15000/256) ~= 3281.25. The midpoint of that interval is approximately 3251.95 ~= 3252.

Therefore, the actual negative offset could be as small as 25.177 ~= (2 * 3222.7) / 256 and as large as (but less than) 38.452 ~= (3 * 3281.25) / 256. All values in that range are equally likely to be the true offset. The midpoint of that interval is 31.81464 ~= 32, as reported. We can also arrive at the same value by a simpler route, namely by using 3252 as the midpoint of the DNP interval and 2.5 as the midpoint of the offset interval, as follows:

( 2.5 * 3252 ) / 256 ~= 31.75781 ~= 32 (difference due to rounding)

That is the value reported by the code. Similarly, the positive offset is encoded as 1, meaning that the offset is greater than or equal to 12.588 ~= (1 * 3222.7) / 256 and strictly less than 25.177 ~= (2 * 3222.7) / 256, and midpoint of that interval is 18.883 ~= 12.588 + ((25.177 - 12.588) / 2) ~= 19, which is what the tool reports. The simplified version of the above is:

(1.5 * 3252) / 256 ~= 19.054 ~= 19 (difference due to rounding)

Similar reasoning applies to the bearing calculation.

It seems the real issue is representing these intervals as scalar values. That could mask the ambiguity that is inherent in the binary encoding, which is willing to sacrifice accuracy for terseness (unlike the XML representation). Perhaps a suitable (and backwards-compatible) approach is to add a "tolerance" or "margin-of-error" field to each value affected by the intervals, whose units would be meters for DNP and offsets, and degrees for bearing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants