]> gitweb.michael.orlitzky.com - dead/census-tools.git/commitdiff
Added state, county, and tract fields to the Block class.
authorMichael Orlitzky <michael@orlitzky.com>
Sat, 12 Sep 2009 14:55:14 +0000 (10:55 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sat, 12 Sep 2009 14:55:14 +0000 (10:55 -0400)
Renamed the other Block attributes to follow the GeoRecord/Tiger naming convention.
Updated any tests/methods that depended on the Block attribute names.
Throw an error from within the Block class if the "block" attribute is non-integral.

src/SummaryFile1.py
src/Tests/Unit/SummaryFile1Test.py

index 0ad410d0dc4152b6642d96fb10c3b9647e466c3c..bfc62582f2d80db6c9b96f6d57b8386838d4e065 100644 (file)
@@ -17,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:
@@ -81,6 +116,9 @@ 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
index a29e208cf7fa91ee2bbc20ce186b9f01e1d63d02..edaf59859d91e1e89a5026ee959d1b4b38a87c6a 100644 (file)
@@ -12,6 +12,9 @@ class BlockTest(unittest.TestCase):
         # Fill a GeoRecord with dummy values so that we
         # can calculate its average population density.
         gr = SummaryFile1.GeoRecord()
+        gr.state = '24'
+        gr.county = '001'
+        gr.tract = '123456'
         gr.block = '1728'
         gr.pop100 = '100'
         gr.arealand = '40'
@@ -80,7 +83,7 @@ class SummaryFile1Test(unittest.TestCase):
             b_coords.longitude = b.coordinates.longitude
             
             closest_block = SummaryFile1.FindClosestBlock(blocks, b_coords)
-            self.assertEqual(b.block_number, closest_block.block_number)
+            self.assertEqual(b.block, closest_block.block)
 
 
     def testEachBlockHasItsOwnAverageDensity(self):