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