Skip to content

Latest commit

 

History

History
231 lines (173 loc) · 7.43 KB

d22BuiltEnvironment.md

File metadata and controls

231 lines (173 loc) · 7.43 KB
id elm
litvis
dependencies
gicentre/elm-vegalite
latest

@import "css/litvis.less"

import VegaLite exposing (..)

30 Day Map Challenge, Day 22: Built Environment

This document best viewed in litvis

Initial Thoughts

How has London evolved over time? Perhaps compare my local work area (Clerkenwell) between two periods.

Data Preparation

  1. 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.

  2. 1805 Clerkenwell boundary polygon extracted from file in mapshaper:

    filter 'feature == "boundary"'
    o format=topojson clerkenwellBoundary.json
  3. 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
  4. 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

Map Design

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.

1805

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
            ]
        ]

Modern

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 ]
        ]

day 22