diff --git a/css/65_data.css b/css/65_data.css
index 24af906c4..d15ece1bd 100644
--- a/css/65_data.css
+++ b/css/65_data.css
@@ -1,26 +1,34 @@
/* OSM Notes Layer */
+.layer-keepRight,
.layer-notes {
pointer-events: none;
}
+.layer-keepRight .kr_error,
.layer-notes .note * {
pointer-events: none;
}
.mode-browse .layer-notes .note .note-fill,
.mode-select .layer-notes .note .note-fill,
.mode-select-data .layer-notes .note .note-fill,
-.mode-select-note .layer-notes .note .note-fill {
+.mode-select-note .layer-notes .note .note-fill,
+.layer-keepRight .kr_error .kr_error-fill,
+.layer-notes .note .note-fill {
pointer-events: visible;
cursor: pointer; /* Opera */
cursor: url(img/cursor-select-point.png), pointer; /* FF */
}
.note-header-icon .note-shadow,
-.layer-notes .note .note-shadow {
+.layer-notes .note .note-shadow,
+.kr_error-header-icon .kr_error-shadow,
+.layer-keepRight .kr_error .kr_error-shadow {
color: #000;
}
.note-header-icon .note-fill,
-.layer-notes .note .note-fill {
+.layer-notes .note .note-fill,
+.kr_error-header-icon .kr_error-fill,
+.layer-keepRight .kr_error .kr_error-fill {
color: #ff3300;
stroke: #333;
stroke-width: 40px;
@@ -55,7 +63,6 @@
/* Custom Map Data (geojson, gpx, kml, vector tile) */
-
.layer-mapdata {
pointer-events: none;
}
@@ -115,3 +122,52 @@
stroke-miterlimit: 1;
}
+
+/* OSM Note UI */
+.note-header,
+.kr_error-header {
+ background-color: #f6f6f6;
+ border-radius: 5px;
+ border: 1px solid #ccc;
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+}
+
+.note-header-icon,
+.kr_error-header-icon {
+ background-color: #fff;
+ padding: 10px;
+ flex: 0 0 62px;
+ position: relative;
+ width: 60px;
+ height: 60px;
+ border-right: 1px solid #ccc;
+ border-radius: 5px 0 0 5px;
+}
+[dir='rtl'] .note-header-icon,
+[dir='rtl'] .kr_error-header-icon {
+ border-right: unset;
+ border-left: 1px solid #ccc;
+ border-radius: 0 5px 5px 0;
+}
+
+.note-header-icon .icon-wrap,
+.kr_error-header-icon .icon-wrap {
+ position: absolute;
+ top: 0px;
+}
+
+.note-header-label,
+.kr_error-header-label {
+ background-color: #f6f6f6;
+ padding: 0 15px;
+ flex: 1 1 100%;
+ font-size: 14px;
+ font-weight: bold;
+ border-radius: 0 5px 5px 0;
+}
+[dir='rtl'] .note-header-label,
+[dir='rtl'] .kr_error-header-label {
+ border-radius: 5px 0 0 5px;
+}
diff --git a/modules/osm/keepRight.js b/modules/osm/keepRight.js
index 95d8d14bb..45a422aad 100644
--- a/modules/osm/keepRight.js
+++ b/modules/osm/keepRight.js
@@ -3,14 +3,18 @@ var keepRightSchema = {
'error_id': 0,
'error_type': 0,
'error_name': 0,
- 'object_type': ['node',
-'way',
-'relation'],
+ 'object_type': [
+ 'node',
+ 'way',
+ 'relation'
+ ],
'object_id': 0,
- 'state': ['new',
-'reopened',
-'ignore_temporarily',
-'ignore'],
+ 'state': [
+ 'new',
+ 'reopened',
+ 'ignore_temporarily',
+ 'ignore'
+ ],
'first_occurrence': new Date(),
'last_checked': new Date(),
'object_timestamp': new Date(),
@@ -27,445 +31,445 @@ var keepRightSchema = {
'txt5': ''
};
- var errorSchema = {
- errors: {
- 0: {
- errorType: 0,
- errorName: '',
- message: '',
- subTypes: {}
- },
- 30: {
- errorType: 30,
- errorName: 'non_closed_areas',
- message: 'This way is tagged with \'$1=$2\' and should be closed-loop',
- subTypes: {}
- },
- 40: {
- errorType: 40,
- errorName: 'dead ended oneways',
- message: 'The first node (id $1) of this one-way is not connected to any other way',
- subTypes: {
- 41: {
- errorType: 41,
- errorName: '',
- message: 'The last node (id $1) of this one-way is not connected to any other way'
- },
- 42: {
- errorType: 42,
- errorName: '',
- message: 'This node cannot be reached, because one-ways only lead away from here'
- },
- 43: {
- errorType: 43,
- errorName: '',
- message: 'You cannot escape from this node, because one-ways only lead to here'
- },
+var errorSchema = {
+ errors: {
+ 0: {
+ errorType: 0,
+ errorName: '',
+ message: '',
+ subTypes: {}
+ },
+ 30: {
+ errorType: 30,
+ errorName: 'non_closed_areas',
+ message: 'This way is tagged with \'$1=$2\' and should be closed-loop',
+ subTypes: {}
+ },
+ 40: {
+ errorType: 40,
+ errorName: 'dead ended oneways',
+ message: 'The first node (id $1) of this one-way is not connected to any other way',
+ subTypes: {
+ 41: {
+ errorType: 41,
+ errorName: '',
+ message: 'The last node (id $1) of this one-way is not connected to any other way'
+ },
+ 42: {
+ errorType: 42,
+ errorName: '',
+ message: 'This node cannot be reached, because one-ways only lead away from here'
+ },
+ 43: {
+ errorType: 43,
+ errorName: '',
+ message: 'You cannot escape from this node, because one-ways only lead to here'
+ },
+ }
+ },
+ 50: {
+ errorType: 50,
+ errorName: 'almost junctions',
+ message: 'This node is very close but not connected to way #$1',
+ subTypes: {}
+ },
+ 60: {
+ errorType: 60,
+ errorName: 'depreciated tags',
+ message: 'This $1 uses deprecated tag $2 = $3. Please use $4 instead!',
+ subTypes: {}
+ },
+ 70: {
+ errorType: 70,
+ errorName: 'missing tags',
+ message: 'This $1 has an empty tag: $2',
+ 71: {
+ errorType: 71,
+ errorName: '',
+ message: 'This way has no tags'
+ },
+ 72: {
+ errorType: 72,
+ errorName: '',
+ message: 'This node is not member of any way and does not have any tags'
}
- },
- 50: {
- errorType: 50,
- errorName: 'almost junctions',
- message: 'This node is very close but not connected to way #$1',
- subTypes: {}
- },
- 60: {
- errorType: 60,
- errorName: 'depreciated tags',
- message: 'This $1 uses deprecated tag $2 = $3. Please use $4 instead!',
- subTypes: {}
- },
- 70: {
- errorType: 70,
- errorName: 'missing tags',
- message: 'This $1 has an empty tag: $2',
- 71: {
- errorType: 71,
- errorName: '',
- message: 'This way has no tags'
- },
- 72: {
- errorType: 72,
- errorName: '',
- message: 'This node is not member of any way and does not have any tags'
- }
- },
- 90: {
- errorType: 90,
- errorName: 'motorways without ref',
- message: 'This way is tagged as motorway and therefore needs a ref, nat_ref or int_ref tag'
- },
- 100: {
- errorType: 100,
- errorName: 'places of worship without religion',
- message: 'This $1 is tagged as place of worship and therefore needs a religion tag'
- },
- 110: {
- errorType: 110,
- errorName: 'point of interest without name',
- message: 'This node is tagged as $1 and therefore needs a name tag'
- },
- 120: {
- errorType: 120,
- errorName: 'ways without nodes',
- message: 'This way has just one single node'
- },
- 130: {
- errorType: 130,
- errorName: 'floating islands',
- message: 'This way is not connected to the rest of the map'
- },
- 150: {
- errorType: 150,
- errorName: 'railway crossing without tag',
- message: 'This crossing of a highway and a railway needs to be tagged as railway=crossing or railway=level_crossing'
- },
- 160: {
- errorType: 160,
- errorName: 'wrongly used railway tag',
- message: 'There are ways in different layers coming together in this railway crossing. There are ways tagged as tunnel or bridge coming together in this railway crossing'
- },
- 170: {
- errorType: 0,
- errorName: 'FIXME tagged items',
- message: '$1'
- },
- 180: {
- errorType: 180,
- errorName: 'relations without type',
- message: 'This relation has no type tag, which is mandatory for relations'
- },
- 190: {
- errorType: 190,
- errorName: 'intersections without junctions',
- message: 'Finds way crossings on same layer without common node as a junction',
- subtypes: {
- 191: {
- errorType: 191,
- errorName: 'highway-highway',
- message: 'This $1 intersects the $2 #$3 but there is no junction node'
- },
- 192: {
- errorType: 192,
- errorName: 'highway-waterway',
- message: 'This $1 intersects the $2 #$3'
- },
- 193: {
- errorType: 193,
- errorName: 'highway-riverbank',
- message: 'This $1 intersects the $2 #$3'
- },
- 194: {
- errorType: 194,
- errorName: 'waterway-waterway',
- message: 'This $1 intersects the $2 #$3 but there is no junction node'
- },
- 195: {
- errorType: 195,
- errorName: 'cycleway-cycleway',
- message: 'This $1 intersects the $2 #$3 but there is no junction node'
- },
- 196: {
- errorType: 196,
- errorName: 'highway-cycleway',
- message: 'This $1 intersects the $2 #$3 but there is no junction node'
- },
- 197: {
- errorType: 197,
- errorName: 'cycleway-waterway',
- message: 'This $1 intersects the $2 #$3'
- },
- 198: {
- errorType: 198,
- errorName: 'cycleway-riverbank',
- message: 'This $1 intersects the $2 #$3'
- }
- }
- },
- 200: {
- errorType: 200,
- errorName: 'intersections without junctions',
- message: 'Finds overlapping ways on same layer.',
- subtypes: {
- 201: {
- errorType: 201,
- errorName: 'highway-highway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 202: {
- errorType: 202,
- errorName: 'highway-waterway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 203: {
- errorType: 203,
- errorName: 'highway-riverbank',
- message: 'This $1 overlaps the $2 #$3'
- },
- 204: {
- errorType: 204,
- errorName: 'waterway-waterway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 205: {
- errorType: 205,
- errorName: 'cycleway-cycleway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 206: {
- errorType: 206,
- errorName: 'highway-cycleway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 207: {
- errorType: 207,
- errorName: 'cycleway-waterway',
- message: 'This $1 overlaps the $2 #$3'
- },
- 208: {
- errorType: 208,
- errorName: 'cycleway-riverbank',
- message: 'This $1 overlaps the $2 #$3'
- }
- }
- },
- 210: {
- errorType: 210,
- errorName: 'loopings',
- message: 'These errors contain self intersecting ways',
- subTypes: {
- 211: {
- errorType: 211,
- errorName: '',
- message: 'This way contains more than one node at least twice. Nodes are $1. This may or may not be an error'
- },
- 212: {
- errorType: 212,
- errorName: '',
- message: 'This way has only two different nodes and contains one of them more than once'
- },
- }
- },
- 220: {
- errorType: 220,
- errorName: 'misspelled tags',
- message: ' This $1 is tagged \'$2=$3\' where $4 looks like $5',
- subTypes: {
- 221: {
- errorType: 221,
- errorName: 'misspelled tags',
- message: 'The key of this $1\'s tag is \'key\': $2'
- }
- }
- },
- 230: {
- errorType: 230,
- errorName: 'layer conflicts',
- message: '',
- subTypes: {
- 231: {
- errorType: 231,
- errorName: 'mixed layers intersection',
- message: 'This node is a junction of ways on different layers: $1'
- },
- 232: {
- errorType: 232,
- errorName: 'strange layers',
- message: 'This $1 is tagged with layer $2. This need not be an error, but it looks strange'
- }
- }
- },
- 270: {
- errorType: 270,
- errorName: 'motorways connected directly',
- message: 'This node is a junction of a motorway and a highway other than motorway, motorway_link, trunk, rest_area or construction. Service or unclassified is only valid if it has access=no/private or if it is a service=parking_aisle.'
- },
- 280: {
- errorType: 280,
- errorName: 'boundaries',
- message: '',
- subTypes: {
- 281: {
- errorType: 281,
- errorName: 'missing name',
- message: 'This boundary has no name'
- },
- 282: {
- errorType: 282,
- errorName: 'missing admin level',
- message: 'The boundary of $1 has no valid numeric admin_level. Please do not use admin levels like for example 6;7. Always tag the lowest admin_level of all boundaries.'
- },
- 283: {
- errorType: 283,
- errorName: 'no closed loop',
- message: 'The boundary of $1 is not closed-loop'
- },
- 284: {
- errorType: 284,
- errorName: 'splitting boundary',
- message: 'The boundary of $1 splits here'
- },
- 285: {
- errorType: 285,
- errorName: 'admin_level too high',
- message: 'This boundary-way has admin_level $1 but belongs to a relation with lower admin_level (higher priority); it should have the lowest admin_level of all relations'
- },
- }
- },
- 290: {
- errorType: 290,
- errorName: 'faulty restrictions',
- message: 'Analyses all relations tagged type=restriction or following variations type=restriction:hgv, type=restriction:caravan, type=restriction:motorcar, type=restriction:bus, type=restriction:agricultural, type=restriction:motorcycle, type=restriction:bicycle and type=restriction:hazmat.',
- subTypes: {
- 291: {
- errorType: 291,
- errorName: 'missing type',
- message: 'This turn-restriction has no known restriction type'
- },
- 292: {
- errorType: 292,
- errorName: 'missing from way',
- message: 'A turn-restriction needs exactly one $1 member. This one has $2'
- },
- 293: {
- errorType: 293,
- errorName: 'missing to way',
- message: 'A turn-restriction needs exactly one $1 member. This one has $2'
- },
- 294: {
- errorType: 294,
- errorName: 'from or to not a way',
- message: 'From- and To-members of turn restrictions need to be ways. $1'
- },
- 295: {
- errorType: 295,
- errorName: 'via is not on the way ends',
- message: 'via (node #$1) is not the first or the last member of from (way #$2)'
- },
- 296: {
- errorType: 296,
- errorName: 'wrong restriction angle',
- message: 'restriction type is $1, but angle is $2 degrees. Maybe the restriction type is not appropriate?'
- },
- 297: {
- errorType: 297,
- errorName: 'wrong direction of to member',
- message: 'wrong direction of to way $1'
- },
- 298: {
- errorType: 298,
- errorName: 'already restricted by oneway',
- message: 'entry already prohibited by oneway tag on $1'
- },
- }
- },
- 310: {
- errorType: 310,
- errorName: 'roundabouts',
- message: 'Analyses ways with tag junction=roundabout. More then one way can form a roundabout. It supports tag oneway=-1.',
- subTypes: {
- 311: {
- errorType: 311,
- errorName: 'not closed loop',
- message: 'This way is part of a roundabout but is not closed-loop. (split carriageways approaching a roundabout should not be tagged as roundabout)'
- },
- 312: {
- errorType: 312,
- errorName: 'wrong direction',
- message: 'If this roundabout is in a country with right-hand traffic then its orientation goes the wrong way around | If this roundabout is in a country with left-hand traffic then its orientation goes the wrong way around | If this mini_roundabout is in a country with right-hand traffic then its orientation goes the wrong way around | If this mini_roundabout is in a country with left-hand traffic then its orientation goes the wrong way around'
- },
- 313: {
- errorType: 313,
- errorName: 'faintly connected',
- message: 'This roundabout has only $1 other roads connected. Roundabouts typically have three.'
- },
- }
- },
- 320: {
- errorType: 320,
- errorName: '*link connections',
- message: 'This way is tagged as highway=$1_link but doesn\'t have a connection to any other $1 or $1_link'
- },
- 350: {
- errorType: 350,
- errorName: 'bridge tags',
- message: 'This bridge does not have a tag in common with its surrounding ways that shows the purpose of this bridge. There should be one of these tags: $1'
- },
- 370: {
- errorType: 370,
- errorName: 'doubled places',
- message: 'This node has tags in common with the surrounding way #$1 and seems to be redundand | This node has tags in common with the surrounding way #$1 (including the name \'$2\') and seems to be redundand'
- },
- 380: {
- errorType: 380,
- errorName: 'non-physical use of sportage',
- message: 'This way is tagged $1 but has no physical tag like e.g. leisure, building, amenity or highway'
- },
- 400: {
- errorType: 400,
- errorName: 'geometry glitches',
- message: '',
- subTypes: {
- 401: {
- errorType: 401,
- errorName: 'missing turn restrictions',
- message: 'ways $1 and $2 join in a very sharp angle here and there is no oneway tag or turn restriction that prevents turning'
- },
- 402: {
- errorType: 402,
- errorName: 'impossible angles',
- message: 'this way bends in a very sharp angle here'
- },
- }
- },
- 410: {
- errorType: 410,
- errorName: 'websites',
- message: 'Web pages are analyzed. Web page is defined by any of the following tags website=*, url=*, website:mobile=*, contact:website=*, contact:url=*, image=*, source:website=* or source:url=*.',
- subTypes: {
- 411: {
- errorType: 411,
- errorName: 'http error',
- message: 'The URL ($1) cannot be opened (HTTP status code $2)'
- },
- 412: {
- errorType: 412,
- errorName: 'domain hijacking',
- message: 'Possible domain squatting: $1. Suspicious text is: "$2"'
- },
- 413: {
- errorType: 413,
- errorName: 'non-match',
- message: 'Content of the URL ($1) did not contain these keywords: ($2)'
- },
+ },
+ 90: {
+ errorType: 90,
+ errorName: 'motorways without ref',
+ message: 'This way is tagged as motorway and therefore needs a ref, nat_ref or int_ref tag'
+ },
+ 100: {
+ errorType: 100,
+ errorName: 'places of worship without religion',
+ message: 'This $1 is tagged as place of worship and therefore needs a religion tag'
+ },
+ 110: {
+ errorType: 110,
+ errorName: 'point of interest without name',
+ message: 'This node is tagged as $1 and therefore needs a name tag'
+ },
+ 120: {
+ errorType: 120,
+ errorName: 'ways without nodes',
+ message: 'This way has just one single node'
+ },
+ 130: {
+ errorType: 130,
+ errorName: 'floating islands',
+ message: 'This way is not connected to the rest of the map'
+ },
+ 150: {
+ errorType: 150,
+ errorName: 'railway crossing without tag',
+ message: 'This crossing of a highway and a railway needs to be tagged as railway=crossing or railway=level_crossing'
+ },
+ 160: {
+ errorType: 160,
+ errorName: 'wrongly used railway tag',
+ message: 'There are ways in different layers coming together in this railway crossing. There are ways tagged as tunnel or bridge coming together in this railway crossing'
+ },
+ 170: {
+ errorType: 0,
+ errorName: 'FIXME tagged items',
+ message: '$1'
+ },
+ 180: {
+ errorType: 180,
+ errorName: 'relations without type',
+ message: 'This relation has no type tag, which is mandatory for relations'
+ },
+ 190: {
+ errorType: 190,
+ errorName: 'intersections without junctions',
+ message: 'Finds way crossings on same layer without common node as a junction',
+ subtypes: {
+ 191: {
+ errorType: 191,
+ errorName: 'highway-highway',
+ message: 'This $1 intersects the $2 #$3 but there is no junction node'
+ },
+ 192: {
+ errorType: 192,
+ errorName: 'highway-waterway',
+ message: 'This $1 intersects the $2 #$3'
+ },
+ 193: {
+ errorType: 193,
+ errorName: 'highway-riverbank',
+ message: 'This $1 intersects the $2 #$3'
+ },
+ 194: {
+ errorType: 194,
+ errorName: 'waterway-waterway',
+ message: 'This $1 intersects the $2 #$3 but there is no junction node'
+ },
+ 195: {
+ errorType: 195,
+ errorName: 'cycleway-cycleway',
+ message: 'This $1 intersects the $2 #$3 but there is no junction node'
+ },
+ 196: {
+ errorType: 196,
+ errorName: 'highway-cycleway',
+ message: 'This $1 intersects the $2 #$3 but there is no junction node'
+ },
+ 197: {
+ errorType: 197,
+ errorName: 'cycleway-waterway',
+ message: 'This $1 intersects the $2 #$3'
+ },
+ 198: {
+ errorType: 198,
+ errorName: 'cycleway-riverbank',
+ message: 'This $1 intersects the $2 #$3'
}
}
},
- warnings: {
- 20: {
- errorType: 20,
- errorName: 'multiple nodes on the same spot',
- message: ' There is more than one node in this spot. Offending node IDs: $1'
- },
- 60: {
- errorType: 60,
- errorName: '',
- message: ''
- },
- 300: {
- errorType: 300,
- errorName: 'missing maxspeed',
- message: 'missing maxspeed tag'
- },
- 360: {
- errorType: 360,
- errorName: 'language unknown',
- message: 'It would be nice if this $1 had an additional tag \'name:XX=$2\' where XX shows the language of its name \'$2\'.'
- },
- 390: {
- errorType: 390,
- errorName: 'missing tracktype',
- message: 'This track doesn\'t have a tracktype'
- },
+ 200: {
+ errorType: 200,
+ errorName: 'intersections without junctions',
+ message: 'Finds overlapping ways on same layer.',
+ subtypes: {
+ 201: {
+ errorType: 201,
+ errorName: 'highway-highway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 202: {
+ errorType: 202,
+ errorName: 'highway-waterway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 203: {
+ errorType: 203,
+ errorName: 'highway-riverbank',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 204: {
+ errorType: 204,
+ errorName: 'waterway-waterway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 205: {
+ errorType: 205,
+ errorName: 'cycleway-cycleway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 206: {
+ errorType: 206,
+ errorName: 'highway-cycleway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 207: {
+ errorType: 207,
+ errorName: 'cycleway-waterway',
+ message: 'This $1 overlaps the $2 #$3'
+ },
+ 208: {
+ errorType: 208,
+ errorName: 'cycleway-riverbank',
+ message: 'This $1 overlaps the $2 #$3'
+ }
+ }
},
- };
\ No newline at end of file
+ 210: {
+ errorType: 210,
+ errorName: 'loopings',
+ message: 'These errors contain self intersecting ways',
+ subTypes: {
+ 211: {
+ errorType: 211,
+ errorName: '',
+ message: 'This way contains more than one node at least twice. Nodes are $1. This may or may not be an error'
+ },
+ 212: {
+ errorType: 212,
+ errorName: '',
+ message: 'This way has only two different nodes and contains one of them more than once'
+ },
+ }
+ },
+ 220: {
+ errorType: 220,
+ errorName: 'misspelled tags',
+ message: ' This $1 is tagged \'$2=$3\' where $4 looks like $5',
+ subTypes: {
+ 221: {
+ errorType: 221,
+ errorName: 'misspelled tags',
+ message: 'The key of this $1\'s tag is \'key\': $2'
+ }
+ }
+ },
+ 230: {
+ errorType: 230,
+ errorName: 'layer conflicts',
+ message: '',
+ subTypes: {
+ 231: {
+ errorType: 231,
+ errorName: 'mixed layers intersection',
+ message: 'This node is a junction of ways on different layers: $1'
+ },
+ 232: {
+ errorType: 232,
+ errorName: 'strange layers',
+ message: 'This $1 is tagged with layer $2. This need not be an error, but it looks strange'
+ }
+ }
+ },
+ 270: {
+ errorType: 270,
+ errorName: 'motorways connected directly',
+ message: 'This node is a junction of a motorway and a highway other than motorway, motorway_link, trunk, rest_area or construction. Service or unclassified is only valid if it has access=no/private or if it is a service=parking_aisle.'
+ },
+ 280: {
+ errorType: 280,
+ errorName: 'boundaries',
+ message: '',
+ subTypes: {
+ 281: {
+ errorType: 281,
+ errorName: 'missing name',
+ message: 'This boundary has no name'
+ },
+ 282: {
+ errorType: 282,
+ errorName: 'missing admin level',
+ message: 'The boundary of $1 has no valid numeric admin_level. Please do not use admin levels like for example 6;7. Always tag the lowest admin_level of all boundaries.'
+ },
+ 283: {
+ errorType: 283,
+ errorName: 'no closed loop',
+ message: 'The boundary of $1 is not closed-loop'
+ },
+ 284: {
+ errorType: 284,
+ errorName: 'splitting boundary',
+ message: 'The boundary of $1 splits here'
+ },
+ 285: {
+ errorType: 285,
+ errorName: 'admin_level too high',
+ message: 'This boundary-way has admin_level $1 but belongs to a relation with lower admin_level (higher priority); it should have the lowest admin_level of all relations'
+ },
+ }
+ },
+ 290: {
+ errorType: 290,
+ errorName: 'faulty restrictions',
+ message: 'Analyses all relations tagged type=restriction or following variations type=restriction:hgv, type=restriction:caravan, type=restriction:motorcar, type=restriction:bus, type=restriction:agricultural, type=restriction:motorcycle, type=restriction:bicycle and type=restriction:hazmat.',
+ subTypes: {
+ 291: {
+ errorType: 291,
+ errorName: 'missing type',
+ message: 'This turn-restriction has no known restriction type'
+ },
+ 292: {
+ errorType: 292,
+ errorName: 'missing from way',
+ message: 'A turn-restriction needs exactly one $1 member. This one has $2'
+ },
+ 293: {
+ errorType: 293,
+ errorName: 'missing to way',
+ message: 'A turn-restriction needs exactly one $1 member. This one has $2'
+ },
+ 294: {
+ errorType: 294,
+ errorName: 'from or to not a way',
+ message: 'From- and To-members of turn restrictions need to be ways. $1'
+ },
+ 295: {
+ errorType: 295,
+ errorName: 'via is not on the way ends',
+ message: 'via (node #$1) is not the first or the last member of from (way #$2)'
+ },
+ 296: {
+ errorType: 296,
+ errorName: 'wrong restriction angle',
+ message: 'restriction type is $1, but angle is $2 degrees. Maybe the restriction type is not appropriate?'
+ },
+ 297: {
+ errorType: 297,
+ errorName: 'wrong direction of to member',
+ message: 'wrong direction of to way $1'
+ },
+ 298: {
+ errorType: 298,
+ errorName: 'already restricted by oneway',
+ message: 'entry already prohibited by oneway tag on $1'
+ },
+ }
+ },
+ 310: {
+ errorType: 310,
+ errorName: 'roundabouts',
+ message: 'Analyses ways with tag junction=roundabout. More then one way can form a roundabout. It supports tag oneway=-1.',
+ subTypes: {
+ 311: {
+ errorType: 311,
+ errorName: 'not closed loop',
+ message: 'This way is part of a roundabout but is not closed-loop. (split carriageways approaching a roundabout should not be tagged as roundabout)'
+ },
+ 312: {
+ errorType: 312,
+ errorName: 'wrong direction',
+ message: 'If this roundabout is in a country with right-hand traffic then its orientation goes the wrong way around | If this roundabout is in a country with left-hand traffic then its orientation goes the wrong way around | If this mini_roundabout is in a country with right-hand traffic then its orientation goes the wrong way around | If this mini_roundabout is in a country with left-hand traffic then its orientation goes the wrong way around'
+ },
+ 313: {
+ errorType: 313,
+ errorName: 'faintly connected',
+ message: 'This roundabout has only $1 other roads connected. Roundabouts typically have three.'
+ },
+ }
+ },
+ 320: {
+ errorType: 320,
+ errorName: '*link connections',
+ message: 'This way is tagged as highway=$1_link but doesn\'t have a connection to any other $1 or $1_link'
+ },
+ 350: {
+ errorType: 350,
+ errorName: 'bridge tags',
+ message: 'This bridge does not have a tag in common with its surrounding ways that shows the purpose of this bridge. There should be one of these tags: $1'
+ },
+ 370: {
+ errorType: 370,
+ errorName: 'doubled places',
+ message: 'This node has tags in common with the surrounding way #$1 and seems to be redundand | This node has tags in common with the surrounding way #$1 (including the name \'$2\') and seems to be redundand'
+ },
+ 380: {
+ errorType: 380,
+ errorName: 'non-physical use of sportage',
+ message: 'This way is tagged $1 but has no physical tag like e.g. leisure, building, amenity or highway'
+ },
+ 400: {
+ errorType: 400,
+ errorName: 'geometry glitches',
+ message: '',
+ subTypes: {
+ 401: {
+ errorType: 401,
+ errorName: 'missing turn restrictions',
+ message: 'ways $1 and $2 join in a very sharp angle here and there is no oneway tag or turn restriction that prevents turning'
+ },
+ 402: {
+ errorType: 402,
+ errorName: 'impossible angles',
+ message: 'this way bends in a very sharp angle here'
+ },
+ }
+ },
+ 410: {
+ errorType: 410,
+ errorName: 'websites',
+ message: 'Web pages are analyzed. Web page is defined by any of the following tags website=*, url=*, website:mobile=*, contact:website=*, contact:url=*, image=*, source:website=* or source:url=*.',
+ subTypes: {
+ 411: {
+ errorType: 411,
+ errorName: 'http error',
+ message: 'The URL ($1) cannot be opened (HTTP status code $2)'
+ },
+ 412: {
+ errorType: 412,
+ errorName: 'domain hijacking',
+ message: 'Possible domain squatting: $1. Suspicious text is: "$2"'
+ },
+ 413: {
+ errorType: 413,
+ errorName: 'non-match',
+ message: 'Content of the URL ($1) did not contain these keywords: ($2)'
+ },
+ }
+ }
+ },
+ warnings: {
+ 20: {
+ errorType: 20,
+ errorName: 'multiple nodes on the same spot',
+ message: ' There is more than one node in this spot. Offending node IDs: $1'
+ },
+ 60: {
+ errorType: 60,
+ errorName: '',
+ message: ''
+ },
+ 300: {
+ errorType: 300,
+ errorName: 'missing maxspeed',
+ message: 'missing maxspeed tag'
+ },
+ 360: {
+ errorType: 360,
+ errorName: 'language unknown',
+ message: 'It would be nice if this $1 had an additional tag \'name:XX=$2\' where XX shows the language of its name \'$2\'.'
+ },
+ 390: {
+ errorType: 390,
+ errorName: 'missing tracktype',
+ message: 'This track doesn\'t have a tracktype'
+ },
+ },
+};
\ No newline at end of file
diff --git a/modules/services/keepRight.js b/modules/services/keepRight.js
index 01d80344f..20b62f2f5 100644
--- a/modules/services/keepRight.js
+++ b/modules/services/keepRight.js
@@ -8,6 +8,8 @@ import rbush from 'rbush';
import { dispatch as d3_dispatch } from 'd3-dispatch';
import { request as d3_request } from 'd3-request';
+import { geoExtent } from '../geo';
+
import {
utilRebind,
utilTiler,
@@ -24,18 +26,6 @@ var _keepRightZoom = 16;
var apiBase = 'https://www.keepright.at/export.php?';
-// TODO: remove this
- var schema = {
- 'error_type': '',
- 'object_type': '',
- 'object_id': '',
- 'comment': '',
- 'error_id':'',
- 'schema': '',
- 'description': '',
- 'title': ''
- };
-
function abortRequest(i) {
if (i) {
@@ -70,33 +60,34 @@ export default {
_keepRightCache = { loaded: {}, inflight: {}, keepRight: {}, rtree: rbush()};
},
- loadKeepRight: function(context, projection, keepRightOptions) {
- keepRightOptions = _extend({ 'format': 'geojson' });
+ loadKeepRight: function(context, projection, options, callback) {
+ options = _extend({ 'format': 'geojson' }, options);
if (_off) return;
+ var cache = _keepRightCache;
+
var that = this;
var path = apiBase +
- 'format=' + keepRightOptions.format +
- '&ch=' + keepRightOptions.ch.join() + '&';
+ 'format=' + options.format +
+ '&ch=' + options.ch.join() + '&';
// determine the needed tiles to cover the view
var tiles = tiler.zoomExtent([_keepRightZoom, _keepRightZoom]).getTiles(projection);
// abort inflight requests that are no longer needed
- var hadRequests = !_isEmpty(_keepRightCache.inflight);
- abortUnwantedRequests(_keepRightCache, tiles);
- if (hadRequests && _isEmpty(_keepRightCache.inflight)) {
+ var hadRequests = !_isEmpty(cache.inflight);
+ abortUnwantedRequests(cache, tiles);
+ if (hadRequests && _isEmpty(cache.inflight)) {
dispatch.call('loaded'); // stop the spinner
}
// issue new requests..
tiles.forEach(function(tile) {
- if (_keepRightCache.loaded[tile.id] || _keepRightCache.inflight[tile.id]) return;
- if (_isEmpty(_keepRightCache.inflight)) {
+ if (cache.loaded[tile.id] || cache.inflight[tile.id]) return;
+ if (_isEmpty(cache.inflight)) {
dispatch.call('loading'); // start the spinner
}
- var cache = _keepRightCache;
var rect = tile.extent.rectangle();
var nextPath = path +
utilQsString({
@@ -107,31 +98,78 @@ export default {
});
- function callbackExample() {
- // TODO: implement
- }
+ var options = {}; // TODO: implement
- var exampleOptions = {}; // TODO: implement
-
- _keepRightCache.inflight[tile.id] = that.loadFromAPI(
+ cache.inflight[tile.id] = that.loadFromAPI(
nextPath,
- callbackExample,
- exampleOptions
+ function(err, data) {
+ if (err || !data.features || !data.features.length) return;
+
+ cache.loaded[tile.id] = true;
+ delete cache.inflight[tile.id];
+
+ if (callback) {
+ callback(err, _extend({ data: data }, tile));
+ }
+ if (_isEmpty(cache.inflight)) {
+ dispatch.call('loaded'); // stop the spinner
+ }
+ },
+ options
);
});
},
loadFromAPI: function(path, callback, options) {
- var result = d3_request(path) // TODO: rturn or somethign, dont save to var
+ var cache = _keepRightCache;
+
+ return d3_request(path)
.mimeType('application/json') // TODO: only have this as a response if the input format is json
.header('Content-type', 'application/x-www-form-urlencoded')
.response(function(xhr) {
- console.log('xhr: ', xhr);
return JSON.parse(xhr.responseText);
})
.get(function(err, data) {
- console.log(data);
+
+ var features = data.features.map(function(feature) {
+ var loc = feature.geometry.coordinates;
+ var props = feature.properties;
+ var d = {
+ loc: loc,
+ comment: props.comment || null,
+ description: props.description || '',
+ error_id: props.error_id,
+ error_type: props.error_type,
+ object_id: props.object_id,
+ object_type: props.object_type,
+ schema: props.schema,
+ title: props.title
+ };
+
+ cache.keepRight[d.error_id] = d;
+
+ return {
+ minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
+ };
+
+ }).filter(Boolean);
+
+ cache.rtree.load(features);
+ dispatch.call('loadedKeepRight');
+
+ callback(err, data);
});
- console.log('result: ', result);
- }
+ },
+
+
+ // get all cached notes covering the viewport
+ keepRight: function(projection) {
+ var viewport = projection.clipExtent();
+ var min = [viewport[0][0], viewport[1][1]];
+ var max = [viewport[1][0], viewport[0][1]];
+ var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
+
+ return _keepRightCache.rtree.search(bbox)
+ .map(function(d) { return d.data; });
+ },
};
\ No newline at end of file
diff --git a/modules/svg/keepRight.js b/modules/svg/keepRight.js
index 6352a8cc0..d75f1b104 100644
--- a/modules/svg/keepRight.js
+++ b/modules/svg/keepRight.js
@@ -80,46 +80,53 @@ export function svgKeepRight(projection, context, dispatch) {
function update() {
- console.log('TAH - keepRight.update()');
- return;
var service = getService();
- var data = (service ? service.signs(projection) : []);
- var viewer = d3_select('#photoviewer');
- var selected = viewer.empty() ? undefined : viewer.datum();
- var selectedImageKey = selected && selected.key;
+ var selectedID = context.selectedNoteID(); // TODO: update with selectedErrorID
+ var data = (service ? service.keepRight(projection) : []);
var transform = svgPointTransform(projection);
-
- var signs = layer.selectAll('.icon-sign')
- .data(data, function(d) { return d.key; });
+ var kr_errors = layer.selectAll('.kr_error')
+ .data(data, function(d) { return d.error_id; });
// exit
- signs.exit()
+ kr_errors.exit()
.remove();
// enter
- var enter = signs.enter()
+ var kr_errorsEnter = kr_errors.enter()
+ .append('g')
+ .attr('class', function(d) { return 'kr_error kr_error-' + d.error_id; })
+ .classed('new', function(d) { return d.id < 0; });
+
+ kr_errorsEnter
+ .append('ellipse')
+ .attr('cx', 0.5)
+ .attr('cy', 1)
+ .attr('rx', 6.5)
+ .attr('ry', 3)
+ .attr('class', 'stroke');
+
+ // kr_errorsEnter
+ // .append('path')
+ // .call(markerPath, 'kr_error-shadow');
+
+ kr_errorsEnter
.append('use')
- .attr('class', 'icon-sign')
- .attr('width', '24px')
- .attr('height', '24px')
- .attr('x', '-12px')
- .attr('y', '-12px')
- .attr('xlink:href', function(d) { return '#' + d.value; })
- .classed('selected', function(d) {
- return _some(d.detections, function(detection) {
- return detection.image_key === selectedImageKey;
- });
- })
- .on('click', click);
+ .attr('class', 'kr_error-fill')
+ .attr('width', '20px')
+ .attr('height', '20px')
+ .attr('x', '-8px')
+ .attr('y', '-22px')
+ .attr('xlink:href', '#iD-icon-note'); // TODO: update icon
// update
- signs
- .merge(enter)
+ kr_errors
+ .merge(kr_errorsEnter)
.sort(function(a, b) {
- return (a === selected) ? 1
- : (b === selected) ? -1
+ return (a.id === selectedID) ? 1
+ : (b.id === selectedID) ? -1
: b.loc[1] - a.loc[1]; // sort Y
})
+ .classed('selected', function(d) { return d.id === selectedID; })
.attr('transform', transform);
}
@@ -140,14 +147,18 @@ export function svgKeepRight(projection, context, dispatch) {
.style('display', enabled ? 'block' : 'none')
.merge(layer);
+ function exampleCallback(value1, value2, value3) { // TODO: rename, possibly remove function
+ }
+
if (enabled) {
if (service && ~~context.map().zoom() >= minZoom) {
editOn();
update();
- var options = {
- ch: ['30', ]
+ var options = { // TODO: change out these options and place as default
+ ch: [0,30,40,50,70,90,100,110,120,130,150,160,170,180,191,192,193,194,195,196,197,198,201,202,203,204,205,206,207,208,210,220,231,232,270,281,282,283,284,285,291,292,293,294,295,296,297,298,311,312,313,320,350,370,380,401,402,411,412,413]
};
- service.loadKeepRight(context, projection, options);
+
+ service.loadKeepRight(context, projection, options, exampleCallback);
} else {
editOff();
}
diff --git a/modules/svg/layers.js b/modules/svg/layers.js
index b8810733f..59c9ab22c 100644
--- a/modules/svg/layers.js
+++ b/modules/svg/layers.js
@@ -9,12 +9,8 @@ import { select as d3_select } from 'd3-selection';
import { svgData } from './data';
import { svgDebug } from './debug';
-<<<<<<< HEAD
import { svgGeolocate } from './geolocate';
-=======
-import { svgGpx } from './gpx';
import { svgKeepRight } from './keepRight';
->>>>>>> added simple keepRight button under photoItems
import { svgStreetside } from './streetside';
import { svgMapillaryImages } from './mapillary_images';
import { svgMapillarySigns } from './mapillary_signs';
diff --git a/svg/iD-sprite/icons/icon-keepRight.svg b/svg/iD-sprite/icons/icon-keepRight.svg
new file mode 100644
index 000000000..0498225bb
--- /dev/null
+++ b/svg/iD-sprite/icons/icon-keepRight.svg
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/test/spec/svg/layers.js b/test/spec/svg/layers.js
index f2277229c..16aeed0ed 100644
--- a/test/spec/svg/layers.js
+++ b/test/spec/svg/layers.js
@@ -27,6 +27,7 @@ describe('iD.svgLayers', function () {
container.call(iD.svgLayers(projection, context));
var nodes = container.selectAll('svg .data-layer').nodes();
expect(nodes.length).to.eql(10);
+<<<<<<< HEAD
expect(d3.select(nodes[0]).classed('osm')).to.be.true;
expect(d3.select(nodes[1]).classed('notes')).to.be.true;
expect(d3.select(nodes[2]).classed('data')).to.be.true;
@@ -37,6 +38,18 @@ describe('iD.svgLayers', function () {
expect(d3.select(nodes[7]).classed('debug')).to.be.true;
expect(d3.select(nodes[8]).classed('geolocate')).to.be.true;
expect(d3.select(nodes[9]).classed('touch')).to.be.true;
+=======
+ expect(d3.select(nodes[0]).classed('data-layer-osm')).to.be.true;
+ expect(d3.select(nodes[1]).classed('data-layer-notes')).to.be.true;
+ expect(d3.select(nodes[2]).classed('data-layer-keepRight')).to.be.true;
+ expect(d3.select(nodes[3]).classed('data-layer-gpx')).to.be.true;
+ expect(d3.select(nodes[4]).classed('data-layer-mvt')).to.be.true;
+ expect(d3.select(nodes[5]).classed('data-layer-streetside')).to.be.true;
+ expect(d3.select(nodes[6]).classed('data-layer-mapillary-images')).to.be.true;
+ expect(d3.select(nodes[7]).classed('data-layer-mapillary-signs')).to.be.true;
+ expect(d3.select(nodes[8]).classed('data-layer-openstreetcam-images')).to.be.true;
+ expect(d3.select(nodes[9]).classed('data-layer-debug')).to.be.true;
+>>>>>>> displaying keep right (currently as notes)
});
});