function map()

in modules/renderer/map.js [90:220]


    function map(selection) {
        _selection = selection;

        context
            .on('change.map', immediateRedraw);

        var osm = context.connection();
        if (osm) {
            osm.on('change.map', immediateRedraw);
        }

        function didUndoOrRedo(targetTransform) {
            var mode = context.mode().id;
            if (mode !== 'browse' && mode !== 'select') return;
            if (targetTransform) {
                map.transformEase(targetTransform);
            }
        }

        context.history()
            .on('merge.map', function() { scheduleRedraw(); })
            .on('change.map', immediateRedraw)
            .on('undone.map', function(stack, fromStack) {
                didUndoOrRedo(fromStack.transform);
            })
            .on('redone.map', function(stack) {
                didUndoOrRedo(stack.transform);
            });

        context.background()
            .on('change.map', immediateRedraw);

        context.features()
            .on('redraw.map', immediateRedraw);

        drawLayers
            .on('change.map', function() {
                context.background().updateImagery();
                immediateRedraw();
            });

        selection
            .on('dblclick.map', dblClick)
            .call(zoom)
            .call(zoom.transform, projection.transform());

        supersurface = selection.append('div')
            .attr('id', 'supersurface')
            .call(utilSetTransform, 0, 0);

        // Need a wrapper div because Opera can't cope with an absolutely positioned
        // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
        wrapper = supersurface
            .append('div')
            .attr('class', 'layer layer-data');

        map.surface = surface = wrapper
            .call(drawLayers)
            .selectAll('.surface')
            .attr('id', 'surface');

        surface
            .call(drawLabels.observe)
            .on('gesturestart.surface', function() {
                _gestureTransformStart = projection.transform();
            })
            .on('gesturechange.surface', gestureChange)
            .on('mousedown.zoom', function() {
                if (d3_event.button === 2) {
                    d3_event.stopPropagation();
                }
            }, true)
            .on('mouseup.zoom', function() {
                if (resetTransform()) {
                    immediateRedraw();
                }
            })
            .on('mousemove.map', function() {
                _mouseEvent = d3_event;
            })
            .on('mouseover.vertices', function() {
                if (map.editableDataEnabled() && !_isTransformed) {
                    var hover = d3_event.target.__data__;
                    surface.call(drawVertices.drawHover, context.graph(), hover, map.extent());
                    dispatch.call('drawn', this, { full: false });
                }
            })
            .on('mouseout.vertices', function() {
                if (map.editableDataEnabled() && !_isTransformed) {
                    var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
                    surface.call(drawVertices.drawHover, context.graph(), hover, map.extent());
                    dispatch.call('drawn', this, { full: false });
                }
            });

        context.on('enter.map',  function() {
            if (map.editableDataEnabled(true /* skip zoom check */) && !_isTransformed) {
                // redraw immediately any objects affected by a change in selectedIDs.
                var graph = context.graph();
                var selectedAndParents = {};
                context.selectedIDs().forEach(function(id) {
                    var entity = graph.hasEntity(id);
                    if (entity) {
                        selectedAndParents[entity.id] = entity;
                        if (entity.type === 'node') {
                            graph.parentWays(entity).forEach(function(parent) {
                                selectedAndParents[parent.id] = parent;
                            });
                        }
                    }
                });
                var data = Object.values(selectedAndParents);
                var filter = function(d) { return d.id in selectedAndParents; };

                data = context.features().filter(data, graph);

                surface
                    .call(drawVertices.drawSelected, graph, map.extent())
                    .call(drawLines, graph, data, filter)
                    .call(drawAreas, graph, data, filter)
                    .call(drawMidpoints, graph, data, filter, map.trimmedExtent());

                dispatch.call('drawn', this, { full: false });

                // redraw everything else later
                scheduleRedraw();
            }
        });

        map.dimensions(utilGetDimensions(selection));
    }