ghettovoice / vuelayers

Web map Vue components with the power of OpenLayers
https://vuelayers.github.io/
MIT License
682 stars 230 forks source link

Issues with vl-source-vector using custom strategy/loader #506

Closed kevinelliott closed 1 year ago

kevinelliott commented 1 year ago

There are a couple of issues with vl-source-vector / VlSourceVector:

1) When using loader-factory, there is a deprecation warning to use loader ... when changed to loader, the loader is not called.

2) If url is not specified, the loader is never called even though it should be. Specifying url="-" forces the loader to be called, but it will only call it once since it believes it's a static dataset even though it should be called for each change in view extent.

3) If strategy factory specified with strategy-factory there is an error:

Uncaught TypeError: this.strategy_ is not a function
    at VectorSource.loadFeatures (Vector.js?5831:888:1)
    at CanvasVectorLayerRenderer.prepareFrame (VectorLayer.js?da2f:472:1)
    at Layer.render (Layer.js?1af9:261:1)
    at CompositeMapRenderer.renderFrame (Composite.js?1856:121:1)
    at PluggableMap.renderFrame_ (PluggableMap.js?fe37:1291:1)
    at Map.eval (PluggableMap.js?fe37:245:1)
      <vl-layer-vector>
        <vl-source-vector
          :strategy-factory="strategyFactory"
          :loader-factory="loaderFactory"
          url="-"
          id="airports">
        </vl-source-vector>
      </vl-layer-vector>
  loaderFactory() {
    return (extent: any[], resolution: any, projection: any) => {
      console.log('going to load airports');
      const url = `${this.baseUrl}/airports/bbox/${extent.join(',')}`;
      return fetch(url)
        .then((r) => r.json())
        .then((airports) => {
          const features = airports.map((a: any) => ({
            type: 'Feature',
            geometry: {
              type: 'Point',
              coordinates: [a.longitude, a.latitude],
            },
            properties: {
              name: a.name || a.ident,
              id: a.id,
            },
          }));
          const geojson = {
            type: 'FeatureCollection',
            features,
          };
          console.log(geojson);
          return geojson;
        });
    };
  }

This is with VueLayers 0.12.3.

ghettovoice commented 1 year ago

Hello @kevinelliott , sorry for the late response. The loader looks correct. I guess you have incorrect strategy-factory function, so it prevents calling of your custom loader. If you use deprecated strategy-factory prop, then it should be a function that returns loading strategy function.

Or you can switch to the new simplified props:

<vl-layer-vector>
  <vl-source-vector
    :loading-strategy="loadBBox"
    :loader="airportsLoader"
    id="airports">
  </vl-source-vector>
</vl-layer-vector>

<script>
import { bbox as loadBBox } from 'ol/loadingstrategy'

export default {
  methods: {
    loadBBox,
    async loader (extent, resolution, projection) {
      return fetch('https://....').then(res => res.json()) // return GeoJSON FeatureCollection or array of GeoJSON features
    },
  },
}
</script>
github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.