Use path clipping to hide off-screen features

This commit is contained in:
Tom MacWright
2012-10-24 10:10:21 -04:00
parent e229c91331
commit 54c2ba60f8
4 changed files with 126 additions and 83 deletions

View File

@@ -38,16 +38,79 @@ table th {
text-align:left;
}
path {
fill: none;
}
path.casing {
fill: transparent;
stroke: #ace;
stroke-width: 6;
stroke: #111;
stroke-width: 3;
}
path.stroke {
fill: transparent;
stroke: #5F8594;
stroke-width: 4;
stroke: #555;
stroke-width: 2;
}
path.casing.natural {
display:none;
}
path.stroke.railway-rail {
stroke: white;
stroke-width: 3;
stroke-dasharray: 12,12;
}
path.stroke.railway-subway {
stroke: #444;
stroke-width: 3;
stroke-dasharray: 8,8;
}
path.stroke.natural {
stroke: #ADD6A5;
fill: #ADD6A5;
stroke-width:1;
opacity:0.2;
}
path.stroke.landuse {
stroke: #444;
stroke-width:1;
fill: #444;
opacity:0.2;
}
path.stroke.highway-residential {
stroke:#E8E8E8;
stroke-width:3;
}
path.stroke.highway-unclassified,
path.stroke.highway-tertiary {
stroke:#FEFECB;
stroke-width:3;
}
path.stroke.highway-service {
stroke:#fff;
stroke-width:2;
}
path.stroke.highway-motorway,
path.stroke.highway-motorway_link {
stroke:#809BC0;
}
path.stroke.highway-trunk,
path.stroke.highway-trunk_link {
stroke:#7FC97F;
}
path.stroke.waterway {
stroke: #10539a;
stroke-width: 3;
}
.help-pane {

View File

@@ -111,10 +111,10 @@ Imagery <a href="http://opengeodata.org/microsoft-imagery-details">&copy; 2012</
selector: "#map",
connection: connection,
width: $('#map').width(),
height: $('#map').height()
height: 700
});
map.setZoom(16);
map.setCentre({ lat: 38.8, lon: -77 });
map.setCentre({ lat: 40.407, lon: -74.688 });
map.ruleset = ruleset;
// Initialise controller

View File

@@ -34,8 +34,21 @@ iD.renderer.Map = function(obj) {
.attr({ width: this.width, height: this.width })
.call(this.zoombehavior);
this.tilegroup = this.surface.append('g');
this.container = this.surface.append('g');
var clip = this.surface.append("defs")
.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0")
.attr("width", this.width)
.attr("height", this.height);
this.tilegroup = this.surface.append('g')
.attr("clip-path", "url(#clip)");
this.container = this.surface.append('g')
.attr("clip-path", "url(#clip)");
this.connection = obj.connection;
// Initialise layers
@@ -90,60 +103,6 @@ iD.renderer.Map.prototype = {
this.controller = controller;
},
_moveToPosition:function(group, position) {
// summary: Supplementary method for dojox.gfx.
// This should ideally be core Dojo stuff: see http://bugs.dojotoolkit.org/ticket/15296
var parent=group.getParent();
if (!parent) { return; }
this._moveChildToPosition(parent,group,position);
if (position === group.rawNode.parentNode.childNodes.length) {
group.rawNode.parentNode.appendChild(group.rawNode);
} else {
group.rawNode.parentNode.insertBefore(group.rawNode, group.rawNode.parentNode.childNodes[position]);
}
},
_moveChildToPosition: function(parent, child, position) {
for (var i = 0; i < parent.children.length; ++i){
if (parent.children[i] === child){
parent.children.splice(i, 1);
parent.children.splice(position, 0, child);
break;
}
}
},
// ----------------------------
// Sprite and EntityUI handling
sublayer: function(layer,groupType,sublayer) {
// summary: Find the gfx.Group for a given OSM layer and rendering sublayer, creating it
// if necessary. Note that sublayers are only implemented for stroke and fill.
// groupType: String 'casing','text','hit','stroke', or 'fill'
var collection = this.layers[layer][groupType], sub;
switch (groupType) {
case 'casing':
case 'text':
case 'hit':
return collection;
}
// Find correct sublayer, inserting if necessary
var insertAt=collection.children.length;
for (var i = 0; i < collection.children.length; i++) {
sub=collection.children[i];
if (sub.sublayer==sublayer) { return sub; }
else if (sub.sublayer>sublayer) {
sub = collection.createGroup();
this._moveToPosition(sub,i);
sub.sublayer=sublayer;
return sub;
}
}
sub = collection.createGroup().moveToFront();
sub.sublayer=sublayer;
return sub; // dojox.gfx.Group
},
createUI: function(e, stateClasses) {
// summary: Create a UI (sprite) for an entity, assigning any specified state classes
// (temporary attributes such as ':hover' or ':selected')

View File

@@ -15,27 +15,46 @@ iD.renderer.WayUI = function(entity, map) {
};
iD.renderer.WayUI.prototype = {
getEnhancedTags: function() {
var tags = this.entity.tags;
if (this.entity.isClosed()) { tags[':area']='yes'; }
return tags;
},
getEnhancedTags: function() {
var tags = this.entity.tags;
if (this.entity.isClosed()) { tags[':area']='yes'; }
return tags;
},
draw: function() {
// summary: Draw the object and add hitzone sprites.
var way = this.entity,
maxwidth = 4,
i;
getClasses: function() {
var classes = [];
function clean(x) {
return x.indexOf(' ') === -1 && x.length < 30;
}
for (var k in this.entity.tags) {
var v = this.entity.tags[k];
if (!clean(k) || !clean(v)) {
console.log(k, v);
continue;
}
classes.push(k + '-' + v);
classes.push(k);
classes.push(v);
}
return classes.join(' ');
},
if (!way.nodes.length) { return; }
draw: function() {
// summary: Draw the object and add hitzone sprites.
var way = this.entity;
// Create tags and calculate styleList
var tags = this.getEnhancedTags();
if (!way.nodes.length) { return; }
// Create tags and calculate styleList
var tags = this.getEnhancedTags();
var classes = this.getClasses();
if (!this.casing) {
this.casing = this.map.layers[0].casing.append("path")
.data([way.nodes])
.attr('class', 'casing');
.attr('class', function() {
return 'casing ' + classes;
});
}
this.casing.attr("d", this.map.linegen);
@@ -43,15 +62,17 @@ iD.renderer.WayUI.prototype = {
if (!this.stroke) {
this.stroke = this.map.layers[0].stroke.append("path")
.data([way.nodes])
.attr('class', 'stroke');
.attr('class', function() {
return 'stroke ' + classes;
});
}
this.stroke.attr("d", this.map.linegen);
return this;
},
},
entityMouseEvent:function(event) {
this.inherited(arguments);
}
entityMouseEvent:function(event) {
this.inherited(arguments);
}
};