I'm building a simple ISS tracker with coordinates from the API using Open layers. The map and the point renders correctly, but I can't update the position of the point on the map without refreshing the page. I paste the code below.
import "ol/ol.css"
import Feature from "ol/Feature"
import Map from "ol/Map"
import Point from "ol/geom/Point"
import View from "ol/View"
import { Circle, Fill, Style } from "ol/style"
import { OSM, Vector as VectorSource } from "ol/source"
import { Tile, Vector } from "ol/layer"
import { fromLonLat } from "ol/proj"
const getISSPosition = () => {
fetch("https://api.wheretheiss.at/v1/satellites/25544")
.then(res => res.json())
.then(data => {
const ISSPosition = [data.longitude, data.latitude]
const ISSPositionMercator = fromLonLat(ISSPosition)
const map = new Map({
layers: [
new Tile({
source: new OSM()
})
],
target: "map",
view: new View({
center: [ISSPositionMercator[0], ISSPositionMercator[1]],
zoom: 2
})
})
const positionFeature = new Feature()
positionFeature.setStyle(
new Style({
image: new Circle({
radius: 4,
fill: new Fill({
color: "red"
})
})
})
)
positionFeature.setGeometry(new Point(ISSPositionMercator))
new Vector({
map: map,
source: new VectorSource({
features: [positionFeature]
})
})
})
}
getISSPosition()
Separate the call to the service from the construction of the map. Construct the map once, then update the position of the marker periodically by calling the service with setInterval
.
Create map:
const map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: "map",
view: new ol.View({
center: [0, 0],
zoom: 2
})
})
positionFeature.setStyle(
new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: "red"
})
})
})
)
new ol.layer.Vector({
map: map,
source: new ol.source.Vector({ // VectorSource({
features: [positionFeature]
})
});
update marker:
const updateISSPosition = () => {
fetch("https://api.wheretheiss.at/v1/satellites/25544")
.then(res => res.json())
.then(data => {
const ISSPosition = [data.longitude, data.latitude]
const ISSPositionMercator = ol.proj.fromLonLat(ISSPosition);
positionFeature.setGeometry(new ol.geom.Point(ISSPositionMercator));
map.getView().setCenter(ISSPositionMercator);
console.log(ISSPositionMercator);
});
}
code snippet:
const positionFeature = new ol.Feature();
const updateISSPosition = () => {
fetch("https://api.wheretheiss.at/v1/satellites/25544")
.then(res => res.json())
.then(data => {
const ISSPosition = [data.longitude, data.latitude]
const ISSPositionMercator = ol.proj.fromLonLat(ISSPosition);
positionFeature.setGeometry(new ol.geom.Point(ISSPositionMercator));
map.getView().setCenter(ISSPositionMercator);
console.log(ISSPositionMercator);
});
}
const map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: "map",
view: new ol.View({
center: [0, 0],
zoom: 2
})
})
positionFeature.setStyle(
new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: "red"
})
})
})
)
new ol.layer.Vector({
map: map,
source: new ol.source.Vector({ // VectorSource({
features: [positionFeature]
})
});
updateISSPosition();
setInterval(updateISSPosition, 5000);
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 90%;
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/build/ol.js"></script>
<title>OpenLayers example</title>
<b>My Map</b>
<div id="map" class="map"></div>