Commit 90fd1e3f authored by Bryan Housel's avatar Bryan Housel

Support setting imagery offset via url hash

(closes #3093)
parent 9fd96297
This file documents efforts toward establishing a public API for iD, one that
can support plugin development.
This file documents efforts toward establishing a public API for iD.
## URL parameters
##### iD Standalone
iD supports several URL parameters. When constructing a URL to a standalone instance
of iD (e.g. `http://openstreetmap.us/iD/release/`), the following parameters are available
in the hash portion of the URL:
* `map` - A slash separated zoom level, longitude, and latitude. Example:
`map=20.00/-77.02271/38.90085`.
* `map` - A slash separated `zoom/longitude/latitude`. Example:
`map=20.00/-77.02271/38.90085`
* `id` - The character 'n', 'w', or 'r', followed by the OSM ID of a node,
way or relation, respectively. Selects the specified entity, and, unless
a `map` parameter is also provided, centers the map on it.
......@@ -17,20 +18,32 @@ in the hash portion of the URL:
or a custom tile URL. A custom URL is specified in the format `custom:<url>`,
where the URL can contain the standard tile URL placeholders `{x}`, `{y}` and
`{z}`/`{zoom}`, `{ty}` for flipped TMS-style Y coordinates, and `{switch:a,b,c}` for
DNS multiplexing. Example:
DNS multiplexing. Example:
`background=custom:http://{switch:a,b,c}.tiles.mapbox.com/v4/examples.map-4l7djmvo/{z}/{x}/{y}.png`
* `gpx` - A custom URL for loading a gpx track. Specifying a `gpx` parameter will
automatically enable the gpx layer for display. Example:
`gpx=https://tasks.hotosm.org/project/592/task/16.gpx`
* `offset` - imagery offset in meters, formatted as `east,north`. Example:
`offset=-10,5`
* `comment` - Prefills the changeset comment box, for use when integrating iD with
external task management or quality assurance tools. Example:
external task management or quality assurance tools. Example:
`comment=CAR%20crisis%2C%20refugee%20areas%20in%20Cameroon%20%23hotosm-task-592`.
##### iD on openstreetmap.org (Rails Port)
When constructing a URL to an instance of iD embedded in the OpenStreetMap Rails
Port (e.g. `http://www.openstreetmap.org/edit?editor=id`), the following parameters
are available as regular URL query parameters:
* `map` - slash separated `zoom/latitude/longitude`. Example:
`map=20.00/38.90085/-77.02271`.
* `lat`, `lon`, `zoom` - Self-explanatory.
* `node`, `way`, `relation` - Select the specified entity.
* `background` - same as standalone
* `gpx` - same as standalone
* `offset` - same as standalone
* `comment` - same as standalone
In addition, the `background` parameter is available as a hash parameter as above.
## CSS selectors
......
......@@ -48,6 +48,28 @@ iD.geo.metersToLon = function(m, atLat) {
m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
};
iD.geo.offsetToMeters = function(offset) {
var equatRadius = 6356752.314245179,
polarRadius = 6378137.0,
tileSize = 256;
return [
offset[0] * 2 * Math.PI * equatRadius / tileSize,
-offset[1] * 2 * Math.PI * polarRadius / tileSize
];
};
iD.geo.metersToOffset = function(meters) {
var equatRadius = 6356752.314245179,
polarRadius = 6378137.0,
tileSize = 256;
return [
meters[0] * tileSize / (2 * Math.PI * equatRadius),
-meters[1] * tileSize / (2 * Math.PI * polarRadius)
];
};
// Equirectangular approximation of spherical distances on Earth
iD.geo.sphericalDistance = function(a, b) {
var x = iD.geo.lonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
......
......@@ -197,12 +197,26 @@ iD.Background = function(context) {
var overlays = (q.overlays || '').split(',');
overlays.forEach(function(overlay) {
overlay = findSource(overlay);
if (overlay) background.toggleOverlayLayer(overlay);
if (overlay) {
background.toggleOverlayLayer(overlay);
}
});
if (q.gpx) {
var gpx = context.layers().layer('gpx');
if (gpx) { gpx.url(q.gpx); }
if (gpx) {
gpx.url(q.gpx);
}
}
if (q.offset) {
var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
return !isNaN(n) && n;
});
if (offset.length === 2) {
background.offset(iD.geo.metersToOffset(offset));
}
}
};
......
......@@ -140,30 +140,8 @@ iD.ui.Background = function(context) {
updateOffsetVal();
}
function offsetToMeters(offset) {
var equatRadius = 6356752.314245179,
polarRadius = 6378137.0,
tileSize = 256;
return [
offset[0] * 2 * Math.PI * equatRadius / tileSize,
-offset[1] * 2 * Math.PI * polarRadius / tileSize
];
}
function metersToOffset(meters) {
var equatRadius = 6356752.314245179,
polarRadius = 6378137.0,
tileSize = 256;
return [
meters[0] * tileSize / (2 * Math.PI * equatRadius),
-meters[1] * tileSize / (2 * Math.PI * polarRadius)
];
}
function updateOffsetVal() {
var meters = offsetToMeters(context.background().offset()),
var meters = iD.geo.offsetToMeters(context.background().offset()),
x = +meters[0].toFixed(2),
y = +meters[1].toFixed(2);
......@@ -219,7 +197,7 @@ iD.ui.Background = function(context) {
return;
}
context.background().offset(metersToOffset(d));
context.background().offset(iD.geo.metersToOffset(d));
updateOffsetVal();
}
......
......@@ -131,6 +131,32 @@ describe('iD.geo', function() {
});
});
describe('.offsetToMeters', function() {
it('[0, 0] pixel offset is [0, -0] meter offset', function() {
var meters = iD.geo.offsetToMeters([0, 0]);
expect(meters[0]).to.eql(0);
expect(meters[1]).to.eql(-0);
});
it('[0.00064, -0.00064] pixel offset is roughly [100, 100] meter offset', function() {
var meters = iD.geo.offsetToMeters([0.00064, -0.00064]);
expect(meters[0]).to.be.within(99.5, 100.5);
expect(meters[1]).to.be.within(99.5, 100.5);
});
});
describe('.metersToOffset', function() {
it('[0, 0] meter offset is [0, -0] pixel offset', function() {
var offset = iD.geo.metersToOffset([0, 0]);
expect(offset[0]).to.eql(0);
expect(offset[1]).to.eql(-0);
});
it('[100, 100] meter offset is roughly [0.00064, -0.00064] pixel offset', function() {
var offset = iD.geo.metersToOffset([100, 100]);
expect(offset[0]).to.be.within(0.000635, 0.000645);
expect(offset[1]).to.be.within(-0.000645, -0.000635);
});
});
describe('.sphericalDistance', function() {
it('distance between two same points is zero', function() {
var a = [0, 0],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment