reactjsopenlayersopenlayers-8

Changing coordinates of Point geometry hides it


I am attempting to set a new coordinate for a Point geometry every second, but as soon as I set a new coordinate the geometry becomes invisible. I can see that the point geometry (feature) is still attached to the vector source, but it does not show.

What am I missing?

Source code: React + OpenLayers

import React, { useEffect, useRef } from "react";
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import Feature from "ol/Feature";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { fromLonLat } from "ol/proj";
import OSM from "ol/source/OSM";
import { Point } from "ol/geom";

export default () => {
  const mapRef = useRef();
  const trafficLayer = useRef();
  const aircraftPoint = useRef();

  useEffect(() => {
    aircraftPoint.current = new Feature({
      geometry: new Point(fromLonLat([113.89076390019189, 22.324364815058356]))
    });

    trafficLayer.current = new VectorLayer({
      source: new VectorSource({
        features: [aircraftPoint.current]
      })
    });

    new Map({
      target: mapRef.current,
      layers: [
        new TileLayer({
          source: new OSM()
        }),
        trafficLayer.current
      ],
      view: new View({
        center: fromLonLat([113.91, 22.32]),
        zoom: 14
      })
    });
  });

  useEffect(() => {
    const coordinates = [
      [12678261.843426304, 2550513.917829821],
      [12678276.389975028, 2550516.8934089835],
      [12678294.68746191, 2550522.6226611948],
      [12678310.736252038, 2550529.163896087],
      [12678321.009343857, 2550532.68416079],
      [12678341.116984975, 2550538.615152849],
      [12678352.285823219, 2550542.3976743887]
    ];

    let counter = 0;

    function moveAirplane() {
      console.log("Moving airplane: ", counter);

      const lonlat = fromLonLat([
        coordinates[counter][1],
        coordinates[counter][0]
      ]);
      aircraftPoint.current.getGeometry().setCoordinates(lonlat);

      if (counter + 1 > coordinates.length - 1) {
        counter = 0;
      } else {
        counter = counter + 1;
      }
    }

    let intervalId = setInterval(moveAirplane, 1000);
    return () => {
      clearInterval(intervalId);
    };
  }, []);

  return <div className="map" ref={mapRef} />;
};

Solution

    1. Correct answer

    The correct answer is explained by @Mike in his comments. You should use degree coordinates to make it work.

    1. Re-factoring

    This is not asked but the declaration following function should be reviewed:

    function moveAirplane()

    Reason: The setInterval will trigger the useEffect every seconds, which will recreate the same function over and over. I think you should move it to higher scope. Here is my code review:

    https://codesandbox.io/s/react-openlayers-forked-qp4zw8

    Continuing response to @JJY9 comment: enter image description here

    @JJY9, this is working as you mentioned because you've small environment (1 plane, and all known coordinates). For instance: