Created
March 10, 2023 19:10
-
-
Save oberhamsi/7834b8ad8343beb48687d73ae12fbf2b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const httpclient = require('ringo/httpclient'); | |
const files = require('ringo/utils/files'); | |
const fs = require('fs'); | |
const {command} = require('ringo/subprocess'); | |
const {toot} = require('mastodon-api'); | |
// wien | |
/* | |
const left=16.18; | |
const bottom=48.11; | |
const right=16.58; | |
const top=48.33; | |
*/ | |
// narrow wien | |
const left = 16.2289; | |
const bottom = 48.1095; | |
const right = 16.499; | |
const top = 48.2596; | |
const zoom = 20; | |
const tileWidth = 4; | |
const sendBasemapToo = false; | |
const mastodonConfig = { | |
accessToken: 'XXXXXXXXX', | |
statusUrl: 'https://botsin.space/api/v1/statuses', | |
mediaUrl: 'https://botsin.space/api/v1/media' | |
}; | |
function long2tile(lon, zoom) { | |
return (Math.floor((lon+180)/360*Math.pow(2,zoom))); | |
} | |
function lat2tile(lat, zoom) { | |
return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); | |
} | |
function tile2long(x, zoom) { | |
return (x/Math.pow(2,zoom)*360-180); | |
} | |
function tile2lat(y, zoom) { | |
var n= Math.PI-2*Math.PI*y/Math.pow(2,zoom); | |
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n)))); | |
} | |
function getRandom(min, max) { | |
return Math.random() * (max - min) + min; | |
} | |
function convertCoordinates(tileCoords) { | |
const lat = tile2lat(tileCoords[1], zoom); | |
const lon = tile2long(tileCoords[0], zoom); | |
const x = (lon * 20037508.34) / 180; | |
let y = Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180); | |
y = (y * 20037508.34) / 180; | |
return [x, y]; | |
} | |
function getTilesToCombine() { | |
const lon = getRandom(left, right); | |
const lat = getRandom(bottom, top); | |
const xTile = long2tile(lon, zoom) | |
const yTile = lat2tile(lat, zoom); | |
let combineTiles = []; | |
for (let y=0;y<tileWidth;y++) { | |
for (let x=0;x<tileWidth;x++) { | |
combineTiles.push([ | |
xTile+x, yTile+y | |
]) | |
} | |
} | |
return combineTiles; | |
} | |
function getTileImages(combineTiles, mapType, imageType) { | |
return combineTiles.map(function(tileCoords) { | |
const tileUrl = `https://maps.wien.gv.at/basemap/${mapType}/normal/google3857/${zoom}/${tileCoords[1]}/${tileCoords[0]}.${imageType}`; | |
console.log('retrieving', tileUrl) | |
const exchange = httpclient.request({ | |
method: 'GET', | |
url: tileUrl | |
}); | |
if (exchange.status !== 200) { | |
throw 'error retrieving tile ' + exchange.status; | |
} | |
const tempFile = files.createTempFile('satellite-bot', '.jpeg'); | |
fs.write(tempFile, exchange.contentBytes); | |
return tempFile; | |
}); | |
} | |
function combineImages(imagePaths) { | |
const combinedTempFile = files.createTempFile('combined-satellite-bot', '.jpeg'); | |
let args = [ | |
'gm', 'montage', | |
'-geometry', '256x256', | |
'-tile', tileWidth + 'x' + tileWidth, | |
].concat(imagePaths).concat([combinedTempFile]); | |
command.apply(command, args); | |
imagePaths.forEach(function(path) { | |
fs.remove(path); | |
}) | |
return combinedTempFile; | |
} | |
function main() { | |
const combineTiles = getTilesToCombine(); | |
const satImagePaths = getTileImages(combineTiles, 'bmaporthofoto30cm', 'jpeg'); | |
const satCombinedImage = combineImages(satImagePaths); | |
const mediaPaths = [satCombinedImage] | |
if (sendBasemapToo) { | |
const baseImagePaths = getTileImages(combineTiles, 'geolandbasemap', 'png'); | |
const baseCombinedImage = combineImages(baseImagePaths); | |
mediaPaths.push(baseCombinedImage); | |
} | |
const centerIdx = tileWidth * (tileWidth/2) + (tileWidth/2); | |
const centerTile = JSON.parse(JSON.stringify(combineTiles[centerIdx])); | |
const centerTileCoords = JSON.stringify(convertCoordinates(centerTile)); | |
const url = `https://basemap.at/bmapp/#{%22center%22:${centerTileCoords},%22zoom%22:${zoom},%22rotation%22:0,%22layers%22:%221000000000%22}`; | |
const satToot = toot(mastodonConfig, url, mediaPaths); | |
mediaPaths.forEach(function(path) { | |
fs.remove(path); | |
}); | |
console.log('sat toot result', JSON.stringify(satToot)); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment