Added testing to OSM before loading map

Prevent users in locations blocked OSM seeing an empty div
This commit is contained in:
Donald Zou
2024-10-02 21:53:57 +08:00
parent 4905d61a1a
commit 25be1155a6
6 changed files with 183 additions and 154 deletions
File diff suppressed because one or more lines are too long
+37 -28
View File
File diff suppressed because one or more lines are too long
-116
View File
@@ -1,116 +0,0 @@
<script>
import "ol/ol.css"
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import {Feature} from "ol";
import {fromLonLat} from "ol/proj"
import {LineString, Point} from "ol/geom"
import {Circle, Fill, Stroke, Style, Text} from "ol/style.js";
import {Vector} from "ol/layer"
import {Vector as SourceVector} from "ol/source"
export default {
name: "map",
props: {
type: "",
d: Object || Array
},
methods: {
getLastLonLat(){
if (this.type === 'traceroute'){
const k = this.d.findLast(data => data.geo && data.geo.lat && data.geo.lon)
if (k){
return [k.geo.lon, k.geo.lat]
}
return [0,0]
}
return [this.d.geo.lon, this.d.geo.lat]
}
},
mounted() {
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: fromLonLat(this.getLastLonLat()),
zoom: this.type === 'traceroute' ? 3:10,
}),
});
const coordinates = [];
const vectorSource = new SourceVector();
if (this.type === 'traceroute'){
console.log(this.getLastLonLat())
this.d.forEach(data => {
if (data.geo && data.geo.lat && data.geo.lon) {
const coordinate = fromLonLat([data.geo.lon, data.geo.lat]);
coordinates.push(coordinate);
const l = this.getLastLonLat();
console.log(data.geo.lon, data.geo.lat)
console.log( data.geo.lon === l[0] && data.geo.lat === l[1])
const marker = new Feature({
geometry: new Point(coordinate),
last: data.geo.lon === l[0] && data.geo.lat === l[1]
});
vectorSource.addFeature(marker);
}
})
}else{
const coordinate = fromLonLat([this.d.geo.lon, this.d.geo.lat])
coordinates.push(coordinate);
const marker = new Feature({
geometry: new Point(coordinate)
});
vectorSource.addFeature(marker);
}
const lineString = new LineString(coordinates);
const lineFeature = new Feature({
geometry: lineString
});
vectorSource.addFeature(lineFeature);
const vectorLayer = new Vector({
source: vectorSource,
style: function(feature) {
if (feature.getGeometry().getType() === 'Point') {
return new Style({
image: new Circle({
radius: 10,
fill: new Fill({ color: feature.get("last") ? '#dc3545':'#0d6efd' }),
stroke: new Stroke({ color: 'white', width: 5 }),
})
});
} else if (feature.getGeometry().getType() === 'LineString') {
return new Style({
stroke: new Stroke({
color: '#0d6efd',
width: 2
})
});
}
}
});
map.addLayer(vectorLayer);
}
}
</script>
<template>
<div id="map" class="w-100 rounded-3"></div>
</template>
<style>
.ol-layer canvas{
border-radius: var(--bs-border-radius-lg) !important;
}
#map{
height: 300px;
}
</style>
+133
View File
@@ -0,0 +1,133 @@
<script>
import "ol/ol.css"
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import {Feature} from "ol";
import {fromLonLat} from "ol/proj"
import {LineString, Point} from "ol/geom"
import {Circle, Fill, Stroke, Style, Text} from "ol/style.js";
import {Vector} from "ol/layer"
import {Vector as SourceVector} from "ol/source"
export default {
name: "osmap",
props: {
type: "",
d: Object || Array
},
data(){
return {
osmAvailable: true
}
},
methods: {
getLastLonLat(){
if (this.type === 'traceroute'){
const k = this.d.findLast(data => data.geo && data.geo.lat && data.geo.lon)
if (k){
return [k.geo.lon, k.geo.lat]
}
return [0,0]
}
return [this.d.geo.lon, this.d.geo.lat]
}
},
async mounted() {
const osm = await fetch("https://tile.openstreetmap.org/",
{ signal: AbortSignal.timeout(1500) })
.then(res => {
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: fromLonLat(this.getLastLonLat()),
zoom: this.type === 'traceroute' ? 3:10,
}),
});
const coordinates = [];
const vectorSource = new SourceVector();
if (this.type === 'traceroute'){
console.log(this.getLastLonLat())
this.d.forEach(data => {
if (data.geo && data.geo.lat && data.geo.lon) {
const coordinate = fromLonLat([data.geo.lon, data.geo.lat]);
coordinates.push(coordinate);
const l = this.getLastLonLat();
console.log(data.geo.lon, data.geo.lat)
console.log( data.geo.lon === l[0] && data.geo.lat === l[1])
const marker = new Feature({
geometry: new Point(coordinate),
last: data.geo.lon === l[0] && data.geo.lat === l[1]
});
vectorSource.addFeature(marker);
}
})
}
else{
const coordinate = fromLonLat([this.d.geo.lon, this.d.geo.lat])
coordinates.push(coordinate);
const marker = new Feature({
geometry: new Point(coordinate)
});
vectorSource.addFeature(marker);
}
const lineString = new LineString(coordinates);
const lineFeature = new Feature({
geometry: lineString
});
vectorSource.addFeature(lineFeature);
const vectorLayer = new Vector({
source: vectorSource,
style: function(feature) {
if (feature.getGeometry().getType() === 'Point') {
return new Style({
image: new Circle({
radius: 10,
fill: new Fill({ color: feature.get("last") ? '#dc3545':'#0d6efd' }),
stroke: new Stroke({ color: 'white', width: 5 }),
})
});
} else if (feature.getGeometry().getType() === 'LineString') {
return new Style({
stroke: new Stroke({
color: '#0d6efd',
width: 2
})
});
}
}
});
map.addLayer(vectorLayer);
}).catch(e => {
this.osmAvailable = false
})
}
}
</script>
<template>
<div id="map" class="w-100 rounded-3" v-if="this.osmAvailable"></div>
</template>
<style>
.ol-layer canvas{
border-radius: var(--bs-border-radius-lg) !important;
}
#map{
height: 300px;
}
</style>
+3 -3
View File
@@ -2,11 +2,11 @@
import {fetchGet} from "@/utilities/fetch.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
import Map from "@/components/map/map.vue";
import OSMap from "@/components/map/osmap.vue";
export default {
name: "ping",
components: {Map, LocaleText},
components: {OSMap, LocaleText},
data(){
return {
loading: false,
@@ -177,7 +177,7 @@ export default {
</div>
<div v-else key="pingResult" class="d-flex flex-column gap-2 w-100">
<Map :d="this.pingResult" v-if="this.pingResult.geo && this.pingResult.geo.status === 'success'"></Map>
<OSMap :d="this.pingResult" v-if="this.pingResult.geo && this.pingResult.geo.status === 'success'"></OSMap>
<div class="card rounded-3 bg-transparent shadow-sm animate__animated animate__fadeIn" style="animation-delay: 0.15s">
<div class="card-body row">
<div class="col-sm">
+8 -5
View File
@@ -1,11 +1,12 @@
<script>
import {fetchGet} from "@/utilities/fetch.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import Map from "@/components/map/map.vue";
import OSMap from "@/components/map/osmap.vue";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "traceroute",
components: {Map},
components: {LocaleText, OSMap},
data(){
return {
tracing: false,
@@ -46,14 +47,16 @@ export default {
<div class="d-flex gap-2 flex-column mb-5">
<div>
<label class="mb-1 text-muted" for="ipAddress">
<small>IP Address</small></label>
<small>
<LocaleText t="Enter IP Address / Hostname"></LocaleText>
</small></label>
<input
:disabled="this.tracing"
id="ipAddress"
class="form-control"
v-model="this.ipAddress"
@keyup.enter="this.execute()"
type="text" placeholder="Enter an IP Address you want to trace :)">
type="text">
</div>
<button class="btn btn-primary rounded-3 mt-3 position-relative"
:disabled="this.tracing || !this.ipAddress"
@@ -82,7 +85,7 @@ export default {
v-for="x in 5" ></div>
</div>
<div v-else>
<Map :d="this.tracerouteResult" type="traceroute"></Map>
<OSMap :d="this.tracerouteResult" type="traceroute"></OSMap>
<div key="table" class="w-100 mt-2">
<table class="table table-sm rounded-3 w-100">