1

I am encountering Uncaught (in promise) Error: Unsupported GeoJSON type: undefined. I am rendering it in OpenLayers using a MERN application. I have checked that the API call for the GeoJSON is returning correctly the data, though I am not sure if it is the right format. Could you check my code if this is the correct way to read and render the data? I have checked similar issues and they suggest to change the projection. Is my projection right? Or is it the way I store the data in the database that is the issue?

DataLayer.jsx

import { useEffect, useState } from "react";

import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import GeoJSON from "ol/format/GeoJSON";


const DataLayer = ({ map, layerType }) => {
    const [layers, setLayers] = useState([]);
  
    useEffect(() => {
      const fetchData = async () => {
        if (layerType === 'fireIncident') {
          const res = await fetch(`/api/fire_incident`);
          const data = await res.json();
  
            if (data && data.length > 0 ) {
            const wktOptions = {
                    featureProjection: 'EPSG:3857'
            }
            const vectorSource = new VectorSource({
                features: new GeoJSON().readFeatures(data, wktOptions),
            });
  
            console.log('GeoJSON data:', data)
            const vectorLayer = new VectorLayer({
                source: vectorSource,
            });
  
            map.addLayer(vectorLayer);
            setLayers((layers) => [...layers, vectorLayer]);
            }
        }
      };
  
      fetchData();
    }, [map, layerType]);
  
    return null;
  };
  
  export default DataLayer;

Basemap.jsx

import { useEffect, useRef, useState } from "react";
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from "ol/layer/Tile";
import XYZ from 'ol/source/XYZ';
import { fromLonLat } from "ol/proj";
import 'ol/ol.css';

const BaseMap = ({ center, zoom, children }) => {
  const mapElement = useRef();
  const [map, setMap] = useState(null);

  useEffect(() => {
    const initialMap = new Map({
      target: mapElement.current,
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            crossOrigin: 'anonymous',
          }),
        }),
      ],
      view: new View({
        center: fromLonLat(center),
        zoom: zoom,
      }),
    });

    setMap(initialMap);
    return () => initialMap.setTarget(null);
  }, [center, zoom]);

  return (
    <div id="map" ref={mapElement} style={{ width: '100%', height: '100vh' }}>
      {children(map)}
    </div>
  );
};

export default BaseMap;

Here is the GeoJSON data from the API call which returns 2 results:

[{"properties":{"incyr":2019,"month":"February","penro":"PPG","cenro":"","location":"Brgy Diaz","occur_date":"2019-02-10T00:00:00.000Z","cause":2,"area_damage":1},"geometry":{"type":"Point","coordinates":[120.51350683576823,15.099785805351729]},"_id":"6547bc4174377cd1cbd44415","type":"Feature","__v":0},{"properties":{"incyr":2020,"month":"March","penro":"PPG","cenro":"","location":"San Vicente","occur_date":"2020-03-29T00:00:00.000Z","cause":1,"area_damage":0.5},"geometry":{"type":"Point","coordinates":[120.73099597560082,15.233933632945224]},"_id":"6547bc6174377cd1cbd44417","type":"Feature","__v":0}]

Mongoose schema:

const fireIncidentSchema = new mongoose.Schema({
  type: {
    type: String,
    enum: ['Feature'],
    required: true
  },
  properties: {
    incyr: Number,
    month: String,
    penro: String,
    cenro: String,
    location: String,
    occur_date: Date,
    cause: Number,
    area_damage: Number
  },
  geometry: {
    type: {
      type: String,
      enum: ['Point'],
      required: true
    },
    coordinates: {
      type: [Number],
      required: true
    }
  }
  });

1 Answer 1

2

readFeatures expects a GeoJSON feature collection, your data is a array of feature jsons which must be read individually:

  const vectorSource = new VectorSource({
    features: data.map((f) => new GeoJSON().readFeature(f, wktOptions))
  });
2
  • The error I am encountering now is Uncaught (in promise) TypeError: feature.getId is not a function.
    – Sonny
    Commented Nov 6, 2023 at 0:38
  • Ah sorry, I forgot to remove the 's' from readFeatures. Thank you. It is now working.
    – Sonny
    Commented Nov 6, 2023 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.