This weekend I built ISS Tracker using leaflet a map provider without API or paywalls and there aren't many examples with Svelte implementation.
Leaflet has excellent documentation for JS most things can be achieved with just JS.
Prerequisites:
1/ Svelte starter template (https://svelte.dev/)
2/ ISS API (http://open-notify.org/Open-Notify-API/)
3/ Leaflet via NPM (https://www.npmjs.com/package/leaflet)
4/ *some amount of patience.*
Using the boilerplate fetch with svelte and obtaining the json data from the API.
const URL = "http://api.open-notify.org/iss-now.json"
async function fetchInfo() {
const res = await fetch(URL).then(async data => {
let d = await data.json();
lat = d.iss_position.latitude
lon = d.iss_position.longitude
console.log({lat,lon})
marker.setLatLng([lat, lon]).update();
m.panTo([lat, lon]);
})
setTimeout(fetchInfo,5000)
}
This gives us latitude and longitude that which we can plot on the map. The setTimeout()
is to set positions of the ISS every 5 seconds 😉.
Now leaflet will test your patience basically it is a mash of several tutorials here https://leafletjs.com/examples.html 😅
Here is a small snippet that will help you thanks to this post
The base config can be done like this
import * as L from 'leaflet';
//fancy custom icon
var ISS_Icon = L.icon({
iconUrl: './favicon.png',
iconSize: [48, 48], // size of the icon
});
function createMap(container) {
m = L.map(container).setView([0, 0], 2);
marker = L.marker(m.getCenter(), {icon: greenIcon}).addTo(m)
L.tileLayer(
'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
attribution: `©<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>`,
subdomains: 'abcd',
maxZoom: 14,
}
).addTo(m);
return m;
}
function mapAction(container) {
map = createMap(container);
return {
destroy: () => {
map.remove();
},
};
}
Because leaflet can't repaint itself you will find some grey patches without it a combination of <svelte:window>
calling the resizeMap()
will fix it.
function resizeMap() {
if (map) {
map.invalidateSize();
}
}
<svelte:window on:resize={resizeMap} />
<div style="height:600px;width:100%" use:mapAction /> //invokes the map
Now let's consume the other good juicy stuff from that API. ISS crosses above your location from here obtain and list next 5 passes from the obtained from Using the Geolocation API and the API has CORS... Hmm... 🤔🤔🤔 We can use https://cors-anywhere.herokuapp.com/
before the URL and get the data 😝
let warntext = 'Please allow location access to know when ISS will pass your location.'
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("Geolocation is not supported by this browser / Not shared")
}
}
function showPosition(position) {
console.log(position.coords.latitude, position.coords.longitude);
fetchPasses(position.coords.latitude, position.coords.longitude)
}
getLocation()
let ISSPass = '';
async function fetchPasses(lt, ln) {
warntext = 'loading...'
const res = await fetch(`https://cors-anywhere.herokuapp.com/${passes}lat=${lt}&lon=${ln}`).then(
async data => {
let d = await data.json();
ISSPass = await d.response;
warntext = 'Check below for the passes!'
})
}
And in the svelte we can populate like this
<span>{warntext}</span>
<ul>
{#each ISSPass as item}
<li>
{new Date(item.risetime*1000).toLocaleString()} <br>
</li>
{/each}
</ul>
Thanks for reading my post it's little longer than my usual posts.
Here is the repo.
https://github.com/peopledrivemecrazy/svelte-iss
Enjoy.
Top comments (0)