[GIS] One source to create multiple layers

openlayers

I have an GeoJSON source with the following specifications:

"properties": {
    "sensorid": 500,
    "Locatie": "Prinsestraat 18",
    "9_13_kw1": 513585.0,
    "13_18_kw1": 806317.0,
    "18_22_kw1": 545899.0,
    "22_9_kw1": 477801.0,
    "9_13_kw2": 519198.0,
    "13_18_kw2": 800637.0,
    "18_22_kw2": 550001.0,
    "22_9_kw2": 514971.0,
    "9_13_kw3": 615974.0,
    "13_18_kw3": 916019.0,
    "18_22_kw3": 562191.0,
    "22_9_kw3": 575459.0,
    "9_13_kw4": 615016.0,
    "13_18_kw4": 967845.0,
    "18_22_kw4": 557373.0,
    "22_9_kw4": 559056.0,
    "Totaal": 10097342
  }, 
  'geometry': {
    'type': 'Point',
    'coordinates': [x, y]
  }

Every value in a field in this JSON with the format "number_number_string" has to be in a different layer. E.g. 22_9_kw3 has to be in it's own layer, just as 18_22_kw4. The result will look look like this:

Different layers example - "9_13_kw1, 13_18_kw1 and 18_22_kw1"

As you can see in my example, there are multiple points displayed. Each point has it's own layer, but all the data is in 1 (see above) GeoJSON file.

The only way I know how to do this is to create a lot (16) different ol.layer.Vector's and check the properties during styling. Like this:

var meetpuntenSource = new ol.source.Vector ({
  url: 'points.geojson',
  format: new ol.format.GeoJSON()
});

var meetpuntenObject1 = new ol.layer.Vector ({ 
  source: meetpuntenSource,
  style: styleFunction
});

var meetpuntenObject2 = new ol.layer.Vector ({ 
  source: meetpuntenSource,
  style: styleFunction
});

ect.
With styleFunction:

var styleFunction = function(feature, resolution){
    var properties = feature.getProperties();
    if(meetpuntenObject2Toggle) {style = blablabla}

I hope you get the idea.
I want to be able to create different layers from the same source, because otherwise I have to load in a lot of the same data. Is there a better way?

EDIT

To illustrate this further, I explain what you see in my JSON:

  • ["9_13_kw1"] = the "name" of the property
  • [513585.0] = the value of the property, this value is the radius of the displayed circle (divided by a factor ofc.)

The points represent a sensor-point on the map. The value represents the measured value of that sensor. The more measured, the bigger the circle.

To display all these circles I have to create a layer of EACH of these "name"-value combinations.
Every coordinate will have thus 16 different layers: 4x ..kw1, 4x ..kw2, 4x ..kw3 and 4x ..kw4.

Best Answer

UPDATE: Trying to formulate an answer:

Load you json file with some AJAX function (a custom one here), and add to a new ol.layer.Vector depending on some parameter, called here category:

function getJson(url) {
    var getXhr = function() {
        var xhr = false;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                xhr = new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
                try {
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                } catch(e) {
                    xhr = false;
                }
            }
        }
        return xhr;
    };

    var
        xhr = getXhr(),
        when = {},
        onload = function() {
            if (xhr.status === 200) {
                when.ready.call(undefined, JSON.parse(xhr.response));
            } else {
                console.log("Status code was " + xhr.status);
            }
        },
        onerror = function() {
            console.log("Can't XHR " + JSON.stringify(url));
        },
        onprogress = function(event) {}
    ;
    xhr.open("GET", url, true);
    xhr.setRequestHeader("Accept","application/json");
    xhr.onload = onload;
    xhr.onerror = onerror;
    xhr.onprogress = onprogress;
    xhr.send(null);

    return {
        when: function(obj){
            when.ready = obj.ready;
        }
    };
}

getJson('http://data.mapeando.net/tmp/points.json').when({
    ready: function(response){
        console.info(response);

        /** Read from GeoJSON and add to different layer **/
        var features = new ol.format.GeoJSON()
            .readFeatures(response, {
                featureProjection: 'EPSG:3857'
            });

        features.forEach(function(feature) {
            var category = feature.get('category');
            var layer = thisLayerExists(category);
            if(layer) {
                //just add feature
                layer.getSource().addFeature(feature);
            } else {
                //add layer to map
                layer = new ol.layer.Vector({
                    name: category,
                    source: new ol.source.Vector({
                        features: [feature]
                    }),
                    style: point_style
                });
                map.addLayer(layer);
            }
        });
    }
});

Missing functions see http://jsfiddle.net/jonataswalker/z10de36z/.

Original answer

There is somewhat not OK with your logic. Take this GeoJSON object for example:

var geojsonObject = {
  'type': 'FeatureCollection',
  'crs': {
    'type': 'name',
    'properties': { 'name': 'EPSG:4326' }
  },
  'features': [
    {
      'type': 'Feature',
      'properties': {
        'category': 'cat1',
        'desc': 'Item - cat1'
      },
      'geometry': {
        'type': 'Point',
        'coordinates': [21.54967, 38.70250]
      }
    },
    {
      'type': 'Feature',
      'properties': {
        'category': 'cat1',
        'desc': 'Item 2 - cat1'
      },
      'geometry': {
        'type': 'Point',
        'coordinates': [20.54967, 36.70250]
      }
    }
  ]
};

This part (below) is a feature:

{
  'type': 'Feature',
  'properties': {
    'category': 'cat1',
    'desc': 'Item 2 - cat1'
  },
  'geometry': {
    'type': 'Point',
    'coordinates': [20.54967, 36.70250]
  }
}

But when you say "Every value in a field in this JSON with the format "22_9_kw1" has to be in a different layer.", you are trying to add a single feature to several layers, I think this is not what you want.

I think you should have a single property like a category to add the feature to different layer based on it.