1package basemap23import "image/color"45// Role is what a shape is to the ground -- which stroke of the drawing it6// belongs to, never which dataset it arrived in. A source's curation assigns7// roles; this package knows only how each one draws, which is what keeps a8// publisher's vocabulary out of the renderer (issue #5 ยง5.1).9type Role string1011// The roles the drawing knows. A shape carrying anything else draws nothing:12// an unknown role is a curation entry ahead of the style table, and silence is13// the honest answer to it.14const (15 RoleParcel Role = "parcel"16 RolePark Role = "park"17 RoleWater Role = "water"18 RoleStreet Role = "street"19 RoleTrail Role = "trail"20 RoleBoundary Role = "boundary"21)2223// Style is one role's whole appearance: the colour its ground is flooded with,24// the colour and width of its linework, and the on/off rhythm of a dashed25// stroke. Widths are world-true -- spelled at ReferenceZoom and scaled with26// depth -- so a street keeps its width on the ground however deep the pyramid27// goes.28type Style struct {29 Fill color.NRGBA30 Stroke color.NRGBA31 StrokeWidth float6432 Dash [2]float6433}3435// ReferenceZoom is the local zoom the width column is spelled at. It is36// exported because it is the one number in the style table a reader of a city37// pyramid has to know to predict what a level looks like.38const ReferenceZoom = 63940// Background is the flat ground every tile starts as: a step off the app's own41// near-black, so the map reads as a surface and the palette accents stay the42// information. It is also what the deriver samples when it decides which tile43// of a level is the one worth omitting.44var Background = color.NRGBA{R: 0x14, G: 0x18, B: 0x1d, A: 0xff}4546// styles is the drawing itself. The colours keep to the app's identity:47// neutral greys for everyday linework, a warm earth tone for trails, navy for48// water, and the cerulean accent spent on exactly one line -- the city's own49// boundary.50var styles = map[Role]Style{51 RoleParcel: {Stroke: color.NRGBA{R: 0x23, G: 0x2a, B: 0x31, A: 0xff}, StrokeWidth: 1},52 RolePark: {Fill: color.NRGBA{R: 0x1f, G: 0x2b, B: 0x22, A: 0xff}},53 RoleWater: {Fill: color.NRGBA{R: 0x15, G: 0x25, B: 0x39, A: 0xff}, Stroke: color.NRGBA{R: 0x1f, G: 0x38, B: 0x52, A: 0xff}, StrokeWidth: 1},54 RoleStreet: {Stroke: color.NRGBA{R: 0x3d, G: 0x44, B: 0x4d, A: 0xff}, StrokeWidth: 2.5},55 RoleTrail: {Stroke: color.NRGBA{R: 0x8a, G: 0x6a, B: 0x44, A: 0xff}, StrokeWidth: 1.5, Dash: [2]float64{6, 4}},56 RoleBoundary: {Stroke: color.NRGBA{R: 0x3a, G: 0xa5, B: 0xc9, A: 0xff}, StrokeWidth: 3.5},57}5859// zOrder is the order the roles land on the ground, and it is the drawing's60// only opinion about layering: parcel texture first, then ground covers, water61// over parks so a lake punches through one, streets over water so a bridge62// reads as a bridge, trails above streets, and the boundary last as the single63// accent. Nothing within a role is ordered -- a role's shapes are unioned, so64// two overlapping parks are one park.65var zOrder = []Role{RoleParcel, RolePark, RoleWater, RoleStreet, RoleTrail, RoleBoundary}