Porównaj commity

...

25 Commity

Autor SHA1 Wiadomość Data
Manuel Kasper a8bf61b3a8 Merge branch 'master' into buefy-0.9 2024-01-05 09:49:14 +01:00
Manuel Kasper a4073fba02 Update axios, fix display of "built-in" tracks 2023-12-28 17:12:09 +01:00
Manuel Kasper 0724d9200e Update dependencies, fix saving drawn tracks 2023-12-04 16:26:02 +01:00
Manuel Kasper 5c57070b8a Revert api-db2 changes for the time being (no access for sotlas SSO token) 2023-10-19 07:48:43 +02:00
Manuel Kasper 5309668c5e Handle no bonus correctly 2023-10-18 21:29:02 +02:00
Manuel Kasper 64a6a57f03 Reposition tooltip on mobile 2023-10-18 21:16:42 +02:00
Manuel Kasper 62af0822da Show bonus season on hover 2023-10-18 21:11:12 +02:00
Manuel Kasper 0b96d3c33e Merge branch 'master' into beta 2023-10-18 21:10:38 +02:00
Manuel Kasper c2c6ea1ae7 Fix random switching to other webcam popup 2023-10-16 12:10:39 +02:00
Manuel Kasper 2794e12210 Add bug info for iOS 17 users 2023-10-07 22:03:50 +02:00
Manuel Kasper b19f9d5ecc Use user ID of currently logged in user 2023-09-28 11:29:36 +02:00
Manuel Kasper 53bff389c3 Switch those requests to api-db2 that have already required authentication before
(to maintain public/not-logged-in access to the list of activations for activator details pages)
2023-09-28 11:22:20 +02:00
Manuel Kasper 0434400726 Switch to Windy v3 webcam API due to upcoming deprecation of v2 API 2023-09-28 10:23:56 +02:00
Manuel Kasper 0c6d6f52c7 Add basic background world map to country-specific maps to avoid "blank screen" when outside the selected map's coverage area 2023-09-19 16:16:14 +02:00
Manuel Kasper a978ab19ba Add basemap.at map option (#22), and add link to Austrian Map 2023-09-19 11:01:30 +02:00
Manuel Kasper d458738639 Add info about hiking difficulty 2023-08-19 18:10:05 +02:00
Manuel Kasper 4f94f6ad45 Revert "Show photo waypoints export button also on mobile" (doesn't seem to work on iPhone)
This reverts commit f4c6263f89.
2023-08-02 20:52:31 +02:00
Manuel Kasper f4c6263f89 Show photo waypoints export button also on mobile 2023-08-02 20:49:25 +02:00
Manuel Kasper f390f247a0 Slight legibility improvement 2023-07-30 13:19:49 +02:00
Manuel Kasper 9043e35fda Don't show old photos that are missing an uploadDate 2023-07-24 16:47:19 +02:00
Manuel Kasper 5c1c82d3ad Show warning when uploading low resolution photos 2023-07-21 16:16:18 +02:00
Manuel Kasper ba04fdc2c9 Fix allow ?? region code 2023-06-11 20:00:23 +02:00
Manuel Kasper fa54e7f3f3 Allow -??? summit numbers and XX/?? region codes as well 2023-06-11 19:55:56 +02:00
Manuel Kasper 62219867eb Allow -XXX style references in alerts 2023-06-11 19:47:07 +02:00
Manuel Kasper 05765e9562 Honor line breaks in SMP route descriptions 2023-05-30 20:03:02 +02:00
25 zmienionych plików z 1245 dodań i 702 usunięć

1165
package-lock.json wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -11,6 +11,7 @@
},
"dependencies": {
"@dsb-norge/vue-keycloak-js": "github:manuelkasper/vue-keycloak-js#sotlas",
"@dwayneparton/geojson-to-gpx": "^0.0.30",
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.2",
@ -19,8 +20,8 @@
"@fortawesome/vue-fontawesome": "^0.1.10",
"@mapbox/mapbox-gl-draw": "github:manuelkasper/mapbox-gl-draw#sotlas",
"@tmcw/togeojson": "^3.2.0",
"axios": "^1.4.0",
"buefy": "^0.9.23",
"axios": "^1.6.3",
"buefy": "^0.9.27",
"cheap-ruler": "^2.5.1",
"core-js": "^2.6.12",
"filepond": "^4.30.4",
@ -34,7 +35,6 @@
"node-vincenty": "0.0.6",
"photoswipe": "^4.1.3",
"proj4": "^2.7.2",
"togpx": "^0.5.4",
"vue": "^2.7.14",
"vue-clipboard2": "^0.3.1",
"vue-debounce": "^2.6.0",

Wyświetl plik

@ -0,0 +1,385 @@
{
"version": 8,
"name": "basemapat",
"metadata": {"maputnik:renderer": "mbgljs", "openmaptiles:version": "3.x"},
"center": [13.1411895, 47.698321],
"zoom": 6,
"bearing": 0,
"pitch": 0,
"sources": {
"basemapat": {
"type": "raster",
"tiles": [
"https://mapsneu.wien.gv.at/basemap/bmaphidpi/normal/google3857/{z}/{y}/{x}.jpeg"
],
"tileSize": 256,
"maxzoom": 18,
"bounds": [8.782379, 46.358770, 17.5, 49.037872],
"attribution": "Grundkarte: <a target=\"_blank\" href=\"https://basemap.at/\">basemap.at</a>"
},
"summits": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/summits.json"
},
"summits_inactive": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/summits_inactive.json"
},
"regions": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/regions.json"
},
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://sotl.as/sprites",
"glyphs": "https://0.{mapServer}.map.sotl.as/fonts/{fontstack}/{range}.pbf",
"transition": {},
"layers": [
{
"id": "background",
"type": "background",
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "basemapat",
"type": "raster",
"source": "basemapat",
"layout": {"visibility": "visible"},
"paint": {
"raster-opacity": 0.75,
"raster-resampling": "linear"
}
},
{
"id": "summits_az",
"type": "fill",
"metadata": {
"sotlas-map-option": "az"
},
"source": "az",
"source-layer": "az",
"layout": {"visibility": "none"},
"minzoom": 12,
"paint": {
"fill-antialias": false,
"fill-color": "rgba(255, 255, 0, 1)",
"fill-opacity": {"stops": [[12, 0], [12.5, 0.5]]}
}
},
{
"id": "summits_az_border",
"type": "line",
"metadata": {
"sotlas-map-option": "az"
},
"source": "az",
"source-layer": "az",
"layout": {"visibility": "none"},
"minzoom": 12,
"paint": {
"line-color": "rgba(235, 196, 0, 1)",
"line-opacity": {"stops": [[12, 0], [12.5, 0.5]]},
"line-width": {"stops": [[12, 1], [16, 3]]}
}
},
{
"id": "summits_selected",
"type": "circle",
"source": "summits",
"source-layer": "summits",
"filter": ["all", ["in", "code"]],
"layout": {"visibility": "visible"},
"paint": {
"circle-color": "rgba(2, 153, 243, 1)",
"circle-radius": {"stops": [[6, 15], [20, 50]]},
"circle-opacity": 0.75,
"circle-stroke-color": "rgba(210, 255, 0, 0.05)",
"circle-stroke-width": 0,
"circle-stroke-opacity": 1,
"circle-blur": 0.7
}
},
{
"id": "summits_names",
"type": "symbol",
"source": "summits",
"source-layer": "summits",
"minzoom": 10,
"maxzoom": 24,
"filter": ["all", ["in", "code"]],
"layout": {
"visibility": "visible",
"text-field": "{name}\n{code}\n{alt} m",
"text-size": {"stops": [[10, 10], [20, 16]]},
"text-font": ["Frutiger Neue Regular"],
"text-anchor": "bottom",
"text-offset": {"stops": [[10, [0, -1]], [20, [0, -2]]]},
"icon-size": 1,
"symbol-spacing": 250,
"symbol-avoid-edges": false,
"text-keep-upright": true,
"text-transform": "none",
"text-optional": false,
"text-allow-overlap": {"stops": [[18, false], [19, true]]},
"text-ignore-placement": false,
"text-justify": "center",
"text-rotate": 0
},
"paint": {
"text-color": "rgba(51, 51, 51, 1)",
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 1,
"text-halo-blur": 1
}
},
{
"id": "summits_circles_all",
"type": "circle",
"source": "summits",
"source-layer": "summits",
"layout": {"visibility": "none"},
"paint": {
"circle-stroke-color": "rgba(255, 255, 255, 1)",
"circle-color": [
"match",
["get", "points"],
[1],
"rgba(77, 122, 32, 0.5)",
[2],
"rgba(109, 165, 54, 0.5)",
[4],
"rgba(174, 167, 39, 0.5)",
[6],
"rgba(239, 168, 24, 0.5)",
[8],
"rgba(220, 93, 4, 0.5)",
[10],
"rgba(200, 16, 30, 0.5)",
"#000"
],
"circle-stroke-width": {"stops": [[4, 0], [15, 1]]},
"circle-radius": {"stops": [[0, 0.05], [10, 2.5], [22, 12]]}
}
},
{
"id": "summits_circles",
"type": "circle",
"source": "summits",
"source-layer": "summits",
"filter": ["all", ["in", "code"]],
"layout": {"visibility": "visible"},
"paint": {
"circle-stroke-color": "rgba(255, 255, 255, 1)",
"circle-color": [
"match",
["get", "points"],
[1],
"rgba(77, 122, 32, 1)",
[2],
"rgba(109, 165, 54, 1)",
[4],
"rgba(174, 167, 39, 1)",
[6],
"rgba(239, 168, 24, 1)",
[8],
"rgba(220, 93, 4, 1)",
[10],
"rgba(200, 16, 30, 1)",
"#000"
],
"circle-stroke-width": {"stops": [[4, 0], [15, 2]]},
"circle-radius": {"stops": [[0, 0.1], [10, 8], [22, 20]]}
}
},
{
"id": "summits_activations",
"type": "symbol",
"source": "summits",
"source-layer": "summits",
"minzoom": 10,
"maxzoom": 24,
"filter": ["all", ["in", "code"]],
"layout": {
"text-field": "{act}",
"text-font": ["Frutiger Neue Bold"],
"text-size": {"stops": [[10, 8], [20, 16]]},
"text-offset": [0,0.1]
},
"paint": {"text-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "summits_highlight",
"type": "circle",
"source": "summits",
"source-layer": "summits",
"filter": ["all", ["in", "code"]],
"layout": {"visibility": "visible"},
"paint": {
"circle-color": "rgba(2, 243, 198, 1)",
"circle-radius": {"stops": [[6, 15], [20, 50]]},
"circle-opacity": 0.75,
"circle-blur": 0.7
}
},
{
"id": "summits_highlight_alerts",
"type": "circle",
"source": "summits",
"source-layer": "summits",
"filter": ["all", ["in", "code"]],
"layout": {"visibility": "visible"},
"paint": {
"circle-color": "rgba(210, 255, 0, 1)",
"circle-radius": {"stops": [[6, 15], [20, 50]]},
"circle-opacity": 0.55,
"circle-blur": 0.7
}
},
{
"id": "summits_inactive_names",
"type": "symbol",
"metadata": {
"sotlas-map-option": "inactive"
},
"source": "summits_inactive",
"source-layer": "summits_inactive",
"minzoom": 10,
"maxzoom": 24,
"filter": ["all", ["in", "code"]],
"layout": {
"visibility": "none",
"text-field": "{name}\n{code}\n{alt} m\n(inactive)",
"text-size": {"stops": [[10, 10], [20, 16]]},
"text-font": ["Frutiger Neue Regular"],
"text-anchor": "bottom",
"text-offset": {"stops": [[10, [0, -1]], [20, [0, -2]]]},
"icon-size": 1,
"symbol-spacing": 250,
"symbol-avoid-edges": false,
"text-keep-upright": true,
"text-transform": "none",
"text-optional": false,
"text-allow-overlap": {"stops": [[18, false], [19, true]]},
"text-ignore-placement": false,
"text-justify": "center",
"text-rotate": 0
},
"paint": {
"text-color": "rgba(51, 51, 51, 1)",
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 1,
"text-halo-blur": 1,
"text-opacity": 1
}
},
{
"id": "summits_inactive_circles",
"type": "circle",
"metadata": {
"sotlas-map-option": "inactive"
},
"source": "summits_inactive",
"source-layer": "summits_inactive",
"filter": ["all", ["in", "code"]],
"layout": {"visibility": "none"},
"paint": {
"circle-stroke-color": "rgba(255, 255, 255, 1)",
"circle-color": [
"match",
["get", "points"],
[1],
"rgba(77, 122, 32, 0.5)",
[2],
"rgba(109, 165, 54, 0.5)",
[4],
"rgba(174, 167, 39, 0.5)",
[6],
"rgba(239, 168, 24, 0.5)",
[8],
"rgba(220, 93, 4, 0.5)",
[10],
"rgba(200, 16, 30, 0.5)",
"#000"
],
"circle-stroke-width": {"stops": [[4, 0], [15, 2]]},
"circle-radius": {"stops": [[0, 0.1], [10, 8], [22, 20]]}
}
},
{
"id": "regions_areas",
"type": "fill",
"metadata": {
"sotlas-map-option": "regions"
},
"source": "regions",
"source-layer": "areas",
"minzoom": 0,
"layout": {"visibility": "none"},
"paint": {
"fill-opacity": 0.1,
"fill-antialias": false,
"fill-color": "rgba(0, 0, 0, 1)"
}
},
{
"id": "regions_labels",
"type": "symbol",
"metadata": {
"sotlas-map-option": "regions"
},
"source": "regions",
"source-layer": "labels",
"layout": {
"visibility": "none",
"text-field": "{region}",
"text-anchor": "top-left",
"text-justify": "center",
"text-offset": [0.3, 0.3],
"text-font": ["Frutiger Neue Regular"],
"text-size": {"stops": [[6, 8], [10, 16]]}
},
"paint": {
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 0.5,
"text-halo-blur": 1,
"text-translate": [0, 0]
}
}
]
}

Wyświetl plik

@ -32,6 +32,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://sotl.as/sprites",
@ -44,6 +48,34 @@
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "caltopo",
"type": "raster",

Wyświetl plik

@ -32,6 +32,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://sotl.as/sprites",
@ -44,6 +48,34 @@
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "norkart",
"type": "raster",

Wyświetl plik

@ -89,6 +89,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://vectortiles.geo.admin.ch/styles/ch.swisstopo.leichte-basiskarte.vt/sprite/sprite",
@ -105,6 +109,34 @@
"background-color": "rgba(255, 255, 255, 1)"
}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "relief_shading",
"type": "raster",

Wyświetl plik

@ -86,6 +86,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://vectortiles.geo.admin.ch/styles/ch.swisstopo.leichte-basiskarte.vt/sprite/sprite",
@ -98,6 +102,34 @@
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "swisstopo",
"type": "raster",

Wyświetl plik

@ -86,6 +86,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://vectortiles.geo.admin.ch/styles/ch.swisstopo.leichte-basiskarte.vt/sprite/sprite",
@ -98,6 +102,34 @@
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "swisstopo",
"type": "raster",
@ -265,7 +297,7 @@
"paint": {
"text-color": "rgba(51, 51, 51, 1)",
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 1,
"text-halo-width": 1.5,
"text-halo-blur": 1
}
},

Wyświetl plik

@ -32,6 +32,10 @@
"az": {
"type": "vector",
"url": "https://1.{mapServer}.map.sotl.as/data/az.json"
},
"openmaptiles": {
"type": "vector",
"url": "https://0.{mapServer}.map.sotl.as/data/osm-sotlas.json"
}
},
"sprite": "https://sotl.as/sprites",
@ -44,6 +48,34 @@
"layout": {"visibility": "visible"},
"paint": {"background-color": "rgba(255, 255, 255, 1)"}
},
{
"id": "water",
"type": "fill",
"metadata": {},
"source": "openmaptiles",
"source-layer": "water",
"filter": ["all"],
"layout": {"visibility": "visible"},
"paint": {"fill-color": "rgba(103, 166, 196, 0.2)"}
},
{
"id": "boundary_2",
"type": "line",
"metadata": {},
"source": "openmaptiles",
"source-layer": "boundary",
"filter": ["all", ["==", "admin_level", 2], ["==", "maritime", 0]],
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(136, 136, 136, 1)",
"line-opacity": 0.2,
"line-width": {"base": 1, "stops": [[3, 1], [5, 1.2], [12, 3]]}
}
},
{
"id": "toposvalbard",
"type": "raster",

Wyświetl plik

@ -245,6 +245,14 @@ export default {
}
}
},
{
name: 'Austrian Map',
url: () => {
if (this.reference && this.reference.match('^OE/')) {
return `https://maps.bev.gv.at/#/center/${this.longitude},${this.latitude}/zoom/13`
}
}
},
{
name: 'Basemap.at',
url: () => {

Wyświetl plik

@ -5,7 +5,7 @@
</header>
<section class="modal-card-body">
<b-field label="Callsign" :message="isOwnCallsign ? '' : 'You are posting an alert for someone else\'s callsign'" :type="isOwnCallsign ? '' : 'is-info'">
<b-input type="text" class="callsign" v-model="callsign" pattern="[a-zA-Z0-9/]{3,}" validation-message="Invalid callsign" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required />
<b-input type="text" class="callsign" v-model="callsign" pattern="[a-zA-Z0-9\/]{3,}" validation-message="Invalid callsign" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required />
</b-field>
<b-field label="Summit reference" :message="summitDisplay" :type="summitType" :class="summitLabelClass" expanded>
@ -122,7 +122,10 @@ export default {
}
},
isInputValid () {
return /^[a-zA-Z0-9/]{3,}$/.test(this.callsign) && this.summit !== null && this.isSummitValid(this.summit) && this.date && /^\d\d:\d\d$/.test(this.time) && this.freqMode.length > 0 && (this.freqMode.join(', ').length <= 40 || this.freqMode.join(',').length <= 40)
return /^[a-zA-Z0-9/]{3,}$/.test(this.callsign) &&
(this.summitCodeXxx || (this.summit !== null && this.isSummitValid(this.summit))) &&
this.date && /^\d\d:\d\d$/.test(this.time) &&
this.freqMode.length > 0 && (this.freqMode.join(', ').length <= 40 || this.freqMode.join(',').length <= 40)
},
summitLabelClass () {
if (!this.summit || this.isSummitValid(this.summit)) {
@ -149,22 +152,29 @@ export default {
handler () {
if (this.summitCode) {
// Shorthand input
let summitRegex = /^([A-Z0-9]{1,8})[/ ]([A-Z]{2})[- ]?([0-9]{3})$/i
let summitRegex = /^([A-Z0-9]{1,8})[/ ]([A-Z]{2}|\?\?)[- ]?([0-9]{3}|xxx|\?\?\?)$/i
let matches = this.summitCode.match(summitRegex)
if (matches) {
this.summitCode = (matches[1] + '/' + matches[2] + '-' + matches[3]).toUpperCase()
this.summitLoading = true
axios.get(process.env.VUE_APP_API_URL + '/summits/' + this.summitCode)
.then(response => {
this.summitLoading = false
this.summitInvalid = false
this.summit = response.data
})
.catch(() => {
this.summitLoading = false
this.summitInvalid = true
this.summit = null
})
if (matches[2].toUpperCase() === 'XX' || matches[2] === '??' || matches[3].toUpperCase() === 'XXX' || matches[3] === '???') {
this.summitInvalid = false
this.summitCodeXxx = true
this.summit = null
} else {
this.summitLoading = true
this.summitCodeXxx = false
axios.get(process.env.VUE_APP_API_URL + '/summits/' + this.summitCode)
.then(response => {
this.summitLoading = false
this.summitInvalid = false
this.summit = response.data
})
.catch(() => {
this.summitLoading = false
this.summitInvalid = true
this.summit = null
})
}
} else {
this.summit = null
this.summitInvalid = false
@ -344,6 +354,7 @@ export default {
comments: '',
summit: null,
summitInvalid: false,
summitCodeXxx: false,
summitLoading: false,
timeZone: 'utc',
posting: false

Wyświetl plik

@ -15,7 +15,7 @@
import MapboxDraw from '@mapbox/mapbox-gl-draw'
import haversineDistance from 'haversine-distance'
import cheapRuler from 'cheap-ruler'
import togpx from 'togpx'
import GeoJsonToGpx from '@dwayneparton/geojson-to-gpx'
import moment from 'moment'
import axios from 'axios'
import utils from '../mixins/utils.js'
@ -295,8 +295,9 @@ export default {
this.addElevations(all)
.then(() => {
loadingComponent.close()
let gpx = togpx(all)
let blob = new Blob([gpx], { type: 'application/gpx+xml' })
let gpx = GeoJsonToGpx(all)
let gpxString = new XMLSerializer().serializeToString(gpx)
let blob = new Blob([gpxString], { type: 'application/gpx+xml' })
let url = window.URL.createObjectURL(blob)
let link = document.createElement('a')
link.download = 'sotlas-' + moment().format('YYYYMMDD-HHmmss') + '.gpx'
@ -454,7 +455,7 @@ export default {
}
let coordsSwapped = feature.geometry.coordinates.map(coord => [coord[1], coord[0]])
return axios.post('https://ele.sotl.as/api', coordsSwapped)
return axios.post(process.env.VUE_APP_ELEVATION_API_URL, coordsSwapped)
.then(result => {
result.data.forEach((elevation, index) => {
if (feature.geometry.coordinates[index].length === 2) {

Wyświetl plik

@ -32,9 +32,12 @@
</b-checkbox>
</b-field>
</div>
<div class="map-option" v-if="mapType !== 'toposvalbard' && mapType !== 'norkart' && mapType !== 'caltopo'">
<div class="map-option" v-if="mapType !== 'toposvalbard' && mapType !== 'norkart' && mapType !== 'caltopo' && mapType !== 'basemapat'">
<b-field grouped>
<b-checkbox v-model="mapOptions.difficulty" size="is-small" @input="setMapOption('difficulty', $event)">Hiking difficulty</b-checkbox>
<b-checkbox v-model="mapOptions.difficulty" size="is-small" @input="setMapOption('difficulty', $event)">
Hiking difficulty
<b-icon pack="fas" icon="info-circle" size="is-small" type="is-info" @click.native="showHikingDifficultyInfo" />
</b-checkbox>
</b-field>
<template v-if="mapType.startsWith('swisstopo')">
<b-field grouped>
@ -205,6 +208,17 @@ export default {
icon: 'info-circle',
iconPack: 'fas'
})
},
showHikingDifficultyInfo (event) {
event.preventDefault()
this.$buefy.dialog.alert({
title: 'Hiking difficulty',
message: '<p>The hiking difficulty grading uses the <a href="https://www.sac-cas.ch/fileadmin/Ausbildung_und_Wissen/Sicher_unterwegs/Sicher_unterwegs_Wandern/2020_Berg_Alpinwanderskala_EN.pdf" target="_blank">SAC scale</a>. Colors shown are as follows:</p><ul><li><span style="color: #cccc00">Yellow</span>: T1</li><li><span style="color: #cc0000">Red</span>: T2…T3</li><li><span style="color: #3333cc">Blue</span>: T4…T6</li></ul>',
type: 'is-info',
hasIcon: true,
icon: 'info-circle',
iconPack: 'fas'
})
}
}
}

Wyświetl plik

@ -25,7 +25,7 @@
<script>
import axios from 'axios'
import togeojson from '@tmcw/togeojson'
import { gpx } from '@tmcw/togeojson'
import { MglGeojsonLayer, MglMarker } from 'vue-mapbox'
import haversineDistance from 'haversine-distance'
import tracks from '../mixins/tracks.js'
@ -180,7 +180,7 @@ export default {
let dom = (new DOMParser()).parseFromString(response.data, 'text/xml')
this.geoJsonSource = {
type: 'geojson',
data: togeojson.gpx(dom)
data: gpx(dom)
}
})
},

Wyświetl plik

@ -6,14 +6,14 @@
<font-awesome-icon icon="circle" />
<font-awesome-icon :icon="['fas', 'camera-home']" transform="shrink-7 left-0.5" :style="{ color: 'white' }" />
</font-awesome-layers>
<div v-if="webcam.map.clustersize > 1" class="clustersize">+{{ webcam.map.clustersize - 1 }}</div>
<div v-if="webcam.clusterSize > 1" class="clustersize">+{{ webcam.clusterSize - 1 }}</div>
</div>
<MglPopup :closeButton="false" @added="popupAdded">
<div :class="['thumbwrapper', size]">
<a :href="thumbnailHref" target="_blank"><img class="thumb" :src="thumbnailSrc" /></a>
<div class="caption">{{ title }}</div>
<template v-if="webcam.map.clustersize > 1 && size != 'is-small'">
<div class="clustercaption">{{ webcam.map.clustersize - 1 }} more webcam{{ webcam.map.clustersize > 2 ? 's' : '' }}</div>
<template v-if="webcam.clusterSize > 1 && size != 'is-small'">
<div class="clustercaption">{{ webcam.clusterSize - 1 }} more webcam{{ webcam.clusterSize > 2 ? 's' : '' }}</div>
<div class="clusterinfo">zoom in to view</div>
</template>
<div class="attribution">Webcams provided by <a href="https://www.windy.com/" target="_blank">windy.com</a></div>
@ -43,10 +43,10 @@ export default {
return this.webcam.title
},
thumbnailSrc () {
return this.$store.state.mapOptions.webcamsType === 'current' ? this.webcam.image.current.preview : this.webcam.image.daylight.preview
return this.$store.state.mapOptions.webcamsType === 'current' ? this.webcam.images.current.preview : this.webcam.images.daylight.preview
},
thumbnailHref () {
return this.$mq.mobile ? this.webcam.url.current.mobile : this.webcam.url.current.desktop
return 'https://www.windy.com/webcams/' + this.webcam.webcamId
}
},
methods: {

Wyświetl plik

@ -1,6 +1,6 @@
<template>
<div>
<MapWebcam v-for="webcam in webcams" :key="webcam.id" :webcam="webcam" :size="size" />
<MapWebcam v-for="webcam in webcams" :key="webcam.webcamId" :webcam="webcam" :size="size" />
</div>
</template>
@ -32,12 +32,41 @@ export default {
},
loadWebcams () {
// Convert MapBox zoom level to Google Maps like zoom level
let mapZoom = Math.floor(Math.min(this.map.getZoom() + 2, 22))
let mapBounds = this.map.getBounds().getNorthEast().lat + ',' + this.map.getBounds().getNorthEast().lng + ',' + this.map.getBounds().getSouthWest().lat + ',' + this.map.getBounds().getSouthWest().lng + ',' + mapZoom
let mapZoom = Math.floor(Math.min(this.map.getZoom() + 1, 18))
axios.get('https://api.windy.com/api/webcams/v2/map/' + mapBounds, { params: { key: this.windyApiKey, show: 'webcams:location,image,url,map' } })
// Windy v3 API has a limit on the latitude/longitude span relative to the zoom level.
// Ensure that we are within the limit, lower the zoom level if necessary, otherwise
// we will get a 400 response.
let latSpan = Math.abs(this.map.getBounds().getNorthEast().lat - this.map.getBounds().getSouthWest().lat)
let lngSpan = Math.abs(this.map.getBounds().getNorthEast().lng - this.map.getBounds().getSouthWest().lng)
while (mapZoom > 4) {
let maxAllowedLatSpan = 22.5 / Math.pow(2, mapZoom - 4)
let maxAllowedLngSpan = 45 / Math.pow(2, mapZoom - 4)
if (latSpan < maxAllowedLatSpan && lngSpan < maxAllowedLngSpan) {
break
}
mapZoom--
}
if (mapZoom <= 4) {
// We have reached the limit of what we can request via the API - so don't request anything
this.webcams = []
return
}
axios.get('https://api.windy.com/webcams/api/v3/map/clusters', {
headers: { 'X-WINDY-API-KEY': this.windyApiKey },
params: {
northLat: this.map.getBounds().getNorthEast().lat,
eastLon: this.map.getBounds().getNorthEast().lng,
southLat: this.map.getBounds().getSouthWest().lat,
westLon: this.map.getBounds().getSouthWest().lng,
zoom: mapZoom,
include: 'location,images,urls'
}
})
.then(response => {
this.webcams = response.data.result.webcams.filter(webcam => { return webcam.status === 'active' })
this.webcams = response.data.filter(webcam => { return webcam.status === 'active' })
})
}
},

Wyświetl plik

@ -22,7 +22,7 @@ export default {
},
prefs: {
key: 'photosUploaderPrefs',
props: ['gpsNotificationShown']
props: ['gpsNotificationShown', 'resolutionWarningShown']
},
mixins: [api, prefs],
computed: {
@ -55,6 +55,18 @@ export default {
})
this.gpsNotificationShown = true
}
if (res.data.length > 0 && res.data[0].width < 1600 && res.data[0].height < 1600 && !this.resolutionWarningShown) {
this.$buefy.dialog.alert({
title: 'Low photo resolution',
message: '<p>Your photo has been uploaded successfully, but its resolution is quite low (< 1600 pixels width or height). Please upload original, full resolution photos whenever possible. SOTLAS will automatically resize them as appropriate.</p><p><small>This alert will not appear again for future uploads of low resolution photos.</small></p>',
type: 'is-info',
hasIcon: true,
icon: 'info-circle',
iconPack: 'far'
})
this.resolutionWarningShown = true
}
})
.catch(err => {
error(err)
@ -81,7 +93,8 @@ export default {
},
data () {
return {
gpsNotificationShown: false
gpsNotificationShown: false,
resolutionWarningShown: false
}
}
}

Wyświetl plik

@ -50,7 +50,7 @@ export default {
let summitPhotos = this.summit.photos
if (this.minDate) {
summitPhotos = summitPhotos.filter(photo => {
return moment(photo.uploadDate).isSameOrAfter(moment(this.minDate))
return photo.uploadDate && moment(photo.uploadDate).isSameOrAfter(moment(this.minDate))
})
}
summitPhotos.forEach(photo => {

Wyświetl plik

@ -13,12 +13,13 @@ import PictureSwipe from './PictureSwipe.vue'
import utils from '../mixins/utils.js'
import photos from '../mixins/photos.js'
import moment from 'moment'
import togpx from 'togpx'
import GeoJsonToGpx from '@dwayneparton/geojson-to-gpx'
export default {
name: 'SummitPhotosGroup',
props: {
photos: Array,
title: String,
summit: Object,
editable: Boolean,
showSummitName: Boolean,
@ -146,11 +147,17 @@ export default {
return feature
})
let gpx = togpx({
let options = {
metadata: {
name: 'Photos from ' + this.title + ' for ' + this.summit.name + ' (' + this.summit.code + ')'
}
}
let gpx = GeoJsonToGpx({
'type': 'FeatureCollection',
'features': features
})
let blob = new Blob([gpx], { type: 'application/gpx+xml' })
}, options)
let gpxString = new XMLSerializer().serializeToString(gpx)
let blob = new Blob([gpxString], { type: 'application/gpx+xml' })
let url = window.URL.createObjectURL(blob)
let link = document.createElement('a')
link.download = 'photos-' + this.summit.code.replace('/', '_') + '-' + this.title + '.gpx'

Wyświetl plik

@ -104,6 +104,7 @@ export default {
'swisstopo': 'swisstopo (Vector)',
'swisstopo_raster': 'swisstopo (Raster)',
'swisstopo_aerial': 'swisstopo (Aerial)',
'basemapat': 'basemap.at',
'caltopo': 'CalTopo',
'toposvalbard': 'TopoSvalbard',
'norkart': 'Norkart'

Wyświetl plik

@ -48,7 +48,7 @@ export default {
routes.push({
id: track.hdr_id,
title: track.track_title,
htmlDescription: '<p>' + this.escapeHtml(track.track_notes) + '</p><p><small>Track imported from <a href="https://www.sotamaps.org" target="_blank">SMP</a></small></p>',
htmlDescription: '<p>' + this.escapeHtml(track.track_notes).replace(/\n/g, '<br />') + '</p><p><small>Track imported from <a href="https://www.sotamaps.org" target="_blank">SMP</a></small></p>',
description: track.track_notes,
author: track.callsign,
distance,

Wyświetl plik

@ -1,8 +1,9 @@
import axios from 'axios'
import ssoauth from './ssoauth.js'
import utils from './utils.js'
export default {
mixins: [ssoauth],
mixins: [ssoauth, utils],
methods: {
loadActivations (callsign) {
return axios.get(process.env.VUE_APP_API_URL + '/activations/' + callsign)

Wyświetl plik

@ -3,7 +3,7 @@
<template v-slot:title>Alerts</template>
<template v-slot:title-right>
<div class="action-button">
<b-button type="is-info" icon-left="plus" @click="$refs.alertsList.addAlert()" :disabled="!authenticated">Add</b-button>
<b-button type="is-info" icon-left="plus" @click="$refs.alertsList.addAlert()">Add</b-button>
</div>
</template>

Wyświetl plik

@ -30,7 +30,7 @@
<MapWebcams v-if="mapOptions.webcams" />
</MglMap>
<div v-if="browserNotSupported" class="browser-not-supported">Your browser does not support WebGL, which is required to render this map.</div>
<div v-if="browserNotSupported" class="browser-not-supported">Your browser does not support WebGL, which is required to render this map. <strong>iOS 17 users: There is a bug in iOS 17 that can sometimes cause this error. Restarting Safari (closing/killing it completely) resolves the issue temporarily.</strong></div>
<div v-if="zoomWarning" class="zoom-warning">Zoom in to see all filtered/spotted summits</div>
<SwisstopoInfo />
<b-loading :is-full-page="false" :active="filtering || !showMap || !mapStyle" />

Wyświetl plik

@ -20,7 +20,14 @@
<p class="subtitle is-size-7-mobile">
<span class="summit-info"><strong>{{ summit.code }}</strong></span>
<span class="summit-info"><AltitudeLabel :altitude="summit.altitude" /></span>
<span class="summit-info"><SummitPointsLabel class="points" :points="summit.points" :bonus="summit.bonusPoints" /> {{ summit.points > 1 ? 'points' : 'point' }}</span>
<span v-if="bonusSeason" class="summit-info">
<b-tooltip class="season-tooltip" type="is-light" :position="$mq.mobile ? 'is-bottom' : 'is-right'" :label="bonusSeason">
<SummitPointsLabel class="points" :points="summit.points" :bonus="summit.bonusPoints" />
</b-tooltip> {{ summit.points > 1 ? 'points' : 'point' }}
</span>
<span v-else class="summit-info">
<SummitPointsLabel class="points" :points="summit.points" :bonus="summit.bonusPoints" /> {{ summit.points > 1 ? 'points' : 'point' }}
</span>
<span v-if="activations !== null" class="summit-info"><font-awesome-icon :icon="['far', 'chevron-circle-up']" class="faicon" /> {{ activations.length }} {{ activations.length === 1 ? 'activation' : 'activations' }}<span v-if="myActivations && myActivations.length > 0"> ({{ myActivations.length }} by me)</span></span>
<span v-if="myChases !== null && myChases.length > 0" class="summit-info"><font-awesome-icon :icon="['far', 'chevron-circle-down']" class="faicon" /> {{ myChases.length }} {{ myChases.length === 1 ? 'chase' : 'chases' }} by me</span>
<span v-if="isComplete" class="summit-info"><font-awesome-icon :icon="['far', 'check-double']" class="faicon" /> Complete</span>
@ -384,6 +391,15 @@ export default {
})
}))
loads.push(axios.get('https://api-db2.sota.org.uk/summits/history/' + this.summitCode)
.then(response => {
if (response.data.BonusPoints > 0) {
this.bonusSeason = '+ ' + response.data.BonusSeason
} else {
this.bonusSeason = null
}
}))
if (this.myUserId) {
loads.push(axios.get('https://api2.sota.org.uk/api/qsos/user-chases-by-summit/' + this.summitCode + '/' + this.myUserId)
.then(response => {
@ -460,7 +476,8 @@ export default {
isAddAlertActive: false,
isAddSpotActive: false,
enlargeMap: false,
alwaysLoadWikipedia: true
alwaysLoadWikipedia: true,
bonusSeason: null
}
}
}
@ -597,4 +614,7 @@ export default {
color: #b5b5b5;
cursor: not-allowed;
}
.season-tooltip {
cursor: default;
}
</style>