Leaflet: Espace entre les vignettes sur les niveaux de zoom fractionnés dans les navigateurs Webkit

Créé le 30 juin 2015  ·  96Commentaires  ·  Source: Leaflet/Leaflet

screen shot 2015-06-30 at 14 39 12

Comme le montre la capture d'écran, il y a un petit espace entre les tuiles. Cela m'arrive avec des niveaux de zoom fractionnés dans Safari, Chrome et Opera. Il semble que cela ait été corrigé dans # 2377 mais supprimé plus tard dans 3ccbe5b en faveur de meilleures performances.

J'ai essayé de réimplémenter le correctif pour voir moi-même l'impact sur les performances et c'était plutôt mauvais et cela n'a même pas résolu le problème pour Chrome.

Quelqu'un a-t-il une idée de la façon dont cela peut être résolu? Les niveaux de zoom fractionnés seraient une excellente fonctionnalité pour notre application, mais tant que ce bogue persiste, nous ne pouvons pas vraiment les utiliser.

Edit: j'ai mis en place un jsFiddle qui montre le problème: http://jsfiddle.net/Eschon/pw9jcjus/1/

bug in progress

Commentaire le plus utile

Surtout sur des cartes ou des images plus sombres (dans mon cas), le problème est assez perceptible. Je pense que l'anticrénelage dans le navigateur provoque les espaces entre les tuiles en raison de la transformation _fractionnelle_ pendant le zoom, comme mentionné par Ivan.

Jusqu'à ce qu'une meilleure solution soit disponible, j'utiliserai cette solution de contournement (ou hack) pour agrandir les tuiles d'un pixel, avec pour effet secondaire qu'elles se chevauchent de 1 px. De plus, les tuiles seront légèrement agrandies et mises à l'échelle (de 1px).

/* 
 * 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';
        }
    });
})()

Tous les 96 commentaires

Aucune idée. : (Bien que je n'ai vu le problème que dans Safari, - Chrome / Opera a bien fonctionné.

Quelqu'un a-t-il une idée de la façon dont cela peut être résolu?

J'ai une idée, mais elle est liée aux mots «radical» et «expérimental»:

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

Une des choses que j'ai découvert est que les textures doivent être serrées. c'est-à-dire si cette ligne est supprimée: https://github.com/IvanSanchez/Leaflet.gl/blob/master/src/core/GlUtil.js#L74 des éclats ("espaces entre les tuiles") apparaissent (lorsque la texture s'enroule autour du triangle et un demi-pixel de l'autre côté de la tuile est montré). Donc, ma supposition éclairée est que Webkit antialiasing un demi-pixel sur le bord de chaque image.

À partir de maintenant, les triangles de tuiles forment un maillage complet qui est rendu sans éclats ... mais les mots "expérimental" seront partout pour le moment.

@mourner Il a un effet plus fort dans Safari mais il est également visible dans Chrome.
screen shot 2015-06-30 at 15 42 07

@IvanSanchez Wow beau travail, mais je ne pense pas que je puisse (encore) l'utiliser.

@Eschon ouais, je n'ai probablement pas remarqué cela car sur l'écran Retina, c'est encore moins visible.

Cela semble affecter Firefox maintenant aussi dans certains cas.
Je n'ai pas pu le reproduire dans jsFiddle mais si vous regardez ce site
J'obtiens les mêmes espaces dans Firefox 39 et 41.0a2

Edit: Cela semble être un problème avec les iframes. Si j'ouvre directement la carte, elle ne se reproduit pas.

Je doute que cela soit possible pour la 1.0 sans beaucoup de piratage. Pousser au bas de l'arriéré.

Nous rencontrons également le même problème sur la dernière version de Chrome. Je souhaite que vous trouviez une solution possible car les cartes OpenStreet ne s'affichent pas bien avec ces lignes. Merci.

Surtout sur des cartes ou des images plus sombres (dans mon cas), le problème est assez perceptible. Je pense que l'anticrénelage dans le navigateur provoque les espaces entre les tuiles en raison de la transformation _fractionnelle_ pendant le zoom, comme mentionné par Ivan.

Jusqu'à ce qu'une meilleure solution soit disponible, j'utiliserai cette solution de contournement (ou hack) pour agrandir les tuiles d'un pixel, avec pour effet secondaire qu'elles se chevauchent de 1 px. De plus, les tuiles seront légèrement agrandies et mises à l'échelle (de 1px).

/* 
 * 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 Merci pour la solution de contournement!
Puisque nous avons principalement des cartes des stations de ski qui sont pour la plupart blanches et bleues. Nous avons ignoré les espaces pour le moment, avec votre solution de contournement, cela semble beaucoup mieux.

Fait un jsbin avec des carreaux sombres cartodb, les lignes sont visibles même sur l'écran de la rétine:
http://jsbin.com/ratoli/5/edit?html , js, sortie

Buggy Safari / Chrome, FF OK pour moi.

Nous devrions faire un rapport de bogue Chrome sans dépliant pour cela, donc il est corrigé dans les futures versions de Chrome.

@hyperknot Je pense qu'il y a déjà un rapport de bogue Chrome, mais je ne le trouve pas pour le moment.

J'utilise leafletjs 1.0 beta et je vois aussi parfois ce bug sur (dernier: chrome, safari, firefox) sur osx El Capitan. lorsque j'édite la propriété transform css d'une image de 1px, la vignette modifiée s'aligne avec la vignette à côté.

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

Parfois, ce bug n'apparaît pas (que 1px de différence) !! Je ne sais pas pourquoi: (mais je suppose actuellement que cela a à voir avec le style du conteneur de carte.

Modifier: dites que les tuiles s'alignent correctement lors du rendu et n'affiche aucune différence de 1px, un espace sera visible sur l'événement de déplacement de la carte. Le comportement est comme un flash d'une bordure 1px autour de la tuile.

J'ai trouvé une solution de contournement css qui élimine le problème pour moi sur Safari 9.1 sur OS X El Capitan:

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

Cependant, je ne peux pas m'attribuer beaucoup de crédit, je l'ai tiré de la réponse Stackoverflow suivante qui fait également allusion à _pourquoi_ cela aide: http://stackoverflow.com/a/17822836/138103

L'utilisation de box-shadow résout le problème plus directement: elle étend les dimensions de repeinture de la boîte, forçant WebKit à repeindre les pixels supplémentaires. Les implications connues des performances de la boîte-ombre dans les navigateurs mobiles sont directement liées au rayon de flou utilisé, de sorte qu'une ombre d'un pixel devrait avoir peu ou pas d'effet.

Peut-être que cela peut être utilisé comme une solution appropriée, bien que ce serait probablement bien si d'autres essayaient cela en premier. Cela fonctionne pour moi cependant et ne semble pas entraîner de problèmes dans les autres navigateurs.

@href Vous pourriez peut-être faire une pull request avec ce correctif? Cela faciliterait le test.

@href @IvanSanchez Êtes-vous sûr que cela n'affectera pas les performances de rendu? Je pense que nous devrions expliquer comment l'ajout d'une boîte-ombre avec une opacité alpha affecte les appareils mobiles, par exemple, cela pourrait avoir un effet visible sur les performances, voire désactiver l'accélération matérielle.

@IvanSanchez terminé.

Êtes-vous sûr que cela n'affectera pas les performances de rendu? Je pense que nous devrions profiler comment l'ajout d'une boîte-ombre avec une opacité alpha affecte les appareils mobiles, par exemple, cela pourrait avoir un effet visible sur les performances, ou même éventuellement désactiver l'accélération matérielle pour le panoramique.

Je ne sais pas du tout quel en est l’effet. D'après la réponse de Stackoverflow, cela ne semble pas avoir d'effet, mais il s'agit simplement de faire confiance à l'opinion de quelqu'un d'autre sur un problème lié de manière tangentielle. Ce serait sûrement une excellente idée si quelqu'un de plus compétent pouvait l'examiner et décrire ma solution de contournement.

J'ai juste eu de la chance quand j'ai cherché sur Google et que je voulais que les autres le sachent.

@hyperknot @href J'effectuerai volontiers quelques benchmarks dans quelques semaines avec mon ensemble de navigateurs de test.

@IvanSanchez @href En outre, il pourrait être bon de limiter ce piratage aux navigateurs concernés uniquement, et pas seulement de l'appliquer globalement.

@IvanSanchez existe-t-il un flux de travail recommandé pour le profilage des performances de rendu des dépliants?

En outre, il pourrait être bon de limiter ce piratage aux navigateurs concernés uniquement, et pas seulement de l'appliquer globalement.

Personnellement, je ne le vois que dans Safari, il serait donc logique de le limiter pour le safari. Cependant, certaines personnes ont vu cela dans Chrome. Quelqu'un voit-il encore ce bogue dans d'autres navigateurs Webkit?

Il est assez simple d'ajouter une classe CSS à la carte uniquement pour les navigateurs sélectionnés, dans les éléments du constructeur L.Map .

@href Le problème est présent dans mon Chromium 49

@hyperknot Je ne connais pas la meilleure façon de profiler ce genre de choses. Parlons-en ce week-end ;-)

@href De plus, ce correctif gâche un peu les carreaux de mon Chromium 49 ... il brouille l'image entière au lieu de juste le bord. Original, avec .leaflet-container { background: black } :

fractional-space

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

fractional-space1

: crying_cat_face:

C'est bizarre. Le problème n'est pas présent pour moi dans Chromium 49 (OS X El Capitan), et l'ombre de la boîte ne semble pas non plus avoir d'influence dans les deux cas.

Création d'un terrain de jeu à jour: http://playground-leaflet.rhcloud.com/yid/1/edit?html , sortie

Je soumettrai des bogues sans Leaflet aux équipes Webkit et Blink.

OK, a réussi à créer un exemple minimal sans dépliant reproduisant le problème:
http://playground-leaflet.rhcloud.com/say/1/edit?html , sortie

Quelques mises à jour du rapport de bogue Chromium, de

Hé, je veux juste vous donner une mise à jour rapide. Je travaille activement sur ce problème.

Le problème était dû au fait que nous tramions des choses dans l'espace local d'un élément. Si l'élément a une traduction fractionnée, la texture rastérisée serait collée sur l'écran avec la traduction fractionnaire en utilisant un rééchantillonnage linéaire, ce qui entraînerait le flou.

La solution consiste à tramer les choses dans un espace aligné en pixels sur notre écran physique. c'est-à-dire appliquer la traduction fractionnaire aux commandes graphiques vectorielles au lieu de la texture tramée.

Le correctif sera disponible en deux parties:

  1. La première partie qui permet à notre système raster de raster avec n'importe quelle matrice générale. Cette partie est presque terminée. J'ai un WIP mais il y a toujours un bug qui provoque une régression des performances. J'espère le terminer dans quelques jours.
    https://codereview.chromium.org/2075873002/
  2. La deuxième partie qui permet à notre gestion de tuilage de pouvoir gérer un ensemble de textures fourni avec différentes traductions raster. J'étais à l'origine pour une matrice générale, mais il s'avère que le calcul de la couverture de tuiles devient très difficile. Je vais plutôt faire une version plus simple qui ne prend en charge que la traduction et l'échelle. J'estime que cela nécessitera une autre semaine de travail.

Je vais essayer de décrocher cela par la branche M53 mais le temps presse. Je suis sûr que cela peut être résolu par M54.

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

Au rapporteur de bogues:

Le scénario de test que vous avez téléchargé a déclenché un cas de pointe dans Chromium pour lequel nous avons géré la capture de pixels d'une manière différente. Si vous ajoutez du contenu aux carreaux, vous ne verrez plus de coutures en arrière-plan. Nous pouvons facilement réparer le boîtier de bord, cependant, il peut encore y avoir des coutures dans le contenu des carreaux.

C'est un problème difficile, et la seule solution parfaite connue consiste à utiliser FSAA, ce qu'aucun navigateur ne fait en raison des coûts CPU / mémoire. Chaque éditeur développe sa propre heuristique pour rendre certains contenus plus beaux, au détriment de certains contenus qui semblent incorrects.

Par exemple: http://jsbin.com/wayapiz/

Chrome dessine avec la bonne géométrie, mais les bords saignent comme un cochon coincé.
Firefox dessine la première boîte en 49x49, la deuxième en 49x50.
Edge dessine la première boîte en 50x50, la seconde en 50x49. Les deux avec aliasing.

De plus, si vous ajoutez une rotation au conteneur, toutes les implémentations saignent les bords.

Ma solution de contournement recommandée consiste à ajouter un chevauchement entre les tuiles. Vous savez, tout comme faire une affiche avec du papier A4. L'idée est de s'assurer que chaque carreau surdessine au moins un pixel après toute la mise à l'échelle, de sorte que chaque pixel physique est garanti d'être couvert par au moins un pixel opaque. La largeur du chevauchement dépend de la plus petite échelle que vous souhaitez prendre en charge. Par exemple, si vous souhaitez prendre en charge jusqu'à 1/4 de la taille, ajoutez 4 pixels de chevauchement.

Vous trouverez ci-dessous une analyse détaillée pour les autres développeurs qui souhaitent s'attaquer à cela.

La repro téléchargée par le journaliste n'était pas une très bonne repro car elle déclenche un chemin de code optimisé en cc. Lorsque nous avons détecté un calque de couleur complètement unie, nous le dessinons comme SolidColorLayerImpl, qui n'a pas le concept d'échelle du contenu. Voici une repro simplifiée: http://jsbin.com/hodoxew/

La boîte noire sera dessinée comme un SolidColorLayerImpl de taille (100, 100), qui générera un seul quad de couleur unie de taille (100, 100), qui sera projeté à l'écran par une transformation de dessin pour devenir (99,5, 99,5). Avec l'anti-alias, la colonne la plus à droite et la rangée inférieure de pixels seront dessinées en semi-transparent.

D'un autre côté, si nous ajoutons quelque chose au calque pour faire croire à cc que le calque n'est pas de couleur unie, le problème se présente maintenant dans deux cas:

  1. La dernière tuile étant de couleur unie, par exemple: http://jsbin.com/zexawa/

La taille du contenu sera arrondie, donc bien que la taille du calque mis à l'échelle soit seulement (600, 300) * 0.995 = (597, 298.5), elle sera sur-dessinée comme (597, 299).

  1. La tuile de liste n'est pas de couleur unie, par exemple: http://jsbin.com/mewaguf/

La taille du contenu sera arrondie. Encore une fois, le contenu réel mis à l'échelle ne couvre que (600, 300) * 0,995 = (597, 298,5), les quads générés couvriront (597 299). La dernière rangée de pixels est censée être semi-transparente en raison de l'anti-alias, mais nous la remplissons en fait avec la couleur d'arrière-plan du calque, qui est la couleur d'arrière-plan de l'élément qui a créé le calque.

Il n'y aura pas de couture à l'arrière-plan, cependant, l'arrière-plan peut saigner sur les bords lorsque le contenu est censé le recouvrir. Par exemple: http://jsbin.com/vigufo/

Un autre cas de test, utilisant des carreaux de couleur non unie:
http://playground-leaflet.rhcloud.com/giqo/edit?output

@hyperknot mise à jour fantastique, mais ces deux citations semblent se contredire (dans une, une personne dit qu'elle travaille sur un correctif, et la suivante dit qu'aucune bonne solution n'est possible). Alors attendons-nous une solution ou acceptons-nous simplement que ce sera ainsi pour toujours?

@mourner désolé, je n'ai pas inclus le contexte complet, et vous avez raison bien sûr. Le rapport de bogue original était donc:
https://bugs.chromium.org/p/chromium/issues/detail?id=600120

À un moment donné, il a été fusionné dans un autre problème:
https://bugs.chromium.org/p/chromium/issues/detail?id=521364

Dans cet autre problème, nous avons obtenu la longue réponse originale avec une solution. J'ai demandé s'il pouvait vérifier si le cas du dépliant était bien fixé par son travail et il a répondu:

Je suis désolé que le problème des brochures soit en fait un problème différent. Je rouvrirai le numéro 600120 et partagerai mon analyse.

Donc, le bug de la brochure est maintenant rouvert et nous avons obtenu la deuxième réponse dans le bug de la brochure. BTW, la dernière mise à jour en ce moment est:

J'ai jeté un coup d'œil à la carte Google mobile pour voir comment ils l'ont gérée. Il s'avère qu'ils sont également en proie à ce problème, mais ils ont fait une astuce d'interface utilisateur pour le rendre moins évident.

La première chose est qu'ils ont utilisé la balise viewport pour interdire le zoom par pincement du navigateur et implémenté le zoom par pincement dans JS. Pendant le zoom par pincement, vous pouvez toujours voir des joints entre les carreaux (très subtils sur les écrans haute résolution). Une fois le mouvement de zoom terminé, ils alignent le facteur d'échelle sur le jeu de tuiles le plus proche. Les mosaïques sont donc toujours affichées en résolution native, sauf pendant le mouvement de zoom.

Honnêtement, nous n'avons pas encore de plan solide. Je vais discuter avec d'autres peintres lundi.

BTW, il semble que Google Maps mobile (je suppose que celui du site Web) utilise exactement la même technique que nous.

@mourner @IvanSanchez une question fondamentale avec une solution possible en utilisant will-change:
https://bugs.chromium.org/p/chromium/issues/detail?id=600120#c15

La stratification actuelle est-elle importante? Je vois que chaque tuile est forcée dans sa propre couche (translate3d), et ces couches sont mises à l'échelle indépendamment d'une valeur fractionnaire.

Tant que nous mettons à l'échelle chaque tuile de carte indépendamment (soit en utilisant des couches ou via drawImageRect + CTM fractionnaire), pour les valeurs d'échelle fractionnaire, nous obtenons des arêtes qui ne sont pas alignées sur les pixels. Ceci déclenche le problème d'anti-crénelage de bord coïncident où un AA discret provoque un fond perdu de couleur.

La façon dont je pense que cela pourrait fonctionner à la place est de pixelliser la carte avec une échelle non fractionnaire (par exemple 1.0), puis de la réduire de manière atomique:

1) éviter la superposition de tuiles individuelles (utilisez "transform: translate ()" au lieu de "transform: translate3d ()")
2) couche de conteneur de force (carte entière) (utilisez "transform: scale3d ()" sur le conteneur)
3) Forcer la pixellisation de la couche de conteneur avec une échelle == 1.0

Avec ces modifications, les images de tuiles de carte doivent être pixellisées avec une échelle de 1,0 (=> les bords sont alignés en pixels => pas d'artefacts de couture), puis toute la couche de carte doit être réduite de manière atomique.

Malheureusement, le n ° 3 n'est pas anodin, et le seul hack auquel je puisse penser est

  • commencez par scale (1) et will-change: transform (voir https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/Ufwrhx_iZ7U pour plus de détails)
  • réinitialiser l'échelle de la couche à la valeur souhaitée après le premier passage du raster

par exemple http://jsbin.com/yaqeru/10/embed?output

chrishtr / danakj ai-je obtenu la bonne sémantique de l'échelle de raster de couche, et y a-t-il un meilleur moyen de verrouiller l'échelle de rastérisation de couche à une valeur particulière?

Pouvez-vous aider à y répondre?

Je sais qu'un correctif est en cours (merci à tous d'avoir poussé là-dessus!), Mais en attendant ... le monkeypatch de @cmulders fonctionne mieux pour moi. Voici une version qui intègre Leaflet en tant que module npm, utilise ES6 et n'assure pas de double patch, au cas où quelqu'un chercherait quelque chose de copypasta.

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;

}

Je suis content que les gens se penchent là-dessus. Au cas où cela serait utile à quiconque comme solution de contournement moins qu'idéale: si vous êtes prêt à sacrifier l'inertie, définir intertia:false sur la carte init élimine les lacunes, et éventuellement zoomAnimation:false

Je pense avoir trouvé une solution (trop compliquée) pour cela, je l'ai mise sur https://github.com/Leaflet/Leaflet.TileLayer.NoGap - les commentaires sont les bienvenus, car je ne suis pas sûr de la performance de cette chose sur de vieux ordinateurs / téléphones.

cc @Eschon @hyperknot

BTW, le bogue se produit également lors de l'utilisation de Chrome sur un écran à haute résolution (2560x1140), sans qu'il soit nécessaire d'utiliser le zoom fractionnaire du dépliant ni le zoom du navigateur.

Désolé pour la réponse tardive.

Je viens de tester votre solution. La démo a bien fonctionné pour moi, j'ai donc essayé d'ajouter le correctif à mon application. Comme j'utilisais toujours une ancienne version 1.0-dev de Leaflet, je l'ai mise à jour vers 1.0.0-rc3 à partir de http://leafletjs.com/download.html

La première chose que j'ai remarquée, c'est qu'il semble y avoir une erreur ici . Il affiche une erreur qui mappe indéfini, je l'ai donc changé en this._map .

Après cela, cela a fonctionné mais c'est vraiment lent sur mon ordinateur de travail. Surtout dans Chrome, mais Firefox était également lent.

Étonnamment, cela n'a pas eu un tel impact sur les téléphones que j'ai testés.
Firefox sur Android semble être le même qu'avant, Chrome est un peu plus lent mais pas trop mal.
Safari sur iOS semble également être à peu près le même qu'avant.

Une autre chose étrange que j'ai remarquée est que sur les mobiles Chrome et Safari, le zoom par pincement semble atteindre des niveaux fixes.

@Eschon Merci d'avoir testé ça!

Je fais toujours l'erreur de taper map au lieu de this._map :-(

Après cela, cela a fonctionné mais c'est vraiment lent sur mon ordinateur de travail. Surtout dans Chrome, mais Firefox était également lent.

Pourriez-vous exécuter un profileur sur cet ordinateur? Ce serait bien de savoir si le ralentissement est lié aux opérations de canevas. J'ai remarqué que les performances étaient légèrement affectées sur IE9-IE11.

Selon que cette solution ralentit ou non la carte sur certaines plates-formes, il peut être judicieux de la rendre complètement facultative et de la désactiver par défaut. Certains commentaires ici sont importants!

Je n'ai pas vraiment regardé comment les gens d'OL3 résolvent ce problème, ou s'ils effectuent une détection des performances sur le navigateur avant d'activer la composition de canevas. Ça vaut peut-être la peine d'y jeter un coup d'œil.

Une autre chose étrange que j'ai remarquée est que sur les mobiles Chrome et Safari, le zoom par pincement semble atteindre des niveaux fixes.

Je parie que cela ne fait que jouer avec les options zoomDelta et zoomSnap , et n'est pas lié à ce bogue.

Pourriez-vous exécuter un profileur sur cet ordinateur? Ce serait bien de savoir si le ralentissement est lié aux opérations de canevas. J'ai remarqué que les performances étaient légèrement affectées sur IE9-IE11.

Dois-je simplement enregistrer un profil de processeur JavaScript avec les outils de développement Chrome? Je n'ai pas beaucoup d'expérience avec ces tests de performances, donc je ne sais pas vraiment quoi faire des données qu'il montre.

Ouais, c'est ça le truc. Recherchez ensuite des éléments larges sur le tableau des flammes.

J'ai juste fait un profil avec le correctif et un autre sans lui. J'ai essayé de faire à peu près la même chose pour les deux profils.

La première chose que j'ai remarquée que la version avec le correctif avait un "pic" supplémentaire (je ne sais pas si c'est le bon mot) causé par _onZoomTransitionEnd

Dans la version sans le correctif, _onZoomTransitionEnd pris 1,8 ms et je ne l'ai même pas vu dans le graphique. Dans la version avec le correctif, cela prenait 6 ms et provoquait un "pic" d'activité.

Les deux autres "pics" se ressemblent assez dans les deux profils, les choses semblent juste se passer un peu différemment mais l'écart entre eux est plus grand dans la version avec le correctif.

J'espère que cela vous aide d'une manière ou d'une autre. J'ai également enregistré les deux profils, donc si vous en avez besoin, je pourrais les télécharger quelque part.

Pour contourner le problème pour le moment, j'ajoute simplement un facteur d'échelle de .002 à la fonction d'origine qui définit la propriété translate3d sur chaque tuile, ce qui élimine presque entièrement les espaces. ".002" était le facteur de mise à l'échelle le plus bas dans mes cas de test pour faire disparaître complètement les lacunes. Je n'ai remarqué aucun effet secondaire.

Testé dans les derniers Chrome, Firefox et IE 11. Testé sur un moniteur 40 "4k avec une mise à l'échelle de Windows réglée à 150% avec différentes valeurs de zoom dans les navigateurs.

des progrès sur ce bogue? @AlexanderUhl votre solution provoque-t-elle une modification des images lorsqu'elle est placée ou est-ce uniquement affecté lors du déplacement / zoom?

Il semble que la propriété CSS will-change été ajoutée pour résoudre ce problème, il suffit de vérifier les avertissements de performance FF, décrits ici: https://github.com/Leaflet/Leaflet/issues/4686

@themre : la propriété scale s'applique à toutes les mosaïques d'image lorsqu'elles sont ajoutées et sont définitivement. Le style attr ressemblera à ceci:
style="width: 256px; height: 256px; transform: translate3d(545px, 745px, 0px) scale(1.002); opacity: 1;"

Mais cela aurait pour effet d'étirer un peu l'image, ce qui est un effet indésirable. J'ai essayé la version 1.0.3 qui a la propriété CSS will-change mais cela provoque toujours un espace blanc. Je vais essayer de regarder un peu plus.

Ofc ça étend l'img, c'est l'approche ;-) Je suis d'accord que cette solution de contournement n'est pas idéale, mais c'est généralement la nature d'une solution de contournement, n'est-ce pas? Néanmoins, cette approche fonctionne mieux pour moi avec des effets secondaires négligeables (pour mon cas d'utilisation qui est une application de cartographie avec des tuiles de mapbox, ici, osm, etc.)

eh bien, si nous utilisons translate normal, le problème est résolu. Je ne sais pas vraiment si la propriété CSS translate3d est tellement plus rapide que la traduction normale, il serait peut-être préférable d'ajouter cet indicateur en option.Je pense que je vais remplacer translate3d par translate.

vue en action:
translatemap

image
Face au même problème, avec la dernière version (1.0.3).

ça sera peut-être corrigé dans 1.1

Le 8 mars 2017, mer à 10:13, Gaurav [email protected] a écrit:

[image: image]
https://cloud.githubusercontent.com/assets/13112509/23697357/7dcc4cf6-040d-11e7-881a-df3a44254015.png
Face au même problème, avec la dernière version (1.0.3).

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/Leaflet/Leaflet/issues/3575#issuecomment-284987808 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAeKj_23QbtFCaXeFjGRJcU-jg0284xBks5rjnEvgaJpZM4FO8Jh
.

Si les valeurs de nx et ny, qui sont utilisées pour traduire le div .leaflet-pane.leaflet-map-pane sont arrondies à un nombre entier, alors le problème de ligne / espace est résolu sur Safari. Je ne vois aucun effet secondaire néfaste (pour mon utilisation en tout cas).

Trouve ça:
translate3d("+n.x+"px,"+n.y+"px,0)")
et remplacer par:
translate3d("+Math.round(n.x)+"px,"+Math.round(n.y)+"px,0)")

@LudwigBogner, il échoue probablement de toute façon une fois que vous avez effectué une mise à l'échelle (réglage du zoom du navigateur, par exemple, ou pendant l'animation de zoom). Voir cet exemple, lié ci-dessus, où les traductions en elles-mêmes sont arrondies: http://playground-leaflet.rhcloud.com/vicu/edit?html , sortie

Je viens de me faire mordre par celui-ci. Pour moi, cela ne semble pas exister sur Chromium ou FireFox. Juste quelques-uns des zooms fractionnaires sur Safari.

Le progrès?

Ce problème existe toujours sur Chrome et Firefox (Mac). J'utilise un zoomDelta et un zoomSnap de 0,25.

Curieusement, la définition de .leaflet-tile { will-change: auto !important; } (ou "unset") résout le problème dans Firefox (uniquement). Toujours à la recherche d'une solution de contournement pour Chrome.

Les autres correctifs proposés pour désactiver l'inertie et modifier le code translate3d pour ajouter un arrondi ne fonctionnaient pas non plus.

@jawinn Je pense que vous pourriez réussir en définissant L_DISABLE_3D sur true , IIRC a à peu près le même effet que la modification de will-change , c'est-à-dire qu'il supprimera l'accélération matérielle lors du rendu du carte. Sachez que cela vous donnera probablement des performances bien pires pour les animations de zoom, le panoramique, etc.

Tout cela est très sensible aux détails de mise en œuvre du navigateur, alors prenez cela avec un grain de sel, cela faisait un bon moment que je n'avais pas examiné cela.

@jawinn
Le travail autour que j'utilise est celui de @cmulders ci-dessus:

/* 
 * 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';
        }
    });
})()

Ce n'est pas parfait mais pour autant que je sache, cela n'a aucun impact sur les performances

Merci les gars. @Eschon Cela a fonctionné. Plus aucune lacune n'apparaît dans Chrome ou Firefox.

Pour ceux qui vont utiliser le "correctif 1px", préparez-vous à ce que vos images deviennent floues et un peu cassées:

Pour moi, qui passais des heures à rendre et à faire du photoshopping l'image originale, c'était inacceptable. J'ai donc dû utiliser L_DISABLE_3D = true et supporter les animations scintillantes et les zooms nerveux à la fin.

Plus d'infos: J'utilise le plugin

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

Q: Quelle est la prochaine meilleure alternative à Leaflet qui n'a pas un tel bug "espace entre les tuiles"?

Je vais chercher moi-même sur Google, mais peut-être que quelqu'un a déjà emprunté cette voie.

@ n3tman avez-vous également essayé le plugin NoGap ? Ça vaudra peut-être le coup.

@perliedman merci d'avoir mentionné celui-ci.
Malheureusement, impossible de le faire fonctionner localement. Erreur Cannot read property 'appendChild' of undefined dans la fonction _initContainer .
Essayé avec les versions précédentes de Leaflet (jusqu'à 1.0.2) - même résultat. La démo montre la même erreur dans Chrome / Firefox.
Peut-être que je manque quelque chose d'évident, pouvez-vous s'il vous plaît aider?

Même écart de 1px ici.

Version de Chrome 66.0.3359.139 (64 bits)
Windows 10 (1709)
Dépliant 1.3.1

Lorsque j'ai ouvert ce problème pour la première fois, j'ai trouvé qu'il était lié aux niveaux de zoom fractionnés, mais ce n'est peut-être plus la seule cause.

J'ai récemment lancé un projet qui utilise le plugin GoogleMutant et là, j'ai trouvé que cela se produit également lorsque je règle simplement le niveau de zoom sur un nombre entier et que je fais un panoramique un peu.

Cela semble être lié à # 6069 et (en quelque sorte) corrigé par # 6240 bien que les écarts apparaissent toujours lors du zoom et du panoramique.

J'ai également supprimé la solution de contournement de mes autres projets et cela semble se produire là aussi, donc ce n'est pas spécifique au plugin GoogleMutant

Inspiré de la solution de contournement @cmulders 1px ... Cela fonctionne, mais l'effet flou qui apparaît n'est pas agréable sur certaines images. J'ai essayé ce qui suit à la place (je n'ai pas beaucoup testé cependant ...) et il semble corriger les écarts tout en conservant des images nettes avec des niveaux de zoom non fractionnaires. Le 0,5px supplémentaire semble être suffisant pour combler les lacunes (essayé Chrome et Firefox sur Linux et Chrome sur Android, avec Leaflet 1.3.4)

(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
Plus de 3 ans plus tard, ce bogue n'a toujours pas été résolu dans Chrome! Je ne vois pas l'effet dans Firefox ou Safari. Merci @cmulders pour votre travail!

Idem ici (Windows 7 Entreprise SP1). Lignes ici et là dans Firefox, grille de ligne complète dans Chrome, mais OK dans IE11. @cmulders fix fonctionne dans Firefox et Chrome.

Voici les résultats complets de quelques tests supplémentaires:

  • Windows 7 Entreprise SP1

    • IE11: OK

    • Chrome, Firefox: pas OK

  • Windows 10

    • IE11, Edge, Firefox: OK

    • Chrome: pas OK

  • macOS

    • Safari, Chrome, Firefox: OK

  • Linux:

    • Chrome, Firefox: OK

  • Android:

    • Chrome, Firefox: OK

    • Application utilisant WebView: OK

Des tests supplémentaires ont montré qu'il s'agissait manifestement d'un problème de très faible niveau qui n'a rien à voir avec Leaflet.
Les tests sur Windows 7 Enterprise SP1 étaient initialement sur deux PC différents, mais tous deux avec des graphiques NVIDIA.

Quand le même test a été fait sur Windows 7 Enterprise SP1 avec des graphiques AMD Radeon, ça s'est passé, pas de lignes entre les tuiles sur Chrome ou Firefox!

Comme NoGap a déjà été mentionné, je voulais juste vous faire savoir que j'ai pris le code d'origine et l'ai modifié pour le faire fonctionner avec les versions actuelles des dépliants (c'est-à-dire dépliant ^ 1.3.3):
https://github.com/Endebert/squadmc/blob/master/src/assets/Leaflet_extensions/NoGapTileLayer.js

Il peut ensuite être utilisé comme un TileLayer classique: https://github.com/Endebert/squadmc/blob/master/src/assets/SquadMap.js#L34

Il utilise les fonctionnalités es6, vous devrez donc peut-être apporter des modifications pour que cela fonctionne pour vous.

Comme NoGap a déjà été mentionné, je voulais juste vous faire savoir que j'ai pris le code d'origine et l'ai modifié pour le faire fonctionner avec les versions actuelles des dépliants (c'est-à-dire dépliant ^ 1.3.3):
https://github.com/Endebert/squadmc/blob/master/src/assets/Leaflet_extensions/NoGapTileLayer.js

Il peut ensuite être utilisé comme un TileLayer classique: https://github.com/Endebert/squadmc/blob/master/src/assets/SquadMap.js#L34

Il utilise les fonctionnalités es6, vous devrez donc peut-être apporter des modifications pour que cela fonctionne pour vous.

@Endebert Avez-vous réussi à faire fonctionner NoGap? J'ai eu la même erreur que @ n3tman il y a quelque temps:
Cannot read property 'appendChild' of undefined erreur dans la fonction _initContainer .

Le seul changement que j'ai trouvé dans votre version est d'ajouter try ... catch à l'appel level.ctx.drawImage(imageSource, offset.x, offset.y, tileSize.x, tileSize.y);
et cela n'a pas aidé.

@TomazicM Oui, mon implémentation est utilisée dans mon application SquadMC . Ce n'est peut-être pas si évident sur le bureau, mais sur mobile, il est évident que le zoom fractionné sans accrochage est activé.

En ce qui concerne l'implémentation: La version originale utilise TileLayer.include() , tandis que j'utilise TileLayer.extend() . Je pense que c'est la différence importante. Comme mentionné, c'est une nouvelle classe qui est destinée à être utilisée à la place de TileLayer.

Eh bien, voici mon résultat de 2 heures d'enquête. Le problème est causé par des décimales de pixels à l'intérieur de translate3d .

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

C'est pourquoi cela fonctionne bien avec L_DISABLE_3D = true , car selon cette partie du code source, il n'utilise pas translate3d .

Solution

N'autorisez tout simplement pas les pixels décimaux. Il peut être réalisé, par exemple:

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

  • ou par de nombreuses autres solutions ...

Eh bien, voici mon résultat de 2 heures d'enquête. Le problème est causé par des décimales de pixels à l'intérieur de translate3d .

Je suppose qu'aujourd'hui, nous sommes en 2019 et que l'utilisation de translate3d pour forcer le navigateur moderne à utiliser le GPU est assez obsolète. Bon travail @mdorda

@mdorda Salut! Cela semble intéressant, mais sachez que l'arrondissement a déjà été discuté dans ce fil: https://github.com/Leaflet/Leaflet/issues/3575#issuecomment -327237235

Je ne sais pas si quelque chose d'important a changé depuis lors qui fait une différence, mais je ne ferais pas espoir avant d'avoir fait des tests approfondis.

Une première étape pour résoudre ce problème serait de soumettre un PR afin que nous puissions le tester.

Pour ceux qui travaillent avec Angular 2+, je l'ai résolu de cette façon. Cela fonctionne pour mon cas d'utilisation simple, je ne sais pas pour les autres implications ...

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);

Je vois cet écart de pixels sur le zoom fractionnaire dans LeafletJS version 1.5.1 sur Windows 10 Pro 1903 avec Mozilla Firefox 69.0.1 (64 bits).
Écart de pixels
Je pense que la raison de l'écart de pixels n'est peut-être pas dans la fonction CSS translate3d () mais dans scale ().
image
Dans la version 1.5.1, comme je le vois, les paramètres translate3d () uniquement entiers.


Cordialement, IMMSPgisgroup

Avez-vous trouvé une solution à ce bug?

J'ai le même problème en ce moment et je n'ai pas trouvé de solution.

error

J'utilise:

  • Windows 10 Famille 1803
  • Google Chrome Versión 77.0.3865.90 (version officielle) (64 bits)
  • Dépliant 1.5.1

Lorsque j'utilise Firefox, les lignes blanches n'apparaissent pas

no_error

@ Arenivar93

Na je suis là-dessus depuis quelques années maintenant. Ils ont essayé un certain nombre de solutions de contournement, mais rien n'a fonctionné pour le corriger sans compromis majeurs. La racine du problème est en amont dans le chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=600120

Le dernier message de l'équipe chrome est qu'il est trop difficile de faire sans casser d'autres choses, donc nous pouvons être coincés avec cela pendant un certain temps.

Surtout sur des cartes ou des images plus sombres (dans mon cas), le problème est assez perceptible. Je pense que l'anticrénelage dans le navigateur provoque les espaces entre les tuiles en raison de la transformation _fractionnelle_ pendant le zoom, comme mentionné par Ivan.

Jusqu'à ce qu'une meilleure solution soit disponible, j'utiliserai cette solution de contournement (ou hack) pour agrandir les tuiles d'un pixel, avec pour effet secondaire qu'elles se chevauchent de 1 px. De plus, les tuiles seront légèrement agrandies et mises à l'échelle (de 1px).

/* 
 * 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';
        }
    });
})()

nous avons eu beaucoup de chance avec cette solution. ce n'est pas parfait, mais c'est mieux que les lignes à notre avis.

en plus de cela, nous nous sommes assurés que la couleur d'arrière-plan de la carte correspondait mieux à la couleur du fond de carte. par exemple, si l'océan était d'un bleu foncé, nous l'utiliserions pour que les carreaux se superposent à cette couleur, minimisant certaines des incohérences qui sont perceptibles.

encore une fois pas parfait, mais ça aide

@colbyfayock Puis-je vous demander où et comment mettre en œuvre votre solution?

Je suis en train de créer une application de réaction, cela peut donc différer, mais j'ai créé un fichier avec ce contenu:

// 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';
    }
  });
})();

les retours en haut le sont car il précompile et n'est pas toujours disponible (pas important ici)

alors je l'importe simplement après avoir importé le dépliant

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

Ma solution de contournement consiste à arrondir la valeur de transformation sans appliquer une modification au code source.
Utilisation avec react mais peut être utilisé par n'importe quel frontal puisqu'il s'agit de JQuery
Ne pas dire que c'est la meilleure option, mais le fait simplement.
Cela résout le problème et je n'ai observé aucun flou ou défaut notable. Ça vaut le coup d'essayer.

    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 - Cela ne semble pas résoudre le problème pour moi. :(

J'utilise le dépliant de réaction avec le zoom snap 0.

image

la solution n'a jamais été parfaite pour nous, mais nous n'avons certainement pas de lignes cohérentes comme celle-là dans les nôtres. Je n'étais pas sûr de la fonctionnalité zoomSnap , alors j'ai dû la rechercher, je ne sais pas vraiment comment 0 fonctionnerait avec cette propriété d'après la lecture de la description. avez-vous essayé de supprimer cela juste pour voir si les lignes sont toujours présentes sans elle?

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

Edit: continué à lire après l'exemple gif

zoomSnap peut être réglé sur zéro. Cela signifie que Leaflet ne cassera pas le niveau de zoom.

Je suppose que vous entrez dans des états fractionnaires que la solution ne peut pas gérer au-delà de l'accrochage entier par défaut complet 🤷‍♂️ mais pas sûr

Leaflet 1.7-dev et le problème persiste. Lignes aux bordures des tuiles dans Firefox et Chrome dans Windows 7 et Windows 10. Pas de problème dans IE11 et l'ancien (non Crome) Edge, même problème dans le nouveau Edge basé sur Chrome.

Il y a deux solutions de travail, mais je n'aime aucune d'elles. La première consiste à désactiver 3d de <script>L_DISABLE_3D = true;</script> , mais cela signifie perdre les opérations animées. L'autre consiste à étendre les éléments HTML de mosaïque d'un pixel, mais cela signifie que vous obtenez des carreaux légèrement flous.

J'ai trouvé une solution très primitive, mais de par sa nature même, elle fonctionne à 100%. Peut-être que quelqu'un le trouve utile.

La solution consiste à afficher la même couche de tuiles incriminées deux fois sur deux volets de carte différents, l'un placé sous l'autre et ayant un décalage [-1, -1].

Le code ressemble à ceci:

<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>

de la suggestion de @cmulders, j'ai

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

Je suis avec @mdorda , lorsque le panoramique et le zoom donnent des nombres entiers dans l'appel de leaflet-map-pane à translate3d() , au lieu de fractions de pixels, alors (avec mes œillères allumées) le problème est parti et tout est à nouveau beau. Je ne prétends pas comprendre toutes les nuances du moment où les fractions doivent être conservées, mais si cela permet à Leaflet de soulager le problème du navigateur, alors serait-il acceptable de placer L.Draggable._onMove dans un revêtement de sol

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

ou même en L.DomUtils.setTransform

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

de sorte qu'aucune traduction ne reçoive des fractions, mais ce serait probablement un gaspillage puisque les images de tuiles ne donnent pas de traductions fractionnaires (n'est-ce pas?).

J'ai perdu deux heures, pour découvrir qu'après cela, les paramètres de mon navigateur ont été agrandis, pas en taille réelle
Il suffit de ramener le zoom sur le réel et tout a fonctionné comme un charme, c'était mon cas

J'ai perdu deux heures, pour découvrir qu'après cela, les paramètres de mon navigateur ont été agrandis, pas en taille réelle
Il suffit de ramener le zoom sur le réel et tout a fonctionné comme un charme, c'était mon cas

@tokenflow : Cette rubrique concerne littéralement «Espace entre les vignettes sur les niveaux de zoom fractionnaires dans les navigateurs Webkit». J'essaie vraiment de ne pas être arrogant ici, mais pensez-vous vraiment que vos informations sur le zoom à 100% sont une contribution utile à quiconque?

J'ai rencontré ce bug sur la version Linux de Firefox et Chromium.
Le problème (du moins pour Firefox) semble être le scale() du principal .leaflet-tile-container , que j'ai pu trouver avec document.querySelector('.leaflet-tile-container:last-of-type').getAttribute('style') .
Par exemple. vous avez scale(0.707107) , mais tous les enfants img ont une largeur / hauteur de 256. Vous calculez donc: 0.707107 * 256px = 181.019392px , qui est un nombre décimal. Lorsque vous arrondissez les pixels et que vous prenez cela comme échelle, cela semble fonctionner dans Firefox / Linux: 181px / 256px = 0.70703125 .

J'ai écrit une fonction qui aide au débogage:

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);
    }
}

Si vous l'appelez avec true comme premier paramètre, il tente de corriger l'échelle. Ceci, cependant, ne fonctionne que sur Firefox pour moi.

J'ai trouvé une solution qui est stupide et qui ne devrait vraiment pas fonctionner.

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

Cela devrait entraîner d'énormes coutures discordantes autour des carreaux, mais je ne peux pas les voir du tout et cela corrige l'espace entre les carreaux.

@ ChrisLowe-Takor en quelque sorte, cela semble vraiment fonctionner bien qu'à première vue, je ne peux pas vraiment dire pourquoi.
Cela peut être préférable à la solution de contournement JavaScript que j'utilise actuellement, mais je vais devoir l'examiner un peu plus et faire des tests.

@ ChrisLowe-Takor - Wow, ça marche aussi pour moi! Bonne trouvaille 👍

@ ChrisLowe-Takor semble également fonctionner pour moi dans R, en utilisant le package Leaflet. Merci beaucoup!

@ ChrisLowe-Takor D'une manière ou d'une autre, cette astuce le fait vraiment pour tous les navigateurs modernes stupides (pour le vieux vénérable IE11, ce n'est pas nécessaire)! Il n'y a qu'une chose à garder à l'esprit: si l'option detectRetina est utilisée pour la couche de tuiles et que l'affichage est un affichage Retina, la taille des tuiles sera de 125 x 125 px.

Mais cette solution présente le même inconvénient que toutes les solutions basées sur l'expansion du conteneur de tuiles: la tuile devient un peu floue.

@ ChrisLowe-Takor Je l'ai essayé. Si maxZoom est supérieur à maxNativeZoom, les tuiles ne s'afficheront pas correctement.

Cette page vous a été utile?
0 / 5 - 0 notes