Merge branch 'master' into layers

This commit is contained in:
Tom MacWright
2013-03-20 10:39:24 -04:00
19 changed files with 964 additions and 42 deletions
+27 -1
View File
@@ -2,7 +2,10 @@ var fs = require('fs'),
path = require('path'),
glob = require('glob'),
YAML = require('js-yaml'),
_ = require('./js/lib/lodash');
_ = require('./js/lib/lodash'),
jsonschema = require('jsonschema'),
fieldSchema = require('./data/presets/schema/field.json'),
presetSchema = require('./data/presets/schema/preset.json');
function read(f) {
return JSON.parse(fs.readFileSync(f));
@@ -16,6 +19,21 @@ function rp(f) {
return r('presets/' + f);
}
function validate(file, instance, schema) {
var result = jsonschema.validate(instance, schema);
if (result.length) {
console.error(file + ": ");
result.forEach(function(error) {
if (error.property) {
console.error(error.property + ' ' + error.message);
} else {
console.error(error);
}
});
process.exit(1);
}
}
var translations = {
fields: {},
presets: {}
@@ -25,12 +43,16 @@ var fields = {};
glob.sync(__dirname + '/data/presets/fields/*.json').forEach(function(file) {
var field = read(file),
id = path.basename(file, '.json');
validate(file, field, fieldSchema);
translations.fields[id] = {label: field.label};
if (field.strings) {
for (var i in field.strings) {
translations.fields[id][i] = field.strings[i];
}
}
fields[id] = field;
});
fs.writeFileSync('data/presets/fields.json', JSON.stringify(fields, null, 4));
@@ -39,10 +61,14 @@ var presets = {};
glob.sync(__dirname + '/data/presets/presets/**/*.json').forEach(function(file) {
var preset = read(file),
id = file.match(/presets\/presets\/([^.]*)\.json/)[1];
validate(file, preset, presetSchema);
translations.presets[id] = {
name: preset.name,
terms: (preset.terms || []).join(',')
};
presets[id] = preset;
});
fs.writeFileSync('data/presets/presets.json', JSON.stringify(presets, null, 4));
+2 -3
View File
@@ -283,7 +283,7 @@ ul.link-list li:last-child {
div.hide,
form.hide {
display:none;
display: none;
}
.deemphasize {
@@ -1147,12 +1147,11 @@ div.combobox {
/* tag editor */
.inspector-inner.additional-tags {
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
}
.tag-list {
margin-top: 10px;
padding-top: 20px;
}
.tag-row {
+5
View File
@@ -588,6 +588,10 @@ locale.en = {
"name": "Building",
"terms": ""
},
"building/entrance": {
"name": "Entrance",
"terms": ""
},
"entrance": {
"name": "Entrance",
"terms": ""
@@ -1047,6 +1051,7 @@ locale.en = {
}
}
};
locale.zh = {
"modes": {
"add_area": {
+3
View File
@@ -256,6 +256,9 @@ en:
building:
name: Building
terms: ""
building/entrance:
name: Entrance
terms: ""
entrance:
name: Entrance
terms: ""
+2 -3
View File
@@ -3,15 +3,14 @@
"icon": "highway",
"id": "Road",
"members": [
"highway/residential",
"highway/motorway",
"highway/trunk",
"highway/primary",
"highway/secondary",
"highway/tertiary",
"highway/unclassified",
"highway/residential",
"highway/service",
"highway/track",
"highway"
"highway/track"
]
}]
+1 -1
View File
@@ -368,7 +368,7 @@
"no"
],
"icon": "wheelchair",
"universal": "true",
"universal": true,
"label": "Wheelchair Access"
},
"wikipedia": {
+1 -1
View File
@@ -7,6 +7,6 @@
"no"
],
"icon": "wheelchair",
"universal": "true",
"universal": true,
"label": "Wheelchair Access"
}
+10 -8
View File
@@ -828,14 +828,6 @@
"building_yes",
"levels"
],
"additional": [
"address",
"phone",
"website",
"wikipedia",
"elevation",
"source"
],
"geometry": [
"area"
],
@@ -845,6 +837,16 @@
"terms": [],
"name": "Building"
},
"building/entrance": {
"geometry": [
"vertex"
],
"tags": {
"building": "entrance"
},
"name": "Entrance",
"searchable": false
},
"entrance": {
"geometry": [
"vertex"
-8
View File
@@ -4,14 +4,6 @@
"building_yes",
"levels"
],
"additional": [
"address",
"phone",
"website",
"wikipedia",
"elevation",
"source"
],
"geometry": [
"area"
],
@@ -0,0 +1,10 @@
{
"geometry": [
"vertex"
],
"tags": {
"building": "entrance"
},
"name": "Entrance",
"searchable": false
}
+67
View File
@@ -0,0 +1,67 @@
{
"title": "Field",
"description": "A reusable form element for presets",
"type": "object",
"properties": {
"key": {
"description": "Tag key whose value is to be displayed",
"type": "string"
},
"keys": {
"description": "Tag keys whose value is to be displayed",
"type": "array",
"items": {
"type": "string"
}
},
"type": {
"description": "Type of field",
"type": "string",
"enum": [
"address",
"check",
"combo",
"defaultcheck",
"text",
"number",
"tel",
"email",
"url",
"radio",
"textarea"
],
"required": true
},
"label": {
"description": "English label for the form",
"type": "string",
"required": true
},
"geometry": {
"type": "string"
},
"default": {
"type": "string"
},
"indexed": {
"type": "boolean"
},
"options": {
"type": "array",
"items": {
"type": "string"
}
},
"universal": {
"type": "boolean",
"default": false
},
"icon": {
"type": "string"
},
"strings": {
"type": "object"
}
},
"additionalProperties": false
}
+55
View File
@@ -0,0 +1,55 @@
{
"title": "Preset",
"description": "Associates an icon, form fields, and other UI with a set of OSM tags",
"type": "object",
"properties": {
"name": {
"description": "The English name for the feature",
"type": "string",
"required": true
},
"geometry": {
"description": "Valid geometry types for the feature",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"enum": ["point", "vertex", "line", "area"]
},
"required": true
},
"tags": {
"description": "Tags that must be present for the preset to match",
"type": "object",
"additionalProperties": {
"type": "string"
},
"required": true
},
"fields": {
"description": "Form fields that are displayed for the preset",
"type": "array",
"items": {
"type": "string"
}
},
"icon": {
"description": "Name of preset icon which represents this preset",
"type": "string"
},
"terms": {
"description": "English synonyms or related terms",
"type": "array",
"items": {
"type": "string"
}
},
"searchable": {
"description": "Whether or not the preset will be suggested via search",
"type": "boolean",
"default": true
}
},
"additionalProperties": false
}
+7 -7
View File
@@ -13,7 +13,7 @@
height="220"
id="svg12393"
version="1.1"
inkscape:version="0.48.1 r9760"
inkscape:version="0.48.2 r9819"
sodipodi:docname="sprite.svg"
inkscape:export-filename="/Users/saman/work_repos/iD/img/sprite.png"
inkscape:export-xdpi="90"
@@ -38,12 +38,12 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-49.735643"
inkscape:cy="134.55123"
inkscape:zoom="1.4142136"
inkscape:cx="2.3449562"
inkscape:cy="33.776287"
inkscape:document-units="px"
inkscape:current-layer="layer12"
showgrid="true"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="700"
inkscape:window-x="361"
@@ -53,7 +53,7 @@
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
showguides="false"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:snap-nodes="false">
@@ -201,7 +201,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 510 KiB

+4 -3
View File
@@ -21,13 +21,14 @@ iD.actions.Circularize = function(wayId, projection, count) {
radius = d3.median(points, function(p) {
return iD.geo.dist(centroid, p);
}),
ids = [];
ids = [],
sign = d3.geom.polygon(points).area() > 0 ? -1 : 1;
for (var i = 0; i < count; i++) {
var node,
loc = projection.invert([
centroid[0] + Math.cos((i / 12) * Math.PI * 2) * radius,
centroid[1] + Math.sin((i / 12) * Math.PI * 2) * radius]);
centroid[0] + Math.cos(sign * (i / 12) * Math.PI * 2) * radius,
centroid[1] + Math.sin(sign * (i / 12) * Math.PI * 2) * radius]);
if (nodes.length) {
var idx = closestIndex(nodes, loc);
-1
View File
@@ -3,7 +3,6 @@ iD.presets.Preset = function(id, preset, fields) {
preset.id = id;
preset.fields = (preset.fields || []).map(getFields);
preset.additional = (preset.additional || []).map(getFields);
function getFields(f) {
return fields[f];
+1 -1
View File
@@ -98,7 +98,7 @@ iD.ui.TagEditor = function(context, entity) {
}
editorwrap.append('div')
.attr('class','inspector-inner col12 fillL additional-tags')
.attr('class','inspector-inner col12 fillL2 additional-tags')
.call(tagList, preset.id === 'other');
// Don't add for created entities
+2 -1
View File
@@ -24,7 +24,8 @@
"mocha-phantomjs": "~1.1.1",
"glob": "~3.1.21",
"js-yaml": "~2.0.3",
"request": "~2.16.2"
"request": "~2.16.2",
"jsonschema": "~0.3.2"
},
"engines": {
"node": "~0.8.20"
+40 -4
View File
@@ -26,7 +26,7 @@ describe("iD.actions.Circularize", function () {
graph = iD.actions.Circularize('-', projection)(graph);
expect(graph.entity('-').nodes.slice(0, 4)).to.eql(['c', 'b', 'a', 'd']);
expect(graph.entity('-').nodes.slice(0, 4).sort()).to.eql(['a', 'b', 'c', 'd']);
});
it("deletes unused nodes that are not members of other ways", function () {
@@ -40,7 +40,7 @@ describe("iD.actions.Circularize", function () {
graph = iD.actions.Circularize('-', projection, 3)(graph);
expect(graph.entity('d')).to.be.undefined;
expect(graph.entity('a')).to.be.undefined;
});
it("reconnects unused nodes that are members of other ways", function () {
@@ -51,12 +51,48 @@ describe("iD.actions.Circularize", function () {
'd': iD.Node({id: 'd', loc: [0, 2]}),
'e': iD.Node({id: 'e', loc: [1, 1]}),
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'd', 'e', 'a']}),
'=': iD.Way({id: '=', nodes: ['d']})
'=': iD.Way({id: '=', nodes: ['a']})
});
graph = iD.actions.Circularize('-', projection, 3)(graph);
expect(graph.entity('d')).to.be.undefined;
expect(graph.entity('a')).to.be.undefined;
expect(graph.entity('=').nodes).to.eql(['c']);
});
function area(id, graph) {
return d3.geom.polygon(_.pluck(graph.childNodes(graph.entity(id)), 'loc')).area();
}
it("leaves clockwise ways clockwise", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [0, 0]}),
'b': iD.Node({id: 'b', loc: [2, 0]}),
'c': iD.Node({id: 'c', loc: [2, 2]}),
'd': iD.Node({id: 'd', loc: [0, 2]}),
'+': iD.Way({id: '+', nodes: ['a', 'd', 'c', 'b', 'a']})
});
expect(area('+', graph)).to.be.gt(0);
graph = iD.actions.Circularize('+', projection)(graph);
expect(area('+', graph)).to.be.gt(0);
});
it("leaves counter-clockwise ways counter-clockwise", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [0, 0]}),
'b': iD.Node({id: 'b', loc: [2, 0]}),
'c': iD.Node({id: 'c', loc: [2, 2]}),
'd': iD.Node({id: 'd', loc: [0, 2]}),
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'd', 'a']})
});
expect(area('-', graph)).to.be.lt(0);
graph = iD.actions.Circularize('-', projection)(graph);
expect(area('-', graph)).to.be.lt(0);
});
});