Merge remote-tracking branch 'systemed/master' into intro

Conflicts:
	build.js
	data/locales.js
This commit is contained in:
Ansis Brammanis
2013-03-26 13:17:35 -04:00
63 changed files with 1990 additions and 772 deletions
+15
View File
@@ -72,6 +72,21 @@ Transiflex, will automatically detect the change.
Use `make` to build the translations with the local changes.
`make translate` can be used to pull the latest translations from Transifex.
## Contributing Documentation
Documentation is maintained as a series of [Markdown](http://daringfireball.net/projects/markdown/)
documents in the `data/doc/` path. The first line of each page of documentation
should be of the form
# GPS
This will be used for navigation and as its title in iD. Documentation is
shown in alphabetical order, so most documentation is prefixed with `02-` and
so on in order to keep it in a certain order.
To add a new page of documentation, simply create a new Markdown file in
`data/doc` in the same format as the rest.
## Javascript
We use the [Airbnb style for Javascript](https://github.com/airbnb/javascript) with
+2 -1
View File
@@ -9,7 +9,7 @@ all: \
iD.js \
iD.min.js
DATA_FILES = $(shell find data -type f -name '*.json')
DATA_FILES = $(shell find data -type f -name '*.json' -o -name '*.md')
data/data.js: $(DATA_FILES)
node build.js
@@ -18,6 +18,7 @@ data/data.js: $(DATA_FILES)
js/lib/d3.v3.js \
js/lib/d3.combobox.js \
js/lib/d3.geo.tile.js \
js/lib/d3.jsonp.js \
js/lib/d3.keybinding.js \
js/lib/d3.one.js \
js/lib/d3.size.js \
+61 -30
View File
@@ -2,13 +2,18 @@ var fs = require('fs'),
path = require('path'),
glob = require('glob'),
YAML = require('js-yaml'),
marked = require('marked'),
_ = require('./js/lib/lodash'),
jsonschema = require('jsonschema'),
fieldSchema = require('./data/presets/schema/field.json'),
presetSchema = require('./data/presets/schema/preset.json');
function readtxt(f) {
return fs.readFileSync(f, 'utf8');
}
function read(f) {
return JSON.parse(fs.readFileSync(f));
return JSON.parse(readtxt(f));
}
function r(f) {
@@ -19,6 +24,10 @@ function rp(f) {
return r('presets/' + f);
}
function stringify(o) {
return JSON.stringify(o, null, 4);
}
function validate(file, instance, schema) {
var result = jsonschema.validate(instance, schema);
if (result.length) {
@@ -39,59 +48,81 @@ var translations = {
presets: {}
};
var fields = {};
glob.sync(__dirname + '/data/presets/fields/*.json').forEach(function(file) {
var field = read(file),
id = path.basename(file, '.json');
function generateDocumentation() {
var docs = [];
glob.sync(__dirname + '/data/doc/*.md').forEach(function(file) {
var text = readtxt(file),
title = text.split('\n')[0]
.replace('#', '').trim();
docs.push({
html: marked(text.split('\n').slice(1).join('\n')),
title: title
});
});
fs.writeFileSync('data/doc.json', stringify(docs));
}
validate(file, field, fieldSchema);
function generateFields() {
var fields = {};
glob.sync(__dirname + '/data/presets/fields/*.json').forEach(function(file) {
var field = read(file),
id = path.basename(file, '.json');
translations.fields[id] = {label: field.label};
if (field.strings) {
for (var i in field.strings) {
translations.fields[id][i] = field.strings[i];
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));
fields[id] = field;
});
fs.writeFileSync('data/presets/fields.json', stringify(fields));
}
var presets = {};
glob.sync(__dirname + '/data/presets/presets/**/*.json').forEach(function(file) {
var preset = read(file),
id = file.match(/presets\/presets\/([^.]*)\.json/)[1];
function generatePresets() {
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);
validate(file, preset, presetSchema);
translations.presets[id] = {
name: preset.name,
terms: (preset.terms || []).join(',')
};
translations.presets[id] = {
name: preset.name,
terms: (preset.terms || []).join(',')
};
presets[id] = preset;
});
fs.writeFileSync('data/presets/presets.json', JSON.stringify(presets, null, 4));
presets[id] = preset;
});
fs.writeFileSync('data/presets/presets.json', stringify(presets));
fs.writeFileSync('data/presets.yaml', YAML.dump({en: {presets: translations}}));
}
fs.writeFileSync('data/presets.yaml', YAML.dump({en: {presets: translations}}));
generateDocumentation();
generateFields();
generatePresets();
fs.writeFileSync('data/data.js', 'iD.data = ' + JSON.stringify({
fs.writeFileSync('data/data.js', 'iD.data = ' + stringify({
deprecated: r('deprecated.json'),
discarded: r('discarded.json'),
keys: r('keys.json'),
imagery: r('imagery.json'),
doc: r('doc.json'),
presets: {
presets: rp('presets.json'),
defaults: rp('defaults.json'),
categories: rp('categories.json'),
fields: rp('fields.json')
}
}, null, 4) + ';');
}) + ';');
// Push changes from data/core.yaml into data/locales.js
var core = YAML.load(fs.readFileSync('data/core.yaml', 'utf8'));
var presets = YAML.load(fs.readFileSync('data/presets.yaml', 'utf8'));
var intro = YAML.load(fs.readFileSync('data/intro.yaml', 'utf8'));
var en = _.merge(_.merge(core, presets), intro);
var out = 'locale.en = ' + JSON.stringify(en.en, null, 4) + ';';
var out = 'locale.en = ' + stringify(en.en) + ';';
fs.writeFileSync('data/locales.js', fs.readFileSync('data/locales.js', 'utf8').replace(/locale.en =[^;]*;/, out));
-1
View File
@@ -70,7 +70,6 @@
<script src='js/id/ui/save.js'></script>
<script src='js/id/ui/tag_reference.js'></script>
<script src='js/id/ui/tail.js'></script>
<script src='js/id/ui/key_reference.js'></script>
<script src='js/id/actions.js'></script>
<script src="js/id/actions/add_midpoint.js"></script>
+260 -136
View File
@@ -62,7 +62,7 @@ h2 {
font-size: 25px;
line-height: 1.25;
font-weight: bold;
margin-bottom: 10px;
margin-bottom: 20px;
}
h3:last-child,
@@ -71,11 +71,9 @@ h4:last-child { margin-bottom: 0;}
h3 {
font-size: 16px;
line-height: 1.3333;
line-height: 1.25;
font-weight: bold;
margin-bottom: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
h4 {
@@ -96,10 +94,15 @@ h5 {
}
p {
font-size: 12px;
margin:0;
padding:0;
}
p:last-child {
padding-bottom: 0;
}
em {
font-style: italic;
}
@@ -147,6 +150,7 @@ input[type=email] {
background-color: white;
border:1px solid #ccc;
padding:5px 10px;
height:30px;
width: 100%;
border-radius:4px;
-webkit-transition: all 100ms;
@@ -159,11 +163,6 @@ input:focus {
background-color: #F1F1F1;
}
input[type=text] {
padding:5px 10px;
height:30px;
}
input.major {
width: 100%;
padding:5px 10px;
@@ -258,6 +257,11 @@ ul.link-list li:last-child {
color: #333;
}
.fillL3 {
background: #f1f1f1;
color: #333;
}
.fillD {
background:rgba(0,0,0,.8);
color: #6C6C6C;
@@ -310,7 +314,6 @@ a.hide {
right: 0;
}
/* Buttons */
button {
@@ -393,10 +396,10 @@ button.action:hover {
background: #597BE7;
}
button.delete {
button.cancel {
background-color: #ff7070;
}
button.delete:hover {
button.cancel:hover {
background-color: #ef5454;
}
@@ -500,8 +503,11 @@ button[disabled] .label {
.icon.warning { background-position: -380px 0px;}
.icon.back { background-position: -420px 0px;}
.icon.forward { background-position: -440px 0px;}
.icon.help { background-position: -460px 0px;}
.icon.inspect.light { background-position: -220px -20px;}
.icon.geocode.light { background-position: -280px -20px;}
.icon.help.light { background-position: -460px -20px;}
.fillD .icon.avatar { background-position: -320px -20px;}
.fillD .icon.nearby { background-position: -340px -20px;}
@@ -513,7 +519,6 @@ button[disabled] .icon.add-area { background-position: -60px -40px;}
button.disabled .icon.undo { background-position: -80px -40px;}
button.disabled .icon.redo { background-position: -100px -40px;}
button[disabled] .apply.icon { background-position: -120px -40px;}
button[disabled] .save.icon { background-position: -140px -40px;}
button[disabled] .close.icon { background-position: -160px -40px;}
button[disabled] .delete.icon { background-position: -180px -40px;}
button[disabled] .icon.remove { background-position: -200px -40px;}
@@ -569,18 +574,22 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
border-radius: 0;
}
/* Header for modals / panes
------------------------------------------------------- */
.header {
border-bottom: 1px solid #ccc;
z-index: 2;
height: 60px;
position: relative;
}
.header h3 {
margin-right: 40px;
margin-bottom: 0;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.modal > button,
@@ -593,10 +602,11 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
overflow: hidden;
position: absolute;
right: 0;
top: 0;
}
.modal > button {
height: 61px;
height: 59px;
z-index: 3;
}
@@ -627,10 +637,6 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
top: 120px;
}
.inspector-body::-webkit-scrollbar {
background: #fff;
}
.inspector-inner {
padding: 20px;
position: relative;
@@ -639,15 +645,11 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
.inspector-wrap .header button.preset-reset {
border-right: 1px solid #CCC;
position: relative;
width: 60px;
}
.inspector-wrap .header button.preset-reset > div {
height: 100%;
padding: 20px 0;
-webkit-transition: opacity 200ms;
-moz-transition: opacity 200ms;
transition: opacity 200ms;
}
.inspector-wrap .header button.preset-reset .col12:last-child {
@@ -669,12 +671,6 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
padding: 0;
}
.pane:last-child .header h3 {
position: absolute;
left: 60px;
right: 40px;
}
.inspector-toggle {
color:#fff;
width: 100%;
@@ -715,25 +711,6 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
background: #ececec;
}
.grid-entry:hover .preset-help {
display: block;
border-radius: 0;
}
.grid-entry .preset-help {
display: none;
position: absolute;
bottom: 0;
right: 0;
height: 30px;
width: 30px;
background: rgba(0,0,0,.5);
}
.grid-entry .preset-help:hover {
background: rgba(0,0,0,.9);
}
.grid-entry > .icon {
position: absolute;
top: 30px;left: 0px; right: 0px;
@@ -814,23 +791,24 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
}
.subgrid {
width: -webkit-calc(100% - 10px);
width: calc(100% - 10px);
width: 100%;
width: -webkit-calc(100% + 10px);
width: calc(100% + 10px);
margin-left: -10px;
overflow: hidden;
}
.subgrid .preset-grid {
background: #eee;
padding: 10px 0px 0px 10px;
border: 1px solid #CCC;
margin-top: 0px;
border: 0;
border-radius: 4px;
border-radius: 8px;
}
.subgrid .arrow {
border: solid rgba(0, 0, 0, 0);
border-width: 10px;
border-bottom-color: #eee;
border-bottom-color: #CCC;
width: 0;
height: 0;
margin-left: 33.3333%;
@@ -861,6 +839,25 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
color: #222;
}
.grid-entry:hover .tag-reference-button {
opacity: 1;
border-radius: 0;
}
.grid-entry .tag-reference-button {
opacity: 0;
position: absolute;
bottom: 0;
right: 0;
width: 20px;
height: 30px;
background: rgba(0,0,0,.5);
}
.grid-entry .tag-reference-button:hover {
background: rgba(0,0,0,.9);
}
/* Preset icon colors */
.inspector-body-line .icon.feature-marker-stroked {
@@ -900,69 +897,104 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
/* preset form basics */
.preset-field.inspector-inner {
padding-bottom: 0;
.tag-wrap .preset-icon-wrap {
border-bottom: 1px solid #CCC;
}
.tag-wrap .grid-button-wrap {
padding: 0;
height: 110px;
}
.tag-wrap .grid-button-wrap .grid-entry {
border-top: 0;
background: #eef0ff;
}
.tag-wrap .grid-button-wrap .grid-entry .label {
background: #eef0ff;
}
.preset-field h4 .modified-icon {
opacity: 0.2;
display: none;
pointer-events: all;
}
.preset-field h4 .modified-icon:hover {
opacity: 0.5;
}
.preset-field.modified h4 .modified-icon {
display: inline-block;
}
.preset-field h4[for*="input-"] {
border: 1px solid #cfcfcf;
padding: 5px 10px;
background: #f6f6f6;
.tag-wrap .preset-icon-wrap::after {
content: "";
position: absolute;
left: 20px;
right: 20px;
height: 0;
width: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
border: solid rgba(0, 0, 0, 0);
border-width: 10px;
border-bottom-color: #CCC;
}
.tag-wrap .preset-icon-wrap div {
height: 80px;
width: 33.3333%;
width: -webkit-calc(33.3333% - 10px);
width: calc(33.3333% - 10px);
margin: auto;
border-radius: 4px;
border: 1px solid #CCC;
position: relative;
}
.tag-wrap .preset-icon-wrap .preset-icon {
position: absolute;
top: 30px;
left: 0px;
right: 0px;
margin: auto;
}
.tag-wrap .preset-icon-wrap .preset-icon.line {
top: 15px;
}
.inspector-preset .form-field {
padding-left: 20px;
padding-right: 20px;
}
.form-label {
position: relative;
font-weight: bold;
border: 1px solid #cfcfcf;
padding: 5px 0px 5px 10px;
background: #f6f6f6;
display: block;
border-radius: 4px 4px 0 0;
pointer-events: none;
z-index: 2;
}
.preset-field h4 + input,
h4 + .input-wrap-position input,
h4 + .preset-input input:first-child {
padding-top: 35px;
height: 60px;
.form-label button {
pointer-events: all;
height: 29px;
margin-top: -5px;
border-left: 1px solid #CCC;
border-radius: 0;
opacity: .5;
}
.preset-field h4 + textarea {
padding-top: 35px;
height: 100px;
.form-label .modified-icon {
border-right: 0;
opacity: 0;
}
.preset-field h4[for="input-building:levels"],
.preset-field h4[for="input-ele"],
.preset-field.checkselect h4 {
right: 50%;
.modified .form-label .modified-icon {
opacity: .5;
}
.preset-field-name h4 + input {
padding-top: 35px;
height: 70px;
.form-label button.tag-reference-button {
border-top-right-radius: 3px;
}
.form-field > input,
.form-field > textarea,
.form-field .preset-input-wrap {
border: 1px solid #CCC;
border-top: 0;
border-radius: 0 0 4px 4px;
}
.form-field textarea {
height: 65px;
}
.form-field-levels,
.form-field-elevation,
.form-field.checkselect {
width: 60%;
}
.form-field-name input {
height: 35px;
font-size: 18px;
font-weight: bold;
}
@@ -989,21 +1021,16 @@ button.preset-add-field {
padding: 0 10px;
}
.view-on-osm {
padding: 20px;
}
/* preset form numbers */
input[type=number] {
position: relative;
width: 50%;
padding-right: 65px;
}
.spin-control {
width: 60px;
height: 30px;
height: 29px;
border-left: 1px solid #CCC;
display: inline-block;
margin-left: -60px;
@@ -1016,13 +1043,14 @@ input[type=number] {
float: left;
height: 100%;
width: 50%;
border: 1px solid #CCC;
border-left: 1px solid #CCC;
border-right: 1px solid #CCC;
border-radius: 0;
border-left: 0;
}
.spin-control button.descend {
border-bottom-right-radius: 4px;
.spin-control button.decrement {
border-bottom-right-radius: 3px;
}
.spin-control button.decrement::after,
@@ -1048,14 +1076,11 @@ input[type=number] {
/* preset form checkbox */
.checkselect label {
.checkselect label:last-of-type {
display: block;
padding: 35px 5px 5px 5px;
border-radius: 4px;
margin-right: 50%;
padding: 5px;
box-sizing: border-box;
color: #999;
border: 1px solid #CCC;
}
.checkselect label:hover {
@@ -1081,11 +1106,8 @@ input[type=number] {
.radio-wrap {
display: block;
padding: 30px 0 0 0;
border-radius: 4px;
box-sizing: border-box;
color: #999;
border: 1px solid #CCC;
overflow: hidden;
}
@@ -1106,25 +1128,29 @@ input[type=number] {
/* Preset form address */
.preset-field .addr-housename {
border-bottom: none;
border-radius: 4px 4px 0 0;
.form-field .addr-housename {
border: none;
}
.preset-field .addr-number {
.form-field .addr-number {
width: 20%;
border-left: none;
border-right: none;
border-bottom: none;
border-radius: 0;
}
.preset-field .addr-street {
.form-field .addr-street {
width: 80%;
border-radius: 0;
border-right: none;
border-bottom: none;
border-radius: 0;
}
.preset-field .addr-city {
.form-field .addr-city {
border-left: none;
border-right: none;
border-bottom: none;
border-radius: 0 0 4px 4px;
}
@@ -1209,7 +1235,7 @@ div.combobox {
.tag-row {
width: 100%;
position: relative;
height: 30px;
clear: both;
}
.tag-row input {
@@ -1228,7 +1254,6 @@ div.combobox {
border-right: 1px solid #CCC;
}
.tag-row:first-child input.key {
border-top: 1px solid #CCC;
border-top-left-radius: 4px;
@@ -1255,6 +1280,10 @@ div.combobox {
left: -20px
}
.tag-row div.tag-help {
display: hidden;
}
.tag-row:hover input.value,
.tag-row:hover input.key {
border-radius: 0;
@@ -1282,6 +1311,20 @@ div.combobox {
display: none;
}
/* Tag reference */
.tag-help {
overflow: hidden;
}
img.wiki-image {
float: left;
max-width: 33.3333%;
margin-right: 20px;
max-height: 200px;
border-radius: 4px;
}
/* Map Controls */
.map-control {
@@ -1523,10 +1566,68 @@ div.combobox {
}
.geolocate-control button {
}
/* Help */
.help-control {
top: 270px;
}
.help-control button {
border-radius: 0 0 4px 0;
border-bottom: 0;
}
.help-wrap {
position: absolute;
top:60px;
bottom: 30px;
padding: 20px 20px 20px 50px;
left: 0;
overflow-y: scroll;
}
.help-wrap p {
font-size: 15px;
margin-bottom: 20px;
}
.help-wrap .left-content .body p code {
padding:2px 4px;
background:#eee;
}
.help-wrap .toc {
/* This is two columns, 41.66666 x .4 = 16.6666 */
width:40%;
float:right;
margin-left: 20px;
margin-bottom: 20px;
padding-left: 5px
}
.help-wrap .toc li a {
display: block;
font-weight: bold;
border: 1px solid #CCC;
border-bottom: 0px;
padding: 5px;
}
.help-wrap .toc li a.selected {
background: #eef0ff;
}
.help-wrap .toc li:first-child a {
border-radius: 4px 4px 0 0;
}
.help-wrap .toc li:last-child a {
border-bottom: 1px solid #CCC;
border-radius: 0 0 4px 4px
}
/* Map
------------------------------------------------------- */
@@ -1597,6 +1698,20 @@ div.combobox {
color:#fff;
}
/* Attribution overlay */
.attribution {
position: absolute;
bottom: 35px;
right:10px;
color:#888;
font-size:10px;
}
.source-image {
height:20px;
vertical-align:top;
}
.user-list a:not(:last-child):after {
content: ', ';
}
@@ -1798,7 +1913,7 @@ div.typeahead a:first-child {
------------------------------------------------------- */
.modal a.success-action {
height: 180px;
height: 170px;
border-bottom: 1px solid #CCC;
text-align: center;
-webkit-transition: all 200ms;
@@ -1820,7 +1935,7 @@ a.success-action:before {
height: 100px;
width: 100px;
margin: auto;
margin-bottom: 20px;
margin-bottom: 10px;
background:transparent url(../img/sprite.png) no-repeat 0px -220px;
}
@@ -2091,13 +2206,24 @@ a.success-action.twitter:before {
@media only screen and (max-height: 840px) {
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {
.map-control .icon,
.button-wrap .icon {
background-image: url(../img/sprite2x.png);
background-size: 500px 320px;
}
}
/* Scrollbars
----------------------------------------------------- */
::-webkit-scrollbar {
height: 20px;
overflow: visible;
width: 10px;
background: #EBEBEB;
background: white;
border-left: 1px solid #DDD;
}
::-webkit-scrollbar-button {
@@ -2114,10 +2240,8 @@ a.success-action.twitter:before {
}
::-webkit-scrollbar-track:hover {
background-color: rgba(0,0,0,.05);
box-shadow: inset 1px 0 0 rgba(0,0,0,.1);
}
::-webkit-scrollbar-track:horizontal:hover {
box-shadow: inset 0 1px 0 rgba(0,0,0,.1)
}
::-webkit-scrollbar-track:active {
background-color: rgba(0,0,0,.05);
+5 -5
View File
@@ -856,11 +856,11 @@ text.point {
cursor: url(../img/cursor-select-remove.png), pointer;
}
.point:active,
.vertex:active,
.line:active,
.area:active,
.midpoint:active,
#map .point:active,
#map .vertex:active,
#map .line:active,
#map .area:active,
#map .midpoint:active,
.mode-select .selected {
cursor: url(../img/cursor-select-acting.png), pointer;
}
+9 -7
View File
@@ -107,7 +107,7 @@ en:
nothing_to_redo: Nothing to redo.
just_edited: "You just edited OpenStreetMap!"
browser_notice: "This editor is supported in Firefox, Chrome, Safari, Opera, and Internet Explorer 9 and above. Please upgrade your browser or use Potlatch 2 to edit the map."
view_on_osm: View on OSM
view_on_osm: "View on OSM →"
zoom_in_edit: zoom in to edit the map
logout: logout
report_a_bug: report a bug
@@ -123,8 +123,8 @@ en:
deleted: Deleted
created: Created
contributors:
list: "Viewing contributions by {users}"
truncated_list: "Viewing contributions by {users} and {count} others"
list: "Contributed by {users}"
truncated_list: "Contributed by {users} and {count} others"
geocoder:
title: Find a place
placeholder: Find a place
@@ -136,7 +136,7 @@ en:
no_documentation_key: There is no documentation available for this key
show_more: Show More
new_tag: New tag
view_on_osm: View on OSM
view_on_osm: View on OSM
editing_feature: "Editing {feature}"
additional: Additional tags
choose: Select feature type
@@ -150,7 +150,8 @@ en:
fix_misalignment: Fix misalignment
reset: reset
restore:
description: "You have unsaved changes from a previous editing session. Do you wish to restore these changes?"
heading: You have unsaved changes
description: "Do you wish to restore changes from a previous editing session?"
restore: Restore
reset: Reset
save:
@@ -167,6 +168,7 @@ en:
start: Start Editing
source_switch:
live: live
lose_changes: "You have unsaved changes. Switching the map server will discard them. Are you sure you want to switch servers?"
dev: dev
tag_reference:
description: Description
@@ -182,8 +184,8 @@ en:
zoom:
in: Zoom In
out: Zoom Out
imagery:
provided_by: "Imagery provided by {source}"
gpx:
local_layer: "Local GPX file"
drag_drop: "Drag and drop a .gpx file on the page"
help:
title: "Help"
+4 -2
View File
@@ -12,7 +12,8 @@ iD.data = {
path + 'data/presets/presets.json',
path + 'data/presets/defaults.json',
path + 'data/presets/categories.json',
path + 'data/presets/fields.json'], d3.json, function (err, data) {
path + 'data/presets/fields.json',
path + 'data/doc.json'], d3.json, function (err, data) {
iD.data = {
deprecated: data[0],
@@ -24,7 +25,8 @@ iD.data = {
defaults: data[5],
categories: data[6],
fields: data[7]
}
},
doc: data[8]
};
callback();
+34
View File
@@ -0,0 +1,34 @@
[
{
"html": "<p>This is an editor for <a href=\"http://www.openstreetmap.org/\">OpenStreetMap</a>, the\nfree and editable map of the world. You can use it to fix and update\ndata in your area, making an open-source and open-data map of the world\nbetter for everyone.</p>\n<p>Edits that you make on this map will be visible to everyone who uses\nOpenStreetMap. In order to make an edit, you&#39;ll need a\n<a href=\"https://www.openstreetmap.org/user/new\">free OpenStreetMap account</a>.</p>\n<p><a href=\"http://ideditor.com/\">iD Editor</a> is a collaborative project with <a href=\"https://github.com/systemed/iD\">source\ncode available on GitHub</a>.</p>\n",
"title": "Help"
},
{
"html": "<p>This editor is designed to work primarily online, and you&#39;re accessing\nit through a website right now.</p>\n<h3>Selecting Features</h3>\n<p>To select a map feature, like a road or point of interest, simply single-click\non it on the map. This will highlight the selected feature, show a panel of\ndetails, and also show a menu of things you can do with the feature.</p>\n<p>Multiple features can be selected by holding the &#39;Shift&#39; key, clicking,\nand dragging on the map. This will select all features within the box\nthat&#39;s drawn, and you can do certain &#39;batch operations&#39; on all features.</p>\n<h3>Saving Edits</h3>\n<p>When you create changes, like editing roads, buildings, and places, these are\nstored locally until you save them to the server. Don&#39;t worry if you make\na mistake - you can undo changes by clicking the undo button, and redo\nchanges by clicking the redo button.</p>\n<p>Click &#39;Save&#39; to finish a group of edits - for instance, if you&#39;ve completed\nan area of town and would like to start on a new area. You&#39;ll have a chance\nto review what you&#39;ve done, and the editor supplies helpful suggestions\nand warnings if something doesn&#39;t seem right about the changes.</p>\n<p>Clicking &#39;Save&#39; again, on the new dialog, will post the changes\nto <a href=\"http://www.openstreetmap.org/\">OpenStreetMap.org</a>, where they are visible\nto all other users and available for others to build and improve upon.</p>\n<p>If you can&#39;t finish your edits in one sitting, you can leave the editor\nwindow and come back (on the same browser and computer), and the\neditor application will offer to restore your work.</p>\n",
"title": "Editing & Saving"
},
{
"html": "<p>You can create, fix, and delete roads with this editor. Roads can be all\nkinds: paths, highways, trails, cycleways, and more - any often-crossed\nsegment should be mappable.</p>\n<h3>Selecting</h3>\n<p>Click on a road to select it. An outline should become visible, along\nwith a small tools menu on the map and a sidebar showing more information\nabout the road.</p>\n<h3>Modifying</h3>\n<p>Often you&#39;ll see roads that aren&#39;t aligned to the imagery behind them\nor a GPS track.</p>\n<p>First click on the road you want to change. This will highlight it and show\n&#39;control points along it&#39; that you can drag to better locations. If\nyou want to add new control points for more detail, double-click a part\nof the road without a point, and one will be added.</p>\n<p>If the road connects to another road, but doesn&#39;t properly connect on\nthe map, you can drag one of its control points onto the other road in\norder to join them. Having roads connect is important for the map\nand essential for providing driving directions.</p>\n<p>You can also click the &#39;Move&#39; tool or type <code>M</code> to move the entire road at\none time, and then click again to save that movement.</p>\n<h3>Deleting</h3>\n<p>If a road is entirely incorrect - you can see that it doesn&#39;t exist in satellite\nimagery and ideally have confirmed locally that it&#39;s not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the road could simply be newly built.</p>\n<p>You can delete a road by clicking on it to select it, then clicking the\ntrash can icon or pressing the &#39;Delete&#39; key.</p>\n<h3>Creating</h3>\n<p>Found somewhere there should be a road but there isn&#39;t? Click the &#39;Line&#39;\nicon in the top-left of the editor or press the key &#39;2&#39; to start drawing\na line.</p>\n<p>Click on the start of the road on the map to start drawing. If the road\nconnects to another road, first, click on the place where they connect.</p>\n<p>Then click on points along the road so that it follows the right path, according\nto satellite imagery or GPS. When you&#39;re done drawing the road, double-click\nor press &#39;Return&#39; or &#39;Enter&#39; on your keyboard.</p>\n",
"title": "Roads"
},
{
"html": "<p>GPS data is the most trusted source of data for OpenStreetMap. This editor\nsupports local traces - <code>.gpx</code> files on your local computer. You can collect\nthis kind of GPS trace with a number of smartphone applications as well as\npersonal GPS hardware.</p>\n<p>For information on how to perform a GPS survey, read\n<a href=\"http://learnosm.org/en/beginner/using-gps/\">Surveying with a GPS</a>.</p>\n<p>To use a GPX track for mapping, drag and drop the GPX file onto the map map\neditor. If it&#39;s recognized, it will be added to the map as a bright green\nline. Click on the &#39;Background Settings&#39; menu on the left side to enable,\ndisable, or zoom to this new GPX-powered layer.</p>\n<p>The GPX track isn&#39;t directly uploaded to OpenStreetMap - the best way to\nuse it is to draw on the map, using it as a guide for the new features that\nyou add.</p>\n",
"title": "GPS"
},
{
"html": "<p>Aerial imagery is an important resource for mapping. A combination of\nairplane flyovers, satellite views, and freely-compiled sources are available\nin the editor under the &#39;Background Settings&#39; menu on the left.</p>\n<p>By default a <a href=\"http://www.bing.com/maps/\">Bing Maps</a> satellite layer is\npresented in the editor, but as you pan and zoom the map to new geographical\nareas, new sources will become available. Some countries, like the United\nStates, France, and Denmark have very high-resolution, high-quality imagery\navailable for smaller geographical coverages.</p>\n<p>Imagery is sometimes offset from the map data because of a mistake on the\nimagery provider&#39;s side - so if you see many roads shifted from the background,\ndon&#39;t immediately go to move them all. You can set an offset for imagery\nby clicking &#39;Fix alignment&#39; at the bottom of the bottom of the Background\nSettings UI.</p>\n",
"title": "Imagery"
},
{
"html": "<p>Addresses are some of the most useful information for the map.</p>\n<p>Although addresses are often represented as parts of streets, in OpenStreetMap\nthey&#39;re recorded as attributes of buildings and places along streets.</p>\n<p>You can add address information to places mapped as building outlines as well\nas well as those mapped as single points. The optimal source of address\ndata is from an on-the-ground survey or personal knowledge - as with any\nother feature, copying from commercial sources like Google Maps is strictly\nforbidden.</p>\n",
"title": "Addresses"
},
{
"html": "<p>The inspector is the user interface element on the right-hand side of the\npage that appears when an element is selected and allows to edit its details.</p>\n<h3>Selecting a Preset</h3>\n<p>The inspector has two modes: the first allows you to pick a preset, or\npredetermined selection of forms and tags.</p>\n<p>Click the &#39;i&#39; in the bottom-right-hand corner of a preset option to learn\nmore about it. Click a preset to choose it.</p>\n<h3>Using Forms and Editing Tags</h3>\n<p>The second allows you to edit the\nattributes of a map element using those forms and tags.</p>\n<p>Below the forms you see, you can click icons to add more easy-to-use forms,\nlike <a href=\"http://www.wikipedia.org/\">Wikipedia</a> information, wheelchair\naccess, and more.</p>\n<p>At the bottom of the inspector, click &#39;Additional tags&#39; to add arbitrary\nother tags to the element. <a href=\"http://taginfo.openstreetmap.org/\">Taginfo</a> is a\ngreat resource for learn more about popular tag combinations.</p>\n<p>Changes you make in the inspector are automatically applied to the map.\nYou can undo them at any time by clicking the Undo button.</p>\n<h3>Closing the Inspector</h3>\n<p>You can close the inspector by either clicking the close button in the top-right,\npressing the &#39;Escape&#39; key, or clicking on the map.</p>\n",
"title": "Using the Inspector"
},
{
"html": "<p>OpenStreetMap is the world&#39;s largest database of buildings. You can create\nand improve this database.</p>\n<h3>Selecting</h3>\n<p>You can select a building by clicking on its border. This will highlight the\nbuilding and open a small tools menu and a sidebar showing more information\nabout the building.</p>\n<h3>Modifying</h3>\n<p>Sometimes buildings are incorrectly placed or have incorrect tags.</p>\n<p>To move an entire building, select it, then click the &#39;Move&#39; tool. Move your\nmouse to shift the building, and click when it&#39;s correctly placed.</p>\n<p>To fix the specific shape of a building, click and drag the points that form\nits border into better places.</p>\n<h3>Creating</h3>\n<p>One of the main questions around adding buildings to the map is that\nOpenStreetMap records buildings both as shapes and points. The rule of thumb\nis to <em>map a building as a shape whenever possible</em>, and map companies, homes,\namenities, and other things that operate out of buildings as points placed\nwithin the building shape.</p>\n<p>Start drawing a building as a shape by clicking the &#39;Area&#39; button in the top\nleft of the interface, and end it either by pressing &#39;Return&#39; on your keyboard\nor clicking on the first point drawn to close the shape.</p>\n<h3>Deleting</h3>\n<p>If a building is entirely incorrect - you can see that it doesn&#39;t exist in satellite\nimagery and ideally have confirmed locally that it&#39;s not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the road could simply be newly built.</p>\n<p>You can delete a building by clicking on it to select it, then clicking the\ntrash can icon or pressing the &#39;Delete&#39; key.</p>\n",
"title": "Buildings"
}
]
+13
View File
@@ -0,0 +1,13 @@
# Help
This is an editor for [OpenStreetMap](http://www.openstreetmap.org/), the
free and editable map of the world. You can use it to fix and update
data in your area, making an open-source and open-data map of the world
better for everyone.
Edits that you make on this map will be visible to everyone who uses
OpenStreetMap. In order to make an edit, you'll need a
[free OpenStreetMap account](https://www.openstreetmap.org/user/new).
[iD Editor](http://ideditor.com/) is a collaborative project with [source
code available on GitHub](https://github.com/systemed/iD).
+34
View File
@@ -0,0 +1,34 @@
# Editing & Saving
This editor is designed to work primarily online, and you're accessing
it through a website right now.
### Selecting Features
To select a map feature, like a road or point of interest, simply single-click
on it on the map. This will highlight the selected feature, show a panel of
details, and also show a menu of things you can do with the feature.
Multiple features can be selected by holding the 'Shift' key, clicking,
and dragging on the map. This will select all features within the box
that's drawn, and you can do certain 'batch operations' on all features.
### Saving Edits
When you create changes, like editing roads, buildings, and places, these are
stored locally until you save them to the server. Don't worry if you make
a mistake - you can undo changes by clicking the undo button, and redo
changes by clicking the redo button.
Click 'Save' to finish a group of edits - for instance, if you've completed
an area of town and would like to start on a new area. You'll have a chance
to review what you've done, and the editor supplies helpful suggestions
and warnings if something doesn't seem right about the changes.
Clicking 'Save' again, on the new dialog, will post the changes
to [OpenStreetMap.org](http://www.openstreetmap.org/), where they are visible
to all other users and available for others to build and improve upon.
If you can't finish your edits in one sitting, you can leave the editor
window and come back (on the same browser and computer), and the
editor application will offer to restore your work.
+53
View File
@@ -0,0 +1,53 @@
# Roads
You can create, fix, and delete roads with this editor. Roads can be all
kinds: paths, highways, trails, cycleways, and more - any often-crossed
segment should be mappable.
### Selecting
Click on a road to select it. An outline should become visible, along
with a small tools menu on the map and a sidebar showing more information
about the road.
### Modifying
Often you'll see roads that aren't aligned to the imagery behind them
or a GPS track.
First click on the road you want to change. This will highlight it and show
'control points along it' that you can drag to better locations. If
you want to add new control points for more detail, double-click a part
of the road without a point, and one will be added.
If the road connects to another road, but doesn't properly connect on
the map, you can drag one of its control points onto the other road in
order to join them. Having roads connect is important for the map
and essential for providing driving directions.
You can also click the 'Move' tool or type `M` to move the entire road at
one time, and then click again to save that movement.
### Deleting
If a road is entirely incorrect - you can see that it doesn't exist in satellite
imagery and ideally have confirmed locally that it's not present - you can delete
it, which removes it from the map. Be cautious when deleting features -
like any other edit, the results are seen by everyone and satellite imagery
is often out of date, so the road could simply be newly built.
You can delete a road by clicking on it to select it, then clicking the
trash can icon or pressing the 'Delete' key.
### Creating
Found somewhere there should be a road but there isn't? Click the 'Line'
icon in the top-left of the editor or press the key '2' to start drawing
a line.
Click on the start of the road on the map to start drawing. If the road
connects to another road, first, click on the place where they connect.
Then click on points along the road so that it follows the right path, according
to satellite imagery or GPS. When you're done drawing the road, double-click
or press 'Return' or 'Enter' on your keyboard.
+18
View File
@@ -0,0 +1,18 @@
# GPS
GPS data is the most trusted source of data for OpenStreetMap. This editor
supports local traces - `.gpx` files on your local computer. You can collect
this kind of GPS trace with a number of smartphone applications as well as
personal GPS hardware.
For information on how to perform a GPS survey, read
[Surveying with a GPS](http://learnosm.org/en/beginner/using-gps/).
To use a GPX track for mapping, drag and drop the GPX file onto the map map
editor. If it's recognized, it will be added to the map as a bright green
line. Click on the 'Background Settings' menu on the left side to enable,
disable, or zoom to this new GPX-powered layer.
The GPX track isn't directly uploaded to OpenStreetMap - the best way to
use it is to draw on the map, using it as a guide for the new features that
you add.
+17
View File
@@ -0,0 +1,17 @@
# Imagery
Aerial imagery is an important resource for mapping. A combination of
airplane flyovers, satellite views, and freely-compiled sources are available
in the editor under the 'Background Settings' menu on the left.
By default a [Bing Maps](http://www.bing.com/maps/) satellite layer is
presented in the editor, but as you pan and zoom the map to new geographical
areas, new sources will become available. Some countries, like the United
States, France, and Denmark have very high-resolution, high-quality imagery
available for smaller geographical coverages.
Imagery is sometimes offset from the map data because of a mistake on the
imagery provider's side - so if you see many roads shifted from the background,
don't immediately go to move them all. You can set an offset for imagery
by clicking 'Fix alignment' at the bottom of the bottom of the Background
Settings UI.
+12
View File
@@ -0,0 +1,12 @@
# Addresses
Addresses are some of the most useful information for the map.
Although addresses are often represented as parts of streets, in OpenStreetMap
they're recorded as attributes of buildings and places along streets.
You can add address information to places mapped as building outlines as well
as well as those mapped as single points. The optimal source of address
data is from an on-the-ground survey or personal knowledge - as with any
other feature, copying from commercial sources like Google Maps is strictly
forbidden.
+33
View File
@@ -0,0 +1,33 @@
# Using the Inspector
The inspector is the user interface element on the right-hand side of the
page that appears when an element is selected and allows to edit its details.
### Selecting a Preset
The inspector has two modes: the first allows you to pick a preset, or
predetermined selection of forms and tags.
Click the 'i' in the bottom-right-hand corner of a preset option to learn
more about it. Click a preset to choose it.
### Using Forms and Editing Tags
The second allows you to edit the
attributes of a map element using those forms and tags.
Below the forms you see, you can click icons to add more easy-to-use forms,
like [Wikipedia](http://www.wikipedia.org/) information, wheelchair
access, and more.
At the bottom of the inspector, click 'Additional tags' to add arbitrary
other tags to the element. [Taginfo](http://taginfo.openstreetmap.org/) is a
great resource for learn more about popular tag combinations.
Changes you make in the inspector are automatically applied to the map.
You can undo them at any time by clicking the Undo button.
### Closing the Inspector
You can close the inspector by either clicking the close button in the top-right,
pressing the 'Escape' key, or clicking on the map.
+43
View File
@@ -0,0 +1,43 @@
# Buildings
OpenStreetMap is the world's largest database of buildings. You can create
and improve this database.
### Selecting
You can select a building by clicking on its border. This will highlight the
building and open a small tools menu and a sidebar showing more information
about the building.
### Modifying
Sometimes buildings are incorrectly placed or have incorrect tags.
To move an entire building, select it, then click the 'Move' tool. Move your
mouse to shift the building, and click when it's correctly placed.
To fix the specific shape of a building, click and drag the points that form
its border into better places.
### Creating
One of the main questions around adding buildings to the map is that
OpenStreetMap records buildings both as shapes and points. The rule of thumb
is to _map a building as a shape whenever possible_, and map companies, homes,
amenities, and other things that operate out of buildings as points placed
within the building shape.
Start drawing a building as a shape by clicking the 'Area' button in the top
left of the interface, and end it either by pressing 'Return' on your keyboard
or clicking on the first point drawn to close the shape.
### Deleting
If a building is entirely incorrect - you can see that it doesn't exist in satellite
imagery and ideally have confirmed locally that it's not present - you can delete
it, which removes it from the map. Be cautious when deleting features -
like any other edit, the results are seen by everyone and satellite imagery
is often out of date, so the road could simply be newly built.
You can delete a building by clicking on it to select it, then clicking the
trash can icon or pressing the 'Delete' key.
+533 -69
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -372,6 +372,7 @@
"key": "website",
"type": "url",
"icon": "website",
"placeholder": "http://example.com/",
"universal": true,
"label": "Website"
},
+2 -1
View File
@@ -2,6 +2,7 @@
"key": "website",
"type": "url",
"icon": "website",
"placeholder": "http://example.com/",
"universal": true,
"label": "Website"
}
}
+4 -1
View File
@@ -59,9 +59,12 @@
"icon": {
"type": "string"
},
"placeholder": {
"type": "string"
},
"strings": {
"type": "object"
}
},
"additionalProperties": false
}
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

+65 -18
View File
@@ -9,7 +9,7 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="460"
width="500"
height="320"
id="svg12393"
version="1.1"
@@ -39,8 +39,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="237.92081"
inkscape:cy="230.70164"
inkscape:cx="319.99979"
inkscape:cy="247.06899"
inkscape:document-units="px"
inkscape:current-layer="layer12"
showgrid="false"
@@ -53,10 +53,11 @@
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:snap-nodes="false">
inkscape:snap-nodes="true"
inkscape:snap-global="true">
<inkscape:grid
type="xygrid"
id="grid12420"
@@ -192,6 +193,18 @@
orientation="1,0"
position="460,320"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="401,270"
id="guide6083" />
<sodipodi:guide
orientation="1,0"
position="460,310"
id="guide6106" />
<sodipodi:guide
orientation="1,0"
position="480,345"
id="guide3361" />
</sodipodi:namedview>
<metadata
id="metadata12398">
@@ -201,7 +214,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>
@@ -214,8 +227,8 @@
<rect
style="color:#000000;fill:#323232;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4478"
width="440"
height="200"
width="500"
height="310"
x="25"
y="62.362183" />
</g>
@@ -351,14 +364,9 @@
id="path3769"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 255,3.9999969 -1,1 0,1 1,1 1,0 1,-1 0,-1 -1,-1 -1,0 z m 0,4 -1,1 0,5.0000001 1,1 1,0 1,-1 0,-5.0000001 -1,-1 -1,0 z"
id="path10936"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 113,2.01282 -5,4.5 5,4.5 0,-3 3,0 L 117,9 117,12.01282 116,13 l -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
d="m 114,2.01282 -5,4.5 5,4.5 0,-3 3,0 L 118,9 118,12.01282 117,13 l -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
id="path2997"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccc"
@@ -671,7 +679,7 @@
inkscape:connector-curvature="0" />
<path
style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 113,42.01282 -5,4.5 5,4.5 0,-3 3,0 1,0.98718 0,3.01282 -1,0.98718 -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
d="m 114,42.01282 -5,4.5 5,4.5 0,-3 3,0 1,0.98718 0,3.01282 -1,0.98718 -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
id="path16239"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccc"
@@ -835,7 +843,7 @@
sodipodi:nodetypes="cccccccccccccccccccccc"
inkscape:connector-curvature="0"
id="path33325"
d="m 113,22.01282 -5,4.5 5,4.5 0,-3 3,0 1,0.98718 0,3.01282 -1,0.98718 -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
d="m 114,22.01282 -5,4.5 5,4.5 0,-3 3,0 1,0.98718 0,3.01282 -1,0.98718 -5,0.0128 -1,1.00002 0,1 1,0.99998 5,0 2,-0.99998 1,-1 1,-2.00002 0,-3 -1,-1.99998 -1,-1 -2,-1.00002 -3,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -1190,9 +1198,9 @@
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect10175"
width="460"
width="500"
height="320"
x="-485"
x="-525"
y="-3.0624999e-06"
transform="scale(-1,1)" />
<path
@@ -2059,5 +2067,44 @@
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
<g
id="g3815"
transform="translate(0,50)"
style="fill:#1a1a1a;fill-opacity:1">
<path
style="color:#000000;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 464 2 L 463 3 L 463 16 L 464 17 L 475 17 L 476 16 L 476 6 L 472 6 L 472 12 L 469.5 10.5 L 467 12 L 467 6 L 465 6 L 465 5 L 465 4 L 476 4 L 476 3 L 476 2 L 464 2 z "
transform="translate(25,-50.000003)"
id="path3648" />
</g>
<g
transform="translate(0,70)"
id="g3822">
<path
id="path3824"
transform="translate(25,-50.000003)"
d="m 464,2 -1,1 0,13 1,1 11,0 1,-1 0,-10 -4,0 0,6 -2.5,-1.5 -2.5,1.5 0,-6 -2,0 0,-1 0,-1 11,0 0,-1 0,-1 -12,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3837"
transform="translate(-1,0)" />
<g
id="g3842"
transform="translate(0,20)"
style="fill:#ffffff" />
<path
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 251,4.9999969 1.125,-1 6.75,0 1.125,1 0,10.0000001 -1.125,1 -3.375,-2.886751 -3.375,2.886751 -1.125,-1 z"
id="path3854"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
<path
sodipodi:nodetypes="cccccccccc"
inkscape:connector-curvature="0"
id="path3874"
d="m 251,24.999997 1.125,-1 6.75,0 1.125,1 0,10 -1.125,1 -3.375,-2.886751 -3.375,2.886751 -1.125,-1 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 136 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+2 -1
View File
@@ -23,6 +23,7 @@
<script src='js/lib/d3.geo.tile.js'></script>
<script src='js/lib/d3.size.js'></script>
<script src='js/lib/d3.trigger.js'></script>
<script src='js/lib/d3.jsonp.js'></script>
<script src='js/lib/d3.keybinding.js'></script>
<script src='js/lib/d3.curtain.js'></script>
<script src='js/lib/d3.one.js'></script>
@@ -73,6 +74,7 @@
<script src='js/id/ui/modes.js'></script>
<script src='js/id/ui/contributors.js'></script>
<script src='js/id/ui/geocoder.js'></script>
<script src='js/id/ui/help.js'></script>
<script src='js/id/ui/geolocate.js'></script>
<script src='js/id/ui/notice.js'></script>
<script src='js/id/ui/flash.js'></script>
@@ -81,7 +83,6 @@
<script src='js/id/ui/spinner.js'></script>
<script src='js/id/ui/restore.js'></script>
<script src='js/id/ui/tag_reference.js'></script>
<script src='js/id/ui/key_reference.js'></script>
<script src='js/id/ui/preset.js'></script>
<script src='js/id/ui/lasso.js'></script>
<script src='js/id/ui/source_switch.js'></script>
+53 -27
View File
@@ -6,34 +6,54 @@ iD.actions.Orthogonalize = function(wayId, projection) {
var action = function(graph) {
var way = graph.entity(wayId),
nodes = graph.childNodes(way),
points = nodes.map(function(n) { return projection(n.loc); }),
best, i, j;
corner = {i: 0, dotp: 1},
points, i, j, score, motions;
var score = squareness();
for (i = 0; i < 1000; i++) {
var motions = points.map(stepMap);
for (j = 0; j < motions.length; j++) {
points[j] = addPoints(points[j],motions[j]);
}
var newScore = squareness();
if (newScore < score) {
best = _.clone(points);
score = newScore;
}
if (score < 1.0e-8) {
break;
}
}
points = best;
if (nodes.length === 4) {
points = _.uniq(nodes).map(function(n) { return projection(n.loc); });
for (i = 0; i < points.length - 1; i++) {
graph = graph.replace(graph.entity(nodes[i].id)
.move(projection.invert(points[i])));
for (i = 0; i < 1000; i++) {
motions = points.map(calcMotion);
points[corner.i] = addPoints(points[corner.i],motions[corner.i]);
score = corner.dotp;
if (score < 1.0e-8) {
break;
}
}
graph = graph.replace(graph.entity(nodes[corner.i].id)
.move(projection.invert(points[corner.i])));
} else {
var best;
points = nodes.map(function(n) { return projection(n.loc); });
score = squareness();
for (i = 0; i < 1000; i++) {
motions = points.map(calcMotion);
for (j = 0; j < motions.length; j++) {
points[j] = addPoints(points[j],motions[j]);
}
var newScore = squareness();
if (newScore < score) {
best = _.clone(points);
score = newScore;
}
if (score < 1.0e-8) {
break;
}
}
points = best;
for (i = 0; i < points.length - 1; i++) {
graph = graph.replace(graph.entity(nodes[i].id)
.move(projection.invert(points[i])));
}
}
return graph;
function stepMap(b, i, array) {
function calcMotion(b, i, array) {
var a = array[(i - 1 + array.length) % array.length],
c = array[(i + 1) % array.length],
p = subtractPoints(a, b),
@@ -44,9 +64,15 @@ iD.actions.Orthogonalize = function(wayId, projection) {
q = normalizePoint(q, 1.0);
var dotp = p[0] * q[0] + p[1] * q[1];
// nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
if (dotp < -0.707106781186547) {
dotp += 1.0;
if (array.length > 3) {
if (dotp < -0.707106781186547) {
dotp += 1.0;
}
} else if (Math.abs(dotp) < corner.dotp) {
corner.i = i;
corner.dotp = Math.abs(dotp);
}
return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
@@ -86,7 +112,7 @@ iD.actions.Orthogonalize = function(wayId, projection) {
return [a[0] + b[0], a[1] + b[1]];
}
function normalizePoint(point, thickness) {
function normalizePoint(point, scale) {
var vector = [0, 0];
var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
if (length !== 0) {
@@ -94,8 +120,8 @@ iD.actions.Orthogonalize = function(wayId, projection) {
vector[1] = point[1] / length;
}
vector[0] *= thickness;
vector[1] *= thickness;
vector[0] *= scale;
vector[1] *= scale;
return vector;
}
+7 -1
View File
@@ -102,7 +102,13 @@ window.iD = function () {
context.zoomOut = map.zoomOut;
/* Background */
var backgroundSources = iD.data.imagery.map(iD.BackgroundSource.template);
var backgroundSources = iD.data.imagery.map(function(source) {
if (source.sourcetag === 'Bing') {
return iD.BackgroundSource.Bing(source, context.background().dispatch);
} else {
return iD.BackgroundSource.template(source);
}
});
backgroundSources.push(iD.BackgroundSource.Custom);
context.backgroundSources = function() {
+1
View File
@@ -4,6 +4,7 @@ iD.operations.Disconnect = function(selection, context) {
var operation = function() {
context.perform(action, t('operations.disconnect.annotation'));
context.enter(iD.modes.Browse(context));
};
operation.available = function() {
+1 -1
View File
@@ -10,7 +10,7 @@ iD.operations.Orthogonalize = function(selection, context) {
operation.available = function() {
return selection.length === 1 &&
context.entity(entityId).type === 'way' &&
_.uniq(context.entity(entityId).nodes).length > 3;
_.uniq(context.entity(entityId).nodes).length > 2;
};
operation.enabled = function() {
+4 -1
View File
@@ -168,14 +168,17 @@ iD.Background = function() {
}
}
background.dispatch = d3.dispatch('change');
background.source = function(_) {
if (!arguments.length) return source;
source = _;
cache = {};
tile.scaleExtent((source.data && source.data.scaleExtent) || [1, 20]);
setHash(source);
background.dispatch.change();
return background;
};
return background;
return d3.rebind(background, background.dispatch, 'on');
};
+44 -1
View File
@@ -29,12 +29,55 @@ iD.BackgroundSource.template = function(data) {
}
generator.data = data;
generator.copyrightNotices = function() {};
return generator;
};
iD.BackgroundSource.Bing = function(data, dispatch) {
// http://msdn.microsoft.com/en-us/library/ff701716.aspx
// http://msdn.microsoft.com/en-us/library/ff701701.aspx
var bing = iD.BackgroundSource.template(data),
key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
url = 'http://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
key + '&jsonp={callback}',
providers = [];
d3.jsonp(url, function(json) {
providers = json.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
return {
attribution: provider.attribution,
areas: provider.coverageAreas.map(function(area) {
return {
zoom: [area.zoomMin, area.zoomMax],
extent: iD.geo.Extent([area.bbox[1], area.bbox[0]], [area.bbox[3], area.bbox[2]])
};
})
};
});
dispatch.change();
});
bing.copyrightNotices = function(zoom, extent) {
zoom = Math.min(zoom, 21);
return providers.filter(function(provider) {
return _.any(provider.areas, function(area) {
return extent.intersects(area.extent) &&
area.zoom[0] <= zoom &&
area.zoom[1] >= zoom;
});
}).map(function(provider) {
return provider.attribution;
}).join(', ');
};
return bing;
};
iD.BackgroundSource.Custom = function() {
var template = window.prompt('Enter a tile template. Valid tokens are {z}, {x}, {y} for Z/X/Y scheme and {u} for quadtile scheme.');
var template = window.prompt('Enter a tile template. ' +
'Valid tokens are {z}, {x}, {y} for Z/X/Y scheme and {u} for quadtile scheme.');
if (!template) return null;
return iD.BackgroundSource.template({
template: template,
+18 -20
View File
@@ -5,6 +5,17 @@ iD.svg.Surface = function() {
});
}
function autosize(image) {
var img = document.createElement('img');
img.src = image.attr('xlink:href');
img.onload = function() {
image.attr({
width: img.width,
height: img.height
});
};
}
function sprites(stylesheetName, selectorRegexp) {
var sprites = [];
@@ -90,12 +101,9 @@ iD.svg.Surface = function() {
.attr('height', function(d) { return d; });
defs.append('image')
.attr({
id: 'sprite',
width: 460,
height: 320,
'xlink:href': 'img/sprite.png'
});
.attr('id', 'sprite')
.attr('xlink:href', 'img/sprite.png')
.call(autosize);
defs.selectAll()
.data(sprites("app.css", /^\.(icon-operation-[a-z0-9-]+)$/))
@@ -104,20 +112,10 @@ iD.svg.Surface = function() {
.attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr('xlink:href', '#sprite');
var image = defs.append('image')
.attr({
id: 'maki-sprite',
'xlink:href': 'img/feature-icons.png'
});
var img = document.createElement('img');
img.src = 'img/feature-icons.png';
img.onload = function() {
image.attr({
width: img.width,
height: img.height
});
};
defs.append('image')
.attr('id', 'maki-sprite')
.attr('xlink:href', 'img/feature-icons.png')
.call(autosize);
defs.selectAll()
.data(sprites("feature-icons.css", /^\.(feature-[a-z0-9-]+-(12|18))$/))
+2 -2
View File
@@ -69,13 +69,13 @@ iD.svg.Vertices = function(projection, context) {
groups.select('circle.shadow')
.each(center)
.attr('r', function(entity) {
return radiuses.shadow[icon(entity) ? 3 : zoom]
return radiuses.shadow[icon(entity) ? 3 : zoom];
});
groups.select('circle.stroke')
.each(center)
.attr('r', function(entity) {
return radiuses.stroke[icon(entity) ? 3 : zoom]
return radiuses.stroke[icon(entity) ? 3 : zoom];
});
// Each vertex gets either a circle or a use, depending
+13 -6
View File
@@ -52,6 +52,10 @@ iD.ui = function(context) {
.attr('class', 'spinner')
.call(iD.ui.Spinner(context));
container.append('div')
.style('display', 'none')
.attr('class', 'help-wrap fillL col5');
container.append('div')
.attr('class', 'map-control zoombuttons')
.call(iD.ui.Zoom(context));
@@ -68,10 +72,19 @@ iD.ui = function(context) {
.attr('class', 'map-control geolocate-control')
.call(iD.ui.Geolocate(map));
container.append('div')
.attr('class', 'map-control help-control')
.call(iD.ui.Help(context));
container.append('div')
.style('display', 'none')
.attr('class', 'inspector-wrap fr content col4');
container.append('idv')
.attr('class', 'attribution')
.attr('tabindex', -1)
.call(iD.ui.Attribution(context));
var about = container.append('div')
.attr('class','col12 about-block fillD');
@@ -97,12 +110,6 @@ iD.ui = function(context) {
.attr('href', 'https://help.openstreetmap.org/questions/ask/')
.text(t('report_a_bug'));
linkList.append('li')
.attr('class', 'attribution')
.attr('tabindex', -1)
.data([context.background().source()])
.call(iD.ui.Attribution(context));
linkList.append('li')
.attr('class', 'source-switch')
.call(iD.ui.SourceSwitch(context));
+29 -9
View File
@@ -1,6 +1,8 @@
iD.ui.Attribution = function(context) {
return function attribution(selection) {
var d = selection.data()[0];
var selection;
function update() {
var d = context.background().source();
var provided_by = selection
.html('')
@@ -9,18 +11,36 @@ iD.ui.Attribution = function(context) {
if (!d) return;
var desc = t('imagery.provided_by', {
source: (d.data.sourcetag || d.data.name)
});
var source = d.data.sourcetag || d.data.name;
if (d.data.logo) {
source = '<img class="source-image" src="img/' + d.data.logo + '">';
}
if (d.data.terms_url) {
provided_by.append('a')
.attr('href', (d.data.terms_url || ''))
.attr('href', d.data.terms_url)
.attr('target', '_blank')
.classed('disabled', !d.data.terms_url)
.text(desc);
.html(source);
} else {
provided_by.text(desc);
provided_by.text(source);
}
var copyright = d.copyrightNotices(context.map().zoom(), context.map().extent());
if (copyright) {
provided_by.append('span')
.text(copyright);
}
}
return function(select) {
selection = select;
context.background()
.on('change.attribution', update);
context.map()
.on('move.attribution', _.throttle(update, 400));
update();
};
};
+5 -11
View File
@@ -1,6 +1,5 @@
iD.ui.Background = function(context) {
var event = d3.dispatch('cancel', 'save'),
key = 'b',
var key = 'b',
opacities = [1, 0.5, 0],
directions = [
['left', [1, 0]],
@@ -57,16 +56,11 @@ iD.ui.Background = function(context) {
}
}
function selectLayer(d) {
function selectLayer() {
content.selectAll('a.layer')
.classed('selected', function(d) {
return d.data.name === context.background().source().data.name;
});
context.container()
.select('.attribution')
.data([d])
.call(iD.ui.Attribution(context));
}
function clickSetSource(d) {
@@ -85,7 +79,7 @@ iD.ui.Background = function(context) {
.imagery_used(d.data.sourcetag || d.data.name);
}
context.redraw();
selectLayer(d);
selectLayer();
}
function clickGpx(d) {
@@ -139,7 +133,7 @@ iD.ui.Background = function(context) {
layerLinks.exit()
.remove();
selectLayer(context.background().source());
selectLayer();
}
function clickNudge(d) {
@@ -289,5 +283,5 @@ iD.ui.Background = function(context) {
.call(keybinding);
}
return d3.rebind(background, event, 'on');
return background;
};
+3 -3
View File
@@ -36,10 +36,10 @@ iD.ui.Commit = function(context) {
// Comment Section
var commentSection = body.append('div')
.attr('class', 'modal-section preset-field');
.attr('class', 'modal-section form-field');
commentSection.append('h4')
.attr('for','input-commit-note')
commentSection.append('label')
.attr('class','form-label')
.text(t('commit.message_label'));
var commentField = commentSection
+4
View File
@@ -82,6 +82,10 @@ iD.ui.Geocoder = function(context) {
gcForm.call(iD.ui.Toggle(show));
if (!show && !resultsList.classed('hide')) {
resultsList.call(iD.ui.Toggle(show));
// remove results so that they lose focus. if the user has
// tabbed into the list, then they will have focus still,
// even if they're hidden.
resultsList.selectAll('span').remove();
}
if (show) inputNode.node().focus();
else inputNode.node().blur();
+109
View File
@@ -0,0 +1,109 @@
iD.ui.Help = function(context) {
var key = 'h';
function help(selection) {
var shown = false, pane;
function setup() {
pane = context.container()
.select('.help-wrap')
.html('');
var toc = pane.append('ul')
.attr('class', 'toc');
function clickHelp(d) {
doctitle.text(d.title);
body.html(d.html);
body.selectAll('a')
.attr('target', '_blank');
menuItems.classed('selected', function(m) {
return m.title === d.title;
});
}
var menuItems = toc.selectAll('li')
.data(iD.data.doc)
.enter()
.append('li')
.append('a')
.text(function(d) { return d.title; })
.on('click', clickHelp);
var content = pane.append('div')
.attr('class', 'left-content'),
doctitle = content.append('h2')
.text(t('help.title')),
body = content.append('div')
.attr('class', 'body');
clickHelp(iD.data.doc[0]);
}
function hide() { setVisible(false); }
function toggle() {
if (d3.event) d3.event.preventDefault();
tooltip.hide(button);
setVisible(!button.classed('active'));
}
function blockClick() {
pane.on('mousedown.help-inside', function() {
return d3.event.stopPropagation();
});
selection.on('mousedown.help-inside', function() {
return d3.event.stopPropagation();
});
}
function setVisible(show) {
if (show !== shown) {
button.classed('active', show);
shown = show;
if (show) {
pane.style('display', 'block')
.style('left', '-500px')
.transition()
.duration(200)
.style('left', '0px')
.each('end', blockClick);
} else {
pane.style('left', '0px')
.transition()
.duration(200)
.style('left', '-500px')
.each('end', function() {
d3.select(this).style('display', 'none');
});
pane.on('mousedown.help-inside', null);
}
}
}
var tooltip = bootstrap.tooltip()
.placement('right')
.html(true)
.title(iD.ui.tooltipHtml(t('help.title'), key));
var button = selection.append('button')
.attr('tabindex', -1)
.on('click', toggle)
.call(tooltip);
button.append('span')
.attr('class', 'icon help light');
context.surface().on('mousedown.help-outside', hide);
context.container().on('mousedown.b.help-outside', hide);
setup();
var keybinding = d3.keybinding('help');
keybinding.on(key, toggle);
d3.select(document).call(keybinding);
}
return help;
};
+2 -1
View File
@@ -2,7 +2,8 @@ iD.ui.Inspector = function(context, entity) {
var tagEditor;
function changeTags(tags) {
if (!_.isEqual(entity.tags, tags)) {
entity = context.entity(entity.id);
if (entity && !_.isEqual(entity.tags, tags)) {
context.perform(
iD.actions.ChangeTags(entity.id, tags),
t('operations.change_tags.annotation'));
-37
View File
@@ -1,37 +0,0 @@
iD.ui.keyReference = function(selection) {
selection.each(function() {
var selection = d3.select(this),
data = selection.datum(),
header = selection.append('div')
.attr('class','modal-section fillL')
.append('h2'),
body = selection.append('div')
.attr('class', 'modal-section fillL2');
header.append('span').attr('class', 'icon big icon-pre-text big-' + data.geometry);
header.append('span').text(data.title);
body.append('h3').text('Common Values');
var table = body.append('table')
.attr('class', 'tags'),
thead = table.append('thead');
thead.append('th').text('Value');
thead.append('th').text('Description');
thead.append('th').text('Count');
var rows = table.selectAll('tr')
.data(data.data)
.enter()
.append('tr');
var cols = rows.selectAll('td')
.data(function(d) {
return [d.value, d.description || "", d.count];
})
.enter()
.append('td')
.text(String);
});
};
+187 -94
View File
@@ -1,109 +1,212 @@
iD.ui.preset = function(context, entity) {
var event = d3.dispatch('change', 'setTags', 'close'),
tags,
keys,
preset,
iD.ui.preset = function(context, entity, preset) {
var original = context.graph().base().entities[entity.id],
event = d3.dispatch('change', 'close'),
fields = [],
tags = {},
formwrap,
formbuttonwrap;
function presets(selection) {
selection.html('');
function UIField(field, show) {
field = _.clone(field);
keys = [];
formwrap = selection.append('div');
field.input = iD.ui.preset[field.type](field, context)
.on('close', event.close)
.on('change', event.change);
var geometry = entity.geometry(context.graph()),
fields = preset.fields.filter(function(f) {
return f.matchGeometry(geometry);
if (field.type === 'address') {
field.input.entity(entity);
}
field.keys = field.keys || [field.key];
field.show = show;
field.shown = function() {
return field.id === 'name' || field.show || _.any(field.keys, function(key) { return !!tags[key]; });
};
field.modified = function() {
return _.any(field.keys, function(key) {
return original ? tags[key] !== original.tags[key] : tags[key];
});
};
return field;
}
fields.push(UIField(context.presets().field('name')));
var geometry = entity.geometry(context.graph());
preset.fields.forEach(function(field) {
if (field.matchGeometry(geometry)) {
fields.push(UIField(field, true));
}
});
context.presets().universal().forEach(function(field) {
if (fields.indexOf(field) < 0) {
fields.push(UIField(field));
}
});
function fieldKey(field) {
return field.id;
}
function shown() {
return fields.filter(function(field) { return field.shown(); });
}
function notShown() {
return fields.filter(function(field) { return !field.shown(); });
}
function show(field) {
field.show = true;
render();
field.input.focus();
}
function revert(field) {
d3.event.stopPropagation();
d3.event.preventDefault();
var t = {};
field.keys.forEach(function(key) {
t[key] = original ? original.tags[key] : undefined;
});
event.change(t);
}
function toggleReference(field) {
d3.event.stopPropagation();
d3.event.preventDefault();
_.forEach(fields, function(other) {
if (other.id === field.id) {
other.showingReference = !other.showingReference;
} else {
other.showingReference = false;
}
});
render();
}
function render() {
var selection = formwrap.selectAll('.form-field')
.data(shown(), fieldKey);
var enter = selection.enter()
.insert('div', '.more-buttons')
.style('opacity', 0)
.attr('class', function(field) {
return 'form-field form-field-' + field.id + ' fillL col12';
});
fields.unshift(context.presets().field('name'));
enter.transition()
.style('max-height', '0px')
.style('padding-top', '0px')
.style('opacity', '0')
.transition()
.duration(200)
.style('padding-top', '20px')
.style('max-height', '200px')
.style('opacity', '1');
draw(formwrap, fields);
var label = enter.append('label')
.attr('class', 'form-label')
.attr('for', function(field) { return 'preset-input-' + field.id; })
.text(function(field) { return field.label(); });
var wrap = selection.append('div')
.attr('class', 'col12 more-buttons inspector-inner');
label.append('button')
.attr('class', 'tag-reference-button fr')
.attr('tabindex', -1)
.on('click', toggleReference)
.append('span')
.attr('class', 'icon inspect');
formbuttonwrap = wrap.append('div')
.attr('class', 'col12 preset-input');
label.append('button')
.attr('class', 'fr modified-icon')
.attr('tabindex', -1)
.on('click', revert)
.append('div')
.attr('class','icon undo');
formbuttonwrap.selectAll('button')
.data(context.presets().universal().filter(notInForm))
.enter()
enter.each(function(field) {
d3.select(this).call(field.input);
});
enter.append('div')
.attr('class', 'tag-help');
selection
.classed('modified', function(field) {
return field.modified();
});
selection.selectAll('.tag-help')
.style('display', function(field) {
return field.showingReference ? 'block' : 'block';
})
.each(function(field) {
if (field.showingReference) {
d3.select(this)
.call(iD.ui.TagReference(entity, {key: field.key}))
.style('max-height', '0px')
.style('padding-top', '0px')
.style('opacity', '0')
.transition()
.duration(200)
.style('padding-top', '20px')
.style('max-height', '200px')
.style('opacity', '1');
} else {
d3.select(this)
.call(iD.ui.TagReference(entity, {key: field.key}))
.transition()
.duration(200)
.style('max-height', '0px')
.style('padding-top', '0px')
.style('opacity', '0');
}
});
selection.exit()
.remove();
var addFields = formbuttonwrap.selectAll('.preset-add-field')
.data(notShown(), fieldKey);
addFields.enter()
.append('button')
.attr('class', 'preset-add-field')
.on('click', addForm)
.on('click', show)
.call(bootstrap.tooltip()
.placement('top')
.title(function(d) { return d.label(); }))
.append('span')
.attr('class', function(d) { return 'icon ' + d.icon; });
function notInForm(p) {
return preset.fields.indexOf(p) < 0;
}
addFields.exit()
.transition()
.style('opacity', 0)
.remove();
function addForm(d) {
draw(formwrap, [d]);
d3.select(this)
.style('opacity', 1)
.transition()
.style('opacity', 0)
.remove();
if (!wrap.selectAll('button').node()) {
wrap.remove();
}
}
return selection;
}
function draw(selection, fields) {
var sections = selection.selectAll('div.preset-field')
.data(fields, function(field) { return field.id; })
.enter()
.append('div')
.style('opacity', 0)
.attr('class', function(field) {
return 'preset-field preset-field-' + field.id + ' fillL inspector-inner col12';
});
function presets(selection) {
selection.html('');
sections.append('h4')
.attr('for', function(d) { return 'input-' + d.key; })
.text(function(d) { return d.label(); })
.append('button')
.attr('class', 'fr icon undo modified-icon')
.on('click', function(d) {
var original = context.graph().base().entities[entity.id];
var t = {};
(d.keys || [d.key]).forEach(function(key) {
t[key] = original ? original.tags[key] : undefined;
});
event.change(t);
});
formwrap = selection;
sections.transition()
.style('opacity', 1);
formbuttonwrap = selection.append('div')
.attr('class', 'col12 more-buttons inspector-inner');
sections.each(function(field) {
var i = iD.ui.preset[field.type](field, context)
.on('close', event.close)
.on('change', event.change);
event.on('setTags.' + field.key || field.type, function (tags) {
i.tags(_.clone(tags));
});
if (field.type === 'address') i.entity(entity);
keys = keys.concat(field.key ? [field.key] : field.keys);
d3.select(this).call(i);
});
render();
}
presets.rendered = function() {
return keys;
return _.flatten(shown().map(function(field) { return field.keys; }));
};
presets.preset = function(_) {
@@ -112,27 +215,17 @@ iD.ui.preset = function(context, entity) {
return presets;
};
presets.change = function(t) {
tags = t;
presets.change = function(_) {
tags = _;
function haveKey(k) { return k && !!tags[k]; }
formbuttonwrap.selectAll('button').each(function(p) {
if (haveKey(p.key) || _.any(p.keys, haveKey)) {
draw(formwrap, [p]);
d3.select(this).remove();
fields.forEach(function(field) {
if (field.shown()) {
field.input.tags(_);
}
});
formwrap.selectAll('div.preset-field')
.classed('modified', function(d) {
var original = context.graph().base().entities[entity.id];
return _.any(d.keys || [d.key], function(key) {
return original ? tags[key] !== original.tags[key] : tags[key];
});
});
render();
event.setTags(tags);
return presets;
};
+14 -10
View File
@@ -41,15 +41,19 @@ iD.ui.preset.address = function(field, context) {
function close() { return iD.behavior.accept().on('accept', event.close); }
housename = selection.append('input')
var wrap = selection.append('div')
.attr('class', 'preset-input-wrap');
housename = wrap.append('input')
.property('type', 'text')
.attr('placeholder', field.t('placeholders.housename'))
.attr('class', 'addr-housename')
.attr('id', 'preset-input-' + field.id)
.on('blur', change)
.on('change', change)
.call(close());
housenumber = selection.append('input')
housenumber = wrap.append('input')
.property('type', 'text')
.attr('placeholder', field.t('placeholders.number'))
.attr('class', 'addr-number')
@@ -57,25 +61,21 @@ iD.ui.preset.address = function(field, context) {
.on('change', change)
.call(close());
var streetwrap = selection.append('span')
.attr('class', 'input-wrap-position');
street = streetwrap.append('input')
street = wrap.append('input')
.property('type', 'text')
.attr('placeholder', field.t('placeholders.street'))
.attr('class', 'addr-street')
.on('blur', change)
.on('change', change);
.on('change', change)
.call(d3.combobox().data(getStreets()));
city = selection.append('input')
city = wrap.append('input')
.property('type', 'text')
.attr('placeholder', field.t('placeholders.city'))
.attr('class', 'addr-city')
.on('blur', change)
.on('change', change)
.call(close());
streetwrap.call(d3.combobox().data(getStreets()));
}
function change() {
@@ -101,5 +101,9 @@ iD.ui.preset.address = function(field, context) {
return address;
};
address.focus = function() {
housename.node().focus();
};
return d3.rebind(address, event, 'on');
};
+8 -2
View File
@@ -11,11 +11,13 @@ iD.ui.preset.check = function(field) {
selection.classed('checkselect', 'true');
label = selection.append('label');
label = selection.append('label')
.attr('class', 'preset-input-wrap');
box = label.append('input')
.property('indeterminate', true)
.attr('type', 'checkbox');
.attr('type', 'checkbox')
.attr('id', 'preset-input-' + field.id);
text = label.append('span')
.text('unknown')
@@ -38,5 +40,9 @@ iD.ui.preset.check = function(field) {
label.classed('set', !!value);
};
check.focus = function() {
box.node().focus();
};
return d3.rebind(check, event, 'on');
};
+11 -10
View File
@@ -1,20 +1,17 @@
iD.ui.preset.combo = function(field) {
var event = d3.dispatch('change', 'close'),
wrap,
input;
function combo(selection) {
wrap = this.append('span').attr('class', 'input-wrap-position');
input = wrap.append('input')
.attr('type', 'text')
.on('change', change)
.on('blur', change);
var combobox = d3.combobox();
wrap.call(combobox);
input = selection.append('input')
.attr('type', 'text')
.attr('id', 'preset-input-' + field.id)
.on('change', change)
.on('blur', change)
.call(combobox);
if (field.options) {
options(field.options);
@@ -51,5 +48,9 @@ iD.ui.preset.combo = function(field) {
input.property('value', tags[field.key] || '');
};
combo.focus = function() {
input.node().focus();
};
return d3.rebind(combo, event, 'on');
};
+5 -1
View File
@@ -7,7 +7,7 @@ iD.ui.preset.defaultcheck = function(field) {
input = selection.append('input')
.attr('type', 'checkbox')
.attr('id', 'input-' + field.key)
.attr('id', 'preset-input-' + field.id)
.on('change', function() {
var t = {};
t[field.key] = input.property('checked') ? field.value || 'yes' : undefined;
@@ -19,5 +19,9 @@ iD.ui.preset.defaultcheck = function(field) {
input.property('checked', !!tags[field.key] && tags[field.key] !== 'no');
};
check.focus = function() {
input.node().focus();
};
return d3.rebind(check, event, 'on');
};
+5
View File
@@ -10,6 +10,7 @@ iD.ui.preset.url = function(field) {
function i(selection) {
input = selection.append('input')
.attr('type', field.type)
.attr('id', 'preset-input-' + field.id)
.attr('placeholder', field.placeholder || '')
.on('blur', change)
.on('change', change)
@@ -51,5 +52,9 @@ iD.ui.preset.url = function(field) {
input.property('value', tags[field.key] || '');
};
i.focus = function() {
input.node().focus();
};
return d3.rebind(i, event, 'on');
};
+11 -7
View File
@@ -6,18 +6,18 @@ iD.ui.preset.radio = function(field) {
function radio(selection) {
selection.classed('preset-radio', true);
var buttonwrap = selection.append('div').attr('class','radio-wrap');
var buttonwrap = selection.append('div')
.attr('class', 'preset-input-wrap radio-wrap');
buttons = buttonwrap.selectAll('button')
.data(field.keys || field.options)
.enter()
.append('button')
.text(function(d) { return field.t('options.' + d, { 'default': d }); })
.on('click', function() {
buttons.classed('active', false);
d3.select(this).classed('active', true);
change();
});
.text(function(d) { return field.t('options.' + d, { 'default': d }); })
.on('click', function(d) {
buttons.classed('active', function(e) { return d === e; });
change();
});
buttonwrap.append('button')
.on('click', function() {
@@ -52,5 +52,9 @@ iD.ui.preset.radio = function(field) {
});
};
radio.focus = function() {
buttons.node().focus();
};
return d3.rebind(radio, event, 'on');
};
+5
View File
@@ -5,6 +5,7 @@ iD.ui.preset.textarea = function(field) {
function i(selection) {
input = selection.append('textarea')
.attr('id', 'preset-input-' + field.id)
.attr('placeholder', field.placeholder || '')
.attr('maxlength', 255)
.on('blur', change)
@@ -22,5 +23,9 @@ iD.ui.preset.textarea = function(field) {
input.text(tags[field.key] || '');
};
i.focus = function() {
input.node().focus();
};
return d3.rebind(i, event, 'on');
};
+32 -58
View File
@@ -1,9 +1,8 @@
iD.ui.PresetGrid = function(context, entity) {
var event = d3.dispatch('choose', 'close'),
default_limit = 9,
currently_drawn = 9,
presets,
taginfo = iD.taginfo();
defaultLimit = 9,
currentlyDrawn = 9,
presets;
function presetgrid(selection, preset) {
@@ -15,7 +14,7 @@ iD.ui.PresetGrid = function(context, entity) {
.attr('class', 'header fillL cf');
var message = messagewrap.append('h3')
.attr('class', 'inspector-inner fl')
.attr('class', 'inspector-inner')
.text(t('inspector.choose'));
if (preset) {
@@ -39,14 +38,14 @@ iD.ui.PresetGrid = function(context, entity) {
.attr('class', 'preset-grid fillL cf')
.data([context.presets().defaults(entity, 36).collection]);
var show_more = gridwrap.append('button')
var showMore = gridwrap.append('button')
.attr('class', 'fillL show-more')
.text(t('inspector.show_more'))
.on('click', function() {
grid.call(drawGrid, (currently_drawn += default_limit));
grid.call(drawGrid, (currentlyDrawn += defaultLimit));
});
grid.call(drawGrid, default_limit);
grid.call(drawGrid, defaultLimit);
var searchwrap = selection.append('div')
.attr('class', 'preset-grid-search-wrap inspector-inner');
@@ -76,7 +75,7 @@ iD.ui.PresetGrid = function(context, entity) {
if (d3.event.keyCode === 13 && value.length) {
choose(grid.selectAll('.grid-entry:first-child').datum());
} else {
currently_drawn = default_limit;
currentlyDrawn = defaultLimit;
grid.classed('filtered', value.length);
if (value.length) {
var results = presets.search(value);
@@ -85,10 +84,10 @@ iD.ui.PresetGrid = function(context, entity) {
search: value
}));
grid.data([results.collection])
.call(drawGrid, default_limit);
.call(drawGrid, defaultLimit);
} else {
grid.data([context.presets().defaults(entity, 36).collection])
.call(drawGrid, default_limit);
.call(drawGrid, defaultLimit);
}
}
}
@@ -115,7 +114,7 @@ iD.ui.PresetGrid = function(context, entity) {
.attr('class', 'arrow');
subgrid.append('div')
.attr('class', 'preset-grid fillL cf fl')
.attr('class', 'preset-grid fillL3 cf fl')
.data([d.members.collection])
.call(drawGrid, 1000);
@@ -164,10 +163,7 @@ iD.ui.PresetGrid = function(context, entity) {
.style('max-height', '0px')
.style('padding-top', '0px')
.style('padding-bottom', '0px')
.each('end', function() {
shown.remove();
});
.remove();
if (shown.datum() === entity && shown.classed(klass)) return;
shownIndex = Array.prototype.indexOf.call(shown.node().parentNode.childNodes, shown.node());
@@ -203,50 +199,29 @@ iD.ui.PresetGrid = function(context, entity) {
.style('max-height', '0px')
.style('padding-top', '0px')
.style('padding-bottom', '0px')
.style('opacity', '0')
.transition()
.duration(200)
.style('padding-top', '10px')
.style('padding-bottom', '20px')
.style('max-height', '200px');
.style('max-height', '200px')
.style('opacity', '1');
presetinspect.append('h2')
presetinspect.append('h3')
.text(d.name());
var description = presetinspect.append('p');
var link = presetinspect.append('a');
var tag = {key: Object.keys(d.tags)[0]};
var params = {},
locale = iD.detect().locale.split('-')[0] || 'en';
params.key = Object.keys(d.tags)[0];
if (d.tags[params.key] !== '*') {
params.value = d.tags[params.key];
if (d.tags[tag.key] !== '*') {
tag.value = d.tags[tag.key];
}
taginfo.docs(params, function(err, data) {
if (err) return description.text(t('inspector.no_documentation_combination'));
var doc = _.find(data, function(d) { return d.lang === locale; }) ||
_.find(data, function(d) { return d.lang === 'en'; });
if (doc) {
description
.text(doc.description);
link
.attr('href', 'http://wiki.openstreetmap.org/wiki/' +
encodeURIComponent(doc.title))
.text(t('inspector.reference'));
}
});
presetinspect.selectAll('*')
.style('opacity','0')
.transition()
.delay(100)
.duration(200)
.style('opacity','1');
presetinspect.append('div')
.call(iD.ui.TagReference(entity, tag));
}
if (selection.node() === grid.node()) {
show_more
showMore
.style('display', (selection.data()[0].length > limit) ? 'block' : 'none');
}
@@ -256,20 +231,21 @@ iD.ui.PresetGrid = function(context, entity) {
.selectAll('div.grid-entry-wrap')
.data(function(d) { return d.slice(0, limit); }, name);
entries.exit().remove();
entries.exit()
.remove();
var entered = entries.enter()
.append('div')
.attr('class','grid-button-wrap col4 grid-entry-wrap')
.classed('category', function(d) { return !!d.members; })
.classed('current', function(d) { return d === preset; })
.append('button')
.attr('class', 'grid-entry')
.on('click', choose);
.append('button')
.attr('class', 'grid-entry')
.on('click', choose);
entered.style('opacity', 0)
.transition()
.style('opacity', 1);
.transition()
.style('opacity', 1);
entered.append('div')
.attr('class', presetClass);
@@ -286,15 +262,13 @@ iD.ui.PresetGrid = function(context, entity) {
.attr('class','label')
.text(name);
entered.filter(function(d) {
return !d.members;
})
entered.filter(function(d) { return !d.members; })
.append('button')
.attr('tabindex', -1)
.attr('class', 'preset-help')
.attr('class', 'tag-reference-button')
.on('click', helpClick, selection)
.append('span')
.attr('class', 'icon inspect');
.attr('class', 'icon inspect light');
entries.order();
}
+12 -4
View File
@@ -6,21 +6,29 @@ iD.ui.Restore = function(context) {
var modal = iD.ui.modal(selection);
modal.select('.modal')
.attr('class', 'modal-splash modal');
.attr('class', 'modal fillL col6');
var introModal = modal.select('.content');
introModal.attr('class','cf');
introModal.append('div')
.attr('class', 'modal-section header')
.append('h3')
.text(t('restore.description'));
.text(t('restore.heading'));
introModal.append('div')
.attr('class','modal-section')
.append('p')
.text(t('restore.description'));
var buttonWrap = introModal.append('div')
.attr('class', 'modal-section cf col12');
.attr('class', 'modal-section col12');
var buttons = buttonWrap
.append('div')
.attr('class', 'button-wrap joined col6');
.attr('class', 'button-wrap joined col4');
var restore = buttons.append('button')
.attr('class', 'save action button col6')
+3
View File
@@ -2,6 +2,9 @@ iD.ui.SourceSwitch = function(context) {
function click() {
d3.event.preventDefault();
if (context.history().hasChanges() &&
!window.confirm(t('source_switch.lose_changes'))) return;
var live = d3.select(this).classed('live');
context.connection()
+1 -1
View File
@@ -15,5 +15,5 @@ iD.ui.Spinner = function(context) {
img.transition()
.style('opacity', 0);
});
}
};
};
+15 -17
View File
@@ -26,26 +26,18 @@ iD.ui.TagEditor = function(context, entity) {
var messagewrap = selection.append('div')
.attr('class', 'header fillL cf');
var back = messagewrap.append('button')
.attr('class', 'preset-reset fl ' + geometry)
messagewrap.append('button')
.attr('class', 'preset-reset fl ')
.on('click', function() {
event.choose(preset);
});
var icon = preset.icon || (geometry === 'line' ? 'other-line' : 'marker-stroked');
back.append('div')
.attr('class', 'col12')
.append('span')
.attr('class', 'preset-icon icon feature-' + icon);
back.append('div')
.attr('class', 'col12')
})
.append('span')
.attr('class', 'icon back');
var icon = preset.icon || (geometry === 'line' ? 'other-line' : 'marker-stroked');
messagewrap.append('h3')
.attr('class', 'inspector-inner fl')
.attr('class', 'inspector-inner')
.text(t('inspector.editing_feature', { feature: preset.name() }));
messagewrap.append('button')
@@ -57,8 +49,14 @@ iD.ui.TagEditor = function(context, entity) {
var editorwrap = selection.append('div')
.attr('class', 'tag-wrap inspector-body fillL2 inspector-body-' + geometry);
presetUI = iD.ui.preset(context, entity)
.preset(preset)
editorwrap.append('div')
.attr('class', 'col12 inspector-inner preset-icon-wrap fillL3')
.append('div')
.attr('class','fillL')
.append('span')
.attr('class', geometry + ' preset-icon icon feature-' + icon);
presetUI = iD.ui.preset(context, entity, preset)
.on('change', changeTags)
.on('close', event.close);
@@ -75,7 +73,7 @@ iD.ui.TagEditor = function(context, entity) {
if (!entity.isNew()) {
tageditorpreset.append('div')
.attr('class', 'view-on-osm')
.attr('class', 'col12 inspector-inner')
.append('a')
.attr('href', 'http://www.openstreetmap.org/browse/' + entity.type + '/' + entity.osmId())
.attr('target', '_blank')
+58 -44
View File
@@ -1,50 +1,64 @@
iD.ui.tagReference = function(selection) {
selection.each(function() {
function g(x) { return function(d) { return d[x]; }; }
var selection = d3.select(this);
var header = selection.append('div')
.attr('class','modal-section fillL header')
.append('h3');
iD.ui.TagReference = function(entity, tag) {
var taginfo = iD.taginfo();
header.selectAll('span.icon')
.data(g('types'))
.enter()
.append('span')
.attr('title', function(d) {
return t('tag_reference.used_with', {type: d});
})
.attr('class', function(d) {
return 'icon big icon-pre-text big-' + d;
function findLocal(docs) {
var locale = iD.detect().locale.toLowerCase(),
localized;
localized = _.find(docs, function(d) {
return d.lang.toLowerCase() === locale;
});
if (localized) return localized;
// try the non-regional version of a language, like
// 'en' if the language is 'en-US'
if (locale.indexOf('-') !== -1) {
var first = locale.split('-')[0];
localized = _.find(docs, function(d) {
return d.lang.toLowerCase() === first;
});
header.append('span')
.text(g('title'));
var referenceBody = selection.append('div')
.attr('class','modal-section fillL2');
referenceBody
.append('h4')
.text(t('tag_reference.description'));
if (selection.datum().image) {
referenceBody
.append('img')
.attr('class', 'wiki-image')
.attr('src', selection.datum().image.image_url);
if (localized) return localized;
}
referenceBody
.append('p')
.text(g('description'));
// finally fall back to english
return _.find(docs, function(d) {
return d.lang.toLowerCase() === 'en';
});
}
referenceBody
.append('a')
.attr('target', '_blank')
.attr('href', function(d) {
return 'http://wiki.openstreetmap.org/wiki/' + d.title;
})
.text(function(d) {
return t('tag_reference.on_wiki', {tag: d.title});
});
});
return function(selection) {
selection.html('');
selection.classed('cf', true);
taginfo.docs(tag, function(err, docs) {
if (!err && docs) {
docs = findLocal(docs);
}
if (!docs || !docs.description) {
return selection.text(t('inspector.no_documentation_key'));
}
var referenceBody = selection.append('div')
.attr('class','tag-reference-wrap');
if (docs.image && docs.image.thumb_url_prefix) {
referenceBody
.append('img')
.attr('class', 'wiki-image')
.attr('src', docs.image.thumb_url_prefix + "100" + docs.image.thumb_url_suffix);
}
referenceBody
.append('p')
.text(docs.description);
referenceBody
.append('a')
.attr('target', '_blank')
.attr('href', 'http://wiki.openstreetmap.org/wiki/' + docs.title)
.text(t('inspector.reference'));
});
};
};
+28 -110
View File
@@ -1,7 +1,6 @@
iD.ui.Taglist = function(context, entity) {
var event = d3.dispatch('change'),
taginfo = iD.taginfo(),
initial = false,
collapsebutton,
list;
@@ -26,12 +25,8 @@ iD.ui.Taglist = function(context, entity) {
.attr('class', 'tag-list');
var newTag = wrap.append('button')
.attr('class', 'add-tag col6');
newTag.on('click', function() {
addTag();
focusNewKey();
});
.attr('class', 'add-tag col6')
.on('click', addTag);
newTag.append('span')
.attr('class', 'icon plus');
@@ -86,101 +81,30 @@ iD.ui.Taglist = function(context, entity) {
row.each(bindTypeahead);
var removeBtn = row.append('button')
row.append('button')
.attr('tabindex', -1)
.attr('class','remove minor')
.on('click', removeTag);
removeBtn.append('span')
.on('click', removeTag)
.append('span')
.attr('class', 'icon delete');
function findLocal(docs) {
var locale = iD.detect().locale.toLowerCase(),
localized;
localized = _.find(docs, function(d) {
return d.lang.toLowerCase() === locale;
});
if (localized) return localized;
// try the non-regional version of a language, like
// 'en' if the language is 'en-US'
if (locale.indexOf('-') !== -1) {
var first = locale.split('-')[0];
localized = _.find(docs, function(d) {
return d.lang.toLowerCase() === first;
});
if (localized) return localized;
}
// finally fall back to english
return _.find(docs, function(d) {
return d.lang.toLowerCase() === 'en';
});
}
function keyValueReference(err, docs) {
var local;
if (!err && docs) {
local = findLocal(docs);
}
if (local) {
var types = [];
if (local.on_area) types.push('area');
if (local.on_node) types.push('point');
if (local.on_way) types.push('line');
local.types = types;
iD.ui.modal(context.container())
.select('.content')
.datum(local)
.call(iD.ui.tagReference);
} else {
iD.ui.flash(context.container())
.select('.content')
.append('h3')
.text(t('inspector.no_documentation_combination'));
}
}
function keyReference(err, values, params) {
if (!err && values.length) {
iD.ui.modal(context.container())
.select('.content')
.datum({
data: values,
title: 'Key:' + params.key,
geometry: params.geometry
})
.call(iD.ui.keyReference);
} else {
iD.ui.flash(context.container())
.select('.content')
.append('h3')
.text(t('inspector.no_documentation_key'));
}
}
var helpBtn = row.append('button')
row.append('button')
.attr('tabindex', -1)
.attr('class', 'tag-help minor')
.on('click', function(d) {
var params = _.extend({}, d, {
geometry: entity.geometry(context.graph())
});
if (d.key && d.value) {
taginfo.docs(params, keyValueReference);
} else if (d.key) {
taginfo.values(params, keyReference);
}
});
.on('click', function(tag) {
row.selectAll('div.tag-help')
.style('display', 'none');
helpBtn.append('span')
.attr('class', 'icon inspect');
d3.select(d3.select(this).node().parentNode)
.select('div.tag-help')
.style('display', 'block')
.call(iD.ui.TagReference(entity, {key: tag.key}));
})
.append('span')
.attr('class', 'icon inspect light');
if (initial && tags.length === 1 &&
tags[0].key === '' && tags[0].value === '') {
focusNewKey();
}
row.append('div')
.attr('class', 'tag-help');
return li;
}
@@ -190,7 +114,6 @@ iD.ui.Taglist = function(context, entity) {
list.selectAll('li:last-child input.value').node() === this &&
!d3.event.shiftKey) {
addTag();
focusNewKey();
d3.event.preventDefault();
}
}
@@ -198,8 +121,8 @@ iD.ui.Taglist = function(context, entity) {
function bindTypeahead() {
var geometry = entity.geometry(context.graph()),
row = d3.select(this),
key = row.selectAll('.key-wrap'),
value = row.selectAll('.input-wrap-position');
key = row.selectAll('input.key'),
value = row.selectAll('input.value');
function sort(value, data) {
var sameletter = [],
@@ -214,40 +137,35 @@ iD.ui.Taglist = function(context, entity) {
return sameletter.concat(other);
}
var keyinput = key.select('input');
key.call(d3.combobox()
.fetcher(function(_, __, callback) {
.fetcher(function(value, __, callback) {
taginfo.keys({
debounce: true,
geometry: geometry,
query: keyinput.property('value')
query: value
}, function(err, data) {
if (!err) callback(sort(keyinput.property('value'), data));
if (!err) callback(sort(value, data));
});
}));
var valueinput = value.select('input');
value.call(d3.combobox()
.fetcher(function(_, __, callback) {
.fetcher(function(value, __, callback) {
taginfo.values({
debounce: true,
key: keyinput.property('value'),
key: key.property('value'),
geometry: geometry,
query: valueinput.property('value')
query: value
}, function(err, data) {
if (!err) callback(sort(valueinput.property('value'), data));
if (!err) callback(sort(value, data));
});
}));
}
function focusNewKey() {
list.selectAll('li:last-child input.key').node().focus();
}
function addTag() {
var tags = taglist.tags();
tags[''] = '';
drawTags(tags);
list.selectAll('li:last-child input.key').node().focus();
}
function removeTag(d) {
+20 -21
View File
@@ -1,7 +1,7 @@
d3.combobox = function() {
var event = d3.dispatch('accept'),
id = d3.combobox.id ++,
container, input, shown = false, data = [];
data = [];
var fetcher = function(val, data, cb) {
cb(data.filter(function(d) {
@@ -12,22 +12,28 @@ d3.combobox = function() {
}));
};
var typeahead = function(selection) {
var idx = -1;
input = selection.select('input').classed('combobox-input', true);
var typeahead = function(input) {
var idx = -1, container, shown = false;
selection.append('div', selection.select('input'))
.attr('class', 'combobox-carat')
.on('mousedown', stop)
.on('mousedown', function() {
d3.event.preventDefault();
mousedown();
input
.classed('combobox-input', true)
.each(function() {
var parent = this.parentNode,
sibling = this.nextSibling;
d3.select(parent)
.insert('div', function() { return sibling; })
.attr('class', 'combobox-carat')
.on('mousedown', function () {
// prevent the form element from blurring. it blurs
// on mousedown
d3.event.stopPropagation();
d3.event.preventDefault();
mousedown();
});
});
function updateSize() {
var rect = selection.select('input')
.node()
.getBoundingClientRect();
var rect = input.node().getBoundingClientRect();
container.style({
'left': rect.left + 'px',
'width': rect.width + 'px',
@@ -35,13 +41,6 @@ d3.combobox = function() {
});
}
function stop() {
// prevent the form element from blurring. it blurs
// on mousedown
d3.event.stopPropagation();
d3.event.preventDefault();
}
function blur() {
// hide the combobox whenever the input element
// loses focus
@@ -210,7 +209,7 @@ d3.combobox = function() {
.order();
}
fetcher.apply(selection, [value, data, render]);
fetcher.apply(input, [value, data, render]);
}
// select the choice given as d
+25
View File
@@ -0,0 +1,25 @@
d3.jsonp = function (url, callback) {
function rand() {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
c = '', i = -1;
while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
return c;
}
function create(url) {
var e = url.match(/callback=d3.jsonp.(\w+)/),
c = e ? e[1] : rand();
d3.jsonp[c] = function(data) {
callback(data);
delete d3.jsonp[c];
script.remove();
};
return 'd3.jsonp.' + c;
}
var cb = create(url),
script = d3.select('head')
.append('script')
.attr('type', 'text/javascript')
.attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
};
+3
View File
@@ -29,5 +29,8 @@
},
"engines": {
"node": "~0.8.20"
},
"dependencies": {
"marked": "~0.2.8"
}
}
+2 -1
View File
@@ -26,6 +26,7 @@
<script src='../js/lib/d3.geo.tile.js'></script>
<script src='../js/lib/d3.size.js'></script>
<script src='../js/lib/d3.trigger.js'></script>
<script src='../js/lib/d3.jsonp.js'></script>
<script src='../js/lib/d3.keybinding.js'></script>
<script src='../js/lib/d3.one.js'></script>
<script src='../js/lib/d3-compat.js'></script>
@@ -81,7 +82,6 @@
<script src='../js/id/ui/splash.js'></script>
<script src='../js/id/ui/restore.js'></script>
<script src='../js/id/ui/tag_reference.js'></script>
<script src='../js/id/ui/key_reference.js'></script>
<script src='../js/id/ui/preset.js'></script>
<script src='../js/id/ui/lasso.js'></script>
<script src='../js/id/ui/source_switch.js'></script>
@@ -184,6 +184,7 @@
<script src="spec/actions/add_entity.js"></script>
<script src="spec/actions/change_tags.js"></script>
<script src='spec/actions/circularize.js'></script>
<script src='spec/actions/orthogonalize.js'></script>
<script src='spec/actions/connect.js'></script>
<script src="spec/actions/delete_multiple.js"></script>
<script src="spec/actions/delete_node.js"></script>
+30
View File
@@ -0,0 +1,30 @@
describe("iD.actions.Orthogonalize", function () {
var projection = d3.geo.mercator();
it("orthoganalizes a quad", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [0, 0]}),
'b': iD.Node({id: 'b', loc: [4, 0]}),
'c': iD.Node({id: 'c', loc: [3, 2]}),
'd': iD.Node({id: 'd', loc: [0, 2]}),
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'd', 'a']})
});
graph = iD.actions.Orthogonalize('-', projection)(graph);
expect(graph.entity('-').nodes).to.have.length(5);
});
it("orthoganalizes a triangle", function () {
var graph = iD.Graph({
'a': iD.Node({id: 'a', loc: [0, 0]}),
'b': iD.Node({id: 'b', loc: [3, 0]}),
'c': iD.Node({id: 'c', loc: [2, 2]}),
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'a']})
});
graph = iD.actions.Orthogonalize('-', projection)(graph);
expect(graph.entity('-').nodes).to.have.length(4);
});
});