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;
} 

0

Your Answer

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

Browse other questions tagged or ask your own question.