sites, RadioReferencePreference.Location location)
{
DecimalFormat frequencyFormat = new DecimalFormat("0.00000");
StringBuilder sb = new StringBuilder("");
int shown = Math.min(sites.size(), MAX_SITES);
for(int index = 0; index < shown; index++)
{
SiteRecord site = sites.get(index);
if(index > 0)
{
sb.append("
");
}
sb.append("").append(escape(site.systemName() != null ? site.systemName() : "(unnamed system)"))
.append("
");
appendLine(sb, site.protocol(), site.voice());
String siteName = "Site " + site.siteNumber();
String distance = location != null ? DistanceFormat.format(Coverage.distanceKilometers(
location.latitude(), location.longitude(), site.latitude(), site.longitude())) : null;
appendLine(sb, siteName, site.description(), site.county(), distance);
appendLine(sb, site.nac() != null ? "NAC " + site.nac() : null,
site.rfss() > 0 ? "RFSS " + site.rfss() : null, site.zone() > 0 ? "Zone " + site.zone() : null);
appendChannels(sb, site.channels(), frequencyFormat);
}
if(sites.size() > shown)
{
sb.append("
+ ").append(sites.size() - shown).append(" more site")
.append(sites.size() - shown > 1 ? "s" : "").append(" here
");
}
sb.append("");
return sb.toString();
}
/**
* Channels in columns, control channels marked C and alternate control channels marked A
*/
private static void appendChannels(StringBuilder sb, List channels,
DecimalFormat frequencyFormat)
{
if(channels == null || channels.isEmpty())
{
return;
}
int shown = Math.min(channels.size(), MAX_CHANNELS);
boolean control = false;
sb.append("");
for(int index = 0; index < shown; index++)
{
if(index % CHANNEL_COLUMNS == 0)
{
sb.append("");
}
SiteRecord.SiteChannel channel = channels.get(index);
sb.append("| ").append(frequencyFormat.format(channel.frequencyHz() / 1E6));
if("Control".equals(channel.use()))
{
sb.append(" C");
control = true;
}
else if("Alternate control".equals(channel.use()))
{
sb.append(" A");
control = true;
}
sb.append(" | ");
if(index % CHANNEL_COLUMNS == CHANNEL_COLUMNS - 1)
{
sb.append("
");
}
}
if(shown % CHANNEL_COLUMNS != 0)
{
sb.append("");
}
sb.append("
");
List notes = new ArrayList<>();
if(channels.size() > shown)
{
notes.add("+ " + (channels.size() - shown) + " more channels");
}
if(control)
{
notes.add("C control, A alternate control");
}
if(!notes.isEmpty())
{
appendLine(sb, notes.toArray(new String[0]));
}
}
/**
* Appends a line with the non-empty values separated by dots, or nothing when all are empty
*/
private static void appendLine(StringBuilder sb, String... values)
{
StringBuilder line = new StringBuilder();
for(String value: values)
{
if(value != null && !value.isBlank())
{
if(!line.isEmpty())
{
line.append(SEPARATOR);
}
line.append(escape(value));
}
}
if(!line.isEmpty())
{
sb.append("").append(line).append("
");
}
}
private static String escape(String text)
{
return text.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """);
}
}