Files
iD/modules/svg/lines.js
2016-07-19 12:04:16 -04:00

135 lines
3.8 KiB
JavaScript

import _ from 'lodash';
import { OneWaySegments, Path, RelationMemberTags, TagClasses } from './index';
import { Detect } from '../util/detect';
import { Entity } from '../core/index';
import { simpleMultipolygonOuterMember } from '../geo/index';
export function Lines(projection) {
var highway_stack = {
motorway: 0,
motorway_link: 1,
trunk: 2,
trunk_link: 3,
primary: 4,
primary_link: 5,
secondary: 6,
tertiary: 7,
unclassified: 8,
residential: 9,
service: 10,
footway: 11
};
function waystack(a, b) {
var as = 0, bs = 0;
if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
return as - bs;
}
return function drawLines(surface, graph, entities, filter) {
var ways = [], pathdata = {}, onewaydata = {},
getPath = Path(projection, graph);
for (var i = 0; i < entities.length; i++) {
var entity = entities[i],
outer = simpleMultipolygonOuterMember(entity, graph);
if (outer) {
ways.push(entity.mergeTags(outer.tags));
} else if (entity.geometry(graph) === 'line') {
ways.push(entity);
}
}
ways = ways.filter(getPath);
pathdata = _.groupBy(ways, function(way) { return way.layer(); });
_.forOwn(pathdata, function(v, k) {
onewaydata[k] = _(v)
.filter(function(d) { return d.isOneWay(); })
.map(OneWaySegments(projection, graph, 35))
.flatten()
.valueOf();
});
var layergroup = surface
.selectAll('.layer-lines')
.selectAll('g.layergroup')
.data(d3.range(-10, 11));
layergroup.enter()
.append('g')
.attr('class', function(d) { return 'layer layergroup layer' + String(d); });
var linegroup = layergroup
.selectAll('g.linegroup')
.data(['shadow', 'casing', 'stroke']);
linegroup.enter()
.append('g')
.attr('class', function(d) { return 'layer linegroup line-' + d; });
var lines = linegroup
.selectAll('path')
.filter(filter)
.data(
function() { return pathdata[this.parentNode.parentNode.__data__] || []; },
Entity.key
);
// Optimization: call simple TagClasses only on enter selection. This
// works because Entity.key is defined to include the entity v attribute.
lines.enter()
.append('path')
.attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
.call(TagClasses());
lines
.sort(waystack)
.attr('d', getPath)
.call(TagClasses().tags(RelationMemberTags(graph)));
lines.exit()
.remove();
var onewaygroup = layergroup
.selectAll('g.onewaygroup')
.data(['oneway']);
onewaygroup.enter()
.append('g')
.attr('class', 'layer onewaygroup');
var oneways = onewaygroup
.selectAll('path')
.filter(filter)
.data(
function() { return onewaydata[this.parentNode.parentNode.__data__] || []; },
function(d) { return [d.id, d.index]; }
);
oneways.enter()
.append('path')
.attr('class', 'oneway')
.attr('marker-mid', 'url(#oneway-marker)');
oneways
.attr('d', function(d) { return d.d; });
if (Detect().ie) {
oneways.each(function() { this.parentNode.insertBefore(this, this); });
}
oneways.exit()
.remove();
};
}