All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.imsweb.algorithms.ruralurban.RuralUrbanCsvData Maven / Gradle / Ivy

/*
 * Copyright (C) 2014 Information Management Services, Inc.
 */
package com.imsweb.algorithms.ruralurban;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;

import au.com.bytecode.opencsv.CSVReader;

/**
 * The purpose of this class is to get the rural urban continuum for the provided year category, state of dx, and county of dx
 * from the csv file lookup.  This implementation is memory consumer. If there is a database, it is better to use another implementation.
 * 

* The data used by this provider comes from the official census website. See the following SEER website for more information: * https://seer.cancer.gov/seerstat/variables/countyattribs/ * In particular, the rural/urban percentage comes from these sections: * 2010: https://seer.cancer.gov/seerstat/variables/countyattribs/#10 * 2000: https://seer.cancer.gov/seerstat/variables/countyattribs/#ca2000 *

* Created on Aug 12, 2014 by HoweW * @author howew */ public class RuralUrbanCsvData implements RuralUrbanDataProvider { // data structure for the values keyed by state+county only private static class CountyDataDto { private Long _urbanContinuum; private Map _censusData; public Long getUrbanContinuum() { return _urbanContinuum; } public void setUrbanContinuum(Long urbanContinuum) { _urbanContinuum = urbanContinuum; } public Map getCensusData() { if (_censusData == null) _censusData = new HashMap<>(); return _censusData; } } // data structure for the values keyed by state+county+census private static class CensusDataDto { private Long _urbanCensus; private Long _urbanCommuting; private Float _urbanPercentage2000; private Float _urbanPercentage2010; public Long getUrbanCensus() { return _urbanCensus; } public void setUrbanCensus(Long urbanCensus) { _urbanCensus = urbanCensus; } public Long getUrbanCommuting() { return _urbanCommuting; } public void setUrbanCommuting(Long urbanCommuting) { _urbanCommuting = urbanCommuting; } public Float getUrbanPercentage2000() { return _urbanPercentage2000; } public void setUrbanPercentage2000(Float urbanPercentage2000) { _urbanPercentage2000 = urbanPercentage2000; } public Float getUrbanPercentage2010() { return _urbanPercentage2010; } public void setUrbanPercentage2010(Float urbanPercentage2010) { _urbanPercentage2010 = urbanPercentage2010; } } // main (and unique) cached data private static Map _RURAL_URBAN_LOOK_UP = new HashMap<>(); // all the data is initialized at once; if we need a more fine-grain initialization, we will need more variables to keep track of which data has been initialized... private static synchronized void initializeAllLookups() { initializeRuralUrbanCensusLookup(); initializeRuralUrbanCommutingAreaLookup(); initializeRuralUrbanContinuumLookup(); } ////////////////////////////////////////////////////////////////////////////////// // RURAL URBAN CENSUS CODE SECTION STARTS HERE ////////////////////////////////////////////////////////////////////////////////// @Override public String getRuralUrbanCensus(String tractCategory, String state, String county, String censusTract) { String ruralUrbanCensus = RuralUrbanUtils.RURAL_URBAN_CENSUS_UNKNOWN; if (tractCategory == null || state == null || county == null || censusTract == null) return ruralUrbanCensus; if (_RURAL_URBAN_LOOK_UP.isEmpty()) initializeAllLookups(); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(state + county); CensusDataDto censusData = countyData == null ? null : countyData.getCensusData().get(censusTract); Long ruralUrbanCensusValue = censusData == null ? null : censusData.getUrbanCensus(); if (ruralUrbanCensusValue != null) { if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_1)) ruralUrbanCensus = String.valueOf((ruralUrbanCensusValue / 100) % 100); else if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_2)) { ruralUrbanCensus = String.valueOf(ruralUrbanCensusValue % 100); // if you didn't find a match in the 2010 lookup, check the 2000 lookup if (ruralUrbanCensus.equals(RuralUrbanUtils.RURAL_URBAN_CENSUS_UNKNOWN)) ruralUrbanCensus = String.valueOf((ruralUrbanCensusValue / 100) % 100); } } return StringUtils.isBlank(ruralUrbanCensus) ? RuralUrbanUtils.RURAL_URBAN_CENSUS_UNKNOWN : StringUtils.leftPad(ruralUrbanCensus, 2, '0'); } @Override public Float getRuralUrbanCensusPercentage(String tractCategory, String state, String county, String censusTract) { if (tractCategory == null || state == null || county == null || censusTract == null) return null; if (_RURAL_URBAN_LOOK_UP.isEmpty()) initializeAllLookups(); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(state + county); if (countyData == null) return null; CensusDataDto censusData = countyData.getCensusData().get(censusTract); if (censusData == null) return null; if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_1)) return censusData.getUrbanPercentage2000(); if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_2)) return censusData.getUrbanPercentage2010(); return null; } private static synchronized void initializeRuralUrbanCensusLookup() { int year1 = 0, year2 = 1; Map tmp = new HashMap<>(); Map tmp2 = new HashMap<>(); try { Reader reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-census-2000.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], tract = row[2], percent = row[3], census = row[4]; String key = state + county + "#" + tract; // that will allow us to split the key later in the process... byte[] values = tmp.get(key); if (values == null) { values = new byte[2]; values[0] = values[1] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_CENSUS_UNKNOWN); tmp.put(key, values); } values[year1] = Byte.valueOf(census); if (!".".equals(percent)) { Float[] percentValues = tmp2.get(key); if (percentValues == null) { percentValues = new Float[2]; tmp2.put(key, percentValues); } percentValues[year1] = Float.valueOf(percent); } } reader.close(); reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-census-2010.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], tract = row[2], percent = row[3], census = row[4]; String key = state + county + "#" + tract; // that will allow us to split the key later in the process... byte[] values = tmp.get(key); if (values == null) { values = new byte[2]; values[0] = values[1] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_CENSUS_UNKNOWN); tmp.put(key, values); } values[year2] = Byte.valueOf(census); if (!".".equals(percent)) { Float[] percentValues = tmp2.get(key); if (percentValues == null) { percentValues = new Float[2]; tmp2.put(key, percentValues); } percentValues[year2] = Float.valueOf(percent); } } reader.close(); } catch (IOException e) { throw new RuntimeException(e); } for (Entry entry : tmp.entrySet()) { String[] key = StringUtils.split(entry.getKey(), '#'); byte[] values = entry.getValue(); long result = (long)(values[0] * 100 + values[1]); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(key[0]); if (countyData == null) { countyData = new CountyDataDto(); _RURAL_URBAN_LOOK_UP.put(key[0], countyData); } CensusDataDto censusData = countyData.getCensusData().get(key[1]); if (censusData == null) { censusData = new CensusDataDto(); countyData.getCensusData().put(key[1], censusData); } censusData.setUrbanCensus(result); Float[] percentValues = tmp2.get(entry.getKey()); if (percentValues != null) { censusData.setUrbanPercentage2000(percentValues[year1]); censusData.setUrbanPercentage2010(percentValues[year2]); } } } ////////////////////////////////////////////////////////////////////////////////// // RURAL URBAN COMMUTING AREA CODE SECTION STARTS HERE ////////////////////////////////////////////////////////////////////////////////// @Override public String getRuralUrbanCommutingArea(String tractCategory, String state, String county, String censusTract) { String ruralUrbanCommutingArea = RuralUrbanUtils.RURAL_URBAN_COMMUTING_AREA_UNKNOWN; if (tractCategory == null || state == null || county == null || censusTract == null) return ruralUrbanCommutingArea; if (_RURAL_URBAN_LOOK_UP.isEmpty()) initializeAllLookups(); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(state + county); CensusDataDto censusData = countyData == null ? null : countyData.getCensusData().get(censusTract); Long ruralUrbanCommutingAreaValue = censusData == null ? null : censusData.getUrbanCommuting(); if (ruralUrbanCommutingAreaValue != null) { if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_1)) ruralUrbanCommutingArea = String.valueOf((ruralUrbanCommutingAreaValue / 100) % 100); else if (tractCategory.equals(RuralUrbanDataProvider.TRACT_CATEGORY_2)) { ruralUrbanCommutingArea = String.valueOf(ruralUrbanCommutingAreaValue % 100); // if you didn't find a match in the 2010 lookup, check the 2000 lookup if (ruralUrbanCommutingArea.equals(RuralUrbanUtils.RURAL_URBAN_COMMUTING_AREA_UNKNOWN)) ruralUrbanCommutingArea = String.valueOf((ruralUrbanCommutingAreaValue / 100) % 100); } } return StringUtils.isBlank(ruralUrbanCommutingArea) ? RuralUrbanUtils.RURAL_URBAN_COMMUTING_AREA_UNKNOWN : StringUtils.leftPad(ruralUrbanCommutingArea, 2, '0'); } private static void initializeRuralUrbanCommutingAreaLookup() { int year1 = 0, year2 = 1; List urbanCommutingAreas = Arrays.asList("1.0", "1.1", "2.0", "2.1", "3.0", "4.1", "5.1", "7.1", "8.1", "10.1"); Map tmp = new HashMap<>(); try { Reader reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-commuting-area-2000.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], tract = row[2], primary = row[3], secondary = row[4]; String key = state + county + "#" + tract; // that will allow us to split the key later in the process... byte[] values = tmp.get(key); if (values == null) { values = new byte[2]; values[0] = values[1] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_COMMUTING_AREA_UNKNOWN); tmp.put(key, values); } if (primary.equals("99")) values[year1] = 9; else if (urbanCommutingAreas.contains(secondary)) values[year1] = 1; else values[year1] = 2; } reader.close(); reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-commuting-area-2010.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], tract = row[2], primary = row[3], secondary = row[4]; String key = state + county + "#" + tract; // that will allow us to split the key later in the process... byte[] values = tmp.get(key); if (values == null) { values = new byte[2]; values[0] = values[1] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_COMMUTING_AREA_UNKNOWN); tmp.put(key, values); } if (primary.equals("99")) { values[year2] = 9; } else if (urbanCommutingAreas.contains(secondary)) { values[year2] = 1; } else { values[year2] = 2; } } reader.close(); } catch (IOException e) { throw new RuntimeException(e); } for (Entry entry : tmp.entrySet()) { String[] key = StringUtils.split(entry.getKey(), '#'); byte[] values = entry.getValue(); long result = (long)(values[0] * 100 + values[1]); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(key[0]); if (countyData == null) { countyData = new CountyDataDto(); _RURAL_URBAN_LOOK_UP.put(key[0], countyData); } CensusDataDto censusData = countyData.getCensusData().get(key[1]); if (censusData == null) { censusData = new CensusDataDto(); countyData.getCensusData().put(key[1], censusData); } censusData.setUrbanCommuting(result); } } ////////////////////////////////////////////////////////////////////////////////// // RURAL URBAN CONTINUUM CODE SECTION STARTS HERE ////////////////////////////////////////////////////////////////////////////////// @Override public String getRuralUrbanContinuum(String bealeCategory, String state, String county) { String ruralUrbanContinuum = RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN; if (bealeCategory == null || state == null || county == null) return ruralUrbanContinuum; if (_RURAL_URBAN_LOOK_UP.isEmpty()) initializeAllLookups(); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(state + county); Long ruralUrbanContinuumValue = countyData == null ? null : countyData.getUrbanContinuum(); if (ruralUrbanContinuumValue != null) { switch (bealeCategory) { case RuralUrbanDataProvider.BEALE_CATEGORY_1: ruralUrbanContinuum = String.valueOf((ruralUrbanContinuumValue / 10000) % 100); break; case RuralUrbanDataProvider.BEALE_CATEGORY_2: ruralUrbanContinuum = String.valueOf((ruralUrbanContinuumValue / 100) % 100); // if you didn't find a match in the 2003 lookup, check the 1993 lookup if (ruralUrbanContinuum.equals(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN)) ruralUrbanContinuum = String.valueOf((ruralUrbanContinuumValue / 10000) % 100); break; case RuralUrbanDataProvider.BEALE_CATEGORY_3: ruralUrbanContinuum = String.valueOf(ruralUrbanContinuumValue % 100); // if you didn't find a match in the 2013 lookup, check the 2003 lookup if (ruralUrbanContinuum.equals(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN)) ruralUrbanContinuum = String.valueOf((ruralUrbanContinuumValue / 100) % 100); // if you didn't find a match in the 2003 lookup, check the 1993 lookup if (ruralUrbanContinuum.equals(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN)) ruralUrbanContinuum = String.valueOf((ruralUrbanContinuumValue / 10000) % 100); break; default: throw new RuntimeException("Unsupported category: " + bealeCategory); } } return StringUtils.isBlank(ruralUrbanContinuum) ? RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN : StringUtils.leftPad(ruralUrbanContinuum, 2, '0'); } private static void initializeRuralUrbanContinuumLookup() { int year1 = 0, year2 = 1, year3 = 2; Map tmp = new HashMap<>(); try { Reader reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-continuum-1993.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], val = row[2]; byte[] values = tmp.get(state + county); if (values == null) { values = new byte[3]; values[0] = values[1] = values[2] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN); tmp.put(state + county, values); } values[year1] = Byte.valueOf(val); } reader.close(); reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-continuum-2003.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], val = row[2]; byte[] values = tmp.get(state + county); if (values == null) { values = new byte[3]; values[0] = values[1] = values[2] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN); tmp.put(state + county, values); } values[year2] = Byte.valueOf(val); } reader.close(); reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("ruralurban/rural-urban-continuum-2013.csv"), "US-ASCII"); for (String[] row : new CSVReader(reader, ',', '\"', 1).readAll()) { String state = row[0], county = row[1], val = row[2]; byte[] values = tmp.get(state + county); if (values == null) { values = new byte[3]; values[0] = values[1] = values[2] = Byte.valueOf(RuralUrbanUtils.RURAL_URBAN_CONTINUUM_UNKNOWN); tmp.put(state + county, values); } values[year3] = Byte.valueOf(val); } reader.close(); } catch (IOException e) { throw new RuntimeException(e); } for (Entry entry : tmp.entrySet()) { byte[] values = entry.getValue(); long result = (long)(values[0] * 10000 + values[1] * 100 + values[2]); CountyDataDto countyData = _RURAL_URBAN_LOOK_UP.get(entry.getKey()); if (countyData == null) { countyData = new CountyDataDto(); _RURAL_URBAN_LOOK_UP.put(entry.getKey(), countyData); } countyData.setUrbanContinuum(result); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy