Skip to content

Commit

Permalink
changed the color of all features to match their urban/rural classifi…
Browse files Browse the repository at this point in the history
…cations
  • Loading branch information
davidplummer-pe committed Jul 14, 2020
1 parent ac6c9f4 commit 18749dc
Showing 1 changed file with 138 additions and 220 deletions.
358 changes: 138 additions & 220 deletions firecares/firestation/static/firestation/js/services/censusService.js
Original file line number Diff line number Diff line change
@@ -1,235 +1,153 @@
"use strict";

(function () {
angular
.module("fireStation.censusService", [])
.factory("census", CensusService);
angular
.module("fireStation.censusService", [])
.factory("census", CensusService);

CensusService.$inject = ["$http", "$q", "$rootScope"];
function CensusService($http, $q, $rootScope) {
return {
stateCodes: {
AL: { id: "01", name: "Alabama" },
AK: { id: "02", name: "Alaska" },
AZ: { id: "04", name: "Arizona" },
AR: { id: "05", name: "Arkansas" },
CA: { id: "06", name: "California" },
CO: { id: "08", name: "Colorado" },
CT: { id: "09", name: "Connecticut" },
DE: { id: "10", name: "Delaware" },
FL: { id: "12", name: "Florida" },
GA: { id: "13", name: "Georgia" },
HI: { id: "15", name: "Hawaii" },
ID: { id: "16", name: "Idaho" },
IL: { id: "17", name: "Illinois" },
IN: { id: "18", name: "Indiana" },
IA: { id: "19", name: "Iowa" },
KS: { id: "20", name: "Kansas" },
KY: { id: "21", name: "Kentucky" },
LA: { id: "22", name: "Louisiana" },
ME: { id: "23", name: "Maine" },
MD: { id: "24", name: "Maryland" },
MA: { id: "25", name: "Massachusetts" },
MI: { id: "26", name: "Michigan" },
MN: { id: "27", name: "Minnesota" },
MS: { id: "28", name: "Mississippi" },
MO: { id: "29", name: "Missouri" },
MT: { id: "30", name: "Montana" },
NE: { id: "31", name: "Nebraska" },
NV: { id: "32", name: "Nevada" },
NH: { id: "33", name: "New Hampshire" },
NJ: { id: "34", name: "New Jersey" },
NM: { id: "35", name: "New Mexico" },
NY: { id: "36", name: "New York" },
NC: { id: "37", name: "North Carolina" },
ND: { id: "38", name: "North Dakota" },
OH: { id: "39", name: "Ohio" },
OK: { id: "40", name: "Oklahoma" },
OR: { id: "41", name: "Oregon" },
PA: { id: "42", name: "Pennsylvania" },
RI: { id: "44", name: "Rhode Island" },
SC: { id: "45", name: "South Carolina" },
SD: { id: "46", name: "South Dakota" },
TN: { id: "47", name: "Tennessee" },
TX: { id: "48", name: "Texas" },
UT: { id: "49", name: "Utah" },
VT: { id: "50", name: "Vermont" },
VA: { id: "51", name: "Virginia" },
WA: { id: "53", name: "Washington" },
WV: { id: "54", name: "West Virginia" },
WI: { id: "55", name: "Wisconsin" },
WY: { id: "56", name: "Wyoming" },
PR: { id: "72", name: "Puerto Rico" },
},
/**
* Fetch the state code for the given abbreviation
* @param {String} abbreviation
*/
stateAbbreviationToCode(abbreviation) {
try{
for (var x in this.stateCodes) {
if (x == abbreviation) return this.stateCodes[x].id;
}
}catch(ex){
console.error(ex);
return null; }
},

/** fetch the census statistical data for the given state
* @param {String} stateAbbreviation
*/
getTractData(stateAbbreviation) {
return new Promise((res, rej) => {

var stateId = this.stateAbbreviationToCode(stateAbbreviation);
if(!stateId){
return res({
'success':false,
'error':'The state ID is invalid.'
})
}
$http({
method: "GET",
url:
"https://api.census.gov/data/2017/acs/acs5?get=NAME,B01001_001E&in=state:" +
stateId +
"%20county:*&for=tract:*&key=655fd4220567937e8b2c8f1041dbe01696457797",
}).then(
async (resp) => {
//convert the successful response from a string array into a json array
if (resp.status == 200 && resp.data?.length > 1) {
var data = [];
var densityData = await this.getCountyDensityData(stateId);

for (var x = 1; x < resp.data.length; x++) {
var e = {};
for (var i in resp.data[0]) {
e[resp.data[0][i]] = resp.data[x][i];
}
e.DENSITY = densityData[e.state + e.county];
data.push(e);
}

res((await this.generateLayerJSON(data)));
} else {
rej();
}
CensusService.$inject = ["$http", "$q", "$rootScope"];
function CensusService($http, $q, $rootScope) {
return {
COLORS: {
U: "rgba(100,172,255,1)",//urban area
R: "rgba(164,255,164,1)",//rural area
default: "rgba(164,255,164,1)",//unknown area (sometimes the api returns a null value for UR)
},
(error) => {
rej(error);
}
);
});
},

/**
* retrieve the population density data for all counties in the given state
* @param {String} stateId
*/
getCountyDensityData(stateId) {
return new Promise((res, rej) => {
$http({
method: "GET",
url:
"https://api.census.gov/data/2019/pep/population" +
"?get=COUNTY,STATE,DENSITY,POP,NAME&for=county:*" +
"&in=state:" +
stateId,
}).then(
(resp) => {
//convert the successful response from a string array into a json array
if (resp.status == 200 && resp.data?.length > 1) {
var data = [];
for (var x = 1; x < resp.data.length; x++) {
var e = {};
for (var i in resp.data[0]) {
e[resp.data[0][i]] = resp.data[x][i];
}
data.push(e);
}
var densityData = {};
for (var x in data) {
densityData[data[x].state + data[x].county] = data[x].DENSITY;
stateCodes: {
AL: { id: "01", name: "Alabama" },
AK: { id: "02", name: "Alaska" },
AZ: { id: "04", name: "Arizona" },
AR: { id: "05", name: "Arkansas" },
CA: { id: "06", name: "California" },
CO: { id: "08", name: "Colorado" },
CT: { id: "09", name: "Connecticut" },
DE: { id: "10", name: "Delaware" },
FL: { id: "12", name: "Florida" },
GA: { id: "13", name: "Georgia" },
HI: { id: "15", name: "Hawaii" },
ID: { id: "16", name: "Idaho" },
IL: { id: "17", name: "Illinois" },
IN: { id: "18", name: "Indiana" },
IA: { id: "19", name: "Iowa" },
KS: { id: "20", name: "Kansas" },
KY: { id: "21", name: "Kentucky" },
LA: { id: "22", name: "Louisiana" },
ME: { id: "23", name: "Maine" },
MD: { id: "24", name: "Maryland" },
MA: { id: "25", name: "Massachusetts" },
MI: { id: "26", name: "Michigan" },
MN: { id: "27", name: "Minnesota" },
MS: { id: "28", name: "Mississippi" },
MO: { id: "29", name: "Missouri" },
MT: { id: "30", name: "Montana" },
NE: { id: "31", name: "Nebraska" },
NV: { id: "32", name: "Nevada" },
NH: { id: "33", name: "New Hampshire" },
NJ: { id: "34", name: "New Jersey" },
NM: { id: "35", name: "New Mexico" },
NY: { id: "36", name: "New York" },
NC: { id: "37", name: "North Carolina" },
ND: { id: "38", name: "North Dakota" },
OH: { id: "39", name: "Ohio" },
OK: { id: "40", name: "Oklahoma" },
OR: { id: "41", name: "Oregon" },
PA: { id: "42", name: "Pennsylvania" },
RI: { id: "44", name: "Rhode Island" },
SC: { id: "45", name: "South Carolina" },
SD: { id: "46", name: "South Dakota" },
TN: { id: "47", name: "Tennessee" },
TX: { id: "48", name: "Texas" },
UT: { id: "49", name: "Utah" },
VT: { id: "50", name: "Vermont" },
VA: { id: "51", name: "Virginia" },
WA: { id: "53", name: "Washington" },
WV: { id: "54", name: "West Virginia" },
WI: { id: "55", name: "Wisconsin" },
WY: { id: "56", name: "Wyoming" },
PR: { id: "72", name: "Puerto Rico" },
},
/**
* Fetch the state code for the given abbreviation
* @param {String} abbreviation
*/
stateAbbreviationToCode(abbreviation) {
try {
for (var x in this.stateCodes) {
if (x == abbreviation) return this.stateCodes[x].id;
}
} catch (ex) {
console.error(ex);
return null;
}

res(densityData);
} else rej();
},
(error) => {
rej(error);
}
);
});
},

/**
* Take the given statistical data and build a layer with it
* @param {Object} response
*/
generateLayerJSON(response) {
return new Promise((res, rej) => {
//extract the density values

var values = response
.map(function (county) {
//return Math.random() * 33;
/** fetch the census statistical data for the given state
* and return a vector tile layer in JSON format
* @param {String} stateAbbreviation
*/
getTractData(stateAbbreviation) {
return new Promise((res, rej) => {

return parseFloat(county.DENSITY);
})
.sort((a, b) => a - b);
var stateId = this.stateAbbreviationToCode(stateAbbreviation);
if (!stateId) {
return res({
'success': false,
'error': 'The state ID is invalid.'
})
}
//get the list of tracts for the selected state
$http({
method: "GET",
url:
"https://tigerweb.geo.census.gov/arcgis/rest/services/TIGERweb/Tracts_Blocks/MapServer/10/query?" +
"where=STATE=" + stateId + "&f=pjson&outFields=STATE,COUNTY,TRACT,UR&returnGeometry=false"
}).then(
(resp) => {

//define the color scale for the features
var colorScale = chroma.scale(["#cccccc", "#ff0000"]).domain(values);
function getColor(val) {
return colorScale(val).alpha(1).css();
}
//return an error if no features could be found
if (resp.status != 200 || resp.data?.features?.length <= 0) {
res({
success: false,
error: "No map data could be found for the selected state."
})
} else {
var features = {};
//assign colors to each of the features based on its rural/urban classification
for (var x in resp.data.features) {
let data = resp.data.features[x].attributes;
features[(data.STATE + data.COUNTY + data.TRACT)] = this.COLORS[data.UR] || this.COLORS.default
}

//generate style expressions for each of the features
var colorJSON = {};
var colors = {};
var GEOIDs = [];
response.forEach((county) => {
var GEOID = county.state + county.county + county.tract;
GEOIDs.push(GEOID);
var value = county.DENSITY;
var color = getColor(value);
if (!colors[color]) {
colors[color] = [];
}
colors[color].push(GEOID);
});
var colorExpression = ["match", ["get", "GEOID"]];
Object.entries(colors).forEach(function ([color, GEOIDs]) {
colorExpression.push(GEOIDs, color);
GEOIDs.forEach((item) => {
colorJSON[item] = color;
});
});
colorExpression.push("rgba(0,0,0,0)");
// return the layer json
res({
url:
"https://gis-server.data.census.gov/arcgis/rest/services/Hosted/VT_2018_140_00_PY_D1/VectorTileServer/tile/{z}/{y}/{x}.pbf",

// return the layer json
res({
url:
"https://gis-server.data.census.gov/arcgis/rest/services/Hosted/VT_2018_140_00_PY_D1/VectorTileServer/tile/{z}/{y}/{x}.pbf",
/** only keep the features within the selected state */
filter(feature) {
return !!features[feature.properties.GEOID];
},
/** set the color for each feature in the layer */
style(feature) {
return {
color: features[feature.properties.GEOID],
outline: {
color: "#ffffff",
size: 1,
},
};
},

/** only keep the features with in the selected state */
filter(feature) {
if (GEOIDs.indexOf(feature.properties.GEOID) > -1) return true;
else return false;
});
}
},
(error) => {
rej(error)
}
)
})
},
/** set the color for each feature in the layer */
style(feature) {
return {
color: colorJSON[feature.properties.GEOID],
outline: {
color: "#ffffff",
size: 1,
},
};
},
});
});
},
};
}

};
}
})();

0 comments on commit 18749dc

Please sign in to comment.