/src/gdal/ogr/ogrsf_frmts/tiger/tigerpolygon.cpp
Line | Count | Source |
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 | | TigerPolygon::TigerPolygon(OGRTigerDataSource *poDSIn, |
333 | | const char * /* pszPrototypeModule */) |
334 | 150 | : psRTAInfo(nullptr), psRTSInfo(nullptr), fpRTS(nullptr), bUsingRTS(true), |
335 | 150 | nRTSRecLen(0) |
336 | 150 | { |
337 | 150 | poDS = poDSIn; |
338 | 150 | poFeatureDefn = new OGRFeatureDefn("Polygon"); |
339 | 150 | poFeatureDefn->Reference(); |
340 | 150 | poFeatureDefn->SetGeomType(wkbNone); |
341 | | |
342 | 150 | if (poDS->GetVersion() >= TIGER_2004) |
343 | 141 | { |
344 | 141 | psRTAInfo = &rtA_2004_info; |
345 | 141 | } |
346 | 9 | else if (poDS->GetVersion() >= TIGER_2003) |
347 | 0 | { |
348 | 0 | psRTAInfo = &rtA_2003_info; |
349 | 0 | } |
350 | 9 | else if (poDS->GetVersion() >= TIGER_2002) |
351 | 0 | { |
352 | 0 | psRTAInfo = &rtA_2002_info; |
353 | 0 | } |
354 | 9 | else |
355 | 9 | { |
356 | 9 | psRTAInfo = &rtA_info; |
357 | 9 | } |
358 | | |
359 | 150 | if (poDS->GetVersion() >= TIGER_2002) |
360 | 141 | { |
361 | 141 | psRTSInfo = &rtS_2002_info; |
362 | 141 | } |
363 | 9 | else if (poDS->GetVersion() >= TIGER_2000_Redistricting) |
364 | 6 | { |
365 | 6 | psRTSInfo = &rtS_2000_Redistricting_info; |
366 | 6 | } |
367 | 3 | else |
368 | 3 | { |
369 | 3 | psRTSInfo = &rtS_info; |
370 | 3 | } |
371 | | |
372 | | /* -------------------------------------------------------------------- */ |
373 | | /* Fields from type A record. */ |
374 | | /* -------------------------------------------------------------------- */ |
375 | 150 | AddFieldDefns(psRTAInfo, poFeatureDefn); |
376 | | |
377 | | /* -------------------------------------------------------------------- */ |
378 | | /* Add the RTS records if it is available. */ |
379 | | /* -------------------------------------------------------------------- */ |
380 | 150 | if (bUsingRTS) |
381 | 150 | { |
382 | 150 | AddFieldDefns(psRTSInfo, poFeatureDefn); |
383 | 150 | } |
384 | 150 | } |
385 | | |
386 | | /************************************************************************/ |
387 | | /* ~TigerPolygon() */ |
388 | | /************************************************************************/ |
389 | | |
390 | | TigerPolygon::~TigerPolygon() |
391 | | |
392 | 150 | { |
393 | 150 | if (fpRTS != nullptr) |
394 | 0 | VSIFCloseL(fpRTS); |
395 | 150 | } |
396 | | |
397 | | /************************************************************************/ |
398 | | /* SetModule() */ |
399 | | /************************************************************************/ |
400 | | |
401 | | bool TigerPolygon::SetModule(const char *pszModuleIn) |
402 | | |
403 | 302 | { |
404 | 302 | if (!OpenFile(pszModuleIn, "A")) |
405 | 152 | return false; |
406 | | |
407 | 150 | EstablishFeatureCount(); |
408 | | |
409 | | /* -------------------------------------------------------------------- */ |
410 | | /* Open the RTS file */ |
411 | | /* -------------------------------------------------------------------- */ |
412 | 150 | if (bUsingRTS) |
413 | 150 | { |
414 | 150 | if (fpRTS != nullptr) |
415 | 0 | { |
416 | 0 | VSIFCloseL(fpRTS); |
417 | 0 | fpRTS = nullptr; |
418 | 0 | } |
419 | | |
420 | 150 | if (pszModuleIn) |
421 | 0 | { |
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 | 0 | } |
430 | 150 | } |
431 | | |
432 | 150 | return true; |
433 | 302 | } |
434 | | |
435 | | /************************************************************************/ |
436 | | /* GetFeature() */ |
437 | | /************************************************************************/ |
438 | | |
439 | | OGRFeature *TigerPolygon::GetFeature(int nRecordId) |
440 | | |
441 | 0 | { |
442 | 0 | char achRecord[OGR_TIGER_RECBUF_LEN]; |
443 | |
|
444 | 0 | if (nRecordId < 0 || nRecordId >= nFeatures) |
445 | 0 | { |
446 | 0 | CPLError(CE_Failure, CPLE_FileIO, |
447 | 0 | "Request for out-of-range feature %d of %sA", nRecordId, |
448 | 0 | pszModule); |
449 | 0 | return nullptr; |
450 | 0 | } |
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 | 0 | { |
460 | 0 | CPLError(CE_Failure, CPLE_AppDefined, "Record length too large"); |
461 | 0 | return nullptr; |
462 | 0 | } |
463 | | |
464 | 0 | { |
465 | 0 | const auto nOffset = static_cast<uint64_t>(nRecordId) * nRecordLength; |
466 | 0 | if (VSIFSeekL(fpPrimary, nOffset, SEEK_SET) != 0) |
467 | 0 | { |
468 | 0 | CPLError(CE_Failure, CPLE_FileIO, |
469 | 0 | "Failed to seek to %" PRIu64 " of %sA", nOffset, |
470 | 0 | pszModule); |
471 | 0 | return nullptr; |
472 | 0 | } |
473 | 0 | } |
474 | | |
475 | 0 | if (VSIFReadL(achRecord, nRecordLength, 1, fpPrimary) != 1) |
476 | 0 | { |
477 | 0 | CPLError(CE_Failure, CPLE_FileIO, "Failed to read record %d of %sA", |
478 | 0 | nRecordId, pszModule); |
479 | 0 | return nullptr; |
480 | 0 | } |
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 | 0 | { |
496 | 0 | char achRTSRec[OGR_TIGER_RECBUF_LEN]; |
497 | |
|
498 | 0 | { |
499 | 0 | const auto nOffset = static_cast<uint64_t>(nRecordId) * nRTSRecLen; |
500 | 0 | if (VSIFSeekL(fpRTS, nOffset, SEEK_SET) != 0) |
501 | 0 | { |
502 | 0 | CPLError(CE_Failure, CPLE_FileIO, |
503 | 0 | "Failed to seek to %" PRIu64 " of %sS", nOffset, |
504 | 0 | pszModule); |
505 | 0 | delete poFeature; |
506 | 0 | return nullptr; |
507 | 0 | } |
508 | 0 | } |
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 | 0 | { |
514 | 0 | CPLError(CE_Failure, CPLE_FileIO, "Failed to read record %d of %sS", |
515 | 0 | nRecordId, pszModule); |
516 | 0 | delete poFeature; |
517 | 0 | return nullptr; |
518 | 0 | } |
519 | | |
520 | 0 | SetFields(psRTSInfo, poFeature, achRTSRec); |
521 | 0 | } |
522 | | |
523 | 0 | return poFeature; |
524 | 0 | } |