background.init = function()

in modules/renderer/background.js [373:491]


    background.init = function() {
        function parseMap(qmap) {
            if (!qmap) return false;
            var args = qmap.split('/').map(Number);
            if (args.length < 3 || args.some(isNaN)) return false;
            return geoExtent([args[2], args[1]]);
        }

        var q = utilStringQs(window.location.hash.substring(1));
        var requested = q.background || q.layer;
        var extent = parseMap(q.map);
        var first;
        var best;


        data.imagery = data.imagery || [];
        data.imagery.features = {};

        // build efficient index and querying for data.imagery
        var features = data.imagery.map(function(source) {
            if (!source.polygon) return null;

            // Add an extra array nest to each element in `source.polygon`
            // so the rings are not treated as a bunch of holes:
            // what we have: [ [[outer],[hole],[hole]] ]
            // what we want: [ [[outer]],[[outer]],[[outer]] ]
            var rings = source.polygon.map(function(ring) { return [ring]; });

            var feature = {
                type: 'Feature',
                properties: { id: source.id },
                geometry: { type: 'MultiPolygon', coordinates: rings }
            };

            data.imagery.features[source.id] = feature;
            return feature;

        }).filter(Boolean);

        data.imagery.query = whichPolygon({
            type: 'FeatureCollection',
            features: features
        });


        // Add all the available imagery sources
        _backgroundSources = data.imagery.map(function(source) {
            if (source.type === 'bing') {
                return rendererBackgroundSource.Bing(source, dispatch);
            } else if (/^EsriWorldImagery/.test(source.id)) {
                return rendererBackgroundSource.Esri(source);
            } else {
                return rendererBackgroundSource(source);
            }
        });

        first = _backgroundSources.length && _backgroundSources[0];

        // Add 'None'
        _backgroundSources.unshift(rendererBackgroundSource.None());

        // Add 'Custom'
        var template = context.storage('background-custom-template') || '';
        var custom = rendererBackgroundSource.Custom(template);
        _backgroundSources.unshift(custom);


        // Decide which background layer to display
        if (!requested && extent) {
            best = this.sources(extent).find(function(s) { return s.best(); });
        }
        if (requested && requested.indexOf('custom:') === 0) {
            template = requested.replace(/^custom:/, '');
            background.baseLayerSource(custom.template(template));
            context.storage('background-custom-template', template);
        } else {
            background.baseLayerSource(
                background.findSource(requested) ||
                best ||
                background.findSource(context.storage('background-last-used')) ||
                background.findSource('Bing') ||
                first ||
                background.findSource('none')
            );
        }

        var locator = _backgroundSources.find(function(d) {
            return d.overlay && d.default;
        });

        if (locator) {
            background.toggleOverlayLayer(locator);
        }

        var overlays = (q.overlays || '').split(',');
        overlays.forEach(function(overlay) {
            overlay = background.findSource(overlay);
            if (overlay) {
                background.toggleOverlayLayer(overlay);
            }
        });

        if (q.gpx) {
            var gpx = context.layers().layer('data');
            if (gpx) {
                gpx.url(q.gpx, '.gpx');
            }
        }

        if (q.offset) {
            var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
                return !isNaN(n) && n;
            });

            if (offset.length === 2) {
                background.offset(geoMetersToOffset(offset));
            }
        }
    };