yakra / tmtools

Tools to aid in development of the TravelMapping project
0 stars 0 forks source link

GISplunge: KeyValue not found #9

Closed yakra closed 6 years ago

yakra commented 6 years ago

Sometimes perfectly valid KeyValues are not found. Most often observed with ADRANGENID in GeoBase files - I don't ever recall this working. Also observed with RTE_UNIQ_I (left-justified Numeric) in txdot-2015-roadways_48113

gisplunge02.cpp, in ProcRte(), line 645:

if (!KeyFound)
{   cout << KeyValue << " not found!" << endl;
    cout << "Skipping this file." << endl << endl;
    return 2;
}

...because KeyFound is never set to 1 in if (KeyMatch(KeyValue, DBFname, DBF.tellg())) starting on line 569.


No leads as to what's causing this yet. The most immediate thing I see is the RecordNum issue (#8) starting right away @ line 570. I doubt this is related, but it may be worth tackling first, as it's something that I have seen; see if anything changes afterwards...

yakra commented 6 years ago

May be related after all -- see https://github.com/yakra/tmtools/issues/8#issuecomment-345044423

yakra commented 6 years ago

Not related.

yakra commented 6 years ago
ShapeRoot /home/yakra/gis/data/tx/txdot-roads_48113/txdot-2015-roadways_48113
KeyField RTE_UNIQ_I
KeyValue 211311

ProcRte 566 DBF.seekg(HeaderLength + KeyOffset + 1); --> DBF.seekg(577 + 79 + 1); --> DBF.seekg(657); 569 if (KeyMatch(KeyValue, DBFname, DBF.tellg())) --> if (KeyMatch("211311", DBFname, 657))

KeyMatch 515 for (int index = 0; index < strlen(KeyValue); index++) --> for (int index = 0; index < strlen("211311"); index++) --> for (int index = 0; index < 6; index++) 516 if (file.get() != *(KeyValue+index)) --> if (file.get() != *KeyValue) --> if ('5' != '2') 518 return 0;

ProcRte 569 KeyMatch("211311", DBFname, 657) == 0; 643 DBF.seekg(RecordLength, ios::cur); --> DBF.seekg(199, ios::cur); --> DBF.seekg(856); ... DBF.seekg(1055); ... DBF.seekg(714868); 569 if (KeyMatch(KeyValue, DBFname, DBF.tellg())) --> if (KeyMatch("211311", DBFname, 714868))

KeyMatch // "211311" matches, followed by 'K' 521 if (file.get() > 0x20) return 0; --> if ('K' > 0x20) return 0; --> if (0x4B > 0x20) return 0; --> return 0;

BOOM! This explains... • why NID works: it's followed by a numeric field, padded left with 0x20. • why ADRANGENID doesn't: it's followed by a character field, no padding.

The solution would be something like 521 if (file.get() > 0x20 && strlen(KeyValue) < FieldLength) return 0; Declare in main, pass by reference to DBFheader instead of declaring it there, pass between a few more functions to get it to KeyMatch, and presto!