@@ -182,11 +182,14 @@ static int isInRange(int x, const int minx, int const maxx) // returns nonzero i
182
182
return 0 ;
183
183
}
184
184
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 ) {
187
186
return (b -> miny <= coord32 -> lat && coord32 -> lat < b -> maxy && isInRange (coord32 -> lon , b -> minx , b -> maxx ));
188
187
}
189
188
189
+ static int fitsInside (const point32 * coord32 , const int m ) {
190
+ return fitsInsideBoundaries (coord32 ,boundaries (m ));
191
+ }
192
+
190
193
static int xDivider4 (const int miny , const int maxy ) {
191
194
if (miny >= 0 ) { // both above equator? then miny is closest
192
195
return xdivider19 [(miny ) >> 19 ];
@@ -197,6 +200,22 @@ static int xDivider4(const int miny, const int maxy) {
197
200
return xdivider19 [(- maxy ) >> 19 ]; // both negative, so maxy is closest to equator
198
201
}
199
202
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
+
200
219
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
201
220
//
202
221
// Lowlevel ccode, iso, and disambiguation
@@ -1311,7 +1330,8 @@ static void encoderEngine(const int ccode, const encodeRec *enc, const int stop_
1311
1330
from = firstrec (ccode );
1312
1331
upto = lastrec (ccode );
1313
1332
1314
- if (ccode != ccode_earth ) {
1333
+ if (ccode != ccode_earth ) // @@@ why?
1334
+ {
1315
1335
if (!fitsInside (& enc -> coord32 , upto )) {
1316
1336
return ;
1317
1337
}
@@ -1334,9 +1354,7 @@ static void encoderEngine(const int ccode, const encodeRec *enc, const int stop_
1334
1354
else if (recType (i ) > 1 ) {
1335
1355
encodeAutoHeader (result , enc , i , extraDigits );
1336
1356
}
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 )) {
1340
1358
// *** do a recursive call for the parent ***
1341
1359
encoderEngine (ParentTerritoryOf (ccode ), enc , stop_with_one_result , extraDigits , requiredEncoder , ccode );
1342
1360
return ; /**/
@@ -2290,33 +2308,35 @@ double maxErrorInMeters(int extraDigits) {
2290
2308
return maxErrorInMetersForDigits [extraDigits ];
2291
2309
}
2292
2310
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 ) {
2295
2313
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 );
2306
2329
for (m = upto ; m >= from ; m -- ) {
2307
2330
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
+ }
2310
2336
}
2311
2337
}
2312
2338
}
2313
2339
}
2314
2340
}
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 ;
2322
2342
}
0 commit comments