FOSS
There are a whole host of questions I still have regarding the intersections of individuals, societies, economies, and technology. One of the more practically philosophical realizations of this intersection than FOSS. Free and Open Source Software has become one of my go to tools in tackling a problem and has that special allure of feel good contribution and intrinsic reproducibility to it. I’ve created a few tools that take a FOSS approach to GIS, and here I’d like to demonstrate how to create one.
I’ll flesh this section out more at a later date, but some links I’ve leaned heavily on in the creation of FOSSFlood and ClusteR.
- https://ficonsulting.com/filabs/RInno
- https://www.r-bloggers.com/deploying-desktop-apps-with-r/: The foundation/inspiration for this implementation.
- https://www.robvanderwoude.com/vbstech_hta.php: A great HTA resource page
- https://stackoverflow.com/questions/24789746/portable-browser-issues-when-deploying-r-shiny-app
- https://stackoverflow.com/questions/30965410/creating-stand-alone-shiny-app-chrome-error/31272180#31272180
- https://englianhu.files.wordpress.com/2018/10/web-application-development-with-r-using-shiny-build-stunning-graphics-and-interactive-data-visualizations-to-deliver-cutting-edge-analytics-3ed.pdf
There are some useful tidbits of code, mostly in R, that I’ve flagged specifically. Many are part of FOSSFlood, but that global file is more than 1000 lines of code so it’s understandable if you didn’t see them.
#/////////////////////////////////////
# -- Grab backup roads and points
#/////////////////////////////////////
# TIGRIS Roads from Census
# Dev notes: here I grab the counties and use roads package to download roads (from Census)
# This is redundent with the OSM data I download for buildings defaults.
# There is also no handling of zip codes which straddle state lines
print("-- Base data collection - This may take upwards of 2 hours to run - Grabbing TIGER road files")
CountiesFIPS <- quiet(counties(cb=TRUE))
CountiesFIPSProj <- sp::spTransform(CountiesFIPS, CRS("+init=epsg:4326"))
aoiCounties <- CountiesFIPSProj[aoiZIPCodesProj, ]
# Error checking: Download roads for AOI that interset more than one state or county
if(length(unique(aoiCounties$COUNTYFP)) > 1) {
myHoldRoads <- quiet(roads(unique(aoiCounties$STATEFP),unique(aoiCounties$COUNTYFP)[1], year = 2014, refresh = TRUE)[NULL,])
for(i in unique(aoiCounties$COUNTYFP)) {
myRoads <- quiet(roads(unique(aoiCounties$STATEFP),i, year = 2014, refresh = TRUE))
myHoldRoads <- rbind(myHoldRoads, myRoads)
}
myRoads <- myHoldRoads
} else {
myRoads <- quiet(roads(unique(aoiCounties$STATEFP),unique(aoiCounties$COUNTYFP), year = 2014, refresh = TRUE))
}
myRoadsProj <- sp::spTransform(myRoads, CRS("+init=epsg:4326"))
myRoads_subset <- myRoadsProj[aoiZIPCodesProj, ]
writeOGR(obj=myRoads_subset, dsn=paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/roads"), layer="tigerroads", driver="ESRI Shapefile")
# OSM Roads and points
print("-- Base data collection - This may take upwards of 2 hours to run - Grabbing OSM data")
osmDataURL <- paste0("https://download.geofabrik.de/north-america/us/",tolower(gsub(" ", "-", fips(aoiCounties$STATEFP[1], to = "Name"))),"-latest-free.shp.zip")
download.file(osmDataURL, paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/",tolower(gsub(" ", "-", fips(aoiCounties$STATEFP[1], to = "Name"))),"-latest-free.shp.zip"))
unzip(paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/",tolower(gsub(" ", "-", fips(aoiCounties$STATEFP[1], to = "Name"))),"-latest-free.shp.zip"), exdir = paste0(basedir,"/AOI/",UserZipCodeFileName, "/geo/tmp"))
osmPoints <- readOGR(paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/gis_osm_pois_free_1.shp"), verbose = FALSE)
osmPointsProj <- sp::spTransform(osmPoints, CRS("+init=epsg:4326"))
writeOGR(obj=osmPointsProj[aoiZIPCodesProj, ], dsn=paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/addresses"), layer='OSMaddresses', driver="ESRI Shapefile")
osmRoads <- readOGR(paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/gis_osm_roads_free_1.shp"), verbose = FALSE)
osmRoadsProj <- sp::spTransform(osmRoads, CRS("+init=epsg:4326"))
writeOGR(obj=osmRoadsProj[aoiZIPCodesProj, ], dsn=paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/roads"), layer='OSMroads', driver="ESRI Shapefile")
# OpenAddresses points
print("-- Base data collection - This may take upwards of 2 hours to run - Grabbing OpenAddresses data")
if(aoiCounties$STATEFP %in% c('09','23','25','33','44','50','34','36','42')) {
oaURL <- "https://data.openaddresses.io/openaddr-collected-us_northeast.zip"
} else if(aoiCounties$STATEFP %in% c('18','17','26','39','55','19','20','27','29','31','38','46')) {
oaURL <- "https://data.openaddresses.io/openaddr-collected-us_midwest.zip"
} else if(aoiCounties$STATEFP %in% c('10','11','12','13','24','37','45','51','54','01','21','28','47','05','22','40','48')) {
oaURL <- "https://data.openaddresses.io/openaddr-collected-us_south.zip"
} else if(aoiCounties$STATEFP %in% c('04','08','16','35','30','49','32','56','02','06','15','41','53')) {
oaURL <- "https://data.openaddresses.io/openaddr-collected-us_west.zip"
}
download.file(oaURL, paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/OpenAddresses.zip"))
unzip(paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/OpenAddresses.zip"), exdir = paste0(basedir,"/AOI/",UserZipCodeFileName, "/geo/tmp"))
FullOpenAddresses <- paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/tmp/us/",tolower(fips(aoiCounties$STATEFP[1], to = "Abbreviation")),"/statewide.csv")
FullOpenAddressesCSV<- read.csv(FullOpenAddresses, header=TRUE, stringsAsFactors = FALSE)
coordinates(FullOpenAddressesCSV)<- ~LON+LAT
proj4string(FullOpenAddressesCSV) <- CRS("+init=epsg:4326")
writeOGR(obj=FullOpenAddressesCSV[aoiZIPCodesProj, ], dsn=paste0(basedir,"/AOI/",UserZipCodeFileName,"/geo/addresses"), layer='OpenAddresses', driver="ESRI Shapefile")