Merge branch 'info-box'

This commit is contained in:
Bryan Housel
2017-07-05 18:14:25 -04:00
24 changed files with 1378 additions and 326 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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

View File

@@ -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"
}
]
}
]
}
]}

View File

@@ -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
View File

@@ -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": {

View File

@@ -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';

View File

@@ -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;
};

View File

@@ -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')
);
});
});
}
}

View File

@@ -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);
});
},

View File

@@ -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);

View File

@@ -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);

View File

@@ -81,10 +81,7 @@ export function uiInit(context) {
.call(map);
content
.call(uiMapInMap(context));
content
.append('div')
.call(uiMapInMap(context))
.call(uiInfo(context));
bar

View 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;
}

View 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;
}

View 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,
};

View 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;
}

View 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;
}

View File

@@ -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
View File

21
scripts/txpush.sh Executable file
View 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

View File

@@ -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');
});
});

View File

@@ -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');