2

I'm trying to mimic most of the great google-vector-layers and leaflet-vector-layers from Jason Sanford (https://github.com/JasonSanford) to easily display, style and add customized popups for data from Postgis-databases. This works in combination with a modified version of the PHP-Database-GeoJSON from Bryan McBride.

Until now I got a lot of things to work (load Postgis-layers, by passing field-nemes and a WHERE-cause, creating layer-individual popups, ...) but I'm actually having problems to implement a styling function.

In the examples mentioned above they pass a symbology-object to a constructor that cares about the styling of the layer. I've tried to use and adapt this code so that it could work in Openlayers 3 as well, but I need help from experienced developers. Could someone have a look at the code and point me in the right direction?

The layer definitions, that are used to create new ol3Vectors look like this:

n2k_dh_l = new ol3Vector({
            map: map,
            title: "Natura 2000 Habitats Directive",
            attribution: "<br />Réseau Natura 2000 Habitats Directive",
            geotable: "n2k_dh",
            fields: "gid as id,surfha,sitecode,sitename",
            where: "sitename ilike '%moselle%'",
            minResolution: 0.01,
            maxResolution: 50,
            content: "<p><strong> BH {sitecode}</strong><hr>{sitename}<br />{surfha} ha </p>",
            symbology: {
               type: "single",
               styleOptions: {
                  fill: "rgba(100,250,0,0.1)",
                  color: "green",
                  width: 2
               }
            }
});

communes = new ol3Vector({
            map: map,
            title: "Communes",
            attribution: "<br />Communes ACT",
            geotable: "communes",
            fields: "gid as id,surfha,commune,stat",
            where: "",
            minResolution: 0.01,
            maxResolution: 50,
            content: "<p><strong>{commune}</strong><hr>{stat}<br />{surfha} ha </p>",
            symbology:{
               type: "unique",
               property: "stat",
               values: [
                {
                value: "XYZ",
                styleOptions: {
                    fill: "rgba(100,250,0,0.1)",
                    color: "green",
                    width: 2                
                }},
                {
                value: "UVZ",
                styleOptions: {
                    fill: "rgba(100,250,0,0.1)",
                    color: "red",
                    width: 2                
                }},
                {
                value: "",
                styleOptions: {
                    fill: "rgba(100,250,0,0.1)",
                    color: "grey",
                    width: 2        
                }}
                ]   
            }
});

Inside the ol3Vector-constructor I try to implement a function to style features based on the symbology defined in the layer options.

When I pass the style options for a layer with a single style directly like this:

style: new ol.style.Style({
            fill: new ol.style.Fill({color: options.symbology.styleOptions.fill}),
                stroke: new ol.style.Stroke({
                    color: options.symbology.styleOptions.color,
                    width: options.symbology.styleOptions.width
                })
          }),

everything works fine, but the following styling function _getStyledFeatures inside the ol3Vector-function I would like to use, causes me headache.

Maybe someone has an idea how to get that work.

function ol3Vector(options){

var options = options || {};    

newLayer = new ol.layer.Vector({
              title: options.title,
              visible: false,
              minResolution: options.minResolution,
              maxResolution: options.maxResolution,
              content: options.content,
              symbology: options.symbology,
              style: _getStyledFeatures,             
              source: new ol.source.Vector({
              projection: 'EPSG:4326',
                  attributions: [new ol.Attribution ({html: options.attribution })],
                  strategy: ol.loadingstrategy.bbox,
              loader: function(extent, resolution, projection) {
              var extent = ol.proj.transformExtent(extent, projection.getCode(), ol.proj.get('EPSG:4326').getCode());
              $.ajax({
              type: 'GET',
              url: "./mapdata/get_geojson.php?"+
                  "geotable=" + options.geotable +
                  "&fields=" + options.fields +
                      "&where=" + options.where +
                  "&bbox=" + extent.join(','),
                  context: this
                  }).done (function (data) {
                     var format = new ol.format.GeoJSON();
                     this.addFeatures (format.readFeatures(data,{
                     dataProjection: 'EPSG:4326',
                     featureProjection: 'EPSG:3857'
                     }));
              });
              }
                 })

})


return newLayer;
};

ol.inherits(ol3Vector, ol.layer.Vector);



function _getStyledFeatures(feature) {
        //
        // Create empty styleOptions and feartureStyles objects to add to, or leave as is if no symbology can be found
        //
        var styleOptions = {};
        var featureStyles = {};

        //
        // get properties.
        //
        var atts = feature.getProperties();

        //
        // Is there a symbology set for this layer?
        // if not, style with default style
        var defaultStyle = new ol.style.Style({
                    fill: new ol.style.Fill({color: 'rgba(255,255,255,0.4)'}),
                        stroke: new ol.style.Stroke({
                            color: '#3399CC',
                            width: 1.25
                    })
                });
        if (!options.symbology) {
        return defaultStyle;
        }
        else (options.symbology) {
            switch (options.symbology.type) {
                case "single":
                    //
                    // Its a single symbology for all features so just set the key/value pairs in styleOptions
                    //
                    for (var key in options.symbology.styleOptions) {
                        styleOptions[key] = options.symbology.styleOptions[key];
                        if (styleOptions.title) {
                            for (var prop in atts) {
                                var re = new RegExp("{" + prop + "}", "g");
                                styleOptions.title = styleOptions.title.replace(re, atts[prop]);
                                featureStyles = new ol.style.Style(styleOptions){
                            fill: new ol.style.Fill({color: styleOptions.fill}),
                                stroke: new ol.style.Stroke({
                                color: styleOptions.color,
                                width: styleOptions.width
                            })
                        };
                            }
                        }
                    }
                    break;
                case "unique":
                    //
                    // Its a unique symbology. Check if the features property value matches that in the symbology and style accordingly
                    //
                    var att = options.symbology.property;
                    for (var i = 0, len = options.symbology.values.length; i < len; i++) {
                        if (atts[att] == options.symbology.values[i].value) {
                            for (var key in options.symbology.values[i].styleOptions) {
                                styleOptions[key] = options.symbology.values[i].styleOptions[key];
                                if (styleOptions.title) {
                                    for (var prop in atts) {
                                        var re = new RegExp("{" + prop + "}", "g");
                                        styleOptions.title = styleOptions.title.replace(re, atts[prop]);
                                        featureStyles = new ol.style.Style(styleOptions){
                                fill: new ol.style.Fill({color: styleOptions.fill}),
                                    stroke: new ol.style.Stroke({
                                        color: styleOptions.color,
                                        width: styleOptions.width
                                })
                            };
                                    }
                                }
                            }
                        }
                    }
                    break;
                case "range":
                    //
                    // Its a range symbology. Check if the features property value is in the range set in the symbology and style accordingly
                    //
                    var att = options.symbology.property;
                    for (var i = 0, len = options.symbology.ranges.length; i < len; i++) {
                        if (atts[att] >= options.symbology.ranges[i].range[0] && atts[att] <= options.symbology.ranges[i].range[1]) {
                            for (var key in options.symbology.ranges[i].styleOptions) {
                                styleOptions[key] = options.symbology.ranges[i].styleOptions[key];
                                if (styleOptions.title) {
                                    for (var prop in atts) {
                                        var re = new RegExp("{" + prop + "}", "g");
                                        styleOptions.title = styleOptions.title.replace(re, atts[prop]);
                                        featureStyles = new ol.style.Style(styleOptions){
                                fill: new ol.style.Fill({color: styleOptions.fill}),
                                    stroke: new ol.style.Stroke({
                                        color: styleOptions.color,
                                        width: styleOptions.width
                                })
                            };
                                    }
                                }
                            }
                        }
                    }
                    break;
            }
        }       
        return featureStyles;
} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.