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

🚧 use int for internal coordinate representation and add static function to convert coordinates to int/double and vice versa #320

Closed
wants to merge 9 commits into from

Conversation

rtroilo
Copy link
Member

@rtroilo rtroilo commented Dec 18, 2020

Changes proposed in this pull request:

improve conversion from long coordinate to double coordinate,

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

the current implementation leads to a "not so nice" representation of long value coordinate as a double coordinate

 long l = 1231234567L; // internal long for 123.1234567;
 double d = l * OSHDB.GEOM_PRECISION;
 -> 123.12345669999999

This pull request adds static functions to the OSHDB class

  • coordinateToLong, coordinateToDouble
    which improve the conversion from long value coordinates to double value and vice versa.
  long l = 1231234567L;
  double convertedDouble = OSHDB.coordinateToDouble(l);
  assertEquals(123.1234567, convertedDouble,0.0);

Checklist

@rtroilo rtroilo added bug Something isn't working as expected clean-up code quality Related to our standards for 'good' code labels Dec 18, 2020
@rtroilo rtroilo added this to the release 0.7.0 milestone Dec 18, 2020
@tyrasd tyrasd changed the title add static function to convert coordinates to long/double and versa add static function to convert coordinates to long/double and vice versa Dec 18, 2020
Copy link
Member

@tyrasd tyrasd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few general questions:

  1. why classify this a bug?
  2. does it make sense that these methods live in the OSHDB class? at first glance, it seems like that place looks a bit too prominent?!
  3. basically what the implementation does to avoid rounding errors is to use a floating point division instead of a multiplication. note that divisions are not as fast as multiplications on typical CPUs, so this might come with a small(?) performance overhead. I'd guess that for us it wouldn't make a huge difference, but it would perhaps be nice to verify that by some benchmarking.

oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDB.java Outdated Show resolved Hide resolved
oshdb/src/main/java/org/heigit/ohsome/oshdb/OSHDB.java Outdated Show resolved Hide resolved
oshdb/src/test/java/org/heigit/ohsome/oshdb/OSHDBTest.java Outdated Show resolved Hide resolved
@tyrasd tyrasd force-pushed the more-precise-coordinate-conversion branch from 14819ee to f952994 Compare December 18, 2020 17:29
@rtroilo rtroilo closed this Jan 5, 2021
@rtroilo rtroilo deleted the more-precise-coordinate-conversion branch January 5, 2021 11:48
@tyrasd tyrasd restored the more-precise-coordinate-conversion branch January 5, 2021 16:09
@tyrasd tyrasd reopened this Jan 8, 2021
revert conversation from long to double coordinate, from a division to a multiplication.
Division over multiplication introduces a slightly worse performance, around 1.5 to 2 times slower.
The rounding errors which will occur due the non exact floating point multiplication should be handled in the output methods.
reverting the conversion from long to double back to multiplication over division, makes this test fail, because of the rounding errors from the multiplication.
@rtroilo
Copy link
Member Author

rtroilo commented Jan 12, 2021

  1. does it make sense that these methods live in the OSHDB class? at first glance, it seems like that place looks a bit too prominent?!

According to your question, it makes no sense for you, right? So where do you want to have this methods then?

  1. basically what the implementation does to avoid rounding errors is to use a floating point division instead of a multiplication. note that divisions are not as fast as multiplications on typical CPUs, so this might come with a small(?) performance overhead. I'd guess that for us it wouldn't make a huge difference, but it would perhaps be nice to verify that by some benchmarking.

You are right, the multiplication introduces a slightly worse performance. In this case I undo the conversion, to a multiplication over division. The now introduce rounding errors should be handled in outputing methods e.g.

  System.out.printf("%.7f, %.7f", lon, lat);

or for geometries with a precision model

  Point point = ...;
  var pm = new PrecisionModel(10000000);
  var writer = new WKTWriter();
  writer.setPrecisionModel(pm);
  writer.write(point);

@tyrasd
Copy link
Member

tyrasd commented Jan 12, 2021

does it make sense that these methods live in the OSHDB class? at first glance, it seems like that place looks a bit too prominent?!

According to your question, it makes no sense for you, right? So where do you want to have this methods then?

If you ask me: I'd put it somewhere near where they belong conceptionally. And since the coordinates belong (only) to the OSMNodes it might make sense to add it either to the OSMNode class, or perhaps in a new utility class (OSMNodes?).

@tyrasd tyrasd removed the bug Something isn't working as expected label Jan 12, 2021
@rtroilo
Copy link
Member Author

rtroilo commented Jan 12, 2021

does it make sense that these methods live in the OSHDB class? at first glance, it seems like that place looks a bit too prominent?!

According to your question, it makes no sense for you, right? So where do you want to have this methods then?

If you ask me: I'd put it somewhere near where they belong conceptionally. And since the coordinates belong (only) to the OSMNodes it might make sense to add it either to the OSMNode class, or perhaps in a new utility class (OSMNodes?).

OSHDBBoundingBox also use internally the long coordinate system, and do the long to double conversation.

@tyrasd
Copy link
Member

tyrasd commented Jan 12, 2021

I'd put it somewhere near where they belong conceptionally. And since the coordinates belong (only) to the OSMNodes it might make sense to add it either to the OSMNode class, or perhaps in a new utility class (OSMNodes?).

OSHDBBoundingBox also use internally the long coordinate system, and do the long to double conversation.

True. Then maybe call the utility class Coordinates, EncodedCoordinates or something similar? Do you have any suggestion?

@tyrasd tyrasd removed the clean-up label Jan 28, 2021
@rtroilo rtroilo force-pushed the more-precise-coordinate-conversion branch from 8db7266 to a9e26a4 Compare February 18, 2021 11:03
Copy link
Member

@tyrasd tyrasd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that sometimes we perform Math.round when converting from double to long, and some other times we only cast to (double). Should we be more consistent or does it not matter?

@rtroilo rtroilo mentioned this pull request Apr 29, 2021
6 tasks
@tyrasd
Copy link
Member

tyrasd commented Apr 29, 2021

@rtroilo rtroilo changed the title add static function to convert coordinates to long/double and vice versa 🚧 use int for internal coordinate representation and add static function to convert coordinates to int/double and vice versa Apr 29, 2021
@rtroilo rtroilo mentioned this pull request Jul 13, 2021
5 tasks
@rtroilo rtroilo closed this in #395 Jul 16, 2021
@rtroilo rtroilo deleted the more-precise-coordinate-conversion branch July 16, 2021 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code quality Related to our standards for 'good' code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants