Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: TIGER/Line Translator
4 : * Purpose: Implements TigerAltName, providing access to RT4 files.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Frank Warmerdam
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "ogr_tiger.h"
14 : #include "cpl_conv.h"
15 :
16 : #include <cinttypes>
17 :
18 : static const char FOUR_FILE_CODE[] = "4";
19 :
20 : static const TigerFieldInfo rt4_fields[] = {
21 : // fieldname fmt type OFTType beg end len bDefine bSet
22 : {"MODULE", ' ', ' ', OFTString, 0, 0, 8, 1, 0},
23 : {"TLID", 'R', 'N', OFTInteger, 6, 15, 10, 1, 1},
24 : {"RTSQ", 'R', 'N', OFTInteger, 16, 18, 3, 1, 1},
25 : {"FEAT", ' ', ' ', OFTIntegerList, 0, 0, 8, 1, 0}
26 : // Note: we don't mention the FEAT1, FEAT2, FEAT3, FEAT4, FEAT5 fields
27 : // here because they're handled separately in the code below; they
28 : // correspond
29 : // to the FEAT array field here.
30 : };
31 :
32 : static const TigerRecordInfo rt4_info = {
33 : rt4_fields, sizeof(rt4_fields) / sizeof(TigerFieldInfo), 58};
34 :
35 : /************************************************************************/
36 : /* TigerAltName() */
37 : /************************************************************************/
38 :
39 0 : TigerAltName::TigerAltName(OGRTigerDataSource *poDSIn,
40 0 : CPL_UNUSED const char *pszPrototypeModule)
41 0 : : TigerFileBase(&rt4_info, FOUR_FILE_CODE)
42 : {
43 0 : OGRFieldDefn oField("", OFTInteger);
44 :
45 0 : poDS = poDSIn;
46 0 : poFeatureDefn = new OGRFeatureDefn("AltName");
47 0 : poFeatureDefn->Reference();
48 0 : poFeatureDefn->SetGeomType(wkbNone);
49 :
50 : /* -------------------------------------------------------------------- */
51 : /* Fields from type 4 record. */
52 : /* -------------------------------------------------------------------- */
53 :
54 0 : AddFieldDefns(psRTInfo, poFeatureDefn);
55 0 : }
56 :
57 : /************************************************************************/
58 : /* GetFeature() */
59 : /************************************************************************/
60 :
61 0 : OGRFeature *TigerAltName::GetFeature(int nRecordId)
62 :
63 : {
64 : char achRecord[OGR_TIGER_RECBUF_LEN];
65 :
66 0 : if (nRecordId < 0 || nRecordId >= nFeatures)
67 : {
68 0 : CPLError(CE_Failure, CPLE_FileIO,
69 : "Request for out-of-range feature %d of %s4", nRecordId,
70 : pszModule);
71 0 : return nullptr;
72 : }
73 :
74 : /* -------------------------------------------------------------------- */
75 : /* Read the raw record data from the file. */
76 : /* -------------------------------------------------------------------- */
77 0 : if (fpPrimary == nullptr)
78 0 : return nullptr;
79 :
80 0 : const auto nOffset = static_cast<uint64_t>(nRecordId) * nRecordLength;
81 0 : if (VSIFSeekL(fpPrimary, nOffset, SEEK_SET) != 0)
82 : {
83 0 : CPLError(CE_Failure, CPLE_FileIO,
84 : "Failed to seek to %" PRIu64 " of %s4", nOffset, pszModule);
85 0 : return nullptr;
86 : }
87 :
88 : // Overflow cannot happen since psRTInfo->nRecordLength is unsigned
89 : // char and sizeof(achRecord) == OGR_TIGER_RECBUF_LEN > 255
90 0 : if (VSIFReadL(achRecord, psRTInfo->nRecordLength, 1, fpPrimary) != 1)
91 : {
92 0 : CPLError(CE_Failure, CPLE_FileIO, "Failed to read record %d of %s4",
93 : nRecordId, pszModule);
94 0 : return nullptr;
95 : }
96 :
97 : /* -------------------------------------------------------------------- */
98 : /* Set fields. */
99 : /* -------------------------------------------------------------------- */
100 :
101 0 : OGRFeature *poFeature = new OGRFeature(poFeatureDefn);
102 0 : int anFeatList[5] = {0};
103 0 : int nFeatCount = 0;
104 :
105 0 : SetFields(psRTInfo, poFeature, achRecord);
106 :
107 0 : for (int iFeat = 0; iFeat < 5; iFeat++)
108 : {
109 : const char *pszFieldText =
110 0 : GetField(achRecord, 19 + iFeat * 8, 26 + iFeat * 8);
111 :
112 0 : if (*pszFieldText != '\0')
113 0 : anFeatList[nFeatCount++] = atoi(pszFieldText);
114 : }
115 :
116 0 : poFeature->SetField("FEAT", nFeatCount, anFeatList);
117 :
118 0 : return poFeature;
119 : }
|