53
53
54
54
#define USIZE 256
55
55
56
+ #define MATH_PI 3.14159265358979323846
57
+
56
58
// Radius of Earth.
57
59
#define EARTH_RADIUS_X_METERS 6378137
58
60
#define EARTH_RADIUS_Y_METERS 6356752
59
61
60
62
// Circumference of Earth.
61
- #define EARTH_CIRCUMFERENCE_X (EARTH_RADIUS_X_METERS * 2 * _PI )
62
- #define EARTH_CIRCUMFERENCE_Y (EARTH_RADIUS_Y_METERS * 2 * _PI )
63
+ #define EARTH_CIRCUMFERENCE_X (EARTH_RADIUS_X_METERS * 2 * MATH_PI )
64
+ #define EARTH_CIRCUMFERENCE_Y (EARTH_RADIUS_Y_METERS * 2 * MATH_PI )
63
65
64
66
// Meters per degree latitude is fixed. For longitude: use factor * cos(midpoint of two degree latitudes).
65
67
#define METERS_PER_DEGREE_LAT (EARTH_CIRCUMFERENCE_Y / 360.0)
66
68
#define METERS_PER_DEGREE_LON (EARTH_CIRCUMFERENCE_X / 360.0)
67
69
68
- #define _PI 3.14159265358979323846
70
+ #define PARENT_LETTER ( ccode ) ((int) parentletter[ccode])
69
71
70
72
// Legacy buffers: NOT threadsafe!
71
73
static char legacy_asciiBuffer [MAX_MAPCODE_RESULT_LEN ];
@@ -95,7 +97,7 @@ double distanceInMeters(double latDeg1, double lonDeg1, double latDeg2, double l
95
97
}
96
98
{
97
99
const double dy = (latDeg2 - latDeg1 ) * METERS_PER_DEGREE_LAT ;
98
- const double dx = (lonDeg2 - lonDeg1 ) * METERS_PER_DEGREE_LON * cos ((latDeg1 + latDeg2 ) * _PI / 360.0 );
100
+ const double dx = (lonDeg2 - lonDeg1 ) * METERS_PER_DEGREE_LON * cos ((latDeg1 + latDeg2 ) * MATH_PI / 360.0 );
99
101
return sqrt (dx * dx + dy * dy );
100
102
}
101
103
}
@@ -338,14 +340,12 @@ static int lastrec(const int ccode) {
338
340
return data_start [ccode + 1 ] - 1 ;
339
341
}
340
342
341
- #define ParentLetter (ccode ) ((int)parentletter[ccode])
342
-
343
343
// returns parent of ccode, or -1
344
344
static int parentTerritoryOf (const int ccode ) {
345
345
if (ccode < 0 || ccode > ccode_earth ) {
346
346
return -1 ;
347
347
}
348
- return parentnr [ParentLetter (ccode )];
348
+ return parentnr [PARENT_LETTER (ccode )];
349
349
}
350
350
351
351
static int coDex (const int m ) {
@@ -1090,7 +1090,7 @@ static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes,
1090
1090
1091
1091
typedef struct {
1092
1092
// input
1093
- MapcodeElements mapcodeFormat ;
1093
+ MapcodeElements mapcodeElements ;
1094
1094
const char * orginput ; // original full input string
1095
1095
const char * mapcode ; // input mapcode (first character of proper mapcode excluding territory code)
1096
1096
const char * extension ; // input extension (or empty)
@@ -1543,19 +1543,22 @@ static int decoderEngine(decodeRec *dec) {
1543
1543
int ccode ;
1544
1544
int err ;
1545
1545
int codex ;
1546
+ int from ;
1547
+ int upto ;
1548
+ int i ;
1546
1549
char * s ;
1547
1550
1548
- err = parseMapcodeString (& dec -> mapcodeFormat , dec -> orginput , 1 , dec -> context );
1551
+ err = parseMapcodeString (& dec -> mapcodeElements , dec -> orginput , 1 , dec -> context );
1549
1552
if (err ) {
1550
1553
return err ;
1551
1554
}
1552
1555
1553
- ccode = dec -> mapcodeFormat .territoryCode - 1 ;
1556
+ ccode = dec -> mapcodeElements .territoryCode - 1 ;
1554
1557
dec -> context = ccode ;
1555
- dec -> mapcode = dec -> mapcodeFormat .properMapcode ;
1556
- dec -> extension = dec -> mapcodeFormat .precisionExtension ;
1557
- codex = dec -> mapcodeFormat .indexOfDot * 9 + (int ) strlen (dec -> mapcodeFormat .properMapcode ) - 1 ;
1558
- s = dec -> mapcodeFormat .properMapcode ;
1558
+ dec -> mapcode = dec -> mapcodeElements .properMapcode ;
1559
+ dec -> extension = dec -> mapcodeElements .precisionExtension ;
1560
+ codex = dec -> mapcodeElements .indexOfDot * 9 + (int ) strlen (dec -> mapcodeElements .properMapcode ) - 1 ;
1561
+ s = dec -> mapcodeElements .properMapcode ;
1559
1562
1560
1563
if (strchr (s , 'A' ) || strchr (s , 'E' ) || strchr (s , 'U' )) {
1561
1564
if (unpack_if_alldigits (s ) <= 0 ) {
@@ -1574,95 +1577,94 @@ static int decoderEngine(decodeRec *dec) {
1574
1577
}
1575
1578
}
1576
1579
1580
+ if (ccode < 0 ) {
1581
+ return -1 ;
1582
+ }
1583
+ from = firstrec (ccode );
1584
+ upto = lastrec (ccode );
1577
1585
1578
- {
1579
- const int from = firstrec (ccode );
1580
- const int upto = lastrec (ccode );
1581
- int i ;
1582
-
1583
- // try all ccode rectangles to decode s (pointing to first character of proper mapcode)
1584
- for (i = from ; i <= upto ; i ++ ) {
1585
- const int codexi = coDex (i );
1586
- const int r = recType (i );
1587
- if (r == 0 ) {
1588
- if (isNameless (i )) {
1589
- if (((codexi == 21 ) && (codex == 22 )) ||
1590
- ((codexi == 22 ) && (codex == 32 )) ||
1591
- ((codexi == 13 ) && (codex == 23 ))) {
1592
- err = decodeNameless (dec , i );
1593
- break ;
1594
- }
1595
- } else {
1596
- if ((codexi == codex ) || ((codex == 22 ) && (codexi == 21 ))) {
1597
- err = decodeGrid (dec , i , 0 );
1598
-
1599
- // first of all, make sure the zone fits the country
1600
- restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (upto ));
1601
-
1602
- if ((err == 0 ) && isRestricted (i )) {
1603
- int nrZoneOverlaps = 0 ;
1604
- int j ;
1605
-
1606
- // *** make sure decode fits somewhere ***
1607
- dec -> result = getMidPointFractions (& dec -> zone );
1608
- dec -> coord32 = convertFractionsToCoord32 (& dec -> result );
1609
- for (j = i - 1 ; j >= from ; j -- ) { // look in previous rects
1610
- if (!isRestricted (j )) {
1611
- if (fitsInsideBoundaries (& dec -> coord32 , boundaries (j ))) {
1612
- nrZoneOverlaps = 1 ;
1613
- break ;
1614
- }
1586
+ // try all ccode rectangles to decode s (pointing to first character of proper mapcode)
1587
+ for (i = from ; i <= upto ; i ++ ) {
1588
+ const int codexi = coDex (i );
1589
+ const int r = recType (i );
1590
+ if (r == 0 ) {
1591
+ if (isNameless (i )) {
1592
+ if (((codexi == 21 ) && (codex == 22 )) ||
1593
+ ((codexi == 22 ) && (codex == 32 )) ||
1594
+ ((codexi == 13 ) && (codex == 23 ))) {
1595
+ err = decodeNameless (dec , i );
1596
+ break ;
1597
+ }
1598
+ } else {
1599
+ if ((codexi == codex ) || ((codex == 22 ) && (codexi == 21 ))) {
1600
+ err = decodeGrid (dec , i , 0 );
1601
+
1602
+ // first of all, make sure the zone fits the country
1603
+ restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (upto ));
1604
+
1605
+ if ((err == 0 ) && isRestricted (i )) {
1606
+ int nrZoneOverlaps = 0 ;
1607
+ int j ;
1608
+
1609
+ // *** make sure decode fits somewhere ***
1610
+ dec -> result = getMidPointFractions (& dec -> zone );
1611
+ dec -> coord32 = convertFractionsToCoord32 (& dec -> result );
1612
+ for (j = i - 1 ; j >= from ; j -- ) { // look in previous rects
1613
+ if (!isRestricted (j )) {
1614
+ if (fitsInsideBoundaries (& dec -> coord32 , boundaries (j ))) {
1615
+ nrZoneOverlaps = 1 ;
1616
+ break ;
1615
1617
}
1616
1618
}
1619
+ }
1617
1620
1618
- if (!nrZoneOverlaps ) {
1619
- MapcodeZone zfound ;
1620
- Boundaries prevu ;
1621
- for (j = from ; j < i ; j ++ ) { // try all smaller rectangles j
1622
- if (!isRestricted (j )) {
1623
- MapcodeZone z ;
1624
- if (restrictZoneTo (& z , & dec -> zone , boundaries (j ))) {
1625
- nrZoneOverlaps ++ ;
1626
- if (nrZoneOverlaps == 1 ) {
1627
- // first fit! remember...
1628
- zoneCopyFrom (& zfound , & z );
1629
- memcpy (& prevu , boundaries (j ), sizeof (Boundaries ));
1630
- } else { // nrZoneOverlaps >= 2
1631
- // more than one hit
1632
- break ; // give up
1633
- }
1621
+ if (!nrZoneOverlaps ) {
1622
+ MapcodeZone zfound ;
1623
+ Boundaries prevu ;
1624
+ for (j = from ; j < i ; j ++ ) { // try all smaller rectangles j
1625
+ if (!isRestricted (j )) {
1626
+ MapcodeZone z ;
1627
+ if (restrictZoneTo (& z , & dec -> zone , boundaries (j ))) {
1628
+ nrZoneOverlaps ++ ;
1629
+ if (nrZoneOverlaps == 1 ) {
1630
+ // first fit! remember...
1631
+ zoneCopyFrom (& zfound , & z );
1632
+ memcpy (& prevu , boundaries (j ), sizeof (Boundaries ));
1633
+ } else { // nrZoneOverlaps >= 2
1634
+ // more than one hit
1635
+ break ; // give up
1634
1636
}
1635
- } // isRestricted
1636
- } // for j
1637
+ }
1638
+ } // isRestricted
1639
+ } // for j
1637
1640
1638
- // if several sub-areas intersect, just return the whole zone
1639
- // (the center of which may NOT re-encode to the same mapcode!)
1640
- if (nrZoneOverlaps == 1 ) { // found exactly ONE intersection?
1641
- zoneCopyFrom (& dec -> zone , & zfound );
1642
- }
1641
+ // if several sub-areas intersect, just return the whole zone
1642
+ // (the center of which may NOT re-encode to the same mapcode!)
1643
+ if (nrZoneOverlaps == 1 ) { // found exactly ONE intersection?
1644
+ zoneCopyFrom (& dec -> zone , & zfound );
1643
1645
}
1646
+ }
1644
1647
1645
- if (!nrZoneOverlaps ) {
1646
- err = -1234 ;
1647
- }
1648
- } // *** make sure decode fits somewhere ***
1649
- break ;
1650
- }
1651
- }
1652
- } else if (r == 1 ) {
1653
- if (codex == codexi + 10 && headerLetter (i ) == * s ) {
1654
- err = decodeGrid (dec , i , 1 );
1655
- break ;
1656
- }
1657
- } else { //r>1
1658
- if (((codex == 23 ) && (codexi == 22 )) ||
1659
- ((codex == 33 ) && (codexi == 23 ))) {
1660
- err = decodeAutoHeader (dec , i );
1648
+ if (!nrZoneOverlaps ) {
1649
+ err = -1234 ;
1650
+ }
1651
+ } // *** make sure decode fits somewhere ***
1661
1652
break ;
1662
1653
}
1663
1654
}
1664
- } // for
1665
- }
1655
+ } else if (r == 1 ) {
1656
+ if (codex == codexi + 10 && headerLetter (i ) == * s ) {
1657
+ err = decodeGrid (dec , i , 1 );
1658
+ break ;
1659
+ }
1660
+ } else { //r>1
1661
+ if (((codex == 23 ) && (codexi == 22 )) ||
1662
+ ((codex == 33 ) && (codexi == 23 ))) {
1663
+ err = decodeAutoHeader (dec , i );
1664
+ break ;
1665
+ }
1666
+ }
1667
+ } // for
1666
1668
1667
1669
restrictZoneTo (& dec -> zone , & dec -> zone , boundaries (lastrec (ccode )));
1668
1670
@@ -2249,14 +2251,26 @@ int getTerritoryCode(const char *territoryISO, int optionalTerritoryContext) {
2249
2251
} else if (territoryISO [2 ] && territoryISO [3 ] == '-' ) {
2250
2252
return binfindmatch (getParentNumber (territoryISO , 3 ), territoryISO + 4 );
2251
2253
} else {
2252
- const int parentNumber =
2253
- ccode < 0 ? 0 : ((parentnumber [ccode ] > 0 ) ? parentnumber [ccode ] : parentnumber [parentTerritoryOf (
2254
- ccode )]);
2255
- const int b = binfindmatch (parentNumber , territoryISO );
2254
+ int b ;
2255
+ int parentNumber = 0 ;
2256
+ if (ccode >= 0 ) {
2257
+ if (parentnumber [ccode ] > 0 ) {
2258
+ parentNumber = parentnumber [ccode ];
2259
+ } else {
2260
+ int parentTerritory = parentTerritoryOf (ccode );
2261
+ if (parentTerritory >= 0 ) {
2262
+ parentNumber = parentnumber [parentTerritory ];
2263
+ } else {
2264
+ parentNumber = -1 ;
2265
+ }
2266
+
2267
+ }
2268
+ }
2269
+ b = binfindmatch (parentNumber , territoryISO );
2256
2270
if (b > 0 ) {
2257
2271
return b ;
2258
- } //
2259
- } //
2272
+ }
2273
+ }
2260
2274
return binfindmatch (0 , territoryISO );
2261
2275
} // else, fail:
2262
2276
return -1 ;
0 commit comments