diff --git a/2019-11-03-polygons.R b/2019-11-03-polygons.R new file mode 100644 index 0000000..5ecd443 --- /dev/null +++ b/2019-11-03-polygons.R @@ -0,0 +1,101 @@ +library(zipcode) +library(sf) +library(curlconverter) # hrbrmstr/curlconverter +library(hrbrthemes) +library(tidyverse) + +st_read(here::here("data/me-counties.json")) %>% + st_set_crs(4326) -> maine + +url <- "curl 'https://hotspots.wifi.comcast.com/ajax/map-search' -H 'Connection: keep-alive' -H 'sec-ch-ua: \"Google Chrome 79\"' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Sec-Fetch-Dest: empty' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.16 Safari/537.36' -H 'DNT: 1' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Origin: https://hotspots.wifi.xfinity.com' -H 'Sec-Fetch-Site: cross-site' -H 'Sec-Fetch-Mode: cors' -H 'Referer: https://hotspots.wifi.xfinity.com/mobile/' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,la;q=0.8' --data 'txtSearch=03901&typeFilter=[]&clat=44.686349&clon=-68.904427' --compressed" + +straighten(url) %>% + make_req() -> req + +fetch_hotspots <- function(zip) { + + message(zip) + + httr::POST( + url = "https://hotspots.wifi.comcast.com/ajax/map-search", + httr::add_headers( + Connection = "keep-alive", + `sec-ch-ua` = "Google Chrome 79", + Accept = "application/json, text/javascript, */*; q=0.01", + `Sec-Fetch-Dest` = "empty", + `User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.16 Safari/537.36", + DNT = "1", Origin = "https://hotspots.wifi.xfinity.com", + `Sec-Fetch-Site` = "cross-site", + `Sec-Fetch-Mode` = "cors", + Referer = "https://hotspots.wifi.xfinity.com/mobile/", + `Accept-Encoding` = "gzip, deflate, br", + `Accept-Language` = "en-US,en;q=0.9,la;q=0.8" + ), + body = list( + txtSearch = zip, + typeFilter = "[]", + clat = "44.686349", + clon = "-68.904427" + ), + encode = "form" + ) -> res + + stop_for_status(res) + + out <- content(res, as = "text", encoding = "UTF-8") + out <- jsonlite::fromJSON(out) + + if (length(out$results) == 0) return(NULL) + + out <- as_tibble(out$results) + out <- select(out, lng=V7, lat=V6) + out <- mutate_all(out, as.numeric) + + out + +} + +if (!file.exists(here::here("data/me-xfin-hotspots.rds"))) { + + as_tibble(zipcode) %>% + filter(state == "ME") %>% + pull(zip) %>% + map_df(fetch_hotspots) -> maine_xfin_hotspots + + saveRDS(maine_xfin_hotspots, here::here("data/me-xfin-hotspots.rds")) + +} + +maine_xfin_hotspots <- readRDS(here::here("data/me-xfin-hotspots.rds")) + +bbox <- st_bbox(maine) + +maine_xfin_hotspots %>% + filter( + between(lat, bbox$ymin, bbox$ymax), + between(lng, bbox$xmin, bbox$xmax), + ) -> maine_xfin_hotspots + +ggplot() + + geom_sf( + data = maine, color = "#b2b2b2", size = 0.125, fill = "#3B454A" + ) + + geom_point( + data = maine_xfin_hotspots, aes(lng, lat), + size = 0.125, alpha=1/2, color = "white" + ) + + stat_density_2d( + data = maine_xfin_hotspots, geom = "polygon", + aes(lng, lat, fill = stat(level)), n = 1000, h = c(0.2, 0.2) + ) + + scale_fill_viridis_c(option = "magma", direction = -1) + + coord_sf(datum = NA) + + labs( + x = NULL, y = NULL, + title = "Xfinity Hotspot Coverage in Maine", + subtitle = glue::glue("{scales::comma(nrow(maine_xfin_hotspots))} total Xfinity hotspots in Maine\nPolygons show areas of highest hotspot density\nDots show individual hotspots"), + caption = "Data source: \nhttps://git.rud.is/hrbrmstr/y2019-30daymapchallenge • #30DayMapChallenge" + ) + + theme_ft_rc(grid="") + + theme(axis.text = element_blank()) + + theme(legend.position = "none") diff --git a/data/me-counties.json b/data/me-counties.json new file mode 100644 index 0000000..e34dfd6 --- /dev/null +++ b/data/me-counties.json @@ -0,0 +1 @@ +{"type":"Topology","transform":{"scale":[0.0017667279204809255,0.0012459878711682589],"translate":[-71.08434144614728,43.05975103006082]},"arcs":[[[1857,2102],[-56,1],[-83,-32]],[[1718,2071],[-120,-29],[-85,-25],[-13,7],[3,292],[-5,79],[0,271],[-152,11],[-64,0]],[[1282,2677],[-2,142],[-508,1]],[[772,2820],[-171,0]],[[601,2820],[15,97],[101,145],[143,201],[72,100],[124,166],[36,-5],[27,-12],[39,-11],[-8,-35],[8,-107],[40,-26],[37,-28],[56,31],[72,21],[40,5],[9,26],[46,12],[27,-8],[48,5],[-5,28],[13,23],[52,-2],[37,-11],[29,-21],[40,-33],[48,-44],[26,-17],[35,-62],[57,-43],[0,-218],[0,-155],[4,-258],[1,-193],[0,-81],[17,-16],[-30,-39],[22,-31],[-22,-39],[12,-41],[-12,-42]],[[913,1310],[57,50],[25,-32],[34,6]],[[1029,1334],[35,6],[12,-69],[95,23],[100,24],[13,-15]],[[1284,1303],[0,-13],[-17,-42],[26,-38],[-3,-88],[-52,-199]],[[1238,923],[-22,-6]],[[1216,917],[-9,13],[-39,9]],[[1168,939],[-57,20],[-83,88],[-44,-45],[-27,27],[-23,-8]],[[934,1021],[-40,8]],[[894,1029],[34,98],[28,-6],[13,70],[-25,6],[14,71],[-39,6],[-6,36]],[[479,1123],[21,15],[41,7]],[[541,1145],[16,-83],[-18,-10],[18,-29],[15,-36],[8,-79],[38,-9],[-19,-36],[12,-8]],[[611,855],[-16,-99],[-10,-8],[10,-12]],[[595,736],[-27,-40],[-20,-16],[-64,54],[-49,51],[-27,-41],[-66,37]],[[342,781],[-3,23],[53,74],[38,43],[34,124],[-5,63],[20,15]],[[611,855],[61,-13],[24,47],[52,-11],[3,-11]],[[751,867],[-19,-79],[-12,-11],[64,-17],[-25,-90],[29,-30],[-2,-49]],[[786,591],[-12,-3],[-21,-39],[-30,-12],[-15,-22],[-12,3],[-4,43],[-14,7]],[[678,568],[-4,89],[21,54],[-68,-24],[-32,49]],[[55,589],[9,-7],[67,16],[40,8]],[[171,606],[73,-21],[-3,-62],[62,4],[52,-59],[-20,-29],[87,-63]],[[422,376],[-13,1],[-13,-34],[33,-23],[-32,-36],[-19,-42],[-28,-17],[-29,3],[-9,-8],[-12,-9],[-17,-42],[4,-34],[1,-5],[-12,-47],[-14,-23],[-25,-47],[-22,-13],[-29,16],[-36,35],[-5,5],[2,40],[0,0],[7,30],[-34,43],[-29,44],[-34,41],[9,43],[4,36],[3,28],[-5,25],[-5,24],[-5,105],[-3,74]],[[1714,1760],[66,12],[-62,299]],[[1857,2102],[0,-1],[52,2],[20,-39],[25,-8],[55,-21],[45,8],[18,-26],[3,-57],[-33,-4],[-4,-36],[32,-63],[-19,-59],[-11,-26],[15,-21],[36,-70],[28,-23],[24,17],[15,36],[38,-16],[24,-7],[28,-41],[12,-35],[5,-31],[28,-72],[28,-30],[-5,-43],[24,-26],[-43,-39],[-27,-21],[-24,-29],[-30,-35],[-37,-20],[-33,-31],[-43,21],[-17,-18],[-28,-2],[-25,-35],[-16,-37],[10,-27],[-43,-38],[-32,46],[-10,31],[-30,-19],[-50,-6],[-25,-24],[-9,-36],[-26,-20],[-21,13],[-4,-3]],[[1777,1081],[-10,13],[-31,133],[-50,281],[70,14],[-42,238]],[[0,1802],[26,6],[15,26],[35,-11],[22,-28],[10,-46],[28,-4],[6,30]],[[142,1775],[30,-203],[-24,-4],[28,-140],[2,-86],[88,51],[59,-135],[-22,-14],[152,-33],[-15,-25],[32,-28],[7,-35]],[[342,781],[-36,-21],[-29,21],[4,72],[-21,38],[-111,-74],[60,-93],[-49,-85],[11,-33]],[[55,589],[-2,37],[-6,204],[-4,132],[-1,21],[-1,13],[-1,32],[-3,80],[-2,48],[-8,189],[-12,212],[-15,245]],[[541,1145],[49,-1],[4,18],[-21,17],[18,34],[0,14],[49,-11],[4,6],[9,23]],[[653,1245],[61,-3],[17,-24],[28,20],[44,-13],[34,-7],[15,38],[-30,59],[92,16],[-1,-21]],[[894,1029],[-13,-54],[-11,-11],[-58,15],[-9,-42],[5,-81],[-5,-1],[-52,12]],[[1238,923],[38,-1],[61,-74],[98,11],[10,-32]],[[1445,827],[-30,-14],[-19,-50],[-23,-5],[-7,58],[-62,-15],[-53,-26],[-18,42],[-17,43],[26,22],[-26,35]],[[1222,663],[28,16],[15,-45],[-23,-37],[-31,26],[11,40]],[[1168,939],[-10,3],[-9,-50],[-12,-33],[25,-40],[-20,-32],[13,-27],[-18,-26],[-31,2],[-25,1],[-21,-45],[-17,-2],[-21,-32],[-24,-18],[-19,49],[-14,21]],[[965,710],[9,55],[46,32],[-31,125],[-54,14],[-10,70],[9,15]],[[678,568],[-16,6],[-39,-24],[-10,-28],[-35,3],[-4,0],[-14,-33],[-41,2],[-13,-24],[-15,-39],[6,-31],[-22,-15],[-43,-10],[-10,1]],[[979,1616],[70,13],[145,30],[66,13],[-13,66],[59,12],[-46,231],[-61,-12],[4,120],[74,18],[5,570]],[[1714,1760],[-140,-25],[18,-98],[-71,-13],[12,-69],[-71,-13],[13,-74],[13,-70],[5,-31],[-97,-18],[-17,-30],[-25,15],[-30,-49],[-40,18]],[[1029,1334],[-8,53],[0,16],[-14,71],[-28,142]],[[965,710],[-7,10],[-17,-27],[-9,-11],[-37,-57],[-28,3],[-14,-15],[-41,-16],[-26,-6]],[[1777,1081],[-19,-16],[-20,2],[-20,-47],[-31,27],[-13,18],[-36,-11],[9,-36],[-10,-18],[-21,-32],[31,-33],[-75,8],[-5,-31],[-9,-71],[-61,7],[-36,-13],[-16,-8]],[[301,2093],[19,-125],[57,-295],[62,15],[9,-43],[76,15],[28,-145],[-22,-41],[10,-37],[55,11],[21,-150],[21,3],[16,-56]],[[142,1775],[2,13],[12,19],[-6,24],[7,28],[-10,20],[25,24],[14,-2],[15,-23],[29,-4],[25,-9],[-1,36],[-22,19],[-28,47],[20,43],[22,27],[33,26],[22,30]],[[772,2820],[-6,-144],[2,-334],[25,5],[21,-96],[-32,10],[-17,-97],[-29,24],[-27,-38],[74,-89],[-44,-68],[90,-427],[68,34],[82,16]],[[301,2093],[0,0],[60,29],[36,25],[-18,41],[10,18],[38,37],[40,29],[4,34],[-7,24],[-27,-1],[5,30],[-8,16],[6,34],[23,32],[15,34],[-29,34],[20,49],[13,31],[16,12],[-1,25],[26,23],[24,19],[22,21],[15,15],[17,116]]],"objects":{"cb_2015_maine_county_20m":{"type":"GeometryCollection","geometries":[{"arcs":[[0,1,2,3,4]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"003","COUNTYNS":"00581287","AFFGEOID":"0500000US23003","GEOID":"23003","NAME":"Aroostook","LSAD":"06","ALAND":17278047428,"AWATER":405253178}},{"arcs":[[5,6,7,8,9,10,11,12]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"027","COUNTYNS":"00581299","AFFGEOID":"0500000US23027","GEOID":"23027","NAME":"Waldo","LSAD":"06","ALAND":1890504130,"AWATER":318126866}},{"arcs":[[13,14,15,16,17]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"001","COUNTYNS":"00581286","AFFGEOID":"0500000US23001","GEOID":"23001","NAME":"Androscoggin","LSAD":"06","ALAND":1211937419,"AWATER":75599699}},{"arcs":[[18,19,20,21,-16]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"023","COUNTYNS":"00581297","AFFGEOID":"0500000US23023","GEOID":"23023","NAME":"Sagadahoc","LSAD":"06","ALAND":657803474,"AWATER":300569626}},{"arcs":[[22,23,24]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"031","COUNTYNS":"00581301","AFFGEOID":"0500000US23031","GEOID":"23031","NAME":"York","LSAD":"06","ALAND":2566086356,"AWATER":722457634}},{"arcs":[[25,-1,26,27]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"029","COUNTYNS":"00581300","AFFGEOID":"0500000US23029","GEOID":"23029","NAME":"Washington","LSAD":"06","ALAND":6637321519,"AWATER":1799989402}},{"arcs":[[28,29,-18,30,-23,31]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"017","COUNTYNS":"00581294","AFFGEOID":"0500000US23017","GEOID":"23017","NAME":"Oxford","LSAD":"06","ALAND":5379039602,"AWATER":256039720}},{"arcs":[[32,33,-13,34,-19,-15]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"011","COUNTYNS":"00581291","AFFGEOID":"0500000US23011","GEOID":"23011","NAME":"Kennebec","LSAD":"06","ALAND":2246806175,"AWATER":216724439}},{"arcs":[[[-9,35,36]],[[37]],[[-11,38,39]]],"type":"MultiPolygon","properties":{"STATEFP":"23","COUNTYFP":"013","COUNTYNS":"00581292","AFFGEOID":"0500000US23013","GEOID":"23013","NAME":"Knox","LSAD":"06","ALAND":945693971,"AWATER":2017108221}},{"arcs":[[-17,-22,40,-24,-31]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"005","COUNTYNS":"00581288","AFFGEOID":"0500000US23005","GEOID":"23005","NAME":"Cumberland","LSAD":"06","ALAND":2164390945,"AWATER":988822127}},{"arcs":[[41,-2,-26,42,-7,43]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"019","COUNTYNS":"00581295","AFFGEOID":"0500000US23019","GEOID":"23019","NAME":"Penobscot","LSAD":"06","ALAND":8799074164,"AWATER":413603851}},{"arcs":[[-35,-12,-40,44,-20]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"015","COUNTYNS":"00581293","AFFGEOID":"0500000US23015","GEOID":"23015","NAME":"Lincoln","LSAD":"06","ALAND":1180625664,"AWATER":631363741}},{"arcs":[[-8,-43,-28,45,-36]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"009","COUNTYNS":"00581290","AFFGEOID":"0500000US23009","GEOID":"23009","NAME":"Hancock","LSAD":"06","ALAND":4110275786,"AWATER":1963073951}},{"arcs":[[46,-33,-14,-30,47]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"007","COUNTYNS":"00581289","AFFGEOID":"0500000US23007","GEOID":"23007","NAME":"Franklin","LSAD":"06","ALAND":4395175202,"AWATER":121369620}},{"arcs":[[-4,48,-44,-6,-34,-47,49]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"025","COUNTYNS":"00581298","AFFGEOID":"0500000US23025","GEOID":"23025","NAME":"Somerset","LSAD":"06","ALAND":10164314642,"AWATER":437895944}},{"arcs":[[-3,-42,-49]],"type":"Polygon","properties":{"STATEFP":"23","COUNTYFP":"021","COUNTYNS":"00581296","AFFGEOID":"0500000US23021","GEOID":"23021","NAME":"Piscataquis","LSAD":"06","ALAND":10258678459,"AWATER":1080563045}}]}}} \ No newline at end of file diff --git a/data/me-xfin-hotspots.rds b/data/me-xfin-hotspots.rds new file mode 100644 index 0000000..9b78f28 Binary files /dev/null and b/data/me-xfin-hotspots.rds differ