Select to view content in your preferred language

Arcade layering

89
0
12-05-2024 03:47 PM
Labels (1)
KateDoughty1
Regular Contributor

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.

KateDoughty1_0-1733442242587.png

I'd like to make the background white with a thin black border, like:

KateDoughty1_1-1733442281625.png

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, "&#000D;", 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)
0 Kudos
0 Replies