diff --git a/API.md b/API.md
index 3a506b020..9263c1831 100644
--- a/API.md
+++ b/API.md
@@ -34,6 +34,10 @@ in the hash portion of the URL:
_Example:_ `hashtags=%23hotosm-task-592,%23MissingMaps`
* __`rtl=true`__ - Force iD into right-to-left mode (useful for testing).
* __`walkthrough=true`__ - Start the walkthrough automatically
+* __`features`__ - Enables features in the list.
+ _Example:_ `features=water,service_roads,points,paths`
+ _Available features:_ `points` `traffic_roads` `service_roads` `paths` `buildings` `landuse`
+ `boundaries` `water` `rail` `power` `past_future` `others`
##### iD on openstreetmap.org (Rails Port)
@@ -50,6 +54,7 @@ are available as regular URL query parameters:
* __`comment`__ - same as standalone
* __`hashtags`__ - same as standalone
* __`walkthrough`__ - same as standalone
+* __`features`__ - same as standalone
## CSS selectors
diff --git a/modules/renderer/features.js b/modules/renderer/features.js
index 281e27da4..23f58b94c 100644
--- a/modules/renderer/features.js
+++ b/modules/renderer/features.js
@@ -3,11 +3,16 @@ import _groupBy from 'lodash-es/groupBy';
import _reduce from 'lodash-es/reduce';
import _some from 'lodash-es/some';
import _union from 'lodash-es/union';
+import _get from 'lodash-es/get';
import { dispatch as d3_dispatch } from 'd3-dispatch';
import { osmEntity } from '../osm';
import { utilRebind } from '../util/rebind';
+import {
+ utilQsString,
+ utilStringQs
+} from '../util';
export function rendererFeatures(context) {
@@ -60,10 +65,19 @@ export function rendererFeatures(context) {
_features = {},
_stats = {},
_keys = [],
- _hidden = [];
+ _hidden = [],
+ _initFeaturesStr = _get(utilStringQs(window.location.hash.substring(1)), 'features', '').trim();
function update() {
+ var q = utilStringQs(window.location.hash.substring(1));
+
+ q.features = context.features().enabledList();
+
+ if (!window.mocha) {
+ window.location.replace('#' + utilQsString(q, true));
+ }
+
_hidden = features.hidden();
dispatch.call('change');
dispatch.call('redraw');
@@ -71,10 +85,16 @@ export function rendererFeatures(context) {
function defineFeature(k, filter, max) {
+ var isEnabled = true;
+
+ if (_initFeaturesStr.length) {
+ isEnabled = _initFeaturesStr.split(',').some(function(key){ return key === k; });
+ }
+
_keys.push(k);
_features[k] = {
filter: filter,
- enabled: true, // whether the user wants it enabled..
+ enabled: isEnabled, // whether the user wants it enabled..
count: 0,
currentMax: (max || Infinity),
defaultMax: (max || Infinity),
@@ -197,6 +217,10 @@ export function rendererFeatures(context) {
return _features[k] && _features[k].enabled;
};
+ features.enabledList = function () {
+ return _keys.filter(function(k) { return _features[k].enabled; });
+ };
+
features.disabled = function(k) {
if (!arguments.length) {
@@ -229,6 +253,28 @@ export function rendererFeatures(context) {
}
};
+ features.enableList = function (enabledKeys) {
+ var keysForToggle = {};
+
+ for (var i = 0; i < _keys.length; i++) {
+ keysForToggle[_keys[i]] = false;
+ }
+
+ for (i = 0; i < enabledKeys.length; i++) {
+ if (_features[enabledKeys[i]]) {
+ keysForToggle[enabledKeys[i]] = true;
+ }
+ }
+
+ for (i = 0; i < _keys.length; i++) {
+ if (keysForToggle[_keys[i]]) {
+ _features[_keys[i]].enable();
+ } else {
+ _features[_keys[i]].disable();
+ }
+ }
+ };
+
features.disable = function(k) {
if (_features[k] && _features[k].enabled) {