<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Model Flying Fields in Austria</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
margin: 0;
}
html, body, #map {
width: 100%;
height: 100%;
}
</style>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
</head>
<body>
<div id="map"
ondrop="dropHandler(event);"
ondragover="dragOverHandler(event);">
</div>
<script>
const osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
const google_sat = L.tileLayer('https://{s}.google.com/vt?lyrs=s&x={x}&y={y}&z={z}', {
maxZoom: 19,
attribution: '© Google',
subdomains: ['mt0','mt1','mt2','mt3']
});
const icon_orange = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-orange.png',
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
const icon_red = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-red.png',
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
const icon_green = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png',
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
function pointToLayer(feature, latlng) {
return L.marker(latlng);
}
function pointToLayerDJI(feature, latlng) {
switch (feature.properties.level) {
case 0: return L.marker(latlng, {icon: icon_orange});
case 3: return L.marker(latlng, {icon: icon_orange});
default: return L.marker(latlng, {icon: icon_red});
}
}
function onEachFeature(feature, layer) {
let content = "";
if (feature.properties && feature.properties.name) {
content += "<strong>"+feature.properties.name+"</strong>";
}
if (feature.properties && feature.properties.description) {
content += "<br />";
content += feature.properties.description;
}
if (feature.geometry && feature.geometry.type == "Point") {
content += "<br />";
content += feature.geometry.coordinates[1]+", "+feature.geometry.coordinates[0];
}
if (content) {
layer.bindPopup(content);
}
}
const geojson_fields = L.geoJSON([], {
pointToLayer: pointToLayer,
onEachFeature: onEachFeature
});
const geojson_dji = L.geoJSON([], {
pointToLayer: pointToLayerDJI,
style: function(feature) {
switch (feature.properties.level) {
case 0: return {color: "#ffcc00"};
case 3: return {color: "#ffcc00"};
default: return {color: "#ff0000"};
}
},
onEachFeature: onEachFeature
});
const geojson_austrocontrol = L.geoJSON([], {
style: {color: "#ff0000"},
onEachFeature: onEachFeature
});
const geojson_dropped = L.geoJSON([], {
pointToLayer: pointToLayer,
onEachFeature: onEachFeature
});
const marker_loc = L.marker([0.0, 0.0], {icon: icon_green});
const layer_loc = L.layerGroup();
const map = L.map('map', {
center: [47.2038, 14.7428],
zoom: 9,
layers: [osm, geojson_fields, geojson_dji, geojson_dropped, layer_loc]
});
map.attributionControl.setPrefix('<a href="https://leafletjs.com" title="A JavaScript library for interactive maps">Leaflet</a>');
const base_layers = {
'OpenStreetMap': osm,
'Google Satellite': google_sat
};
const overlays = {
'Model Flying Fields': geojson_fields,
'DJI GEO Zones': geojson_dji,
'Austro Control Zones': geojson_austrocontrol,
'Dropped GeoJSON': geojson_dropped,
'Current Location': layer_loc
};
const layerControl = L.control.layers(base_layers, overlays).addTo(map);
async function populateFields() {
// https://www.austrocontrol.at/jart/prj3/ac/data/uploads/OeAeC_MOD_001-i16a_modellflugplaetze.pdf
// Version: 2021-03-15, downloaded on 2023-02-13
const requestURL = 'OeAeC_MOD_001-i16a_modellflugplaetze.geojson';
const request = new Request(requestURL);
const response = await fetch(request);
const fields = await response.json();
geojson_fields.addData(fields);
}
populateFields();
async function populateDJI() {
// https://www.dji.com/at/flysafe/geo-map
const requestURL = 'dji_geozones_at.geojson';
const request = new Request(requestURL);
const response = await fetch(request);
const geozones = await response.json();
geojson_dji.addData(geozones);
}
populateDJI();
async function populateAustroControl() {
// https://map.dronespace.at/
const requestURL = 'austrocontrol_zones.geojson';
const request = new Request(requestURL);
const response = await fetch(request);
const zones = await response.json();
geojson_austrocontrol.addData(zones);
}
populateAustroControl();
function dragOverHandler(event) {
event.preventDefault();
}
function dropHandler(event) {
event.preventDefault();
const reader = new FileReader();
reader.onload = function() {
const data = JSON.parse(this.result);
geojson_dropped.addData(data);
};
reader.readAsText(event.dataTransfer.files[0]);
}
function onPositionReceived(position) {
const coords = [position.coords.latitude, position.coords.longitude];
marker_loc.setLatLng(coords)
.bindPopup("<strong>You are here</strong><br />"+coords.join(", "));
if (!layer_loc.hasLayer(marker_loc)) {
layer_loc.addLayer(marker_loc);
}
}
navigator.geolocation.watchPosition(onPositionReceived);
</script>
</body>
</html>