Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@americana/maplibre-shield-generator

Package Overview
Dependencies
Maintainers
2
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@americana/maplibre-shield-generator

Generate highway shields for maplibre-gl-js maps

  • 0.0.1-alpha
  • unpublished
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
13
increased by333.33%
Maintainers
2
Weekly downloads
 
Created
Source

Americana Shield Renderer

The Americana shield renderer is a library intended to draw highway shields on a maplibre-gl-js vector-tiled map.

Pictoral highway shields

Shield rendering workflow

Rendering shields requires the following compoments:

  1. Encode shield information in vector tiles. First, your tiles must contain the information which tells the shield renderer what shields to draw. In OpenMapTiles, shield information is encoded in the transportation_name vector tile layer with a series of attributes named route_1, route_2, etc. Each attribute contains a text string which contains all of the information needed to determine which graphic to display, including numeric route number if the shield is numbered. However, this library allows you to specify how the shield information has been encoded, and it's possible to stitch together data from multiple fields when encoding shield data.

  2. Expose shield information in a style layer. Next, route information must be exposed in a maplibre expression using image in a structured string containing the route information. For example, you might encode Interstate 95 as an image named shield|US:I=95. Normally, the image expression is used to point to pre-designated sprites in a sprite sheet, but in thise case, we're pointing to a sprite which doesn't exist called shield|US:I=95. This will trigger a styleimagemissing event which allows the shield renderer to create the required graphic on the fly. As an example of how to encode shield information, see OSM Americana's highway_shield style layer.

  3. Create a callback that defines how route information is encoded. There are three parts to a route definition:

    1. The network string, which defines a network with a common shield shape, graphic, and color
    2. The ref string, which defines a text sequence that should be drawn on top of the shield graphic
    3. The wayName string, which defines a name, separate from the ref, that is used to determine which graphic to draw
let routeExtractor = (id) => {
  //format is `${shield}|${network}=${ref}|${wayName}`
  let id_parts = id.split("\n");
  let network_ref = id_parts[1].split("=");

  return {
    network: network_ref[0],
    ref: network_ref[1],
    wayName: id_parts[2],
  };
};
  1. (Optional) Create predicates that define which shields will be handled. For example, if all sprite IDs in your style that need a shield begin with the string shield|, this would look like:
let shieldPredicate = (imageID) => imageID.startsWith("shield");

This step can be skipped if all unhandled image IDs are shields.

Additionally, you can specify which networks will be handled. The example below ignores all nwn, lwn, ncn, etc network values:

let networkPredicate = (network: string) => !/^[lrni][chimpw]n$/.test(network);
  1. Create shield definitions and artwork. The shield definition is expressed as a JSON file along with a set of sprites containing any raster artwork used for the shields. It can be generated as an object or hosted as a JSON file accessible by URL. See the next section for how to create this definition.

  2. Hook up the shield generator to a maplibre-gl-js map. Pass either the URL of the JSON shield definition or create an object in javascript code. There are two separate classes for each approach.

new URLShieldRenderer("shields.json", routeExtractor)
  .filterImageID(shieldPredicate)
  .filterNetwork(networkPredicate)
  .renderOn(map);
new ShieldRenderer(shields, shieldPredicate)
  .filterImageID(shieldPredicate)
  .filterNetwork(networkPredicate)
  .renderOn(map);

Shield Definition

The purpose of the shield definition is to define which graphics and text to draw for each network/ref/name combination that you wish to display. This can be created in javascript as an object, or as an HTTP-accessible JSON file.

This description uses the following conventions:

  • A network is a set of routes with a common graphical presentation. Each route may have variations in appearance, such as a different route number, or a special case definition as described below. The network value corresponds in concept to the OpenStreetMap network tag.
  • A ref contains the text to be drawn on shield artwork. The ref value corresponds in concept to the OpenStreetMap ref tag.

The structure is as follows:

{
    "default": { ...definiton },
    "network_1": { ...definiton },
    "network_2": { ...definiton },
    "network_2": { ...definiton }
}

You should create one definition entry for each network. The entry key must match the encoded network value exactly. The "default" network defines what should be drawn if there's no definition for a particular network. A network definiton can contain any combination of the following parameters:

{
  "textColor": "black",
  "textHaloColor": "white",
  "padding": {
    "left": 3,
    "right": 3,
    "top": 3,
    "bottom": 3
  },
  "spriteBlank": "name_of_image_1",
  "noref": {
    "spriteBlank": "name_of_image_2"
  }
  "canvasDrawnBlank": {
    "drawFunc": "pentagon",
    "params": {
      "pointUp": false,
      "offset": 5,
      "angle": 0,
      "fillColor": "white",
      "strokeColor": "black",
      "radius1": 2,
      "radius2": 2
    }
  },
  "modifiers": ["ALT"],
  "textLayout": {
    "constraintFunc": "roundedRect",
    "options": {
      "radius": 2
    }
  },
  "colorLighten": "#006747",
  "overrideByRef": {
    "REF": {
      "spriteBlank": "special_case_image",
      "textColor": "#003f87",
      "colorLighten": "#003f87"
    }
  },
  "refsByWayName": {
    "Audubon Parkway": "AU"
  },
  "overrideByWayName": {
    "Merritt Parkway": {
      "spriteBlank": "shield_us_ct_parkway_merritt"
    }
  }
}

Shield property descriptions

  • textColor: determines what color to draw the ref on the shield.
  • textHaloColor: color to draw a knockout halo around the ref text.
  • padding: padding around the ref, which allows you to squeeze the text into a smaller space within the shield.
  • spriteBlank: specify the name of an image in the sprite sheet to use as the shield background. This can either be a single string or an array of strings if there are multiple options for different width. If it's an array of strings, they must be ordered from narrowest to widest, and the engine will choose the narrowest shield graphic that fits the text at a reasonable size.
  • noref: specify alternate attributes to apply in the event that no ref is supplied. This allows you to use one graphic for numbered routes and a separate unitary graphic for non-numbered routes within the same network. Supports spriteBlank, colorLighten, and colorDarken.
  • canvasDrawnBlank: specify that a shield should be drawn as a common shape (rectangle, ellipse, pentagon, etc), with colors and dimensions as specified. See the drawn shield shapes section for available drawing options.
  • modifiers: specify that one or more short text strings (up to 4 characters) should be drawn above the shield. This is specified as an array, and text will be drawn in order from top to bottom.
  • textLayout: specify how text should be inscribed within the padded bounds of the shield. The text will be drawn at the maximum size allowed by this constraint. See the text layout functions section for text layout options.
  • colorLighten: specify that the shield artwork should be lightened (multiplied) by the specified color. This means that black areas will be recolor with this color and white areas will remain the same. Alpha values will remain unmodified.
  • overrideByRef: specify that a specific ref within a network should have different shield properties than other routes in the network, with one entry per special-case ref. Supported options are spriteBlank, textColor, and colorLighten.
  • refsByWayName: specify that a wayName with the specified key should be treated as a ref with the specified value.
  • overrideWayName: specify that particular wayName should use a specific spriteBlank which differs from the rest of the network.

Text layout functions

Text is laid out on shields in accordance with the specified textLayout value. The text will be drawn, measured, and expanded until it hits the edge of a text layout constraint. For example, an ellipse constraint would fill a padded shield like this, with the text drawn from the center and expanding until it reaches the ellipse:

Ellipse constraint

Not all constraints are center-specified. For example, the southHalfEllipse constraint would grow from the top of the shield as follows:

South half-ellipse constraint

The supported text constraints are:

  • ellipse
  • rect
  • roundedRect
  • southHalfEllipse

Defining drawn shield shapes

If canvasDrawnBlank is specified, the shield will be drawn as a shape. This needs to be specified with a drawing function, drawFunc and a params block the describes how the shape will be drawn. The draw functions are as follows:

drawFunc
diamond
ellipse
escutcheon
fishhead
hexagonVertical
hexagonHorizontal
octagonVertical
pentagon
roundedRectangle
trapezoid
triangle

The following params options can be specified:

  • angle - applies to several shape types, indicates the key angle in degrees.
  • fill - specifies the internal fill color.
  • outline - specifies the outline color.
  • outlineWidth - specifies the width of the outline.
  • pointUp - applies to several shape types and specifies whether the pointy side is up.
  • radius - specifies the rounding radius, in pixels, to use for corners.
  • radius1 - Corner radius of pointed side of pentagon (defaults to 2)
  • radius2 - Corner radius of flat side of pentagon (defaults to 0)
  • shortSideUp - for trapezoid only, a boolean which specifies whether the short side is up or down.

Custom shield graphics

In addition to the stock drawing functions, a custom draw function can be specified. paDot and branson are included as examples of this, for rendering the Allegheny County belt system and the Branson, Missouri colored route system. See the file src/custom_shields.mjs for an example of how this is done.

Keywords

FAQs

Package last updated on 26 Feb 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc