CruisersWiki:Ol3chartlet-features-test.js

From CruisersWiki

Revision as of 10:28, 22 December 2016 by Vadim (Talk | contribs)
Jump to: navigation, search
//
/*
   features.js

   Copyright (c) 2016 Vadim Shlyakhov
   Licensed MIT
*/

(function () {

    function parsePage (options) {
        var parents = [];
        
        function out(poi) {
            var feature = new ol.Feature(poi);
            feature.getGeometry().transform('EPSG:4326', options.projection);
            options.addFeature(feature);
        }

        function some (arr) {
            return typeof arr !== 'undefined' && arr.length > 0;
        }
        function first (arr) {
            return some(arr) ? arr[0] : '';
        }
        function join (arr) {
            return some(arr) ? arr.join(' ') : '';
        }
        function join_html (arr) {
            var out = [];
            if (arr) {
                for (var i=0, li=arr.length; i < li; i++) {
                    out.push(arr[i].html);
                }
            }
            return out.join(' ');
        }
        function set (props, poi, sfield, dfield) {
            var val = first(props[sfield])
            if (val) 
                poi[dfield || sfield] = val;
        }
        
        var mf_processors = {
            "h-entry": function (props, poi) {
                set (props, poi, 'url');
                set (props, poi, 'name');
                poi.description = join_html(props.summary);
            },
            "h-item": function (props, poi) {
                set (props, poi, 'url');
                set (props, poi, 'name');
                poi.description = join_html(props.description);
            },
            "h-card": function (props, poi) {
                poi.name || set (props, poi, 'name');
                set (props, poi, 'category');
            },
            "h-geo": function (props, poi) {
                set (props, poi, 'name');
                var lon = parseFloat(first(props.longitude));
                var lat = parseFloat(first(props.latitude));
                if (isNaN(lat + lon))
                    return;
                poi.geometry = new ol.geom.Point([lon, lat]);
            },
            "h-cite": function (props, poi) {
                if ( !(options.recursive > 0))
                    return;
                var copt = $.extend({}, options);
                if (copt.recursive !== true && ! isNaN(copt.recursive * 1)) 
                    copt.recursive--;
                var page = first(props.name);
                if (!page)
                    return;
                copt.page = page.split('#', 1)[0].replace(/_/g, ' ');
                loadPage(copt);
            },
        };

        function process_placemark(item_list) {
            var poi = {};
            for (var i=0, li=item_list.length; i < li; i++) {
                var item = item_list[i];
                var type = first(item.type);
                var props = item.properties;
                var processor = mf_processors[type];
                processor && processor(props, poi);
            }
            poi.name = poi.name && $.trim(poi.name);
            if (!poi.name) 
                return;
            if (poi.geometry) {
                out(poi);
            }
        }
        var mf_subitem_map = {
            "h-entry": 'location',
            "h-item": 'location',
            "h-card": 'geo',
        };
        function process_item_list (item_list, parents) {
            if (!item_list)
                return;
            for (var i=item_list.length-1; i >= 0; i--) {
                var item = item_list[i];
                var type = first(item.type);
                if (type != 'h-entry' && parents.length == 0 && options.childrenlocations && options.recursive == 0)
                    continue;
                var props = item.properties;
                var subitem_id = mf_subitem_map[type];
                if (subitem_id) {
                    process_item_list(item.properties[subitem_id], [item].concat(parents))
                } else {
                    process_placemark([item].concat(parents));
                }
                if (item.children) 
                    process_item_list(item.children, []);
            }
        }

        var parsed = Microformats.get(options.data);
        if (parsed.items && parsed.items.length > 0) {
            // console.log('POIs loaded ' + parsed.items.length);
            process_item_list(parsed.items, []);
        }
        //console.log(kml_out);
    }

    var loadedPages = {};
    
    function loadPage (options) {
        var page = options.page = options.page || wgPageName;
        if (page in loadedPages)
            return;
        loadedPages[page] = true;
        options.url = wikiUri(page)+'&redirect=no';
        if (page != wgPageName) {
            $.get(options.url, function(data, status) {
                if (!data || status != "success")
                    return;
                if (data.indexOf('redirectText') != -1) {
                    var parsed = $.parseHTML(data);
                    var redirect = $(parsed).find('.redirectText a').text();
                    if (redirect) {
                        options.page = redirect;
                        loadPage (options);
                        return;
                    }
                }
                options.data =  {
                    'baseUrl': wgServer,
                    'html': data
                };
                parsePage(options);
            });
        } else {
            parsePage(options);
        }
    }
            
    function loadFeatures (options) {
        loadWikiScript('CruisersWiki:Microformat-shiv.min.js', function () {
            loadPage (options)
        });
    }

    function getArticleLayer (options) {
        var iconData = null;
        var iconsUrl = 'http://www.cruiserswiki.org/index.php?title=CruisersWiki:Chartlet/icons&action=render';

        $.get(iconsUrl, function(data, status) {
            iconData = $.parseHTML(data);
            addFeature();
        });        

        var defferedFeatures = [];
        var addFeature = function (feature) {
            if (!iconData) {
                defferedFeatures.push(feature);
                return;
            }
            if (defferedFeatures) {
                source.addFeatures(defferedFeatures);
                defferedFeatures = null;
            }
            if (feature) {
                source.addFeature(feature);
            }
        };

        var loader = function(extent, resolution, projection) {
            /**
            * @param {ol.Extent} extent Extent.
            * @param {number} resolution Resolution.
            * @param {ol.proj.Projection} projection Projection.
            * @this {ol.source.Vector|ol.VectorTile}
            */
            options.projection = projection;
            options.addFeature = addFeature;
            loadFeatures(options);
        };

        var iconStyles = {};
        function getIconStyle(category) {
            var style = iconStyles[category];
            if (!style) {
                var icon = $(iconData).find('#' + category + ' img');
                if (icon.length == 0)
                    icon = $(iconData).find('#other img');
                var styleOptions = {
                    src: icon.attr('src')
                };
                /*
                var height = parseFloat(icon.attr('height'));
                var width = parseFloat(icon.attr('width'));
                if (!(isNaN(height) || isNaN(width))) 
                    styleOptions.imgSize = [100,100]; //[width, height];
                */
                //styleOptions.imgSize = [40,40];
                style = new ol.style.Icon(styleOptions);
                iconStyles[category] = style;
            }
            return style;
        }

        var textStyles = {};
        var textStyleOptions = {
            font: 'bold 16px sans-serif',
            textAlign: 'center',
            offsetY: 18,
            fill: new ol.style.Fill({
                color: [128, 0, 128, 1]
            }),
            stroke: new ol.style.Stroke({
                color: [255, 255, 224, 0.5],
                //color: [255, 255, 255, 0.5],
                width: 4
            })
        };        
        function getTextStyle(text) {
            textStyleOptions.text = text;
            var style = new ol.style.Text(textStyleOptions);
            return style;
        }

        var styleFunction = function (feature, resolution) {
            var geom = feature.getGeometry();
            if (geom.getType() == 'Point') {            
                var category = feature.get('category') || 'other';
                var styleOptions = {
                    //zIndex: 2
                };
                options.icons && (styleOptions.image = getIconStyle(category));
                options.captions && (styleOptions.text = getTextStyle(feature.get('name')));
                var style = new ol.style.Style(styleOptions);
                return style;
            }
        };

        var source = new ol.source.Vector({
            loader: loader,
        });
        
        var layer = new ol.layer.Vector({
            title: 'POI',
            visible: true,
            style: styleFunction,
            source: source,
        });
        
        return layer;
    };

    window.getArticleLayer = getArticleLayer;
})();
// 
Personal tools
advertisement
Friends of Cruisers Wiki