diff --git a/package.json b/package.json index b7846b14..5181ce15 100644 --- a/package.json +++ b/package.json @@ -33,14 +33,15 @@ "rbush": "^3.0.1" }, "scripts": { - "dev": "esbuild src/index.ts --bundle --target=es6 --servedir=. --outfile=dist/protomaps-leaflet.js --global-name=protomapsL", - "build": "esbuild src/index.ts --bundle --target=es6 --outfile=dist/protomaps-leaflet.js --global-name=protomapsL", - "build-min": "esbuild src/index.ts --bundle --target=es6 --minify --outfile=dist/protomaps-leaflet.min.js --global-name=protomapsL", - "build-module": "esbuild src/index.ts --bundle --target=es6 --outfile=dist/index.js --format=esm", + "dev": "esbuild src/index.ts --bundle --target=es2015 --servedir=. --outfile=dist/protomaps-leaflet.js --global-name=F.ProtomapsLeaflet", + "build": "esbuild src/index.ts --bundle --target=es2015 --outfile=dist/protomaps-leaflet.js --global-name=F.ProtomapsLeaflet", + "build-min": "esbuild src/index.ts --bundle --target=es2015 --minify --outfile=dist/protomaps-leaflet.min.js --global-name=F.ProtomapsLeaflet", + "build-module": "esbuild src/index.ts --bundle --target=es2015 --outfile=dist/index.js --format=esm", "build-tsc": "tsc --declaration --outdir dist", "tsc": "tsc --noEmit --watch", "test": "tsx --test --test-reporter spec test/*.test.ts", "dist": "npm run build && npm run build-min && npm run build-module && npm run build-tsc", + "classic": "npm run dist && cp dist/protomaps-leaflet.min.js ../classic/javascript/protomaps-leaflet.js", "check": "biome check src test" }, "repository": { diff --git a/src/default_style/style.ts b/src/default_style/style.ts index bc8220a5..e8d745e4 100644 --- a/src/default_style/style.ts +++ b/src/default_style/style.ts @@ -379,18 +379,6 @@ export const paintRules = (t: Theme): PaintRule[] => { return f.props["pmap:kind"] === "highway"; }, }, - { - dataLayer: "boundaries", - symbolizer: new LineSymbolizer({ - dash: [3, 2], - color: t.boundaries, - width: 1, - }), - filter: (z, f) => { - const minAdminLevel = f.props["pmap:min_admin_level"]; - return typeof minAdminLevel === "number" && minAdminLevel <= 2; - }, - }, { dataLayer: "transit", symbolizer: new LineSymbolizer({ @@ -412,20 +400,61 @@ export const paintRules = (t: Theme): PaintRule[] => { { dataLayer: "boundaries", symbolizer: new LineSymbolizer({ - dash: [3, 2], color: t.boundaries, - width: 0.5, + width: (z, f) => { + return exp(1.6, [ + [1, 0.66], + [7, 1.5], + [13, 3], + ])(z); + }, + opacity: 0.85, + }), + filter: (z, f) => { + return f.props["pmap:kind"] === "country"; + }, + }, + { + dataLayer: "boundaries", + symbolizer: new LineSymbolizer({ + color: t.boundaries, + width: (z, f) => { + return exp(1.6, [ + [1, 0.33], + [7, 0.66], + [13, 1.5], + ])(z); + }, + opacity: 0.85, }), filter: (z, f) => { - const minAdminLevel = f.props["pmap:min_admin_level"]; - return typeof minAdminLevel === "number" && minAdminLevel > 2; + return f.props["pmap:kind"] === "region"; + }, + }, + { + dataLayer: "boundaries", + symbolizer: new LineSymbolizer({ + color: t.boundaries, + width: (z, f) => { + return exp(1.6, [ + [1, 0], + [7, 0.33], + [13, 0.66], + ])(z); + }, + opacity: 0.7, + }), + filter: (z, f) => { + const kind = getString(f.props, "pmap:kind"); + return !(["country", "region"].includes(kind)); }, }, ]; }; export const labelRules = (t: Theme): LabelRule[] => { - const nametags = ["name"]; + // @ts-ignore + const nametags = ["name:" + F.config.flickr.lang.slice(0,2), "name"]; return [ // { @@ -435,7 +464,7 @@ export const labelRules = (t: Theme): LabelRule[] => { // new CenteredTextSymbolizer({ // labelProps: nametags, // fill: params.neighbourhoodLabel, - // font: "500 10px sans-serif", + // font: "500 10px Proxima Nova", // textTransform: "uppercase", // }), // params.neighbourhoodLabel, @@ -449,7 +478,7 @@ export const labelRules = (t: Theme): LabelRule[] => { symbolizer: new LineLabelSymbolizer({ labelProps: nametags, fill: t.roads_label_minor, - font: "400 12px sans-serif", + font: "400 12px Proxima Nova", width: 2, stroke: t.roads_label_minor_halo, }), @@ -465,7 +494,7 @@ export const labelRules = (t: Theme): LabelRule[] => { symbolizer: new LineLabelSymbolizer({ labelProps: nametags, fill: t.roads_label_major, - font: "400 12px sans-serif", + font: "400 12px Proxima Nova", width: 2, stroke: t.roads_label_major_halo, }), @@ -481,7 +510,7 @@ export const labelRules = (t: Theme): LabelRule[] => { symbolizer: new LineLabelSymbolizer({ labelProps: nametags, fill: t.roads_label_major, - font: "400 12px sans-serif", + font: "400 12px Proxima Nova", width: 2, stroke: t.roads_label_major_halo, }), @@ -498,19 +527,38 @@ export const labelRules = (t: Theme): LabelRule[] => { labelProps: nametags, fill: t.ocean_label, lineHeight: 1.5, - letterSpacing: 1, + letterSpacing: 3, font: (z, f) => { const size = linear([ - [3, 10], - [10, 12], + [1, 11], + [3, 16], + [10, 26], ])(z); - return `400 ${size}px sans-serif`; + return `400 ${size}px Proxima Nova`; }, - textTransform: "uppercase", }), filter: (z, f) => { - const kind = getString(f.props, "pmap:kind"); - return ["ocean", "bay", "strait", "fjord"].includes(kind); + return f.props["pmap:kind"] === "ocean"; + }, + }, + { + dataLayer: "physical_point", + symbolizer: new CenteredTextSymbolizer({ + labelProps: nametags, + fill: t.ocean_label, + lineHeight: 1.5, + letterSpacing: 2, + font: (z, f) => { + const size = linear([ + [4, 13], + [6, 14], + ])(z); + return `400 ${size}px Proxima Nova`; + }, + }), + filter: (z, f) => { + if (z < 4) return false; + return f.props["pmap:kind"] === "sea"; }, }, { @@ -522,16 +570,16 @@ export const labelRules = (t: Theme): LabelRule[] => { letterSpacing: 1, font: (z, f) => { const size = linear([ - [3, 0], - [6, 12], + [3, 10], [10, 12], ])(z); - return `400 ${size}px sans-serif`; + return `400 ${size}px Proxima Nova`; }, + textTransform: "uppercase", }), filter: (z, f) => { const kind = getString(f.props, "pmap:kind"); - return ["sea", "lake", "water"].includes(kind); + return ["bay", "strait", "lake", "fjord", "water"].includes(kind); }, }, { @@ -547,9 +595,13 @@ export const labelRules = (t: Theme): LabelRule[] => { stroke: t.state_label_halo, width: 1, lineHeight: 1.5, + letterSpacing: 2, font: (z: number, f?: Feature) => { - if (z < 6) return "400 16px sans-serif"; - return "400 12px sans-serif"; + return "600 " + exp(1.6, [ + [6, 10], + [8, 15], + [14, 20], + ])(z) + "px Proxima Nova"; }, textTransform: "uppercase", }), @@ -562,12 +614,19 @@ export const labelRules = (t: Theme): LabelRule[] => { symbolizer: new CenteredTextSymbolizer({ labelProps: nametags, fill: t.country_label, + stroke: t.country_label_halo, + width: 1, lineHeight: 1.5, font: (z: number, f?: Feature) => { - if (z < 6) return "600 12px sans-serif"; - return "600 12px sans-serif"; + return "600 " + exp(1.6, [ + [0, 10], + [3, 12], + [4, 14], + [5, 16], + [6, 18], + [14, 20], + ])(z) + "px Proxima Nova"; }, - textTransform: "uppercase", }), filter: (z, f) => { return f.props["pmap:kind"] === "country"; @@ -580,20 +639,22 @@ export const labelRules = (t: Theme): LabelRule[] => { symbolizer: new CenteredTextSymbolizer({ labelProps: nametags, fill: t.city_label, + stroke: t.city_label_halo, + width: 1, lineHeight: 1.5, font: (z: number, f?: Feature) => { - if (!f) return "400 12px sans-serif"; + if (!f) return "400 12px Proxima Nova"; const minZoom = f.props["pmap:min_zoom"]; let weight = 400; if (minZoom && minZoom <= 5) { weight = 600; } - let size = 12; + let size = 14; const popRank = f.props["pmap:population_rank"]; if (popRank && popRank > 9) { size = 16; } - return `${weight} ${size}px sans-serif`; + return `${weight} ${size}px Proxima Nova`; }, }), sort: (a, b) => { @@ -602,6 +663,7 @@ export const labelRules = (t: Theme): LabelRule[] => { return aRank - bRank; }, filter: (z, f) => { + if (z < 4) return false; return f.props["pmap:kind"] === "locality"; }, }, @@ -623,11 +685,12 @@ export const labelRules = (t: Theme): LabelRule[] => { offsetX: 6, offsetY: 4.5, font: (z, f) => { - return "400 12px sans-serif"; + return "400 12px Proxima Nova"; }, }), ]), filter: (z, f) => { + if (z < 4) return false; return f.props["pmap:kind"] === "locality"; }, }, diff --git a/src/default_style/themes.ts b/src/default_style/themes.ts index 5dc80f89..734e2139 100644 --- a/src/default_style/themes.ts +++ b/src/default_style/themes.ts @@ -86,6 +86,7 @@ export interface Theme { state_label: string; state_label_halo: string; country_label: string; + country_label_halo?: string; } export const LIGHT: Theme = { @@ -538,12 +539,106 @@ export const BLACK: Theme = { country_label: "#707070", }; + +export const FLICKR: Theme = { // ff0084 ff9700 + background: "#edf0f2", + earth: "#edf0f2", + park_a: "#ddecd6", + park_b: "#ddecd6", + hospital: "#e3e3e3", + industrial: "#e3e3e3", + school: "#e3e3e3", + wood_a: "#c9e3bc", + wood_b: "#c9e3bc", + pedestrian: "#ececec", + scrub_a: "#ddecd6", + scrub_b: "#ddecd6", + glacier: "#edf0f2", + sand: "#e8e4d0", + beach: "#e8e4d0", + aerodrome: "#e3e3e3", + runway: "#cccccc", + water: "#87c6ed", + pier: "#e0e0e0", + zoo: "#bbe3a3", + military: "#dcdcdc", + + tunnel_other_casing: "#e0e0e0", + tunnel_minor_casing: "#e0e0e0", + tunnel_link_casing: "#e0e0e0", + tunnel_medium_casing: "#e0e0e0", + tunnel_major_casing: "#e0e0e0", + tunnel_highway_casing: "#e0e0e0", + tunnel_other: "#d5d5d5", + tunnel_minor: "#d5d5d5", + tunnel_link: "#d5d5d5", + tunnel_medium: "#d5d5d5", + tunnel_major: "#d5d5d5", + tunnel_highway: "#d5d5d5", + + transit_pier: "#e0e0e0", + buildings: "#cccccc", + + minor_service_casing: "#e0e0e0", + minor_casing: "#e0e0e0", + link_casing: "#e0e0e0", + medium_casing: "#e0e0e0", + major_casing_late: "#e0e0e0", + highway_casing_late: "#e0e0e0", + other: "#ebebeb", + minor_service: "#ebebeb", + minor_a: "#ebebeb", + minor_b: "#ffffff", + link: "#ffffff", + medium: "#f5f5f5", + major_casing_early: "#e0e0e0", + major: "#ffffff", + highway_casing_early: "#e0e0e0", + highway: "#ffffff", + + railway: "#a7b1b3", + boundaries: "#aaaaaa", + waterway_label: "#107fd1", + + bridges_other_casing: "#e0e0e0", + bridges_minor_casing: "#e0e0e0", + bridges_link_casing: "#e0e0e0", + bridges_medium_casing: "#e0e0e0", + bridges_major_casing: "#e0e0e0", + bridges_highway_casing: "#e0e0e0", + bridges_other: "#ebebeb", + bridges_minor: "#ffffff", + bridges_link: "#ffffff", + bridges_medium: "#f0eded", + bridges_major: "#f5f5f5", + bridges_highway: "#ffffff", + + roads_label_minor: "#91888b", + roads_label_minor_halo: "#ffffff", + roads_label_major: "#938a8d", + roads_label_major_halo: "#ffffff", + ocean_label: "#107fd1", + peak_label: "#7e9aa0", + subplace_label: "#8f8f8f", + subplace_label_halo: "#e0e0e0", + city_circle: "#000000", + city_circle_stroke: "#ffffff", + city_label: "#000000", + city_label_halo: "#ffffff", + state_label: "#000000", + state_label_halo: "#ffffff", + country_label: "#000000", + country_label_halo: "#ffffff", +}; + + const themes: Record = { light: LIGHT, dark: DARK, white: WHITE, grayscale: GRAYSCALE, black: BLACK, + flickr: FLICKR, }; export default themes;