@@ -182,11 +182,14 @@ static int isInRange(int x, const int minx, int const maxx) // returns nonzero i
182182 return 0 ;
183183}
184184
185- static int fitsInside (const point32 * coord32 , const int m ) {
186- const mminforec * b = boundaries (m );
185+ static int fitsInsideBoundaries (const point32 * coord32 , const mminforec * b ) {
187186 return (b -> miny <= coord32 -> lat && coord32 -> lat < b -> maxy && isInRange (coord32 -> lon , b -> minx , b -> maxx ));
188187}
189188
189+ static int fitsInside (const point32 * coord32 , const int m ) {
190+ return fitsInsideBoundaries (coord32 ,boundaries (m ));
191+ }
192+
190193static int xDivider4 (const int miny , const int maxy ) {
191194 if (miny >= 0 ) { // both above equator? then miny is closest
192195 return xdivider19 [(miny ) >> 19 ];
@@ -197,6 +200,22 @@ static int xDivider4(const int miny, const int maxy) {
197200 return xdivider19 [(- maxy ) >> 19 ]; // both negative, so maxy is closest to equator
198201}
199202
203+ static mminforec * getExtendedBoundaries (mminforec * target , const mminforec * source , int deltaLat , int deltaLon ) {
204+ target -> miny = source -> miny - deltaLat ;
205+ target -> minx = source -> minx - deltaLon ;
206+ target -> maxy = source -> maxy + deltaLat ;
207+ target -> maxx = source -> maxx + deltaLon ;
208+ return target ;
209+ }
210+
211+ static int isNearBorderOf (const point32 * coord32 , int m ) {
212+ mminforec tmp ;
213+ const mminforec * b = boundaries (m );
214+ int xdiv8 = xDivider4 (b -> miny , b -> maxy ) / 6 ; // should be /8 but there's some extra margin
215+ return (fitsInsideBoundaries (coord32 , getExtendedBoundaries (& tmp ,boundaries (m ),+60 ,+ xdiv8 )) &&
216+ (! fitsInsideBoundaries (coord32 , getExtendedBoundaries (& tmp ,boundaries (m ),-60 ,- xdiv8 ))));
217+ }
218+
200219////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
201220//
202221// Lowlevel ccode, iso, and disambiguation
@@ -1311,7 +1330,8 @@ static void encoderEngine(const int ccode, const encodeRec *enc, const int stop_
13111330 from = firstrec (ccode );
13121331 upto = lastrec (ccode );
13131332
1314- if (ccode != ccode_earth ) {
1333+ if (ccode != ccode_earth ) // @@@ why?
1334+ {
13151335 if (!fitsInside (& enc -> coord32 , upto )) {
13161336 return ;
13171337 }
@@ -1334,9 +1354,7 @@ static void encoderEngine(const int ccode, const encodeRec *enc, const int stop_
13341354 else if (recType (i ) > 1 ) {
13351355 encodeAutoHeader (result , enc , i , extraDigits );
13361356 }
1337- else if (i == upto && isRestricted (i ) &&
1338- isSubdivision (ccode )) // if the last item is a reference to a state's country
1339- {
1357+ else if ((i == upto ) && isSubdivision (ccode )) {
13401358 // *** do a recursive call for the parent ***
13411359 encoderEngine (ParentTerritoryOf (ccode ), enc , stop_with_one_result , extraDigits , requiredEncoder , ccode );
13421360 return ; /**/
@@ -2290,33 +2308,35 @@ double maxErrorInMeters(int extraDigits) {
22902308 return maxErrorInMetersForDigits [extraDigits ];
22912309}
22922310
2293- // returns nonzero if coordinate is inside territory
2294- int isInsideTerritory (double lat , double lon , int territoryCode ) {
2311+ // returns nonzero if coordinate is near more than one territory border
2312+ int multipleBordersNearby (double lat , double lon , int territoryCode ) {
22952313 const int ccode = territoryCode - 1 ;
2296- if ((lat < -90 ) || (lat > 90 ) || (ccode < 0 ) || (ccode > ccode_earth )) {
2297- return 0 ; // invalid arguments!
2298- }
2299- else {
2300- int m ;
2301- point32 coord32 ;
2302- const int from = firstrec (ccode );
2303- const int upto = lastrec (ccode );
2304- convertCoordsToMicrosAndFractions (& coord32 , NULL , NULL , lat , lon );
2305- if (fitsInside (& coord32 , upto )) {
2314+ if ((ccode >= 0 ) && (ccode < ccode_earth )) { // valid territory, not earth
2315+ const int parentTerritoryCode = getParentCountryOf (territoryCode );
2316+ if (parentTerritoryCode >= 0 ) {
2317+ // there is a parent! check its borders as well...
2318+ if (multipleBordersNearby (lat , lon , parentTerritoryCode )) {
2319+ return 1 ;
2320+ }
2321+ }
2322+ {
2323+ int m ;
2324+ int nrFound = 0 ;
2325+ const int from = firstrec (ccode );
2326+ const int upto = lastrec (ccode );
2327+ point32 coord32 ;
2328+ convertCoordsToMicrosAndFractions (& coord32 , NULL , NULL , lat , lon );
23062329 for (m = upto ; m >= from ; m -- ) {
23072330 if (!isRestricted (m )) {
2308- if (fitsInside (& coord32 , m )) {
2309- return 1 ;
2331+ if (isNearBorderOf (& coord32 , m )) {
2332+ nrFound ++ ;
2333+ if (nrFound > 1 ) {
2334+ return 1 ;
2335+ }
23102336 }
23112337 }
23122338 }
23132339 }
23142340 }
2315- return 0 ;
2316- }
2317-
2318- // Check if a point is inside a territory and (if it has a parent) also inside its parent territory
2319- int isFullyInsideTerritory (double lat , double lon , int territoryCode ) {
2320- return (isInsideTerritory (lat , lon , territoryCode ) &&
2321- ((getParentCountryOf (territoryCode ) < 0 ) || isInsideTerritory (lat , lon , getParentCountryOf (territoryCode ))));
2341+ return 0 ;
23222342}
0 commit comments