mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-22 00:07:03 +02:00
Massive rework
This commit is contained in:
+12
@@ -38,6 +38,18 @@ table th {
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
path.casing {
|
||||
fill: transparent;
|
||||
stroke: #ace;
|
||||
stroke-width: 6;
|
||||
}
|
||||
|
||||
path.stroke {
|
||||
fill: transparent;
|
||||
stroke: #5F8594;
|
||||
stroke-width: 4;
|
||||
}
|
||||
|
||||
.help-pane {
|
||||
position:absolute;
|
||||
left:0;
|
||||
|
||||
+17
-13
@@ -4,7 +4,6 @@
|
||||
<meta charset="utf-8">
|
||||
<title>iD</title>
|
||||
<!-- load Dojo -->
|
||||
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8/dijit/themes/claro/claro.css">
|
||||
<link rel="stylesheet" href="css/app.css">
|
||||
</head>
|
||||
<body class="claro">
|
||||
@@ -15,9 +14,18 @@
|
||||
<script type="text/javascript" src="js/iD/Util.js"></script>
|
||||
<script type="text/javascript" src="js/iD/Taginfo.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/iD/controller/controller.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/edit.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/EditBaseState.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/NoSelection.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/SelectedPOINode.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/SelectedWay.js"></script>
|
||||
<script type="text/javascript" src="js/iD/controller/edit/SelectedWayNode.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/iD/styleparser/styleparser.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/Condition.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/Rule.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/RuleChain.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/Style.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/StyleChooser.js"></script>
|
||||
<script type="text/javascript" src="js/iD/styleparser/StyleList.js"></script>
|
||||
@@ -86,28 +94,27 @@
|
||||
<!-- Map div -->
|
||||
|
||||
<div id="map"></div>
|
||||
<p>Work in progress: <a href='http://www.geowiki.com/'>introduction</a>, <a href='http://github.com/systemed/iD'>code</a>, <a href='http://www.geowiki.com/docs'>docs</a>. Imagery <a href="http://opengeodata.org/microsoft-imagery-details">© 2012</a> Bing, GeoEye, Getmapping, Intermap, Microsoft.</p>
|
||||
<p>Work in progress: <a href='http://www.geowiki.com/'>introduction</a>,
|
||||
<a href='http://github.com/systemed/iD'>code</a>,
|
||||
<a href='http://www.geowiki.com/docs'>docs</a>.
|
||||
Imagery <a href="http://opengeodata.org/microsoft-imagery-details">© 2012</a> Bing, GeoEye, Getmapping, Intermap, Microsoft.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var ruleset = new iD.styleparser.RuleSet();
|
||||
var connection = new iD.Connection("http://www.overpass-api.de/api/xapi?");
|
||||
|
||||
// Load styles
|
||||
ruleset.registerCallback(styleLoaded);
|
||||
ruleset.loadFromCSS("potlatch.css", styleLoaded);
|
||||
|
||||
// Initialise map
|
||||
var map = new iD.renderer.Map({
|
||||
lat: 51.87,
|
||||
lon: -1.49,
|
||||
zoom: 17,
|
||||
selector: "#map",
|
||||
connection: connection,
|
||||
width: $('#map').width(),
|
||||
height: $('#map').height()
|
||||
});
|
||||
map.setZoom(14);
|
||||
map.setCentre({ lat: 38.8, lon: -77 });
|
||||
map.ruleset = ruleset;
|
||||
|
||||
// Initialise controller
|
||||
@@ -116,16 +123,13 @@
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Data is loaded and app ready to go
|
||||
function styleLoaded() {
|
||||
// Initialise drag-and-drop icons
|
||||
new iD.ui.DragAndDrop("map", map, "dndgrid");
|
||||
|
||||
ruleset.loadFromCSS("potlatch.css", function styleLoaded() {
|
||||
// Set initial controllerState
|
||||
controller.setState(new iD.controller.edit.NoSelection());
|
||||
|
||||
// Load data
|
||||
map.download();
|
||||
}
|
||||
});
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Mode button handlers
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@
|
||||
if (typeof iD === 'undefined') iD = {};
|
||||
|
||||
iD.Controller = function(map) {
|
||||
var controller = {};
|
||||
var controller = {},
|
||||
state = null;
|
||||
|
||||
controller.editorCache = {};
|
||||
controller.undoStack = new iD.UndoStack();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
iD.controller = {};
|
||||
@@ -1,13 +1,8 @@
|
||||
// iD/controller/edit/EditBaseState.js
|
||||
|
||||
define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array','dojo/on',
|
||||
'dijit/registry'
|
||||
], function(declare,lang,array,on,registry){
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// EditBaseState class - provides shared UI functions to edit mode states
|
||||
|
||||
declare("iD.controller.edit.EditBaseState", null, {
|
||||
iD.controller.edit.EditBaseState = function() {};
|
||||
iD.controller.edit.EditBaseState.prototype = {
|
||||
|
||||
editortooltip: null,
|
||||
|
||||
@@ -73,8 +68,4 @@ declare("iD.controller.edit.EditBaseState", null, {
|
||||
// summary: Close the tooltip.
|
||||
$('.edit-pane').removeClass('active').hide();
|
||||
}
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
// iD/controller/edit/NoSelection.js
|
||||
|
||||
define(['dojo/_base/declare',
|
||||
'iD/controller/edit/EditBaseState',
|
||||
'iD/controller/edit/SelectedWay',
|
||||
'iD/controller/edit/SelectedWayNode',
|
||||
'iD/controller/edit/SelectedPOINode'
|
||||
], function(declare){
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// edit.NoSelection class
|
||||
|
||||
declare("iD.controller.edit.NoSelection", [iD.controller.edit.EditBaseState], {
|
||||
iD.controller.edit.NoSelection = function() {};
|
||||
iD.controller.edit.NoSelection.prototype = {
|
||||
|
||||
constructor: function() {
|
||||
// summary: In 'Edit object' mode but nothing selected.
|
||||
},
|
||||
|
||||
enterState: function() {
|
||||
this.controller.stepper.hide();
|
||||
// this.controller.stepper.hide();
|
||||
},
|
||||
|
||||
processMouseEvent: function(event, entityUI) {
|
||||
@@ -38,8 +30,4 @@ declare("iD.controller.edit.NoSelection", [iD.controller.edit.EditBaseState], {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,50 +1,43 @@
|
||||
// iD/controller/edit/SelectedPOINode.js
|
||||
// ----------------------------------------------------------------------
|
||||
// edit.SelectedPOINode class
|
||||
|
||||
define(['dojo/_base/declare','iD/controller/edit/EditBaseState'], function(declare){
|
||||
iD.controller.edit.SelectedPOINode = function() {};
|
||||
iD.controller.edit.SelectedPOINode.prototype = {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// edit.SelectedPOINode class
|
||||
node: null,
|
||||
nodeUI: null,
|
||||
|
||||
declare("iD.controller.edit.SelectedPOINode", [iD.controller.edit.EditBaseState], {
|
||||
constructor: function(node) {
|
||||
// summary: In 'Edit object' mode and a POI node is selected.
|
||||
this.node = node;
|
||||
},
|
||||
|
||||
node: null,
|
||||
nodeUI: null,
|
||||
enterState: function() {
|
||||
var map = this.controller.map;
|
||||
this.nodeUI = map.getUI(this.node);
|
||||
this.nodeUI.setStateClass('selected')
|
||||
.redraw();
|
||||
this.openEditorTooltip(this.node);
|
||||
return this;
|
||||
},
|
||||
|
||||
constructor: function(node) {
|
||||
// summary: In 'Edit object' mode and a POI node is selected.
|
||||
this.node = node;
|
||||
},
|
||||
exitState: function() {
|
||||
this.nodeUI.resetStateClass('selected')
|
||||
.redraw();
|
||||
this.closeEditorTooltip();
|
||||
return this;
|
||||
},
|
||||
|
||||
enterState: function() {
|
||||
var map = this.controller.map;
|
||||
this.nodeUI = map.getUI(this.node);
|
||||
this.nodeUI.setStateClass('selected')
|
||||
.redraw();
|
||||
this.openEditorTooltip(this.node);
|
||||
return this;
|
||||
},
|
||||
|
||||
exitState: function() {
|
||||
this.nodeUI.resetStateClass('selected')
|
||||
.redraw();
|
||||
this.closeEditorTooltip();
|
||||
return this;
|
||||
},
|
||||
|
||||
processMouseEvent: function(event, entityUI) {
|
||||
if (event.type !== 'click') return this;
|
||||
var entity = entityUI ? entityUI.entity : null;
|
||||
var entityType = entity ? entity.entityType : null;
|
||||
switch (entityType) {
|
||||
case null: return new iD.controller.edit.NoSelection();
|
||||
case 'node': return new iD.controller.edit.SelectedPOINode(entityUI.entity);
|
||||
case 'way': return new iD.controller.edit.SelectedWay(entityUI.entity, event);
|
||||
}
|
||||
return this;
|
||||
processMouseEvent: function(event, entityUI) {
|
||||
if (event.type !== 'click') return this;
|
||||
var entity = entityUI ? entityUI.entity : null;
|
||||
var entityType = entity ? entity.entityType : null;
|
||||
switch (entityType) {
|
||||
case null: return new iD.controller.edit.NoSelection();
|
||||
case 'node': return new iD.controller.edit.SelectedPOINode(entityUI.entity);
|
||||
case 'way': return new iD.controller.edit.SelectedWay(entityUI.entity, event);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
// iD/controller/edit/SelectedWay.js
|
||||
|
||||
define(['dojo/_base/declare','iD/controller/edit/EditBaseState'], function(declare){
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// edit.SelectedWay class
|
||||
|
||||
declare("iD.controller.edit.SelectedWay", [iD.controller.edit.EditBaseState], {
|
||||
iD.controller.edit.SelectedWay = function() {};
|
||||
iD.controller.edit.SelectedWay.prototype = {
|
||||
|
||||
way: null,
|
||||
wayUI: null,
|
||||
@@ -57,8 +54,4 @@ declare("iD.controller.edit.SelectedWay", [iD.controller.edit.EditBaseState], {
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
// iD/controller/edit/SelectedWayNode.js
|
||||
|
||||
define(['dojo/_base/declare','iD/controller/edit/EditBaseState'], function(declare){
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// SelectedWayNode class
|
||||
|
||||
declare("iD.controller.edit.SelectedWayNode", [iD.controller.edit.EditBaseState], {
|
||||
iD.controller.edit.SelectedWayNode = function() {};
|
||||
iD.controller.edit.SelectedWayNode.prototype = {
|
||||
|
||||
node: null,
|
||||
way: null,
|
||||
@@ -53,8 +49,4 @@ declare("iD.controller.edit.SelectedWayNode", [iD.controller.edit.EditBaseState]
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
iD.controller.edit = {};
|
||||
+91
-236
@@ -8,29 +8,27 @@ iD.renderer.Map = function(obj) {
|
||||
// summary: The main map display, containing the individual sprites (UIs) for each entity.
|
||||
// obj: Object An object containing .lat, .lon, .scale, .div (the name of the <div> to be used),
|
||||
// .connection, .width (px) and .height (px) properties.
|
||||
this.mapwidth = obj.width ? obj.width : 800;
|
||||
this.mapheight = obj.height ? obj.height : 400;
|
||||
this.width = obj.width ? obj.width : 800;
|
||||
this.height = obj.height ? obj.height : 400;
|
||||
|
||||
// Initialise variables
|
||||
this.uis = {};
|
||||
|
||||
this.projection = d3.geo.mercator()
|
||||
.scale(512).translate([512, 512]);
|
||||
this.zoombehavior = d3.behavior.zoom()
|
||||
.translate(this.projection.translate())
|
||||
.scale(this.projection.scale())
|
||||
.on("zoom", _.bind(this.redraw, this));
|
||||
|
||||
this.surface = d3.selectAll(obj.selector)
|
||||
.append('svg')
|
||||
.attr('width', this.mapwidth)
|
||||
.attr('height', this.mapwidth);
|
||||
.attr({ width: this.width, height: this.width })
|
||||
.call(this.zoombehavior);
|
||||
|
||||
this.tilegroup = this.surface.append('g');
|
||||
this.container = this.surface.append('g');
|
||||
this.connection = obj.connection;
|
||||
this.zoom = obj.zoom ? obj.zoom : 17;
|
||||
this.baselon = obj.lon;
|
||||
this.baselat = obj.lat;
|
||||
this.baselatp = this.lat2latp(obj.lat);
|
||||
this._setScaleFactor();
|
||||
this.updateCoordsFromViewportPosition();
|
||||
|
||||
// Cache the margin box, since this is expensive.
|
||||
// this.marginBox = domGeom.getMarginBox(this.div);
|
||||
|
||||
// Initialise layers
|
||||
this.layers={};
|
||||
@@ -50,22 +48,12 @@ iD.renderer.Map = function(obj) {
|
||||
this.elastic = this.container.append('g');
|
||||
|
||||
// Make draggable
|
||||
this.tilegroup.on('onmousedown', _.bind(this.startDrag, this));
|
||||
this.surface.on('onclick', _.bind(this.clickSurface, this));
|
||||
this.surface.on('onmousemove', _.bind(this.processMove, this));
|
||||
this.surface.on('onmousedown', _.bind(this._mouseEvent, this));
|
||||
this.surface.on('onmouseup', _.bind(this._mouseEvent, this));
|
||||
};
|
||||
iD.renderer.Map.prototype = {
|
||||
|
||||
MASTERSCALE: 5825.4222222222,
|
||||
MINSCALE: 14,
|
||||
MAXSCALE: 23,
|
||||
zoom: NaN,
|
||||
zoomfactor: NaN,
|
||||
baselon: NaN, // original longitude at top left of viewport
|
||||
baselat: NaN, // original latitude at top left of viewport
|
||||
baselatp: NaN, // original projected latitude at top left of viewport
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
iD.renderer.Map.prototype = {
|
||||
|
||||
div: '', // <div> of this map
|
||||
surface: null, // <div>.surface containing the rendering
|
||||
@@ -81,20 +69,14 @@ iD.renderer.Map.prototype = {
|
||||
|
||||
dragging: false, // current drag state
|
||||
dragged: false, // was most recent click a drag?
|
||||
dragx: NaN, // click co-ordinates at previously recorded drag event
|
||||
dragy: NaN, // |
|
||||
startdragx: NaN, // click co-ordinates at start of drag
|
||||
startdragy: NaN, // |
|
||||
dragtime: NaN, // timestamp of mouseup (compared to stop resulting click from firing)
|
||||
dragconnect: null, // event listener for endDrag
|
||||
|
||||
containerx: 0, // screen co-ordinates of container
|
||||
containery: 0, // |
|
||||
centrelat: NaN, // lat/long and bounding box of map
|
||||
centrelon: NaN, // |
|
||||
extent: {}, // |
|
||||
mapheight: NaN, // size of map object in pixels
|
||||
mapwidth: NaN, // |
|
||||
|
||||
height: NaN, // size of map object in pixels
|
||||
width: NaN, // |
|
||||
|
||||
layers: null, // array-like object of Groups, one for each OSM layer
|
||||
minlayer: -5, // minimum OSM layer supported
|
||||
@@ -134,7 +116,7 @@ iD.renderer.Map.prototype = {
|
||||
// ----------------------------
|
||||
// Sprite and EntityUI handling
|
||||
|
||||
sublayer:function(layer,groupType,sublayer) {
|
||||
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'
|
||||
@@ -205,18 +187,18 @@ iD.renderer.Map.prototype = {
|
||||
// remove: Boolean Should we delete any UIs that are no longer in the bbox?
|
||||
var o = this.connection.getObjectsByBbox(this.extent);
|
||||
var touch = _(o.inside).chain()
|
||||
.filter(function(w) { return w.loaded; })
|
||||
.map(_.bind(function(e) {
|
||||
if (!this.uis[e.id]) {
|
||||
this.createUI(e);
|
||||
} else {
|
||||
this.uis[e.id].redraw();
|
||||
}
|
||||
return '' + e.id;
|
||||
}, this)).value();
|
||||
_.each(_.difference(_.keys(this.uis), touch), _.bind(function(k) {
|
||||
this.deleteUI(k);
|
||||
}, this));
|
||||
.filter(function(w) { return w.loaded; })
|
||||
.map(_.bind(function(e) {
|
||||
if (!this.uis[e.id]) {
|
||||
this.createUI(e);
|
||||
} else {
|
||||
this.uis[e.id].redraw();
|
||||
}
|
||||
return '' + e.id;
|
||||
}, this)).value();
|
||||
_.each(_.difference(_.keys(this.uis), touch), _.bind(function(k) {
|
||||
this.deleteUI(k);
|
||||
}, this));
|
||||
},
|
||||
|
||||
// -------------
|
||||
@@ -235,16 +217,11 @@ iD.renderer.Map.prototype = {
|
||||
},
|
||||
|
||||
setZoom: function(zoom) {
|
||||
if (zoom < this.MINSCALE || zoom > this.MAXSCALE) return this;
|
||||
// summary: Redraw the map at a new zoom level.
|
||||
this.zoom = zoom;
|
||||
this._setScaleFactor();
|
||||
this._blankTiles();
|
||||
this.setCentre({
|
||||
lat: this.centrelat,
|
||||
lon: this.centrelon
|
||||
});
|
||||
this.projection.scale(256 * Math.pow(2, zoom - 1));
|
||||
this.zoombehavior.scale(this.projection.scale());
|
||||
this.updateUIs(true, true);
|
||||
this.redraw();
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -272,149 +249,60 @@ iD.renderer.Map.prototype = {
|
||||
width: 1
|
||||
});
|
||||
},
|
||||
redraw: function() {
|
||||
var projection = this.projection,
|
||||
width = this.width,
|
||||
height = this.height;
|
||||
|
||||
// -------------
|
||||
// Tile handling
|
||||
// ** FIXME: see docs
|
||||
loadTiles: function() {
|
||||
// summary: Load all tiles for the current viewport. This is a bare-bones function
|
||||
// at present: it needs configurable URLs (not just Bing), attribution/logo
|
||||
// support, and to be 'nudgable' (i.e. adjust the offset).
|
||||
var tl = this.locationCoord({
|
||||
lat: this.extent.north,
|
||||
lon: this.extent.west
|
||||
}, this.zoom),
|
||||
br = this.locationCoord({
|
||||
lat: this.extent.south,
|
||||
lon: this.extent.east
|
||||
}, this.zoom),
|
||||
tileKeys = _.keys(this.tiles),
|
||||
seen = [],
|
||||
coord = { z: this.zoom };
|
||||
|
||||
for (coord.x = tl.x; coord.x <= br.x; coord.x++) {
|
||||
for (coord.y = tl.y; coord.y <= br.y; coord.y++) {
|
||||
if (!this._getTile(coord)) {
|
||||
this._fetchTile(coord);
|
||||
}
|
||||
seen.push(iD.Util.tileKey(coord));
|
||||
}
|
||||
if (d3.event) {
|
||||
projection
|
||||
.translate(d3.event.translate)
|
||||
.scale(d3.event.scale);
|
||||
}
|
||||
|
||||
_.each(_.without(tileKeys, seen), _.bind(function(key) {
|
||||
delete this.tiles[key];
|
||||
}, this));
|
||||
},
|
||||
var t = projection.translate(),
|
||||
s = projection.scale(),
|
||||
z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
|
||||
rz = Math.floor(z),
|
||||
ts = 256 * Math.pow(2, z - rz);
|
||||
|
||||
_fetchTile: function(coord) {
|
||||
// summary: Load a tile image at the given tile co-ordinates.
|
||||
var t = this.tilegroup.append('image')
|
||||
.attr({
|
||||
width: 256,
|
||||
height: 256,
|
||||
x: Math.floor(this.lon2coord(this.tile2lon(coord.x))),
|
||||
y: Math.floor(this.lat2coord(this.tile2lat(coord.y))),
|
||||
'xlink:href': this._tileURL(coord)
|
||||
// This is the 0, 0 px of the projection
|
||||
var tile_origin = [s / 2 - t[0], s / 2 - t[1]],
|
||||
coords = [],
|
||||
cols = d3.range(Math.max(0, Math.floor((tile_origin[0] - width) / ts)),
|
||||
Math.max(0, Math.ceil((tile_origin[0] + width) / ts))),
|
||||
rows = d3.range(Math.max(0, Math.floor((tile_origin[1] - height) / ts)),
|
||||
Math.max(0, Math.ceil((tile_origin[1] + height) / ts)));
|
||||
|
||||
cols.forEach(function(x) {
|
||||
rows.forEach(function(y) { coords.push([Math.floor(z), x, y]); });
|
||||
});
|
||||
|
||||
var tmpl = this.tilebaseURL;
|
||||
|
||||
function tileUrl(coord) {
|
||||
var u = '';
|
||||
for (var zoom = coord[0]; zoom > 0; zoom--) {
|
||||
var byte = 0;
|
||||
var mask = 1 << (zoom - 1);
|
||||
if ((coord[1] & mask) !== 0) byte++;
|
||||
if ((coord[2] & mask) !== 0) byte += 2;
|
||||
u += byte.toString();
|
||||
}
|
||||
return tmpl.replace('$quadkey', u);
|
||||
}
|
||||
|
||||
var tiles = this.tilegroup.selectAll('image.tile')
|
||||
.data(coords, function(d) { return d.join(','); });
|
||||
|
||||
tiles.exit().remove();
|
||||
tiles.enter().append('image')
|
||||
.attr('class', 'tile')
|
||||
.attr('xlink:href', tileUrl);
|
||||
tiles.attr({ width: ts, height: ts })
|
||||
.attr('transform', function(d) {
|
||||
return 'translate(' + [(d[1] * ts) - tile_origin[0], (d[2] * ts) - tile_origin[1]] + ')';
|
||||
});
|
||||
this._assignTile(coord, t);
|
||||
},
|
||||
|
||||
_getTile: function(coord) {
|
||||
// summary: See if this tile is already loaded.
|
||||
return this.tiles[iD.Util.tileKey(coord)];
|
||||
},
|
||||
|
||||
_assignTile: function(coord, t) {
|
||||
// summary: Store a reference to the tile so we know it's loaded.
|
||||
this.tiles[iD.Util.tileKey(coord)] = t;
|
||||
},
|
||||
|
||||
_tileURL: function(coord) {
|
||||
// summary: Calculate the URL for a tile at the given co-ordinates.
|
||||
var u = '';
|
||||
for (var zoom = coord.z; zoom > 0; zoom--) {
|
||||
var byte = 0;
|
||||
var mask = 1 << (zoom - 1);
|
||||
if ((coord.x & mask) !== 0) byte++;
|
||||
if ((coord.y & mask) !== 0) byte += 2;
|
||||
u += byte.toString();
|
||||
}
|
||||
return this.tilebaseURL
|
||||
.replace('$z', coord.z)
|
||||
.replace('$x', coord.x)
|
||||
.replace('$y', coord.y)
|
||||
.replace('$quadkey', u);
|
||||
},
|
||||
|
||||
_blankTiles: function() {
|
||||
// summary: Unload all tiles and remove from the display.
|
||||
this.tilegroup.clear();
|
||||
this.tiles = {};
|
||||
},
|
||||
|
||||
// -------------------------------------------
|
||||
// Co-ordinate management, dragging and redraw
|
||||
|
||||
startDrag: function(e) {
|
||||
// summary: Start dragging the map in response to a mouse-down.
|
||||
// e: MouseEvent The mouse-down event that triggered it.
|
||||
var srcElement = (e.gfxTarget === this.backdrop) ?
|
||||
e.gfxTarget : e.gfxTarget.parent;
|
||||
Event.stop(e);
|
||||
this.dragging = true;
|
||||
this.dragged = false;
|
||||
this.dragx = this.dragy=NaN;
|
||||
this.startdragx = e.clientX;
|
||||
this.startdragy = e.clientY;
|
||||
this.dragconnect = srcElement.connect("onmouseup", _.bind(this.endDrag, this));
|
||||
},
|
||||
|
||||
endDrag: function(e) {
|
||||
// summary: Stop dragging the map in response to a mouse-up.
|
||||
// e: MouseEvent The mouse-up event that triggered it.
|
||||
Event.stop(e);
|
||||
dojo.disconnect(this.dragconnect);
|
||||
this.dragging=false;
|
||||
this.dragtime=e.timeStamp;
|
||||
this.updateCoordsFromViewportPosition();
|
||||
if (Math.abs(e.clientX - this.startdragx) < 3 &&
|
||||
Math.abs(e.clientY - this.startdragy) < 3) {
|
||||
return;
|
||||
}
|
||||
this.download();
|
||||
},
|
||||
|
||||
processMove: function(e) {
|
||||
// summary: Drag the map to a new origin.
|
||||
// e: MouseEvent The mouse-move event that triggered it.
|
||||
var x = e.clientX;
|
||||
var y = e.clientY;
|
||||
if (this.dragging) {
|
||||
if (this.dragx) {
|
||||
this.containerx += (x - this.dragx);
|
||||
this.containery += (y - this.dragy);
|
||||
this.updateOrigin();
|
||||
this.dragged=true;
|
||||
}
|
||||
this.dragx = x;
|
||||
this.dragy = y;
|
||||
} else {
|
||||
this.controller.entityMouseEvent(e,null);
|
||||
}
|
||||
},
|
||||
|
||||
updateOrigin: function() {
|
||||
// summary: Tell Dojo to update the viewport origin.
|
||||
// this.container.setTransform([Matrix.translate(this.containerx, this.containery)]);
|
||||
// this.tilegroup.setTransform([Matrix.translate(this.containerx, this.containery)]);
|
||||
},
|
||||
|
||||
_mouseEvent: function(e) {
|
||||
// summary: Catch mouse events on the surface but not the tiles - in other words,
|
||||
// on drawn items that don't have their own hitzones, like the fill of a shape.
|
||||
if (e.type=='mousedown') { this.startDrag(e); }
|
||||
// ** FIXME: we may want to reinstate this at some point...
|
||||
// this.controller.entityMouseEvent(e,null);
|
||||
},
|
||||
|
||||
updateCoordsFromViewportPosition: function(e) {
|
||||
@@ -424,11 +312,14 @@ iD.renderer.Map.prototype = {
|
||||
|
||||
setCentre: function(loc) {
|
||||
// summary: Update centre and bbox to a specified lat/lon.
|
||||
var coord = this.locationCoord(loc, this.zoom);
|
||||
this._updateCoords(
|
||||
-coord.x - this.mapwidth / 2,
|
||||
-coord.y - this.mapheight / 2);
|
||||
return this;
|
||||
var t = this.projection.translate(),
|
||||
ll = this.projection([loc.lon, loc.lat]);
|
||||
this.projection.translate([
|
||||
t[0] - ll[0] + this.width / 2,
|
||||
t[1] - ll[1] + this.height / 2]);
|
||||
this.zoombehavior.translate(this.projection.translate());
|
||||
this.redraw();
|
||||
return this;
|
||||
},
|
||||
|
||||
setCenter: function(loc) { this.setCentre(loc); },
|
||||
@@ -437,7 +328,6 @@ iD.renderer.Map.prototype = {
|
||||
// summary: Set centre and bbox.
|
||||
this.containerx = x;
|
||||
this.containery = y;
|
||||
this.updateOrigin();
|
||||
this.centrelon = this.coord2lon(-x + this.mapwidth/2);
|
||||
this.centrelat = this.coord2lat(-y + this.mapheight/2);
|
||||
|
||||
@@ -447,8 +337,6 @@ iD.renderer.Map.prototype = {
|
||||
west: this.coord2lon(-x),
|
||||
east: this.coord2lon(-x + this.mapwidth)
|
||||
};
|
||||
|
||||
this.loadTiles();
|
||||
},
|
||||
|
||||
clickSurface:function(e) {
|
||||
@@ -457,40 +345,7 @@ iD.renderer.Map.prototype = {
|
||||
this.controller.entityMouseEvent(e,null);
|
||||
},
|
||||
|
||||
// -----------------------
|
||||
// Co-ordinate conversions
|
||||
|
||||
latp2coord:function(a) { return -(a-this.baselatp)*this.zoomfactor; },
|
||||
coord2latp:function(a) { return a/-this.zoomfactor+this.baselatp; },
|
||||
lon2coord:function(a) { return (a-this.baselon)*this.zoomfactor; },
|
||||
coord2lon:function(a) { return a/this.zoomfactor+this.baselon; },
|
||||
lon2screen:function(a) { return this.lon2coord(a) + this.marginBox.l + this.containerx; },
|
||||
|
||||
lat2latp:function(a) { return 180/Math.PI * Math.log(Math.tan(Math.PI/4+a*(Math.PI/180)/2)); },
|
||||
latp2lat:function(a) { return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2); },
|
||||
lat2coord:function(a) { return -(this.lat2latp(a)-this.baselatp)*this.zoomfactor; },
|
||||
coord2lat:function(a) { return this.latp2lat(a/-this.zoomfactor+this.baselatp); },
|
||||
lat2screen:function(a) { return this.lat2coord(a) + this.marginBox.t + this.containery; },
|
||||
|
||||
locationCoord: function(ll, z) {
|
||||
var z2 = Math.pow(2, z), d2r = Math.PI / 180;
|
||||
return {
|
||||
z: z,
|
||||
x: Math.floor((ll.lon + 180) / 360 * z2),
|
||||
y: Math.floor((1 - Math.log(Math.tan(ll.lat * d2r) +
|
||||
1 / Math.cos(ll.lat * d2r)) / Math.PI) / 2 * z2)
|
||||
};
|
||||
},
|
||||
lon2tile:function(a) { return (Math.floor((a+180)/360*Math.pow(2,this.zoom))); },
|
||||
lat2tile:function(a) { return (Math.floor((1-Math.log(Math.tan(a*Math.PI/180) + 1/Math.cos(a*Math.PI/180))/Math.PI)/2 *Math.pow(2,this.zoom))); },
|
||||
tile2lon:function(a) { return (a/Math.pow(2,this.zoom)*360-180); },
|
||||
tile2lat:function(a) {
|
||||
var n=Math.PI-2*Math.PI*a/Math.pow(2,this.zoom);
|
||||
return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
|
||||
},
|
||||
|
||||
// Turn event co-ordinates into map co-ordinates
|
||||
|
||||
mouseX: function(e) { return e.clientX - this.marginBox.l - this.containerx; },
|
||||
mouseY: function(e) { return e.clientY - this.marginBox.t - this.containery; }
|
||||
};
|
||||
|
||||
+21
-85
@@ -1,94 +1,30 @@
|
||||
iD.renderer.NodeUI = function() {};
|
||||
iD.renderer.NodeUI = function(node, map) {
|
||||
this.node = node;
|
||||
this.map = map;
|
||||
this.draw();
|
||||
};
|
||||
iD.renderer.NodeUI.prototype = {
|
||||
getEnhancedTags:function() {
|
||||
var tags=this.inherited(arguments);
|
||||
if (!this.entity.entity.hasParentWays()) { tags[':poi']='yes'; }
|
||||
getEnhancedTags: function() {
|
||||
var tags = this.node.tags;
|
||||
if (!this.node.entity.hasParentWays()) { tags[':poi']='yes'; }
|
||||
// add junction and dupe
|
||||
return tags;
|
||||
},
|
||||
redraw:function() {
|
||||
draw: function() {
|
||||
// summary: Draw the object (mostly icons) and add hitzone sprites.
|
||||
var node = this.entity;
|
||||
this.removeSprites();
|
||||
|
||||
// Tags, position and styleList
|
||||
var x = Math.floor(this.map.lon2coord(this.entity.lon));
|
||||
var y = Math.floor(this.map.latp2coord(this.entity.latp));
|
||||
var x = Math.floor(this.map.lon2coord(this.node.lon));
|
||||
var y = Math.floor(this.map.latp2coord(this.node.latp));
|
||||
var tags = this.getEnhancedTags();
|
||||
this.refreshStyleList(tags);
|
||||
|
||||
// Iterate through each subpart, drawing any styles on that layer
|
||||
var drawn = false;
|
||||
var s, p, t, w, h;
|
||||
for (i = 0; i < this.styleList.subparts.length; i++) {
|
||||
var subpart=this.styleList.subparts[i];
|
||||
p = this.styleList.pointStyles[subpart];
|
||||
if (!p || !p.drawn()) { continue; }
|
||||
s = this.styleList.shapeStyles[subpart];
|
||||
t = this.styleList.textStyles[subpart];
|
||||
w = p.icon_width ? p.icon_width : 16;
|
||||
h = p.icon_height ? p.icon_height: w;
|
||||
|
||||
// Draw icon
|
||||
var shape;
|
||||
if (p.icon_image === 'square') {
|
||||
shape = this.targetGroup('stroke', p.sublayer)
|
||||
.createRect({
|
||||
x: x-w/2,
|
||||
y: y-h/2,
|
||||
width: w,
|
||||
height: h
|
||||
});
|
||||
} else if (p.icon_image === 'circle') {
|
||||
shape = this.targetGroup('stroke', p.sublayer)
|
||||
.createCircle({
|
||||
cx: x,
|
||||
cy: y,
|
||||
r: w
|
||||
});
|
||||
} else {
|
||||
shape = this.targetGroup('stroke',p.sublayer)
|
||||
.createImage({
|
||||
width: w,
|
||||
height: h,
|
||||
x: x-w/2,
|
||||
y: y-h/2,
|
||||
src: p.icon_image
|
||||
});
|
||||
if (p.icon_image === 'square' || p.icon_image === 'circle') {
|
||||
shape.setStroke(s.shapeStrokeStyler()).setFill(s.shapeFillStyler());
|
||||
}
|
||||
this.recordSprite(shape);
|
||||
|
||||
// Add text label
|
||||
// Add hit-zone
|
||||
var hit;
|
||||
if (p.icon_image === 'circle') {
|
||||
hit = this.targetGroup('hit').createCircle({
|
||||
cx: x,
|
||||
cy: y,
|
||||
r: w
|
||||
});
|
||||
} else {
|
||||
hit = this.targetGroup('hit').createRect({
|
||||
x: x-w/2,
|
||||
y: y-h/2,
|
||||
width: w,
|
||||
height: h
|
||||
});
|
||||
}
|
||||
hit.setFill([0,1,0,0]).setStroke({
|
||||
width:2,
|
||||
color:[0,0,0,0]
|
||||
});
|
||||
this.recordSprite(hit);
|
||||
hit.source = this;
|
||||
hit.connect("onclick", _.bind(this.entityMouseEvent, this));
|
||||
hit.connect("onmousedown", _.bind(this.entityMouseEvent, this));
|
||||
hit.connect("onmouseup", _.bind(this.entityMouseEvent, this));
|
||||
hit.connect("onmouseenter", _.bind(this.entityMouseEvent, this));
|
||||
hit.connect("onmouseleave", _.bind(this.entityMouseEvent, this));
|
||||
}
|
||||
}
|
||||
|
||||
var im = this.map.layers[0].hit.append("image")
|
||||
.attr('class', 'poi')
|
||||
.attr('x', x)
|
||||
.attr('y', y)
|
||||
.attr('width', 16)
|
||||
.attr('height', 16)
|
||||
.attr("xlink:href", function() {
|
||||
return tags.amenity ? 'icons/' + tags.amenity + '.png' : '';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
+19
-92
@@ -8,30 +8,28 @@
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// WayUI class
|
||||
iD.renderer.WayUI = function() {};
|
||||
iD.renderer.WayUI = function(entity, map) {
|
||||
this.entity = entity;
|
||||
this.map = map;
|
||||
this.draw();
|
||||
};
|
||||
|
||||
iD.renderer.WayUI.prototype = {
|
||||
getEnhancedTags: function() {
|
||||
var tags = this.inherited(arguments);
|
||||
var tags = this.entity.tags;
|
||||
if (this.entity.isClosed()) { tags[':area']='yes'; }
|
||||
return tags;
|
||||
},
|
||||
recalculate: function() {
|
||||
// summary: Not yet implemented - calculate length/centrepoint of UI for use in rendering.
|
||||
// ** FIXME: todo
|
||||
},
|
||||
redraw: function() {
|
||||
draw: function() {
|
||||
// summary: Draw the object and add hitzone sprites.
|
||||
var way = this.entity,
|
||||
maxwidth = 4,
|
||||
i;
|
||||
|
||||
this.removeSprites();
|
||||
if (!way.nodes.length) { return; }
|
||||
|
||||
// Create tags and calculate styleList
|
||||
var tags = this.getEnhancedTags();
|
||||
this.refreshStyleList(tags);
|
||||
|
||||
// List of co-ordinates
|
||||
var coords = _.map(way.nodes, _.bind(function(node) {
|
||||
@@ -41,91 +39,20 @@ iD.renderer.WayUI.prototype = {
|
||||
};
|
||||
}, this));
|
||||
|
||||
// Iterate through each subpart, drawing any styles on that layer
|
||||
var drawn = false;
|
||||
for (i = 0; i < this.styleList.subparts.length; i++) {
|
||||
var subpart = this.styleList.subparts[i];
|
||||
if (this.styleList.shapeStyles[subpart]) {
|
||||
var s = this.styleList.shapeStyles[subpart], line;
|
||||
var line = d3.svg.line()
|
||||
.x(function(d) { return d.x; })
|
||||
.y(function(d) { return d.y; })
|
||||
.interpolate("linear");
|
||||
|
||||
// Stroke
|
||||
if (s.width) {
|
||||
line = this.targetGroup('stroke',s.sublayer)
|
||||
.createPolyline(coords)
|
||||
.setStroke(s.strokeStyler());
|
||||
this.map.layers[0].casing.append("path")
|
||||
.data([coords])
|
||||
.attr('class', 'casing')
|
||||
.attr("d", line);
|
||||
|
||||
this.recordSprite(line);
|
||||
maxwidth = Math.max(maxwidth, s.width);
|
||||
drawn = true;
|
||||
}
|
||||
|
||||
// Fill
|
||||
if (!isNaN(s.fill_color)) {
|
||||
line = this.targetGroup('fill',s.sublayer)
|
||||
.createPolyline(coords)
|
||||
.setFill(s.fillStyler());
|
||||
|
||||
this.recordSprite(line);
|
||||
drawn = true;
|
||||
}
|
||||
|
||||
// Casing
|
||||
if (s.casing_width) {
|
||||
line = this.targetGroup('casing')
|
||||
.createPolyline(coords)
|
||||
.setStroke(s.casingStyler());
|
||||
|
||||
this.recordSprite(line);
|
||||
maxwidth = Math.max(maxwidth, s.width + s.casing_width * 2);
|
||||
drawn = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Text label on path
|
||||
if (this.styleList.textStyles[subpart]) {
|
||||
var t = this.styleList.textStyles[subpart];
|
||||
if (t.text && tags[t.text]) {
|
||||
var tp=this.recordSprite(this.targetGroup('text')
|
||||
.createTextPath(t.textStyler(tags[t.text]))
|
||||
.setFont(t.fontStyler())
|
||||
.setFill(t.fillStyler())
|
||||
.moveTo(coords[0].x,coords[0].y));
|
||||
for (var j=1; j<coords.length; j++) {
|
||||
tp.lineTo(coords[j].x,coords[j].y);
|
||||
}
|
||||
// *** this next line is SVG-specific
|
||||
tp.rawNode.setAttribute("pointer-events","none");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add hitzone sprite
|
||||
if (drawn) {
|
||||
var hit=this.recordSprite(this.targetGroup('hit')
|
||||
.createPolyline(coords)
|
||||
.setStroke({
|
||||
width: maxwidth+8,
|
||||
color: [0,0,0,0]
|
||||
}));
|
||||
|
||||
var entityMouseEvent = _.bind(this.entityMouseEvent, this);
|
||||
hit.source=this;
|
||||
hit.connect("onclick", entityMouseEvent);
|
||||
hit.connect("onmousedown", entityMouseEvent);
|
||||
hit.connect("onmouseup", entityMouseEvent);
|
||||
hit.connect("onmouseenter", entityMouseEvent);
|
||||
hit.connect("onmouseleave", entityMouseEvent);
|
||||
}
|
||||
// Draw nodes
|
||||
for (i=0; i<way.nodes.length; i++) {
|
||||
var node=way.nodes[i];
|
||||
var sc=[];
|
||||
if (tags[':shownodes']) { sc.push('selectedway'); }
|
||||
if (tags[':shownodeshover']) { sc.push('hoverway'); }
|
||||
if (node.entity.parentWays().length>1) { sc.push('junction'); }
|
||||
this.map.createUI(node,sc);
|
||||
}
|
||||
this.map.layers[0].stroke.append("path")
|
||||
.data([coords])
|
||||
.attr('class', 'stroke')
|
||||
.attr("d", line);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -67,8 +67,4 @@ iD.styleparser.RuleChain.prototype = {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// End of module
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,12 +7,6 @@ iD.styleparser.RuleSet = function() {};
|
||||
iD.styleparser.RuleSet.prototype = {
|
||||
|
||||
choosers: [], // list of StyleChoosers
|
||||
callback: null,
|
||||
|
||||
registerCallback: function(callback) {
|
||||
// summary: Set a callback function to be called when the CSS is loaded and parsed.
|
||||
this.callback = callback;
|
||||
},
|
||||
|
||||
getStyles: function(entity, tags, zoom) {
|
||||
// summary: Find the styles for a given entity.
|
||||
@@ -23,15 +17,16 @@ iD.styleparser.RuleSet.prototype = {
|
||||
return sl; // iD.styleparser.StyleList
|
||||
},
|
||||
|
||||
loadFromCSS:function(url) {
|
||||
loadFromCSS: function(url, callback) {
|
||||
// summary: Load a MapCSS file from a URL, then throw it at the parser when it's loaded.
|
||||
this.callback = callback;
|
||||
$.ajax({
|
||||
url: url,
|
||||
load: _.bind(this.parseCSS, this)
|
||||
success: _.bind(this.parseCSS, this)
|
||||
});
|
||||
},
|
||||
|
||||
parseCSS:function(css) {
|
||||
parseCSS: function(css) {
|
||||
// summary: Parse a CSS document into a set of StyleChoosers.
|
||||
var previous=0; // what was the previous CSS word?
|
||||
var sc = new iD.styleparser.StyleChooser(); // currently being assembled
|
||||
|
||||
@@ -7,11 +7,9 @@ iD.styleparser.Style.prototype = {
|
||||
interactive: true,
|
||||
properties: [],
|
||||
styleType: 'Style',
|
||||
evals: null,
|
||||
evals: {},
|
||||
|
||||
constructor: function() {
|
||||
// summary: Base class for a set of painting attributes, into which the CSS declaration is parsed.
|
||||
this.evals = {};
|
||||
},
|
||||
|
||||
drawn: function() {
|
||||
@@ -77,6 +75,7 @@ iD.styleparser.InstructionStyle = function() {};
|
||||
iD.styleparser.InstructionStyle.prototype = {
|
||||
set_tags: null,
|
||||
breaker: false,
|
||||
evals: {},
|
||||
styleType: 'InstructionStyle',
|
||||
addSetTag: function(k,v) {
|
||||
this.edited=true;
|
||||
@@ -93,12 +92,34 @@ iD.styleparser.PointStyle.prototype = {
|
||||
properties: ['icon_image','icon_width','icon_height','rotation'],
|
||||
icon_image: null,
|
||||
icon_width: 0,
|
||||
evals: {},
|
||||
icon_height: NaN,
|
||||
rotation: NaN,
|
||||
styleType: 'PointStyle',
|
||||
drawn:function() {
|
||||
return (this.icon_image !== null);
|
||||
},
|
||||
|
||||
setPropertyFromString: function(k,v,isEval) {
|
||||
this.edited=true;
|
||||
if (isEval) { this.evals[k]=v; return; }
|
||||
|
||||
if (typeof(this[k])=='boolean') {
|
||||
v=Boolean(v);
|
||||
} else if (typeof(this[k])=='number') {
|
||||
v=Number(v);
|
||||
} else if (this[k] && this[k].constructor==Array) {
|
||||
v = v.split(',').map(function(a) { return Number(a); });
|
||||
}
|
||||
this[k]=v;
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
|
||||
has: function(k) {
|
||||
return this.properties.indexOf(k)>-1;
|
||||
},
|
||||
maxwidth:function() {
|
||||
return this.evals.icon_width ? 0 : this.icon_width;
|
||||
}
|
||||
@@ -118,9 +139,31 @@ iD.styleparser.ShapeStyle.prototype = {
|
||||
fill_image:null, fill_color:NaN, fill_opacity:NaN,
|
||||
casing_width:NaN, casing_color:NaN, casing_opacity:NaN, casing_dashes:[],
|
||||
|
||||
evals: {},
|
||||
layer:NaN, // optional layer override (usually set by OSM tag)
|
||||
styleType: 'ShapeStyle',
|
||||
|
||||
|
||||
setPropertyFromString: function(k,v,isEval) {
|
||||
this.edited=true;
|
||||
if (isEval) { this.evals[k]=v; return; }
|
||||
|
||||
if (typeof(this[k])=='boolean') {
|
||||
v=Boolean(v);
|
||||
} else if (typeof(this[k])=='number') {
|
||||
v=Number(v);
|
||||
} else if (this[k] && this[k].constructor==Array) {
|
||||
v = v.split(',').map(function(a) { return Number(a); });
|
||||
}
|
||||
this[k]=v;
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
|
||||
has: function(k) {
|
||||
return this.properties.indexOf(k)>-1;
|
||||
},
|
||||
drawn:function() {
|
||||
return (this.fill_image || !isNaN(this.fill_color) || this.width || this.casing_width);
|
||||
},
|
||||
@@ -184,6 +227,7 @@ iD.styleparser.TextStyle.prototype = {
|
||||
font_italic: false,
|
||||
font_underline: false,
|
||||
font_caps: false,
|
||||
evals: {},
|
||||
font_size: NaN,
|
||||
text_color: NaN,
|
||||
text_offset: NaN,
|
||||
@@ -195,6 +239,23 @@ iD.styleparser.TextStyle.prototype = {
|
||||
letter_spacing: 0,
|
||||
styleType: 'TextStyle',
|
||||
|
||||
|
||||
setPropertyFromString: function(k,v,isEval) {
|
||||
this.edited=true;
|
||||
if (isEval) { this.evals[k]=v; return; }
|
||||
|
||||
if (typeof(this[k])=='boolean') {
|
||||
v=Boolean(v);
|
||||
} else if (typeof(this[k])=='number') {
|
||||
v=Number(v);
|
||||
} else if (this[k] && this[k].constructor==Array) {
|
||||
v = v.split(',').map(function(a) { return Number(a); });
|
||||
}
|
||||
this[k]=v;
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
drawn: function() {
|
||||
return (this.text !== null);
|
||||
},
|
||||
@@ -213,6 +274,10 @@ iD.styleparser.TextStyle.prototype = {
|
||||
text: _text
|
||||
};
|
||||
},
|
||||
|
||||
has: function(k) {
|
||||
return this.properties.indexOf(k)>-1;
|
||||
},
|
||||
fillStyler:function() {
|
||||
// not implemented yet
|
||||
return this.dojoColor(0,1);
|
||||
@@ -230,6 +295,7 @@ iD.styleparser.ShieldStyle.prototype = {
|
||||
shield_image: null,
|
||||
shield_width: NaN,
|
||||
shield_height: NaN,
|
||||
evals: {},
|
||||
styleType: 'ShieldStyle',
|
||||
drawn:function() {
|
||||
return (shield_image !== null);
|
||||
|
||||
Reference in New Issue
Block a user