Ejemplo n.º 1
0
export async function loadUnits() {
  const {client: {drive}} = await loadAndConfigureGapi();

  const files = await loadAllPages(
    pageToken => drive.files.list({
      pageToken,
      q: `'${escapeQuotes(MASTER_CURRICULUM_FOLDER_ID)}' in parents`,
    }),
    property('files'),
  );

  return map(
    sortBy(
      filter(
        map(
          files,
          file => ({file, sequence: getUnitSequence(file.name)}),
        ),
        'sequence'
      ),
      'sequence',
    ),
    'file'
  );
}
Ejemplo n.º 2
0
 return _uniq(_reduce(ids, function(result, id) {
     var entity = graph.entity(id);
     if (entity.type === 'way') {
         try {
             var children = graph.childNodes(entity);
             result.push.apply(result, _map(_filter(children, 'version'), 'id'));
         } catch (err) {
             /* eslint-disable no-console */
             if (typeof console !== 'undefined') console.error(err);
             /* eslint-enable no-console */
         }
     }
     return result;
 }, _clone(ids)));
Ejemplo n.º 3
0
Archivo: history.js Proyecto: 1ec5/iD
    function redraw(selection) {
        var selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
            singular = selected.length === 1 ? selected[0] : null;

        osm = context.connection();

        selection.html('');

        selection
            .append('h4')
            .attr('class', 'history-heading')
            .text(singular || t('info_panels.history.selected', { n: selected.length }));

        if (!singular) return;

        var entity = context.entity(singular);

        var list = selection
            .append('ul');

        list
            .append('li')
            .text(t('info_panels.history.version') + ': ' + entity.version);

        list
            .append('li')
            .text(t('info_panels.history.last_edit') + ': ' + displayTimestamp(entity));

        list
            .append('li')
            .text(t('info_panels.history.edited_by') + ': ')
            .call(displayUser, entity);

        list
            .append('li')
            .text(t('info_panels.history.changeset') + ': ')
            .call(displayChangeset, entity);

        if (osm) {
            selection
                .append('a')
                .attr('class', 'view-history-on-osm')
                .attr('target', '_blank')
                .attr('tabindex', -1)
                .attr('href', osm.historyURL(entity))
                .call(svgIcon('#icon-out-link', 'inline'))
                .append('span')
                .text(t('info_panels.history.link_text'));
        }
    }
Ejemplo n.º 4
0
    function relations(q) {
        var newRelation = {
                relation: null,
                value: t('inspector.new_relation')
            },
            result = [],
            graph = context.graph();

        context.intersects(context.extent()).forEach(function(entity) {
            if (entity.type !== 'relation' || entity.id === id)
                return;

            var matched = context.presets().match(entity, graph),
                presetName = (matched && matched.name()) || t('inspector.relation'),
                entityName = utilDisplayName(entity) || '';

            var value = presetName + ' ' + entityName;
            if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
                return;

            result.push({
                relation: entity,
                value: value
            });
        });

        result.sort(function(a, b) {
            return osmRelation.creationOrder(a.relation, b.relation);
        });

        // Dedupe identical names by appending relation id - see #2891
        var dupeGroups = _filter(
            _groupBy(result, 'value'),
            function(v) { return v.length > 1; }
        );

        dupeGroups.forEach(function(group) {
            group.forEach(function(obj) {
                obj.value += ' ' + obj.relation.id;
            });
        });

        result.unshift(newRelation);
        return result;
    }
Ejemplo n.º 5
0
function loadTiles(which, url, projection) {
    var s = projection.scale() * 2 * Math.PI,
        currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));

    var tiles = getTiles(projection).filter(function(t) {
            return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
        });

    _filter(which.inflight, function(v, k) {
        var wanted = _find(tiles, function(tile) { return k === (tile.id + ',0'); });
        if (!wanted) delete which.inflight[k];
        return !wanted;
    }).map(abortRequest);

    tiles.forEach(function(tile) {
        loadNextTilePage(which, currZoom, url, tile);
    });
}
Ejemplo n.º 6
0
Archivo: combo.js Proyecto: slhh/iD
        taginfo[fn](params, function(err, data) {
            if (err) return;
            if (hasCountryPrefix) {
                data = _filter(data, function(d) {
                    return d.value.toLowerCase().indexOf(_country + ':') === 0;
                });
            }

            _comboData = _map(data, function(d) {
                var k = d.value;
                if (isMulti) k = k.replace(field.key, '');
                var v = snake_case ? unsnake(k) : k;
                return {
                    key: k,
                    value: v,
                    title: isMulti ? v : d.title
                };
            });

            _comboData = objectDifference(_comboData, _multiData);
            if (callback) callback(_comboData);
        });
Ejemplo n.º 7
0
Archivo: lines.js Proyecto: Stalfur/iD
 _forOwn(pathdata, function(v, k) {
     var arr = _filter(v, function(d) { return d.isOneWay(); });
     onewaydata[k] = _flatten(_map(arr, svgOneWaySegments(projection, graph, 35)));
 });
Ejemplo n.º 8
0
    function redraw(selection) {
        var resolver = context.graph(),
            selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
            singular = selected.length === 1 ? selected[0] : null,
            extent = geoExtent(),
            entity;

        selection.html('');

        selection
            .append('h4')
            .attr('class', 'measurement-heading')
            .text(singular || t('info_panels.measurement.selected', { n: selected.length }));

        if (!selected.length) return;

        var center;
        for (var i = 0; i < selected.length; i++) {
            entity = context.entity(selected[i]);
            extent._extend(entity.extent(resolver));
        }
        center = extent.center();


        var list = selection
            .append('ul');

        // multiple features, just display extent center..
        if (!singular) {
            list
                .append('li')
                .text(t('info_panels.measurement.center') + ': ' +
                    center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
                );
            return;
        }

        // single feature, display details..
        if (!entity) return;
        var geometry = entity.geometry(resolver);

        if (geometry === 'line' || geometry === 'area') {
            var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
                feature = entity.asGeoJSON(resolver),
                length = radiansToMeters(d3_geoLength(toLineString(feature))),
                lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
                centroid = d3_geoCentroid(feature);

            list
                .append('li')
                .text(t('info_panels.measurement.geometry') + ': ' +
                    (closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry) );

            if (closed) {
                var area = steradiansToSqmeters(entity.area(resolver));
                list
                    .append('li')
                    .text(t('info_panels.measurement.area') + ': ' + displayArea(area));
            }

            list
                .append('li')
                .text(lengthLabel + ': ' + displayLength(length));

            list
                .append('li')
                .text(t('info_panels.measurement.centroid') + ': ' +
                    centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION)
                );


            var toggle  = isImperial ? 'imperial' : 'metric';

            selection
                .append('a')
                .text(t('info_panels.measurement.' + toggle))
                .attr('href', '#')
                .attr('class', 'button button-toggle-units')
                .on('click', function() {
                    d3_event.preventDefault();
                    isImperial = !isImperial;
                    selection.call(redraw);
                });

        } else {
            var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));

            list
                .append('li')
                .text(t('info_panels.measurement.geometry') + ': ' + t('geometry.' + geometry));

            list
                .append('li')
                .text(centerLabel + ': ' +
                    center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
                );
        }
    }
Ejemplo n.º 9
0
        search: function(value, geometry) {
            if (!value) return this;

            function leading(a) {
                var index = a.indexOf(value);
                return index === 0 || a[index - 1] === ' ';
            }

            function suggestionName(name) {
                var nameArray = name.split(' - ');
                if (nameArray.length > 1) {
                    name = nameArray.slice(0, nameArray.length - 1).join(' - ');
                }
                return name.toLowerCase();
            }


            value = value.toLowerCase();

            var searchable = _filter(this.collection, function(a) {
                    return a.searchable !== false && a.suggestion !== true;
                }),
                suggestions = _filter(this.collection, function(a) {
                    return a.suggestion === true;
                });


            // matches value to preset.name
            var leading_name = _filter(searchable, function(a) {
                    return leading(a.name().toLowerCase());
                }).sort(function(a, b) {
                    var aCompare = a.name().toLowerCase(),
                        bCompare = b.name().toLowerCase(),
                        i;

                    // priority if search string matches preset name exactly - #4325
                    if (value === aCompare) return -1;
                    if (value === bCompare) return 1;

                    // priority for higher matchScore
                    i = b.originalScore - a.originalScore;
                    if (i !== 0) return i;

                    // priority if search string appears earlier in preset name
                    i = aCompare.indexOf(value) - bCompare.indexOf(value);
                    if (i !== 0) return i;

                    // priority for shorter preset names
                    return a.name().length - b.name().length;
                });

            // matches value to preset.terms values
            var leading_terms = _filter(searchable, function(a) {
                    return _some(a.terms() || [], leading);
                });

            // matches value to preset.tags values
            var leading_tag_values = _filter(searchable, function(a) {
                    return _some(_without(_values(a.tags || {}), '*'), leading);
                });


            // finds close matches to value in preset.name
            var similar_name = searchable.map(function(a) {
                    return {
                        preset: a,
                        dist: utilEditDistance(value, a.name())
                    };
                }).filter(function(a) {
                    return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
                }).sort(function(a, b) {
                    return a.dist - b.dist;
                }).map(function(a) {
                    return a.preset;
                });

            // finds close matches to value in preset.terms
            var similar_terms = _filter(searchable, function(a) {
                    return _some(a.terms() || [], function(b) {
                        return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
                    });
                });

            var leading_suggestions = _filter(suggestions, function(a) {
                    return leading(suggestionName(a.name()));
                }).sort(function(a, b) {
                    a = suggestionName(a.name());
                    b = suggestionName(b.name());
                    var i = a.indexOf(value) - b.indexOf(value);
                    if (i === 0) return a.length - b.length;
                    else return i;
                });

            var similar_suggestions = suggestions.map(function(a) {
                    return {
                        preset: a,
                        dist: utilEditDistance(value, suggestionName(a.name()))
                    };
                }).filter(function(a) {
                    return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
                }).sort(function(a, b) {
                    return a.dist - b.dist;
                }).map(function(a) {
                    return a.preset;
                });

            var other = presets.item(geometry);

            var results = leading_name.concat(
                    leading_terms,
                    leading_tag_values,
                    leading_suggestions.slice(0, maxSuggestionResults + 5),
                    similar_name,
                    similar_terms,
                    similar_suggestions.slice(0, maxSuggestionResults)
                ).slice(0, maxSearchResults - 1);

            return presetCollection(_uniq(results.concat(other)));
        }
Ejemplo n.º 10
0
        fromJSON: function(json, loadChildNodes) {
            var h = JSON.parse(json);
            var loadComplete = true;

            osmEntity.id.next = h.nextIDs;
            _index = h.index;

            if (h.version === 2 || h.version === 3) {
                var allEntities = {};

                h.entities.forEach(function(entity) {
                    allEntities[osmEntity.key(entity)] = osmEntity(entity);
                });

                if (h.version === 3) {
                    // This merges originals for changed entities into the base of
                    // the _stack even if the current _stack doesn't have them (for
                    // example when iD has been restarted in a different region)
                    var baseEntities = h.baseEntities.map(function(d) { return osmEntity(d); });
                    _stack[0].graph.rebase(baseEntities, _map(_stack, 'graph'), true);
                    _tree.rebase(baseEntities, true);

                    // When we restore a modified way, we also need to fetch any missing
                    // childnodes that would normally have been downloaded with it.. #2142
                    if (loadChildNodes) {
                        var osm = context.connection();
                        var nodes = _flatten(_uniq(_map(_filter(baseEntities, { type: 'way' }), 'nodes')));
                        var missing = _reject(nodes, function(n) { return _stack[0].graph.hasEntity(n); });

                        if (!_isEmpty(missing) && osm) {
                            loadComplete = false;
                            context.redrawEnable(false);

                            var loading = uiLoading(context).blocking(true);
                            context.container().call(loading);

                            var childNodesLoaded = function(err, result) {
                                if (!err) {
                                    var visible = _groupBy(result.data, 'visible');
                                    if (!_isEmpty(visible.true)) {
                                        missing = _difference(missing, _map(visible.true, 'id'));
                                        _stack[0].graph.rebase(visible.true, _map(_stack, 'graph'), true);
                                        _tree.rebase(visible.true, true);
                                    }

                                    // fetch older versions of nodes that were deleted..
                                    _forEach(visible.false, function(entity) {
                                        osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
                                    });
                                }

                                if (err || _isEmpty(missing)) {
                                    loading.close();
                                    context.redrawEnable(true);
                                    dispatch.call('change');
                                    dispatch.call('restore', this);
                                }
                            };

                            osm.loadMultiple(missing, childNodesLoaded);
                        }
                    }
                }

                _stack = h.stack.map(function(d) {
                    var entities = {}, entity;

                    if (d.modified) {
                        d.modified.forEach(function(key) {
                            entity = allEntities[key];
                            entities[entity.id] = entity;
                        });
                    }

                    if (d.deleted) {
                        d.deleted.forEach(function(id) {
                            entities[id] = undefined;
                        });
                    }

                    return {
                        graph: coreGraph(_stack[0].graph).load(entities),
                        annotation: d.annotation,
                        imageryUsed: d.imageryUsed,
                        transform: d.transform,
                        selectedIDs: d.selectedIDs
                    };
                });

            } else { // original version
                _stack = h.stack.map(function(d) {
                    var entities = {};

                    for (var i in d.entities) {
                        var entity = d.entities[i];
                        entities[i] = entity === 'undefined' ? undefined : osmEntity(entity);
                    }

                    d.graph = coreGraph(_stack[0].graph).load(entities);
                    return d;
                });
            }

            var transform = _stack[_index].transform;
            if (transform) {
                context.map().transformEase(transform, 0);   // 0 = immediate, no easing
            }

            if (loadComplete) {
                dispatch.call('change');
                dispatch.call('restore', this);
            }

            return history;
        },
Ejemplo n.º 11
0
Archivo: move.js Proyecto: Stalfur/iD
    function setupCache(graph) {
        function canMove(nodeId) {
            // Allow movement of any node that is in the selectedIDs list..
            if (moveIds.indexOf(nodeId) !== -1) return true;

            // Allow movement of a vertex where 2 ways meet..
            var parents = _map(graph.parentWays(graph.entity(nodeId)), 'id');
            if (parents.length < 3) return true;

            // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
            var parentsMoving = _every(parents, function(id) { return cache.moving[id]; });
            if (!parentsMoving) delete cache.moving[nodeId];

            return parentsMoving;
        }

        function cacheEntities(ids) {
            for (var i = 0; i < ids.length; i++) {
                var id = ids[i];
                if (cache.moving[id]) continue;
                cache.moving[id] = true;

                var entity = graph.hasEntity(id);
                if (!entity) continue;

                if (entity.type === 'node') {
                    cache.nodes.push(id);
                    cache.startLoc[id] = entity.loc;
                } else if (entity.type === 'way') {
                    cache.ways.push(id);
                    cacheEntities(entity.nodes);
                } else {
                    cacheEntities(entity.members.map(function(member) {
                        return member.id;
                    }));
                }
            }
        }

        function cacheIntersections(ids) {
            function isEndpoint(way, id) {
                return !way.isClosed() && !!way.affix(id);
            }

            for (var i = 0; i < ids.length; i++) {
                var id = ids[i];

                // consider only intersections with 1 moved and 1 unmoved way.
                var childNodes = graph.childNodes(graph.entity(id));
                for (var j = 0; j < childNodes.length; j++) {
                    var node = childNodes[j];
                    var parents = graph.parentWays(node);
                    if (parents.length !== 2) continue;

                    var moved = graph.entity(id);
                    var unmoved = null;
                    for (var k = 0; k < parents.length; k++) {
                        var way = parents[k];
                        if (!cache.moving[way.id]) {
                            unmoved = way;
                            break;
                        }
                    }
                    if (!unmoved) continue;

                    // exclude ways that are overly connected..
                    if (_intersection(moved.nodes, unmoved.nodes).length > 2) continue;
                    if (moved.isArea() || unmoved.isArea()) continue;

                    cache.intersections.push({
                        nodeId: node.id,
                        movedId: moved.id,
                        unmovedId: unmoved.id,
                        movedIsEP: isEndpoint(moved, node.id),
                        unmovedIsEP: isEndpoint(unmoved, node.id)
                    });
                }
            }
        }


        if (!cache) {
            cache = {};
        }
        if (!cache.ok) {
            cache.moving = {};
            cache.intersections = [];
            cache.replacedVertex = {};
            cache.startLoc = {};
            cache.nodes = [];
            cache.ways = [];

            cacheEntities(moveIds);
            cacheIntersections(cache.ways);
            cache.nodes = _filter(cache.nodes, canMove);

            cache.ok = true;
        }
    }
Ejemplo n.º 12
0
    function save(changeset, tryAgain, checkConflicts) {
        // Guard against accidentally entering save code twice - #4641
        if (_isSaving && !tryAgain) {
            return;
        }

        var osm = context.connection();
        if (!osm) {
            cancel();
            return;
        }

        // If user somehow got logged out mid-save, try to reauthenticate..
        // This can happen if they were logged in from before, but the tokens are no longer valid.
        if (!osm.authenticated()) {
            osm.authenticate(function(err) {
                if (err) {
                    cancel();   // quit save mode..
                } else {
                    save(changeset, tryAgain, checkConflicts);  // continue where we left off..
                }
            });
            return;
        }

        if (!_isSaving) {
            keybindingOff();
            context.container().call(loading);  // block input
            _isSaving = true;
        }

        var history = context.history();
        var localGraph = context.graph();
        var remoteGraph = coreGraph(history.base(), true);

        _conflicts = [];
        _errors = [];

        // Store original changes, in case user wants to download them as an .osc file
        _origChanges = history.changes(actionDiscardTags(history.difference()));

        // First time, `history.perform` a no-op action.
        // Any conflict resolutions will be done as `history.replace`
        if (!tryAgain) {
            history.perform(actionNoop());
        }

        // Attempt a fast upload.. If there are conflicts, re-enter with `checkConflicts = true`
        if (!checkConflicts) {
            upload(changeset);

        // Do the full (slow) conflict check..
        } else {
            var modified = _filter(history.difference().summary(), { changeType: 'modified' });
            _toCheck = _map(_map(modified, 'entity'), 'id');
            _toLoad = withChildNodes(_toCheck, localGraph);
            _loaded = {};
            _toLoadCount = 0;
            _toLoadTotal = _toLoad.length;

            if (_toCheck.length) {
                showProgress(_toLoadCount, _toLoadTotal);
                _toLoad.forEach(function(id) { _loaded[id] = false; });
                osm.loadMultiple(_toLoad, loaded);
            } else {
                upload(changeset);
            }
        }

        return;


        function withChildNodes(ids, graph) {
            return _uniq(_reduce(ids, function(result, id) {
                var entity = graph.entity(id);
                if (entity.type === 'way') {
                    try {
                        var children = graph.childNodes(entity);
                        result.push.apply(result, _map(_filter(children, 'version'), 'id'));
                    } catch (err) {
                        /* eslint-disable no-console */
                        if (typeof console !== 'undefined') console.error(err);
                        /* eslint-enable no-console */
                    }
                }
                return result;
            }, _clone(ids)));
        }


        // Reload modified entities into an alternate graph and check for conflicts..
        function loaded(err, result) {
            if (_errors.length) return;

            if (err) {
                _errors.push({
                    msg: err.message || err.responseText,
                    details: [ t('save.status_code', { code: err.status }) ]
                });
                showErrors();

            } else {
                var loadMore = [];

                result.data.forEach(function(entity) {
                    remoteGraph.replace(entity);
                    _loaded[entity.id] = true;
                    _toLoad = _without(_toLoad, entity.id);

                    if (!entity.visible) return;

                    // Because loadMultiple doesn't download /full like loadEntity,
                    // need to also load children that aren't already being checked..
                    var i, id;
                    if (entity.type === 'way') {
                        for (i = 0; i < entity.nodes.length; i++) {
                            id = entity.nodes[i];
                            if (_loaded[id] === undefined) {
                                _loaded[id] = false;
                                loadMore.push(id);
                            }
                        }
                    } else if (entity.type === 'relation' && entity.isMultipolygon()) {
                        for (i = 0; i < entity.members.length; i++) {
                            id = entity.members[i].id;
                            if (_loaded[id] === undefined) {
                                _loaded[id] = false;
                                loadMore.push(id);
                            }
                        }
                    }
                });

                _toLoadCount += result.data.length;
                _toLoadTotal += loadMore.length;
                showProgress(_toLoadCount, _toLoadTotal);

                if (loadMore.length) {
                    _toLoad.push.apply(_toLoad, loadMore);
                    osm.loadMultiple(loadMore, loaded);
                }

                if (!_toLoad.length) {
                    detectConflicts();
                }
            }
        }


        function detectConflicts() {
            function choice(id, text, action) {
                return { id: id, text: text, action: function() { history.replace(action); } };
            }
            function formatUser(d) {
                return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
            }
            function entityName(entity) {
                return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
            }

            function sameVersions(local, remote) {
                if (local.version !== remote.version) return false;

                if (local.type === 'way') {
                    var children = _union(local.nodes, remote.nodes);
                    for (var i = 0; i < children.length; i++) {
                        var a = localGraph.hasEntity(children[i]);
                        var b = remoteGraph.hasEntity(children[i]);
                        if (a && b && a.version !== b.version) return false;
                    }
                }

                return true;
            }

            _toCheck.forEach(function(id) {
                var local = localGraph.entity(id);
                var remote = remoteGraph.entity(id);

                if (sameVersions(local, remote)) return;

                var action = actionMergeRemoteChanges;
                var merge = action(id, localGraph, remoteGraph, formatUser);

                history.replace(merge);

                var mergeConflicts = merge.conflicts();
                if (!mergeConflicts.length) return;  // merged safely

                var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local');
                var forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote');
                var keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore'));
                var keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));

                _conflicts.push({
                    id: id,
                    name: entityName(local),
                    details: mergeConflicts,
                    chosen: 1,
                    choices: [
                        choice(id, keepMine, forceLocal),
                        choice(id, keepTheirs, forceRemote)
                    ]
                });
            });

            upload(changeset);
        }
    }
Ejemplo n.º 13
0
    function redraw(selection) {
        var resolver = context.graph();
        var selectedNoteID = context.selectedNoteID();
        var osm = services.osm;

        var selected, center, entity, note, geometry;

        if (selectedNoteID && osm) {       // selected 1 note
            selected = [ t('note.note') + ' ' + selectedNoteID ];
            note = osm.getNote(selectedNoteID);
            center = note.loc;
            geometry = 'note';

        } else {                           // selected 1..n entities
            var extent = geoExtent();
            selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); });
            if (selected.length) {
                for (var i = 0; i < selected.length; i++) {
                    entity = context.entity(selected[i]);
                    extent._extend(entity.extent(resolver));
                }
                center = extent.center();
                geometry = entity.geometry(resolver);
            }
        }

        var singular = selected.length === 1 ? selected[0] : null;

        selection.html('');

        selection
            .append('h4')
            .attr('class', 'measurement-heading')
            .text(singular || t('info_panels.measurement.selected', { n: selected.length.toLocaleString(locale) }));

        if (!selected.length) return;


        var list = selection
            .append('ul');
        var coordItem;

        // multiple selected features, just display extent center..
        if (!singular) {
            coordItem = list
                .append('li')
                .text(t('info_panels.measurement.center') + ':');
            coordItem.append('span')
                .text(dmsCoordinatePair(center));
            coordItem.append('span')
                .text(decimalCoordinatePair(center));
            return;
        }

        // single selected feature, display details..
        if (geometry === 'line' || geometry === 'area') {
            var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate());
            var feature = entity.asGeoJSON(resolver);
            var length = radiansToMeters(d3_geoLength(toLineString(feature)));
            var lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length'));
            var centroid = d3_geoCentroid(feature);

            list
                .append('li')
                .text(t('info_panels.measurement.geometry') + ':')
                .append('span')
                .text(
                    closed ? t('info_panels.measurement.closed_' + geometry) : t('geometry.' + geometry)
                );

            if (entity.type !== 'relation') {
                list
                    .append('li')
                    .text(t('info_panels.measurement.node_count') + ':')
                    .append('span')
                    .text(nodeCount(feature).toLocaleString(locale));
            }

            if (closed) {
                var area = steradiansToSqmeters(entity.area(resolver));
                list
                    .append('li')
                    .text(t('info_panels.measurement.area') + ':')
                    .append('span')
                    .text(displayArea(area, isImperial));
            }


            list
                .append('li')
                .text(lengthLabel + ':')
                .append('span')
                .text(displayLength(length, isImperial));

            coordItem = list
                .append('li')
                .text(t('info_panels.measurement.centroid') + ':');
            coordItem.append('span')
                .text(dmsCoordinatePair(centroid));
            coordItem.append('span')
                .text(decimalCoordinatePair(centroid));

            var toggle  = isImperial ? 'imperial' : 'metric';

            selection
                .append('a')
                .text(t('info_panels.measurement.' + toggle))
                .attr('href', '#')
                .attr('class', 'button button-toggle-units')
                .on('click', function() {
                    d3_event.preventDefault();
                    isImperial = !isImperial;
                    selection.call(redraw);
                });

        } else {
            var centerLabel = t('info_panels.measurement.' +
                (note || entity.type === 'node' ? 'location' : 'center'));

            list
                .append('li')
                .text(t('info_panels.measurement.geometry') + ':')
                .append('span')
                .text(t('geometry.' + geometry));

            coordItem = list
                .append('li')
                .text(centerLabel + ':');
            coordItem.append('span')
                .text(dmsCoordinatePair(center));
            coordItem.append('span')
                .text(decimalCoordinatePair(center));
        }
    }
Ejemplo n.º 14
0
Archivo: osm.js Proyecto: grischard/iD
    loadTiles: function(projection, dimensions, callback) {
        if (off) return;

        var that = this,
            s = projection.scale() * 2 * Math.PI,
            z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
            ts = 256 * Math.pow(2, z - tileZoom),
            origin = [
                s / 2 - projection.translate()[0],
                s / 2 - projection.translate()[1]
            ];

        var tiles = d3_geoTile()
            .scaleExtent([tileZoom, tileZoom])
            .scale(s)
            .size(dimensions)
            .translate(projection.translate())()
            .map(function(tile) {
                var x = tile[0] * ts - origin[0],
                    y = tile[1] * ts - origin[1];

                return {
                    id: tile.toString(),
                    extent: geoExtent(
                        projection.invert([x, y + ts]),
                        projection.invert([x + ts, y]))
                };
            });

        _filter(inflight, function(v, i) {
            var wanted = _find(tiles, function(tile) {
                return i === tile.id;
            });
            if (!wanted) delete inflight[i];
            return !wanted;
        }).map(abortRequest);

        tiles.forEach(function(tile) {
            var id = tile.id;

            if (loadedTiles[id] || inflight[id]) return;

            if (_isEmpty(inflight)) {
                dispatch.call('loading');
            }

            inflight[id] = that.loadFromAPI(
                '/api/0.6/map?bbox=' + tile.extent.toParam(),
                function(err, parsed) {
                    delete inflight[id];
                    if (!err) {
                        loadedTiles[id] = true;
                    }

                    if (callback) {
                        callback(err, _extend({ data: parsed }, tile));
                    }

                    if (_isEmpty(inflight)) {
                        dispatch.call('loaded');
                    }
                }
            );
        });
    },
Ejemplo n.º 15
0
export function coreValidator(context) {
    var dispatch = d3_dispatch('reload');
    var self = {};
    var _issues = [];
    var _issuesByEntityID = {};

    var _disabledValidations = {};

    var validations = _filter(Validations, _isFunction).reduce(function(obj, validation) {
        var func = validation();
        obj[func.type] = func;
        return obj;
    }, {});

    var entityValidationIDs = [];
    var changesValidationIDs = [];

    for (var key in validations) {
        var validation = validations[key];
        if (validation.inputType && validation.inputType === 'changes') {
            changesValidationIDs.push(key);
        } else {
            entityValidationIDs.push(key);
        }
    }

    var validationIDsToDisplay = Object.keys(validations).filter(function(rule) {
        return rule !== 'maprules';
    });
    validationIDsToDisplay.sort(function(rule1, rule2) {
        return t('issues.' + rule1 + '.title') > t('issues.' + rule2 + '.title');
    });

    //self.featureApplicabilityOptions = ['edited', 'all'];

    /*var featureApplicability = context.storage('issue-features') || 'edited';

    self.getFeatureApplicability = function() {
        return featureApplicability;
    };

    self.setFeatureApplicability = function(applicability) {
        featureApplicability = applicability;
        context.storage('issue-features', applicability);
    };*/

    self.getIssues = function() {
        return _issues;
    };

    self.getWarnings = function() {
        return _issues.filter(function(d) { return d.severity === 'warning'; });
    };

    self.getErrors = function() {
        return _issues.filter(function(d) { return d.severity === 'error'; });
    };

    self.getIssuesForEntityWithID = function(entityID) {
        if (!context.hasEntity(entityID)) return [];
        var entity = context.entity(entityID);
        var key = osmEntity.key(entity);

        if (!_issuesByEntityID[key]) {
            _issuesByEntityID[key] = validateEntity(entity);
        }
        return _issuesByEntityID[key];
    };

    self.getRuleIDs = function(){
        return validationIDsToDisplay;
    };

    self.getDisabledRules = function(){
        return _disabledValidations;
    };

    self.toggleRule = function(ruleID) {
        if (_disabledValidations[ruleID]) {
            delete _disabledValidations[ruleID];
        } else {
            _disabledValidations[ruleID] = true;
        }
        self.validate();
    };

    function validateEntity(entity) {
        var _issues = [];
        var ran = {};

        // runs validation and appends resulting issues, returning true if validation passed
        function runValidation(which) {
            if (ran[which]) return true;

            if (_disabledValidations[which]) {
                // don't run disabled validations but mark as having run
                ran[which] = true;
                return true;
            }

            var fn = validations[which];
            var typeIssues = fn(entity, context);
            _issues = _issues.concat(typeIssues);
            ran[which] = true;   // mark this validation as having run
            return !typeIssues.length;
        }

        runValidation('missing_role');
        
        if (entity.type === 'relation') {
            if (!runValidation('old_multipolygon')) {
                // don't flag missing tags if they are on the outer way
                ran.missing_tag = true;
            }
        }

        // other validations require feature to be tagged
        if (!runValidation('missing_tag')) return _issues;

        if (entity.type === 'way') {
            runValidation('crossing_ways');

            // only check for disconnected way if no almost junctions
            if (runValidation('almost_junction')) {
                runValidation('disconnected_way');
            } else {
                ran.disconnected_way = true;
            }

            runValidation('tag_suggests_area');
        }

        // run all validations not yet run manually
        entityValidationIDs.forEach(runValidation);

        return _issues;
    }


    self.validate = function() {
        _issuesByEntityID = {};   // clear cached
        _issues = [];

        for (var validationIndex in validations) {
            if (validations[validationIndex].reset) {
                validations[validationIndex].reset();
            }
        }

        var history = context.history();
        var changes = history.changes();
        var entitiesToCheck = changes.created.concat(changes.modified);
        var graph = history.graph();

        _issues = _flatten(changesValidationIDs.map(function(ruleID) {
            if (_disabledValidations[ruleID]) {
                return [];
            }
            var validation = validations[ruleID];
            return validation(changes, context);
        }));

        entitiesToCheck = _uniq(_flattenDeep(entitiesToCheck.map(function(entity) {
            var entities = [entity];
            if (entity.type === 'node') {  // validate ways if their nodes have changed
                entities = entities.concat(graph.parentWays(entity));
            }
            entities = entities.map(function(entity) {
                if (entity.type !== 'relation') {  // validate relations if their geometries have changed
                    return [entity].concat(graph.parentRelations(entity));
                }
                return entity;
            });
            return entities;
        })));

        var issuesByID = {};

        for (var entityIndex in entitiesToCheck) {
            var entity = entitiesToCheck[entityIndex];
            var entityIssues = validateEntity(entity);
            _issuesByEntityID[entity.id] = entityIssues;
            entityIssues.forEach(function(issue) {
                // Different entities can produce the same issue so store them by
                // the ID to ensure that there are no duplicate issues.
                issuesByID[issue.id()] = issue;
            });
        }

        for (var issueID in issuesByID) {
            _issues.push(issuesByID[issueID]);
        }

        dispatch.call('reload', self, _issues);
    };

    return utilRebind(self, dispatch, 'on');
}