Henrique Köhler: Kreise oder Bilder auf OSM Karte lassen sich nicht removen

Hallo zusammen,

ich bin ein deutsch-brasilianischer Erfinder und habe ein Orientierungssystem entwickelt das auf imaginären Uhren basiert, siehe Video www.volksnav.de/aSimpleCircle

Nach vielen Jahren melde ich - ewiger Zauberlehrling - mich wieder. Ich habe ein online tool entwickelt zur Festlegung und Speicherung von Leitzahlen für Kreuzungen, Haltestellen, Brücken etc., siehe www.volksnav.cm/onlineGen. Funktioniert wie gewünscht: beim Klicken auf der Karte erscheint die Blase mit dem was man so braucht wenn man weiss dass die Postleitzahlen weltweit obsolet geworden sind.

Aus diversen Gründen will ich an derselben Stelle zusätzlich einen Kreis oder ein Bild einblenden - das aber wie die Blase beim nächsten Klick verschwindet. Habe alles versucht, aber der Zusatz wird nicht gelöscht. Habe auch versucht das mit einem externen Knopf zu erreichen. Vergebens. Kann mir jemand helfen?

Der bis zum Problem reduzierten code sieht so aus:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Circle</title> 
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" /><style type="text/css"> #map { height: 60%; }</style> 
</head> 

<body> 
<div id="map" style="width: 600px; height: 400px"></div> <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script> 

<script> 
var map = L.map('map').setView([3.8614, 11.5205], 11);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: ' &copy; <a href="http://osm.org/copyright">OpenStreetMap</a>contributors'}).addTo(map); 

map.on('click', onMapClick); 

function onMapClick(e) { 
    var myCircle = new L.circle([e.latlng.lat, e.latlng.lng], 3000, {color: 'red', fillOpacity: 0, weight:2}); 

   if(map.hasLayer(myCircle)){ 
      map.removeLayer(myCircle); 	// stört nicht, aber hilft nicht 
   }else{     
map.addLayer(myCircle); 	// funktioniert
   } 
  
} 
</script></body></html>
  1. Hallo,

    so genau habe ich dein Problem jetzt nicht verstanden. Aber im Blog https://blog.selfhtml.org/2019/jan/13/einstieg-in-leaflet habe ich mal etwas zu Leaflet geschrieben. Im letzten Beispiel http://test.berkemeier.eu/selfwiki/leaflet/Beispiel_JS-Leaflet5.html werden Popus da geöffnet, wo man klickt. Klickt man an eine andere Stelle, wird das alte Popup geschlossen und ein neues geöffnet. Klickt man das X, wird das Popup geschlossen. Suchst du so etwas?

    Gruß
    Jürgen

    1. Hallo Jürgen, danke für die spontane Hilfe.

      Was Du popup nennst, nenne ich Blase (mein System soll kinderlogisch sein :-) ). Popups funktionieren schon.

      Wie könnte man desselbe (auch mit X) bewirken wenn zum popup eine Zielscheibe als Bild oder layer benötigt wird?

      1. Servus!

        Hallo Jürgen, danke für die spontane Hilfe.

        Was Du popup nennst, nenne ich Blase (mein System soll kinderlogisch sein :-) ). Popups funktionieren schon.

        Kinderleicht und logisch ist es, wenn man etablierte Begriffe verwendet und keine eigenen erfindet, an die sich Nutzer erst gewöhnen müssen

        Wie könnte man desselbe (auch mit X) bewirken wenn zum popup eine Zielscheibe als Bild oder layer benötigt wird?

        Du hast ein div mit einer Zeichenkette als Inhalt:

        <div class="leaflet-popup-content" style="width: 231px;">9_167_79 ; ; 3.932 ; 11.388 ; m9:79 r167 ; ; </div>

        Dort könntest du mit DOM-Methoden weitere Elemente oder Grafiken einfügen oder removen.

        Herzliche Grüße

        Matthias Scharwies

        --
        Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
        1. Hallo Matthias,

          DOM scheint die Lösung zu sein! Die massgebliche Passage sieht heute so aus:

          popup
          .setLatLng(e.latlng)
          .setContent(...) //funktioniert bestens
          .openOn(map)

          Dieser code beinhaltet erstaunlicherweise bereits eine remove-Intelligenz! Wenn man sich dran hängen könnte, wäre das Problem gelöst.

          Bisher war es nicht nötig mich mit DOM zu befassen. Habe gestern viel gelesen, wenig verstanden (bin nicht mehr der Jüngste) und habe kein entsprechendes Beispiel gefunden.

          Kannst mir bitte einen Tipp geben, wie die Ergänzung in etwa ausschauen könnte? Dann schaffe ich es alleine weiter.

          Henrique

      2. Hallo,

        du verwendst beim Anlegen der Kreise die Methode addLayer, und beim Entfernen removeLayer. Ich hätte hier addTo(map) und remove() genommen.

        Gruß
        Jürgen

        1. Beide Varianten sind völlig identisch. Habe gestern ausprobiert, es ändert sich nichts.

          Übrigens: Deine neue Potleitzahl könnte so aussehen www.volksnav.de/Juergen.

          Die Alternativen wären www.volksnav.de/alternatives. Was wäre Dir lieber? Enigmatisch oder vorstellbar?

          1. Hallo Henrique,

            Deine neue Po(s)tleitzahl könnte so aussehen

            Das wäre eher ein Ersatz für die Wohnortadresse.

            • Postleitzahlen müssen bundesweit identifizieren
            • sind nicht für den Kunden da, sondern für den Zustell-Dienstleister
            • müssen dem Dienstleister helfen, das Zustellgut nach Zustellbereichen vorzusortieren

            Aber eine Wohnortadresse auf Koordinatenbasis - egal in welchem Koordinatensystem - ist für die Postzustellung ebenfalls nicht hilfreich.

            • Straßen folgen keinen Koordinatensystemen, sondern natürlichen Gegebenheiten
            • Ein Zusteller folgt den Straßen und muss deshalb die Post nach Straßen sortieren
            • Ein Besucher folgt ebenfalls den Straßen

            Das Gleiche gilt für Wegweisungen. Es hilft mir nichts, wenn Du mir sagt: Dingenskirchen liegt von deinem Standort aus 5km in Richtung m7, wenn ich dabei auf einen Fluss, eine Autobahn oder sonst ein Hindernis stoße. Wenn die Straße nach Dingenskirchen aufgrund natürlicher Gegebenheiten zunächst 3km in Richtung m1 führt, dann muss ich daher fahren. Und diese Information bekomme ich von einer Karte, und wenn ich zu blöd bin, sie zu lesen, hilft mir kein Koordinatensystem - egal welches.

            Insofern erscheint mir deine Erfindung eine Lösung auf der Suche nach einem Problem zu sein.

            Rolf

            --
            sumpsi - posui - obstruxi
  2. @@Henrique Köhler

    ich bin ein deutsch-brasilianischer Erfinder und habe ein Orientierungssystem entwickelt das auf imaginären Uhren basiert

    Oh, du hast Polarkoordinaten erfunden‽ Die Angabe der Richtung als Uhrzeit ist auch kaum auf deinem Mist gewachsen, das tun andere seit Urzeiten (No pun intended.)

    Was erfindest du als nächstes? Das Rad?

    🤡

    🖖 Живіть довго і процвітайте

    --
    When the power of love overcomes the love of power the world will know peace.
    — Jimi Hendrix
    1. Hi,

      Die Angabe der Richtung als Uhrzeit ist auch kaum auf deinem Mist gewachsen, das tun andere seit Urzeiten (No pun intended.)

      und immer mehr Uhren haben Digitalanzeigen - da ergibt sich aus der Zeit keine wirkliche Richtung …

      Was erfindest du als nächstes? Das Rad?

      vielleicht ja ein Koordinatensystem, bei dem jedem Ort eine Handvoll sinnlos zusammengewürfelter Worte zugeordnet wird?

      cu,
      Andreas a/k/a MudGuard

      1. Hallo,

        vielleicht ja ein Koordinatensystem, bei dem jedem Ort eine Handvoll sinnlos zusammengewürfelter Worte zugeordnet wird?

        Warum nur jedem Ort? Nimm doch z.b. jedes 5×5m großes Quadrat?!

        Gruß
        Kalk

        1. Hallo,

          vielleicht ja ein Koordinatensystem, bei dem jedem Ort eine Handvoll sinnlos zusammengewürfelter Worte zugeordnet wird?

          Warum nur jedem Ort? Nimm doch z.b. jedes 5×5m großes Quadrat?!

          oder 3x3m?

          Einen schönen Tag noch
           Martin

          --
          In Massachusetts gilt heute noch per Gesetz, dass man nicht zu Bett gehen darf, ohne vorher zu baden.
          Außerdem verbietet ein anderes Gesetz das Baden am Sonntag.
          Darf man also in der Nacht von Sonntag auf Montag nicht ins Bett?
          1. Hallo,

            oder 3x3m?

            Wie? Hat da jemand meine Idee geklaut und abgewandelt?

            Gruß
            Kalk

        2. Hallo Tabellenkalk,

          wie wär's mit ///metaphorically.crumpling.remnant - ein sehr treffener Name für eine pressierende Situation 😉

          Rolf

          --
          sumpsi - posui - obstruxi
        3. Hi,

          vielleicht ja ein Koordinatensystem, bei dem jedem Ort eine Handvoll sinnlos zusammengewürfelter Worte zugeordnet wird?

          Warum nur jedem Ort?

          Du verwechselst Ort und Ortschaft 😉

          cu,
          Andreas a/k/a MudGuard

      2. @@MudGuard

        Was erfindest du als nächstes? Das Rad?

        vielleicht ja ein Koordinatensystem, bei dem jedem Ort eine Handvoll sinnlos zusammengewürfelter Worte zugeordnet wird?

        Sowas wie Hintertupferdingen? Vordertupferdingen?

        Du meinst, man könne Orten auch sowas wie Namen geben? O. Ri. Gi. Nell.

        🖖 Живіть довго і процвітайте

        --
        When the power of love overcomes the love of power the world will know peace.
        — Jimi Hendrix
    2. Hi,

      Eure Meinungen sind alle richtig, berücksichtigen aber nicht die ganze Problematik:

      . dank KI, benötigt man weltweit keine PLZ mehr! Es gibt zahlreiche Alternativen www.volksnav.de/alternatives, Meine ist die einzige deutsche Alternative. Elfenbeinküste hat sich für Leitzahlen entschieden die aus 3 Namen (?!) bestehen, Cabo Verde für die enigmatischen PlusCodes von Google.

      . es gibt Länder, die noch keine PLZ haben. Zumindest dort habe ich meinen Platz, z. b. in Kamerun, worum es hier geht. Auf www.volksnav.de/Yaounde blende ich zusätzlich den PlusCode ein. Was würde Euch besser gefallen?

      . Hausnummerierung ist heute nur möglich wenn man sicher weiss wo die Strasse anfängt. Das ist oft schwierig zu entscheiden. In Mexico City habe ich eine belebte, 6 km lange, Strasse entdeckt die noch keine Nummerierung hat.

      . In Kamerun definiere ich Leitzahlen für points-of-decision POD. Die moderne Hausnummer ist ganz simpel der Abstand zu einer Vorzugskreuzung. Der property owner kann die Hausnummer selbst vergeben.

      . spricht was dagegen wenn die U-Bahnen in Asien, arabischen Ländern etc. auch Stationsleitzahlen anzeigen www.volksnav.de/TokyoMetro ?

      . Es geht auch um die Verbesserung der Kartographie. Was ist besser: eine Karte mit oder ohne Referenzgitter, siehe Video www.volksnav.de/aSimpleCircle

      . Es geht auch um die Verbesserung der Beschilderung: Piktogramme für Norden, Stadtmitte, Mekka etc. auch indoor.

      . Es geht auch um Raumnummerierung, Reduzierung von Panikgefahr, Reduzierung von Geisterfahrten, Vermeidung von Schilderwald etc. etc.

      Kann mir jemand bei meinem Problem helfen? Mit DOM den popup ergänzen. Danke im Voraus

      1. Servus!

        Kann mir jemand bei meinem Problem helfen? Mit DOM den popup ergänzen.

        Herzliche Grüße

        Matthias Scharwies

        --
        Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
        1. Danke Matthias.

          Ich war unterwegs, nun befasse ich mich wieder mit dieser Problematik und mit den DOM-Manipulationen als Lösung.

          Leider fand ich keine Beispiele die näher am Problem wären. Der folgende code (bitte nicht laut lachen) tut dasselbe wie vorher: erzeugt popup und Kreis beim Klicken, löscht aber nur popup.

          Die Kopplung parent/child ist mir nicht gelungen, sie ist mir in der Kodierung zu abstrakt. Die Auskommentierungen zeigen dass ich mich bemüht habe.

          Bitte nochmals um Tipps, Danke im Voraus.

          Henrique

          <!DOCTYPE html>
          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Munich Orientation Convention</title>
          <meta charset="utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
          <style type="text/css">
          #map { height: 60%; }
          </style>
          </head>
          <body> 
          <div id="map" style="width: 1000px; height: 600px"></div>
          <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
          <script src="FileSaver.js"></script>
          <script>
          var poleLat = 3.8614;
          poleLon = 11.5205; 
          var map = L.map('map').setView([poleLat, poleLon], 11);
          L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', 
                      {attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}
                     ).addTo(map);
          
          document.addEventListener('DOMContentLoaded', function () {
            var popup = L.popup();
            map.on('click', onMapClick);
          
          	function onMapClick(e) {
          	
              var myCircle = new L.circle([e.latlng.lat, e.latlng.lng], 3000, {color: 'red', fillOpacity: 0, weight:2});
              popup.setLatLng(e.latlng).setContent("here").openOn(map);
          //   var parent = popup.parentNode; 
          
              document.appendChild(myCircle);
          
              myCircle.addTo(map); 	// .addTo(popup) wäre zu einfach
          
              document.addEventListener('click', removeElement);	
            }   //onMap click 
          });  // DOMcontentLoaded
          	
          	  
            function removeElement(e) {
              
              var myCircle = e.target;              //var elem = e.target;
              var body = document.querySelector('body');
           
              if (body != myCircle) {
                var parent = popup.parentNode;     //var parent = elem.parentNode;
                parent.removeChild(myCircle);         //parent.removeChild(elem);
                return false;
              }  
            } 
          </script>
          </body>
          </html>
          
          1. Hallo Henrique,

            von Leaflet habe ich keine Ahnung, nur von JavaScript im Allgemeinen.

            Ich habe zunächst einmal den von Dir geposteten Code formatiert. Sowas hilft extrem bei der Lesbarkeit, auch für einen selbst. Es kann natürlich sein, dass deine Formatierung beim Kopieren ins Forum kaputt gegangen ist, aber eigentlich sah es danach nicht aus.

            Sodann kommt ein ~~~html davor und ein ~~~ dahinter, damit das Forum es als Code formatiert. Das habe ich letztes Mal kommentarlos für Dich gemacht - ich hätte schon da darauf hinweisen sollen. Sorry.

            Zum Code selbst:

            Einen DOMContentLoaded Handler braucht man nicht, wenn das Script am Ende der Seite steht. Der ist nur nötig, wenn Du es im <head> einbindest und Du auf DOM Elemente zugreifen willst (wie das >div id="map">, die dann noch nicht da sind. Steht das Script am Ende, sind sie schon da.

            Wenn man sich darauf verlässt, dass der Internet Explorer tot ist, kann man die Script-Ausführung am Ende des Body auch mit dem defer Attribut des Script-Elements erzwingen. defer-Scripte laufen unmittelbar vor dem DOMContentLoaded Event.

            Für den body braucht man querySelector nicht, der ist über document.body auch direkt zugänglich

            Für genauere Aussagen müsste ich den Code online sehen. Ich habe an einigen Stellen den Verdacht, dass Du nicht auf die richtigen Elemente zugreifst, aber da ich Leaflet nicht kenne, müsste man dafür ein bisschen debuggen.

            Zum Beispiel:

            • Ich würde annehmen, dass L.popup() ein neues Popup erzeugt. Dieses Popup wird bei Dir, wie es aussieht, für jeden Klick auf die Karte recycled. Ich bin nicht sicher, ob das eine gute Idee ist. Vermutlich sollte man für jeden Klick ein neues Popup erzeugen und das alte verwerfen
            • Das Popup wird nicht geschlossen. Ich sehe den "openOn(map)" dafür, aber wenn removeElement läuft, sehe ich nur das Entfernen von myCircle. Das Popup bleibt. Ist das deine Absicht?
            • Es ist falsch, den click-Handler für den remove auf dem Dokument zu registrieren. Diese click-Handler sammeln sich an, du erzeugst bei jedem click einen neuen. Wenn Du das Popup wiederverwenden willst, registriere den remove-Handler auf dem Popup, und nur einmal. Nicht im onMapClick. Wenn Du für jeden onMapClick ein neues Popup erzeugen willst, dann registriere den click-Handler für's remove in onMapClick, aber auf dem Popup. Im removeElement verwende dann event.currentTarget, um das HTML Element für das Popup zu erhalten.

            Ob das so passt, weiß ich nicht, weil ich nicht weiß, was L.popup liefert. Ist das ein Leaflet-internes Objekt, oder das DOM Element, das Leaflet für das Popup verwenden will?

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Habe online gestellt: www.volksnav.de/selfHTML.

              Beim Wiederclicken verschwindet popup, Kreise nicht.

              Wie gesagt, ich bin nur ein Zauberlehrling.

              1. Hallo,

                die Testseite wirft einen Javascript-Fehler.

                Gruß
                Jürgen

                1. Hallo JürgenB,

                  vor allem führt die Registrierung eines click-Handlers im onMapClick dazu, dass dieser Handler schon beim öffnen des Popup ausgeführt wird.

                  Das liegt daran, dass das click-Event aus der Map weiter nach oben bubbled und dann beim Dokument landet. Und dort ist der frische Click-Handler fromm, fröhlich und frei am Start und will das Popup gleich wieder schließen. Was schiefgeht, weil er aus die popup-Variable nicht zugreifen kann.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
          2. Hallo,

            das ist aber ein wüster Mix aus DOM und Leaflet-Methoden. Warum machst du das? Leaflet bietet dir Methoden für das Erzeugen und Entfernen von Kartenelementen.

            Gruß
            Jürgen

            1. Am Anfang des threads versuche ich geklickte Kreise mit leaftet zu removen, aber es funktioniert nicht.

              Der popup-Befehl beinhaltet seltsamerweise den remove Befehl für vorherige popups. Das scheint irgendwie zu stören, daher der Versuch mit DOM.

              Mir wäre eine simple Lösung lieber wie

              myCircle.addTo(popup) statt .addTo(map)

              , aber auch das ging nicht.

              1. Hallo

                ich habe das Beispiel 5 aus dem Blog-Artikel mal um einen Kreis erweitert:

                http://test.berkemeier.eu/selfwiki/leaflet/Beispiel_JS-Leaflet5b.html

                			var popup = L.popup();
                			var circle = new L.circle([],{radius: 1000, color: "red"});
                
                			map.on("click", function(e) {
                				popup
                					.setLatLng(e.latlng)
                					.setContent('<p>'+e.latlng.lat+','+e.latlng.lng+'</p>')
                					.openOn(map);
                				
                				circle
                					.setLatLng(e.latlng)
                					.addTo(map);
                			});
                
                			map.on("popupclose", function() {
                				circle.remove();
                			});
                

                Zum Entfernen des Kreises nehme ich die Methode remove im popupclose-Event.

                Gruß
                Jürgen

                1. Danke, Jürgen,

                  es funktioniert tatsächlich ohne DOM!!

                  Auf www.volksnav.cm/onlineGen wird nun AUCH der Kreis gelöscht.

                  Bitte einzoomen, der Kreis hat einen Durchmesser von nur 30 Meter ( 1 Breitensekunde), so kann der property owner seine Hausnummer besser abschätzen.

                  Alles andere funktioniert auch. Allerdings habe ich wieder ein Haufen callBack code übernommen den ich vorher nicht benötigte. Werde gelegentlich versuchen das zu verkürzen.

                  Das Proble wäre gelöst, Danke an alle!

                  Henrique