Skip to content
152 changes: 152 additions & 0 deletions src/graphics/BRC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include "BRC.h"
#include "GPSStatus.h"
#include "gps/GeoCoord.h"
#include "graphics/Screen.h"

using namespace meshtastic;

const int32_t BRC_LATI = (40.786958 * 1e7);
const int32_t BRC_LONI = (-119.202994 * 1e7);
const double BRC_LATF = 40.786958;
const double BRC_LONF = -119.202994;
const double BRC_NOON = 1.5;
const double RAD_TO_HOUR = (6.0 / 3.14159);
const double METER_TO_FEET = 3.28084;
const double FEET_TO_METER = 1.0 / METER_TO_FEET;

// Pre-calculated street data for performance
struct StreetInfo {
float center;
float width;
const char *name;
};

/*
# python code to generate the StreetInfo

esp_center = 2500
street_info = [
# name, width, preceeding block depth
('Esp', 40, 60), # block size is fake
('A', 30, 400),
('B', 30, 250),
('C', 30, 250),
('D', 30, 250),
('E', 40, 250),
('F', 30, 450), # E-F block is exra deep
('G', 30, 250),
('H', 30, 250),
('I', 30, 250),
('J', 30, 150),
('K', 50, 150),
]

street_center = esp_center - street_info[0][1] //2 - street_info[0][2]
last_center = esp_center
for (name, street_width, block_width) in street_info:
offset = (street_width + block_width) // 2
street_center += street_width //2 + block_width

dia = street_center * 2
dist = street_center - last_center

print(f"{{{street_center}, {offset}, \"{name}\"}},\t// +{dist}ft\tdia: {dia:,}ft")

last_center = street_center
street_center += street_width //2

street_center += 50 # extra buffer after the edge of k to include walk-in camping parking
print(f"{{{street_center}, 0, nullptr}},\t// +{street_center-last_center}ft")
*/

static const StreetInfo streets[] = {
{2500, 50, "Esp"}, // +0ft dia: 5,000ft
{2935, 215, "A"}, // +435ft dia: 5,870ft
{3215, 140, "B"}, // +280ft dia: 6,430ft
{3495, 140, "C"}, // +280ft dia: 6,990ft
{3775, 140, "D"}, // +280ft dia: 7,550ft
{4060, 145, "E"}, // +285ft dia: 8,120ft
{4545, 240, "F"}, // +485ft dia: 9,090ft
{4825, 140, "G"}, // +280ft dia: 9,650ft
{5105, 140, "H"}, // +280ft dia: 10,210ft
{5385, 140, "I"}, // +280ft dia: 10,770ft
{5565, 90, "J"}, // +180ft dia: 11,130ft
{5755, 100, "K"}, // +190ft dia: 11,510ft
{5830, 0, nullptr}, // +75ft
};

BRCAddress::BRCAddress(int32_t lat, int32_t lon)
{
bearing = GeoCoord::bearing(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * RAD_TO_HOUR;
bearing += 12.0 - BRC_NOON;
while (bearing > 12.0) {
bearing -= 12.0;
}

// In imperial units because that is how golden spike data is provided.
distance = GeoCoord::latLongToMeter(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * METER_TO_FEET;
};

int BRCAddress::radial(char *buf, size_t len)
{
uint8_t hour = (uint8_t)(bearing);
uint8_t minute = (uint8_t)((bearing - hour) * 60.0);
hour %= 12;
if (hour == 0) {
hour = 12;
}
return snprintf(buf, len, "%d:%02d", hour, minute);
};

int BRCAddress::annular(char *buf, size_t len, bool noUnit)
{
const char *unit = "m";
float unitMultiplier = FEET_TO_METER;
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
unitMultiplier = 1.0;
unit = "ft";
}
if (noUnit)
unit = "";

if (bearing > 1.75 && bearing < 10.25) {
const char *street = nullptr;
float dist = 0;
// Find the appropriate street based on distance
for (const auto &s : streets) {
if (distance > s.center - s.width) {
street = s.name;
dist = distance - s.center;
} else {
break;
}
}
if (street) {
return snprintf(buf, len, "%s %d%s", street, int(dist * unitMultiplier), unit);
}
}

return snprintf(buf, len, "%d%s", int(distance * unitMultiplier), unit);
};

int BRCAddress::full(char *buf, size_t len)
{
auto l = radial(buf, len - 4);
buf += l;
*(buf++) = ' ';
*(buf++) = '&';
*(buf++) = ' ';
buf += annular(buf, len - l - 4, false);
buf[l] = 0; // always null terminated
return l;
};

int BRCAddress::compact(char *buf, size_t len)
{
auto l = radial(buf, len - 2);
buf += l;
*(buf++) = '&';
buf += annular(buf, len - l - 2, true);
buf[l] = 0; // always null terminated
return l;
};
146 changes: 9 additions & 137 deletions src/graphics/BRC.h
Original file line number Diff line number Diff line change
@@ -1,147 +1,19 @@
#pragma once

#include "GPSStatus.h"
#include "gps/GeoCoord.h"
#include "graphics/Screen.h"

using namespace meshtastic;

const int32_t BRC_LATI = (40.786958 * 1e7);
const int32_t BRC_LONI = (-119.202994 * 1e7);
const double BRC_LATF = 40.786958;
const double BRC_LONF = -119.202994;
const double BRC_NOON = 1.5;
const double RAD_TO_HOUR = (6.0 / 3.14159);
const double METER_TO_FEET = 3.28084;
const double FEET_TO_METER = 1.0 / METER_TO_FEET;

// Pre-calculated street data for performance
struct StreetInfo {
float center;
float width;
const char *name;
};

/*
# python code to generate the StreetInfo

esp_center = 2500
street_info = [
# name, width, preceeding block depth
('Esp', 40, 60), # block size is fake
('A', 30, 400),
('B', 30, 250),
('C', 30, 250),
('D', 30, 250),
('E', 40, 250),
('F', 30, 450), # E-F block is exra deep
('G', 30, 250),
('H', 30, 250),
('I', 30, 250),
('J', 30, 150),
('K', 50, 150),
]

street_center = esp_center - street_info[0][1] //2 - street_info[0][2]
last_center = esp_center
for (name, street_width, block_width) in street_info:
offset = (street_width + block_width) // 2
street_center += street_width //2 + block_width

dia = street_center * 2
dist = street_center - last_center

print(f"{{{street_center}, {offset}, \"{name}\"}},\t// +{dist}ft\tdia: {dia:,}ft")

last_center = street_center
street_center += street_width //2

street_center += 50 # extra buffer after the edge of k to include walk-in camping parking
print(f"{{{street_center}, 0, nullptr}},\t// +{street_center-last_center}ft")
*/

static const StreetInfo streets[] = {
{2500, 50, "Esp"}, // +0ft dia: 5,000ft
{2935, 215, "A"}, // +435ft dia: 5,870ft
{3215, 140, "B"}, // +280ft dia: 6,430ft
{3495, 140, "C"}, // +280ft dia: 6,990ft
{3775, 140, "D"}, // +280ft dia: 7,550ft
{4060, 145, "E"}, // +285ft dia: 8,120ft
{4545, 240, "F"}, // +485ft dia: 9,090ft
{4825, 140, "G"}, // +280ft dia: 9,650ft
{5105, 140, "H"}, // +280ft dia: 10,210ft
{5385, 140, "I"}, // +280ft dia: 10,770ft
{5565, 90, "J"}, // +180ft dia: 11,130ft
{5755, 100, "K"}, // +190ft dia: 11,510ft
{5830, 0, nullptr}, // +75ft
};
// For size_t/int32_t types on some platforms.
#include <cstdint>
// For size_t
#include <cstddef>

class BRCAddress
{
public:
BRCAddress(int32_t lat, int32_t lon)
{
bearing = GeoCoord::bearing(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * RAD_TO_HOUR;
bearing += 12.0 - BRC_NOON;
while (bearing > 12.0) {
bearing -= 12.0;
}

// In imperial units because that is how golden spike data is provided.
distance = GeoCoord::latLongToMeter(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * METER_TO_FEET;
};

int radial(char *buf, size_t len)
{
uint8_t hour = (uint8_t)(bearing);
uint8_t minute = (uint8_t)((bearing - hour) * 60.0);
hour %= 12;
if (hour == 0) {
hour = 12;
}
return snprintf(buf, len, "%d:%02d", hour, minute);
};

int annular(char *buf, size_t len)
{
const char *unit = "m";
float unitMultiplier = FEET_TO_METER;
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
unitMultiplier = 1.0;
unit = "ft";
}

if (bearing > 1.75 && bearing < 10.25) {
const char *street = nullptr;
float dist = 0;
// Find the appropriate street based on distance
for (const auto &s : streets) {
if (distance > s.center - s.width) {
street = s.name;
dist = distance - s.center;
} else {
break;
}
}
if (street) {
return snprintf(buf, len, "%s %d%s", street, int(dist * unitMultiplier), unit);
}
}

return snprintf(buf, len, "%d%s", int(distance * unitMultiplier), unit);
};
BRCAddress(int32_t lat, int32_t lon);

int full(char *buf, size_t len)
{
auto l = radial(buf, len - 4);
buf += l;
*(buf++) = ' ';
*(buf++) = '&';
*(buf++) = ' ';
buf += annular(buf, len - l - 4);
buf[l] = 0; // always null terminated
return l;
};
int radial(char *buf, size_t len);
int annular(char *buf, size_t len, bool noUnit);
int full(char *buf, size_t len);
int compact(char *buf, size_t len);

private:
float bearing;
Expand Down
15 changes: 10 additions & 5 deletions src/graphics/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ void Screen::setFrames(FrameFocus focus)

// Show detailed node views only on E-Ink builds
#ifdef USE_EINK
fsi.positions.nodelist_lastheard = numframes;
fsi.positions.nodelist_bearings = numframes;
normalFrames[numframes++] = graphics::NodeListRenderer::drawLastHeardScreen;
indicatorIcons.push_back(icon_nodes);

Expand All @@ -916,11 +916,15 @@ void Screen::setFrames(FrameFocus focus)
fsi.positions.nodelist_distance = numframes;
normalFrames[numframes++] = graphics::NodeListRenderer::drawDistanceScreen;
indicatorIcons.push_back(icon_distance);
#endif
#if HAS_GPS

fsi.positions.nodelist_bearings = numframes;
normalFrames[numframes++] = graphics::NodeListRenderer::drawNodeListWithCompasses;
indicatorIcons.push_back(icon_list);
#endif
#if HAS_GPS
fsi.positions.nodelist_brc = numframes;
normalFrames[numframes++] = graphics::NodeListRenderer::drawBRCList;
indicatorIcons.push_back(icon_bm);

fsi.positions.gps = numframes;
normalFrames[numframes++] = graphics::UIRenderer::drawCompassAndLocationScreen;
Expand Down Expand Up @@ -1386,7 +1390,8 @@ int Screen::handleInputEvent(const InputEvent *event)
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_hopsignal ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_distance ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_hopsignal ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_bearings) {
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_bearings ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_brc) {
Comment thread
Xaositek marked this conversation as resolved.
menuHandler::nodeListMenu();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.wifi) {
menuHandler::wifiBaseMenu();
Expand Down Expand Up @@ -1447,4 +1452,4 @@ bool shouldWakeOnReceivedMessage()
return false;
}
return true;
}
}
1 change: 1 addition & 0 deletions src/graphics/Screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ class Screen : public concurrency::OSThread
uint8_t nodelist_hopsignal = 255;
uint8_t nodelist_distance = 255;
uint8_t nodelist_bearings = 255;
uint8_t nodelist_brc = 255;
uint8_t clock = 255;
uint8_t firstFavorite = 255;
uint8_t lastFavorite = 255;
Expand Down
Loading