@@ -81,9 +81,25 @@ int isEmpty(const MapcodeZone *z) {
8181 return ((z -> fmaxx <= z -> fminx ) || (z -> fmaxy <= z -> fminy ));
8282}
8383
84- void getMidPoint (point * p , MapcodeZone * z ) {
85- p -> lon = (z -> fminx + z -> fmaxx ) / (2 * MICROLON_TO_FRACTIONS_FACTOR );
86- p -> lat = (z -> fminy + z -> fmaxy ) / (2 * MICROLAT_TO_FRACTIONS_FACTOR );
84+ point getMidPointFractions (MapcodeZone * z ) {
85+ point p ;
86+ p .lon = floor ((z -> fminx + z -> fmaxx ) / 2 );
87+ p .lat = floor ((z -> fminy + z -> fmaxy ) / 2 );
88+ return p ;
89+ }
90+
91+ point32 convertFractionsToCoord32 (const point * p ) {
92+ point32 p32 ;
93+ p32 .lat = (int ) floor (p -> lat / 810000 );
94+ p32 .lon = (int ) floor (p -> lon / 3240000 );
95+ return p32 ;
96+ }
97+
98+ point convertFractionsToDegrees (const point * p ) {
99+ point pd ;
100+ pd .lat = p -> lat / ( 810000 * 1000000.0 );
101+ pd .lon = p -> lon / (3240000 * 1000000.0 );
102+ return pd ;
87103}
88104
89105void zoneCopyFrom (MapcodeZone * target , const MapcodeZone * source ) {
@@ -211,7 +227,7 @@ static mminforec *getExtendedBoundaries(mminforec *target, const mminforec *sour
211227static int isNearBorderOf (const point32 * coord32 , int m ) {
212228 mminforec tmp ;
213229 const mminforec * b = boundaries (m );
214- int xdiv8 = xDivider4 (b -> miny , b -> maxy ) / 6 ; // should be /8 but there's some extra margin
230+ int xdiv8 = xDivider4 (b -> miny , b -> maxy ) / 4 ; // should be /8 but there's some extra margin
215231 return (fitsInsideBoundaries (coord32 , getExtendedBoundaries (& tmp ,boundaries (m ),+60 ,+ xdiv8 )) &&
216232 (! fitsInsideBoundaries (coord32 , getExtendedBoundaries (& tmp ,boundaries (m ),-60 ,- xdiv8 ))));
217233}
@@ -1330,8 +1346,7 @@ static void encoderEngine(const int ccode, const encodeRec *enc, const int stop_
13301346 from = firstrec (ccode );
13311347 upto = lastrec (ccode );
13321348
1333- if (ccode != ccode_earth ) // @@@ why?
1334- {
1349+ if (ccode != ccode_earth ) {
13351350 if (!fitsInside (& enc -> coord32 , upto )) {
13361351 return ;
13371352 }
@@ -1569,20 +1584,19 @@ static int decoderEngine(decodeRec *dec) {
15691584 err = decodeGrid (dec , i , 0 );
15701585
15711586 // first of all, make sure the zone fits the country
1572- if (err == 0 ) {
1587+ if (( err == 0 ) && ( ccode != ccode_earth ) ) {
15731588 if (!restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (upto ))) {
15741589 err = -2999 ;
15751590 }
15761591 }
15771592
1578- if (err == 0 && isRestricted (i )) {
1593+ if (( err == 0 ) && isRestricted (i )) {
15791594 int nrZoneOverlaps = 0 ;
15801595 int j ;
15811596
15821597 // *** make sure decode fits somewhere ***
1583- getMidPoint (& dec -> result ,& dec -> zone );
1584- dec -> coord32 .lon = (int ) floor (dec -> result .lon );
1585- dec -> coord32 .lat = (int ) floor (dec -> result .lat );
1598+ dec -> result = getMidPointFractions (& dec -> zone );
1599+ dec -> coord32 = convertFractionsToCoord32 (& dec -> result );
15861600 for (j = i - 1 ; j >= from ; j -- ) { // look in previous rects
15871601 if (!isRestricted (j )) {
15881602 if (fitsInside (& dec -> coord32 , j )) {
@@ -1607,9 +1621,9 @@ static int decoderEngine(decodeRec *dec) {
16071621 prevj = j ;
16081622 memcpy (& prevu ,boundaries (j ),sizeof (mminforec ));
16091623 }
1610- else { // nrZoneOverlaps >= 2
1624+ else { // nrZoneOverlaps >= 2
16111625 // more than one hit
1612- break ; // GIVE UP!
1626+ break ; // give up
16131627 }
16141628 }
16151629 } // isRestricted
@@ -1645,33 +1659,29 @@ static int decoderEngine(decodeRec *dec) {
16451659 } // for
16461660 }
16471661
1662+ if (ccode != ccode_earth ) {
1663+ restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (lastrec (ccode )));
1664+ }
1665+
1666+ if (isEmpty (& dec -> zone )) {
1667+ err = -2222 ;
1668+ }
1669+
16481670 if (err ) {
16491671 dec -> result .lat = dec -> result .lon = 0 ;
1672+ return err ;
16501673 }
1651- else {
16521674
1653- if (ccode == ccode_earth ) {
1654- getMidPoint (& dec -> result ,& dec -> zone );
1655- }
1656- else {
1657- if (!restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (lastrec (ccode )))) {
1658- return -2222 ;
1659- }
1660- getMidPoint (& dec -> result ,& dec -> zone );
1661- }
1675+ dec -> result = getMidPointFractions (& dec -> zone );
1676+ dec -> result = convertFractionsToDegrees (& dec -> result );
16621677
1663- // normalise between =180 and 180
1664- if (dec -> result .lat < -90000000 .0 ) { dec -> result .lat = -90000000 .0 ; }
1665- if (dec -> result .lat > 90000000 .0 ) { dec -> result .lat = 90000000 .0 ; }
1666- if (dec -> result .lon < -180000000 .0 ) { dec -> result .lon += 360000000 .0 ; }
1667- if (dec -> result .lon >= 180000000 .0 ) { dec -> result .lon -= 360000000 .0 ; }
1678+ // normalise between =180 and 180
1679+ if (dec -> result .lat < -90 .0 ) { dec -> result .lat = -90 .0 ; }
1680+ if (dec -> result .lat > 90 .0 ) { dec -> result .lat = 90 .0 ; }
1681+ if (dec -> result .lon < -180 .0 ) { dec -> result .lon += 360 .0 ; }
1682+ if (dec -> result .lon >= 180 .0 ) { dec -> result .lon -= 360 .0 ; }
16681683
1669- // convert from microdegrees to degrees
1670- dec -> result .lat /= (double ) 1000000.0 ;
1671- dec -> result .lon /= (double ) 1000000.0 ;
1672- }
1673-
1674- return err ;
1684+ return 0 ;
16751685}
16761686
16771687
@@ -2156,7 +2166,6 @@ int convertTerritoryIsoNameToCode(const char *string, int optional_tc) // option
21562166#endif
21572167}
21582168
2159-
21602169// decode string into lat,lon; returns negative in case of error
21612170int decodeMapcodeToLatLon (double * lat , double * lon , const char * input ,
21622171 int context_tc ) // context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available
0 commit comments