Skip to content

Commit

Permalink
Merge pull request #79 from MoffKalast/ros2-navsat-additions
Browse files Browse the repository at this point in the history
Navsat Additions (ROS 2)
  • Loading branch information
MoffKalast authored May 22, 2024
2 parents e64a396 + 9e04828 commit 2487ffb
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 58 deletions.
67 changes: 46 additions & 21 deletions vizanti_server/public/js/modules/navsat.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ export class Navsat {
this.queue = new Set();
this.queue_history = new Set();

this.loadingloop = async ()=>{
this.download_queue = new Set();
this.currently_downloading = new Set();

while(this.queue.size > 0){
let items = Array.from(this.queue);
let tile_url = items[0];
let loaded = undefined;
this.loadingloop = async ()=>{

let items = Array.from(this.queue);
for(let tile_url of items){

//we already got it?
if(this.live_cache[tile_url] !== undefined){
this.queue.delete(tile_url);
Expand All @@ -37,28 +38,46 @@ export class Navsat {
//check the indexed DB
if(Boolean(await db.keyExists(tile_url))){
const data = await db.getObject(tile_url);
loaded = await dataToImage(data);
}else{
//download from tile server, in case there's no internet we don't hang forever
const timeout = new Promise(resolve => setTimeout(() => resolve(undefined), 4000));
const data = await Promise.race([imageToDataURL(tile_url), timeout]);

if(data){
//info.downloaded++;
db.setObject(tile_url, data);
loaded = await dataToImage(data);
}
}

if(loaded){
this.live_cache[tile_url] = loaded;
this.live_cache[tile_url] = await dataToImage(data);
this.queue.delete(tile_url);
continue;
}

//hit up the CDN
this.download_queue.add(tile_url);
}

setTimeout(this.loadingloop, 500);
setTimeout(this.loadingloop, 100);
}
this.loadingloop();

this.downloadingloop = async ()=>{

const attemptDownload = async (tile_url) => {
//download from tile server, in case there's no internet we don't hang forever
const timeout = new Promise(resolve => setTimeout(() => resolve(undefined), 4000));
const data = await Promise.race([imageToDataURL(tile_url), timeout]);

if (data) {
await db.setObject(tile_url, data);
this.live_cache[tile_url] = await dataToImage(data);
this.download_queue.delete(tile_url);
}

this.currently_downloading.delete(tile_url);
}

// Inside your loop
let items = Array.from(this.download_queue);
for (let tile_url of items) {
if(tile_url && !this.currently_downloading.has(tile_url)){
this.currently_downloading.add(tile_url);
attemptDownload(tile_url);
}
}
setTimeout(this.downloadingloop, 500);
}
this.downloadingloop();
}

async enqueue(keyurl){
Expand All @@ -69,6 +88,12 @@ export class Navsat {
this.queue.add(keyurl);
}

async clear_queue(keyurl){
this.queue = new Set();
this.queue_history = new Set();
this.download_queue = new Set();
}

//https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
coordToTile(lon, lat, zoom) {
return {
Expand Down
4 changes: 2 additions & 2 deletions vizanti_server/public/js/modules/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ function hasClassInParentChain(element, className) {
return hasClassInParentChain(element.parentElement, className);
}

const MAX_SCALE = 10000;
const MIN_SCALE = 3.0;
const MAX_SCALE = 5000;
const MIN_SCALE = 0.001;
const ZOOM_FACTOR = 1.05;

export class View {
Expand Down
4 changes: 2 additions & 2 deletions vizanti_server/public/templates/grid/grid_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ linethickness.addEventListener("input", (event) =>{
});

gridstep.addEventListener("input", (event) =>{
if(gridstep.value > 10000)
grid_size = 10000;
if(gridstep.value > 1000000)
grid_size = 1000000;
else if(gridstep.value < 0.01)
grid_size = 0.01;
else if(isNaN(gridstep.value))
Expand Down
105 changes: 72 additions & 33 deletions vizanti_server/public/templates/satelite/satelite_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let copyright = "© OpenStreetMap";
let topic = getTopic("{uniqueID}");
let server_url = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
let listener = undefined;
let zoomLevel = 19;
let zoomLevel = 12;

let map_topic = undefined;
let map_fix = undefined;
Expand Down Expand Up @@ -91,15 +91,16 @@ function saveSettings(){
settings.save();
}

function drawTile(screenSize, i, j){
function drawTile(screenSize, i, j, tempMeterSize, tempZoomLevel, maxtile){

const x = fix_data.tilePos.x + i;
const y = fix_data.tilePos.y + j;
//wrap around the date line
const x = (fix_data.tilePos.x + i + maxtile + 1) % (maxtile + 1);
const y = (fix_data.tilePos.y + j + maxtile + 1) % (maxtile + 1);

const offsetX = fix_data.offset.x - i * fix_data.metersSize;
const offsetY = fix_data.offset.y - j * fix_data.metersSize;
const offsetX = fix_data.offset.x - i * tempMeterSize;
const offsetY = fix_data.offset.y - j * tempMeterSize;

const tileURL = server_url.replace("{z}",zoomLevel).replace("{x}",x).replace("{y}",y);
const tileURL = server_url.replace("{z}",tempZoomLevel).replace("{x}",x).replace("{y}",y);
let tileImage = navsat.live_cache[tileURL];

if(!tileImage || !tileImage.complete){
Expand Down Expand Up @@ -144,6 +145,14 @@ function drawTile(screenSize, i, j){
ctx.restore();
}

function clamp(val, from, to){
if(val > to)
return to;
if(val < from)
return from;
return val;
}

//Rendering
async function drawTiles(){

Expand All @@ -160,9 +169,19 @@ async function drawTiles(){

const frame = tf.absoluteTransforms[map_fix.header.frame_id];

let tempZoomLevel = Math.round(Math.log2(view.scale)+17);
tempZoomLevel = clamp(tempZoomLevel, 7, 19);
if(tempZoomLevel != zoomLevel){
navsat.clear_queue();
zoomLevel = tempZoomLevel;
updateFixData();
}


if(frame){

const tileScreenSize = view.getMapUnitsInPixels(fix_data.metersSize);
let metersSize = navsat.tileSizeInMeters(map_fix.latitude, tempZoomLevel)
const tileScreenSize = view.getMapUnitsInPixels(metersSize);
const corners = [
{ x: 0, y: 0, z: 0 },
{ x: wid, y: 0, z: 0 },
Expand All @@ -187,19 +206,37 @@ async function drawTiles(){

// Convert the corners to tile coordinates
const cornerTileCoords = cornerCoords.map((coord) =>
navsat.coordToTile(coord.longitude, coord.latitude, zoomLevel)
navsat.coordToTile(coord.longitude, coord.latitude, tempZoomLevel)
);

// Calculate the range of tiles to cover the screen
const minX = Math.min(...cornerTileCoords.map((coord) => coord.x)) - fix_data.tilePos.x;// - 1;
const minX = Math.min(...cornerTileCoords.map((coord) => coord.x)) - fix_data.tilePos.x;
const maxX = Math.max(...cornerTileCoords.map((coord) => coord.x)) - fix_data.tilePos.x;// + 1;
const minY = Math.min(...cornerTileCoords.map((coord) => coord.y)) - fix_data.tilePos.y;// - 1;
const maxY = Math.max(...cornerTileCoords.map((coord) => coord.y)) - fix_data.tilePos.y;// + 1;

for (let i = minX; i <= maxX; i++) {
for (let j = minY; j <= maxY; j++) {
drawTile(tileScreenSize, i, j);
//draw tiles in concentric circles, starting from the center of the screen
const matrixWidth = (maxX - minX)+2;
const matrixHeight = (maxY - minY)+2;
const centerX = Math.round((maxX+minX)/2);
const centerY = Math.round((maxY+minY)/2)-1;
const maxtile = Math.pow(2, tempZoomLevel) - 1;

let x = 0;
let y = 0;
let dx = 0;
let dy = -1;

const maxDimension = Math.max(matrixWidth, matrixHeight);
for (let i = 0; i < maxDimension ** 2; i++) {
if (-matrixWidth / 2 < x && x <= matrixWidth / 2 && -matrixHeight / 2 < y && y <= matrixHeight / 2) {
drawTile(tileScreenSize, centerX+x, centerY+y, metersSize, tempZoomLevel, maxtile);
}
if (x === y || (x < 0 && x === -y) || (x > 0 && x === 1 - y)) {
[dx, dy] = [-dy, dx];
}
x += dx;
y += dy;
}

ctx.globalAlpha = 0.6;
Expand Down Expand Up @@ -245,32 +282,34 @@ function connect(){
}

map_fix = msg;

const tilePos = navsat.coordToTile(map_fix.longitude, map_fix.latitude, zoomLevel);
const tileCoords = navsat.tileToCoord(tilePos.x, tilePos.y, zoomLevel);
const nextTileCoords = navsat.tileToCoord(tilePos.x+1, tilePos.y+1, zoomLevel);
const metersSize = navsat.tileSizeInMeters(map_fix.latitude, zoomLevel);

fix_data = {
tilePos: tilePos,
tileCoords: tileCoords,
offset:{
x: navsat.haversine(map_fix.latitude, tileCoords.longitude, map_fix.latitude, map_fix.longitude),
y: navsat.haversine(tileCoords.latitude, map_fix.longitude, map_fix.latitude, map_fix.longitude)
},
metersSize: metersSize,
degreesPerMeter: {
longitude: Math.abs(tileCoords.longitude - nextTileCoords.longitude)/metersSize,
latitude: Math.abs(tileCoords.latitude - nextTileCoords.latitude)/metersSize
}
}

updateFixData();
drawTiles();
});

saveSettings();
}

function updateFixData(){
const tilePos = navsat.coordToTile(map_fix.longitude, map_fix.latitude, zoomLevel);
const tileCoords = navsat.tileToCoord(tilePos.x, tilePos.y, zoomLevel);
const nextTileCoords = navsat.tileToCoord(tilePos.x+1, tilePos.y+1, zoomLevel);
const metersSize = navsat.tileSizeInMeters(map_fix.latitude, zoomLevel);

fix_data = {
tilePos: tilePos,
tileCoords: tileCoords,
offset:{
x: navsat.haversine(map_fix.latitude, tileCoords.longitude, map_fix.latitude, map_fix.longitude),
y: navsat.haversine(tileCoords.latitude, map_fix.longitude, map_fix.latitude, map_fix.longitude)
},
metersSize: metersSize,
degreesPerMeter: {
longitude: Math.abs(tileCoords.longitude - nextTileCoords.longitude)/metersSize,
latitude: Math.abs(tileCoords.latitude - nextTileCoords.latitude)/metersSize
}
}
}

async function loadTopics(){
let result = await rosbridge.get_topics("sensor_msgs/msg/NavSatFix");

Expand Down

0 comments on commit 2487ffb

Please sign in to comment.