Leaflet: Abstand zwischen Kacheln in Bruchzoomstufen in Webkit-Browsern

Erstellt am 30. Juni 2015  ·  96Kommentare  ·  Quelle: Leaflet/Leaflet

screen shot 2015-06-30 at 14 39 12

Wie der Screenshot zeigt, befindet sich zwischen den Kacheln ein kleiner Abstand. Dies passiert mir bei Bruchzoomstufen in Safari, Chrome und Opera. Es scheint, dass dies in # 2377 behoben wurde, aber später in 3ccbe5b zugunsten einer besseren Leistung entfernt wurde.

Ich habe versucht, das Update erneut zu implementieren, um zu sehen, wie sich die Leistung selbst auswirkt, und es war ziemlich schlecht. Außerdem wurde das Problem für Chrome nicht behoben.

Hat jemand eine Idee, wie dies behoben werden kann? Bruchzoomstufen wären eine großartige Funktion für unsere App, aber solange dieser Fehler bestehen bleibt, können wir sie nicht wirklich verwenden.

Bearbeiten: Ich habe eine jsFiddle eingerichtet, die das Problem anzeigt: http://jsfiddle.net/Eschon/pw9jcjus/1/

bug in progress

Hilfreichster Kommentar

Besonders auf dunkleren Karten oder Bildern (in meinem Fall) ist das Problem ziemlich auffällig. Ich denke, dass Antialiasing im Browser die Leerzeichen zwischen Kacheln aufgrund der fraktionellen Transformation beim Zoomen verursacht, wie von Ivan erwähnt.

Bis eine bessere Lösung verfügbar ist, werde ich diese Problemumgehung (oder Hack) verwenden, um die Kacheln 1 Pixel größer zu machen, mit dem Nebeneffekt, dass sie sich um 1 Pixel überlappen. Außerdem werden die Kacheln leicht vergrößert und skaliert (um 1 Pixel).

/* 
 * Workaround for 1px lines appearing in some browsers due to fractional transforms
 * and resulting anti-aliasing.
 * https://github.com/Leaflet/Leaflet/issues/3575
 */
(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });
})()

Alle 96 Kommentare

Keine Ahnung. :( Obwohl ich das Problem nur in Safari gesehen habe, hat - Chrome / Opera gut funktioniert.

Hat jemand eine Idee, wie dies behoben werden kann?

Ich habe eine Idee, aber sie hängt mit den Worten "radikal" und "experimentell" zusammen:

https://github.com/IvanSanchez/Leaflet.gl

Eines der Dinge, die ich entdeckt habe, ist, dass Texturen geklemmt werden müssen. dh wenn diese Zeile entfernt wird: https://github.com/IvanSanchez/Leaflet.gl/blob/master/src/core/GlUtil.js#L74 Splitter ("Leerzeichen zwischen Kacheln") werden angezeigt (während die Textur um das Feld gewickelt wird) Dreieck und ein halbes Pixel der anderen Seite der Kachel sind gezeigt). Meine Vermutung ist also, dass Webkit ein halbes Pixel am Rand jedes Bildes antialiasiert.

Ab sofort bilden die Kachelschichtdreiecke ein vollständiges Netz, das ohne Splitter gerendert wird ... aber die Worte "experimentell" werden vorerst überall vorkommen.

@mourner Es hat einen stärkeren Effekt in Safari, ist aber auch in Chrome sichtbar.
screen shot 2015-06-30 at 15 42 07

@IvanSanchez Wow,

@Eschon Ja, das habe ich wahrscheinlich nicht bemerkt, weil es auf dem Retina-Bildschirm noch weniger sichtbar ist.

Dies scheint jetzt in einigen Fällen auch Firefox zu betreffen.
Ich konnte es nicht in jsFiddle reproduzieren, aber wenn Sie sich diese Seite ansehen
Ich bekomme die gleichen Leerzeichen in Firefox 39 und 41.0a2

Bearbeiten: Dies scheint ein Problem mit Iframes zu sein. Wenn ich die Karte direkt öffne,

Ich bezweifle, dass dies für 1.0 ohne viel Hacking möglich sein wird. Auf den Grund des Rückstands gehen.

Das gleiche Problem tritt auch bei der neuesten Version von Chrome auf. Ich wünsche mir, dass Sie eine mögliche Lösung finden, da OpenStreet-Karten mit diesen Linien nicht gut angezeigt werden. Vielen Dank.

Besonders auf dunkleren Karten oder Bildern (in meinem Fall) ist das Problem ziemlich auffällig. Ich denke, dass Antialiasing im Browser die Leerzeichen zwischen Kacheln aufgrund der fraktionellen Transformation beim Zoomen verursacht, wie von Ivan erwähnt.

Bis eine bessere Lösung verfügbar ist, werde ich diese Problemumgehung (oder Hack) verwenden, um die Kacheln 1 Pixel größer zu machen, mit dem Nebeneffekt, dass sie sich um 1 Pixel überlappen. Außerdem werden die Kacheln leicht vergrößert und skaliert (um 1 Pixel).

/* 
 * Workaround for 1px lines appearing in some browsers due to fractional transforms
 * and resulting anti-aliasing.
 * https://github.com/Leaflet/Leaflet/issues/3575
 */
(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });
})()

@cmulders Danke für die
Da wir hauptsächlich Karten von Skigebieten haben, die meistens weiß und blau sind. Wir haben die Leerzeichen vorerst ignoriert. Mit Ihrer Problemumgehung sieht es viel besser aus.

Aus dunklen Kacheln hergestellt, sind die Linien sogar auf dem Retina-Bildschirm sichtbar:
http://jsbin.com/ratoli/5/edit?html , js, Ausgabe

Safari / Chrome Buggy, FF OK für mich.

Wir sollten hierfür einen blattlosen Chrome-Fehlerbericht erstellen, damit dieser in zukünftigen Chrome-Versionen behoben wird.

@hyperknot Ich denke, es gibt bereits einen Chrome-Fehlerbericht, aber ich kann ihn

Ich verwende leafletjs 1.0 Beta und sehe diesen Fehler manchmal auch auf (aktuell: Chrome, Safari, Firefox) auf Osx El Capitan. Wenn ich die transform css-Eigenschaft eines Bildes um 1 Pixel bearbeite, wird die bearbeitete Kachel an der Kachel daneben ausgerichtet.

// ex.
 transform: translate3d(1556px, -81px, 0px);
 // to
 transform: translate3d(1555px, -80px, 0px);

Manchmal tritt dieser Fehler jedoch nicht auf (dieser 1px Unterschied) !! Ich weiß nicht warum :( aber ich vermute derzeit, dass es mit dem Styling des Kartencontainers zu tun hat.

Bearbeiten: Angenommen, die Kacheln werden beim Rendern korrekt ausgerichtet und zeigen keinen Unterschied von 1 Pixel. Beim Verschieben der Karte wird eine Lücke angezeigt. Das Verhalten ist wie ein Blitz eines 1px-Rahmens um die Kachel.

Ich habe eine CSS-Problemumgehung gefunden, die das Problem für mich in Safari 9.1 unter OS X El Capitan beseitigt:

.leaflet-tile-container img {
    box-shadow: 0 0 1px rgba(0, 0, 0, 0.05);
}

Ich kann jedoch nicht viel Kredit aufnehmen, ich habe es der folgenden Stackoverflow-Antwort entnommen, die auch Hinweise darauf gibt, warum dies hilft: http://stackoverflow.com/a/17822836/138103

Die Verwendung von Box-Shadow löst das Problem direkter: Es erweitert die Repaint-Abmessungen der Box und zwingt WebKit, die zusätzlichen Pixel neu zu malen. Die bekannten Auswirkungen von Box-Shadow auf die Leistung in mobilen Browsern hängen direkt mit dem verwendeten Unschärferadius zusammen, sodass ein Ein-Pixel-Schatten kaum oder gar keine Auswirkungen haben sollte.

Vielleicht kann dies als richtige Lösung verwendet werden, obwohl es wahrscheinlich gut wäre, wenn andere dies zuerst versuchen würden. Es funktioniert jedoch für mich und scheint in anderen Browsern keine Probleme zu verursachen.

@href Vielleicht könntest du mit diesem Fix eine Pull-Anfrage stellen? Das würde das Testen einfacher machen.

@href @IvanSanchez Sind Sie sicher, dass dies die Renderleistung nicht beeinträchtigt? Ich denke, wir sollten uns vorstellen, wie sich das Hinzufügen eines Kastenschattens mit einer Alpha-Deckkraft auf mobile Geräte auswirkt. Dies kann sich beispielsweise sichtbar auf die Leistung auswirken oder möglicherweise sogar die Hardwarebeschleunigung deaktivieren.

@ IvanSanchez fertig.

Sind Sie sicher, dass dies die Renderleistung nicht beeinträchtigt? Ich denke, wir sollten uns vorstellen, wie sich das Hinzufügen eines Box-Shadows mit einer Alpha-Deckkraft auf mobile Geräte auswirkt. Dies kann sich beispielsweise sichtbar auf die Leistung auswirken oder möglicherweise sogar die Hardwarebeschleunigung für das Schwenken deaktivieren.

Ich bin mir überhaupt nicht sicher, wie sich das auswirkt. Aus der Stackoverflow-Antwort geht hervor, dass dies keine Auswirkung zu haben scheint, aber dass man nur der Meinung eines anderen zu einem tangential verwandten Thema vertraut. Es wäre sicherlich eine großartige Idee, wenn jemand, der sich besser auskennt, sich damit befassen und meine Problemumgehung profilieren könnte.

Ich hatte gerade Glück, als ich herum googelte und wollte, dass andere es wissen.

@hyperknot @href Ich werde in ein paar Wochen gerne einige Benchmarks mit meinen Testbrowsern durchführen.

@IvanSanchez @href Es kann auch sinnvoll sein, diesen Hack nur auf betroffene Browser zu beschränken und nicht nur global anzuwenden.

@IvanSanchez Gibt es einen empfohlenen Workflow für die Profilerstellung der Leistung beim Rendern von Broschüren?

Es kann auch sinnvoll sein, diesen Hack nur auf betroffene Browser zu beschränken und nicht nur global anzuwenden.

Ich persönlich sehe es nur in Safari, daher wäre es sinnvoll, es für Safari einzuschränken. Es gab jedoch Erwähnungen von Leuten, die dies in Chrome sahen. Hat jemand diesen Fehler noch in anderen Webkit-Browsern gesehen?

Es ist ziemlich trivial, der Karte nur für ausgewählte Browser eine CSS-Klasse hinzuzufügen, und zwar im Konstruktor-Material L.Map .

@href Das Problem ist in meinem Chromium 49 vorhanden

@hyperknot Ich weiß nicht,

@href Außerdem Update die Kacheln in meinem Chromium 49 .leaflet-container { background: black } :

fractional-space

Mit img.leaflet-tile.leaflet-tile-loaded { box-shadow: 0 0 1px rgba(0, 0, 0, 0.05); } :

fractional-space1

: cry_cat_face:

Das ist komisch. Das Problem ist für mich in Chrom 49 (OS X El Capitan) nicht vorhanden, und der Kastenschatten scheint auch keinen Einfluss darauf zu haben.

Erstellt einen aktuellen Spielplatz: http://playground-leaflet.rhcloud.com/yid/1/edit?html , Ausgabe

Ich werde Fehler ohne Flugblätter an Webkit- und Blink-Teams senden.

OK, erfolgreich ein minimales Beispiel ohne Broschüre erstellt, das das Problem reproduziert:
http://playground-leaflet.rhcloud.com/say/1/edit?html , Ausgabe

Einige Updates aus dem Chromium-Fehlerbericht von [email protected]

Hey, ich möchte euch nur ein kurzes Update geben. Ich arbeite aktiv an diesem Thema.

Das Problem war darauf zurückzuführen, dass wir Dinge im lokalen Bereich eines Elements rasterten. Wenn das Element eine fraktionierte Translation hat, wird die gerasterte Textur mit der fraktionierten Translation unter Verwendung einer linearen Neuabtastung auf den Bildschirm eingefügt, was zu einer Unschärfe führt.

Die Lösung besteht darin, Dinge in einem Raum zu rasteren, der pixelausgerichtet auf unseren physischen Bildschirm ausgerichtet ist. dh Anwenden der gebrochenen Übersetzung auf die Vektorgrafikbefehle anstelle der gerasterten Textur.

Das Update besteht aus zwei Teilen:

  1. Der erste Teil, der es unserem Rastersystem ermöglicht, mit jeder allgemeinen Matrix zu rasteren. Dieser Teil ist fast fertig. Ich habe eine WIP, aber es gibt immer noch einen Fehler, der zu einer Leistungsregression führt. Ich erwarte, es in ein paar Tagen fertig zu stellen.
    https://codereview.chromium.org/2075873002/
  2. Der zweite Teil ermöglicht es unserem Kachelmanagement, eine Reihe von Texturen zu verwalten, die mit verschiedenen Rasterübersetzungen geliefert werden. Ich habe mich ursprünglich für eine allgemeine Matrix entschieden, aber es stellt sich heraus, dass die Berechnung der Kachelabdeckung sehr schwierig wird. Ich werde stattdessen eine einfachere Version machen, die nur Übersetzung und Skalierung unterstützt. Ich schätze, dass dies eine weitere Woche Arbeit erfordern wird.

Ich werde versuchen, dies durch M53-Zweig zu landen, aber die Zeit ist knapp. Ziemlich sicher, dass dies durch M54 behoben werden kann.

https://bugs.chromium.org/p/chromium/issues/detail?id=600120

An den Bug Reporter:

Der von Ihnen hochgeladene Testfall hat in Chromium einen Randfall ausgelöst, bei dem das Pixel-Snapping auf andere Weise behandelt wurde. Wenn Sie den Kacheln Inhalte hinzufügen, werden im Hintergrund keine Nähte mehr angezeigt. Wir können das Kantengehäuse leicht reparieren, es können jedoch noch Nähte im Flieseninhalt vorhanden sein.

Dies ist ein schwieriges Problem, und die einzige bekannte perfekte Lösung ist die Verwendung von FSAA, was aufgrund der CPU- / Speicherkosten kein Browser tut. Jeder Anbieter entwickelt seine eigenen Heuristiken, damit einige Inhalte besser aussehen, auf Kosten einiger Inhalte jedoch falsch.

Zum Beispiel: http://jsbin.com/wayapiz/

Chrom zeichnet mit der richtigen Geometrie, aber die Kanten bluten wie ein feststeckendes Schwein.
Firefox zeichnet die erste Box als 49x49, die zweite als 49x50.
Edge zeichnet die erste Box als 50x50, die zweite als 50x49. Beides mit Aliasing.

Auch wenn Sie dem Container eine Drehung hinzufügen, bluten alle Implementierungen die Kanten aus.

Meine empfohlene Problemumgehung besteht darin, eine gewisse Überlappung zwischen den Kacheln hinzuzufügen. Sie wissen, genau wie ein Poster mit A4-Papieren. Die Idee ist, sicherzustellen, dass jede Kachel nach der gesamten Skalierung mindestens ein Pixel überzeichnet, sodass garantiert wird, dass jedes physische Pixel von mindestens einem undurchsichtigen Pixel bedeckt ist. Die Breite der Überlappung hängt von der kleinsten Skala ab, die Sie unterstützen möchten. Wenn Sie beispielsweise eine Größe von bis zu 1/4 unterstützen möchten, fügen Sie 4 Pixel Überlappung hinzu.

Nachfolgend finden Sie eine detaillierte Analyse für andere Entwickler, die dies angehen möchten.

Der vom Reporter hochgeladene Repro war kein sehr guter Repro, da er einen optimierten Codepfad in cc auslöst. Wenn wir eine vollständig einfarbige Ebene erkannt haben, zeichnen wir sie als SolidColorLayerImpl, für die das Konzept der Inhaltsskala nicht vorhanden ist. Hier ist ein vereinfachter Repro: http://jsbin.com/hodoxew/

Die Blackbox wird als SolidColorLayerImpl der Größe (100, 100) gezeichnet, wodurch ein einzelnes einfarbiges Quad der Größe (100, 100) generiert wird, das durch Zeichentransformation auf den Bildschirm projiziert wird, um (99,5, 99,5) zu werden. Bei Anti-Alias ​​werden die Spalte ganz rechts und die unterste Pixelreihe halbtransparent gezeichnet.

Wenn wir andererseits der Ebene etwas hinzufügen, um cc dazu zu bringen, die Ebene als nicht einfarbig zu betrachten, tritt das Problem nun in zwei Fällen auf:

  1. Die letzte Kachel ist einfarbig, zum Beispiel: http://jsbin.com/zexawa/

Die Inhaltsgröße wird aufgerundet. Obwohl die skalierte Ebenengröße nur (600, 300) * 0,995 = (597, 298,5) beträgt, wird sie als (597, 299) überzeichnet.

  1. Die Listenkachel ist nicht einfarbig, zum Beispiel: http://jsbin.com/mewaguf/

Die Inhaltsgröße wird aufgerundet. Wiederum deckt der tatsächlich skalierte Inhalt nur (600, 300) * 0,995 = (597, 298,5) ab, die erzeugten Quads decken (597,299) ab. Die letzte Pixelreihe soll aufgrund von Anti-Alias ​​halbtransparent sein, aber wir füllen sie tatsächlich mit der Hintergrundfarbe der Ebene, der Hintergrundfarbe des Elements, das die Ebene erstellt hat.

Es gibt keine Naht im Hintergrund, jedoch kann der Hintergrund an den Rändern ausbluten, wenn der Inhalt ihn bedecken soll. Zum Beispiel: http://jsbin.com/vigufo/

Ein weiterer Testfall mit nicht einfarbigen Kacheln:
http://playground-leaflet.rhcloud.com/giqo/edit?output

@hyperknot fantastisches Update, aber diese beiden Zitate scheinen sich zu widersprechen (in einem sagt eine Person, dass sie an einem Fix arbeitet, und im nächsten sagt, dass kein guter Fix möglich ist). Warten wir also auf eine Lösung oder akzeptieren wir einfach, dass dies für immer so sein wird?

@mourner Entschuldigung, ich habe nicht den vollständigen Kontext angegeben, und Sie haben natürlich Recht. Der ursprüngliche Fehlerbericht lautete also:
https://bugs.chromium.org/p/chromium/issues/detail?id=600120

An einem Punkt wurde es in ein anderes Thema verschmolzen:
https://bugs.chromium.org/p/chromium/issues/detail?id=521364

In dieser anderen Ausgabe erhielten wir die ursprüngliche lange Antwort mit einer Lösung. Ich fragte, ob er überprüfen könne, ob der Fall der Broschüre tatsächlich durch seine Arbeit behoben wurde, und er antwortete:

Es tut mir leid, dass das Problem mit den Broschüren tatsächlich ein anderes Problem ist. Ich werde die Ausgabe 600120 erneut öffnen und meine Analyse teilen.

Der Leaflet-Bug ist jetzt wieder geöffnet und wir haben die zweite Antwort im Leaflet-Bug erhalten. Übrigens ist das neueste Update im Moment:

Ich habe mir die mobile Google-Karte angesehen, um zu sehen, wie sie damit umgegangen ist. Es stellt sich heraus, dass sie auch von diesem Problem geplagt sind, aber sie haben einen UI-Trick gemacht, um es weniger offensichtlich zu machen.

Das erste ist, dass sie das Ansichtsfenster-Tag verwendet haben, um den Browser-Pinch-Zoom nicht zuzulassen, und den Pinch-Zoom in JS implementiert haben. Während des Pinch-Zooms sehen Sie immer noch Nähte zwischen den Kacheln (sehr subtil bei hochauflösenden Displays). Nach Abschluss der Zoomgeste rasten sie den Skalierungsfaktor auf den nächstgelegenen Kachelsatz ein. Grundsätzlich werden Kacheln immer in nativer Auflösung angezeigt, außer während der Zoomgeste.

Ehrlich gesagt haben wir noch keinen festen Plan. Ich werde am Montag mit anderen Malern diskutieren.

Übrigens scheint es, dass mobiles Google Maps (ich denke die Website eins) genau die gleiche Technik wie wir verwendet.

@mourner @IvanSanchez einige Kernfragen mit einer möglichen Lösung unter Verwendung von Willensänderung:
https://bugs.chromium.org/p/chromium/issues/detail?id=600120#c15

Ist die aktuelle Schichtung wichtig? Ich sehe, dass jede Kachel in eine eigene Ebene gezwungen wird (translate3d), und diese Ebenen werden unabhängig voneinander um einen Bruchteilswert skaliert.

Solange wir jede Kartenkachel unabhängig skalieren (entweder mithilfe von Ebenen oder über drawImageRect + Bruch-CTM), erhalten wir für Bruch-Skalierungswerte Kanten, die nicht pixelausgerichtet sind. Dies löst das Anti-Aliasing-Problem der alten zusammenfallenden Kante aus, bei dem diskretes AA Hintergrundblutungen verursacht.

Ich denke, dies könnte stattdessen funktionieren, indem die Karte mit einem nicht gebrochenen Maßstab (z. B. 1.0) gerastert und dann atomar verkleinert wird:

1) Vermeiden Sie die individuelle Kachelschichtung (verwenden Sie "transform: translate ()" anstelle von "transform: translate3d ()").
2) Container-Layerisierung (gesamte Karte) erzwingen (verwenden Sie "transform: scale3d ()" für den Container)
3) Erzwingen Sie die Rasterung der Containerschicht mit einer Skala von == 1,0

Mit diesen Änderungen sollten Kartenkachelbilder mit einem Maßstab von 1,0 gerastert werden (=> Kanten sind pixelausgerichtet => keine Nahtartefakte), dann sollte die gesamte Kartenebene atomar verkleinert werden.

Leider ist # 3 nicht trivial und der einzige Hack, an den ich denken kann, ist

  • Beginnen Sie mit Skala (1) und ändern Sie den Willen: transformieren (Details siehe https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/Ufwrhx_iZ7U)
  • Setzen Sie die Ebenenskala nach dem ersten Rasterdurchlauf auf den gewünschten Wert zurück

zB http://jsbin.com/yaqeru/10/embed?output

chrishtr / danakj habe ich die Semantik der Ebenenrasterskala richtig eingestellt, und gibt es eine bessere Möglichkeit, die Ebenenrasterskala auf einen bestimmten Wert festzulegen?

Können Sie helfen, es zu beantworten?

Ich weiß, dass ein Fix im Gange ist (danke an alle, die daran gearbeitet haben!), Aber in der Zwischenzeit ... @cmulders '

https://gist.github.com/ericsoco/5712076f69f9068b11d41262b9e93666

import leaflet from 'leaflet';
// ...
patchMapTileGapBug();
// ...
function patchMapTileGapBug () {

    // Workaround for 1px lines appearing in some browsers due to fractional transforms
    // and resulting anti-aliasing. adapted from <strong i="9">@cmulders</strong>' solution:
    // https://github.com/Leaflet/Leaflet/issues/3575#issuecomment-150544739
    let originalInitTile = leaflet.GridLayer.prototype._initTile;
    if (originalInitTile.isPatched) return;

    leaflet.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });

    leaflet.GridLayer.prototype._initTile.isPatched = true;

}

Ich bin froh, dass die Leute sich darum kümmern. Falls dies für jemanden als weniger als ideale Problemumgehung nützlich ist: Wenn Sie bereit sind, die Trägheit zu opfern, werden durch das Festlegen von intertia:false auf dem Map-Init die Lücken und möglicherweise zoomAnimation:false beseitigt

Ich glaube, ich habe eine (überkomplizierte) Lösung dafür gefunden. Ich habe sie unter https://github.com/Leaflet/Leaflet.TileLayer.NoGap veröffentlicht. Kommentare sind willkommen, da ich mir der Leistung nicht sicher bin davon auf alten Computern / Telefonen.

cc @Eschon @hyperknot

Übrigens tritt der Fehler auch bei der Verwendung von Chrome auf einem Bildschirm mit hohen DPI-Werten (2560 x 1140) auf, ohne dass ein fraktionierter Zoom für Flugblätter oder ein Browser-Zoom erforderlich ist.

Entschuldigung für die späte Antwort.

Ich habe gerade Ihre Lösung getestet. Die Demo hat für mich gut funktioniert, also habe ich versucht, das Update zu meiner Anwendung hinzuzufügen. Da ich noch eine alte 1.0-dev-Version von Leaflet verwendete, habe ich sie von http://leafletjs.com/download.html auf 1.0.0-rc3 aktualisiert

Das erste , was mir aufgefallen ist , dass es scheint ein Fehler zu sein hier . Es wird ein Fehler angezeigt, der undefiniert zugeordnet ist, sodass ich ihn in this._map geändert habe.

Danach hat es funktioniert, aber auf meinem Arbeitscomputer ist es sehr langsam. Besonders in Chrome war Firefox aber auch langsam.

Überraschenderweise hatte es keinen so großen Einfluss auf die von mir getesteten Telefone.
Firefox auf Android scheint das gleiche zu sein wie zuvor, Chrome ist etwas langsamer, aber nicht schlecht.
Safari unter iOS scheint auch ungefähr so ​​zu sein wie zuvor.

Eine andere seltsame Sache, die mir aufgefallen ist, ist, dass auf Mobilgeräten wie Chrome und Safari das Pinch-Zoom auf ein festes Niveau zu rasten scheint

@Eschon Danke fürs Testen!

Ich mache immer den Fehler, map anstelle von this._map :-( einzugeben

Danach hat es funktioniert, aber auf meinem Arbeitscomputer ist es sehr langsam. Besonders in Chrome war Firefox aber auch langsam.

Könnten Sie einen Profiler auf diesem Computer ausführen? Es wäre schön zu wissen, ob die Verlangsamung mit Canvas-Operationen zusammenhängt. Mir ist aufgefallen, dass dies ein kleiner Leistungseinbruch bei IE9-IE11 war.

Abhängig davon, ob diese Lösung die Karte auf einigen Plattformen langsamer macht, kann es sinnvoll sein, sie vollständig optional und standardmäßig deaktiviert zu machen. Einige Rückmeldungen hier sind wichtig!

Ich habe mir nicht wirklich angesehen, wie die OL3-Leute dieses Problem lösen oder ob sie eine Leistungserkennung im Browser durchführen, bevor sie das Canvas-Compositing aktivieren. Könnte einen Blick wert sein.

Eine andere seltsame Sache, die mir aufgefallen ist, ist, dass auf Mobilgeräten wie Chrome und Safari das Pinch-Zoom auf ein festes Niveau zu rasten scheint

Ich wette, das spielt nur mit den Optionen zoomDelta und zoomSnap und hat nichts mit diesem Fehler zu tun.

Könnten Sie einen Profiler auf diesem Computer ausführen? Es wäre schön zu wissen, ob die Verlangsamung mit Canvas-Operationen zusammenhängt. Mir ist aufgefallen, dass dies ein kleiner Leistungseinbruch bei IE9-IE11 war.

Sollte ich nur ein JavaScript-CPU-Profil mit den Chrome-Entwicklungstools aufnehmen? Ich habe nicht viel Erfahrung mit diesen Leistungstests, daher weiß ich nicht wirklich, was ich mit den angezeigten Daten anfangen soll.

Ja, das ist die Sache. Suchen Sie dann auf der Flammenkarte nach breiten Dingen.

Ich habe gerade ein Profil mit dem Fix erstellt und ein anderes ohne. Ich habe versucht, für beide Profile ungefähr das Gleiche zu tun.

Das erste, was mir auffiel, war, dass die Version mit dem Fix einen zusätzlichen "Peak" hatte (ich weiß nicht, ob dies das richtige Wort ist), der durch _onZoomTransitionEnd

In der Version ohne das Update hat _onZoomTransitionEnd 1,8 ms gedauert und ich habe es nicht einmal in der Tabelle gesehen. In der Version mit dem Fix dauerte es 6 ms und verursachte einen "Peak" in der Aktivität.

Die anderen beiden "Peaks" sehen in den beiden Profilen ziemlich ähnlich aus. Die Dinge scheinen nur ein wenig anders zu laufen, aber der Abstand zwischen ihnen ist in der Version mit dem Fix größer.

Ich hoffe das hilft dir irgendwie. Ich habe die beiden Profile auch gespeichert, damit ich sie bei Bedarf irgendwo hochladen kann.

Als schmutzige Problemumgehung füge ich der ursprünglichen Funktion vorerst nur einen Skalierungsfaktor von 0,002 hinzu, mit dem die Eigenschaft translate3d für jede Kachel festgelegt wird, wodurch die Lücken fast vollständig beseitigt werden. ".002" war der niedrigste Skalierungsfaktor in meinen Testfällen, damit die Lücken vollständig verschwinden. Ich habe keine Nebenwirkungen bemerkt.

Getestet in den neuesten Versionen von Chrome, Firefox und IE 11. Getestet auf einem 40 "4k-Monitor mit einer auf 150% eingestellten Windows-Skalierung und verschiedenen Zoomwerten in den Browsern.

Fortschritte bei diesem Fehler? @AlexanderUhl Verursacht Ihre Lösung beim Platzieren Änderungen an Bildern oder ist dies nur beim Verschieben / Zoomen betroffen?

Es scheint, dass eine will-change CSS-Eigenschaft hinzugefügt wurde, um dieses Problem zu beheben. Sie müssen lediglich die hier beschriebenen FF-Leistungswarnungen überprüfen: https://github.com/Leaflet/Leaflet/issues/4686

@themre : Die Eigenschaft scale gilt beim Hinzufügen für alle Bildkacheln und ist dauerhaft. Der Stil attr sieht folgendermaßen aus:
style="width: 256px; height: 256px; transform: translate3d(545px, 745px, 0px) scale(1.002); opacity: 1;"

Dies würde jedoch dazu führen, dass das Bild etwas gedehnt wird, was ein unerwünschter Effekt ist. Ich habe die Version 1.0.3 ausprobiert, die die CSS-Eigenschaft will-change aber immer noch eine weiße Lücke verursacht. Ich werde versuchen, noch mehr zu suchen.

Natürlich dehnt es das Bild aus, das ist der Ansatz ;-) Ich stimme zu, dass diese Problemumgehung nicht ideal ist, aber das ist normalerweise die Natur einer Problemumgehung, nicht wahr? Trotzdem funktioniert dieser Ansatz am besten für mich mit vernachlässigbaren Nebenwirkungen (für meinen Anwendungsfall, bei dem es sich um eine Mapping-Anwendung mit Kacheln aus Mapbox, hier, Osm usw. handelt).

Nun, wenn wir normales translate , ist das Problem weg. Ich weiß nicht genau, ob die CSS-Eigenschaft translate3d so viel schneller als die normale Übersetzung ist. Vielleicht ist es am besten, dieses Flag als Option hinzuzufügen. Ich denke, ich werde translate3d durch translate ersetzen.

Ansicht in Aktion:
translatemap

image
Gleiches Problem mit der neuesten Version (1.0.3).

es wird möglicherweise in 1.1 behoben

Am 8. März 2017, Mi um 10:13 Uhr, schrieb Gaurav [email protected] :

[Bild: Bild]
https://cloud.githubusercontent.com/assets/13112509/23697357/7dcc4cf6-040d-11e7-881a-df3a44254015.png
Gleiches Problem mit der neuesten Version (1.0.3).

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/Leaflet/Leaflet/issues/3575#issuecomment-284987808 ,
oder schalten Sie den Thread stumm
https://github.com/notifications/unsubscribe-auth/AAeKj_23QbtFCaXeFjGRJcU-jg0284xBks5rjnEvgaJpZM4FO8Jh
.

Wenn die Werte von nx und ny, die zum Übersetzen des Divs .leaflet-pane.leaflet-map-pane verwendet werden, auf eine ganze Zahl gerundet werden, wird das Linien- / Lückenproblem in Safari behoben. Ich kann keine schädlichen Nebenwirkungen sehen (für meinen Gebrauch immer).

Finde das:
translate3d("+n.x+"px,"+n.y+"px,0)")
und ersetzen durch:
translate3d("+Math.round(n.x)+"px,"+Math.round(n.y)+"px,0)")

@LudwigBogner schlägt wahrscheinlich trotzdem fehl, wenn Sie etwas skalieren (z. B. Einstellen des Browser-Zooms oder während der Zoom-Animation). In diesem oben verlinkten Beispiel werden die Übersetzungen an sich gerundet: http://playground-leaflet.rhcloud.com/vicu/edit?html , Ausgabe

Ich bin gerade von diesem gebissen worden. Für mich scheint es auf Chromium oder FireFox nicht zu existieren. Nur einige der fraktionierten Zooms auf Safari.

Fortschritt?

Dieses Problem besteht weiterhin in Chrome und Firefox (Mac). Ich verwende ein zoomDelta und zoomSnap von 0,25.

Seltsamerweise behebt das Setzen von .leaflet-tile { will-change: auto !important; } (oder "nicht gesetzt") das Problem in Firefox (nur). Ich suche immer noch nach einer Problemumgehung für Chrome.

Die anderen vorgeschlagenen Korrekturen zum Deaktivieren der Trägheit und zum Ändern des translate3d-Codes zum Hinzufügen von Rundungen funktionierten ebenfalls nicht.

@jawinn Ich denke, Sie könnten Erfolg haben, wenn Sie L_DISABLE_3D auf true . IIRC hat ungefähr den gleichen Effekt wie das Ändern von will-change , dh es entfernt die Hardwarebeschleunigung beim Rendern des Karte. Beachten Sie, dass Sie wahrscheinlich eine viel schlechtere Leistung für Zoomanimationen, Schwenken usw. erzielen.

All dies ist sehr empfindlich gegenüber Details der Browser-Implementierung. Nehmen Sie dies also mit einem Körnchen Salz. Es ist eine ganze Weile her, seit ich mich damit befasst habe.

@ Jawinn
Die Arbeit, die ich verwende, ist die von @cmulders oben:

/* 
 * Workaround for 1px lines appearing in some browsers due to fractional transforms
 * and resulting anti-aliasing.
 * https://github.com/Leaflet/Leaflet/issues/3575
 */
(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });
})()

Es ist nicht perfekt, aber soweit ich das beurteilen kann, hat es keinen Einfluss auf die Leistung

Danke Leute. @Eschon Das hat funktioniert. In Chrome oder Firefox werden keine Lücken mehr angezeigt.

Wenn Sie den "1px-Fix" verwenden möchten, sollten Sie darauf vorbereitet sein, dass Ihre Bilder verschwommen und etwas kaputt werden:

Für mich, der Stunden damit verbracht hat, das Originalbild zu rendern und mit Photoshops zu versehen, war dies nicht akzeptabel. Also musste ich L_DISABLE_3D = true und am Ende mit flackernden Animationen und nervösen Zooms fertig werden.

Weitere Informationen: Ich verwende das Leaflet-Rastercoords- Plugin und meine Karteneinstellungen sind folgende:

    map = L.map('map', {
        center: [3250, 1700],
        zoom: 5,
        minZoom: 2,
        maxZoom: 6,
        maxBoundsViscosity: 1,
    });

F: Was ist die nächstbeste Alternative zu Leaflet, bei der es keinen solchen Fehler "Abstand zwischen Kacheln" gibt?

Ich werde es selbst googeln, aber vielleicht hat schon jemand diesen Weg eingeschlagen.

@ n3tman hast du auch das NoGap Plugin

@perliedman, danke, dass du diesen erwähnt hast.
Leider konnte es nicht lokal funktionieren. Ich habe einen Cannot read property 'appendChild' of undefined Fehler in der _initContainer Funktion.
Versucht mit früheren Versionen von Leaflet (bis zu 1.0.2) - gleiches Ergebnis. Die Demo zeigt den gleichen Fehler in Chrome / Firefox.
Vielleicht fehlt mir etwas Offensichtliches. Können Sie mir bitte helfen?

Gleiche 1px Lücke hier.

Chrome Version 66.0.3359.139 (64-Bit)
Windows 10 (1709)
Faltblatt 1.3.1

Als ich dieses Problem zum ersten Mal öffnete, stellte ich fest, dass es mit Bruchzoomstufen zusammenhängt, aber dies ist möglicherweise nicht mehr die einzige Ursache.

Ich habe kürzlich ein Projekt gestartet, das das GoogleMutant-Plugin verwendet, und dort habe ich festgestellt, dass dies auch passiert, wenn ich die stelle und nur ein wenig schwenke.

Es scheint mit # 6069 verwandt zu sein und (irgendwie) durch # 6240 behoben zu sein, obwohl die Lücken beim Zoomen und Schwenken immer noch angezeigt werden.

Ich habe die Problemumgehung auch aus meinen anderen Projekten entfernt und es scheint auch dort zu passieren, sodass es nicht spezifisch für das GoogleMutant-Plugin ist

Inspiriert von der 1px-Problemumgehung von @cmulders ... Es funktioniert, aber der verschwommene Effekt, der angezeigt wird, ist bei einigen Bildern nicht gut. Ich habe stattdessen das Folgende versucht (ich habe allerdings nicht viel getestet ...) und es scheint die Lücken zu schließen und trotzdem scharfe Bilder mit nicht gebrochenen Zoomstufen zu behalten. Die zusätzlichen 0,5 Pixel scheinen ausreichend zu sein, um die Lücken zu schließen (Chrome und Firefox unter Linux und Chrome unter Android mit Leaflet 1.3.4 ausprobiert)

(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();
            var map = this._map;
            var isFix = function() {
                return !(parseFloat(tile.style.width) % 0 === 0);
            };
            var fixOn = function() {
                if(!isFix()) return;
                tile.style.width = tileSize.x + 0.5 + 'px';
                tile.style.height = tileSize.y + 0.5 + 'px';
            };
            var fixOff = function() {
                if(isFix()) return;
                tile.style.width = tileSize.x + 'px';
                tile.style.height = tileSize.y + 'px';
            };
            var checkFix = function(){
                var zoom = map.getZoom();
                if(zoom % 1 === 0) {
                    fixOff();
                }
                else {
                    fixOn();
                }                
            };
            map.on('zoomstart',fixOn);
            map.on('zoomend',checkFix);
            checkFix();
        }
    });
})()

screen shot 2018-09-28 at 3 56 33 pm
Mehr als 3 Jahre später wurde dieser Fehler in Chrome immer noch nicht behoben! Ich sehe den Effekt in Firefox oder Safari nicht. Vielen Dank an @cmulders für Ihre Arbeit!

Gleiches hier (Windows 7 Enterprise SP1). Linien hier und da in Firefox, komplettes Linienraster in Chrome, aber OK in IE11. @cmulders Fix funktioniert in Firefox und Chrome.

Hier sind die vollständigen Ergebnisse einiger weiterer Tests:

  • Windows 7 Enterprise SP1

    • IE11: OK

    • Chrome, Firefox: nicht OK

  • Windows 10

    • IE11, Edge, Firefox: OK

    • Chrome: nicht OK

  • Mac OS

    • Safari, Chrome, Firefox: OK

  • Linux:

    • Chrome, Firefox: OK

  • Android:

    • Chrome, Firefox: OK

    • App mit WebView: OK

Weitere Tests haben gezeigt, dass dies offensichtlich ein Problem auf sehr niedrigem Niveau ist, das nichts mit Leaflet zu tun hat.
Das Testen unter Windows 7 Enterprise SP1 wurde ursprünglich auf zwei verschiedenen PCs durchgeführt, beide jedoch mit NVIDIA-Grafik.

Als der gleiche Test unter Windows 7 Enterprise SP1 mit AMD Radeon-Grafiken durchgeführt wurde, ging es in Ordnung, keine Linien zwischen Kacheln in Chrome oder Firefox!

Wie NoGap bereits erwähnt wurde, wollte ich Sie nur wissen lassen, dass ich den Originalcode genommen und geändert habe, damit er mit den aktuellen Faltblattversionen (dh Faltblatt ^ 1.3.3) funktioniert:
https://github.com/Endebert/squadmc/blob/master/src/assets/Leaflet_extensions/NoGapTileLayer.js

Es kann dann wie ein normaler TileLayer verwendet werden: https://github.com/Endebert/squadmc/blob/master/src/assets/SquadMap.js#L34

Es verwendet es6-Funktionen, daher müssen Sie möglicherweise einige Änderungen vornehmen, damit es für Sie funktioniert.

Wie NoGap bereits erwähnt wurde, wollte ich Sie nur wissen lassen, dass ich den Originalcode genommen und geändert habe, damit er mit den aktuellen Faltblattversionen (dh Faltblatt ^ 1.3.3) funktioniert:
https://github.com/Endebert/squadmc/blob/master/src/assets/Leaflet_extensions/NoGapTileLayer.js

Es kann dann wie ein normaler TileLayer verwendet werden: https://github.com/Endebert/squadmc/blob/master/src/assets/SquadMap.js#L34

Es verwendet es6-Funktionen, daher müssen Sie möglicherweise einige Änderungen vornehmen, damit es für Sie funktioniert.

@Endebert Hast du es geschafft, NoGap zum Laufen zu bringen? Ich habe vor einiger Zeit den gleichen Fehler wie @ n3tman erhalten :
Cannot read property 'appendChild' of undefined Fehler in der Funktion _initContainer .

Die einzige Änderung, die ich in Ihrer Version gefunden habe, ist das Hinzufügen von try ... catch zum Aufruf level.ctx.drawImage(imageSource, offset.x, offset.y, tileSize.x, tileSize.y);
und es hat nicht geholfen.

@ TomazicM Ja, meine Implementierung wird in meiner App SquadMC verwendet . Auf dem Desktop ist dies möglicherweise nicht so offensichtlich, aber auf Mobilgeräten ist der Bruchzoom ohne Einrasten aktiviert.

In Bezug auf die Implementierung: Die Originalversion verwendet TileLayer.include() , während ich TileLayer.extend() . Ich glaube, das ist der wichtige Unterschied. Wie bereits erwähnt, handelt es sich um eine neue Klasse, die anstelle von TileLayer verwendet werden soll.

Nun, hier ist mein Ergebnis einer 2-stündigen Untersuchung. Das Problem wird durch Pixel-Dezimalstellen in translate3d .

<div class="leaflet-pane leaflet-map-pane" style="transform: translate3d(-10.7773px, -8.41406px, 0px);"></div>

Aus diesem Grund funktioniert es gut mit L_DISABLE_3D = true , da laut diesem Teil des Quellcodes nicht translate3d .

Lösung

Erlaube nur keine Dezimalpixel. Dies kann zum Beispiel erreicht werden durch:

```js
var pos = (offset && offset.round()) || new Point(0, 0);
```

  • oder durch viele und viele andere Lösungen ...

Nun, hier ist mein Ergebnis einer 2-stündigen Untersuchung. Das Problem wird durch Pixel-Dezimalstellen in translate3d .

Ich denke, dass heute 2019 ist und die Verwendung von translate3d , um die Verwendung moderner Browser-GPUs zu erzwingen, ziemlich veraltet ist. Gute Arbeit @mdorda

@ Mdorda Hallo! Klingt interessant, aber beachten Sie, dass die Rundung bereits in diesem Thread behandelt wurde: https://github.com/Leaflet/Leaflet/issues/3575#issuecomment -327237235

Ich bin mir nicht sicher, ob sich seitdem etwas Wichtiges geändert hat, was einen Unterschied macht, aber ich würde meine Hoffnungen nicht wecken, bis wir einige gründliche Tests durchgeführt haben.

Ein erster Schritt, um dies zu beheben, wäre die Einreichung einer PR, damit wir dies testen können.

Für diejenigen, die mit Angular 2+ arbeiten, habe ich es so gelöst. Es funktioniert für meinen einfachen Anwendungsfall, weiß nichts über andere Implikationen ...

const tileLayer = new TileLayer(this.tileLayerUrlTemplate, this.tileLayerOptions);
tileLayer.on('load', () => {
    for (const tile of Array.from(document.getElementsByClassName('leaflet-tile'))) {
        (<HTMLElement>tile).style.height = (tile.clientHeight + 1) + 'px';
        (<HTMLElement>tile).style.width = (tile.clientWidth + 1) + 'px';
    }
});
this.map.addLayer(tileLayer);

Ich sehe diese Pixellücke beim Bruchzoom in LeafletJS Version 1.5.1 unter Windows 10 Pro 1903 mit Mozilla Firefox 69.0.1 (64-Bit).
Pixellücke
Ich denke, dass der Grund für die Pixellücke möglicherweise nicht in der CSS-Funktion translate3d () liegt, sondern in scale ().
image
In Version 1.5.1 sind die Parameter translate3d (), wie ich sehe, nur ganzzahlig.


Mit freundlichen Grüßen IMMSPgisgroup

Haben Sie eine Lösung für diesen Fehler gefunden?

Ich habe in diesem Moment das gleiche Problem und habe keine Lösung gefunden.

error

Ich benutze:

  • Windows 10 Home 1803
  • Google Chrome Versión 77.0.3865.90 (Build oficial) (64 Bit)
  • Faltblatt 1.5.1

Wenn ich Firefox verwende, werden die weißen Linien nicht angezeigt

no_error

@ Arenivar93

Na, ich habe das jetzt seit ein paar Jahren im Auge. Sie haben eine Reihe von Problemumgehungen versucht, aber nichts hat funktioniert, um dies ohne größere Kompromisse zu korrigieren. Die Wurzel des Problems liegt in Chrom: https://bugs.chromium.org/p/chromium/issues/detail?id=600120

Die neueste Nachricht des Chromteams ist, dass es zu schwierig ist, andere Dinge nicht zu beschädigen, sodass wir möglicherweise eine Weile daran festhalten.

Besonders auf dunkleren Karten oder Bildern (in meinem Fall) ist das Problem ziemlich auffällig. Ich denke, dass Antialiasing im Browser die Leerzeichen zwischen Kacheln aufgrund der fraktionellen Transformation beim Zoomen verursacht, wie von Ivan erwähnt.

Bis eine bessere Lösung verfügbar ist, werde ich diese Problemumgehung (oder Hack) verwenden, um die Kacheln 1 Pixel größer zu machen, mit dem Nebeneffekt, dass sie sich um 1 Pixel überlappen. Außerdem werden die Kacheln leicht vergrößert und skaliert (um 1 Pixel).

/* 
 * Workaround for 1px lines appearing in some browsers due to fractional transforms
 * and resulting anti-aliasing.
 * https://github.com/Leaflet/Leaflet/issues/3575
 */
(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });
})()

Wir hatten viel Glück mit dieser Lösung. Es ist nicht perfekt, aber unserer Meinung nach besser als die Zeilen.

Darüber hinaus haben wir sichergestellt, dass die Hintergrundfarbe der Karte besser mit der Farbe der Grundkarte übereinstimmt. Wenn der Ozean beispielsweise dunkelblau wäre, würden wir dies verwenden, damit die Kacheln diese Farbe überlagern und einige der wahrnehmbaren Inkonsistenzen minimieren.

wieder nicht perfekt, aber es hilft

@colbyfayock Darf ich fragen, wo und wie Sie Ihre Lösung implementieren?

Ich erstelle eine Reaktions-App, damit sie sich unterscheidet, aber ich habe eine Datei mit folgenden Inhalten erstellt:

// Fix via https://github.com/Leaflet/Leaflet/issues/3575#issuecomment-150544739
import L from 'leaflet';

(function () {
  if (!L || !L.GridLayer || !L.GridLayer.prototype) return;

  var originalInitTile = L.GridLayer.prototype._initTile;

  L.GridLayer.include({
    _initTile: function (tile) {
      originalInitTile.call(this, tile);

      var tileSize = this.getTileSize();

      tile.style.width = tileSize.x + 1 + 'px';
      tile.style.height = tileSize.y + 1 + 'px';
    }
  });
})();

Die Renditen oben sind, weil es vorkompiliert und nicht immer verfügbar ist (hier nicht wichtig).

dann importiere ich es einfach, nachdem ich die Broschüre importiert habe

import L from 'leaflet';
...
import '../plugins/leaflet-tilelayer-subpixel-fix';

Meine Problemumgehung besteht darin, den Transformationswert zu runden, ohne den Quellcode zu ändern.
Die Verwendung mit "Reagieren" kann jedoch von jedem Front-End verwendet werden, da es sich um JQuery handelt
Nicht zu sagen, dass es die beste Option ist, macht es einfach.
Dies behebt das Problem und ich habe keine merklichen Unschärfen oder Defekte festgestellt. Einen Versuch wert.

    this.leftMap.on('move', () => {
      const mapDiv = window.document.getElementsByClassName("leaflet-pane leaflet-map-pane")
      let styleString = mapDiv.getAttribute("style");
      const transformValue = styleString.substring(styleString.indexOf("(")+1,styleString.indexOf("px,"));
      const roundedTransformValue = Math.round(parseFloat(transformValue));
      styleString = styleString.replace(transformValue,roundedTransformValue);
      mapDiv.setAttribute("style",styleString);
    });

@colbyfayock - Es scheint es nicht für mich zu beheben. :(

Ich verwende eine Reaktionsbroschüre mit Zoom-Snap 0.

image

Die Lösung war nie perfekt für uns, aber wir haben definitiv keine einheitlichen Linien wie diese in unserer. Ich war mir nicht sicher über die zoomSnap -Funktion und musste sie nachschlagen. Ich bin mir nicht sicher, wie 0 mit dieser Eigenschaft funktionieren würde, wenn ich die Beschreibung lese. Haben Sie versucht, das zu entfernen, um zu sehen, ob die Zeilen ohne sie noch vorhanden sind?

https://leafletjs.com/examples/zoom-levels/#fractional -zoom

Bearbeiten: las weiter nach dem Beispiel gif

zoomSnap kann auf Null gesetzt werden. Dies bedeutet, dass die Broschüre die Zoomstufe nicht erfasst.

Ich vermute, Sie geraten in gebrochene Zustände, die die Lösung nicht über den vollständigen Ganzzahl-Standard-Snap hinaus verarbeiten kann - aber nicht sicher

Faltblatt 1.7-dev und das Problem besteht weiterhin. Linien an den Rändern von Kacheln in Firefox und Chrome in Windows 7 und Windows 10. Kein Problem in IE11 und altem (nicht Crome) Edge, dasselbe Problem in neuem, Chrome-basiertem Edge.

Es gibt zwei funktionierende Lösungen, aber ich mag keine davon. Eine Möglichkeit besteht darin, 3d um <script>L_DISABLE_3D = true;</script> zu deaktivieren. Dies bedeutet jedoch, dass animierte Vorgänge verloren gehen. Eine andere Möglichkeit besteht darin, Kachel-HTML-Elemente um 1 Pixel zu erweitern. Dies bedeutet jedoch, dass Sie leicht unscharfe Kacheln erhalten.

Ich habe eine sehr primitive Lösung gefunden, aber von Natur aus funktioniert sie zu 100%. Vielleicht findet es jemand nützlich.

Die Lösung besteht darin, dieselbe beleidigende Kachelebene zweimal auf zwei verschiedenen Kartenfenstern anzuzeigen, die untereinander angeordnet sind und einen Versatz [-1, -1] aufweisen.

Code sieht ungefähr so ​​aus:

<style>
  .originOffset {
    transform: translate(-1px, -1px);
  }
</style>

<script>
  var pane1 = map.createPane('pane1');
  var pane2 = map.createPane('pane2');

  pane1.style.zIndex = 210;
  pane2.style.zIndex = 220;

  L.DomUtil.addClass(pane1, 'originOffset');

  var layer1 = L.tileLayer( ... , {
    pane: 'pane1',
    ...
  });
  var layer2 = L.tileLayer( ... , {
    pane: 'pane2,
    ...
  });
  var layer = L.layerGroup([layer1, layer2]);
</script>

Von @ cmulders Vorschlag habe ich diese Linie und keinen Platz mehr zwischen den Kacheln

map.on ('Zoomend Drag', Funktion () {
$ ('# map> div.leaflet-pane.leaflet-map-pane> div.leaflet-pane.leaflet-tile-pane> div> div> img'). each (function () {
if (String ($ (this) .css ("width")). include ('. 5') === false) {
var imgW = String ($ (this) .css ("width")). split ("px") .join (".5")
var imgH = String ($ (this) .css ("height")). split ("px") .join (".5")
$ (this) .css ("width", imgW);
$ (this) .css ("height", imgH);
}}
});

Ich bin bei @mdorda , wenn beim Schwenken und Zoomen ganze Zahlen in leaflet-map-pane 's Aufruf von translate3d() anstelle von Bruchteilen von Pixeln angezeigt werden, ist das Problem (mit eingeschalteten Blindern) verschwunden und alles ist wieder schön. Ich behaupte nicht, alle Nuancen zu verstehen, in denen Brüche aufbewahrt werden müssen, aber wenn es Leaflet eine gewisse Erleichterung für das Problem des Browsers bietet, wäre es akzeptabel, L.Draggable._onMove in einen Bodenbelag zu legen

    offset.x = Math.floor(offset.x / this._parentScale.x);
    offset.y = Math.floor(offset.y / this._parentScale.y);

oder sogar in L.DomUtils.setTransform

    pos.x = Math.floor(pos.x);
    pos.y = Math.floor(pos.y);

Damit keine Übersetzungen mit Brüchen versehen werden, wäre dies wahrscheinlich verschwenderisch, da Kachelbilder keine gebrochenen Übersetzungen ergeben (richtig?).

Ich habe zwei Stunden verschwendet, um festzustellen, dass meine Browsereinstellungen vergrößert wurden und nicht die tatsächliche Größe
Nehmen Sie einfach den Zoom zurück zum tatsächlichen und alles funktionierte wie Charme, das war mein Fall

Ich habe zwei Stunden verschwendet, um festzustellen, dass meine Browsereinstellungen vergrößert wurden und nicht die tatsächliche Größe
Nehmen Sie einfach den Zoom zurück zum tatsächlichen und alles funktionierte wie Charme, das war mein Fall

@tokenflow: Dieses Thema ist buchstäblich über ‚Raum zwischen den Fliesen auf fraktionierte Zoomstufen in Webkit - Browsern‘. Ich versuche wirklich, hier nicht übermütig zu sein, aber denken Sie wirklich, dass Ihre Informationen über das Zoomen auf 100% ein nützlicher Beitrag für irgendjemanden sind?

Ich habe diesen Fehler in der Linux-Version von Firefox und Chromium festgestellt.
Das Problem (zumindest für Firefox) scheint das scale() des Haupt .leaflet-tile-container , das ich mit document.querySelector('.leaflet-tile-container:last-of-type').getAttribute('style') .
Z.B. Sie haben scale(0.707107) , aber alle img-Kinder sind Breite / Höhe 256. Sie berechnen also: 0.707107 * 256px = 181.019392px , was eine Dezimalzahl ist. Wenn Sie dann die Pixel runden und diese als Skalierung verwenden, scheint dies in Firefox / Linux zu funktionieren: 181px / 256px = 0.70703125 .

Ich habe eine Funktion geschrieben, die beim Debuggen hilft:

function getCurrentScale (doFix = false) {
    const tileContainer = document.querySelector('.leaflet-tile-container:last-of-type');

    if (!tileContainer) {
        return;
    }

    const tileStyle = tileContainer.getAttribute('style');
    const scaleRegEx = /scale\(([0-9\.]+)\)/i;
    const matches = scaleRegEx.exec(tileStyle);

    if (!matches || matches.length !== 2) {
        return;
    }

    const scale = parseFloat(matches[1]);

    const mod = (scale * 256) % 1;

    if (mod) {
        console.log('scale is off by px:', mod);
        if (doFix) {
            const newScale = Math.round(scale * 256) / 256;
            console.log('old scale / new scale', scale, newScale);
            const newStyle = tileStyle.replace(scaleRegEx, `scale(${newScale})`);
            tileContainer.setAttribute('style', newStyle);
        }
    } else {
        console.log('scale seems to be fine:', scale);
    }
}

Wenn Sie es mit true als erstem Parameter aufrufen, wird versucht, die Skalierung zu korrigieren. Dies funktioniert jedoch nur unter Firefox für mich.

Ich habe eine Lösung gefunden, die dumm ist und eigentlich nicht funktionieren sollte.

.leaflet-tile-container img {
    width: 256.5px !important;
    height: 256.5px !important;
}

Dies sollte zu massiven Nähten um die Fliesen führen, aber ich kann sie überhaupt nicht sehen und es korrigiert den Raum zwischen den Fliesen.

@ ChrisLowe-Takor irgendwie scheint es wirklich zu funktionieren, obwohl ich auf den ersten Blick nicht wirklich sagen kann warum.
Dies ist möglicherweise der JavaScript-Problemumgehung vorzuziehen, die ich gerade verwende, aber ich muss mich noch etwas genauer damit befassen und einige Tests durchführen.

@ ChrisLowe-Takor - Wow, das funktioniert auch bei mir! Guter Fund 👍

@ ChrisLowe-Takor Scheint auch für mich in R mit dem Leaflet-Paket zu funktionieren. Vielen Dank!

@ ChrisLowe-Takor Irgendwie macht dieser Trick es wirklich für alle dummen modernen Browser (für den alten ehrwürdigen IE11 wird er nicht benötigt)! Es gibt nur eine Sache zu beachten: Wenn die Option detectRetina für die Kachelebene verwendet wird und die Anzeige eine Retina-Anzeige ist, beträgt die Kachelgröße 125 x 125 px.

Diese Lösung hat jedoch den gleichen Nachteil wie alle Lösungen, die auf der Erweiterung des Kachelcontainers basieren: Die Kachel wird etwas unscharf.

@ ChrisLowe-Takor Ich habe es versucht. Wenn maxZoom größer als maxNativeZoom ist, werden die Kacheln nicht richtig angezeigt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen