Skip to content

Commit

Permalink
Merge pull request #1032 from ZeLonewolf/1ec5-structured-image-names-…
Browse files Browse the repository at this point in the history
…1620

Rename shield image names based on structured route properties
  • Loading branch information
1ec5 authored Apr 4, 2024
2 parents f7fdbc1 + f83d0fe commit cbad54b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/configs/config.aws.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*
Planetiler tile server, hosted at AWS
*/
const OPENMAPTILES_URL = "https://tile.ourmap.us/data/v3.json";
const OPENMAPTILES_URL = "https://tile.ourmap.us/data/omt_3_15.json";

/*
The following two variables override the color of the bounding box and halo of
Expand Down
14 changes: 4 additions & 10 deletions src/js/shield_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type {
RouteParser,
} from "@americana/maplibre-shield-generator";

import { parseImageName } from "../layer/highway_shield.js";

export const shieldPredicate: StringPredicate = (imageID: string) =>
imageID && imageID.startsWith("shield");

Expand All @@ -14,16 +16,8 @@ export const networkPredicate: StringPredicate = (network: string) =>

export const routeParser: RouteParser = {
parse: (id: string) => {
//Americana format is `${shield}\n${network}=${ref}\n${name}`
let id_parts: string[] = id.split("\n");
let network_ref = id_parts[1].split("=");

return {
network: network_ref[0],
ref: network_ref[1],
name: id_parts[2],
};
return parseImageName(id);
},
format: (network: string, ref: string, name: string) =>
`shield\n${network}=${ref}\n${name}`,
`shield\n${network}\n${ref}\n${name}\n`,
};
47 changes: 17 additions & 30 deletions src/layer/highway_shield.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
"use strict";

export const namedRouteNetworks = [
"US:CT:Parkway",
"US:KY:Parkway",
"US:NH:Turnpike",
"US:NY:Parkway",
"US:TX:Fort_Bend:FBCTRA",
"US:TX:Harris:HCTRA",
];
const orderedRouteAttributes = ["network", "ref", "name", "color"];

export function getImageNameExpression(routeIndex) {
return [
"concat",
"shield\n",
["get", "route_" + routeIndex],
[
"match",
["get", "route_" + routeIndex],
namedRouteNetworks.map((n) => n + "="),
["concat", "\n", ["get", "name"]],
"",
],
];
let concat = ["concat", "shield"];
for (let attr of orderedRouteAttributes) {
concat.push("\n");
concat.push(["coalesce", ["get", `route_${routeIndex}_${attr}`], ""]);
}
return concat;
}

function routeConcurrency(routeIndex) {
return [
"case",
["!=", ["get", "route_" + routeIndex], null],
[
"any",
...orderedRouteAttributes.map(a => ["has", `route_${routeIndex}_${a}`]),
],
["image", getImageNameExpression(routeIndex)],
["literal", ""],
];
Expand All @@ -37,12 +27,14 @@ function routeConcurrency(routeIndex) {
* Returns a structured representation of the given image name.
*
* @param name An image name in the format returned by `routeConcurrency`.
* @return An object with the keys in `orderedRouteAttributes` plus the full image name in `imageName`.
*/
export function parseImageName(imageName) {
let lines = imageName.split("\n");
let [, network, ref] = lines[1].match(/^(.*?)=(.*)/) || [];
let name = lines[2];
return { imageName, network, ref, name };
lines.shift(); // "shield"
let parsed = Object.fromEntries(orderedRouteAttributes.map((a, i) => [a, lines[i]]));
parsed.imageName = imageName;
return parsed;
}

let shieldTextField = ["format"];
Expand Down Expand Up @@ -113,11 +105,6 @@ export const shield = {
},
filter: [
"any",
["has", "route_1"],
["has", "route_2"],
["has", "route_3"],
["has", "route_4"],
["has", "route_5"],
["has", "route_6"],
...orderedRouteAttributes.map(a => ["has", `route_1_${a}`]),
],
};
4 changes: 3 additions & 1 deletion test/shield_format/shield_format.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { expect } from "chai";
import { shieldPredicate, routeParser } from "../../src/js/shield_format.js";

const image_id_I95 = "shield\nUS:I=95";
const image_id_I95 = "shield\nUS:I\n95\nEye Ninety-Five";
const route_def_I95 = {
network: "US:I",
ref: "95",
name: "Eye Ninety-Five",
};

describe("shield_format", function () {
Expand All @@ -19,6 +20,7 @@ describe("shield_format", function () {
let extractedDef = routeParser.parse(image_id_I95);
expect(extractedDef.network).to.be.equal(route_def_I95.network);
expect(extractedDef.ref).to.be.equal(route_def_I95.ref);
expect(extractedDef.name).to.be.equal(route_def_I95.name);
});
});
});
28 changes: 15 additions & 13 deletions test/spec/highway_shield.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,51 @@ describe("highway_shield", function () {
.createExpression(HighwayShieldLayers.getImageNameExpression(1))
.value.expression.evaluate(expressionContext(properties));

let expectImageName = (network, ref, name, expectedImageName) => {
let expectImageName = (network, ref, name, color, expectedImageName) => {
let properties = {
route_1: `${network || ""}=${ref || ""}`,
name: name || null,
route_1_network: network || "",
route_1_ref: ref || "",
route_1_name: name || "",
route_1_color: color || "",
};
let evaluated = evaluatedExpression(properties);
let expectedProperties = {
imageName: expectedImageName,
network: network || "",
ref: ref || "",
name:
!ref && HighwayShieldLayers.namedRouteNetworks.includes(network)
? name
: undefined,
name: name || "",
color: color || "",
};
expect(HighwayShieldLayers.parseImageName(evaluated)).to.be.deep.equal(
expectedProperties
);
};

it("parses an image name for a numbered route", function () {
expectImageName("NET", "REF", undefined, "shield\nNET=REF");
expectImageName("NET", "REF", "NAME", "shield\nNET=REF");
expectImageName("NET", "REF", undefined, undefined, "shield\nNET\nREF\n\n");
expectImageName("NET", "REF", "NAME", undefined, "shield\nNET\nREF\nNAME\n");
});
it("parses an image name for an unnumbered route", function () {
expectImageName("NET", undefined, undefined, "shield\nNET=");
expectImageName("NET", undefined, undefined, undefined, "shield\nNET\n\n\n");
});
it("parses an image name for a named route", function () {
expectImageName(
"US:KY:Parkway",
undefined,
"NAME",
"shield\nUS:KY:Parkway=\nNAME"
undefined,
"shield\nUS:KY:Parkway\n\nNAME\n"
);
expectImageName(
"US:KY:Parkway",
"REF",
"NAME",
"shield\nUS:KY:Parkway=REF"
undefined,
"shield\nUS:KY:Parkway\nREF\nNAME\n"
);
});
it("parses an image name for a network-independent route", function () {
expectImageName(undefined, "REF", "NAME", "shield\n=REF");
expectImageName(undefined, "REF", "NAME", undefined, "shield\n\nREF\nNAME\n");
});
});
});
22 changes: 11 additions & 11 deletions test/spec/shield.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ const shieldRenderer = new ShieldRenderer(shields, routeParser)

const handler = shieldRenderer.getStyleImageMissingHandler();

handler({ id: "shield\nBAB=5" });
handler({ id: "shield\nUS:RI=" });
handler({ id: "shield\nUS:RI=ABC123" });
handler({ id: "shield\nUS:RI=Equator" });
handler({ id: "shield\nrwn=" });
handler({ id: "shield\nBAB\n5\n\n" });
handler({ id: "shield\nUS:RI\n\n\n" });
handler({ id: "shield\nUS:RI\nABC123\n\n" });
handler({ id: "shield\nUS:RI\nEquator\n\n" });
handler({ id: "shield\nrwn\n\n\n" });
handler({ id: "foo" });

function isBlankSprite(id) {
Expand All @@ -39,21 +39,21 @@ function isBlankSprite(id) {
describe("shield", function () {
describe("#isValidNetwork", function () {
it("rejects a recreational network", function () {
expect(isBlankSprite("shield\nBAB=5")).to.be.false;
expect(isBlankSprite("shield\nrwn=")).to.be.true;
expect(isBlankSprite("shield\nBAB\n5\n\n")).to.be.false;
expect(isBlankSprite("shield\nrwn\n\n\n")).to.be.true;
});
it("rejects other missing image prefixes", function () {
expect(mockRepo.hasSprite("foo")).to.be.false;
});
});
describe("#isValidRef", function () {
it("rejects an empty ref", function () {
expect(isBlankSprite("shield\nUS:RI=")).to.be.true;
expect(isBlankSprite("shield\nUS:RI\n\n\n")).to.be.true;
});
it("rejects a long ref", function () {
expect(mockRepo.hasSprite("shield\nUS:RI=ABC123")).to.be.true;
expect(isBlankSprite("shield\nUS:RI=ABC123")).to.be.false;
expect(isBlankSprite("shield\nUS:RI=Equator")).to.be.true;
expect(mockRepo.hasSprite("shield\nUS:RI\nABC123\n\n")).to.be.true;
expect(isBlankSprite("shield\nUS:RI\nABC123\n\n")).to.be.false;
expect(isBlankSprite("shield\nUS:RI\nEquator\n\n")).to.be.true;
});
});
});

0 comments on commit cbad54b

Please sign in to comment.