Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store latitude in 3.5 bytes

I know that title sounds little bit weird but it's extremely important to compact our message into 16 bytes. However, whole data is 17. The only possible solution that I can think of is to try to save one byte putting coordinates into 7 bytes instead of 8.

Requirement for coordinates is to store value with 5 decimal places as the very minimum, e.g., 0.00001.

Say we have 3.5 bytes (28 bits). One bit will be used for sign, another 4 for scale, 2 for exponent and 21 bits for decimal points which are 2097152 of unique values which is enough to store 6 decimal places even.

My question is how can I convert 4 byte float to 3.5 byte float in C/Java? Can you refer me to existing solutions for "fine-tuning" floats like this where I can define all the components of float number? Thanks.

like image 248
ruruskyi Avatar asked Mar 20 '14 15:03

ruruskyi


People also ask

How many bytes can you store latitude and longitude?

latitude : 4-Byte Floating Point Number Specifies the geographic latitude of the location. longitude : 4-Byte Floating Point Number Specifies the geographic longitude of the location.

What data type is latitude?

precision you should use DECIMAL . Latitudes range from -90 to +90 (degrees), so DECIMAL(10,8) is ok for that, but longitudes range from -180 to +180 (degrees) so you need DECIMAL(11,8) . The first number is the total number of digits stored, and the second is the number after the decimal point.

How do you store latitude and longitude in a database?

Storing Latitude & Longitude data as Floats or Decimal This is one of the most fundamental ways of storing geocoordinate data. Latitude & longitude values can be represented & stored in a SQL database using decimal points (Decimal degrees) rather than degrees (or Degrees Minutes Seconds).

What is the data type for GPS?

The latitude/longitude coordinates generated by the GPS are considered the standard for location data. Your device receives signals from the satellites and it can calculate where it is by measuring the time it takes for the signal to arrive.


1 Answers

My first choice in this case wouldn't be a strange 3.5 byte "float" but to pack it into an integer. Assuming your latitude range is -90 to 90 and longitude from -180 to 180 it would look something like this (Cish code, untested):

 float latitude = 45.12345
 float longitude = 110.12345

 unsigned int packedLatitude  = (latitude + 90) * 100000     //25 bits
 unsigned int packedLongitude = (longitude + 180) * 100000   //26 bits

 float unpackedLatitude  = packedLatitude / 100000.0f - 90.0f
 float unpackedLongitude = packedLongitude / 100000.0f - 180.0f 

This gives you your coordinate in 6.4 bytes. All that is left is to pack these 6.4 bytes into your 16-18 byte structure which I assume you already know how to do (it depends on what you're packing it into and where).

Note there are a few gotchas with this method you need to be aware of. The lower limits (-90 and -180) are hard limits and if exceeded your unpacked coordinates won't be correct. Your upper limits have a little give: latitude can go to 245, longitude to 491 but you probably should make sure they are normalized to -90-90/-180-180. If it matters you should also be aware of how you are rounding or truncating extra digits below 0.00001 (I believe this method truncates them).

like image 200
uesp Avatar answered Sep 22 '22 16:09

uesp