id | elm | ||||
---|---|---|---|---|---|
litvis |
|
@import "css/litvis.less"
import VegaLite exposing (..)
This document best viewed in litvis
How has London evolved over time? Perhaps compare my local work area (Clerkenwell) between two periods.
-
James Tyrer's Clerkenwell Map of 1805 digitized in LandSerf and georectified to match modern Ordnance Survey coordinates. Saved as a Shapefile and saved as topoJSON file
clerkenwell1805Polys.json
in mapshaper. -
1805 Clerkenwell boundary polygon extracted from file in mapshaper:
filter 'feature == "boundary"' o format=topojson clerkenwellBoundary.json
-
Building shadows generated by offsetting building objects by 2m east and south in mapshaper:
filter 'feature == "building"' affine shift=2,-2 o format=topojson clerkenwell1805BuildingsOffset.json
-
Modern Clerkenwell extracted from Open Street Map central London area (via Overpass API ), projected to Ordnance Survey grid coordinates, clipped to 1805 Clerkenwell boundary area, boundaries removed and saved as a topoJSON file:
mapshaper centralLondonPolysOSGB.json \ -clip clerkenwell1805Boundary.json \ -filter 'type != "boundary"' -o format=topojson 'clerkenwellPolys.json'
Location of generated files:
path : String -> String
path file =
"https://gicentre.github.io/data/30dayMapChallenge/" ++ file
Would like mimic the style of the Tyrer map, but text placement and orientation along roads and around features is challenging, so will stick to non-text layers for the maps. Keeping related colour schemes in both maps helps comparison. Also show the "Clerk's Well" (southern part of map as small circle) that gave rise to the name of the district on both. The River Fleet was technically outside Clerkenwell but added for context in the 1805 map especially as it adds to the contrast between the two time periods now that the Fleet has bee re-routed as part of the sewer system.
clerkenwell1805 : Spec
clerkenwell1805 =
let
w =
900
h =
w * 29 / 30
cfg =
configure
<< configuration (coView [ vicoStrokeWidth 2, vicoStroke (Just "#999") ])
data =
dataFromUrl (path "clerkenwell1805Polys.json") [ topojsonFeature "clerkenwell" ]
buildingsOffsetData =
dataFromUrl (path "clerkenwell1805BuildingsOffset.json") [ topojsonFeature "clerkenwell" ]
fleetData =
dataFromUrl (path "riverFleet.json") [ topojsonFeature "fleet" ]
wellData =
dataFromJson (geometry (geoPoint 531460 182070) [])
proj =
projection
[ prType identityProjection, prReflectY True ]
boundaryFilter =
transform << filter (fiExpr "datum.properties.feature == 'boundary'")
boundarySpec =
asSpec [ boundaryFilter [], geoshape [ maFill "rgb(235,227,200)", maStroke "#aaa", maStrokeWidth 2 ] ]
fieldsFilter =
transform << filter (fiExpr "datum.properties.name == 'field'")
fieldsSpec =
asSpec [ fieldsFilter [], geoshape [ maColor "rgb(222,235,171)", maStroke "rgb(184,176,140)", maStrokeOpacity 0.3, maFillOpacity 0.5 ] ]
gardensFilter =
transform << filter (fiExpr "datum.properties.name == 'garden'")
gardensSpec =
asSpec [ gardensFilter [], geoshape [ maColor "rgb(183,204,144)", maStroke "rgb(183,204,144)", maFillOpacity 0.5 ] ]
waterFilter =
transform << filter (fiExpr "datum.properties.feature == 'water'")
waterSpec =
asSpec [ waterFilter [], geoshape [ maColor "rgb(199,206,206)", maStroke "#99a", maFillOpacity 0.5, maStrokeOpacity 0.5 ] ]
fleetSpec =
asSpec [ fleetData, geoshape [ maFilled False, maStroke "#99c", maStrokeJoin joRound, maStrokeWidth 8, maStrokeOpacity 0.5 ] ]
buildingsFilter =
transform << filter (fiExpr "datum.properties.feature == 'building'")
buildingsSpec =
asSpec [ buildingsFilter [], geoshape [ maColor "rgb(196,153,121)", maFillOpacity 0.8 ] ]
buildingsShadowSpec =
asSpec [ buildingsOffsetData, geoshape [ maColor "#333", maFillOpacity 0.5 ] ]
wellSpec =
asSpec [ wellData [], geoshape [ maStroke "#227", maStrokeWidth 3, maFill "white", maOpacity 0.5 ] ]
in
toVegaLite
[ cfg []
, background "rgb(231,228,218)"
, title "CLERKENWELL\n1805"
[ tiFont "Jacques Francois Shadow"
, tiFontSize 42
, tiFontWeight fwNormal
, tiColor "#333"
]
, width w
, height h
, padding (paSize 40)
, data
, proj
, layer
[ boundarySpec
, fieldsSpec
, gardensSpec
, waterSpec
, fleetSpec
, buildingsShadowSpec
, buildingsSpec
, wellSpec
]
]
clerkenwellModern : Spec
clerkenwellModern =
let
w =
900
h =
w * 29 / 30
cfg =
configure
<< configuration (coView [ vicoStroke Nothing ])
data =
dataFromUrl (path "clerkenwell2019Polys.json") [ topojsonFeature "clerkenwell" ]
boundaryData =
dataFromUrl (path "clerkenwell1805Boundary.json") [ topojsonFeature "clerkenwell" ]
wellData =
dataFromJson (geometry (geoPoint 531447 182130) [])
proj =
projection [ prType identityProjection, prReflectY True ]
boundarySpec =
asSpec [ boundaryData, geoshape [ maFill "rgb(235,227,200)", maStroke "#aaa", maStrokeWidth 2 ] ]
greenFilter =
transform << filter (fiExpr "datum.properties.leisure == 'garden' || datum.properties.leisure == 'park'")
greenSpec =
asSpec [ greenFilter [], geoshape [ maColor "rgb(211,215,176)", maStroke "#ab9", maFillOpacity 1 ] ]
landuseFilter =
transform << filter (fiExpr "isValid(datum.properties.landuse) || isValid(datum.properties.amenity)")
landuseSpec =
asSpec [ landuseFilter [], geoshape [ maColor "#bbb", maStroke "#666", maStrokeWidth 0.5, maOpacity 0.8 ] ]
buildingsFilter =
transform << filter (fiExpr "isValid(datum.properties.building)")
buildingsSpec =
asSpec [ buildingsFilter [], geoshape [ maColor "rgb(204,151,116)", maStroke "black", maStrokeWidth 0.2, maFillOpacity 1 ] ]
wellSpec =
asSpec [ wellData [], geoshape [ maStroke "#227", maStrokeWidth 3, maFill "white", maOpacity 0.6 ] ]
in
toVegaLite
[ cfg []
, background "#eee"
, title "CLERKENWELL\n2019"
[ tiFont "Raleway"
, tiFontSize 42
, tiFontWeight fwNormal
, tiColor "#333"
]
, width w
, height h
, padding (paSize 40)
, data
, proj
, layer [ boundarySpec, landuseSpec, greenSpec, buildingsSpec, wellSpec ]
]