-Zeilen heraus. * * Warum nicht einfach am Bild abmessen: die Zeichenfläche ist 400 × 300 groß * und hat mit Metern nichts zu tun. Wer das im Kopf umrechnet, verrechnet * sich - und zwar in jeder Ecke anders. * * Das Luftbild kommt live vom WMS der Bayerischen Vermessungsverwaltung, es * liegt also keine Kopie im Repository. Der Ausschnitt lässt sich über die * Adresszeile verschieben, ohne diese Datei anzufassen: * * tools/lageplan.php?lat=47.5781&lon=10.2628&breite=120 * * "breite" ist die Kantenlänge des Ausschnitts in Metern; die Höhe ergibt * sich aus dem Seitenverhältnis 4:3 der Zeichenfläche. * * Aufruf: http:///smart/tools/lageplan.php * * Bewusst eine eigene Seite und kein Eintrag im Menü: sie wird einmal * gebraucht und danach nie wieder - genau wie kachelpositionen.php, mit der * sie sich die Bauart teilt. */ require_once(__DIR__ . "/../helper.php"); require_once(__DIR__ . "/../restricted/rooms.php"); if (!checkLogin()) { http_response_code(403); exit; } /** So groß ist die Zeichenfläche - siehe restricted/home.php. */ const PLAN_BREIT = 400; const PLAN_HOCH = 300; /** So groß ist eine Kachel, für die vorgeschlagene x/y-Zeile. */ const KACHEL_BREIT = 24; const KACHEL_HOCH = 19; /** Welche Etage hier vermessen wird. */ const ETAGE = "AG"; /** * Das Luftbild. CC BY 4.0 - die Namensnennung steht unten auf der Seite und * gehört dort hin, auch wenn die Seite nur intern erreichbar ist. */ const WMS_URL = "https://geoservices.bayern.de/od/wms/dop/v1/dop20"; const WMS_LAYER = "by_dop20c"; // Wie viele Bildpunkte je Einheit der Zeichenfläche geholt werden. Drei ist // scharf genug zum Abklicken und bleibt weit unter der Grenze des Dienstes. const WMS_SCHAERFE = 3; /** * Mittelpunkt des Ausschnitts. Dieselben Koordinaten stehen in * restricted/gartenbewaesserung/auto_watering.py, von wo die Regendaten * geholt werden - es ist derselbe Ort. */ $lat = isset($_GET["lat"]) ? floatval($_GET["lat"]) : 47.5781; $lon = isset($_GET["lon"]) ? floatval($_GET["lon"]) : 10.2628; $breite = isset($_GET["breite"]) ? floatval($_GET["breite"]) : 120.0; $breite = max(20.0, min(400.0, $breite)); $hoehe = $breite * PLAN_HOCH / PLAN_BREIT; /** * WGS84 nach UTM Zone 32 Nord (EPSG:25832). * * Der WMS kann auch mit Längen- und Breitengraden umgehen, aber dann ist ein * quadratischer Ausschnitt keiner mehr: ein Grad Länge ist auf dieser Breite * nur zwei Drittel so lang wie ein Grad Breite. In UTM ist ein Meter ein * Meter, und der Maßstab der Seite stimmt ohne Umrechnung. */ function nachUtm32($lonGrad, $latGrad) { $a = 6378137.0; $f = 1 / 298.257223563; $k0 = 0.9996; $e2 = $f * (2 - $f); $ep2 = $e2 / (1 - $e2); $lon0 = deg2rad(32 * 6 - 183); $lat = deg2rad($latGrad); $lon = deg2rad($lonGrad); $N = $a / sqrt(1 - $e2 * pow(sin($lat), 2)); $T = pow(tan($lat), 2); $C = $ep2 * pow(cos($lat), 2); $A = cos($lat) * ($lon - $lon0); $M = $a * ((1 - $e2 / 4 - 3 * $e2 ** 2 / 64 - 5 * $e2 ** 3 / 256) * $lat - (3 * $e2 / 8 + 3 * $e2 ** 2 / 32 + 45 * $e2 ** 3 / 1024) * sin(2 * $lat) + (15 * $e2 ** 2 / 256 + 45 * $e2 ** 3 / 1024) * sin(4 * $lat) - (35 * $e2 ** 3 / 3072) * sin(6 * $lat)); $x = $k0 * $N * ($A + (1 - $T + $C) * $A ** 3 / 6 + (5 - 18 * $T + $T ** 2 + 72 * $C - 58 * $ep2) * $A ** 5 / 120) + 500000.0; $y = $k0 * ($M + $N * tan($lat) * ($A ** 2 / 2 + (5 - $T + 9 * $C + 4 * $C ** 2) * $A ** 4 / 24 + (61 - 58 * $T + $T ** 2 + 600 * $C - 330 * $ep2) * $A ** 6 / 720)); return [$x, $y]; } list($mx, $my) = nachUtm32($lon, $lat); $bbox = sprintf("%.1f,%.1f,%.1f,%.1f", $mx - $breite / 2, $my - $hoehe / 2, $mx + $breite / 2, $my + $hoehe / 2); $luftbild = WMS_URL . "?" . http_build_query([ "SERVICE" => "WMS", "VERSION" => "1.3.0", "REQUEST" => "GetMap", "LAYERS" => WMS_LAYER, "STYLES" => "", "CRS" => "EPSG:25832", "BBOX" => $bbox, "WIDTH" => (int) (PLAN_BREIT * WMS_SCHAERFE), "HEIGHT" => (int) (PLAN_HOCH * WMS_SCHAERFE), "FORMAT" => "image/jpeg", ]); /** * Die Flächen, die abgeklickt werden. * * Sie kommen aus der Raumtabelle - ein neuer AG-Raum in rooms.php taucht hier * von selbst auf. Das Haus steht davor, obwohl es kein Raum ist: es ist der * Umriss, an dem sich beim Zeichnen alles andere ausrichtet. */ $flaechen = [["schluessel" => "haus", "name" => "Haus", "raum" => null]]; foreach (allRooms() as $raum) { if ($raum["floor"] !== ETAGE) { continue; } $flaechen[] = ["schluessel" => $raum["id"], "name" => $raum["mqtt"], "raum" => $raum]; } // Genug unterscheidbare Farben, danach wiederholen sie sich - bei sieben // Flächen kommt es dazu nicht. $farben = ["#ffbe3c", "#35b6cf", "#7ed957", "#ff7a7a", "#c58cff", "#ffe066", "#6ee7c8"]; foreach ($flaechen as $i => $f) { $flaechen[$i]["farbe"] = $farben[$i % count($farben)]; } ?> Lageplan Außengelände

Lageplan Außengelände

Die Zeichenfläche ist × und zeigt hier × m – eine Einheit sind m. Wähle eine Fläche und klick ihre Ecken der Reihe nach ab; Backspace nimmt den letzten Punkt zurück. Unten stehen die fertigen Zeilen für restricted/home.php und restricted/rooms.php. Passt der Ausschnitt nicht, verschieb ihn über ?lat=, ?lon= und ?breite= in der Adresszeile.

Fläche wählen und die erste Ecke anklicken …

Für restricted/home.php – der Plan

Für restricted/rooms.php – die Kacheln

Luftbild: Datenquelle Bayerische Vermessungsverwaltungwww.geodaten.bayern.de, DOP20 (20 cm), CC BY 4.0. Live vom WMS geholt, es liegt keine Kopie im Repository. Ausschnitt in EPSG:25832.