I am trying to use the Esri Airport font in arcade to display dynamic labels. I'm having issue with the font being hollow. For example, "S" in the Airport Font is a hollow stop sign.
I'd like to make the background white with a thin black border, like:
I am using arcade from the Airports Aviation extension.
// MARK: - Global Variables
var autoAdjustWidths = false
//(set true or false) adds filler to sign to better match opposite side width. Must be true for labelAlignment and blackBackgroundFiller to work.
var labelAlignment = "center"
//(set "left" or "right")If autoAdjustWidths = true, determines if text is aligned "left" or "right". To make use of a field, see AddFiller($feature.field) near end of this expression.
var blackBackgroundFiller = true
//(set true or false)If true, black box filler is added if autoAdjustWidths = true.
var yellow = [255, 236, 0, 100]
var red = [230, 0, 0, 100]
var blue = [0, 180, 230, 100]
var black = [0, 0, 0, 100]
var white = [255, 255, 255, 100]
var gray = [210, 210, 210, 100]
var none = [0, 0, 0, 0]
var typeOneFound = true
var textFontName = "SimHei"
var textFontStyle = "65 Bold"
var signFontName = "Esri Airport Sign"
var signFontStyle = ""
var frontSignString = $feature.AIRPORTSIGNMSGFRONT // this is where airport sign front would be retrieved
var backSignString = $feature.AIRPORTSIGNMSGBACK // this is where airport sign back would be retrieved
var spacingInput = ""
var finalFrontExpression = ""
var fillerLength = 0
var signFrontPairs = [["",""]] // this is where type and character will be stored as pairs for Front-Sign
var signBackPairs = [["",""]] // this is where type and character will be stored as pairs for Back-Sign
var globalDifference=0 // this variable will be used to keep track of the character difference between labels
var sectionsCount=0 // this variable will keep track of how many sections there are within the Front Label
// MARK: - Functions
// Set background and outline
function FormatBO(background, outline, width, padding, txt) {
var attr = ""
if (background != none && count(background) == 4) {
attr += " red='" + background[0] + "'"
attr += " green='" + background[1] + "'"
attr += " blue='" + background[2] + "'"
attr += " alpha='" + background[3] + "'"
}
if (outline != none && count(outline) == 4) {
attr += " outline_red='" + outline[0] + "'"
attr += " outline_green='" + outline[1] + "'"
attr += " outline_blue='" + outline[2] + "'"
attr += " outline_alpha='" + outline[3] + "'"
attr += " width='" + width + "'"
attr += " padding='" + padding + "'"
}
return "<BGD" + attr + ">" + txt + "</BGD>"
}
// Set text color
function SetTextColor(rgba, txt)
{
var r = rgba[0]
var g = rgba[1]
var b = rgba[2]
var a = rgba[3]
return "<CLR red='" + r + "' green='" + g + "' blue='" + b + "' alpha='" + a + "'>" + txt + "</CLR>";
}
// Set font formatting information
function FormatFont(type, label, name, style, size){
var indexCount = count(signFrontPairs)
var tagName = iif(name == "", "", " NAME='" + name + "'")
var tagStyle = iif(style == "", "", " STYLE='" + style + "'")
var tagSize = iif(size == 0, "", " SIZE='" + size + "'")
label = Replace(label, "�D;", TextFormatting.NewLine)
if(type == 7 || type == 13)
return "<FNT" + tagName + tagStyle + tagSize + ">"+CreateFillerString(1,"|")+label+CreateFillerString(1,"|")+"</FNT>"
else if (type == 6 || type == 8 || type == 9)
return "<FNT"+tagName + tagStyle + tagSize+">"+label+"</FNT>"
else
return "<FNT" + tagName + tagStyle + tagSize + ">"+CreateFillerString(1,"|")+label+CreateFillerString(1,"|")+"</FNT>"
}
function FormatCharacterSpacing(spacing, expressionTxt) {
if(typeOneFound){return expressionTxt}
/*Remove if you want wrd spacing to be applied to typeOne
if(HasKey($feature, "SPACING") && !IsEmpty($feature.SPACING)){
return "<WRD spacing='" + $feature.SPACING + "'>" + expressionTxt + "</WRD>"
}else{
return "<WRD spacing='0'>" + expressionTxt + "</WRD>" // default spacing of 60
}*/
}
function splitAndPairFeatureDesc(featureDesc) {
var labelPairs = [["",""]]
var splitLabelExpr = Split(featureDesc, '[')
for (var s in splitLabelExpr) {
var pair = Split(splitLabelExpr[s], ']')
labelPairs [s] = pair
}
return labelPairs
}
function GetPairs(){
signFrontPairs = splitAndPairFeatureDesc(frontSignString)
signBackPairs = splitAndPairFeatureDesc(backSignString)
}
function howManyCharacters(inputPairs) {
var numCharacters = 0
for (var c in inputPairs) {
if (count(inputPairs[c]) > 1 && inputPairs[c][1] != "") {
numCharacters += count(inputPairs[c][1])
}
else if(count(inputPairs[c]) > 1 && inputPairs[c][1] == ""){
if(inputPairs[c][0] == "5"){
numCharacters += 1
}else if (inputPairs[c][0] == "6"){
numCharacters += 3
}else if (inputPairs[c][0] == "8"){
numCharacters += 4
}else if (inputPairs[c][0] == "9"){
numCharacters+= 3
}else if (inputPairs[c][0] == "11"){
numCharacters += 1
}else if (inputPairs[c][0] == "12"){
numCharacters += 1
}
}
}
return numCharacters
}
// Function calls on howManyCharacters() using sign-Front and sign-Back as inputs
function findNumberCharacterDifference() {
var backSignCharacterCount = howManyCharacters(signBackPairs)+(2*(count(signBackPairs)-1))
var frontSignCharacterCount = howManyCharacters(signFrontPairs)+(2*(count(signFrontPairs)-1))
var chDif = frontSignCharacterCount - backSignCharacterCount
fillerLength = abs(chDif)
return chDif
}
// Creates final expression
function createFinalExpression(expression, inputPairs) {
for (var index in inputPairs) {
var pairCount = count(inputPairs[index])
if (pairCount != 2) {
expression += iif(pairCount >= 1, inputPairs[index][0], "")
continue;
}
var type = number(inputPairs[index][0])
var newText = inputPairs[index][1]
if (type == 0) // "DIRECTION")
expression += SetTextColor(black, FormatBO(yellow, black, 0.5, -0.5, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 1) // "INFO_ACFT")
{ typeOneFound=true; expression += SetTextColor(black, FormatBO(yellow, none, 0, 0, FormatFont(type, newText, textFontName, textFontStyle, 0)));}
else if (type == 2) //"INFO_VEH")
expression += SetTextColor(black, FormatBO(white, none, 0, 0, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 3) // "LOCATION")
expression += SetTextColor(yellow, FormatBO(black, yellow, 0.75, -1.5, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 4) // "MANDATORY")
expression += SetTextColor(white, FormatBO(red, none, 0, 0, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 5) // "NO_ENTRY")
expression += SetTextColor(red, FormatBO(white, none, 0, 0, FormatFont(type, "O", signFontName, "", 0)));
else if (type == 6){ // "RWY_CRITICAL") --> [6]3
typeOneFound = true; expression += SetTextColor(black, FormatBO(yellow, none, 0, 0, FormatFont(type, "III", signFontName, "", 0)));}
else if (type == 7) // "RWY_DIST_REMAIN")
expression += SetTextColor(white, FormatBO(black, none, 0, 2, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 8){ //"RWY_SAFETY")
typeOneFound = true;
expression += SetTextColor(black, FormatBO(yellow, none, 0, 0, FormatFont(type, "RRRR", signFontName, "", 0)));}
else if (type == 9){ //"TAXIWAY_END")
typeOneFound = true;
expression += SetTextColor(black, FormatBO(yellow, none, 0, 0, FormatFont(type, "TTT", signFontName, "", 0)));}
else if (type == 10) //"TERMINAL")
expression += SetTextColor(white, FormatBO(blue, none, 0, 0, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else if (type == 11) //"VEH_STOP")
expression += SetTextColor(red, FormatBO(white, none, 0, -2, FormatFont(type, "S", signFontName, "", 0)));
else if (type == 12) //"VEH_YIELD")
expression += SetTextColor(red, FormatBO(white, none, 0, 0, FormatFont(type, "Y", signFontName, "", 0)));
else if (type == 13) //"GRAY_BLANK")
expression += SetTextColor(black, FormatBO(gray, none, 0, 0, FormatFont(type, newText, textFontName, textFontStyle, 0)));
else
expression += newText
}
return expression
}
// MARK: - Filler Functions
function CreateFillerString(length, char){
var fillerString = ""
for(var i = 0; i != length; i++){ // create a string of filler characters
fillerString += char
}
return "<CLR alpha='0'><FNT NAME='SimHei' STYLE='65 Bold'>" + fillerString + "</FNT></CLR>"
}
function FillerLeftAlignment(){
var filler = ""
if((count(signBackPairs)-1) == (count(signFrontPairs)-1))
filler = CreateFillerString(fillerLength,"|")
else
filler = CreateFillerString(fillerLength,"|")
if(blackBackgroundFiller){
return FormatBO(black, none, 0, 0, filler)}
else
return filler
}
function FillerRightAlignment(){
var filler = ""
if((count(signBackPairs)-1) == (count(signFrontPairs)-1))
filler = CreateFillerString(fillerLength,"|")
else
filler = CreateFillerString(fillerLength,"|")
if(blackBackgroundFiller){
return FormatBO(black, none,0,0, filler)}
else
return filler
}
function AddFiller(labelAlignment){
var splitExpression = split(finalFrontExpression, '>')
var end = count(splitExpression)-1
var filleredExpression = ""
for(var a in splitExpression){
if((labelAlignment != "middle" && labelAlignment != "right") && a == end-2){
filleredExpression += FillerLeftAlignment()}
else if(labelAlignment == "left" && a == end-2){
filleredExpression += FillerLeftAlignment()
}else if (labelAlignment == "right" && a == 2){
filleredExpression += FillerRightAlignment()
}
if(a != end){
filleredExpression += splitExpression[a]+">"
}
}
finalFrontExpression = filleredExpression
}
// MARK: - Creating expression
GetPairs()
globalDifference = findNumberCharacterDifference()
sectionsCount = count(signFrontPairs)-1
finalFrontExpression = createFinalExpression(finalFrontExpression, signFrontPairs)
if(autoAdjustWidths && globalDifference<0){
if(finalFrontExpression == "" && blackBackgroundFiller == true){
var filler = CreateFillerString(fillerLength, "|")
return FormatBO(black, none, 0, 0, filler)
}else{
AddFiller(labelAlignment)//if using a field for labelAlignment, comment out this line
//AddFiller($feature.FILLER_ALIGNMENT)// insert field Name, this will allow you to have individual control over each label alignment instead of a global left or right alignment which is applied to the smallest label side in order to try and match widths. You can add a textfield to AirportSign and populate with value 'right' as needed, else defaults left aligned.
}
}
return FormatCharacterSpacing(spacingInput, finalFrontExpression)