@@ -50,7 +50,7 @@ typedef struct { // point
5050typedef struct {
5151 // input
5252 point32 coord32 ;
53- double fraclat , fraclon ;
53+ double fraclat , fraclon ; // fractions, pre-multiplied into integers
5454 // output
5555 Mapcodes * mapcodes ;
5656} encodeRec ;
@@ -309,17 +309,18 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4
309309 int ydirection ,
310310 const encodeRec * enc ) // append extra characters to result for more precision
311311{
312+ if (extraDigits > 0 ) { // anything to do?
312313 char * s = result + strlen (result );
313- int factorx = MAX_PRECISION_FACTOR * dividerx4 ; // 30^4
314- int factory = MAX_PRECISION_FACTOR * dividery ; // 30^4
315- int valx = (int ) floor ( MAX_PRECISION_FACTOR * ( extrax4 + 4 * enc -> fraclon ));
316- int valy = (int ) floor ( MAX_PRECISION_FACTOR * ( extray + enc -> fraclat * ydirection ));
314+ double factorx = MAX_PRECISION_FACTOR * dividerx4 ; // perfect integer!
315+ double factory = MAX_PRECISION_FACTOR * dividery ; // perfect integer!
316+ double valx = (MAX_PRECISION_FACTOR * extrax4 ) + enc -> fraclon ; // perfect integer!
317+ double valy = (MAX_PRECISION_FACTOR * extray ) + ( ydirection * enc -> fraclat ); // perfect integer!
317318
318319 // protect against floating point errors
319320 if (valx < 0 ) { valx = 0 ; } else if (valx >=factorx ) { valx = factorx - 1 ; }
320321 if (valy < 0 ) { valy = 0 ; } else if (valy >=factory ) { valy = factory - 1 ; }
321322
322- if (extraDigits < 0 ) { extraDigits = 0 ; } else if ( extraDigits > MAX_PRECISION_DIGITS ) {
323+ if (extraDigits > MAX_PRECISION_DIGITS ) {
323324 extraDigits = MAX_PRECISION_DIGITS ;
324325 }
325326
@@ -331,11 +332,11 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4
331332 int gx , gy , column1 , column2 , row1 , row2 ;
332333
333334 factorx /= 30 ;
334- gx = (valx / factorx );
335+ gx = (int )( valx / factorx );
335336 valx -= factorx * gx ;
336337
337338 factory /= 30 ;
338- gy = (valy / factory );
339+ gy = (int )( valy / factory );
339340 valy -= factory * gy ;
340341
341342 column1 = (gx / 6 );
@@ -347,8 +348,9 @@ static void encodeExtension(char *result, int extrax4, int extray, int dividerx4
347348 if (extraDigits -- > 0 ) {
348349 * s ++ = encode_chars [row2 * 6 + column2 ];
349350 }
350- * s = 0 ;
351351 }
352+ * s = 0 ; // terminate the result
353+ }
352354}
353355
354356#define decodeChar (c ) decode_chars[(unsigned char)c] // force c to be in range of the index, between 0 and 255
@@ -388,8 +390,8 @@ static int decodeExtension(decodeRec *dec, int dividerx4, int dividery0, int lon
388390 lat32 = lat32 * 30 + row1 * 5 + row2 ;
389391 }
390392
391- dec -> result .lon = dec -> coord32 .lon + (lon32 * dividerx / processor ) + lon_offset4 / 4.0 ;
392- dec -> result .lat = dec -> coord32 .lat + (lat32 * dividery / processor );
393+ dec -> result .lon = dec -> coord32 .lon + (( lon32 * dividerx ) / processor ) + lon_offset4 / 4.0 ;
394+ dec -> result .lat = dec -> coord32 .lat + (( lat32 * dividery ) / processor );
393395
394396#ifdef FORCE_RECODE
395397 dec -> range_min .lon = dec -> result .lon ;
@@ -1107,7 +1109,7 @@ static void encodeNameless(char *result, const encodeRec *enc, int input_ctry, i
11071109 int v = storage_offset ;
11081110
11091111 int dividerx4 = xDivider4 (b -> miny , b -> maxy ); // *** note: dividerx4 is 4 times too large!
1110- int xFracture = (int ) ( 4 * enc -> fraclon );
1112+ int xFracture = (int )( enc -> fraclon / MAX_PRECISION_FACTOR );
11111113 int dx = (4 * (enc -> coord32 .lon - b -> minx ) + xFracture ) / dividerx4 ; // div with quarters
11121114 int extrax4 = (enc -> coord32 .lon - b -> minx ) * 4 - dx * dividerx4 ; // mod with quarters
11131115
@@ -1524,7 +1526,7 @@ static int decoderEngine(decodeRec *dec) {
15241526 }
15251527 }
15261528#ifdef FORCE_RECODE
1527- if (err == 0 && !fitssomewhere ) {
1529+ if (!fitssomewhere ) {
15281530 for (j = from ; j < i ; j ++ ) { // try all smaller rectangles j
15291531 if (!isRestricted (j )) {
15301532 const mminforec * b = boundaries (j );
@@ -1898,37 +1900,26 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double
18981900 enc .mapcodes = mapcodes ;
18991901 enc .mapcodes -> count = 0 ;
19001902
1901- if (lat < -90 ) { lat = -90 ; } else if (lat > 90 ) { lat = 90 ; }
1902- lat += 90 ; // lat now [0..180]
1903- lon -= (360.0 * floor (lon / 360 )); // lon now in [0..360>
1904-
1905- lat *= 1000000 ;
1906- lon *= 1000000 ;
1907- enc .coord32 .lat = (int ) lat ;
1908- enc .coord32 .lon = (int ) lon ;
1909- enc .fraclat = lat - enc .coord32 .lat ;
1910- enc .fraclon = lon - enc .coord32 .lon ;
19111903 {
19121904 double f ;
1913- // for 8-digit precision, cells are divided into 810,000 by 810,000 minicells.
1914- f = enc .fraclat * MAX_PRECISION_FACTOR ;
1915- if (f < 1 ) { enc .fraclat = 0 ; } else {
1916- if (f >= (MAX_PRECISION_FACTOR - 0.5 )) {
1917- enc .fraclat = 0 ;
1918- enc .coord32 .lat ++ ;
1919- }
1920- }
1921- f = enc .fraclon * MAX_PRECISION_FACTOR ;
1922- if (f < 1 ) { enc .fraclon = 0 ; } else {
1923- if (f >= (MAX_PRECISION_FACTOR - 0.5 )) {
1924- enc .fraclon = 0 ;
1925- enc .coord32 .lon ++ ;
1926- }
1927- }
1905+ if (lat < -90 ) { lat = -90 ; } else if (lat > 90 ) { lat = 90 ; }
1906+ lat += 90 ; // lat now [0..180]
1907+ lat *= (double ) 810000000000 ;
1908+ enc .fraclat = floor (lat + 0.1 );
1909+ f = enc .fraclat / (double ) 810000 ;
1910+ enc .coord32 .lat = (int )f ;
1911+ enc .fraclat -= (double )enc .coord32 .lat * (double ) 810000 ;
1912+ enc .coord32 .lat -= 90000000 ;
1913+
1914+ lon -= (360.0 * floor (lon / 360 )); // lon now in [0..360>
1915+ lon *= (double )3240000000000 ;
1916+ enc .fraclon = floor (lon + 0.1 );
1917+ f = enc .fraclon / (double )3240000 ;
1918+ enc .coord32 .lon = (int )f ;
1919+ enc .fraclon -= (double )enc .coord32 .lon * (double )3240000 ;
1920+ if (enc .coord32 .lon >= 180000000 )
1921+ enc .coord32 .lon -= 360000000 ;
19281922 }
1929- enc .coord32 .lat -= 90000000 ;
1930- if (enc .coord32 .lon >= 180000000 )
1931- enc .coord32 .lon -= 360000000 ;
19321923
19331924 if (tc <= 0 ) // ALL results?
19341925 {
0 commit comments