Amir,
I have tried adding the fabric to a new map, and the default popup expression still gives me troubles.
As far as I can tell, the default custom display expression (Layer Properties > Display > Display Field > Set an Expression) uses an identical expression to the popup and the Attributes panel shows the correct format.
Your popups display correctly? Hmm. Could it be a setting or system configuration for me?
I was able to construct a new expression using the new ConvertDirection function, however, it still excludes the single quote. You can see the default fabric expression followed by the ConvertDirection expression.
Thank you for looking at this with me!
-Paul
Here is the full default fabric popup expression.
// Change the settings portion to configure direction format, rounding and abbreviations
// This is an Arcade expression
// SETTINGS
var QuadrantBearingFormat = true; //set 'true' for quadrant bearing, 'false' for north azimuth
var ShowDistance = true; //set as 'true' to show distance
var ShowDirection = true; //set as 'true' to show direction
var ShowRadius = true; //set as 'true' to show radius
var ShowCurveParemater = true; //set as 'true' to show a curve parameter
var CurveParameter = "ArcLength"; //set as 'ArcLength' or 'Chord' or 'Angle' for central angle. Case sensitive!
var ErrorString = "COGO ERROR"; //set to display invalid COGO combinations
var RadiusAbbr = 'R='; //radius abbreviation
var Radius2Abbr = 'R2='; //radius2 abbreviation for spiral curves
var ArclengthAbrr = 'L='; //arclength abbreviation
var ChordAbbr = 'C='; //chord abbreviation
var AngleAbbr = 'A='; //central Angle abbreviation
var DistUnitRounding = 2; //number of decimal places for distance units: distance, radius, arclength & chord
var NumberFormat = "#,###.00" //number format. In this example: thousands separator with padding of 2 zeros
// VARIABLES
var direction=$feature.Direction;
var distance=$feature.Distance;
var radius=$feature.Radius;
var arclength=$feature.Arclength;
var radius2=$feature.Radius2
var prefix; // quadrant bearing prefix
var postfix; // quadrant bearing postfix
var bearing;
var quadbearing;
var binaryDictionary; //binary dictionary to check COGO combinations
var checksum=0; //initialize checksum
var validValuesArray; //array of valid values for COGO combinations
var partialValuesArray; //array of partial values for COGO
var degrees;
var minutes;
var seconds;
var DMS;
var directionStr = ""; //direction string using for label
var distanceStr = ""; //distance string using for label
var radiusStr = ""; //radius string using for label
var radius2Str = ""; //radius2 string using for labeling spiral curves
var curveStr = ""; //curve parameter string using for label
var angleRad; //curve angle in radians
var COGOValidity; //COGO combinations validity. can be valid, partial or invalid.
function NorthAzimuth2Quadbearing(azimuth){
if (azimuth<90 && azimuth>=0){
bearing=azimuth;
prefix = "N";
postfix= "E";}
else if (azimuth<180 && azimuth>=90){
bearing=180-azimuth;
prefix = "S";
postfix= "E";}
else if (azimuth<270 && azimuth>=180){
bearing=abs(180-azimuth);
prefix = "S";
postfix= "W";}
else if (azimuth<360 && azimuth>=270){
bearing=360-azimuth;
prefix = "N";
postfix= "W";}
degrees=floor(bearing);
minutes=floor((bearing-degrees)*60)
seconds=((bearing-degrees-minutes/60)*3600)
if (seconds>=59.5){
seconds=0;
minutes+=1;
if (minutes==60){
minutes=0;
degrees+=1;}}
quadbearing=prefix+degrees+"°"+text(minutes,"00")+"'"+text(seconds,"00")+"''"+postfix;
return quadbearing;
}
function DMS(bearing){
degrees=floor(bearing);
minutes=floor((bearing-degrees)*60)
seconds=((bearing-degrees-minutes/60)*3600)
if (seconds>=59.5){
seconds=0;
minutes+=1;
if (minutes==60){
minutes=0;
degrees+=1;}}
DMS=degrees+"°"+text(minutes,"00")+"'"+text(seconds,"00")+"''";
return DMS;
}
function IsValidCOGO(direction, distance, radius, arclength, radius2) {
binaryDictionary= Dictionary('dir', 1, 'dist',2, 'rad',4, 'arc',8, 'rad2',16)
if (!IsEmpty(direction)) {checksum+=binaryDictionary.dir}
if (!IsEmpty(distance)) {checksum+=binaryDictionary.dist}
if (!IsEmpty(radius)) {checksum+=binaryDictionary.rad}
if (!IsEmpty(arclength)) {checksum+=binaryDictionary.arc}
if (!IsEmpty(radius2)) {checksum+=binaryDictionary.rad2}
validValuesArray=[0,3,8,13,29]; //array of valid combinations: '0' for nothing, ... '13' for direction & radius & arclength ...
partialValuesArray=[1,2,4,20,13,16,21,25,28]; //array of partial combinations: '1' for only direction, '2' for only distance...
if (IndexOf(validValuesArray,checksum)>-1) { // a negative value is returned if checksum value is not in the a valid combination array
return "valid";
}
if (IndexOf(partialValuesArray,checksum)>-1){
return "partial";
}
return "invalid";
}
COGOValidity = IsValidCOGO(direction, distance, radius, arclength, radius2);
if ( COGOValidity == "invalid") { //if invalid COGO return error string
return ErrorString;
}
// Direction string
if (ShowDirection) {
if (IsEmpty(direction)==false) {
if (QuadrantBearingFormat==true) { //using quadrant bearing format
directionStr = NorthAzimuth2Quadbearing(direction);
}
else { //using north azimuth format
directionStr = DMS(direction);
}
}
}
// Distance string
if (ShowDistance) {
if (IsEmpty(distance)==false) {
distanceStr = text(round(distance,DistUnitRounding), NumberFormat);
}
}
//Radius String
if (ShowRadius) {
if (!IsEmpty(radius)) { //it can be a curve or a spiral
if (IsEmpty(radius2)) { //if radius2 is empty this is a curve
radiusStr = RadiusAbbr + " " + text(round(radius, DistUnitRounding), NumberFormat);
}
else { // it is a spiral
radiusStr = RadiusAbbr + " " + text(round(radius, DistUnitRounding),NumberFormat);
radius2Str = Radius2Abbr + " " + text(round(radius2, DistUnitRounding),NumberFormat);
if (radius == 0) { //substitute to infinity sign
radiusStr = RadiusAbbr + " ∞ ";
}
if (radius2 == 0) { //substitute to infinity sign
radius2Str = Radius2Abbr + " ∞ ";
}
}
}
}
// Curve Parameter
if (ShowCurveParemater) {
if (!IsEmpty(arclength)) {
if (CurveParameter == 'ArcLength') {
curveStr = ArclengthAbrr + text(round(arclength, DistUnitRounding), NumberFormat); //return Arc length
}
angleRad = arclength/(abs(radius)) //calculate angle in radians
if (CurveParameter == 'Angle') {
curveStr = AngleAbbr + DMS(angleRad * 180 / pi); // convert radian to degrees and show as DMS
}
if (CurveParameter == 'Chord') {
curveStr = ChordAbbr + text(round((2 * abs(radius) * Sin(angleRad/2)),DistUnitRounding), NumberFormat); //calculate chord length
}
}
}
// Assemble label string
if (IsEmpty(radius)) { //if its empty it is not a curve
return directionStr + " " + distanceStr
}
else { //it's a curve
return radiusStr + " " + radius2Str + " " + curveStr;
}