This is part of the Scicloj Clojure Data Scrapbook. |
Seattle Parks and Neighborhoods - DRAFT
Timothy Prately and Daniel Slutsky
(Probably, this notebook will be divided into a few book chapters.)
Choosing where to live depends on many factors such as job opportunities and cost of living. I like walking, so one factor that is important to me is access to parks. In this analysis we’ll rank neighborhoods by park area proportional to total area. This article demonstrates how to prepare the geospatial data, calculate the value we want, and how to explore the meaning behind the numbers.
ns index
(:require [geo
(:as geohash]
[geohash :as jts]
[jts :as spatial]
[spatial :as geoio]
[io :as crs]]
[crs :as fun]
[tech.v3.datatype.functional :as tc]
[tablecloth.api :as kind]
[scicloj.kindly.v4.kind :as kindly]
[scicloj.kindly.v4.api :as hiccup]
[hiccup.core :as charred]
[charred.api :as color]
[clojure2d.color :as str])
[clojure.string :import (org.locationtech.jts.index.strtree STRtree)
(
(org.locationtech.jts.geom Geometry Point Polygon Coordinate)
(org.locationtech.jts.geom.prep PreparedGeometry
PreparedLineString
PreparedPolygon
PreparedGeometryFactory) (java.util TreeMap)))
Gathering geospatial data
Both the neighborhood geometry and park geometry can be downloaded from Seattle GeoData:
I’ve saved a snapshot in the data
directory.
The data format is gzipped GeoJSON. Java has a built-in class for handling gzip streams, and we’ll use the factual/geojson library to parse the string representation.
defn slurp-gzip
("Read a gzipped file into a string"
path]
[with-open [in (java.util.zip.GZIPInputStream. (clojure.java.io/input-stream path))]
(slurp in))) (
Now we can conveniently load the data files we downloaded previously.
defonce neighborhoods-geojson
("data/Seattle/Neighborhood_Map_Atlas_Neighborhoods.geojson.gz")) (slurp-gzip
def neighborhoods-features
( (geoio/read-geojson neighborhoods-geojson))
Let’s check that we got some data.
count neighborhoods-features) (
94
This seems like a reasonable number of neighborhoods.
Each member of the dataset is called a Feature. Here is one:
-> neighborhoods-features
(first
kind/pprint)
:properties
{:OBJECTID 27,
{:L_HOOD "Ballard",
:S_HOOD "Loyal Heights",
:S_HOOD_ALT_NAMES nil,
:Shape__Area 2.13206555455933E7,
:Shape__Length 18831.00959637},
:geometry
0x734a2288 "POLYGON ((-122.376336564723 47.6759176989664, -122.376707907517 47.6759982290459, -122.377903057631 47.6759978849021, -122.379988625303 47.6759893429385, -122.38182788443 47.675992079457, -122.383602752477 47.675979810424, -122.385435721425 47.6759587956618, -122.387087434206 47.6759521343769, -122.387702391216 47.6759476875929, -122.388955759168 47.6759424488678, -122.390449346263 47.6759259868868, -122.391773109273 47.6759158131504, -122.392827172066 47.6759153143353, -122.392956550545 47.6759141859541, -122.392956303464 47.6763287099834, -122.392959618409 47.676929558447, -122.392961263359 47.6775085790216, -122.392971502986 47.6781034200237, -122.392975009807 47.6792517755972, -122.392983771129 47.6798142464259, -122.39300195772 47.6811303942788, -122.393014530791 47.6824285808909, -122.393016158048 47.6837341155494, -122.393022827056 47.685021586284, -122.393030577589 47.6863450742964, -122.393032746621 47.687668638629, -122.393046187318 47.6889956475812, -122.393010665051 47.6902980913372, -122.393002415356 47.6905813205566, -122.392432373275 47.6905826938111, -122.390347910813 47.6905631204492, -122.388192979124 47.6905805029145, -122.385832831602 47.6905766041982, -122.383275316007 47.690593164597, -122.383201215024 47.6905936585447, -122.381453020656 47.6905978829044, -122.379876313408 47.6905988541749, -122.379103841332 47.6906041929746, -122.377117910432 47.6906029639028, -122.376810344766 47.6906051591463, -122.376810264834 47.6905341242701, -122.376810989127 47.6900117143006, -122.376803067488 47.688976146724, -122.376794751014 47.6879443550321, -122.376800402808 47.6870068457338, -122.376784403749 47.6860923366759, -122.376785260609 47.6851813698577, -122.376780535885 47.6842704786057, -122.376787310842 47.6833707854178, -122.376777423242 47.6822860591882, -122.376767820487 47.6811938310584, -122.376770442503 47.680154307228, -122.376770065639 47.6792017979916, -122.376769882216 47.6780678404081, -122.376759750881 47.6775387646826, -122.376761985459 47.676862137338, -122.376772171763 47.6764361697665, -122.376772451106 47.6764114022001, -122.376770700102 47.6763866189683, -122.37676692258 47.6763619488292, -122.376761120573 47.6763374777451, -122.376753802121 47.6763131984825, -122.376744969247 47.6762891966531, -122.376733608705 47.6762655291531, -122.376721246367 47.6762423037704, -122.376706358898 47.6762194979699, -122.376690473449 47.6761972626929, -122.376672575492 47.6761756116819, -122.376653693551 47.6761550023704, -122.376620811506 47.6761243856628, -122.37659791092 47.6761051588887, -122.376573006221 47.6760868163511, -122.376547112434 47.6760693435982, -122.376519722058 47.6760527482053, -122.376336564723 47.6759176989664))"]} #object[org.locationtech.jts.geom.Polygon
Each feature, in our case, represents a geographic region with a geometry and some properties.
And similarly for the parks:
defonce parks-geojson
("data/Seattle/Park_Boundary_(details).geojson.gz")) (slurp-gzip
def parks-features
( (geoio/read-geojson parks-geojson))
count parks-features) (
2809
There are more parks than neighborhoods, which sounds right.
delay
(-> parks-features
(first
kind/pprint))
:properties
{:SE_ANNO_CAD_DATA "",
{:NAMEFLAG 9,
:ADDRESS " ",
:MAINT "DPR",
:LEASE "N",
:PMA_NAME "East Duwamish GS: S Chicago St",
:SUBPARCEL 9851,
:PMA 442,
:REVIEW_DATE "2004-04-08T00:00:00Z",
:GlobalID "{D4B7025E-1135-4232-88AB-CBF72932E6AE}",
:OBJECTID 207882,
:AMWOID "PROPERTY-EDUWSC",
:SDQL "QL-D1",
:USE_ nil,
:PIN "4006000485",
:GIS_EDT_DT "2024-01-19T14:07:23Z",
:SHAPE_Area 1.4691943312522366E-6,
:SHAPE_Length 0.005215887160444538,
:GIS_CRT_DT "2024-01-19T14:07:23Z",
:NAME "EAST DUWAMISH GREENBELT",
:OWNER "DPR",
:ACQ_DATE "1997-10-21T00:00:00Z"},
:geometry
0x1788033d "MULTIPOLYGON (((-122.28235899499998 47.525165833000074, -122.28168484899999 47.525164389000054, -122.28168307199996 47.52516438600003, -122.28145050399996 47.52516388600003, -122.281450582 47.525147437000044, -122.28092621899998 47.525146310000025, -122.28092721899998 47.52433074500004, -122.28129411599997 47.52433142700005, -122.28247185299995 47.52433360800006, -122.28270306299999 47.52433403400005, -122.28270162899997 47.52516656600005, -122.28235899499998 47.525165833000074)))"]} #object[org.locationtech.jts.geom.MultiPolygon
And the parks are defined as geographic regions.
Drawing a map
def Seattle-center
(47.608013 -122.335167]) [
The map we will create is A choropleth, though for now, we will use a fixed color, which is not so informative.
We will enrich every feature (e.g., neighborhood) with data relevant for its visual representation.
defn enrich-feature [{:as feature :keys [geometry]}
(:keys [tooltip-keys
{
style]}]-> feature
(update :properties
(fn [properties]
(-> properties
(assoc :tooltip (-> properties
(select-keys tooltip-keys)
(->> (map (fn [[k v]]
(:p [:b k] ": " v]))
[into [:div]))
(
hiccup/html):style style))))))
def neighborhoods-enriched-features
(-> neighborhoods-geojson
(:key-fn keyword})
(charred/read-json {:features
->> (mapv (fn [feature]
(-> feature
(
(enrich-feature:tooltip-keys [:L_HOOD :S_HOOD]
{:style {:opacity 0.3
:fillOpacity 0.1
:color "purple"
:fillColor "purple"}})))))))
Here is how we may generate a Choroplet map in Leaflet:
defn choropleth-map [details]
(delay
(
(kind/reagentfn [{:keys [provider
['(
center
enriched-features]}]:div
[:style {:height "900px"}
{:ref (fn [el]
let [m (-> js/L
(map el)
(.
(.setView (clj->js center)11))]
-> js/L
(
.-tileLayer
(.provider provider)
(.addTo m))-> js/L
(
(.geoJson (clj->js enriched-features):style (fn [feature]
(clj->js {-> feature
(
.-properties
.-style))}))fn [layer]
(.bindTooltip (-> layer
(
.-feature
.-properties
.-tooltip)))
(.addTo m))))}])
details]:reagent/deps [:leaflet]}))) {
We pick a tile layer provider from leaflet-providers.
defn Seattle-choropleth-map [enriched-features]
(
(choropleth-map:provider "OpenStreetMap.Mapnik"
{:center Seattle-center
:enriched-features enriched-features}))
For our basic neighborhoods map:
delay
(
(Seattle-choropleth-map neighborhoods-enriched-features))
Now, let us see the parks:
def parks-enriched-features
(-> parks-geojson
(:key-fn keyword})
(charred/read-json {:features
->> (mapv (fn [feature]
(-> feature
(
(enrich-feature:tooltip-keys [:PMA_NAME :NAME]
{:style {:opacity 0.3
:fillOpacity 0.1
:color "darkgreen"
:fillColor "darkgreen"}})))))))
Coordinate conversions
Both datasets use the WGS84 coordinate system.
For area computations we need to convert them to a coordinate system which is locally correct in terms of distances in a region around Seattle.
United States (USA) - Oregon and Washington. [1 3]:
Center coordinates | Projected bounds | WGS84 bounds |
---|---|---|
[1692592.39 -541752.55] | [[559165.71 -1834123.81] [2832684.98 777497.1]] | [[-124.79 41.98] [-116.47 49.05]] |
def crs-transform
(4326)
(geo.crs/create-transform (geo.crs/create-crs 2285))) (geo.crs/create-crs
defn wgs84->Seattle
("Transforming latitude-longitude coordinates
to local Euclidean coordinates around Seattle."
[geometry] (geo.jts/transform-geom geometry crs-transform))
Some geometrical functions
defn area [geometry]
( (.getArea geometry))
defn buffer [geometry radius]
( (.buffer geometry radius))
defn intersection [geometry1 geometry2]
(intersection geometry1 geometry2)) (.
Geometry datasets
defn geojson->dataset [geojson dataset-name]
(-> geojson
(->> (map (fn [{:keys [geometry properties]}]
(assoc properties :geometry geometry))))
(
tc/dataset:geometry [:geometry] wgs84->Seattle)
(tc/map-columns (tc/set-dataset-name dataset-name)))
def neighborhoods
(-> neighborhoods-features
("Seattle neighborhoods")
(geojson->dataset :feature neighborhoods-enriched-features))) (tc/add-column
delay
(-> neighborhoods
(:geometry :feature])
(tc/drop-columns [:element/max-height "600px"}))) (kind/table {
OBJECTID | L_HOOD | S_HOOD | S_HOOD_ALT_NAMES | Shape__Area | Shape__Length |
---|---|---|---|---|---|
27 | Ballard | Loyal Heights | 2.13206555455933E7 | 18831.00959637 | |
28 | Ballard | Ballard | Adams | 2.25521329700012E7 | 29926.3393002841 |
29 | Ballard | Whittier Heights | 1.41956874919434E7 | 15934.4392663199 | |
30 | Ballard | West Woodland | 2.21993668730164E7 | 21789.6510873493 | |
31 | North Central | Phinney Ridge | Woodland Park | 3.21231178777466E7 | 27120.7859379681 |
32 | North Central | Wallingford | Meridian, Tangle Town, Northlake | 4.20683426137695E7 | 33040.2469861198 |
33 | North Central | Fremont | 2.65037565718689E7 | 25999.2849357187 | |
34 | North Central | Green Lake | 3.73146297898865E7 | 25387.7074962486 | |
35 | Northeast | View Ridge | 2.56129799440918E7 | 22657.0394732799 | |
36 | Northeast | Ravenna | University Village | 3.67833915366516E7 | 31163.6208763331 |
37 | Northeast | Sand Point | 1.92498571397095E7 | 21396.6958008648 | |
38 | Northeast | Bryant | 1.54850780333252E7 | 20928.0017243062 | |
39 | Northeast | Windermere | Hawthorne Hills | 2.23639666230164E7 | 33332.8291968304 |
40 | Northeast | Laurelhurst | 1.90517768183594E7 | 26489.2422321737 | |
41 | Northeast | Roosevelt | Fairview | 2.1491594324707E7 | 22866.0797374364 |
42 | University District | University of Washington | 2.55236751180115E7 | 30983.2126641678 | |
43 | Queen Anne | East Queen Anne | 1.93546995965576E7 | 21488.397378299 | |
44 | Queen Anne | West Queen Anne | 1.79749859528503E7 | 20631.7057292923 | |
45 | Queen Anne | Lower Queen Anne | Uptown, Seattle Center | 1.75156244566956E7 | 20496.7289222394 |
46 | Queen Anne | North Queen Anne | 2.9604288333252E7 | 26753.5542817429 | |
47 | Cascade | Westlake | 3645184.07894897 | 11017.3231739615 | |
48 | Cascade | Eastlake | 7426907.96139526 | 16672.5117837403 | |
49 | Cascade | South Lake Union | 1.6107105419342E7 | 29323.5462843847 | |
50 | Magnolia | Lawton Park | 5.5091525290863E7 | 38766.0673349107 | |
51 | Magnolia | Briarcliff | Carleton Park | 2.65509365782471E7 | 26609.7912261135 |
52 | Magnolia | Southeast Magnolia | 1.84692638882751E7 | 20223.1801501522 | |
53 | Central Area | Madrona | 1.38454828085938E7 | 17052.9427067693 | |
54 | Central Area | Harrison/Denny-Blaine | 1.36033956731873E7 | 17241.2743191595 | |
55 | Central Area | Minor | Central District, Squire Park | 1.7933144708252E7 | 18241.5487859812 |
56 | Central Area | Leschi | 1.80917413764954E7 | 20413.0560516882 | |
57 | Central Area | Mann | Central District, Garfield | 1.11338288620605E7 | 17843.105758736 |
58 | Central Area | Atlantic | Judkins Park, Jackson Place, Coleman | 2.06649862726135E7 | 25426.2311626675 |
59 | Downtown | Pike-Market | Pike Place Market | 2343359.32580566 | 7326.58173024624 |
60 | Downtown | Belltown | Denny Regrade | 9845864.78594971 | 17836.7271544608 |
61 | Downtown | International District | Chinatown, ID, Little Saigon | 6169375.81655884 | 11772.3871410021 |
62 | Downtown | Central Business District | Commercial Core, West Edge | 9477398.61834717 | 18209.4628624588 |
63 | Downtown | First Hill | 9517568.47363281 | 13225.2335159542 | |
64 | Downtown | Yesler Terrace | 5348937.24771118 | 9611.35354641661 | |
65 | Downtown | Pioneer Square | 7545979.0869751 | 17297.5867148564 | |
66 | Interbay | Interbay | 3.35039410921631E7 | 64207.5867611718 | |
67 | Greater Duwamish | SODO | 4.96031675905914E7 | 38520.9885110863 | |
68 | Greater Duwamish | Georgetown | 5.13050726461182E7 | 45963.6656769607 | |
69 | Greater Duwamish | South Park | 2.94234521522369E7 | 30433.4048686311 | |
70 | Greater Duwamish | Harbor Island | 1.78323007354431E7 | 24381.2966280601 | |
71 | West Seattle | Seaview | 1.8463061797821E7 | 23122.2640032568 | |
72 | West Seattle | Gatewood | Morgan Junction | 2.28217074689484E7 | 23801.2647005122 |
73 | West Seattle | Arbor Heights | 2.61973140573883E7 | 28162.4351386166 | |
74 | West Seattle | Alki | 2.45834691841736E7 | 45568.1378536906 | |
75 | West Seattle | North Admiral | Belvidere | 4.85814163202972E7 | 30687.7844700837 |
76 | West Seattle | Fairmount Park | 1.61539000976257E7 | 24955.7128414259 | |
77 | West Seattle | Genesee | Alaska Junction, West Seattle Junction | 2.11649765813446E7 | 19870.8696089241 |
78 | West Seattle | Fauntleroy | Endolyne, Arroyo Heights, Brace Point | 3.38818638706665E7 | 42276.5317877774 |
79 | Beacon Hill | North Beacon Hill | Jefferson Park | 4.84759144557953E7 | 33865.4891739901 |
80 | Beacon Hill | Mid-Beacon Hill | 5.26204707883301E7 | 40522.1829275323 | |
81 | Beacon Hill | South Beacon Hill | 3.84488268989563E7 | 38996.7151070849 | |
82 | Beacon Hill | Holly Park | New Holly | 8444235.97859192 | 15848.3624185113 |
83 | Rainier Valley | Brighton | 1.8366938275177E7 | 18911.3293490837 | |
84 | Rainier Valley | Dunlap | 1.96016012150879E7 | 20847.6531922997 | |
85 | Rainier Valley | Rainier Beach | 3.31282361414948E7 | 34965.6132100475 | |
86 | Rainier Valley | Rainier View | Lake Ridge | 1.82485661794434E7 | 34791.8218147105 |
87 | Rainier Valley | Mount Baker | North Rainier | 2.89869952343292E7 | 26318.9819054871 |
88 | Rainier Valley | Columbia City | Columbia Heights | 3.74065764927979E7 | 35177.0608039675 |
89 | Delridge | Highland Park | 3.98103334158325E7 | 31111.0630837714 | |
90 | Delridge | North Delridge | Avalon, Luna Park, Pigeon Point | 2.94546565672607E7 | 23549.9313666304 |
91 | Delridge | Riverview | 3.30382671929626E7 | 25917.1176391015 | |
92 | Delridge | High Point | 2.33430083368683E7 | 23180.3963596714 | |
93 | Delridge | South Delridge | White Center | 1.79233162238464E7 | 23416.3405359794 |
94 | Delridge | Roxhill | Westwood Village | 1.87810598441162E7 | 22360.0472289145 |
95 | Seward Park | Seward Park | Lakewood, Hillman City | 4.38352790059662E7 | 52212.7868103531 |
96 | Northeast | Wedgwood | 3.05997136261597E7 | 23840.2187274324 | |
97 | Capitol Hill | Portage Bay | Roanoke Park | 4421635.26721191 | 10013.2739563989 |
98 | Capitol Hill | Montlake | North Capitol Hill | 2.1474786741394E7 | 46165.83098345 |
99 | Capitol Hill | Madison Park | Broadmoor, Washington Park | 2.46809502223511E7 | 26230.4347480002 |
100 | Capitol Hill | Broadway | Pike/Pine | 3.02392405212402E7 | 26851.9474418256 |
101 | Capitol Hill | Stevens | Interlaken Park, Miller Park, Madison-Miller | 2.60395920790405E7 | 25522.3456368768 |
102 | Lake City | Victory Heights | 2.15127314890137E7 | 20753.0018992847 | |
103 | Lake City | Matthews Beach | 3.09809783014832E7 | 31369.8925404597 | |
104 | Lake City | Meadowbrook | 1.70348487789307E7 | 18770.2820324215 | |
105 | Lake City | Olympic Hills | 2.58367421641541E7 | 19993.8160570763 | |
106 | Lake City | Cedar Park | 2.04414858487244E7 | 22788.760382662 | |
110 | Northwest | Broadview | 4.81134497303162E7 | 34640.309665739 | |
111 | Northwest | Bitter Lake | 2.76903364438171E7 | 26446.2030540938 | |
112 | Northgate | Haller Lake | 4.72030810796204E7 | 29413.5534484151 | |
113 | Northgate | Pinehurst | Jackson Park | 2.94388508770142E7 | 26171.2717608103 |
114 | Northwest | North Beach/Blue Ridge | 3.10622649915771E7 | 32947.8059119899 | |
115 | Northgate | Licton Springs | North College Park | 2.17047062611389E7 | 20132.8982458333 |
116 | Northgate | Maple Leaf | Olympic View | 3.43804707826233E7 | 25503.0574082691 |
117 | Northwest | Crown Hill | 1.58657504196777E7 | 18997.8080379411 | |
118 | Northwest | Greenwood | 4.20445636731262E7 | 26501.5265911049 | |
119 | Ballard | Sunset Hill | Golden Gardens, Shilshole | 2.43356204689941E7 | 29416.7300633571 |
121 | University District | University District | 1.36862548569946E7 | 21581.6459789299 | |
123 | University District | University Heights | Cowen Park | 1.03757480522461E7 | 15163.9069096811 |
124 | Downtown | Denny Triangle | Denny Regrade | 5128172.31045532 | 10574.1779826691 |
126 | Greater Duwamish | Industrial District | 6.24341310114746E7 | 88995.7569839975 |
def parks
(-> parks-features
("Seattle parks")
(geojson->dataset ;; avoiding some [linestring pathologies](https://gis.stackexchange.com/questions/50399/fixing-non-noded-intersection-problem-using-postgis)
:geometry [:geometry] #(buffer % 1)))) (tc/map-columns
delay
(-> parks
(:geometry :feature])
(tc/drop-columns [20)
(tc/head :element/max-height "600px"}))) (kind/table {
SE_ANNO_CAD_DATA | NAMEFLAG | ADDRESS | MAINT | LEASE | PMA_NAME | SUBPARCEL | PMA | REVIEW_DATE | GlobalID | OBJECTID | AMWOID | SDQL | USE_ | PIN | GIS_EDT_DT | SHAPE_Area | SHAPE_Length | GIS_CRT_DT | NAME | OWNER | ACQ_DATE |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
9 | DPR | N | East Duwamish GS: S Chicago St | 9851 | 442 | 2004-04-08T00:00:00Z | {D4B7025E-1135-4232-88AB-CBF72932E6AE} | 207882 | PROPERTY-EDUWSC | QL-D1 | 4006000485 | 2024-01-19T14:07:23Z | 1.4691943312522366E-6 | 0.005215887160444538 | 2024-01-19T14:07:23Z | EAST DUWAMISH GREENBELT | DPR | 1997-10-21T00:00:00Z | |||
9 | DPR | N | East Duwamish GS: S Chicago St | 4779 | 443 | 2004-04-08T00:00:00Z | {26B4F4BC-F9AE-42D4-B062-51387C6D9FFF} | 207883 | PROPERTY-EDUWC | QL-D1 | 0603001220 | 2024-01-19T14:07:23Z | 1.460570191594512E-7 | 0.0015461198840460832 | 2024-01-19T14:07:23Z | EAST DUWAMISH GREENBELT | DPR | 1994-10-06T00:00:00Z | |||
9 | DPR | N | East Duwamish GS: S Chicago St | 4711 | 443 | 2004-04-08T00:00:00Z | {E97D7F7F-2666-4008-A905-2F416A66C2A1} | 207884 | PROPERTY-EDUWC | QL-D1 | 0603001220 | 2024-01-19T14:07:23Z | 9.743577447048599E-8 | 0.0013271653095071236 | 2024-01-19T14:07:23Z | EAST DUWAMISH GREENBELT | DPR | 1994-10-06T00:00:00Z | |||
9 | DPR | N | East Duwamish GS: S Chicago St | 4779 | 443 | 2004-04-08T00:00:00Z | {C28A4700-BB4F-4C25-928E-57022F6D001B} | 207885 | PROPERTY-EDUWC | QL-D1 | 0603001220 | 2024-01-19T14:07:23Z | 4.87386722719263E-8 | 0.0011082207640129814 | 2024-01-19T14:07:23Z | EAST DUWAMISH GREENBELT | DPR | 1994-10-06T00:00:00Z | |||
9 | DPR | N | East Duwamish GS: S Chicago St | 4712 | 443 | 2004-04-08T00:00:00Z | {4DB6A932-327A-4E2E-AC8A-C068D114AA61} | 207886 | PROPERTY-EDUWC | QL-D1 | 0603001220 | 2024-01-19T14:07:23Z | 9.757207624044397E-8 | 0.0013284113092379031 | 2024-01-19T14:07:23Z | EAST DUWAMISH GREENBELT | DPR | 1994-10-06T00:00:00Z | |||
9 | DPR | N | Genesee Park and Playfield | 4618 | 409 | 1899-12-30T00:00:01Z | {AD2E47C9-323B-4DDE-8186-98A4FC79C3F8} | 207887 | PROPERTY-GENPK | QL-D1 | 4154300585 | 2024-01-19T14:07:23Z | 2.892289652506793E-6 | 0.007000440212562059 | 2024-01-19T14:07:23Z | GENESEE PARK AND PLAYFIELD | DPR | 1996-06-03T00:00:00Z | |||
9 | 5244 SW JACOBSEN ROAD | DPR | N | Wolf Creek Ravine Natural Area | 16397 | 278 | 2004-04-19T00:00:00Z | {A7E54352-0DC3-47E4-B562-DAA0F18B78E2} | 207888 | PROPERTY-WLFCRAV | QL-D1 | 5344200125 | 2024-01-19T14:07:23Z | 6.25557675764001E-8 | 0.0010504796990982068 | 2024-01-19T14:07:23Z | WOLF CREEK RAVINE NATURAL AREA | DPR | 2004-04-07T00:00:00Z | ||
9 | DPR | N | Jefferson Park | 15550 | 114 | 2004-04-08T00:00:00Z | {B82B7BD2-DCD9-49A2-BE5D-30C1D9BF4392} | 207889 | PROPERTY-JEFFPK | QL-D1 | 1624049270 | 2024-01-19T14:07:23Z | 3.2670040661028276E-6 | 0.018380332716286137 | 2024-01-19T14:07:23Z | JEFFERSON PARK | DPR | 1988-07-25T00:00:00Z | |||
9 | DPR | N | Queen Anne Boulevard | 753 | 328 | 2004-04-09T00:00:00Z | {3DA31C7B-C33D-4DD9-9092-71B1DA135BC8} | 207890 | PROPERTY-QABL | QL-D1 | 2533300180 | 2024-01-19T14:07:23Z | 5.790553187521671E-9 | 4.111515370853996E-4 | 2024-01-19T14:07:23Z | QUEEN ANNE BOULEVARD | DPR | 1910-07-25T00:00:01Z | |||
9 | DPR | N | Queen Anne Boulevard | 4688 | 328 | 2004-04-09T00:00:00Z | {D3DA12EE-31E0-4476-95CE-1739E8FF8550} | 207891 | PROPERTY-QABL | QL-D1 | 2533300180 | 2024-01-19T14:07:23Z | 5.139665582905777E-9 | 3.9228813174494234E-4 | 2024-01-19T14:07:23Z | QUEEN ANNE BOULEVARD | DPR | 1910-07-25T00:00:01Z | |||
7 | DPR | N | Ravenna Woods | 15807 | 4411 | 2004-05-05T00:00:00Z | {B1A2F3C6-C43A-4600-8064-A3DEFAE61DDC} | 207892 | PROPERTY-RAVWOOD | QL-D1 | 0925049168 | 2024-01-19T14:07:23Z | 5.585829095854119E-7 | 0.0030915009702507513 | 2024-01-19T14:07:23Z | RAVENNA WOODS | DPR | 2002-07-02T00:00:00Z | |||
9 | DPR | N | Montlake Playfield | 1507 | 376 | 1998-10-15T00:00:00Z | {BF38EE1A-DBAB-400C-B083-B3F8B6A1EB39} | 207893 | PROPERTY-MTLKPF | QL-D1 | 4089400080 | 2024-01-19T14:07:23Z | 3.917576385699785E-7 | 0.0026768636765498316 | 2024-01-19T14:07:23Z | MONTLAKE PLAYFIELD | DPR | 1933-12-31T00:00:01Z | |||
9 | DPR | N | Montlake Playfield | 1507 | 376 | 2004-03-30T00:00:00Z | {4CC47610-4927-465F-A346-04F66008D480} | 207894 | PROPERTY-MTLKPF | QL-D1 | 6788202280 | 2024-01-19T14:07:23Z | 1.1273410584671711E-6 | 0.004459900867682873 | 2024-01-19T14:07:23Z | MONTLAKE PLAYFIELD | DPR | 1933-12-31T00:00:01Z | |||
9 | DPR | N | Montlake Playfield | 1507 | 376 | 2004-03-30T00:00:00Z | {10310B09-822A-4344-95CC-2D5D90C2466C} | 207895 | PROPERTY-MTLKPF | QL-D1 | 6788202280 | 2024-01-19T14:07:23Z | 1.4591960880701082E-6 | 0.006312257575513224 | 2024-01-19T14:07:23Z | MONTLAKE PLAYFIELD | DPR | 1933-12-31T00:00:01Z | |||
9 | 4357 PALATINE AVE N | DPR | N | Fremont Peak Park | 16454 | 4424 | 2004-10-06T00:00:00Z | {A13D75B6-B355-4BDF-84CF-4D2838170201} | 207896 | PROPERTY-FRMPKPK | QL-D1 | 6610000810 | 2024-01-19T14:07:23Z | 6.118914081332531E-8 | 0.0011669443524576426 | 2024-01-19T14:07:23Z | FREMONT PEAK PARK | DPR | 2004-09-30T00:00:00Z | ||
9 | DPR | N | SW Queen Anne Greenbelt | 16459 | 234 | 2005-01-06T00:00:00Z | {A13C70F6-F0AE-4E55-A12C-990BBC545F8D} | 207897 | PROPERTY-SWQAGRB | QL-D1 | 7705100037 | 2024-01-19T14:07:23Z | 5.565195258199712E-9 | 3.556012201607765E-4 | 2024-01-19T14:07:23Z | SW QUEEN ANNE GREENBELT | DPR | 2004-11-04T00:00:00Z | |||
3 | 9026 4TH AVE S | DPR | N | Marra-Desimone Park | 16455 | 4447 | 2007-02-21T00:00:00Z | {E641A30D-FE4B-4B1D-9358-7F0F71324691} | 207898 | PROPERTY-MARDESPK | QL-D1 | 3224049044 | 2024-01-19T14:07:23Z | 2.211413981358282E-6 | 0.006388002898489655 | 2024-01-19T14:07:23Z | MARRA-DESIMONE PARK | DPR | 2004-12-28T00:00:00Z | ||
9 | 9026 4TH AVE S | DPR | N | Marra-Desimone Park | 16455 | 4447 | 2007-02-21T00:00:00Z | {6A440787-F078-4DB9-9187-DA0E029A8E18} | 207899 | PROPERTY-MARDESPK | QL-D1 | 3224049035 | 2024-01-19T14:07:23Z | 1.981420659558925E-6 | 0.009774073825241834 | 2024-01-19T14:07:23Z | MARRA-DESIMONE PARK | DPR | 2004-12-28T00:00:00Z | ||
9 | DPR | Y | Meadowbrook Playfield | 803 | 352 | {49C14F14-94FF-4080-9DE8-56EDF006145A} | 207900 | PROPERTY-MBPF | QL-D1 | 2024-01-19T14:07:23Z | 5.268695375108406E-7 | 0.00550990095454217 | 2024-01-19T14:07:23Z | MEADOWBROOK PLAYFIELD | SSD1 | ||||||
9 | DPR | N | Meadowbrook Teen Life Center | 352 | {D099D793-CFEA-44E9-A57B-D8A1BA4525AF} | 207901 | PROPERTY-MBPF | QL-D1 | 2024-01-19T14:07:23Z | 8.504523207167994E-8 | 0.0011865488770908574 | 2024-01-19T14:07:23Z | MEADOWBROOK TEEN LIFE CENTER | SSD1 |
A Spatial index structure
We need an index structure to quickly match between the two sets of geometries.
See the JTS SearchUsingPreparedGeometryIndex tutorial.
defn make-spatial-index [dataset & {:keys [geometry-column]
(:or {geometry-column :geometry}}]
let [tree (org.locationtech.jts.index.strtree.STRtree.)]
(doseq [row (tc/rows dataset :as-maps)]
(let [geometry (row geometry-column)]
(
(.insert tree
(.getEnvelopeInternal geometry)assoc row
(:prepared-geometry
(org.locationtech.jts.geom.prep.PreparedGeometryFactory/prepare geometry))))) tree))
def parks-index
( (make-spatial-index parks))
defn intersecting-places [region spatial-index]
(->> (.query spatial-index (.getEnvelopeInternal region))
(filter (fn [row]
(:prepared-geometry row) region)))
(.intersects ( tc/dataset))
For example, let us find the parks intersecting with the first neighborhood:
delay
(-> neighborhoods
(:geometry
first
(intersecting-places parks-index):PMA_NAME :NAME]))) (tc/select-columns [
_unnamed [2 2]:
:PMA_NAME | :NAME |
---|---|
Salmon Bay Park | SALMON BAY PARK |
Loyal Heights Playfield | LOYAL HEIGHTS PLAYFIELD |
A Joined dataset
We compute a spatial join of the two datasets.
Note that even though many parks will appear as intersecting many neighbourhoods, this is not too memory-heavy, since they are references to the same map.
def neighborhoods-with-parks
(-> neighborhoods
(:parks
(tc/map-columns :geometry]
[% parks-index)))) #(intersecting-places
delay
(-> neighborhoods-with-parks
(:n-parks
(tc/map-columns :parks]
[
tc/row-count):L_HOOD :S_HOOD :n-parks])
(tc/select-columns [:element/max-height "600px"}))) (kind/table {
L_HOOD | S_HOOD | n-parks |
---|---|---|
Ballard | Loyal Heights | 2 |
Ballard | Ballard | 7 |
Ballard | Whittier Heights | 4 |
Ballard | West Woodland | 5 |
North Central | Phinney Ridge | 11 |
North Central | Wallingford | 27 |
North Central | Fremont | 15 |
North Central | Green Lake | 19 |
Northeast | View Ridge | 15 |
Northeast | Ravenna | 12 |
Northeast | Sand Point | 17 |
Northeast | Bryant | 9 |
Northeast | Windermere | 5 |
Northeast | Laurelhurst | 7 |
Northeast | Roosevelt | 22 |
University District | University of Washington | 3 |
Queen Anne | East Queen Anne | 62 |
Queen Anne | West Queen Anne | 46 |
Queen Anne | Lower Queen Anne | 6 |
Queen Anne | North Queen Anne | 19 |
Cascade | Westlake | 3 |
Cascade | Eastlake | 18 |
Cascade | South Lake Union | 33 |
Magnolia | Lawton Park | 83 |
Magnolia | Briarcliff | 36 |
Magnolia | Southeast Magnolia | 34 |
Central Area | Madrona | 30 |
Central Area | Harrison/Denny-Blaine | 33 |
Central Area | Minor | 14 |
Central Area | Leschi | 43 |
Central Area | Mann | 11 |
Central Area | Atlantic | 71 |
Downtown | Pike-Market | 13 |
Downtown | Belltown | 15 |
Downtown | International District | 8 |
Downtown | Central Business District | 8 |
Downtown | First Hill | 7 |
Downtown | Yesler Terrace | 5 |
Downtown | Pioneer Square | 18 |
Interbay | Interbay | 35 |
Greater Duwamish | SODO | 0 |
Greater Duwamish | Georgetown | 4 |
Greater Duwamish | South Park | 10 |
Greater Duwamish | Harbor Island | 0 |
West Seattle | Seaview | 3 |
West Seattle | Gatewood | 15 |
West Seattle | Arbor Heights | 15 |
West Seattle | Alki | 68 |
West Seattle | North Admiral | 180 |
West Seattle | Fairmount Park | 5 |
West Seattle | Genesee | 9 |
West Seattle | Fauntleroy | 35 |
Beacon Hill | North Beacon Hill | 158 |
Beacon Hill | Mid-Beacon Hill | 74 |
Beacon Hill | South Beacon Hill | 93 |
Beacon Hill | Holly Park | 2 |
Rainier Valley | Brighton | 5 |
Rainier Valley | Dunlap | 26 |
Rainier Valley | Rainier Beach | 76 |
Rainier Valley | Rainier View | 9 |
Rainier Valley | Mount Baker | 136 |
Rainier Valley | Columbia City | 75 |
Delridge | Highland Park | 23 |
Delridge | North Delridge | 116 |
Delridge | Riverview | 121 |
Delridge | High Point | 136 |
Delridge | South Delridge | 7 |
Delridge | Roxhill | 12 |
Seward Park | Seward Park | 56 |
Northeast | Wedgwood | 12 |
Capitol Hill | Portage Bay | 4 |
Capitol Hill | Montlake | 54 |
Capitol Hill | Madison Park | 29 |
Capitol Hill | Broadway | 37 |
Capitol Hill | Stevens | 40 |
Lake City | Victory Heights | 26 |
Lake City | Matthews Beach | 32 |
Lake City | Meadowbrook | 19 |
Lake City | Olympic Hills | 3 |
Lake City | Cedar Park | 11 |
Northwest | Broadview | 32 |
Northwest | Bitter Lake | 2 |
Northgate | Haller Lake | 3 |
Northgate | Pinehurst | 8 |
Northwest | North Beach/Blue Ridge | 32 |
Northgate | Licton Springs | 6 |
Northgate | Maple Leaf | 18 |
Northwest | Crown Hill | 5 |
Northwest | Greenwood | 36 |
Ballard | Sunset Hill | 9 |
University District | University District | 11 |
University District | University Heights | 21 |
Downtown | Denny Triangle | 3 |
Greater Duwamish | Industrial District | 5 |
Computing areas
For every neighborhood, we will compute the proportion of its area covered by parks.
TODO: L_HOOD should be used, S_HOOD produces too many rows to be understood (maybe S_HOOD would be interesting for looking at one L_HOOD at a time)
def neighborhoods-with-park-proportions
(-> neighborhoods-with-parks
(:neighborhood-area
(tc/map-columns :geometry]
[
area):intersection-area
(tc/map-columns :geometry :parks]
[fn [neigh-geometry parks]
(->> parks
(:geometry
map (fn [park-geometry]
(
(areaintersection (.buffer park-geometry 1)
(.
neigh-geometry))))
fun/sum))):park-names
(tc/map-columns :parks]
[fn [parks]
(->> parks
(:PMA_NAME
distinct
vec)))
:park-names-str
(tc/map-columns :park-names]
[partial str/join ","))
(:park-proportion
(tc/add-column :intersection-area %)
#(fun// (:neighborhood-area %))))) (
delay
(-> neighborhoods-with-park-proportions
(:L_HOOD
(tc/select-columns [:S_HOOD
:park-names
:neighborhood-area
:intersection-area
:park-proportion])
:park-proportion] :desc)
(tc/order-by [:element/max-height "600px"}))) (kind/table {
L_HOOD | S_HOOD | park-names | neighborhood-area | intersection-area | park-proportion |
---|---|---|---|---|---|
Northeast | Sand Point |
|
1.924985714007309E7 | 1.2694407322392896E7 | 0.6594546250406457 |
Magnolia | Lawton Park |
|
5.5091525292193405E7 | 2.5768911594667178E7 | 0.46774728886148104 |
Delridge | North Delridge |
|
2.945465656812994E7 | 1.3245569878227614E7 | 0.44969357723081976 |
North Central | Green Lake |
|
3.731462978987473E7 | 1.5314645167249074E7 | 0.41041932489987293 |
Seward Park | Seward Park |
|
4.3835279006813824E7 | 1.3252664479684925E7 | 0.30232873566573876 |
Delridge | Riverview |
|
3.303826719332341E7 | 8769575.924383609 | 0.2654369211638261 |
North Central | Phinney Ridge |
|
3.2123117878649313E7 | 8349752.958056866 | 0.25992971758219474 |
Northgate | Pinehurst |
|
2.9438850877818238E7 | 7646861.188494857 | 0.2597540651376668 |
Capitol Hill | Montlake |
|
2.14747867418963E7 | 5452986.107546446 | 0.25392504116969533 |
West Seattle | Fauntleroy |
|
3.3881863871407755E7 | 7399817.180664994 | 0.2184005345381709 |
Beacon Hill | North Beacon Hill |
|
4.847591445665426E7 | 1.046069634381901E7 | 0.2157916247907537 |
Delridge | Highland Park |
|
3.981033341691431E7 | 8327022.199101201 | 0.20916735642217155 |
Capitol Hill | Madison Park |
|
2.4680950222860403E7 | 4675806.696395554 | 0.18945002741688 |
Rainier Valley | Mount Baker |
|
2.8986995235084333E7 | 4682493.1951638255 | 0.16153772259555838 |
Delridge | High Point |
|
2.3343008337069765E7 | 3379054.5025715176 | 0.14475659922570583 |
Northwest | Broadview |
|
4.8113449731243916E7 | 6789015.469879707 | 0.14110431714629385 |
Central Area | Leschi |
|
1.8091741377063915E7 | 2488664.0659542754 | 0.13755801689213387 |
West Seattle | Alki |
|
2.45834691846126E7 | 3368610.236147073 | 0.13702745576102698 |
Capitol Hill | Stevens |
|
2.6039592079779927E7 | 3257296.7380544366 | 0.12509015994086056 |
Ballard | Sunset Hill |
|
2.4335620469794728E7 | 2999062.204514957 | 0.12323754835991878 |
West Seattle | North Admiral |
|
4.858141632113909E7 | 5960598.691665671 | 0.12269297898324247 |
Rainier Valley | Columbia City |
|
3.7406576493219726E7 | 4344458.806638756 | 0.11614157760270384 |
Central Area | Atlantic |
|
2.0664986273336366E7 | 2395983.464898887 | 0.11594411112628604 |
Queen Anne | West Queen Anne |
|
1.797498595288394E7 | 1964455.447449051 | 0.10928828832457976 |
Capitol Hill | Broadway |
|
3.0239240521690477E7 | 3304530.7655596808 | 0.10927955558901538 |
Downtown | Pike-Market |
|
2343359.3260714533 | 255005.04346191516 | 0.10882029086397978 |
Magnolia | Briarcliff |
|
2.6550936578728132E7 | 2713294.302010858 | 0.10219203733041468 |
Interbay | Interbay |
|
3.350394109364654E7 | 3234156.7950585634 | 0.09653063757540652 |
Rainier Valley | Dunlap |
|
1.9601601215604942E7 | 1782788.7703944917 | 0.0909511805073967 |
Central Area | Madrona |
|
1.3845482808694465E7 | 1211682.0145605851 | 0.08751460901021757 |
Magnolia | Southeast Magnolia |
|
1.8469263888735063E7 | 1466342.6454210556 | 0.07939367016762483 |
Beacon Hill | Holly Park |
|
8444235.979074124 | 656778.4801970643 | 0.07777831905984671 |
Beacon Hill | South Beacon Hill |
|
3.844882690015128E7 | 2989598.1245943466 | 0.07775524939572562 |
Rainier Valley | Rainier View |
|
1.8248566179783218E7 | 1398373.180214077 | 0.07662920836834146 |
Queen Anne | East Queen Anne |
|
1.9354699596494563E7 | 1448114.7496615453 | 0.07481979983423878 |
Rainier Valley | Rainier Beach |
|
3.312823614223316E7 | 2442620.8848146023 | 0.07373229514325559 |
Central Area | Harrison/Denny-Blaine |
|
1.360339567318952E7 | 946560.209820138 | 0.06958264190504156 |
Northeast | Ravenna |
|
3.678339153768188E7 | 2537736.5238547004 | 0.06899136859783514 |
Lake City | Meadowbrook |
|
1.703484877942584E7 | 1162909.7193452865 | 0.06826651262967551 |
Northwest | North Beach/Blue Ridge |
|
3.1062264992039643E7 | 1942086.5722656162 | 0.06252237474515514 |
Northeast | Roosevelt |
|
2.1491594324983705E7 | 1309062.5613024468 | 0.06091044440480054 |
Lake City | Matthews Beach |
|
3.0980978301755752E7 | 1770241.0308238121 | 0.05713961042745668 |
Northeast | Bryant |
|
1.5485078033882016E7 | 829201.5932133237 | 0.053548428454735265 |
Delridge | Roxhill |
|
1.87810598448122E7 | 995987.7545642204 | 0.053031498903366586 |
Northeast | View Ridge |
|
2.561297994427941E7 | 1288763.708935325 | 0.05031682028951758 |
Cascade | South Lake Union |
|
1.6107105419750454E7 | 800866.192857775 | 0.04972129827099516 |
Queen Anne | North Queen Anne |
|
2.960428833366627E7 | 1355843.879844315 | 0.04579890131330861 |
North Central | Wallingford |
|
4.2068342614797205E7 | 1777393.4021316427 | 0.04225014088162481 |
Lake City | Victory Heights |
|
2.151273148967749E7 | 900485.900698212 | 0.04185827825398623 |
Beacon Hill | Mid-Beacon Hill |
|
5.262047078955701E7 | 2161142.3873948674 | 0.041070373468109767 |
Central Area | Mann |
|
1.113382886245558E7 | 443902.819098556 | 0.03986973615118534 |
Cascade | Eastlake |
|
7426907.961769626 | 293104.7959594849 | 0.039465252224513386 |
Northgate | Maple Leaf |
|
3.4380470783073254E7 | 1130968.2364097128 | 0.03289565880425725 |
Northeast | Laurelhurst |
|
1.905177681936156E7 | 622689.0135556267 | 0.03268403884108136 |
Northeast | Wedgwood |
|
3.059971362703256E7 | 968985.0098010622 | 0.031666473144540686 |
Downtown | Yesler Terrace |
|
5348937.247801803 | 159300.53646585828 | 0.02978171720584764 |
Downtown | Belltown |
|
9845864.786277873 | 279689.8893769705 | 0.028406838347686095 |
Capitol Hill | Portage Bay |
|
4421635.267367266 | 121026.6277003076 | 0.027371463357349548 |
Greater Duwamish | South Park |
|
2.9423452152724065E7 | 788757.1095861244 | 0.0268070893072654 |
West Seattle | Arbor Heights |
|
2.619731405785146E7 | 661354.2410716552 | 0.0252451163356361 |
Lake City | Cedar Park |
|
2.04414858490784E7 | 500421.66464288835 | 0.02448068933626221 |
University District | University District |
|
1.3686254858800735E7 | 324977.58184178185 | 0.023744814428383235 |
Northgate | Licton Springs |
|
2.1704706262052845E7 | 513945.6292462934 | 0.023678994916639065 |
Northgate | Haller Lake |
|
4.720308108008111E7 | 1112625.044392759 | 0.023571025851155034 |
Northeast | Windermere |
|
2.2363966623912185E7 | 500567.5192937572 | 0.022382769913389885 |
Ballard | Loyal Heights |
|
2.1320655545884836E7 | 421263.7501266854 | 0.019758480184629914 |
Downtown | International District |
|
6169375.816795917 | 121130.99413208748 | 0.019634238167548886 |
Rainier Valley | Brighton |
|
1.8366938275487844E7 | 342712.9789050467 | 0.01865923289797433 |
Downtown | Central Business District |
|
9477398.618861396 | 176559.42602316735 | 0.018629524105041706 |
North Central | Fremont |
|
2.650375657209128E7 | 443605.6587439842 | 0.016737463519081116 |
Northwest | Bitter Lake |
|
2.769033644488096E7 | 463326.8142235621 | 0.016732437149900217 |
Northwest | Greenwood |
|
4.204456367454267E7 | 689596.1664853458 | 0.01640155364254346 |
University District | University Heights |
|
1.037574805292391E7 | 166849.97798407465 | 0.016080766141681316 |
West Seattle | Gatewood |
|
2.2821707469523415E7 | 355085.68614532915 | 0.015559120044787095 |
West Seattle | Fairmount Park |
|
1.6153900097573552E7 | 237376.26008061314 | 0.014694671791134142 |
Downtown | First Hill |
|
9517568.473671103 | 126769.23408250557 | 0.0133194979824094 |
Downtown | Pioneer Square |
|
7545979.087288558 | 95347.44250189843 | 0.0126355296508195 |
Ballard | Ballard |
|
2.255213297047855E7 | 244344.9612760165 | 0.01083467189537556 |
Cascade | Westlake |
|
3645184.079110308 | 37961.61985636592 | 0.010414184587800388 |
Ballard | West Woodland |
|
2.2199366873893585E7 | 226099.72709449235 | 0.010184962858575269 |
Central Area | Minor |
|
1.7933144708720244E7 | 172158.54773067622 | 0.009600019992420052 |
Greater Duwamish | Industrial District |
|
6.243413101303743E7 | 559378.0064992205 | 0.00895949054504197 |
Ballard | Whittier Heights |
|
1.4195687492422596E7 | 108946.50009691996 | 0.007674619503639655 |
Delridge | South Delridge |
|
1.792331622408078E7 | 132742.1724476857 | 0.007406116746929937 |
Queen Anne | Lower Queen Anne |
|
1.7515624457317874E7 | 106952.95177903834 | 0.006106145518229259 |
Northwest | Crown Hill |
|
1.586575041985613E7 | 94943.40486711139 | 0.005984173603808166 |
University District | University of Washington |
|
2.5523675124439575E7 | 142125.03524102044 | 0.005568360925614982 |
Greater Duwamish | Georgetown |
|
5.130507264703818E7 | 281438.2271119965 | 0.005485582859383083 |
Lake City | Olympic Hills |
|
2.5836742164596498E7 | 141195.81351923634 | 0.005464923271662082 |
West Seattle | Genesee |
|
2.1164976581792817E7 | 91891.1780685815 | 0.00434166216595916 |
West Seattle | Seaview |
|
1.846306179837895E7 | 51860.33722001134 | 0.002808869828110777 |
Downtown | Denny Triangle |
|
5128172.310711999 | 11668.172603196248 | 0.002275308218256073 |
Greater Duwamish | Harbor Island |
|
1.7832300735864956E7 | 0.0 | 0.0 |
Greater Duwamish | SODO |
|
4.9603167591402024E7 | 0.0 | 0.0 |
defn plot-neighborhoods-with-park-proportions [data]
(
(kind/echarts:title {:text "Neighborhoods by park proportion"}
{:tooltip {}
:xAxis {:data (:S_HOOD data)
:axisLabel {:rotate 90}}
:yAxis {}
:series [{:type "bar"
:data (:park-proportion data)}]
:grid {:containLabel true}}))
delay
(-> neighborhoods-with-park-proportions
(:park-proportion] :desc)
(tc/order-by [ plot-neighborhoods-with-park-proportions))
Note you may hover to see the neighborhood names. Let us take the ten most park-intense neighborhoods.
delay
(-> neighborhoods-with-park-proportions
(:park-proportion] :desc)
(tc/order-by [10)
(tc/head plot-neighborhoods-with-park-proportions))
Representing park proportions as colors:
We will use Clojure2d’s clojure.color functionality.
def gradient
(:purple :yellow])) (color/gradient [
delay
(-> 0.4
(
gradient color/format-hex))
"#b3664d"
A choropleth coloured by park proportions
def neighborhoods-coloured-by-park-proportion
(-> neighborhoods-with-park-proportions
(:feature
(tc/map-columns :feature :park-names-str :park-proportion]
[fn [feature park-names-str park-proportion]
(let [color (-> park-proportion
(
gradient
color/format-hex)]-> feature
(update-in
(:properties :style]
[fn [style]
(-> style
(assoc :color color
(:fillColor color
:opacity 0.7
:fillOpacity 0.7))))
update-in
(:properties :tooltip]
[str
(hiccup/html:div
[:p [:b "Park proportion: "]
[format "%.01f%%"
(* 100 park-proportion))]
(:p {:style {:max-width "200px"
[:text-wrap :wrap}}
:b "Parks: "]
[ park-names-str]]))))))))
delay
(-> neighborhoods-coloured-by-park-proportion
(:feature
vec
Seattle-choropleth-map))
Another option: use opacity rather than color to higlight differences.
def neighborhoods-highlighted-by-park-proportion
(-> neighborhoods-coloured-by-park-proportion
(:feature
(tc/map-columns :feature :park-proportion]
[fn [feature park-proportion]
(-> feature
(update-in
(:properties :style]
[fn [style]
(-> style
(assoc :color "yellow"
(:opacity park-proportion
:fillColor "yellow"
:fillOpacity park-proportion)))))))))
delay
(-> neighborhoods-highlighted-by-park-proportion
(:feature
vec
Seattle-choropleth-map))
In this case the choropleth mainly helps us in pointing out a few park-intense neighborhoods.
Let us focus on the ten most park-intense neighborhoods:
delay
(-> neighborhoods-coloured-by-park-proportion
(:park-proportion] :desc)
(tc/order-by [10)
(tc/head :feature
vec
Seattle-choropleth-map))
(kind/md"TODO: The area proportions would be best represented in a bar chart to accompany the table
TODO: summarizing the quartiles of values might be useful as well
TODO: An interesting map would show just one L_HOOD and all the parks,
perhaps choosing the \"winner\" with most park space and showing where in Seattle it is, and what parks are there.
## Conclusion
Park access is fairly uniform and high in Seattle.
TODO: can we compare it to another city?
"
)
TODO: The area proportions would be best represented in a bar chart to accompany the table TODO: summarizing the quartiles of values might be useful as well
TODO: An interesting map would show just one L_HOOD and all the parks, perhaps choosing the “winner” with most park space and showing where in Seattle it is, and what parks are there.
Conclusion
Park access is fairly uniform and high in Seattle. TODO: can we compare it to another city?
Draft text for the story to be told.
Intersections and spatial joins
In what context would these visualizations be useful?
Using the REPL to dive into cases and their details
Doing that in self-documenting way
How does this compose with GUI-based explorations?
Choice of colors