]> gitweb.michael.orlitzky.com - dead/census-tools.git/blobdiff - src/SummaryFile1.py
Added state, county, and tract fields to the Block class.
[dead/census-tools.git] / src / SummaryFile1.py
index bd69d0095137d30caff160fbed0cea2567530040..bfc62582f2d80db6c9b96f6d57b8386838d4e065 100644 (file)
@@ -1,9 +1,10 @@
-import os, GPS, inspect
+import os
 
-class RecordError(StandardError):
-    pass
+import GPS
+import StringUtils
 
-class InvalidAreaError(StandardError):
+
+class RecordError(StandardError):
     pass
 
 class GeoRecord:
@@ -16,36 +17,71 @@ class GeoRecord:
 
 class Block:
     """
-    Represents a block (which is a special case of a GeoRecord.
-    All we care about here is the block number, population,
-    area, and coordinates.
+    Represents a block (which is a special case of a GeoRecord).
+    There are some convenience methods tacked on to make computation
+    and querying easier.
     """
 
     def __init__(self, geo_record):
-        """We initialize from a GeoRecord object"""
+        """
+        We initialize from a GeoRecord object. It is important that
+        we raise some kind of error if there is no 'block' field, since
+        that means we weren't passed a block.
+        """
+        if not (StringUtils.is_integer(geo_record.block)):
+            raise RecordError('GeoRecord object does not represent a block.')
+
+        # These need to be stored as strings so they don't
+        # affect the block_identifier() generation.
+        self.state = geo_record.state
+        self.county = geo_record.county
+        self.tract = geo_record.tract
+        self.block = geo_record.block
+
         # All of these int/float conversions will throw a ValueError
         # if the input string cannot be converted o the specified
         # type.
-        self.block_number = int(geo_record.block)
-        self.tract_number = int(geo_record.tract)
-        self.population = int(geo_record.pop100)
-        self.area_land = float(geo_record.arealand)
-        self.area_water = float(geo_record.areawatr)
+        self.pop100 = int(geo_record.pop100)
+        self.arealand = float(geo_record.arealand)
+        self.areawatr = float(geo_record.areawatr)
 
         self.coordinates = GPS.Coordinates()
         self.coordinates.latitude = float(geo_record.intptlat)
         self.coordinates.longitude = float(geo_record.intptlon)
 
-        if (self.total_area() == 0):
-            raise InvalidAreaError('A block may not have zero area.')
-        
+
+    def tiger_blkidfp00(self):
+        # From the Tiger/Line shapefile documentation:
+        #
+        #   Current block identifier; a concatenation of Census 2000
+        #   state FIPS code, Census 2000 county FIPS code, Census
+        #   BLKIDFP 16 String 2000 census tract code, Census 2000
+        #   tabulation block number, and current block suffix 1.
+        #
+        return (self.state +
+                self.county +
+                self.tract +
+                self.block)
+
 
     def total_area(self):
-        return (self.area_land + self.area_water)
+        return (self.arealand + self.areawatr)
 
 
     def population_density(self):
-        return (self.population / self.total_area())
+        # There are some unusual cases where a block will have a
+        # total area of zero. It also seems that these unusual blocks
+        # do in fact posess geometries, provided in the Tiger database.
+        # Therefore, we allow them to be parsed.
+        #
+        # The choice to assign these blocks an average density of 0
+        # was arbitrary.
+        #
+        if (self.total_area() == 0):
+            return 0
+        else:
+            return (self.pop100 / self.total_area())
+
 
     
 class GeoRecordParser:
@@ -80,12 +116,12 @@ class GeoRecordParser:
             try:
                 block = Block(record)
                 blocks.append(block)
+            except RecordError:
+                # Ain't a block.
+                continue
             except ValueError:
                 # A value couldn't be converted to the appropriate type.
                 continue
-            except InvalidAreaError:
-                # Something is funny with the geometry.
-                continue
             
         return blocks