简体   繁体   中英

How do i join an external json file with features from Vectortile source in OpenLayers?

I am new to programming i would like to know if it is possible to use feature.set() to join an external json file to a feature originating from a vector tile source.

import 'ol/ol.css';
import MVT from 'ol/format/MVT';
import Map from 'ol/Map';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import View from 'ol/View';
import {Fill, Stroke, Style} from 'ol/style';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';


 // define some colours matching some arbitrary divisions of the
      // OECD income data
      var high = [64,196,64,1];
      var mid = [108,152,64,1];
      var low = [152,108,64,1];
      var poor = [196,32,32,1];
      // map the income level codes to a colour value, grouping them
      var incomeLevels = {
        'HIC': high, // high income
        'OEC': high, // high income OECD
        'NOC': high, // high income, non-OECD
        'UMC': mid, // upper middle income
        'MIC': mid, // middle income
        'LMC': mid, // lower middle income
        'LIC': low, // low income
        'LMY': low, // low and middle income
        'HPC': poor // heavily indebted poor country
      };

      // a default style is good practice!
      var defaultStyle = new Style({
        fill: new Fill({
          color: [250,250,250,1]
        }),
        stroke: new Stroke({
          color: [220,220,220,1],
          width: 1
        })
      });

      // a javascript object literal can be used to cache
      // previously created styles. Its very important for
      // performance to cache styles.
      var styleCache = {};

      // the style function returns an array of styles
      // for the given feature and resolution.
      // Return null to hide the feature.
      function styleFunction(feature, resolution) {
        // get the incomeLevel from the feature properties
        var level = feature.get('incomeLevel');
        // if there is no level or its one we don't recognize,
        // return the default style (in an array!)
        if (!level || !incomeLevels[level]) {
          return [defaultStyle];
        }
        // check the cache and create a new style for the income
        // level if its not been created before.
        if (!styleCache[level]) {
          styleCache[level] = new ol.style.Style({
            fill: new ol.style.Fill({
              color: incomeLevels[level]
            }),
            stroke: defaultStyle.stroke
          });
        }
        // at this point, the style for the current level is in the cache
        // so return it (as an array!)
        return [styleCache[level]];
      }

var source = new VectorTileSource({
    maxZoom: 15,
    format: new MVT({
     // idProperty: 'UN_A3',
    }),
    url:
      'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/' +
      'countries:ne_110m_admin_0_countries@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf',
  });


// VectorTile Layer Constuctor to the Map.
var vtLayer = new VectorTileLayer({
  declutter: true,
  source: new VectorTileSource({
    maxZoom: 15,
    format: new MVT({
     // idProperty: 'UN_A3',
    }),
    url:
      'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/' +
      'countries:ne_110m_admin_0_countries@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf',
  }),
  style:styleFunction // here we apply the styleFunction to the layer
});


//In order to create the map viewer, you must first create a map. 
//The OpenLayers.Map constructor requires one argument:
// This argument must either be an HTML Element, or the ID of an HTML element. 
//This is the element in which the map will be placed.
// Map Constuctor
var map = new Map({
  layers: [vtLayer],
  // 'map' the ID of an HTML element which id the target container.
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2,
    multiWorld: true,
  }),
});


// Reading JSON with joined attributes for tjsApi with XMLHttpRequest.XMLHttpRequest API provides client functionality for transferring data between a client and a server. It allows an easy way to retrieve data from a URL without having to do a full page refresh.
   
   var getJSON = function(url, callback) {
   
//This reads JSON data with XMLHttpRequest.
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    
    xhr.onload = function() {
    
        var status = xhr.status;
        
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    
    xhr.send();
};
getJSON('http://127.0.0.1:5000/tjs/api/v1/resources/income', function(err, data) {
    
    if (err != null) {
        console.error(err);
    } else {
console.log(data);
    }
    
    vtLayer.getSource().forEachFeature(pixel ,function(feature){
        
        var code = feature.get('ISO_A2');
        if (data[code]) {
                feature.set('incomeLevel', data[code]);
              }
        
    });
});

 var key = source.on('change', function(event) {
        if (source.getState() == 'ready') {
          source.unByKey(key);
getJSON('http://127.0.0.1:5000/tjs/api/v1/resources/income', function(err, data) {
    
    if (err != null) {
        console.error(err);
    } else {
console.log(data);
    }
    
    vtLayer.getSource().forEachFeature(function(feature){
        
        var code = feature.get('ISO_A2');
        if (data[code]) {
                feature.set('incomeLevel', data[code]);
              }
        
    });
});

 }
      });

I am trying to follow the example ( http://openlayersbook.github.io/ch06-styling-vector-layers/example-07.html ). I keep getting an error on vtLayer.getSource().forEachFeature(function(feature) is there a way around it?

A vector tile source does not have features, the tiles do. You can access them as the tiles load (maybe push them into an array for later use?)

vtLayer.getSource().on('tileloadend', function(evt) {
    var features = evt.tile.getFeatures();
    ...
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM