mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Merge branch 'info-box'
This commit is contained in:
@@ -5,10 +5,4 @@ node_js:
|
||||
- "8"
|
||||
sudo: required
|
||||
after_success:
|
||||
- if [[ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "master" ]]; then exit 0; fi
|
||||
- pip install virtualenv
|
||||
- virtualenv ~/env
|
||||
- source ~/env/bin/activate
|
||||
- pip install transifex-client
|
||||
- sudo echo $'[https://www.transifex.com]\nhostname = https://www.transifex.com\nusername = '"$TRANSIFEX_USER"$'\npassword = '"$TRANSIFEX_PASSWORD"$'\n' > ~/.transifexrc
|
||||
- tx push -s
|
||||
- ./scripts/txpush.sh
|
||||
|
||||
@@ -2484,13 +2484,16 @@ img.tile {
|
||||
}
|
||||
|
||||
.tile-label-debug {
|
||||
font-size: 10px;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 128px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
z-index: 2;
|
||||
margin-left: -50px;
|
||||
margin-top: -20px;
|
||||
|
||||
transform-origin:0 0;
|
||||
-ms-transform-origin:0 0;
|
||||
@@ -2505,7 +2508,7 @@ img.tile {
|
||||
}
|
||||
|
||||
img.tile-debug {
|
||||
border: 1px solid red;
|
||||
outline: 1px solid red;
|
||||
}
|
||||
|
||||
img.tile-loaded {
|
||||
@@ -2644,38 +2647,96 @@ img.tile-removing {
|
||||
|
||||
/* Info Box
|
||||
------------------------------------------------------- */
|
||||
.infobox {
|
||||
.info-panels {
|
||||
display: flex;
|
||||
flex-flow: row-reverse wrap-reverse;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 0;
|
||||
bottom: 30px;
|
||||
width: 240px;
|
||||
border-radius: 4px 0 0 0;
|
||||
border-bottom: 1px solid black;
|
||||
-ms-user-select: element;
|
||||
}
|
||||
|
||||
.infobox .infobox-heading {
|
||||
display: block;
|
||||
border-radius: 4px 0 0 0;
|
||||
padding: 5px 10px;
|
||||
height: 30px;
|
||||
.info-panels h1,
|
||||
.info-panels h2,
|
||||
.info-panels h3,
|
||||
.info-panels h4,
|
||||
.info-panels h5 {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.infobox ul {
|
||||
.info-panels h1,
|
||||
.info-panels h2,
|
||||
.info-panels h3 {
|
||||
color: #ff8;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
flex: 0 0 auto;
|
||||
margin: 2px 0 0 2px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.75);
|
||||
padding-bottom: 10px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.panel-container .panel-title {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.infobox .button {
|
||||
position: absolute;
|
||||
.panel-title button.close {
|
||||
float: right;
|
||||
height: 20px;
|
||||
background: none;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.panel-title button.close:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.panel-title button.close .icon {
|
||||
height: 20px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.panel-content {
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-content .button {
|
||||
display: inline-block;
|
||||
background: #7092ff;
|
||||
border-radius: 2px;
|
||||
padding: 0 4px;
|
||||
margin-top: 10px;
|
||||
color: white;
|
||||
top: 40px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.panel-content-history .links a {
|
||||
margin-left: 10px;
|
||||
}
|
||||
[dir='rtl'] .panel-content-history .links a {
|
||||
margin-left: auto;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.panel-content-history .view-history-on-osm {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.panel-content-location .location-info {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* About Section
|
||||
------------------------------------------------------- */
|
||||
|
||||
@@ -3111,6 +3172,7 @@ img.tile-removing {
|
||||
|
||||
.modal-shortcuts .modal-section:last-child {
|
||||
padding-top: 10px;
|
||||
min-height: 275px;
|
||||
}
|
||||
|
||||
.modal-shortcuts .tabs-bar {
|
||||
@@ -3145,6 +3207,11 @@ img.tile-removing {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.modal-shortcuts .shortcut-tab-tools .shortcut-column {
|
||||
flex: 1 1 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal-shortcuts td {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
@@ -272,19 +272,44 @@ en:
|
||||
contributors:
|
||||
list: "Edits by {users}"
|
||||
truncated_list: "Edits by {users} and {count} others"
|
||||
infobox:
|
||||
info_panels:
|
||||
key: I
|
||||
selected: "{n} selected"
|
||||
geometry: Geometry
|
||||
closed: closed
|
||||
center: Center
|
||||
perimeter: Perimeter
|
||||
length: Length
|
||||
area: Area
|
||||
centroid: Centroid
|
||||
location: Location
|
||||
metric: Metric
|
||||
imperial: Imperial
|
||||
background:
|
||||
key: B
|
||||
title: Background
|
||||
zoom: Zoom
|
||||
vintage: Vintage
|
||||
unknown: Unknown
|
||||
show_tiles: Show Tiles
|
||||
hide_tiles: Hide Tiles
|
||||
history:
|
||||
key: H
|
||||
title: History
|
||||
selected: "{n} selected"
|
||||
version: Version
|
||||
last_edit: Last Edit
|
||||
edited_by: Edited By
|
||||
changeset: Changeset
|
||||
unknown: Unknown
|
||||
link_text: History on openstreetmap.org
|
||||
location:
|
||||
key: L
|
||||
title: Location
|
||||
unknown_location: Unknown Location
|
||||
measurement:
|
||||
key: M
|
||||
title: Measurement
|
||||
selected: "{n} selected"
|
||||
geometry: Geometry
|
||||
closed: closed
|
||||
center: Center
|
||||
perimeter: Perimeter
|
||||
length: Length
|
||||
area: Area
|
||||
centroid: Centroid
|
||||
location: Location
|
||||
metric: Metric
|
||||
imperial: Imperial
|
||||
geometry:
|
||||
point: point
|
||||
vertex: vertex
|
||||
@@ -1076,7 +1101,6 @@ en:
|
||||
lasso: "Draw a selection lasso around features"
|
||||
with_selected:
|
||||
title: "With feature selected"
|
||||
infobox: "Toggle info / measurement box"
|
||||
edit_menu: "Toggle edit menu"
|
||||
vertex_selected:
|
||||
title: "With node selected"
|
||||
@@ -1116,3 +1140,12 @@ en:
|
||||
undo: "Undo last action"
|
||||
redo: "Redo last action"
|
||||
save: "Save changes"
|
||||
tools:
|
||||
title: "Tools"
|
||||
info:
|
||||
title: "Information"
|
||||
all: "Toggle all information panels"
|
||||
background: "Toggle background panel"
|
||||
history: "Toggle history panel"
|
||||
location: "Toggle location panel"
|
||||
measurement: "Toggle measurement panel"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
"name": "2013 aerial imagery for San Juan County WA",
|
||||
"type": "tms",
|
||||
"template": "http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2013_WM/MapServer/tile/{zoom}/{y}/{x}",
|
||||
"endDate": "2013-06-01T00:00:00.000Z",
|
||||
"startDate": "2013-05-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
19
|
||||
@@ -162,6 +164,8 @@
|
||||
"name": "2016 aerial imagery for San Juan County WA",
|
||||
"type": "tms",
|
||||
"template": "http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2016_WM/MapServer/tile/{zoom}/{y}/{x}",
|
||||
"endDate": "2016-07-01T00:00:00.000Z",
|
||||
"startDate": "2016-05-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
19
|
||||
@@ -1631,6 +1635,8 @@
|
||||
"name": "Basemap geoportail.lu",
|
||||
"type": "tms",
|
||||
"template": "https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/basemap/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2010-07-20T00:00:00.000Z",
|
||||
"startDate": "2013-07-19T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -6528,6 +6534,8 @@
|
||||
"name": "British Columbia Mosaic",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c,d}.imagery.paulnorman.ca/tiles/bc_mosaic/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2013-06-01T00:00:00.000Z",
|
||||
"startDate": "2009-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
9,
|
||||
20
|
||||
@@ -8645,6 +8653,8 @@
|
||||
"name": "City of Cape Town 2013 Aerial",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2013/{zoom}/{x}/{y}.jpg",
|
||||
"endDate": "2015-01-01T00:00:00.000Z",
|
||||
"startDate": "2013-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
1,
|
||||
21
|
||||
@@ -9450,6 +9460,8 @@
|
||||
"name": "City of Cape Town 2015 Aerial",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2015/{zoom}/{x}/{y}.jpg",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2015-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
1,
|
||||
21
|
||||
@@ -14343,6 +14355,8 @@
|
||||
"name": "FÖMI orthophoto 2000",
|
||||
"type": "tms",
|
||||
"template": "http://e.tile.openstreetmap.hu/ortofoto2000/{zoom}/{x}/{y}.jpg",
|
||||
"endDate": "2000-01-01T00:00:00.000Z",
|
||||
"startDate": "2000-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
17
|
||||
@@ -16651,6 +16665,8 @@
|
||||
"name": "FÖMI orthophoto 2005",
|
||||
"type": "tms",
|
||||
"template": "http://e.tile.openstreetmap.hu/ortofoto2005/{zoom}/{x}/{y}.jpg",
|
||||
"endDate": "2005-01-01T00:00:00.000Z",
|
||||
"startDate": "2005-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
17
|
||||
@@ -24559,6 +24575,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Adams Bridge",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R119_N09_20160327T050917&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-03-27T00:00:00.000Z",
|
||||
"startDate": "2016-03-27T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -24597,6 +24615,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Alaska Range",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80700162014211LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2014-07-31T00:00:00.000Z",
|
||||
"startDate": "2014-07-31T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -24639,6 +24659,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Bakun Reservoir",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81190582014075LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2014-03-16T00:00:00.000Z",
|
||||
"startDate": "2014-03-16T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -24681,6 +24703,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Batam",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81250592016107LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2014-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -24719,6 +24743,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Bouvet Island",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81800982013291LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-10-18T00:00:00.000Z",
|
||||
"startDate": "2013-10-18T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -24758,6 +24784,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Cental Alps in late September 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R065_N47_20160929T102022&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-09-29T00:00:00.000Z",
|
||||
"startDate": "2016-09-29T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -24808,6 +24836,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Clerke Rocks",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82050982015344LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-12-10T00:00:00.000Z",
|
||||
"startDate": "2015-12-10T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -24850,6 +24880,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Coropuna",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=EO1A0040712016264110KF&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-09-21T00:00:00.000Z",
|
||||
"startDate": "2016-09-21T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -24896,6 +24928,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Cotonou",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R022_N06_20151221T103009&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-12-21T00:00:00.000Z",
|
||||
"startDate": "2015-12-21T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -24938,6 +24972,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Darwin and Wolf islands, Galapagos",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R040_N01_20160311T164128&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-03-11T00:00:00.000Z",
|
||||
"startDate": "2016-03-11T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -24976,6 +25012,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Eastern Devon Island coast",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80360072014245LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2014-09-02T00:00:00.000Z",
|
||||
"startDate": "2014-09-02T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
11
|
||||
@@ -25014,6 +25052,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Eastern Iceland",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82160152013239LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-08-27T00:00:00.000Z",
|
||||
"startDate": "2013-08-27T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -25052,6 +25092,8 @@
|
||||
"name": "imagico.de OSM images for mapping: El Altar",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00302052007154424_20150518041444_91492&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2012-02-05T00:00:00.000Z",
|
||||
"startDate": "2012-02-05T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -25090,6 +25132,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Elephant Island/Clarence Island",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R009_S61_20160109&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-01-09T00:00:00.000Z",
|
||||
"startDate": "2016-01-09T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -25132,6 +25176,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Enderby Land and Kemp Coast",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=enderby&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2017-03-27T00:00:00.000Z",
|
||||
"startDate": "2017-01-25T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -25182,6 +25228,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Fogo, Cape Verde",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82100502015347LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-12-13T00:00:00.000Z",
|
||||
"startDate": "2015-12-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -25220,6 +25268,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Greenland mosaic",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=greenland&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-01-01T00:00:00.000Z",
|
||||
"startDate": "2013-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -25870,6 +25920,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Heard Island coast",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R047_S54_20160411T044330&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-04-12T00:00:00.000Z",
|
||||
"startDate": "2016-04-12T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -25912,6 +25964,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Isla Londonderry",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82280982013259LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-09-16T00:00:00.000Z",
|
||||
"startDate": "2013-09-16T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -25962,6 +26016,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Kerch Strait",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R021_N44_20160807T083013&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-08-07T00:00:00.000Z",
|
||||
"startDate": "2016-08-07T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26000,6 +26056,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Landsat off-nadir July 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=ls_polar2&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-07-17T00:00:00.000Z",
|
||||
"startDate": "2016-07-17T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26050,6 +26108,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Leskov Island ASTER",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00311162013112731_20150618142416_109190&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-11-16T00:00:00.000Z",
|
||||
"startDate": "2013-11-16T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26088,6 +26148,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Leskov Island Landsat",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81991002015286LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-10-13T00:00:00.000Z",
|
||||
"startDate": "2015-10-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26130,6 +26192,8 @@
|
||||
"name": "imagico.de OSM images for mapping: May 2013 off-nadir Landsat",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=ls_polar&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-05-17T00:00:00.000Z",
|
||||
"startDate": "2013-05-17T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26200,6 +26264,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Mount Kenya 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S02_20160613T075613&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-06-13T00:00:00.000Z",
|
||||
"startDate": "2016-06-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26238,6 +26304,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Mount Kilimanjaro 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S05_20160802T075556&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-08-02T00:00:00.000Z",
|
||||
"startDate": "2016-08-02T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26276,6 +26344,8 @@
|
||||
"name": "imagico.de OSM images for mapping: New Ireland",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80940622015159LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-06-08T00:00:00.000Z",
|
||||
"startDate": "2015-06-08T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26314,6 +26384,8 @@
|
||||
"name": "imagico.de OSM images for mapping: North Sea Coast 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=northsea_s2_2016&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-09-25T00:00:00.000Z",
|
||||
"startDate": "2016-09-25T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26360,6 +26432,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern and Polar Ural mountains August 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=ural_s2_2016&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-08-12T00:00:00.000Z",
|
||||
"startDate": "2016-08-12T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26406,6 +26480,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern Ellesmere Island",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2012-07-09T00:00:00.000Z",
|
||||
"startDate": "2012-07-09T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26452,6 +26528,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern Ellesmere Island July 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast_2016&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2012-07-15T00:00:00.000Z",
|
||||
"startDate": "2012-07-08T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26502,6 +26580,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern German west coast tidalflats",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00vis&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-08-21T00:00:00.000Z",
|
||||
"startDate": "2015-08-21T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -26544,6 +26624,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern German west coast tidalflats (infrared)",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00ir&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-08-21T00:00:00.000Z",
|
||||
"startDate": "2015-08-21T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -26586,6 +26668,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northern Greenland ASTER",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=ngreenland_ast&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2012-08-13T00:00:00.000Z",
|
||||
"startDate": "2005-06-21T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26644,6 +26728,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Northwest Heard Island",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=EO1A1350972013086110KF&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-03-13T00:00:00.000Z",
|
||||
"startDate": "2013-03-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26690,6 +26776,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Panama Canal",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R111_N09_20160604T154554&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-06-07T00:00:00.000Z",
|
||||
"startDate": "2016-06-07T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26728,6 +26816,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Panama Canal - Pacific side",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=EO1A0120532016364110KF&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-12-30T00:00:00.000Z",
|
||||
"startDate": "2016-12-30T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26774,6 +26864,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Pechora Sea Coast",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N68_20160930T081002&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-09-30T00:00:00.000Z",
|
||||
"startDate": "2016-09-30T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -26832,6 +26924,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Pensacola Mountains",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81511242016033LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-02-02T00:00:00.000Z",
|
||||
"startDate": "2016-02-02T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -26878,6 +26972,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Prokletije Mountains",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R136_N41_20150831T093006&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-08-31T00:00:00.000Z",
|
||||
"startDate": "2015-08-31T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -26916,6 +27012,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Qasigiannguit",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=DMS_1142622_03746_20110415_17533956&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2011-04-15T00:00:00.000Z",
|
||||
"startDate": "2011-04-15T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
15
|
||||
@@ -26954,6 +27052,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Rann of Kutch",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81510432015030LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-01-01T00:00:00.000Z",
|
||||
"startDate": "2015-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -26996,6 +27096,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Rila and Pirin Mountains",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R093_N41_20150828T092005&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-08-28T00:00:00.000Z",
|
||||
"startDate": "2015-08-28T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -27038,6 +27140,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Rwenzori Mountains",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81730602015040LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-02-09T00:00:00.000Z",
|
||||
"startDate": "2015-02-09T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27076,6 +27180,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Rwenzori Mountains 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N01_20160702T082522&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-07-02T00:00:00.000Z",
|
||||
"startDate": "2016-07-02T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -27114,6 +27220,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Scott Island",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80611072014036LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2014-02-05T00:00:00.000Z",
|
||||
"startDate": "2014-02-05T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27152,6 +27260,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Shag Rocks",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82100972015347LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-12-13T00:00:00.000Z",
|
||||
"startDate": "2015-12-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27190,6 +27300,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Southeastern Sulawesi",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81130622013270LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-09-27T00:00:00.000Z",
|
||||
"startDate": "2013-09-27T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27236,6 +27348,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Southern Transantarctic Mountains",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80281222016035LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-02-04T00:00:00.000Z",
|
||||
"startDate": "2016-02-04T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
10
|
||||
@@ -27294,6 +27408,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Svalbard mosaic",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=s2sval&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2016-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27404,6 +27520,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Thule Air Base",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=DMS_1142636_160xx_20110507_1822xxxx&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2011-05-07T00:00:00.000Z",
|
||||
"startDate": "2011-05-07T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
15
|
||||
@@ -27450,6 +27568,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Thule Airbase DMS low altitude overflight September 2015",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=dms_thule2_2015.09.25&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-09-25T00:00:00.000Z",
|
||||
"startDate": "2015-09-25T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
17
|
||||
@@ -27504,6 +27624,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Thule Airbase DMS overflight October 2015",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.10.06&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-10-06T00:00:00.000Z",
|
||||
"startDate": "2015-10-06T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
16
|
||||
@@ -27554,6 +27676,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Thule Airbase DMS overflight September 2015",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.09.25&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2015-09-25T00:00:00.000Z",
|
||||
"startDate": "2015-09-25T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
16
|
||||
@@ -27600,6 +27724,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Ushakov Island August 2016",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R094_N79_20160812T105622&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-08-12T00:00:00.000Z",
|
||||
"startDate": "2016-08-12T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
12
|
||||
@@ -27638,6 +27764,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Vanatinai",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC80910682014358LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2014-12-24T00:00:00.000Z",
|
||||
"startDate": "2014-12-24T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27680,6 +27808,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Volcán Calbuco",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC82330892016031LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-01-31T00:00:00.000Z",
|
||||
"startDate": "2016-01-31T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27722,6 +27852,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Vostochny Cosmodrome",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R089_N52_20160623T024048&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-06-23T00:00:00.000Z",
|
||||
"startDate": "2016-06-23T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27760,6 +27892,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Western Karakoram",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=LC81490352013282LGN00&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2013-10-09T00:00:00.000Z",
|
||||
"startDate": "2013-10-09T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
13
|
||||
@@ -27798,6 +27932,8 @@
|
||||
"name": "imagico.de OSM images for mapping: Willkanuta Mountains and Quelccaya Ice Cap",
|
||||
"type": "tms",
|
||||
"template": "http://imagico.de/map/osmim_tiles.php?layer=S2A_R039_S15_20160510T145731&z={zoom}&x={x}&y={-y}",
|
||||
"endDate": "2016-05-10T00:00:00.000Z",
|
||||
"startDate": "2016-05-10T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
14
|
||||
@@ -28589,6 +28725,8 @@
|
||||
"name": "Kanton Aargau 25cm (AGIS 2011)",
|
||||
"type": "tms",
|
||||
"template": "http://tiles.poole.ch/AGIS/OF2011/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2011-01-01T00:00:00.000Z",
|
||||
"startDate": "2011-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
14,
|
||||
19
|
||||
@@ -29240,6 +29378,8 @@
|
||||
"name": "Kanton Aargau 25cm (AGIS 2014)",
|
||||
"type": "tms",
|
||||
"template": "http://mapproxy.osm.ch:8080/tiles/AGIS2014/EPSG900913/{zoom}/{x}/{y}.png?origin=nw",
|
||||
"endDate": "2014-01-01T00:00:00.000Z",
|
||||
"startDate": "2014-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
8,
|
||||
19
|
||||
@@ -29891,6 +30031,8 @@
|
||||
"name": "Kanton Aargau 25cm (AGIS 2016)",
|
||||
"type": "tms",
|
||||
"template": "http://mapproxy.osm.ch:8080/tiles/AGIS2016/EPSG900913/{zoom}/{x}/{y}.png?origin=nw",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2016-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
8,
|
||||
19
|
||||
@@ -32526,6 +32668,8 @@
|
||||
"name": "Kelowna 2012",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna2012/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2012-05-14T00:00:00.000Z",
|
||||
"startDate": "2012-05-13T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
9,
|
||||
20
|
||||
@@ -33324,6 +33468,8 @@
|
||||
"name": "Landsat 233055",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_233055/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2013-09-03T00:00:00.000Z",
|
||||
"startDate": "2013-09-03T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
5,
|
||||
14
|
||||
@@ -33359,6 +33505,8 @@
|
||||
"name": "Latest southwest British Columbia Landsat",
|
||||
"type": "tms",
|
||||
"template": "http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_047026/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2013-09-12T00:00:00.000Z",
|
||||
"startDate": "2013-09-12T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
5,
|
||||
13
|
||||
@@ -34067,6 +34215,8 @@
|
||||
"name": "Lithuania - NŽT ORT10LT",
|
||||
"type": "tms",
|
||||
"template": "http://ort10lt.openmap.lt/g16/{zoom}/{x}/{y}.jpeg",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2010-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
4,
|
||||
18
|
||||
@@ -36754,6 +36904,8 @@
|
||||
"name": "MD Latest 6 Inch Aerial Imagery",
|
||||
"type": "tms",
|
||||
"template": "http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/MD_SixInchImagery/http://geodata.md.gov/imap/services/Imagery/MD_SixInchImagery/MapServer/WmsServer",
|
||||
"endDate": "2016-01-01T00:00:00.000Z",
|
||||
"startDate": "2013-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -37641,6 +37793,8 @@
|
||||
"name": "NJ 2015 Aerial Imagery (Infrared)",
|
||||
"type": "tms",
|
||||
"template": "http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Infrared2015/http://geodata.state.nj.us/imagerywms/Infrared2015",
|
||||
"endDate": "2015-05-03T00:00:00.000Z",
|
||||
"startDate": "2015-03-29T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -38098,6 +38252,8 @@
|
||||
"name": "NJ 2015 Aerial Imagery (Natural Color)",
|
||||
"type": "tms",
|
||||
"template": "http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Natural2015/http://geodata.state.nj.us/imagerywms/Natural2015",
|
||||
"endDate": "2015-05-03T00:00:00.000Z",
|
||||
"startDate": "2015-03-29T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -45994,6 +46150,7 @@
|
||||
"name": "NLSC General Map with Contour line",
|
||||
"type": "tms",
|
||||
"template": "http://wmts.nlsc.gov.tw/wmts/EMAP5_OPENDATA/default/EPSG:3857/{zoom}/{y}/{x}",
|
||||
"startDate": "2015-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
15
|
||||
@@ -48853,6 +49010,8 @@
|
||||
"name": "Ortho 2010 geoportail.lu",
|
||||
"type": "tms",
|
||||
"template": "https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2010/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg",
|
||||
"endDate": "2010-07-02T00:00:00.000Z",
|
||||
"startDate": "2010-06-24T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -49774,6 +49933,8 @@
|
||||
"name": "Ortho 2013 geoportail.lu",
|
||||
"type": "tms",
|
||||
"template": "https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2013/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg",
|
||||
"endDate": "2013-07-20T00:00:00.000Z",
|
||||
"startDate": "2013-07-19T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -50695,6 +50856,8 @@
|
||||
"name": "Ortho 2016 geoportail.lu",
|
||||
"type": "tms",
|
||||
"template": "https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2016/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg",
|
||||
"endDate": "2016-08-16T00:00:00.000Z",
|
||||
"startDate": "2013-08-30T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -57237,6 +57400,7 @@
|
||||
"name": "Sóskút, Pusztazámor, Tárnok, Diósd ortophoto 2017",
|
||||
"type": "tms",
|
||||
"template": "http://adam.openstreetmap.hu/mapproxy/tiles/1.0.0/Soskut-Tarnok-Pusztazamor-Diosd/mercator/{zoom}/{x}/{y}.png",
|
||||
"startDate": "2017-03-01T00:00:00.000Z",
|
||||
"polygon": [
|
||||
[
|
||||
[
|
||||
@@ -64443,6 +64607,8 @@
|
||||
"name": "Surrey Air Survey",
|
||||
"type": "tms",
|
||||
"template": "http://gravitystorm.dev.openstreetmap.org/surrey/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2009-01-01T00:00:00.000Z",
|
||||
"startDate": "2007-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
8,
|
||||
19
|
||||
@@ -65162,6 +65328,7 @@
|
||||
"name": "Texas Orthophoto",
|
||||
"type": "tms",
|
||||
"template": "https://txgi.tnris.org/login/path/ecology-fiona-poem-romeo/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=texas&STYLE=&FORMAT=image/png&tileMatrixSet=0to20&tileMatrix=0to20:{zoom}&tileRow={y}&tileCol={x}",
|
||||
"startDate": "2012-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -65289,6 +65456,8 @@
|
||||
"name": "Topographical Map geoportail.lu",
|
||||
"type": "tms",
|
||||
"template": "https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/topo/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png",
|
||||
"endDate": "2010-07-20T00:00:00.000Z",
|
||||
"startDate": "2013-07-19T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -67258,6 +67427,8 @@
|
||||
"name": "Tours - Orthophotos 2008-2010",
|
||||
"type": "tms",
|
||||
"template": "http://wms.openstreetmap.fr/tms/1.0.0/tours/{zoom}/{x}/{y}",
|
||||
"endDate": "2011-01-01T00:00:00.000Z",
|
||||
"startDate": "2008-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
20
|
||||
@@ -67862,6 +68033,8 @@
|
||||
"name": "Tours - Orthophotos 2013",
|
||||
"type": "tms",
|
||||
"template": "http://wms.openstreetmap.fr/tms/1.0.0/tours_2013/{zoom}/{x}/{y}",
|
||||
"endDate": "2013-01-01T00:00:00.000Z",
|
||||
"startDate": "2013-01-01T00:00:00.000Z",
|
||||
"scaleExtent": [
|
||||
0,
|
||||
22
|
||||
|
||||
@@ -93,9 +93,8 @@
|
||||
"shortcuts": ["Right-click", "shortcuts.key.space"],
|
||||
"text": "shortcuts.browsing.with_selected.edit_menu"
|
||||
}, {
|
||||
"modifiers": ["⌘"],
|
||||
"shortcuts": ["infobox.key"],
|
||||
"text": "shortcuts.browsing.with_selected.infobox"
|
||||
"shortcuts": [],
|
||||
"text": ""
|
||||
},
|
||||
|
||||
{
|
||||
@@ -166,7 +165,7 @@
|
||||
"shortcuts": ["Z"],
|
||||
"text": "shortcuts.editing.commands.undo"
|
||||
}, {
|
||||
"modifiers": ["⌘","⇧"],
|
||||
"modifiers": ["⌘", "⇧"],
|
||||
"shortcuts": ["Z"],
|
||||
"text": "shortcuts.editing.commands.redo"
|
||||
}, {
|
||||
@@ -221,5 +220,38 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"tab": "tools",
|
||||
"text": "shortcuts.tools.title",
|
||||
"columns" : [
|
||||
{
|
||||
"rows": [
|
||||
{
|
||||
"section": "info",
|
||||
"text": "shortcuts.tools.info.title"
|
||||
}, {
|
||||
"modifiers": ["⌘"],
|
||||
"shortcuts": ["info_panels.key"],
|
||||
"text": "shortcuts.tools.info.all"
|
||||
}, {
|
||||
"modifiers": ["⌘", "⇧"],
|
||||
"shortcuts": ["info_panels.background.key"],
|
||||
"text": "shortcuts.tools.info.background"
|
||||
}, {
|
||||
"modifiers": ["⌘", "⇧"],
|
||||
"shortcuts": ["info_panels.history.key"],
|
||||
"text": "shortcuts.tools.info.history"
|
||||
}, {
|
||||
"modifiers": ["⌘", "⇧"],
|
||||
"shortcuts": ["info_panels.location.key"],
|
||||
"text": "shortcuts.tools.info.location"
|
||||
}, {
|
||||
"modifiers": ["⌘", "⇧"],
|
||||
"shortcuts": ["info_panels.measurement.key"],
|
||||
"text": "shortcuts.tools.info.measurement"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
|
||||
@@ -41,12 +41,6 @@ sources.concat(whitelist).forEach(function(source) {
|
||||
if (source.type !== 'tms' && source.type !== 'bing') return;
|
||||
if (source.id in blacklist) return;
|
||||
|
||||
if (source.end_date) {
|
||||
var endDate = new Date(source.end_date),
|
||||
isValid = !isNaN(endDate.getTime());
|
||||
if (isValid && endDate <= cutoffDate) return;
|
||||
}
|
||||
|
||||
var im = {
|
||||
id: source.id,
|
||||
name: source.name,
|
||||
@@ -54,6 +48,25 @@ sources.concat(whitelist).forEach(function(source) {
|
||||
template: source.url
|
||||
};
|
||||
|
||||
var startDate, endDate, isValid;
|
||||
|
||||
if (source.end_date) {
|
||||
endDate = new Date(source.end_date);
|
||||
isValid = !isNaN(endDate.getTime());
|
||||
if (isValid) {
|
||||
if (endDate <= cutoffDate) return; // too old
|
||||
im.endDate = endDate;
|
||||
}
|
||||
}
|
||||
|
||||
if (source.start_date) {
|
||||
startDate = new Date(source.start_date);
|
||||
isValid = !isNaN(startDate.getTime());
|
||||
if (isValid) {
|
||||
im.startDate = startDate;
|
||||
}
|
||||
}
|
||||
|
||||
var extent = source.extent || {};
|
||||
if (extent.min_zoom || extent.max_zoom) {
|
||||
im.scaleExtent = [
|
||||
|
||||
65
dist/locales/en.json
vendored
65
dist/locales/en.json
vendored
@@ -348,19 +348,48 @@
|
||||
"list": "Edits by {users}",
|
||||
"truncated_list": "Edits by {users} and {count} others"
|
||||
},
|
||||
"infobox": {
|
||||
"info_panels": {
|
||||
"key": "I",
|
||||
"selected": "{n} selected",
|
||||
"geometry": "Geometry",
|
||||
"closed": "closed",
|
||||
"center": "Center",
|
||||
"perimeter": "Perimeter",
|
||||
"length": "Length",
|
||||
"area": "Area",
|
||||
"centroid": "Centroid",
|
||||
"location": "Location",
|
||||
"metric": "Metric",
|
||||
"imperial": "Imperial"
|
||||
"background": {
|
||||
"key": "B",
|
||||
"title": "Background",
|
||||
"zoom": "Zoom",
|
||||
"vintage": "Vintage",
|
||||
"unknown": "Unknown",
|
||||
"show_tiles": "Show Tiles",
|
||||
"hide_tiles": "Hide Tiles"
|
||||
},
|
||||
"history": {
|
||||
"key": "H",
|
||||
"title": "History",
|
||||
"selected": "{n} selected",
|
||||
"version": "Version",
|
||||
"last_edit": "Last Edit",
|
||||
"edited_by": "Edited By",
|
||||
"changeset": "Changeset",
|
||||
"unknown": "Unknown",
|
||||
"link_text": "History on openstreetmap.org"
|
||||
},
|
||||
"location": {
|
||||
"key": "L",
|
||||
"title": "Location",
|
||||
"unknown_location": "Unknown Location"
|
||||
},
|
||||
"measurement": {
|
||||
"key": "M",
|
||||
"title": "Measurement",
|
||||
"selected": "{n} selected",
|
||||
"geometry": "Geometry",
|
||||
"closed": "closed",
|
||||
"center": "Center",
|
||||
"perimeter": "Perimeter",
|
||||
"length": "Length",
|
||||
"area": "Area",
|
||||
"centroid": "Centroid",
|
||||
"location": "Location",
|
||||
"metric": "Metric",
|
||||
"imperial": "Imperial"
|
||||
}
|
||||
},
|
||||
"geometry": {
|
||||
"point": "point",
|
||||
@@ -950,7 +979,6 @@
|
||||
},
|
||||
"with_selected": {
|
||||
"title": "With feature selected",
|
||||
"infobox": "Toggle info / measurement box",
|
||||
"edit_menu": "Toggle edit menu"
|
||||
},
|
||||
"vertex_selected": {
|
||||
@@ -996,6 +1024,17 @@
|
||||
"redo": "Redo last action",
|
||||
"save": "Save changes"
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"title": "Tools",
|
||||
"info": {
|
||||
"title": "Information",
|
||||
"all": "Toggle all information panels",
|
||||
"background": "Toggle background panel",
|
||||
"history": "Toggle history panel",
|
||||
"location": "Toggle location panel",
|
||||
"measurement": "Toggle measurement panel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
|
||||
@@ -12,6 +12,7 @@ export * from './services/index';
|
||||
export * from './svg/index';
|
||||
export * from './ui/fields/index';
|
||||
export * from './ui/intro/index';
|
||||
export * from './ui/panels/index';
|
||||
export * from './ui/index';
|
||||
export * from './util/index';
|
||||
export * from './lib/index';
|
||||
|
||||
@@ -5,6 +5,25 @@ import { geoExtent, geoPolygonIntersectsPolygon } from '../geo/index';
|
||||
import { jsonpRequest } from '../util/jsonp_request';
|
||||
|
||||
|
||||
function localeDateString(s) {
|
||||
if (!s) return null;
|
||||
var d = new Date(s);
|
||||
if (isNaN(d.getTime())) return null;
|
||||
return d.toLocaleDateString();
|
||||
}
|
||||
|
||||
function vintageRange(vintage) {
|
||||
var s;
|
||||
if (vintage.start || vintage.end) {
|
||||
s = (vintage.start || '?');
|
||||
if (vintage.start !== vintage.end) {
|
||||
s += ' - ' + (vintage.end || '?');
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
export function rendererBackgroundSource(data) {
|
||||
var source = _.clone(data),
|
||||
offset = [0, 0],
|
||||
@@ -106,6 +125,16 @@ export function rendererBackgroundSource(data) {
|
||||
source.copyrightNotices = function() {};
|
||||
|
||||
|
||||
source.getVintage = function(center, tileCoord, callback) {
|
||||
var vintage = {
|
||||
start: localeDateString(source.startDate),
|
||||
end: localeDateString(source.endDate)
|
||||
};
|
||||
vintage.range = vintageRange(vintage);
|
||||
callback(null, vintage);
|
||||
};
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -120,6 +149,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
|
||||
url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
|
||||
key + '&jsonp={callback}',
|
||||
cache = {},
|
||||
providers = [];
|
||||
|
||||
jsonpRequest(url, function(json) {
|
||||
@@ -137,6 +167,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
dispatch.call('change');
|
||||
});
|
||||
|
||||
|
||||
bing.copyrightNotices = function(zoom, extent) {
|
||||
zoom = Math.min(zoom, 21);
|
||||
return providers.filter(function(provider) {
|
||||
@@ -150,8 +181,41 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
}).join(', ');
|
||||
};
|
||||
|
||||
|
||||
bing.getVintage = function(center, tileCoord, callback) {
|
||||
var tileId = tileCoord.slice(0, 3).join('/'),
|
||||
zoom = Math.min(tileCoord[2], 21),
|
||||
centerPoint = center[1] + ',' + center[0], // lat,lng
|
||||
url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
|
||||
'?zl=' + zoom + '&key=' + key + '&jsonp={callback}';
|
||||
|
||||
if (!cache[tileId]) {
|
||||
cache[tileId] = {};
|
||||
}
|
||||
if (cache[tileId] && cache[tileId].vintage) {
|
||||
return callback(null, cache[tileId].vintage);
|
||||
}
|
||||
|
||||
jsonpRequest(url, function(result) {
|
||||
var err = (!result && 'Unknown Error') || result.errorDetails;
|
||||
if (err) {
|
||||
return callback(err);
|
||||
} else {
|
||||
var vintage = {
|
||||
start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
|
||||
end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
|
||||
};
|
||||
vintage.range = vintageRange(vintage);
|
||||
cache[tileId].vintage = vintage;
|
||||
return callback(null, vintage);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
|
||||
|
||||
|
||||
return bing;
|
||||
};
|
||||
|
||||
@@ -159,18 +223,22 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
rendererBackgroundSource.None = function() {
|
||||
var source = rendererBackgroundSource({ id: 'none', template: '' });
|
||||
|
||||
|
||||
source.name = function() {
|
||||
return t('background.none');
|
||||
};
|
||||
|
||||
|
||||
source.imageryUsed = function() {
|
||||
return 'None';
|
||||
};
|
||||
|
||||
|
||||
source.area = function() {
|
||||
return -1; // sources in background pane are sorted by area
|
||||
};
|
||||
|
||||
|
||||
return source;
|
||||
};
|
||||
|
||||
@@ -178,17 +246,21 @@ rendererBackgroundSource.None = function() {
|
||||
rendererBackgroundSource.Custom = function(template) {
|
||||
var source = rendererBackgroundSource({ id: 'custom', template: template });
|
||||
|
||||
|
||||
source.name = function() {
|
||||
return t('background.custom');
|
||||
};
|
||||
|
||||
|
||||
source.imageryUsed = function() {
|
||||
return 'Custom (' + template + ')';
|
||||
};
|
||||
|
||||
|
||||
source.area = function() {
|
||||
return -2; // sources in background pane are sorted by area
|
||||
};
|
||||
|
||||
|
||||
return source;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as d3 from 'd3';
|
||||
import { t } from '../util/locale';
|
||||
import { d3geoTile } from '../lib/d3.geo.tile';
|
||||
import { utilPrefixCSSProperty } from '../util/index';
|
||||
import { geoEuclideanDistance } from '../geo';
|
||||
import { utilPrefixCSSProperty } from '../util';
|
||||
import { rendererBackgroundSource } from './background_source.js';
|
||||
|
||||
|
||||
@@ -97,7 +99,7 @@ export function rendererTileLayer(context) {
|
||||
tile().forEach(function(d) {
|
||||
addSource(d);
|
||||
if (d[3] === '') return;
|
||||
if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
|
||||
if (typeof d[3] !== 'string') return; // Workaround for #2295
|
||||
requests.push(d);
|
||||
if (cache[d[3]] === false && lookUp(d)) {
|
||||
requests.push(addSource(lookUp(d)));
|
||||
@@ -118,6 +120,7 @@ export function rendererTileLayer(context) {
|
||||
source.offset()[1] * Math.pow(2, z)
|
||||
];
|
||||
|
||||
|
||||
function load(d) {
|
||||
cache[d[3]] = true;
|
||||
d3.select(this)
|
||||
@@ -145,14 +148,36 @@ export function rendererTileLayer(context) {
|
||||
'scale(' + scale + ',' + scale + ')';
|
||||
}
|
||||
|
||||
function debugTransform(d) {
|
||||
function tileCenter(d) {
|
||||
var _ts = tileSize * Math.pow(2, z - d[2]);
|
||||
var scale = tileSizeAtZoom(d, z);
|
||||
return 'translate(' +
|
||||
((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + scale * (tileSize / 4)) + 'px,' +
|
||||
((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + scale * (tileSize / 2)) + 'px)';
|
||||
return [
|
||||
((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + (_ts / 2)),
|
||||
((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + (_ts / 2))
|
||||
];
|
||||
}
|
||||
|
||||
function debugTransform(d) {
|
||||
var coord = tileCenter(d);
|
||||
return 'translate(' + coord[0] + 'px,' + coord[1] + 'px)';
|
||||
}
|
||||
|
||||
|
||||
// Pick a representative tile near the center of the viewport
|
||||
// (This is useful for sampling the imagery vintage)
|
||||
var dims = tile.size(),
|
||||
mapCenter = [dims[0] / 2, dims[1] / 2],
|
||||
minDist = Math.max(dims[0], dims[1]),
|
||||
nearCenter;
|
||||
|
||||
requests.forEach(function(d) {
|
||||
var c = tileCenter(d);
|
||||
var dist = geoEuclideanDistance(c, mapCenter);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
nearCenter = d;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var image = selection.selectAll('img')
|
||||
.data(requests, function(d) { return d[3]; });
|
||||
@@ -160,6 +185,7 @@ export function rendererTileLayer(context) {
|
||||
image.exit()
|
||||
.style(transformProp, imageTransform)
|
||||
.classed('tile-removing', true)
|
||||
.classed('tile-center', false)
|
||||
.each(function() {
|
||||
var tile = d3.select(this);
|
||||
window.setTimeout(function() {
|
||||
@@ -178,7 +204,9 @@ export function rendererTileLayer(context) {
|
||||
.merge(image)
|
||||
.style(transformProp, imageTransform)
|
||||
.classed('tile-debug', showDebug)
|
||||
.classed('tile-removing', false);
|
||||
.classed('tile-removing', false)
|
||||
.classed('tile-center', function(d) { return d === nearCenter; });
|
||||
|
||||
|
||||
|
||||
var debug = selection.selectAll('.tile-label-debug')
|
||||
@@ -187,12 +215,41 @@ export function rendererTileLayer(context) {
|
||||
debug.exit()
|
||||
.remove();
|
||||
|
||||
debug.enter()
|
||||
.append('div')
|
||||
.attr('class', 'tile-label-debug')
|
||||
.merge(debug)
|
||||
.text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; })
|
||||
.style(transformProp, debugTransform);
|
||||
if (showDebug) {
|
||||
var debugEnter = debug.enter()
|
||||
.append('div')
|
||||
.attr('class', 'tile-label-debug');
|
||||
|
||||
debugEnter
|
||||
.append('div')
|
||||
.attr('class', 'tile-label-debug-coord');
|
||||
|
||||
debugEnter
|
||||
.append('div')
|
||||
.attr('class', 'tile-label-debug-vintage');
|
||||
|
||||
debug = debug.merge(debugEnter);
|
||||
|
||||
debug
|
||||
.style(transformProp, debugTransform);
|
||||
|
||||
debug
|
||||
.selectAll('.tile-label-debug-coord')
|
||||
.text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
|
||||
|
||||
debug
|
||||
.selectAll('.tile-label-debug-vintage')
|
||||
.each(function(d) {
|
||||
var span = d3.select(this);
|
||||
var center = context.projection.invert(tileCenter(d));
|
||||
source.getVintage(center, d, function(err, result) {
|
||||
span.text((result && result.range) ||
|
||||
t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,32 +25,44 @@ export default {
|
||||
|
||||
|
||||
countryCode: function (location, callback) {
|
||||
var countryCodes = nominatimCache.search(
|
||||
this.reverse(location, function(err, result) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
} else if (result.address) {
|
||||
return callback(null, result.address.country_code);
|
||||
} else {
|
||||
return callback('Unable to geocode', null);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
reverse: function (location, callback) {
|
||||
var cached = nominatimCache.search(
|
||||
{ minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
|
||||
);
|
||||
|
||||
if (countryCodes.length > 0) {
|
||||
return callback(null, countryCodes[0].data);
|
||||
if (cached.length > 0) {
|
||||
return callback(null, cached[0].data);
|
||||
}
|
||||
|
||||
var params = { format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
|
||||
var params = { zoom: 13, format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
|
||||
var url = apibase + 'reverse?' + utilQsString(params);
|
||||
if (inflight[url]) return;
|
||||
|
||||
inflight[url] = d3.json(url, function(err, result) {
|
||||
delete inflight[url];
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
return callback(err);
|
||||
else if (result && result.error)
|
||||
} else if (result && result.error) {
|
||||
return callback(result.error);
|
||||
}
|
||||
|
||||
var extent = geoExtent(location).padByMeters(1000);
|
||||
nominatimCache.insert(_.assign(extent.bbox(),
|
||||
{ data: result.address.country_code }
|
||||
));
|
||||
var extent = geoExtent(location).padByMeters(200);
|
||||
nominatimCache.insert(_.assign(extent.bbox(), {data: result}));
|
||||
|
||||
callback(null, result.address.country_code);
|
||||
callback(null, result);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -104,11 +104,14 @@ var parsers = {
|
||||
var attrs = obj.attributes;
|
||||
return new osmNode({
|
||||
id: osmEntity.id.fromOSM('node', attrs.id.value),
|
||||
loc: getLoc(attrs),
|
||||
visible: getVisible(attrs),
|
||||
version: attrs.version.value,
|
||||
changeset: attrs.changeset && attrs.changeset.value,
|
||||
timestamp: attrs.timestamp && attrs.timestamp.value,
|
||||
user: attrs.user && attrs.user.value,
|
||||
tags: getTags(obj),
|
||||
visible: getVisible(attrs)
|
||||
uid: attrs.uid && attrs.uid.value,
|
||||
loc: getLoc(attrs),
|
||||
tags: getTags(obj)
|
||||
});
|
||||
},
|
||||
|
||||
@@ -116,11 +119,14 @@ var parsers = {
|
||||
var attrs = obj.attributes;
|
||||
return new osmWay({
|
||||
id: osmEntity.id.fromOSM('way', attrs.id.value),
|
||||
visible: getVisible(attrs),
|
||||
version: attrs.version.value,
|
||||
changeset: attrs.changeset && attrs.changeset.value,
|
||||
timestamp: attrs.timestamp && attrs.timestamp.value,
|
||||
user: attrs.user && attrs.user.value,
|
||||
uid: attrs.uid && attrs.uid.value,
|
||||
tags: getTags(obj),
|
||||
nodes: getNodes(obj),
|
||||
visible: getVisible(attrs)
|
||||
});
|
||||
},
|
||||
|
||||
@@ -128,11 +134,14 @@ var parsers = {
|
||||
var attrs = obj.attributes;
|
||||
return new osmRelation({
|
||||
id: osmEntity.id.fromOSM('relation', attrs.id.value),
|
||||
visible: getVisible(attrs),
|
||||
version: attrs.version.value,
|
||||
changeset: attrs.changeset && attrs.changeset.value,
|
||||
timestamp: attrs.timestamp && attrs.timestamp.value,
|
||||
user: attrs.user && attrs.user.value,
|
||||
uid: attrs.uid && attrs.uid.value,
|
||||
tags: getTags(obj),
|
||||
members: getMembers(obj),
|
||||
visible: getVisible(attrs)
|
||||
members: getMembers(obj)
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -194,6 +203,11 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
historyURL: function(entity) {
|
||||
return urlroot + '/' + entity.type + '/' + entity.osmId() + '/history';
|
||||
},
|
||||
|
||||
|
||||
userURL: function(username) {
|
||||
return urlroot + '/user/' + username;
|
||||
},
|
||||
@@ -347,10 +361,18 @@ export default {
|
||||
image_url = img[0].getAttribute('href');
|
||||
}
|
||||
|
||||
var changesets = u.getElementsByTagName('changesets'),
|
||||
changesets_count = 0;
|
||||
|
||||
if (changesets && changesets[0] && changesets[0].getAttribute('count')) {
|
||||
changesets_count = changesets[0].getAttribute('count');
|
||||
}
|
||||
|
||||
userDetails = {
|
||||
id: u.attributes.id.value,
|
||||
display_name: u.attributes.display_name.value,
|
||||
image_url: image_url,
|
||||
id: u.attributes.id.value
|
||||
changesets_count: changesets_count
|
||||
};
|
||||
|
||||
callback(undefined, userDetails);
|
||||
|
||||
@@ -1,249 +1,124 @@
|
||||
import * as d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { d3keybinding } from '../lib/d3.keybinding.js';
|
||||
import { t } from '../util/locale';
|
||||
import { geoExtent } from '../geo/index';
|
||||
import { utilDetect } from '../util/detect';
|
||||
import { svgIcon } from '../svg';
|
||||
import { uiCmd } from './cmd';
|
||||
|
||||
import {
|
||||
geoLength as d3GeoLength,
|
||||
geoCentroid as d3GeoCentroid
|
||||
} from 'd3';
|
||||
import { uiInfoPanels } from './panels/index';
|
||||
|
||||
|
||||
export function uiInfo(context) {
|
||||
var isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
|
||||
isHidden = true;
|
||||
var ids = Object.keys(uiInfoPanels),
|
||||
wasActive = ['measurement'],
|
||||
panels = {},
|
||||
active = {};
|
||||
|
||||
// create panels
|
||||
ids.forEach(function(k) {
|
||||
if (!panels[k]) {
|
||||
panels[k] = uiInfoPanels[k](context);
|
||||
active[k] = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function info(selection) {
|
||||
|
||||
function radiansToMeters(r) {
|
||||
// using WGS84 authalic radius (6371007.1809 m)
|
||||
return r * 6371007.1809;
|
||||
}
|
||||
|
||||
function steradiansToSqmeters(r) {
|
||||
// http://gis.stackexchange.com/a/124857/40446
|
||||
return r / (4 * Math.PI) * 510065621724000;
|
||||
}
|
||||
|
||||
|
||||
function toLineString(feature) {
|
||||
if (feature.type === 'LineString') return feature;
|
||||
|
||||
var result = { type: 'LineString', coordinates: [] };
|
||||
if (feature.type === 'Polygon') {
|
||||
result.coordinates = feature.coordinates[0];
|
||||
} else if (feature.type === 'MultiPolygon') {
|
||||
result.coordinates = feature.coordinates[0][0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function displayLength(m) {
|
||||
var d = m * (isImperial ? 3.28084 : 1),
|
||||
p, unit;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 5280) {
|
||||
d /= 5280;
|
||||
unit = 'mi';
|
||||
} else {
|
||||
unit = 'ft';
|
||||
}
|
||||
} else {
|
||||
if (d >= 1000) {
|
||||
d /= 1000;
|
||||
unit = 'km';
|
||||
} else {
|
||||
unit = 'm';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p = d > 1000 ? 0 : d > 100 ? 1 : 2;
|
||||
|
||||
return String(d.toFixed(p)) + ' ' + unit;
|
||||
}
|
||||
|
||||
|
||||
function displayArea(m2) {
|
||||
var d = m2 * (isImperial ? 10.7639111056 : 1),
|
||||
d1, d2, p1, p2, unit1, unit2;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 6969600) { // > 0.25mi² show mi²
|
||||
d1 = d / 27878400;
|
||||
unit1 = 'mi²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'ft²';
|
||||
}
|
||||
|
||||
if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
|
||||
d2 = d / 43560;
|
||||
unit2 = 'ac';
|
||||
}
|
||||
|
||||
} else {
|
||||
if (d >= 250000) { // > 0.25km² show km²
|
||||
d1 = d / 1000000;
|
||||
unit1 = 'km²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'm²';
|
||||
}
|
||||
|
||||
if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
|
||||
d2 = d / 10000;
|
||||
unit2 = 'ha';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
|
||||
p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
|
||||
|
||||
return String(d1.toFixed(p1)) + ' ' + unit1 +
|
||||
(d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
|
||||
}
|
||||
|
||||
|
||||
function redraw() {
|
||||
if (isHidden) return;
|
||||
var activeids = ids.filter(function(k) { return active[k]; }).sort();
|
||||
|
||||
var resolver = context.graph(),
|
||||
selected = _.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
|
||||
singular = selected.length === 1 ? selected[0] : null,
|
||||
extent = geoExtent(),
|
||||
entity;
|
||||
var containers = infoPanels.selectAll('.panel-container')
|
||||
.data(activeids, function(k) { return k; });
|
||||
|
||||
wrap.html('');
|
||||
wrap.append('h4')
|
||||
.attr('class', 'infobox-heading fillD')
|
||||
.text(singular || t('infobox.selected', { n: selected.length }));
|
||||
containers.exit()
|
||||
.style('opacity', 1)
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 0)
|
||||
.on('end', function(d) {
|
||||
d3.select(this)
|
||||
.call(panels[d].off)
|
||||
.remove();
|
||||
});
|
||||
|
||||
if (!selected.length) return;
|
||||
var enter = containers.enter()
|
||||
.append('div')
|
||||
.attr('class', function(d) { return 'fillD2 panel-container panel-container-' + d; });
|
||||
|
||||
var center;
|
||||
for (var i = 0; i < selected.length; i++) {
|
||||
entity = context.entity(selected[i]);
|
||||
extent._extend(entity.extent(resolver));
|
||||
}
|
||||
center = extent.center();
|
||||
enter
|
||||
.style('opacity', 0)
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 1);
|
||||
|
||||
var title = enter
|
||||
.append('div')
|
||||
.attr('class', 'panel-title fillD2');
|
||||
|
||||
title
|
||||
.append('h3')
|
||||
.text(function(d) { return panels[d].title; });
|
||||
|
||||
title
|
||||
.append('button')
|
||||
.attr('class', 'close')
|
||||
.on('click', function (d) { toggle(d); })
|
||||
.call(svgIcon('#icon-close'));
|
||||
|
||||
enter
|
||||
.append('div')
|
||||
.attr('class', function(d) { return 'panel-content panel-content-' + d; });
|
||||
|
||||
|
||||
var list = wrap.append('ul');
|
||||
// redraw the panels
|
||||
infoPanels.selectAll('.panel-content')
|
||||
.each(function(d) {
|
||||
d3.select(this).call(panels[d]);
|
||||
});
|
||||
}
|
||||
|
||||
// multiple features, just display extent center..
|
||||
if (!singular) {
|
||||
list.append('li')
|
||||
.text(t('infobox.center') + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
|
||||
return;
|
||||
}
|
||||
|
||||
// single feature, display details..
|
||||
if (!entity) return;
|
||||
var geometry = entity.geometry(resolver);
|
||||
function toggle(which) {
|
||||
if (d3.event) d3.event.preventDefault();
|
||||
|
||||
if (geometry === 'line' || geometry === 'area') {
|
||||
var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
|
||||
feature = entity.asGeoJSON(resolver),
|
||||
length = radiansToMeters(d3GeoLength(toLineString(feature))),
|
||||
lengthLabel = t('infobox.' + (closed ? 'perimeter' : 'length')),
|
||||
centroid = d3GeoCentroid(feature);
|
||||
var activeids = ids.filter(function(k) { return active[k]; });
|
||||
|
||||
list.append('li')
|
||||
.text(t('infobox.geometry') + ': ' +
|
||||
(closed ? t('infobox.closed') + ' ' : '') + t('geometry.' + geometry) );
|
||||
|
||||
if (closed) {
|
||||
var area = steradiansToSqmeters(entity.area(resolver));
|
||||
list.append('li')
|
||||
.text(t('infobox.area') + ': ' + displayArea(area));
|
||||
if (which) { // toggle one
|
||||
active[which] = !active[which];
|
||||
if (activeids.length === 1 && activeids[0] === which) { // none active anymore
|
||||
wasActive = [which];
|
||||
}
|
||||
} else { // toggle all
|
||||
if (activeids.length) {
|
||||
wasActive = activeids;
|
||||
activeids.forEach(function(k) { active[k] = false; });
|
||||
} else {
|
||||
wasActive.forEach(function(k) { active[k] = true; });
|
||||
}
|
||||
|
||||
list.append('li')
|
||||
.text(lengthLabel + ': ' + displayLength(length));
|
||||
|
||||
list.append('li')
|
||||
.text(t('infobox.centroid') + ': ' + centroid[0].toFixed(5) + ', ' + centroid[1].toFixed(5));
|
||||
|
||||
|
||||
var toggle = isImperial ? 'imperial' : 'metric';
|
||||
wrap.append('a')
|
||||
.text(t('infobox.' + toggle))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button')
|
||||
.on('click', function() {
|
||||
d3.event.preventDefault();
|
||||
isImperial = !isImperial;
|
||||
redraw();
|
||||
});
|
||||
|
||||
} else {
|
||||
var centerLabel = t('infobox.' + (entity.type === 'node' ? 'location' : 'center'));
|
||||
|
||||
list.append('li')
|
||||
.text(t('infobox.geometry') + ': ' + t('geometry.' + geometry));
|
||||
|
||||
list.append('li')
|
||||
.text(centerLabel + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
function toggle() {
|
||||
if (d3.event) {
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
|
||||
isHidden = !isHidden;
|
||||
|
||||
if (isHidden) {
|
||||
wrap
|
||||
.style('display', 'block')
|
||||
.style('opacity', 1)
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 0)
|
||||
.on('end', function() {
|
||||
d3.select(this).style('display', 'none');
|
||||
});
|
||||
} else {
|
||||
wrap
|
||||
.style('display', 'block')
|
||||
.style('opacity', 0)
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 1)
|
||||
.on('end', function() {
|
||||
redraw();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var wrap = selection.selectAll('.infobox')
|
||||
var infoPanels = selection.selectAll('.info-panels')
|
||||
.data([0]);
|
||||
|
||||
wrap = wrap.enter()
|
||||
infoPanels = infoPanels.enter()
|
||||
.append('div')
|
||||
.attr('class', 'infobox fillD2')
|
||||
.style('display', (isHidden ? 'none' : 'block'))
|
||||
.merge(wrap);
|
||||
|
||||
context.map()
|
||||
.on('drawn.info', redraw);
|
||||
.attr('class', 'info-panels')
|
||||
.merge(infoPanels);
|
||||
|
||||
redraw();
|
||||
|
||||
var keybinding = d3keybinding('info')
|
||||
.on(uiCmd('⌘' + t('infobox.key')), toggle);
|
||||
.on(uiCmd('⌘' + t('info_panels.key')), toggle);
|
||||
|
||||
ids.forEach(function(k) {
|
||||
var key = t('info_panels.' + k + '.key', { default: null });
|
||||
if (!key) return;
|
||||
keybinding
|
||||
.on(uiCmd('⌘⇧' + key), function() { toggle(k); });
|
||||
});
|
||||
|
||||
d3.select(document)
|
||||
.call(keybinding);
|
||||
|
||||
@@ -81,10 +81,7 @@ export function uiInit(context) {
|
||||
.call(map);
|
||||
|
||||
content
|
||||
.call(uiMapInMap(context));
|
||||
|
||||
content
|
||||
.append('div')
|
||||
.call(uiMapInMap(context))
|
||||
.call(uiInfo(context));
|
||||
|
||||
bar
|
||||
|
||||
110
modules/ui/panels/background.js
Normal file
110
modules/ui/panels/background.js
Normal file
@@ -0,0 +1,110 @@
|
||||
import * as d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { t } from '../../util/locale';
|
||||
|
||||
|
||||
export function uiPanelBackground(context) {
|
||||
var background = context.background();
|
||||
var currSource = null;
|
||||
var currZoom = '';
|
||||
var currVintage = '';
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
if (currSource !== background.baseLayerSource().name()) {
|
||||
currSource = background.baseLayerSource().name();
|
||||
currZoom = '';
|
||||
currVintage = '';
|
||||
}
|
||||
|
||||
selection.html('');
|
||||
|
||||
var list = selection
|
||||
.append('ul')
|
||||
.attr('class', 'background-info');
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(currSource);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.background.zoom') + ': ')
|
||||
.append('span')
|
||||
.attr('class', 'zoom')
|
||||
.text(currZoom);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.background.vintage') + ': ')
|
||||
.append('span')
|
||||
.attr('class', 'vintage')
|
||||
.text(currVintage);
|
||||
|
||||
if (!currVintage) {
|
||||
debouncedGetVintage(selection);
|
||||
}
|
||||
|
||||
var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles';
|
||||
|
||||
selection
|
||||
.append('a')
|
||||
.text(t('info_panels.background.' + toggle))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button button-toggle-tiles')
|
||||
.on('click', function() {
|
||||
d3.event.preventDefault();
|
||||
context.setDebug('tile', !context.getDebug('tile'));
|
||||
selection.call(redraw);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var debouncedGetVintage = _.debounce(getVintage, 250);
|
||||
function getVintage(selection) {
|
||||
var tile = d3.select('.layer-background img.tile-center'); // tile near viewport center
|
||||
if (tile.empty()) return;
|
||||
|
||||
var d = tile.datum(),
|
||||
zoom = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()),
|
||||
center = context.map().center();
|
||||
|
||||
currZoom = String(zoom);
|
||||
selection.selectAll('.zoom')
|
||||
.text(currZoom);
|
||||
|
||||
if (!d || !d.length >= 3) return;
|
||||
background.baseLayerSource().getVintage(center, d, function(err, result) {
|
||||
currVintage = (result && result.range) || t('info_panels.background.unknown');
|
||||
selection.selectAll('.vintage')
|
||||
.text(currVintage);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var panel = function(selection) {
|
||||
selection.call(redraw);
|
||||
|
||||
context.map()
|
||||
.on('drawn.info-background', function() {
|
||||
selection.call(redraw);
|
||||
})
|
||||
.on('move.info-background', function() {
|
||||
selection.call(debouncedGetVintage);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
panel.off = function() {
|
||||
context.map()
|
||||
.on('drawn.info-background', null)
|
||||
.on('move.info-background', null);
|
||||
};
|
||||
|
||||
panel.id = 'background';
|
||||
panel.title = t('info_panels.background.title');
|
||||
panel.key = t('info_panels.background.key');
|
||||
|
||||
|
||||
return panel;
|
||||
}
|
||||
157
modules/ui/panels/history.js
Normal file
157
modules/ui/panels/history.js
Normal file
@@ -0,0 +1,157 @@
|
||||
import _ from 'lodash';
|
||||
import { t } from '../../util/locale';
|
||||
import { svgIcon } from '../../svg';
|
||||
|
||||
|
||||
export function uiPanelHistory(context) {
|
||||
|
||||
|
||||
function displayTimestamp(entity) {
|
||||
if (!entity.timestamp) return t('info_panels.history.unknown');
|
||||
|
||||
var d = new Date(entity.timestamp);
|
||||
if (isNaN(d.getTime())) return t('info_panels.history.unknown');
|
||||
|
||||
return d.toLocaleString();
|
||||
}
|
||||
|
||||
|
||||
function displayUser(selection, entity) {
|
||||
if (!entity.user) {
|
||||
selection
|
||||
.append('span')
|
||||
.text(t('info_panels.history.unknown'));
|
||||
return;
|
||||
}
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.attr('class', 'user-name')
|
||||
.text(entity.user);
|
||||
|
||||
var links = selection
|
||||
.append('div')
|
||||
.attr('class', 'links');
|
||||
|
||||
links
|
||||
.append('a')
|
||||
.attr('class', 'user-osm-link')
|
||||
.attr('href', context.connection().userURL(entity.user))
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.text('OSM');
|
||||
|
||||
links
|
||||
.append('a')
|
||||
.attr('class', 'user-hdyc-link')
|
||||
.attr('href', 'https://hdyc.neis-one.org/?' + entity.user)
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.text('HDYC');
|
||||
}
|
||||
|
||||
|
||||
function displayChangeset(selection, entity) {
|
||||
if (!entity.changeset) {
|
||||
selection
|
||||
.append('span')
|
||||
.text(t('info_panels.history.unknown'));
|
||||
return;
|
||||
}
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.attr('class', 'changeset-id')
|
||||
.text(entity.changeset);
|
||||
|
||||
var links = selection
|
||||
.append('div')
|
||||
.attr('class', 'links');
|
||||
|
||||
links
|
||||
.append('a')
|
||||
.attr('class', 'changeset-osm-link')
|
||||
.attr('href', context.connection().changesetURL(entity.changeset))
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.text('OSM');
|
||||
|
||||
links
|
||||
.append('a')
|
||||
.attr('class', 'changeset-osmcha-link')
|
||||
.attr('href', 'https://osmcha.mapbox.com/changesets/' + entity.changeset)
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.text('OSMCha');
|
||||
}
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
var selected = _.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
|
||||
singular = selected.length === 1 ? selected[0] : null;
|
||||
|
||||
selection.html('');
|
||||
|
||||
selection
|
||||
.append('h4')
|
||||
.attr('class', 'history-heading')
|
||||
.text(singular || t('info_panels.history.selected', { n: selected.length }));
|
||||
|
||||
if (!singular) return;
|
||||
|
||||
var entity = context.entity(singular);
|
||||
|
||||
var list = selection
|
||||
.append('ul');
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.history.version') + ': ' + entity.version);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.history.last_edit') + ': ' + displayTimestamp(entity));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.history.edited_by') + ': ')
|
||||
.call(displayUser, entity);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.history.changeset') + ': ')
|
||||
.call(displayChangeset, entity);
|
||||
|
||||
selection
|
||||
.append('a')
|
||||
.attr('class', 'view-history-on-osm')
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.attr('href', context.connection().historyURL(entity))
|
||||
.call(svgIcon('#icon-out-link', 'inline'))
|
||||
.append('span')
|
||||
.text(t('info_panels.history.link_text'));
|
||||
}
|
||||
|
||||
|
||||
var panel = function(selection) {
|
||||
selection.call(redraw);
|
||||
|
||||
context.map()
|
||||
.on('drawn.info-history', function() {
|
||||
selection.call(redraw);
|
||||
});
|
||||
};
|
||||
|
||||
panel.off = function() {
|
||||
context.map()
|
||||
.on('drawn.info-history', null);
|
||||
};
|
||||
|
||||
panel.id = 'history';
|
||||
panel.title = t('info_panels.history.title');
|
||||
panel.key = t('info_panels.history.key');
|
||||
|
||||
|
||||
return panel;
|
||||
}
|
||||
16
modules/ui/panels/index.js
Normal file
16
modules/ui/panels/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export * from './background';
|
||||
export * from './history';
|
||||
export * from './location';
|
||||
export * from './measurement';
|
||||
|
||||
import { uiPanelBackground } from './background';
|
||||
import { uiPanelHistory } from './history';
|
||||
import { uiPanelLocation } from './location';
|
||||
import { uiPanelMeasurement } from './measurement';
|
||||
|
||||
export var uiInfoPanels = {
|
||||
background: uiPanelBackground,
|
||||
history: uiPanelHistory,
|
||||
location: uiPanelLocation,
|
||||
measurement: uiPanelMeasurement,
|
||||
};
|
||||
88
modules/ui/panels/location.js
Normal file
88
modules/ui/panels/location.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import _ from 'lodash';
|
||||
import { t } from '../../util/locale';
|
||||
import { services } from '../../services';
|
||||
|
||||
|
||||
export function uiPanelLocation(context) {
|
||||
var currLocation = '';
|
||||
var OSM_PRECISION = 7;
|
||||
|
||||
|
||||
function wrap(x, min, max) {
|
||||
var d = max - min;
|
||||
return ((x - min) % d + d) % d + min;
|
||||
}
|
||||
|
||||
|
||||
function clamp(x, min, max) {
|
||||
return Math.max(min, Math.min(x, max));
|
||||
}
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
selection.html('');
|
||||
|
||||
var list = selection
|
||||
.append('ul');
|
||||
|
||||
// Mouse coordinates
|
||||
var coord = context.map().mouseCoordinates();
|
||||
if (coord.some(isNaN)) {
|
||||
coord = context.map().center();
|
||||
}
|
||||
|
||||
var coordStr =
|
||||
clamp(coord[1], -90, 90).toFixed(OSM_PRECISION) + ', ' +
|
||||
wrap(coord[0], -180, 180).toFixed(OSM_PRECISION);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(coordStr);
|
||||
|
||||
// Location Info
|
||||
selection
|
||||
.append('div')
|
||||
.attr('class', 'location-info')
|
||||
.text(currLocation || ' ');
|
||||
|
||||
debouncedGetLocation(selection, coord);
|
||||
}
|
||||
|
||||
|
||||
var debouncedGetLocation = _.debounce(getLocation, 250);
|
||||
function getLocation(selection, coord) {
|
||||
if (!services.geocoder) {
|
||||
currLocation = t('info_panels.location.unknown_location');
|
||||
selection.selectAll('.location-info')
|
||||
.text(currLocation);
|
||||
} else {
|
||||
services.geocoder.reverse(coord, function(err, result) {
|
||||
currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
|
||||
selection.selectAll('.location-info')
|
||||
.text(currLocation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var panel = function(selection) {
|
||||
selection.call(redraw);
|
||||
|
||||
context.surface()
|
||||
.on('mousemove.info-location', function() {
|
||||
selection.call(redraw);
|
||||
});
|
||||
};
|
||||
|
||||
panel.off = function() {
|
||||
context.surface()
|
||||
.on('mousemove.info-location', null);
|
||||
};
|
||||
|
||||
panel.id = 'location';
|
||||
panel.title = t('info_panels.location.title');
|
||||
panel.key = t('info_panels.location.key');
|
||||
|
||||
|
||||
return panel;
|
||||
}
|
||||
232
modules/ui/panels/measurement.js
Normal file
232
modules/ui/panels/measurement.js
Normal file
@@ -0,0 +1,232 @@
|
||||
import * as d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { t } from '../../util/locale';
|
||||
import { geoExtent } from '../../geo';
|
||||
import { utilDetect } from '../../util/detect';
|
||||
|
||||
import {
|
||||
geoLength as d3GeoLength,
|
||||
geoCentroid as d3GeoCentroid
|
||||
} from 'd3';
|
||||
|
||||
|
||||
export function uiPanelMeasurement(context) {
|
||||
var isImperial = (utilDetect().locale.toLowerCase() === 'en-us');
|
||||
var OSM_PRECISION = 7;
|
||||
|
||||
|
||||
function radiansToMeters(r) {
|
||||
// using WGS84 authalic radius (6371007.1809 m)
|
||||
return r * 6371007.1809;
|
||||
}
|
||||
|
||||
function steradiansToSqmeters(r) {
|
||||
// http://gis.stackexchange.com/a/124857/40446
|
||||
return r / (4 * Math.PI) * 510065621724000;
|
||||
}
|
||||
|
||||
|
||||
function toLineString(feature) {
|
||||
if (feature.type === 'LineString') return feature;
|
||||
|
||||
var result = { type: 'LineString', coordinates: [] };
|
||||
if (feature.type === 'Polygon') {
|
||||
result.coordinates = feature.coordinates[0];
|
||||
} else if (feature.type === 'MultiPolygon') {
|
||||
result.coordinates = feature.coordinates[0][0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function displayLength(m) {
|
||||
var d = m * (isImperial ? 3.28084 : 1),
|
||||
p, unit;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 5280) {
|
||||
d /= 5280;
|
||||
unit = 'mi';
|
||||
} else {
|
||||
unit = 'ft';
|
||||
}
|
||||
} else {
|
||||
if (d >= 1000) {
|
||||
d /= 1000;
|
||||
unit = 'km';
|
||||
} else {
|
||||
unit = 'm';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p = d > 1000 ? 0 : d > 100 ? 1 : 2;
|
||||
|
||||
return String(d.toFixed(p)) + ' ' + unit;
|
||||
}
|
||||
|
||||
|
||||
function displayArea(m2) {
|
||||
var d = m2 * (isImperial ? 10.7639111056 : 1),
|
||||
d1, d2, p1, p2, unit1, unit2;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 6969600) { // > 0.25mi² show mi²
|
||||
d1 = d / 27878400;
|
||||
unit1 = 'mi²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'ft²';
|
||||
}
|
||||
|
||||
if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
|
||||
d2 = d / 43560;
|
||||
unit2 = 'ac';
|
||||
}
|
||||
|
||||
} else {
|
||||
if (d >= 250000) { // > 0.25km² show km²
|
||||
d1 = d / 1000000;
|
||||
unit1 = 'km²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'm²';
|
||||
}
|
||||
|
||||
if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
|
||||
d2 = d / 10000;
|
||||
unit2 = 'ha';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
|
||||
p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
|
||||
|
||||
return String(d1.toFixed(p1)) + ' ' + unit1 +
|
||||
(d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
|
||||
}
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
var resolver = context.graph(),
|
||||
selected = _.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
|
||||
singular = selected.length === 1 ? selected[0] : null,
|
||||
extent = geoExtent(),
|
||||
entity;
|
||||
|
||||
selection.html('');
|
||||
|
||||
selection
|
||||
.append('h4')
|
||||
.attr('class', 'measurement-heading')
|
||||
.text(singular || t('info_panels.measurement.selected', { n: selected.length }));
|
||||
|
||||
if (!selected.length) return;
|
||||
|
||||
var center;
|
||||
for (var i = 0; i < selected.length; i++) {
|
||||
entity = context.entity(selected[i]);
|
||||
extent._extend(entity.extent(resolver));
|
||||
}
|
||||
center = extent.center();
|
||||
|
||||
|
||||
var list = selection
|
||||
.append('ul');
|
||||
|
||||
// multiple features, just display extent center..
|
||||
if (!singular) {
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.center') + ': ' +
|
||||
center[0].toFixed(OSM_PRECISION) + ', ' + center[1].toFixed(OSM_PRECISION)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// single feature, display details..
|
||||
if (!entity) return;
|
||||
var geometry = entity.geometry(resolver);
|
||||
|
||||
if (geometry === 'line' || geometry === 'area') {
|
||||
var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
|
||||
feature = entity.asGeoJSON(resolver),
|
||||
length = radiansToMeters(d3GeoLength(toLineString(feature))),
|
||||
lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
|
||||
centroid = d3GeoCentroid(feature);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.geometry') + ': ' +
|
||||
(closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry) );
|
||||
|
||||
if (closed) {
|
||||
var area = steradiansToSqmeters(entity.area(resolver));
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.area') + ': ' + displayArea(area));
|
||||
}
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(lengthLabel + ': ' + displayLength(length));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.centroid') + ': ' +
|
||||
centroid[0].toFixed(OSM_PRECISION) + ', ' + centroid[1].toFixed(OSM_PRECISION)
|
||||
);
|
||||
|
||||
|
||||
var toggle = isImperial ? 'imperial' : 'metric';
|
||||
|
||||
selection
|
||||
.append('a')
|
||||
.text(t('info_panels.measurement.' + toggle))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button button-toggle-units')
|
||||
.on('click', function() {
|
||||
d3.event.preventDefault();
|
||||
isImperial = !isImperial;
|
||||
selection.call(redraw);
|
||||
});
|
||||
|
||||
} else {
|
||||
var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.geometry') + ': ' + t('geometry.' + geometry));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(centerLabel + ': ' +
|
||||
center[0].toFixed(OSM_PRECISION) + ', ' + center[1].toFixed(OSM_PRECISION)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var panel = function(selection) {
|
||||
selection.call(redraw);
|
||||
|
||||
context.map()
|
||||
.on('drawn.info-measurement', function() {
|
||||
selection.call(redraw);
|
||||
});
|
||||
};
|
||||
|
||||
panel.off = function() {
|
||||
context.map()
|
||||
.on('drawn.info-measurement', null);
|
||||
};
|
||||
|
||||
panel.id = 'measurement';
|
||||
panel.title = t('info_panels.measurement.title');
|
||||
panel.key = t('info_panels.measurement.key');
|
||||
|
||||
|
||||
return panel;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ export function uiShortcuts() {
|
||||
var shortcutsEnter = shortcuts
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'shortcut-tab');
|
||||
.attr('class', function(d) { return 'shortcut-tab shortcut-tab-' + d.tab; });
|
||||
|
||||
var columnsEnter = shortcutsEnter
|
||||
.selectAll('.shortcut-column')
|
||||
|
||||
0
scripts/deploy.sh
Normal file → Executable file
0
scripts/deploy.sh
Normal file → Executable file
21
scripts/txpush.sh
Executable file
21
scripts/txpush.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#/bin/bash
|
||||
|
||||
# This script runs on TravisCI to push new translation strings to transifex
|
||||
|
||||
echo "TRAVIS=$TRAVIS"
|
||||
echo "TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST"
|
||||
echo "TRAVIS_BRANCH=$TRAVIS_BRANCH"
|
||||
echo "TRAVIS_NODE_VERSION=$TRAVIS_NODE_VERSION"
|
||||
|
||||
if [[ "$TRAVIS" != "true" ]]; then exit 0; fi
|
||||
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then exit 0; fi
|
||||
if [[ "$TRAVIS_BRANCH" != "master" ]]; then exit 0; fi
|
||||
if [[ "$TRAVIS_NODE_VERSION" != "6" ]]; then exit 0; fi
|
||||
|
||||
echo "Pushing source strings to Transifex..."
|
||||
pip install virtualenv
|
||||
virtualenv ~/env
|
||||
source ~/env/bin/activate
|
||||
pip install transifex-client
|
||||
sudo echo $'[https://www.transifex.com]\nhostname = https://www.transifex.com\nusername = '"$TRANSIFEX_USER"$'\npassword = '"$TRANSIFEX_PASSWORD"$'\n' > ~/.transifexrc
|
||||
tx push -s
|
||||
@@ -17,7 +17,6 @@ describe('iD.serviceNominatim', function() {
|
||||
|
||||
|
||||
describe('#countryCode', function() {
|
||||
|
||||
it('calls the given callback with the results of the country code query', function() {
|
||||
var callback = sinon.spy();
|
||||
nominatim.countryCode([16, 48], callback);
|
||||
@@ -28,13 +27,15 @@ describe('iD.serviceNominatim', function() {
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'at');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not cache the first country code result', function() {
|
||||
describe('#reverse', function() {
|
||||
it('should not cache distant result', function() {
|
||||
var callback = sinon.spy();
|
||||
nominatim.countryCode([16, 48], callback);
|
||||
nominatim.reverse([16, 48], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
@@ -42,13 +43,14 @@ describe('iD.serviceNominatim', function() {
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'at');
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
|
||||
server.restore();
|
||||
server = sinon.fakeServer.create();
|
||||
|
||||
nominatim.countryCode([17, 49], callback);
|
||||
callback = sinon.spy();
|
||||
nominatim.reverse([17, 49], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
@@ -56,13 +58,13 @@ describe('iD.serviceNominatim', function() {
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{format: 'json', addressdetails: '1', lat: '49', lon: '17'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'cz');
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '49', lon: '17'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'cz'}});
|
||||
});
|
||||
|
||||
it('should cache the first country code result', function() {
|
||||
it('should cache nearby result', function() {
|
||||
var callback = sinon.spy();
|
||||
nominatim.countryCode([16, 48], callback);
|
||||
nominatim.reverse([16, 48], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
@@ -70,24 +72,25 @@ describe('iD.serviceNominatim', function() {
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'at');
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'});
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
|
||||
server.restore();
|
||||
server = sinon.fakeServer.create();
|
||||
|
||||
nominatim.countryCode([16.01, 48.01], callback);
|
||||
callback = sinon.spy();
|
||||
nominatim.reverse([16.000001, 48.000001], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"address":{"country_code":"cz"}}']);
|
||||
server.respond();
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'at');
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
});
|
||||
|
||||
it('calls the given callback with an error', function() {
|
||||
var callback = sinon.spy();
|
||||
nominatim.countryCode([1000, 1000], callback);
|
||||
nominatim.reverse([1000, 1000], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
@@ -95,7 +98,7 @@ describe('iD.serviceNominatim', function() {
|
||||
server.respond();
|
||||
|
||||
expect(query(server.requests[0].url)).to.eql(
|
||||
{format: 'json', addressdetails: '1', lat: '1000', lon: '1000'});
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '1000', lon: '1000'});
|
||||
expect(callback).to.have.been.calledWithExactly('Unable to geocode');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -39,12 +39,50 @@ describe('iD.serviceOsm', function () {
|
||||
expect(connection.changesetURL(2)).to.match(/^https:/);
|
||||
});
|
||||
|
||||
describe('#changesetUrl', function() {
|
||||
describe('#changesetURL', function() {
|
||||
it('provides a changeset url', function() {
|
||||
expect(connection.changesetURL(2)).to.eql('http://www.openstreetmap.org/changeset/2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#changesetsURL', function() {
|
||||
it('provides a local changesets url', function() {
|
||||
var center = [-74.65, 40.65];
|
||||
var zoom = 17;
|
||||
expect(connection.changesetsURL(center, zoom)).to.eql('http://www.openstreetmap.org/history#map=17/40.65000/-74.65000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#entityURL', function() {
|
||||
it('provides an entity url for a node', function() {
|
||||
var e = iD.Node({id: 'n1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/node/1');
|
||||
});
|
||||
it('provides an entity url for a way', function() {
|
||||
var e = iD.Way({id: 'w1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/way/1');
|
||||
});
|
||||
it('provides an entity url for a relation', function() {
|
||||
var e = iD.Relation({id: 'r1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/relation/1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#historyURL', function() {
|
||||
it('provides a history url for a node', function() {
|
||||
var e = iD.Node({id: 'n1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/node/1/history');
|
||||
});
|
||||
it('provides a history url for a way', function() {
|
||||
var e = iD.Way({id: 'w1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/way/1/history');
|
||||
});
|
||||
it('provides a history url for a relation', function() {
|
||||
var e = iD.Relation({id: 'r1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/relation/1/history');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#userURL', function() {
|
||||
it('provides a user url', function() {
|
||||
expect(connection.userURL('bob')).to.eql('http://www.openstreetmap.org/user/bob');
|
||||
|
||||
Reference in New Issue
Block a user