<!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: '&copy; <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: '&copy; 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>