mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
Use live bound object for imagery array, remove context.imagery() accessor
Also update documentation, closes #3359
This commit is contained in:
89
API.md
89
API.md
@@ -137,9 +137,79 @@ class.
|
||||
|
||||
Elements that are currently selected shall have the `.selected` class.
|
||||
|
||||
|
||||
## Customized Deployments
|
||||
|
||||
iD is used to edit data outside of the OpenStreetMap environment. There are some basic configuration steps to introduce custom presets, imagery and tag information.
|
||||
iD may be used to edit maps in a non-OpenStreetMap environment. This requires
|
||||
certain parts of the iD code to be replaced at runtime by custom code or data.
|
||||
|
||||
iD is written in a modular style and bundled with [rollup.js](http://rollupjs.org/),
|
||||
which makes hot code replacement tricky. (ES6 module exports are
|
||||
[immutable bindings](http://www.2ality.com/2015/07/es6-module-exports.html)).
|
||||
Because of this, the parts of iD which are designed for customization are exported
|
||||
as live bound objects that can be overriden at runtime _before initializing the iD context_.
|
||||
|
||||
### Services
|
||||
|
||||
The `iD.services` object includes code that talks to other web services.
|
||||
|
||||
To replace the OSM service with a custom service that exactly mimics the default OSM service:
|
||||
```js
|
||||
iD.services.osm = serviceMyOSM;
|
||||
```
|
||||
|
||||
Some services may be removed entirely. For example, to remove the Mapillary service:
|
||||
```js
|
||||
iD.services.mapillary = undefined;
|
||||
// or
|
||||
delete iD.services.mapillary;
|
||||
```
|
||||
|
||||
|
||||
### Background Imagery
|
||||
|
||||
iD's background imagery database is stored in the `iD.data.imagery` array and can be
|
||||
overridden. (Note that the "None" and "Custom" options will always be shown in the list)
|
||||
|
||||
To remove all imagery from iD:
|
||||
```js
|
||||
iD.data.imagery = [];
|
||||
```
|
||||
|
||||
To replace all imagery with a single source:
|
||||
```js
|
||||
iD.data.imagery = [{
|
||||
"id": "ExampleImagery",
|
||||
"name": "My Imagery",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c}.tiles.example.com/{z}/{x}/{y}.png"
|
||||
}];
|
||||
```
|
||||
|
||||
Each imagery source should have the following properties:
|
||||
* `id` - Unique identifier for this source (also used as a url paramater)
|
||||
* `name` - Display name for the source
|
||||
* `type` - Source type, currently only `tms` is supported
|
||||
* `template` - Url template, valid replacement tokens include:
|
||||
* `{z}`, `{x}`, `{y}` - for Z/X/Y scheme
|
||||
* `{-y}` or `{ty}` - for flipped Y
|
||||
* `{u}` - for quadtile scheme
|
||||
* `{switch:a,b,c}` - for parts of the url that can be cycled for connection parallelization
|
||||
|
||||
Optional properties:
|
||||
* `description` - A longer source description which, if included, will be displayed in a popup when viewing the background imagery list
|
||||
* `overlay` - If `true`, this is an overlay layer (a transparent layer rendered above base imagery layer). Defaults to `false`
|
||||
* `scaleExtent` - Allowable min and max zoom levels, defaults to `[0, 20]`
|
||||
* `polygon` - Array of coordinate rings within which imagery is valid. If omitted, imagery is assumed to be valid worldwide
|
||||
* `overzoom` - Can this imagery be scaled up when zooming in beyond the max zoom? Defaults to `true`
|
||||
* `terms_url` - Url to link to when displaying the imagery terms
|
||||
* `terms_html` - Html content to display in the imagery terms
|
||||
* `terms_text` - Text content to display in the imagery terms
|
||||
* `best` - If set to `true`, this imagery is considered "better than Bing" and may be chosen by default when iD starts. Will display with a star in the background imagery list. Defaults to `false`
|
||||
|
||||
For more details about the `iD.data.imagery` structure, see
|
||||
[`update_imagery.js`](https://github.com/openstreetmap/iD/blob/master/data/update_imagery.js).
|
||||
|
||||
|
||||
### Presets
|
||||
|
||||
@@ -148,27 +218,12 @@ iD can use external presets exclusively or along with the default OpenStreetMap
|
||||
```js
|
||||
|
||||
var id = iD.Context()
|
||||
.presets(customPresets)
|
||||
.imagery(iD.dataImagery);
|
||||
.presets(customPresets);
|
||||
|
||||
```
|
||||
|
||||
The format of the Preset object is [documented here](https://github.com/openstreetmap/iD/tree/master/data/presets#custom-presets).
|
||||
|
||||
### Imagery
|
||||
|
||||
Just like Presets, Imagery can be configured using the `context.imagery` accessor:
|
||||
|
||||
```js
|
||||
|
||||
var id = iD.Context()
|
||||
.presets(customPresets)
|
||||
.imagery(customImagery);
|
||||
|
||||
```
|
||||
|
||||
The Imagery object should follow the structure defined by [editor-layer-index](https://github.com/osmlab/editor-layer-index/blob/gh-pages/schema.json)
|
||||
|
||||
|
||||
### Minimum Editable Zoom
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ export { default as dataSuggestions } from 'name-suggestion-index/name-suggestio
|
||||
export { dataAddressFormats } from './address-formats.json';
|
||||
export { dataDeprecated } from './deprecated.json';
|
||||
export { dataDiscarded } from './discarded.json';
|
||||
export { dataImagery } from './imagery.json';
|
||||
export { dataLocales } from './locales.json';
|
||||
export { dataPhoneFormats } from './phone-formats.json';
|
||||
|
||||
@@ -24,3 +23,8 @@ export var dataPresets = {
|
||||
categories: categories,
|
||||
fields: fields
|
||||
};
|
||||
|
||||
import { dataImagery } from './imagery.json';
|
||||
export var data = {
|
||||
imagery: dataImagery
|
||||
};
|
||||
|
||||
5
dist/index.html
vendored
5
dist/index.html
vendored
@@ -37,9 +37,8 @@
|
||||
document.getElementById('id-container').innerHTML = 'Sorry, your browser is not currently supported. Please use Potlatch 2 to edit the map.';
|
||||
document.getElementById('id-container').className = 'unsupported';
|
||||
} else {
|
||||
var id = iD.Context(window)
|
||||
.presets(iD.dataPresets)
|
||||
.imagery(iD.dataImagery);
|
||||
var id = iD.Context()
|
||||
.presets(iD.dataPresets);
|
||||
|
||||
id.ui()(document.getElementById('id-container'));
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<body>
|
||||
<div id='id-container'></div>
|
||||
<script>
|
||||
|
||||
id = iD.Context()
|
||||
.presets(iD.dataPresets)
|
||||
.imagery(iD.dataImagery)
|
||||
.assetPath('dist/');
|
||||
|
||||
id.ui()(document.getElementById('id-container'), function() {
|
||||
|
||||
@@ -259,13 +259,6 @@ export function coreContext() {
|
||||
};
|
||||
|
||||
|
||||
/* Imagery */
|
||||
context.imagery = function(_) {
|
||||
background.load(_);
|
||||
return context;
|
||||
};
|
||||
|
||||
|
||||
/* Container */
|
||||
var container, embed;
|
||||
context.container = function(_) {
|
||||
@@ -347,7 +340,7 @@ export function coreContext() {
|
||||
context.reset = context.flush = function() {
|
||||
context.debouncedSave.cancel();
|
||||
_.each(services, function(service) {
|
||||
if (typeof service.reset === 'function') {
|
||||
if (service && typeof service.reset === 'function') {
|
||||
service.reset(context);
|
||||
}
|
||||
});
|
||||
@@ -407,10 +400,11 @@ export function coreContext() {
|
||||
context.zoomOutFurther = map.zoomOutFurther;
|
||||
context.redrawEnable = map.redrawEnable;
|
||||
|
||||
background.init();
|
||||
presets = presetInit();
|
||||
|
||||
_.each(services, function(service) {
|
||||
if (typeof service.init === 'function') {
|
||||
if (service && typeof service.init === 'function') {
|
||||
service.init(context);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { utilRebind } from '../util/rebind';
|
||||
import { data } from '../../data/index';
|
||||
import { geoExtent, geoMetersToOffset, geoOffsetToMeters} from '../geo/index';
|
||||
import { utilQsString, utilStringQs } from '../util/index';
|
||||
import { rendererBackgroundSource } from './background_source';
|
||||
import { rendererTileLayer } from './tile_layer';
|
||||
import { utilQsString, utilStringQs } from '../util/index';
|
||||
import { utilRebind } from '../util/rebind';
|
||||
|
||||
|
||||
export function rendererBackground(context) {
|
||||
@@ -191,7 +192,7 @@ export function rendererBackground(context) {
|
||||
};
|
||||
|
||||
|
||||
background.load = function(imagery) {
|
||||
background.init = function() {
|
||||
function parseMap(qmap) {
|
||||
if (!qmap) return false;
|
||||
var args = qmap.split('/').map(Number);
|
||||
@@ -199,12 +200,13 @@ export function rendererBackground(context) {
|
||||
return geoExtent([args[1], args[2]]);
|
||||
}
|
||||
|
||||
var q = utilStringQs(window.location.hash.substring(1)),
|
||||
var dataImagery = data.imagery || [],
|
||||
q = utilStringQs(window.location.hash.substring(1)),
|
||||
chosen = q.background || q.layer,
|
||||
extent = parseMap(q.map),
|
||||
best;
|
||||
|
||||
backgroundSources = imagery.map(function(source) {
|
||||
backgroundSources = dataImagery.map(function(source) {
|
||||
if (source.type === 'bing') {
|
||||
return rendererBackgroundSource.Bing(source, dispatch);
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as d3 from 'd3';
|
||||
import { geoPolygonIntersectsPolygon } from '../geo/index';
|
||||
import {
|
||||
data,
|
||||
dataImperial,
|
||||
dataDriveLeft,
|
||||
dataImagery
|
||||
dataDriveLeft
|
||||
} from '../../data/index';
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ export function svgDebug(projection, context) {
|
||||
|
||||
|
||||
var extent = context.map().extent(),
|
||||
dataImagery = data.imagery || [],
|
||||
availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
|
||||
if (!source.polygon) return false;
|
||||
return source.polygon.some(function(polygon) {
|
||||
|
||||
@@ -2,7 +2,7 @@ describe('iD.behaviorLasso', function () {
|
||||
var lasso, context;
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context().imagery(iD.dataImagery);
|
||||
context = iD.Context();
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
|
||||
// Neuter connection
|
||||
|
||||
@@ -3,7 +3,7 @@ describe('iD.behaviorSelect', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
container = d3.select('body').append('div');
|
||||
context = iD.Context().imagery(iD.dataImagery).container(container);
|
||||
context = iD.Context().container(container);
|
||||
|
||||
a = iD.Node({loc: [0, 0]});
|
||||
b = iD.Node({loc: [0, 0]});
|
||||
|
||||
@@ -6,7 +6,6 @@ describe.skip('iD.modeAddPoint', function() {
|
||||
|
||||
context = iD.Context()
|
||||
.presets(iD.dataPresets)
|
||||
.imagery([])
|
||||
.container(container);
|
||||
|
||||
context.loadTiles = function () {};
|
||||
|
||||
@@ -2,7 +2,7 @@ describe('iD.Map', function() {
|
||||
var context, map;
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context().imagery(iD.dataImagery);
|
||||
context = iD.Context();
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
map = context.map();
|
||||
d3.select(document.createElement('div'))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* globals chai:false */
|
||||
|
||||
iD.debug = true;
|
||||
iD.data.imagery = [];
|
||||
|
||||
mocha.setup({
|
||||
ui: 'bdd',
|
||||
|
||||
Reference in New Issue
Block a user