Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: TIGER/Line Translator
4 : * Purpose: Implements TigerPolygon, providing access to .RTA files.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Frank Warmerdam
9 : * Copyright (c) 2011, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "ogr_tiger.h"
15 : #include "cpl_conv.h"
16 :
17 : #include <cinttypes>
18 :
19 : static const TigerFieldInfo rtA_2002_fields[] = {
20 : // fieldname fmt type OFTType beg end len bDefine bSet
21 : {"MODULE", ' ', ' ', OFTString, 0, 0, 8, 1, 0},
22 : {"FILE", 'L', 'N', OFTInteger, 6, 10, 5, 1, 1},
23 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 1, 1},
24 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 1, 1},
25 : {"STATECU", 'L', 'N', OFTInteger, 26, 27, 2, 1, 1},
26 : {"COUNTYCU", 'L', 'N', OFTInteger, 28, 30, 3, 1, 1},
27 :
28 : {"TRACT", 'L', 'N', OFTInteger, 31, 36, 6, 1, 1},
29 : {"BLOCK", 'L', 'N', OFTInteger, 37, 40, 4, 1, 1},
30 : {"BLOCKSUFCU", 'L', 'A', OFTString, 41, 41, 1, 1, 1},
31 :
32 : {"RS_A1", 'L', 'A', OFTString, 42, 42, 1, 1, 1},
33 : {"AIANHHFPCU", 'L', 'N', OFTInteger, 43, 47, 5, 1, 1},
34 : {"AIANHHCU", 'L', 'N', OFTInteger, 48, 51, 4, 1, 1},
35 : {"AIHHTLICU", 'L', 'A', OFTString, 52, 52, 1, 1, 1},
36 : {"ANRCCU", 'L', 'N', OFTInteger, 53, 57, 5, 1, 1},
37 : {"AITSCECU", 'L', 'N', OFTInteger, 58, 60, 3, 1, 1},
38 : {"AITSCU", 'L', 'N', OFTInteger, 61, 65, 5, 1, 1},
39 : {"CONCITCU", 'L', 'N', OFTInteger, 66, 70, 5, 1, 1},
40 : {"COUSUBCU", 'L', 'N', OFTInteger, 71, 75, 5, 1, 1},
41 : {"SUBMCDCU", 'L', 'N', OFTInteger, 76, 80, 5, 1, 1},
42 : {"PLACECU", 'L', 'N', OFTInteger, 81, 85, 5, 1, 1},
43 : {"SDELMCU", 'L', 'A', OFTString, 86, 90, 5, 1, 1},
44 : {"SDSECCU", 'L', 'A', OFTString, 91, 95, 5, 1, 1},
45 : {"SDUNICU", 'L', 'A', OFTString, 96, 100, 5, 1, 1},
46 : {"MSACMSACU", 'L', 'N', OFTInteger, 101, 104, 4, 1, 1},
47 : {"PMSACU", 'L', 'N', OFTInteger, 105, 108, 4, 1, 1},
48 : {"NECMACU", 'L', 'N', OFTInteger, 109, 112, 4, 1, 1},
49 : {"CDCU", 'R', 'N', OFTInteger, 113, 114, 2, 1, 1},
50 : {"RS_A2", 'L', 'A', OFTString, 115, 119, 5, 1, 1},
51 : {"RS_A3", 'R', 'A', OFTString, 120, 122, 3, 1, 1},
52 : {"RS_A4", 'R', 'A', OFTString, 123, 128, 6, 1, 1},
53 : {"RS_A5", 'R', 'A', OFTString, 129, 131, 3, 1, 1},
54 : {"RS_A6", 'R', 'A', OFTString, 132, 134, 3, 1, 1},
55 : {"RS_A7", 'R', 'A', OFTString, 135, 139, 5, 1, 1},
56 : {"RS_A8", 'R', 'A', OFTString, 140, 145, 6, 1, 1},
57 : {"RS_A9", 'L', 'A', OFTString, 146, 151, 6, 1, 1},
58 : {"RS_A10", 'L', 'A', OFTString, 152, 157, 6, 1, 1},
59 : {"RS_A11", 'L', 'A', OFTString, 158, 163, 6, 1, 1},
60 : {"RS_A12", 'L', 'A', OFTString, 164, 169, 6, 1, 1},
61 : {"RS_A13", 'L', 'A', OFTString, 170, 175, 6, 1, 1},
62 : {"RS_A14", 'L', 'A', OFTString, 176, 181, 6, 1, 1},
63 : {"RS_A15", 'L', 'A', OFTString, 182, 186, 5, 1, 1},
64 : {"RS_A16", 'L', 'A', OFTString, 187, 187, 1, 1, 1},
65 : {"RS_A17", 'L', 'A', OFTString, 188, 193, 6, 1, 1},
66 : {"RS_A18", 'L', 'A', OFTString, 194, 199, 6, 1, 1},
67 : {"RS_A19", 'L', 'A', OFTString, 200, 210, 11, 1, 1},
68 : };
69 : static const TigerRecordInfo rtA_2002_info = {
70 : rtA_2002_fields, sizeof(rtA_2002_fields) / sizeof(TigerFieldInfo), 210};
71 :
72 : static const TigerFieldInfo rtA_2003_fields[] = {
73 : // fieldname fmt type OFTType beg end len bDefine bSet
74 : {"MODULE", ' ', ' ', OFTString, 0, 0, 8, 1, 0},
75 : {"FILE", 'L', 'N', OFTInteger, 6, 10, 5, 1, 1},
76 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 1, 1},
77 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 1, 1},
78 : {"STATECU", 'L', 'N', OFTInteger, 26, 27, 2, 1, 1},
79 : {"COUNTYCU", 'L', 'N', OFTInteger, 28, 30, 3, 1, 1},
80 :
81 : {"TRACT", 'L', 'N', OFTInteger, 31, 36, 6, 1, 1},
82 : {"BLOCK", 'L', 'N', OFTInteger, 37, 40, 4, 1, 1},
83 : {"BLOCKSUFCU", 'L', 'A', OFTString, 41, 41, 1, 1, 1},
84 :
85 : {"RS_A1", 'L', 'A', OFTString, 42, 42, 1, 1, 1},
86 : {"AIANHHFPCU", 'L', 'N', OFTInteger, 43, 47, 5, 1, 1},
87 : {"AIANHHCU", 'L', 'N', OFTInteger, 48, 51, 4, 1, 1},
88 : {"AIHHTLICU", 'L', 'A', OFTString, 52, 52, 1, 1, 1},
89 : {"ANRCCU", 'L', 'N', OFTInteger, 53, 57, 5, 1, 1},
90 : {"AITSCECU", 'L', 'N', OFTInteger, 58, 60, 3, 1, 1},
91 : {"AITSCU", 'L', 'N', OFTInteger, 61, 65, 5, 1, 1},
92 : {"CONCITCU", 'L', 'N', OFTInteger, 66, 70, 5, 1, 1},
93 : {"COUSUBCU", 'L', 'N', OFTInteger, 71, 75, 5, 1, 1},
94 : {"SUBMCDCU", 'L', 'N', OFTInteger, 76, 80, 5, 1, 1},
95 : {"PLACECU", 'L', 'N', OFTInteger, 81, 85, 5, 1, 1},
96 : {"SDELMCU", 'L', 'A', OFTString, 86, 90, 5, 1, 1},
97 : {"SDSECCU", 'L', 'A', OFTString, 91, 95, 5, 1, 1},
98 : {"SDUNICU", 'L', 'A', OFTString, 96, 100, 5, 1, 1},
99 : {"RS_A20", 'L', 'A', OFTString, 101, 104, 4, 1, 1},
100 : {"RS_A21", 'L', 'A', OFTString, 105, 108, 4, 1, 1},
101 : {"RS_A22", 'L', 'A', OFTString, 109, 112, 4, 1, 1},
102 : {"CDCU", 'R', 'N', OFTInteger, 113, 114, 2, 1, 1},
103 : {"ZCTA5CU", 'L', 'A', OFTString, 115, 119, 5, 1, 1},
104 : {"ZCTA3CU", 'R', 'A', OFTString, 120, 122, 3, 1, 1},
105 : {"RS_A4", 'R', 'A', OFTString, 123, 128, 6, 1, 1},
106 : {"RS_A5", 'R', 'A', OFTString, 129, 131, 3, 1, 1},
107 : {"RS_A6", 'R', 'A', OFTString, 132, 134, 3, 1, 1},
108 : {"RS_A7", 'R', 'A', OFTString, 135, 139, 5, 1, 1},
109 : {"RS_A8", 'R', 'A', OFTString, 140, 145, 6, 1, 1},
110 : {"RS_A9", 'L', 'A', OFTString, 146, 151, 6, 1, 1},
111 : {"CBSACU", 'L', 'A', OFTInteger, 152, 156, 5, 1, 1},
112 : {"CSACU", 'L', 'A', OFTInteger, 157, 159, 3, 1, 1},
113 : {"NECTACU", 'L', 'A', OFTInteger, 160, 164, 5, 1, 1},
114 : {"CNECTACU", 'L', 'A', OFTInteger, 165, 167, 3, 1, 1},
115 : {"METDIVCU", 'L', 'A', OFTInteger, 168, 172, 5, 1, 1},
116 : {"NECTADIVCU", 'L', 'A', OFTInteger, 173, 177, 5, 1, 1},
117 : {"RS_A14", 'L', 'A', OFTString, 178, 181, 4, 1, 1},
118 : {"RS_A15", 'L', 'A', OFTString, 182, 186, 5, 1, 1},
119 : {"RS_A16", 'L', 'A', OFTString, 187, 187, 1, 1, 1},
120 : {"RS_A17", 'L', 'A', OFTString, 188, 193, 6, 1, 1},
121 : {"RS_A18", 'L', 'A', OFTString, 194, 199, 6, 1, 1},
122 : {"RS_A19", 'L', 'A', OFTString, 200, 210, 11, 1, 1},
123 : };
124 : static const TigerRecordInfo rtA_2003_info = {
125 : rtA_2003_fields, sizeof(rtA_2003_fields) / sizeof(TigerFieldInfo), 210};
126 :
127 : static const TigerFieldInfo rtA_2004_fields[] = {
128 : // fieldname fmt type OFTType beg end len bDefine bSet
129 : {"MODULE", ' ', ' ', OFTString, 0, 0, 8, 1, 0},
130 : {"FILE", 'L', 'N', OFTInteger, 6, 10, 5, 1, 1},
131 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 1, 1},
132 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 1, 1},
133 : {"STATECU", 'L', 'N', OFTInteger, 26, 27, 2, 1, 1},
134 : {"COUNTYCU", 'L', 'N', OFTInteger, 28, 30, 3, 1, 1},
135 :
136 : {"TRACT", 'L', 'N', OFTInteger, 31, 36, 6, 1, 1},
137 : {"BLOCK", 'L', 'N', OFTInteger, 37, 40, 4, 1, 1},
138 : {"BLOCKSUFCU", 'L', 'A', OFTString, 41, 41, 1, 1, 1},
139 :
140 : {"RS_A1", 'L', 'A', OFTString, 42, 42, 1, 1, 1},
141 : {"AIANHHFPCU", 'L', 'N', OFTInteger, 43, 47, 5, 1, 1},
142 : {"AIANHHCU", 'L', 'N', OFTInteger, 48, 51, 4, 1, 1},
143 : {"AIHHTLICU", 'L', 'A', OFTString, 52, 52, 1, 1, 1},
144 : {"ANRCCU", 'L', 'N', OFTInteger, 53, 57, 5, 1, 1},
145 : {"AITSCECU", 'L', 'N', OFTInteger, 58, 60, 3, 1, 1},
146 : {"AITSCU", 'L', 'N', OFTInteger, 61, 65, 5, 1, 1},
147 : {"CONCITCU", 'L', 'N', OFTInteger, 66, 70, 5, 1, 1},
148 : {"COUSUBCU", 'L', 'N', OFTInteger, 71, 75, 5, 1, 1},
149 : {"SUBMCDCU", 'L', 'N', OFTInteger, 76, 80, 5, 1, 1},
150 : {"PLACECU", 'L', 'N', OFTInteger, 81, 85, 5, 1, 1},
151 : {"SDELMCU", 'L', 'A', OFTString, 86, 90, 5, 1, 1},
152 : {"SDSECCU", 'L', 'A', OFTString, 91, 95, 5, 1, 1},
153 : {"SDUNICU", 'L', 'A', OFTString, 96, 100, 5, 1, 1},
154 : {"RS_A20", 'L', 'A', OFTString, 101, 104, 4, 1, 1},
155 : {"RS_A21", 'L', 'A', OFTString, 105, 108, 4, 1, 1},
156 : {"RS_A22", 'L', 'A', OFTString, 109, 112, 4, 1, 1},
157 : {"CDCU", 'R', 'N', OFTInteger, 113, 114, 2, 1, 1},
158 : {"ZCTA5CU", 'L', 'A', OFTString, 115, 119, 5, 1, 1},
159 : {"ZCTA3CU", 'R', 'A', OFTString, 120, 122, 3, 1, 1},
160 : {"RS_A4", 'R', 'A', OFTString, 123, 128, 6, 1, 1},
161 : {"RS_A5", 'R', 'A', OFTString, 129, 131, 3, 1, 1},
162 : {"RS_A6", 'R', 'A', OFTString, 132, 134, 3, 1, 1},
163 : {"RS_A7", 'R', 'A', OFTString, 135, 139, 5, 1, 1},
164 : {"RS_A8", 'R', 'A', OFTString, 140, 145, 6, 1, 1},
165 : {"RS_A9", 'L', 'A', OFTString, 146, 151, 6, 1, 1},
166 : {"CBSACU", 'L', 'A', OFTInteger, 152, 156, 5, 1, 1},
167 : {"CSACU", 'L', 'A', OFTInteger, 157, 159, 3, 1, 1},
168 : {"NECTACU", 'L', 'A', OFTInteger, 160, 164, 5, 1, 1},
169 : {"CNECTACU", 'L', 'A', OFTInteger, 165, 167, 3, 1, 1},
170 : {"METDIVCU", 'L', 'A', OFTInteger, 168, 172, 5, 1, 1},
171 : {"NECTADIVCU", 'L', 'A', OFTInteger, 173, 177, 5, 1, 1},
172 : {"RS_A14", 'L', 'A', OFTString, 178, 181, 4, 1, 1},
173 : {"UACU", 'L', 'N', OFTInteger, 182, 186, 5, 1, 1},
174 : {"URCU", 'L', 'A', OFTString, 187, 187, 1, 1, 1},
175 : {"RS_A17", 'L', 'A', OFTString, 188, 193, 6, 1, 1},
176 : {"RS_A18", 'L', 'A', OFTString, 194, 199, 6, 1, 1},
177 : {"RS_A19", 'L', 'A', OFTString, 200, 210, 11, 1, 1},
178 : };
179 : static const TigerRecordInfo rtA_2004_info = {
180 : rtA_2004_fields, sizeof(rtA_2004_fields) / sizeof(TigerFieldInfo), 210};
181 :
182 : static const TigerFieldInfo rtA_fields[] = {
183 : // fieldname fmt type OFTType beg end len bDefine bSet
184 : {"MODULE", ' ', ' ', OFTString, 0, 0, 8, 1, 0},
185 : {"FILE", 'L', 'N', OFTString, 6, 10, 5, 1, 1},
186 : {"STATE", 'L', 'N', OFTInteger, 6, 7, 2, 1, 1},
187 : {"COUNTY", 'L', 'N', OFTInteger, 8, 10, 3, 1, 1},
188 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 1, 1},
189 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 1, 1},
190 : {"FAIR", 'L', 'N', OFTInteger, 26, 30, 5, 1, 1},
191 : {"FMCD", 'L', 'N', OFTInteger, 31, 35, 5, 1, 1},
192 : {"FPL", 'L', 'N', OFTInteger, 36, 40, 5, 1, 1},
193 : {"CTBNA90", 'L', 'N', OFTInteger, 41, 46, 6, 1, 1},
194 : {"BLK90", 'L', 'A', OFTString, 47, 50, 4, 1, 1},
195 : {"CD106", 'L', 'N', OFTInteger, 51, 52, 2, 1, 1},
196 : {"CD108", 'L', 'N', OFTInteger, 53, 54, 2, 1, 1},
197 : {"SDELM", 'L', 'A', OFTString, 55, 59, 5, 1, 1},
198 : {"SDSEC", 'L', 'N', OFTString, 65, 69, 5, 1, 1},
199 : {"SDUNI", 'L', 'A', OFTString, 70, 74, 5, 1, 1},
200 : {"TAZ", 'R', 'A', OFTString, 75, 80, 6, 1, 1},
201 : {"UA", 'L', 'N', OFTInteger, 81, 84, 4, 1, 1},
202 : {"URBFLAG", 'L', 'A', OFTString, 85, 85, 1, 1, 1},
203 : {"CTPP", 'L', 'A', OFTString, 86, 89, 4, 1, 1},
204 : {"STATE90", 'L', 'N', OFTInteger, 90, 91, 2, 1, 1},
205 : {"COUN90", 'L', 'N', OFTInteger, 92, 94, 3, 1, 1},
206 : {"AIR90", 'L', 'N', OFTInteger, 95, 98, 4, 1, 1}};
207 :
208 : static const TigerRecordInfo rtA_info = {
209 : rtA_fields, sizeof(rtA_fields) / sizeof(TigerFieldInfo), 98};
210 :
211 : static const TigerFieldInfo rtS_2002_fields[] = {
212 : // fieldname fmt type OFTType beg end len bDefine bSet
213 : {"FILE", 'L', 'N', OFTInteger, 6, 10, 5, 0, 0},
214 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 0, 0},
215 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 0, 0},
216 : {"STATE", 'L', 'N', OFTInteger, 26, 27, 2, 1, 1},
217 : {"COUNTY", 'L', 'N', OFTInteger, 28, 30, 3, 1, 1},
218 : {"TRACT", 'L', 'N', OFTInteger, 31, 36, 6, 0, 0},
219 : {"BLOCK", 'L', 'N', OFTInteger, 37, 40, 4, 0, 0},
220 : {"BLKGRP", 'L', 'N', OFTInteger, 41, 41, 1, 1, 1},
221 : {"AIANHHFP", 'L', 'N', OFTInteger, 42, 46, 5, 1, 1},
222 : {"AIANHH", 'L', 'N', OFTInteger, 47, 50, 4, 1, 1},
223 : {"AIHHTLI", 'L', 'A', OFTString, 51, 51, 1, 1, 1},
224 : {"ANRC", 'L', 'N', OFTInteger, 52, 56, 5, 1, 1},
225 : {"AITSCE", 'L', 'N', OFTInteger, 57, 59, 3, 1, 1},
226 : {"AITS", 'L', 'N', OFTInteger, 60, 64, 5, 1, 1},
227 : {"CONCIT", 'L', 'N', OFTInteger, 65, 69, 5, 1, 1},
228 : {"COUSUB", 'L', 'N', OFTInteger, 70, 74, 5, 1, 1},
229 : {"SUBMCD", 'L', 'N', OFTInteger, 75, 79, 5, 1, 1},
230 : {"PLACE", 'L', 'N', OFTInteger, 80, 84, 5, 1, 1},
231 : {"SDELM", 'L', 'N', OFTInteger, 85, 89, 5, 1, 1},
232 : {"SDSEC", 'L', 'N', OFTInteger, 90, 94, 5, 1, 1},
233 : {"SDUNI", 'L', 'N', OFTInteger, 95, 99, 5, 1, 1},
234 : {"MSACMSA", 'L', 'N', OFTInteger, 100, 103, 4, 1, 1},
235 : {"PMSA", 'L', 'N', OFTInteger, 104, 107, 4, 1, 1},
236 : {"NECMA", 'L', 'N', OFTInteger, 108, 111, 4, 1, 1},
237 : {"CD106", 'L', 'N', OFTInteger, 112, 113, 2, 1, 1},
238 : // Note: spec has CD106 with 'R', but sample data file (08005) seems to
239 : // have been written with 'L', so I'm using 'L' here. mbp Tue Dec 24
240 : // 19:03:40 2002
241 : {"CD108", 'R', 'N', OFTInteger, 114, 115, 2, 1, 1},
242 : {"PUMA5", 'L', 'N', OFTInteger, 116, 120, 5, 1, 1},
243 : {"PUMA1", 'L', 'N', OFTInteger, 121, 125, 5, 1, 1},
244 : {"ZCTA5", 'L', 'A', OFTString, 126, 130, 5, 1, 1},
245 : {"ZCTA3", 'L', 'A', OFTString, 131, 133, 3, 1, 1},
246 : {"TAZ", 'L', 'A', OFTString, 134, 139, 6, 1, 1},
247 : {"TAZCOMB", 'L', 'A', OFTString, 140, 145, 6, 1, 1},
248 : {"UA", 'L', 'N', OFTInteger, 146, 150, 5, 1, 1},
249 : {"UR", 'L', 'A', OFTString, 151, 151, 1, 1, 1},
250 : {"VTD", 'R', 'A', OFTString, 152, 157, 6, 1, 1},
251 : {"SLDU", 'R', 'A', OFTString, 158, 160, 3, 1, 1},
252 : {"SLDL", 'R', 'A', OFTString, 161, 163, 3, 1, 1},
253 : {"UGA", 'L', 'A', OFTString, 164, 168, 5, 1, 1},
254 : };
255 : static const TigerRecordInfo rtS_2002_info = {
256 : rtS_2002_fields, sizeof(rtS_2002_fields) / sizeof(TigerFieldInfo), 168};
257 :
258 : static const TigerFieldInfo rtS_2000_Redistricting_fields[] = {
259 : {"FILE", 'L', 'N', OFTString, 6, 10, 5, 0, 0},
260 : {"STATE", 'L', 'N', OFTInteger, 6, 7, 2, 0, 0},
261 : {"COUNTY", 'L', 'N', OFTInteger, 8, 10, 3, 0, 0},
262 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 0, 0},
263 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 0, 0},
264 : {"WATER", 'L', 'N', OFTString, 26, 26, 1, 1, 1},
265 : {"CMSAMSA", 'L', 'N', OFTInteger, 27, 30, 4, 1, 1},
266 : {"PMSA", 'L', 'N', OFTInteger, 31, 34, 4, 1, 1},
267 : {"AIANHH", 'L', 'N', OFTInteger, 35, 39, 5, 1, 1},
268 : {"AIR", 'L', 'N', OFTInteger, 40, 43, 4, 1, 1},
269 : {"TRUST", 'L', 'A', OFTString, 44, 44, 1, 1, 1},
270 : {"ANRC", 'L', 'A', OFTInteger, 45, 46, 2, 1, 1},
271 : {"STATECU", 'L', 'N', OFTInteger, 47, 48, 2, 1, 1},
272 : {"COUNTYCU", 'L', 'N', OFTInteger, 49, 51, 3, 1, 1},
273 : {"FCCITY", 'L', 'N', OFTInteger, 52, 56, 5, 1, 1},
274 : {"FMCD", 'L', 'N', OFTInteger, 57, 61, 5, 0, 0},
275 : {"FSMCD", 'L', 'N', OFTInteger, 62, 66, 5, 1, 1},
276 : {"PLACE", 'L', 'N', OFTInteger, 67, 71, 5, 1, 1},
277 : {"CTBNA00", 'L', 'N', OFTInteger, 72, 77, 6, 1, 1},
278 : {"BLK00", 'L', 'N', OFTString, 78, 81, 4, 1, 1},
279 : {"RS10", 'R', 'N', OFTInteger, 82, 82, 0, 0, 1},
280 : {"CDCU", 'L', 'N', OFTInteger, 83, 84, 2, 1, 1},
281 :
282 : {"SLDU", 'R', 'A', OFTString, 85, 87, 3, 1, 1},
283 : {"SLDL", 'R', 'A', OFTString, 88, 90, 3, 1, 1},
284 : {"UGA", 'L', 'A', OFTString, 91, 95, 5, 1, 1},
285 : {"BLKGRP", 'L', 'N', OFTInteger, 96, 96, 1, 1, 1},
286 : {"VTD", 'R', 'A', OFTString, 97, 102, 6, 1, 1},
287 : {"STATECOL", 'L', 'N', OFTInteger, 103, 104, 2, 1, 1},
288 : {"COUNTYCOL", 'L', 'N', OFTInteger, 105, 107, 3, 1, 1},
289 : {"BLOCKCOL", 'R', 'N', OFTInteger, 108, 112, 5, 1, 1},
290 : {"BLKSUFCOL", 'L', 'A', OFTString, 113, 113, 1, 1, 1},
291 : {"ZCTA5", 'L', 'A', OFTString, 114, 118, 5, 1, 1}};
292 :
293 : static const TigerRecordInfo rtS_2000_Redistricting_info = {
294 : rtS_2000_Redistricting_fields,
295 : sizeof(rtS_2000_Redistricting_fields) / sizeof(TigerFieldInfo), 120};
296 :
297 : static const TigerFieldInfo rtS_fields[] = {
298 : {"FILE", 'L', 'N', OFTString, 6, 10, 5, 0, 0},
299 : {"STATE", 'L', 'N', OFTInteger, 6, 7, 2, 0, 0},
300 : {"COUNTY", 'L', 'N', OFTInteger, 8, 10, 3, 0, 0},
301 : {"CENID", 'L', 'A', OFTString, 11, 15, 5, 0, 0},
302 : {"POLYID", 'R', 'N', OFTInteger, 16, 25, 10, 0, 0},
303 :
304 : {"WATER", 'L', 'N', OFTString, 26, 26, 1, 1, 1},
305 : {"CMSAMSA", 'L', 'N', OFTInteger, 27, 30, 4, 1, 1},
306 : {"PMSA", 'L', 'N', OFTInteger, 31, 34, 4, 1, 1},
307 : {"AIANHH", 'L', 'N', OFTInteger, 35, 39, 5, 1, 1},
308 : {"AIR", 'L', 'N', OFTInteger, 40, 43, 4, 1, 1},
309 : {"TRUST", 'L', 'A', OFTString, 44, 44, 1, 1, 1},
310 : {"ANRC", 'L', 'A', OFTInteger, 45, 46, 2, 1, 1},
311 : {"STATECU", 'L', 'N', OFTInteger, 47, 48, 2, 1, 1},
312 : {"COUNTYCU", 'L', 'N', OFTInteger, 49, 51, 3, 1, 1},
313 : {"FCCITY", 'L', 'N', OFTInteger, 52, 56, 5, 1, 1},
314 : {"FMCD", 'L', 'N', OFTInteger, 57, 61, 5, 0, 0},
315 : {"FSMCD", 'L', 'N', OFTInteger, 62, 66, 5, 1, 1},
316 : {"PLACE", 'L', 'N', OFTInteger, 67, 71, 5, 1, 1},
317 : {"CTBNA00", 'L', 'N', OFTInteger, 72, 77, 6, 1, 1},
318 : {"BLK00", 'L', 'N', OFTString, 78, 81, 4, 1, 1},
319 : {"RS10", 'R', 'N', OFTInteger, 82, 82, 0, 0, 1},
320 : {"CDCU", 'L', 'N', OFTInteger, 83, 84, 2, 1, 1},
321 :
322 : {"STSENATE", 'L', 'A', OFTString, 85, 90, 6, 1, 1},
323 : {"STHOUSE", 'L', 'A', OFTString, 91, 96, 6, 1, 1},
324 : {"VTD00", 'L', 'A', OFTString, 97, 102, 6, 1, 1}};
325 : static const TigerRecordInfo rtS_info = {
326 : rtS_fields, sizeof(rtS_fields) / sizeof(TigerFieldInfo), 120};
327 :
328 : /************************************************************************/
329 : /* TigerPolygon() */
330 : /************************************************************************/
331 :
332 0 : TigerPolygon::TigerPolygon(OGRTigerDataSource *poDSIn,
333 0 : const char * /* pszPrototypeModule */)
334 : : psRTAInfo(nullptr), psRTSInfo(nullptr), fpRTS(nullptr), bUsingRTS(true),
335 0 : nRTSRecLen(0)
336 : {
337 0 : poDS = poDSIn;
338 0 : poFeatureDefn = new OGRFeatureDefn("Polygon");
339 0 : poFeatureDefn->Reference();
340 0 : poFeatureDefn->SetGeomType(wkbNone);
341 :
342 0 : if (poDS->GetVersion() >= TIGER_2004)
343 : {
344 0 : psRTAInfo = &rtA_2004_info;
345 : }
346 0 : else if (poDS->GetVersion() >= TIGER_2003)
347 : {
348 0 : psRTAInfo = &rtA_2003_info;
349 : }
350 0 : else if (poDS->GetVersion() >= TIGER_2002)
351 : {
352 0 : psRTAInfo = &rtA_2002_info;
353 : }
354 : else
355 : {
356 0 : psRTAInfo = &rtA_info;
357 : }
358 :
359 0 : if (poDS->GetVersion() >= TIGER_2002)
360 : {
361 0 : psRTSInfo = &rtS_2002_info;
362 : }
363 0 : else if (poDS->GetVersion() >= TIGER_2000_Redistricting)
364 : {
365 0 : psRTSInfo = &rtS_2000_Redistricting_info;
366 : }
367 : else
368 : {
369 0 : psRTSInfo = &rtS_info;
370 : }
371 :
372 : /* -------------------------------------------------------------------- */
373 : /* Fields from type A record. */
374 : /* -------------------------------------------------------------------- */
375 0 : AddFieldDefns(psRTAInfo, poFeatureDefn);
376 :
377 : /* -------------------------------------------------------------------- */
378 : /* Add the RTS records if it is available. */
379 : /* -------------------------------------------------------------------- */
380 0 : if (bUsingRTS)
381 : {
382 0 : AddFieldDefns(psRTSInfo, poFeatureDefn);
383 : }
384 0 : }
385 :
386 : /************************************************************************/
387 : /* ~TigerPolygon() */
388 : /************************************************************************/
389 :
390 0 : TigerPolygon::~TigerPolygon()
391 :
392 : {
393 0 : if (fpRTS != nullptr)
394 0 : VSIFCloseL(fpRTS);
395 0 : }
396 :
397 : /************************************************************************/
398 : /* SetModule() */
399 : /************************************************************************/
400 :
401 0 : bool TigerPolygon::SetModule(const char *pszModuleIn)
402 :
403 : {
404 0 : if (!OpenFile(pszModuleIn, "A"))
405 0 : return false;
406 :
407 0 : EstablishFeatureCount();
408 :
409 : /* -------------------------------------------------------------------- */
410 : /* Open the RTS file */
411 : /* -------------------------------------------------------------------- */
412 0 : if (bUsingRTS)
413 : {
414 0 : if (fpRTS != nullptr)
415 : {
416 0 : VSIFCloseL(fpRTS);
417 0 : fpRTS = nullptr;
418 : }
419 :
420 0 : if (pszModuleIn)
421 : {
422 0 : char *pszFilename = poDS->BuildFilename(pszModuleIn, "S");
423 :
424 0 : fpRTS = VSIFOpenL(pszFilename, "rb");
425 :
426 0 : CPLFree(pszFilename);
427 :
428 0 : nRTSRecLen = EstablishRecordLength(fpRTS);
429 : }
430 : }
431 :
432 0 : return true;
433 : }
434 :
435 : /************************************************************************/
436 : /* GetFeature() */
437 : /************************************************************************/
438 :
439 0 : OGRFeature *TigerPolygon::GetFeature(int nRecordId)
440 :
441 : {
442 : char achRecord[OGR_TIGER_RECBUF_LEN];
443 :
444 0 : if (nRecordId < 0 || nRecordId >= nFeatures)
445 : {
446 0 : CPLError(CE_Failure, CPLE_FileIO,
447 : "Request for out-of-range feature %d of %sA", nRecordId,
448 : pszModule);
449 0 : return nullptr;
450 : }
451 :
452 : /* -------------------------------------------------------------------- */
453 : /* Read the raw record data from the file. */
454 : /* -------------------------------------------------------------------- */
455 0 : if (fpPrimary == nullptr)
456 0 : return nullptr;
457 :
458 0 : if (nRecordLength > static_cast<int>(sizeof(achRecord)))
459 : {
460 0 : CPLError(CE_Failure, CPLE_AppDefined, "Record length too large");
461 0 : return nullptr;
462 : }
463 :
464 : {
465 0 : const auto nOffset = static_cast<uint64_t>(nRecordId) * nRecordLength;
466 0 : if (VSIFSeekL(fpPrimary, nOffset, SEEK_SET) != 0)
467 : {
468 0 : CPLError(CE_Failure, CPLE_FileIO,
469 : "Failed to seek to %" PRIu64 " of %sA", nOffset,
470 : pszModule);
471 0 : return nullptr;
472 : }
473 : }
474 :
475 0 : if (VSIFReadL(achRecord, nRecordLength, 1, fpPrimary) != 1)
476 : {
477 0 : CPLError(CE_Failure, CPLE_FileIO, "Failed to read record %d of %sA",
478 : nRecordId, pszModule);
479 0 : return nullptr;
480 : }
481 :
482 : /* -------------------------------------------------------------------- */
483 : /* Set fields. */
484 : /* -------------------------------------------------------------------- */
485 :
486 0 : OGRFeature *poFeature = new OGRFeature(poFeatureDefn);
487 :
488 0 : SetFields(psRTAInfo, poFeature, achRecord);
489 :
490 : /* -------------------------------------------------------------------- */
491 : /* Read RTS record, and apply fields. */
492 : /* -------------------------------------------------------------------- */
493 :
494 0 : if (fpRTS != nullptr)
495 : {
496 : char achRTSRec[OGR_TIGER_RECBUF_LEN];
497 :
498 : {
499 0 : const auto nOffset = static_cast<uint64_t>(nRecordId) * nRTSRecLen;
500 0 : if (VSIFSeekL(fpRTS, nOffset, SEEK_SET) != 0)
501 : {
502 0 : CPLError(CE_Failure, CPLE_FileIO,
503 : "Failed to seek to %" PRIu64 " of %sS", nOffset,
504 : pszModule);
505 0 : delete poFeature;
506 0 : return nullptr;
507 : }
508 : }
509 :
510 : // Overflow cannot happen since psRTInfo->nRecordLength is unsigned
511 : // char and sizeof(achRecord) == OGR_TIGER_RECBUF_LEN > 255
512 0 : if (VSIFReadL(achRTSRec, psRTSInfo->nRecordLength, 1, fpRTS) != 1)
513 : {
514 0 : CPLError(CE_Failure, CPLE_FileIO, "Failed to read record %d of %sS",
515 : nRecordId, pszModule);
516 0 : delete poFeature;
517 0 : return nullptr;
518 : }
519 :
520 0 : SetFields(psRTSInfo, poFeature, achRTSRec);
521 : }
522 :
523 0 : return poFeature;
524 : }
|