Leaflet: L.Icon.Default bringt eine falsche Bild-URL

Erstellt am 28. Sept. 2016  ·  90Kommentare  ·  Quelle: Leaflet/Leaflet

  • [ x] Ich melde einen Fehler, bitte nicht um Hilfe
  • [ ] Ich habe mir die Dokumentation angesehen , um sicherzustellen, dass das Verhalten dokumentiert und erwartet wird
  • [x ] Ich bin mir sicher, dass dies ein Problem mit dem Leaflet-Code ist, kein Problem mit meinem eigenen Code oder dem von mir verwendeten Framework (Cordova, Ionic, Angular, React…)
  • [ ] Ich habe die Probleme durchsucht, um sicherzustellen, dass sie noch nicht gemeldet wurden

Die Bild-URL-Broschüre, die mir präsentiert wird, lautet https://uismedia.geo-info-manager.com/apis/leaflet_1/imagesmarker-icon-2x.png. Anscheinend fehlt ein "/"
Außerdem habe ich einen Fehler
leaflet.min.js:5 GET https://uismedia.geo-info-manager.com/apis/leaflet_1/images/ 403 (Verboten)

compatibility

Hilfreichster Kommentar

Wollte mitteilen, was ich getan habe, um das Problem mit ungültigen Daten: URL zu umgehen. Legen Sie grundsätzlich das Standardsymbol auf ein neues fest, das das bereitgestellte Markierungssymbol und den Schatten verwendet, aber Webpack die Datenkodierung dieser Bilder individuell handhaben lässt. Fügen Sie einfach irgendwo eine solche Datei ein.

import L from 'leaflet';

import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

let DefaultIcon = L.icon({
    iconUrl: icon,
    shadowUrl: iconShadow
});

L.Marker.prototype.options.icon = DefaultIcon;

Könnte wahrscheinlich optimiert werden, um auch das Netzhautsymbol aufzunehmen.

Alle 90 Kommentare

  • Gibt es auf Ihrem Server eine öffentliche Webseite, die wir besuchen können, damit wir das Problem selbst reproduzieren können?
  • Welches Betriebssystem und Webbrowser verwenden Sie?

leaflet.min.js:5 GET https://uismedia.geo-info-manager.com/apis/leaflet_1/images/ 403 (Verboten)

Dies kann von demselben Problem stammen, das in https://github.com/Leaflet/Leaflet/issues/4849 besprochen wird

In der Tat. Deshalb bin ich neugierig, unter welchen Umständen dies reproduziert werden kann, damit wir Komponententests gegen diese durchführen können.

Ich hatte das gleiche Problem beim Wechsel von RC3 auf 1.0.1 - in meinem Code hatte ich die Zeile L.Icon.Default.imagePath = 'images'; - Ich kann mich nicht mehr genau erinnern, warum das so war, aber das Auskommentieren hat das Problem gelöst - es könnte sich lohnen, zu überprüfen, ob Sie ähnliches haben

bekam plötzlich das gleiche Problem in zwei völlig unterschiedlichen Projekten, beide mit Webpack und Leaflet.
Wenn ich der Karte Markierungen hinzufüge, werden die Bilder nicht gefunden. Browser gibt diesen Fehler aus:
image

ok ich hab was.

Ein Marker sieht derzeit also so aus, weil die Bilder (Symbol und Schatten) nicht gefunden werden.
image

diese Funktion im Prospekt:

_getIconUrl: function (name) {
    if (!L.Icon.Default.imagePath) {    // Deprecated, backwards-compatibility only
        L.Icon.Default.imagePath = this._detectIconPath();
    }

    // <strong i="10">@option</strong> imagePath: String
    // `L.Icon.Default` will try to auto-detect the absolute location of the
    // blue icon images. If you are placing these images in a non-standard
    // way, set this option to point to the right absolute path.
    return (this.options.imagePath || L.Icon.Default.imagePath) + L.Icon.prototype._getIconUrl.call(this, name);
},

bewirkt, dass die data:image URLs die folgende Zeichenfolge am Ende der URL haben:
")marker-icon-2x.png .

Der Name der Datei kann entfernt werden, wenn Sie + L.Icon.prototype._getIconUrl.call(this, name) löschen. Der ") Teil stammt wahrscheinlich von der _detectIconPath Regex-Magie. Ich kann das nicht beheben, also habe ich gerade versucht, die letzten beiden Zeichen abzuschneiden, was zu dieser Funktion führt:

_getIconUrl: function (name) {
    if (!L.Icon.Default.imagePath) {    // Deprecated, backwards-compatibility only
        L.Icon.Default.imagePath = this._detectIconPath();
    }

    // <strong i="21">@option</strong> imagePath: String
    // `L.Icon.Default` will try to auto-detect the absolute location of the
    // blue icon images. If you are placing these images in a non-standard
    // way, set this option to point to the right absolute path.
  var url = (this.options.imagePath || L.Icon.Default.imagePath);

  return url.slice(0, - 2);
},

und los gehts, das Symbol wird angezeigt. Ein letztes Problem ist, dass das Schattenbild auch ein Markierungssymbol ist - der src-Pfad ist bereits falsch, ich habe (noch) keine Ahnung warum. Ein Marker sieht nun so aus:

image

@IvanSanchez hilft Ihnen dies, das Problem ein wenig

@codeofsumit wäre schön, _detectIconPath zu durchlaufen und zu sehen, was dort vor sich geht, insbesondere welchen Wert die Variable path hat, bevor sie durch die Regex übergeben wird.

@IvanSanchez @perliedman Ich glaube, ich habe den Fehler gefunden.

Das ist _detectIconPath

_detectIconPath: function () {
    var el = L.DomUtil.create('div',  'leaflet-default-icon-path', document.body);
    var path = L.DomUtil.getStyle(el, 'background-image') ||
               L.DomUtil.getStyle(el, 'backgroundImage');   // IE8
    document.body.removeChild(el);

    return path.indexOf('url') === 0 ?
        path.replace(/^url\([\"\']?/, '').replace(/marker-icon\.png[\"\']?\)$/, '') : '';
}

die Variable path sieht in etwa so aus:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQ…n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=") .

Welches ist richtig.

Jetzt möchte die Regex die data.image-URL daraus extrahieren und gibt dies zurück:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQ…n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=")

Beachten Sie das letzte ") , das nicht aus der Variablen path . Die Regex /^url\([\"\']?/ zielt nur auf url(" am Anfang des Pfads ab, nicht auf ") am Ende.
Die Verwendung dieser Regex funktioniert:

return path.indexOf('url') === 0 ?
    path.replace(/^url\([\"\']?/, '').replace(/\"\)$/, '').replace(/marker-icon\.png[\"\']?\)$/, '') : '';

Dies behebt das Bildproblem zusammen mit

var url = (this.options.imagePath || L.Icon.Default.imagePath);

innen _getIconUrl . Aber es repariert den Schatten nicht - ich weiß immer noch nicht, was mit dem Schatten los ist.

das gleiche Problem haben,
der Pfadwert in _detectIconPath ist etwa "url("data:image/png;base64,i...5CYII=")"
und es sieht so aus, als ob _getIconUrl und _detectIconPath nicht für die Verarbeitung von Daten-URLs entwickelt wurden

Das Schattenproblem scheint dadurch verursacht zu werden, dass in _getIconUrl der Wert für L.Icon.Default.imagePath bereits mit der Markerdaten-URL festgelegt ist, also das Bild für Marker verwendet und gestreckt wird
image

Könnte es mit diesem Commit zusammenhängen, das das Markerbild hartcodiert?
https://github.com/Leaflet/Leaflet/commit/837d19093307eb5eeb1fca6536962a1ab1573dd5

@Radu-Filip Ich konnte es mit diesen Änderungen an Ihrem PR beheben - ich bin mir jedoch nicht sicher, welche anderen Auswirkungen dies haben könnte:
image

Das Problem ist - wie Sie sagten -, dass die Standard-URL das Markierungsbild ist, im Grunde für alle Symbole.
Also habe ich zuerst die Standard-URL für den Schatten zum CSS hinzugefügt:

/* Default icon URLs */
.leaflet-default-icon-path {
    background-image: url(images/marker-icon.png);
}

.leaflet-default-shadow-path {
    background-image: url(images/marker-shadow.png);
}

Dann habe ich den Namen von _getIconUrl an _detectIconPath und damit die Klasse zu dem Element hinzugefügt, aus dem der Pfad extrahiert wird:

_getIconUrl: function (name) {

  L.Icon.Default.imagePath = this._detectIconPath(name);

    // <strong i="15">@option</strong> imagePath: String
    // `L.Icon.Default` will try to auto-detect the absolute location of the
    // blue icon images. If you are placing these images in a non-standard
    // way, set this option to point to the right absolute path.
  var path = this.options.imagePath || L.Icon.Default.imagePath;
  return path.indexOf("data:") === 0 ? path : path + L.Icon.prototype._getIconUrl.call(this, name);
},

_detectIconPath: function (name) {
    var el = L.DomUtil.create('div',  'leaflet-default-' + name + '-path', document.body);
    var path = L.DomUtil.getStyle(el, 'background-image') ||
               L.DomUtil.getStyle(el, 'backgroundImage');   // IE8

    document.body.removeChild(el);

    return path.indexOf('url') === 0 ? path.replace(/^url\([\"\']?/, '').replace(/(marker-icon\.png)?[\"\']?\)$/, '') : '';
}

Ich musste auch das if/else um detectIconPath entfernen, da es nicht für das Schattensymbol aufgerufen wurde. Jetzt funktioniert alles für das Standardmarkierungssymbol - bei benutzerdefinierten bin ich mir nicht sicher.

@codeofsumit ja, ich habe hier etwas ähnliches gemacht https://github.com/Radu-Filip/Leaflet/tree/temp
und ich werde es vorerst als Hack verwenden. Hoffentlich wird es eine zukunftssicherere Lösung für diejenigen geben, die Webpack et al. verwenden

@Radu-Filip macht es Ihnen etwas aus, Ihre PR mit dieser Lösung zu aktualisieren? Es kann zusammengeführt werden.

@codeofsumit fertig, mal sehen ob es durchgeht

Hallo,

Vielleicht übersehe ich etwas, aber es scheint mir, dass dieses Problem beim Erstellen von Webpacks einfach mit einem Leaflet-Plugin behoben werden könnte, das das Verhalten von L.Icon.Default überschreiben würde.

Demo: http://playground-leaflet.rhcloud.com/nexo/1/edit?html ,css,output

Mit diesem Ansatz werden Sie alle kniffligen RegExp los, und die Standard-Marker-Bilder werden inline (durch harte Codierung) eingefügt, was ohnehin ein von Webpack beabsichtigtes Ergebnis für kleine Bilder ist.

Ein möglicher Nachteil ist, dass jeder Marker sein eigenes base64-Symbol hat, ich bin mir nicht sicher, ob Browser das zwischenspeichern können… (gleicher Nachteil für PR #5041)
Wir könnten uns eine Verfeinerung vorstellen, indem wir es als Hintergrundbild festlegen, anstatt es im Bildattribut src , wie es beispielsweise für das Ebenensteuerungssymbol der Fall ist.
Es kann mit dieser Idee eine versteckte Falle sein (edit: klingt wie , dass man ), sonst ist mir sicher , es wäre vor langer Zeit umgesetzt wurde, wie es die Bild Pfaderfassung in erster Linie vermieden hätte.

Demo: http://playground-leaflet.rhcloud.com/mey/1/edit?html ,css,output (ohne Netzhautpflege)

Der größte Vorteil des Plugin-Ansatzes besteht darin, dass dieses spezifische Verhalten nur für Webpack-Projekte beibehalten wird.

Hoffe das hilft.

Übrigens, mir scheint, dass hier etwas an sich nicht stimmt.

Leaflet macht eine "komplexe" Pfaderkennung zu Bildern, die sich im Vergleich zur CSS-Datei an einer vordefinierten Stelle befinden müssen.

Aber Webpack-Build-Prozesspakete, die CSS und können (oder nicht) die Bilder auch verschieben (und umbenennen!), je nachdem, was der Entwickler an Webpack anfordert (z. B. Bilder anfordern).
Daher schlägt die Leaflet-Erkennung sicherlich fehl, wenn Webpack verwendet wird.

PR #5041 ist wie ein Trick, um den Fall zu akzeptieren, dass Webpack Bilder in das CSS einfügt, auf Kosten des Duplizierens des Base64-Bildes in jeden Marker. Nicht einmal über die Kosten für Nicht-Webpack-Benutzer zu sprechen.

PR #4979 war nur dazu gedacht, die Webpack-Build-Fehlermeldung (wegen fehlender Datei) zu verhindern, es scheint überhaupt nicht die tatsächliche Bildpfadauflösung zu verarbeiten.
Ich denke, Entwickler geben dann manuell das L.Icon.Default.imagePath ?
@jasongrout und @Eschon , könntest du vielleicht teilen, wie du es geschafft hast?

Ich komme damit nicht wirklich klar. Ich verwende nur nicht das Standardsymbol, daher war dieser Fehler bis jetzt kein Problem für mich.

Hallo, nur ein Hinweis, dass ich diesen Pfadfehler mit der Version 1.0.1 dieser Bibliothek reproduzieren kann.
Ich verwende es zusammen mit dem Broschüren-Drupal-Modul (7.x-1.x-dev), und hier wird dem Modul ein Problem gemeldet: https://www.drupal.org/node/2814039 falls es sinnvoll.

Soweit ich sehen kann, liegt das "Problem" an der _getIconUrl-Funktion? da nach L.Icon.Default.imagePath ein Schrägstrich fehlt, wird der Bildpfad zB in Drupal wie /sites/all/libraries/leaflet/imagesmarker-icon.png ". Zwischen dem Bildpfad und dem Dateinamen des Markerbilds (marker-icon.png) sollte ein Schrägstrich / stehen.

Hallo @anairamzap-mobomo,

Klingt so, als ob das, was Sie berichten, ein anderes Problem ist.

Da es sich anscheinend um eine Portierung auf ein Framework (Drupal) handelt, müssen Sie leider zuerst sicherstellen, dass der Fehler nicht mit der Funktionsweise dieser Portierung zusammenhängt.

Leaflet 1.0.x mit Vanilla JS enthält korrekt den abschließenden Schrägstrich: http://playground-leaflet.rhcloud.com/fosa/1/edit?html ,output

Siehe zum Beispiel http://cgit.drupalcode.org/leaflet/tree/leaflet.module#n51 , wo L.Icon.Default.imagePath vom Drupal-Modul überschrieben wird.

Sieht so aus, als würde dieses Modul den Wechsel zwischen Leaflet 0.7.x und 1.0.x nicht verarbeiten, wo der Schrägstrich jetzt in L.Icon.Default.imagePath eingefügt werden muss.

Da es sich bei Leaflet 1.0.0 um eine Hauptversion handelt, gibt es wohl keine Verpflichtung zur Abwärtskompatibilität.

hey @ghybs Ich

Vielen Dank für Ihre Rückmeldung!

Ich habe genau das gleiche Problem wie ursprünglich gemeldet - in einem Aurulia-Skelett / esnext + webpack-Projekt.

Bis dies behoben ist, habe ich die Bilder in meinen Quellordner kopiert und verwende einen benutzerdefinierten Marker - das Weglassen von Größen- / Platzierungsinformationen scheint in Ordnung zu sein ...

        var customDefault = L.icon({
            iconUrl: 'images/marker-icon.png',
            shadowUrl: 'images/marker-shadow.png',
        });

Wollte mitteilen, was ich getan habe, um das Problem mit ungültigen Daten: URL zu umgehen. Legen Sie grundsätzlich das Standardsymbol auf ein neues fest, das das bereitgestellte Markierungssymbol und den Schatten verwendet, aber Webpack die Datenkodierung dieser Bilder individuell handhaben lässt. Fügen Sie einfach irgendwo eine solche Datei ein.

import L from 'leaflet';

import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

let DefaultIcon = L.icon({
    iconUrl: icon,
    shadowUrl: iconShadow
});

L.Marker.prototype.options.icon = DefaultIcon;

Könnte wahrscheinlich optimiert werden, um auch das Netzhautsymbol aufzunehmen.

Könnte jemand die geänderte Datei leaflet.js senden?
der Code, den @ajoslin103 verwendet:
```var customDefault = L.icon({
iconUrl: 'images/marker-icon.png',
shadowUrl: 'images/marker-shadow.png',
});

Ich habe die Datei leaflet.js nicht geändert, sondern nur die Markierungsbilder aus der Prospektverteilung in meinen normalen Bilderordner kopiert und dann dieses Fragment, das ich gepostet habe, als benutzerdefiniertes Symbol verwendet.

Ich konnte die Lösung von crob611 nicht verwenden, da sie im ursprünglichen CSS als http referenziert wurde und meine Site über https bereitgestellt wurde.

``` Funktion onLocationFound(e) {
var radius = e.genauigkeit / 2;
var customDefault = L.icon({
iconUrl: 'marker_icon_2x',
shadowUrl: 'marker_shadow.png'
});
L.marker(e.latlng).addTo(map)
.bindPopup("Sie befinden sich innerhalb " + Radius + " Meter von diesem Punkt entfernt").openPopup();
L.circle(e.latlng, radius).addTo(map);
}

Wie kann ich das neue Symbol einstellen?

Ich erstelle das benutzerdefinierte Symbol in meinem Konstruktor (ich verwende das Aurelia-Framework)

        this.customDefault = L.icon({
            iconUrl: 'images/marker-icon.png',
            shadowUrl: 'images/marker-shadow.png',
        });

Dann verwende ich es, wenn ich den Marker in der Methode angehängt () hinzufüge

        var map = L.map('mapid').setView([latitude, longitude], 13);
        let urlTemplate = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';
        map.addLayer(L.tileLayer(urlTemplate, { minZoom: 4 }));
        L.marker([latitude, longitude], { icon: this.customDefault }).addTo(map);

Ref: http://leafletjs.com/examples/custom-icons/

Bis es eine gute Lösung für dieses Problem gibt, kann ich vorschlagen, eine Laufzeitwarnung hinzuzufügen, wenn _getIconUrl() (oder was auch immer) unerwartet auf eine Daten-Benutzeroberfläche stößt, die über console.warn oder so auf eine Github-Problem-URL verweist so wie das.

Das würde Leute mit dem gleichen Problem an die richtige Stelle bringen und Problemumgehungen vorschlagen (wie diese , die bei mir funktioniert hat).

Auf diese Weise hilft React (dev builds) Entwicklern, Probleme zu identifizieren.

Aus dem Reagieren-Problem eine Problemumgehung von @PTihomir

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

dies behebt das Problem, ohne dass die Kerndateien der Broschüre geändert werden.

@codeofsumit : Zu meinem Verständnis funktioniert diese

Die Problemumgehung muss angepasst werden, falls Leflet andere Symbole auf ähnliche Weise benötigt (oder in Zukunft benötigt) (vielleicht für andere Komponenten - ich weiß es nicht).


Für diejenigen, die mit Webpack nicht vertraut sind: Webpack weist diesen Eigenschaften neue URLs zu:

/***/ 5305024559067547:
/***/ function(module, exports, __webpack_require__) {

    module.exports = __webpack_require__.p + "d95d69fa8a7dfe391399e22c0c45e203.png";

/***/ },


...


    _leaflet2['default'].Icon.Default.mergeOptions({
      iconRetinaUrl: __webpack_require__(5305024559067547),
      iconUrl: __webpack_require__(6633266380715105),
      shadowUrl: __webpack_require__(880063406195787)
    });

(Details hängen stark von der verwendeten Webpack-Konfiguration ab)

@jampy ja natürlich. Daher ist es ein Workaround. Alle Änderungen am Merkblatt-Kern werden jedoch mit jedem Update gelöscht. Ich werde die erwähnte Problemumgehung verwenden, bis es eine richtige Lösung gibt, da es am wenigsten schmerzhaft zu sein scheint.

Das gleiche Problem hier, die Funktion detectIconPath gibt http://localhost:8080/2273e3d8ad9264b7daa5bdbf8e6b47f8.png") für den Pfad url("http://localhost:8080/2273e3d8ad9264b7daa5bdbf8e6b47f8.png")

Es ist alles andere als ideal, aber ich verwende Webpack und verwende diese Problemumgehung

Ich habe die Bilder in einen Bilderordner im Stammverzeichnis meines Projekts kopiert

dann habe ich in meiner package.json ein Postbuild-npm-Skript hinzugefügt (im Abschnitt Skripte)
" postbuild:prod ": "./Post-Build4Prod.sh"

das kopiert einen Bilderordner in die Dist

#bin/bash
cp -r ./images ./dist/.

dann definiere ich einen customDefault für Icons

    this.customDefault = L.icon({
        iconUrl: 'images/marker-icon.png',
        shadowUrl: 'images/marker-shadow.png',
    });

und benutze das überall

    L.marker([latitude, longitude], { icon: this.customDefault }).addTo(map);

@ajoslin103 , betrachten Sie diese Problemumgehung . Es ist einfacher und Sie erhalten das gleiche Ergebnis.

Ich habe Folgendes verwendet, um dies in einem Vue-Webpack-Projekt zu umgehen:

import L from 'leaflet';

L.Icon.Default.imagePath = '/';
L.Icon.Default.mergeOptions({
    iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
    iconUrl: require('leaflet/dist/images/marker-icon.png'),
    shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

Ich hatte das gleiche Problem mit Collectstatic und CachedStaticFilesStorage von Django, die einen Hash des Dateiinhalts zum Namen von statischen Dateien hinzufügen, also wird marker-icon.png zu marker-icon.2273e3d8ad92.png und dann zum regexp am Ende von _detectIconPath passt nicht zusammen.

Ich habe es in replace(/marker-icon[^"']+\.png[\"\']?\)$/, '') geändert, was für mich funktioniert hat.

Dieses Problem habe ich aktuell auch.
Mit Leaflet 1.0.3 und Angular2.
Ich gestehe, ich sehe in diesem Thread keine Lösung.

Für Winkel 2 & 4
Ich erstelle eine Datei require.d.ts mit dem Code:

interface WebpackRequire {
    <T>(path: string): T;
    (paths: string[], callback: (...modules: any[]) => void): void;
    ensure: (paths: string[], callback: (require: <T>(path: string) => T) => void) => void;
}
interface NodeRequire extends WebpackRequire {}
declare var require: NodeRequire;

und dann mit requirefür dieses Problem:

                  this.marker = L.marker(e.latlng, {
                    icon: L.icon({
                        iconUrl: require <any>('../../images/marker-icon.png'),
                        shadowUrl: require <any>('../../images/marker-shadow.png'),
                    })

Workaround (mit Größe & Anker) für Vue.js mit Webpack :

import L from 'leaflet'

// BUG https://github.com/Leaflet/Leaflet/issues/4968
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png'
import iconUrl from 'leaflet/dist/images/marker-icon.png'
import shadowUrl from 'leaflet/dist/images/marker-shadow.png'
L.Marker.prototype.options.icon = L.icon({
  iconRetinaUrl,
  iconUrl,
  shadowUrl,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  tooltipAnchor: [16, -28],
  shadowSize: [41, 41]
})

Ich habe einige schnelle Leistungstests durchgeführt, um das Standardsymbol als base64 im Vergleich zur Verwendung einer externen Bild-URL einzubetten. Beim Laden von _vielen_ Markern (in meinem Fall 1000) ist die Leistung für base64-inline-Bilder merklich schlechter.

Hier ist die Leistungsansicht der Chrome-Devtools beim Laden von 1000 Markierungssymbolen als externe URLs:

1000 markers icons as external URLs

Im Vergleich dazu mit 1000 Marker-Icons als inlined base64 (bitte andere Skalierung für Timeline beachten, sorry):

1000 markers icons as inlined base64 URLs

Wie zu sehen ist, verzögert sich der Ebenenaufbau bei Verwendung von Inline-Bildern aus irgendeinem Grund, wodurch der gesamte Ladevorgang etwa eine Sekunde länger dauert.

Für den gelegentlichen Gebrauch spielt dies wahrscheinlich keine Rolle, aber wenn Sie viele Marker verwenden, kann dies relevant sein.

Ein Vorschlag, wie man damit langfristig umgeht:

  • Fix #5041, um die in der Codeüberprüfung erwähnten Probleme zu beheben; Dies würde dazu führen, dass Inline-Symbole sofort funktionieren
  • Protokollieren Sie eine Warnung, wenn Inline-Symbole verwendet werden, um darauf hinzuweisen, dass dies möglicherweise nicht ideal ist

Eine andere Möglichkeit wäre, zur alten Methode (0.7) zum Erkennen des Bildpfads zurückzukehren, aber wir wissen, dass es andere Probleme gab, die wir nicht lösen konnten.

Hallo @perliedman ,

Schönes Profiling!
Es beantwortet die Zweifel, die ich in Bezug auf die Nachteile der Wiederverwendung von Inline-Bildern hatte.

Tatsächlich könnte PR #5041 umgestaltet werden, sodass Leaflet sofort funktionieren könnte, wenn Icon-Bilder in das CSS eingefügt werden (von einer Build-Engine wie Webpack).
Die Lösung, die mir einfällt (meistens ähnlich wie bei der erwähnten PR), würde bedeuten, eine Klasse pro Bild zu erstellen, wodurch die CSS- (und wahrscheinlich JS-) Dateigröße um einige Dutzend Bytes erhöht würde.

Beispiel: http://playground-leaflet.rhcloud.com/dulox/1/edit?html ,css,output

Aber wie ich bereits erwähnt habe , ist es bedauerlich, dass eine solche Änderung aus Kompatibilitätsgründen (mit Build-Engines) Benutzer betrifft, die diese Frameworks und Build-Prozesse nicht verwenden.

Auf der anderen Seite könnte das Ergebnis "sauberer" sein, da wir hartcodierte Dateinamen in den IconDefault Klassenoptionen loswerden und den vollständigen Pfad (einschließlich des Dateinamens) an das CSS delegieren könnten.
Dies ist sehr interessant, da (wenn ich das richtig verstehe) der Sinn dieser komplexen Erkennung darin besteht, den Speicherort der Bilder von der JS-Datei zu entkoppeln und sich stattdessen auf ihren relativen Speicherort zur CSS-Datei zu verlassen. Daher macht es für mich Sinn, dass sogar der Dateiname im CSS definiert ist.

Aber dann könnte es auch kompliziert sein, die Kompatibilität mit der Option imagePath aufrechtzuerhalten, da es wahrscheinlich eine Überarbeitung der zuvor erkannten Bildpfade erfordern würde, um den führenden Pfad zu ersetzen und den Dateinamen beizubehalten. Daher würden wir dort einen neuen RegExp einführen.

Schließlich bin ich mir nicht sicher, ob dies alle Fälle abdecken würde.
Build-Prozesse können stark angepasst werden, was zu sehr unterschiedlichen Situationen in Bezug auf statische Assets wie Symbolbilder führt. Es kann immer noch einige Eckfälle geben, in denen selbst das oben Genannte fehlschlagen würde.

@ghybs Ich mag dieses Beispiel ( http://playground-leaflet.rhcloud.com/dulox/)!

Vielleicht übertreibst du die Dinge, aber was hältst du davon, auch das Symbol _size_ in diesem CSS anzugeben (mit width und height )? Ich kann mir vorstellen, dass jemand diese CSS-Regeln überschreibt, um das Standardsymbol zu ändern, nur um festzustellen, dass es jetzt die falschen Abmessungen hat.

Mit oder ohne die Dimensionen in CSS, ich denke, das ist ein schöner Weg nach vorne. Möchten Sie eine PR nach Ihrem Vorbild machen? Wenn Sie gerade nicht die Zeit oder Energie haben, kann ich es tun, sagen Sie mir einfach, was Sie bevorzugen.

Ich möchte dieses Thema gerne schließen, da ich selbst zufällig über dieses Problem gestolpert bin.

Hallo @perliedman ,

Ich stimme zu, dass es noch besser wäre, auch die Symbolgröße über CSS angeben zu können.

Aber in diesem Fall sollten wir aus Konsistenzgründen auch den Ankerpunkt angeben können. Ich bin mir nicht sicher, welche CSS-Regel dafür geeignet wäre (vielleicht Margin?). Wenn das möglich ist, dann wäre das Ergebnis, wie ich finde, sehr schön: Die Icons wären komplett in CSS definiert.

Weitergehend könnte dies eine zusätzliche Möglichkeit sein, ein Symbol zu definieren: Geben Sie 3 CSS-Klassen an (Symbol, Netzhaut, Schatten) und Leaflet würde alle Symboloptionen daraus extrahieren.

Bitte zögern Sie nicht, daran zu arbeiten, ich bin mir leider nicht sicher, wann ich Zeit finden werde...

Aufbauend auf dem vorherigen Beispiel ist hier ein Konzept zum Lesen von padding und margin CSS-Regeln, um iconAnchor ( shadowAnchor ) und popupAnchor zu bestimmen Optionen:
http://playground-leaflet.rhcloud.com/xuvi/1/edit?html ,css,output

Ich mag die Tatsache nicht, dass ich padding , um die iconAnchor padding zu bestimmen, weil Leaflet am Ende margin um das Symbolbild zu positionieren…
Aber ich fand es am einfachsten, Dinge schnell in CSS anzugeben und das Zurücksetzen von Werten im Vergleich zu der Art, wie wir Symboloptionen angeben, zu vermeiden.

Obwohl mir das Ergebnis der Angabe von allem in CSS gefällt, ist noch mehr Arbeit erforderlich, um die Abwärtskompatibilität mit L.Icon.Default.imagePath aufrechtzuerhalten.

Ich entschuldige mich, dass ich keine Zeit habe, eine PR zu erstellen.

Ich habe gerade einen anderen Fall diagnostiziert, in dem _detectIconPath fehlschlägt: Wenn Sie Firefox verwenden (getestet mit ESR und aktuellen Versionen) und Einstellungen → Inhalt → Farben… → Überschreiben Sie die von der Seite angegebenen Farben mit Ihrer obigen Auswahl: Immer Firefox wird entfernen background-image Eigenschaften einschließlich der in .leaflet-default-icon-path und brechen somit _detectIconPath .

Ich bin mir nicht sicher, wie viele andere Leute diese Firefox-Funktion verwenden, aber ich benutze sie schon sehr lange.

Kann url() auch als Wert anderer CSS-Eigenschaften verwendet werden? Wie die Verwendung des folgenden CSS: .leaflet-default-icon-path { -leaflet-icon: url(images/marker-icon.png); } oder ist es unmöglich, benutzerdefinierte CSS-Eigenschaften selbst zu definieren und zu verwenden? Kein Browser müsste die Eigenschaft -leaflet-icon _verstehen_, sie müssten sie jedoch immer noch füllen und ihren Wert Skripten zur Verfügung stellen.

Hallo @roques ,

Vielen Dank, dass Sie dieses Problem bei Verwendung dieser speziellen Option in Firefox gemeldet haben!
Sieht so aus, als hätte Chrome eine High Contrast-Erweiterung , die jedoch nur die Farben ändert, ohne etwas im Leaflet zu beschädigen.

Leider entfernt Firefox CSS-Eigenschaften, die es nicht versteht.
Der Bild-CSS-Datentyp kann jedoch mit einigen anderen Regeln verwendet werden, einschließlich cursor , was auch dann gut zu funktionieren scheint, wenn die Einstellung zum Überschreiben von Farben in Firefox verwendet wird:
http://playground-leaflet.rhcloud.com/yov/1/edit?html ,css,output

Ich finde es weniger elegant, cursor anstelle von background-image , da seine Verwendung viel weiter von dem entfernt ist, was wir tun würden, um einen Marker durch CSS-Styling zu erstellen… aber das ist sowieso schon ein Hack für den Pfad nur Erkennung.

Ich wollte gerade eine PR machen, um das Webpack-Problem anzugehen. Ich werde diese Problemumgehung gleich hinzufügen.
Ich habe keine Ahnung, wie wir einen automatisierten Test für diesen Fall durchführen könnten, aber ich denke, der Workaround sollte bereits gut sein.

Hat jemand eine klare Lösung für dieses Problem gefunden?

Aufbauend auf der Antwort von @Shiva127 für alle, die Angular + Angular CLI verwenden:

Sie können dies in app.module.ts :

// BUG https://github.com/Leaflet/Leaflet/issues/4968
import {icon, Marker} from 'leaflet';
const iconRetinaUrl = 'assets/marker-icon-2x.png';
const iconUrl = 'assets/marker-icon.png';
const shadowUrl = 'assets/marker-shadow.png';
const iconDefault = icon({
  iconRetinaUrl,
  iconUrl,
  shadowUrl,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  tooltipAnchor: [16, -28],
  shadowSize: [41, 41]
});
Marker.prototype.options.icon = iconDefault;

und fügen Sie die Glob-Zeile in Ihre .angular-cli.json :

"assets": [
        "assets",
        "favicon.ico",
        { "glob": "**/*", "input": "../node_modules/leaflet/dist/images/", "output": "./assets/" }
      ],

Dadurch werden die Symbole zur Build-Zeit in den Ordner „assets“ im Ordner „dist“ kopiert (in src/assets werden sie nicht angezeigt). Außerdem ist es ein guter Ort, die Arbeit in app.module.ts lagern, um globale Prototypen-Änderungsimporte (wie RxJS-beobachtbare Patches) zu behalten. Damit funktioniert das Importieren von Marker an anderer Stelle in der Codebasis korrekt.

Ich habe dieses Problem so behoben.

Ich habe ein Standardsymbol für Marker drawOptions bereitgestellt:

const myIcon = L.icon({
    ...
    ...
});

const drawOptions = {
      ....
      marker: {
         icon: myIcon
      }
};

...

Dann gespeicherter Pfad zum Symbol auf L.Draw.Event.CREATED

this.map.on(L.Draw.Event.CREATED, (e) => {

      const layer: any = (e as L.DrawEvents.Created).layer;
      const type = (e as L.DrawEvents.Created).layerType;

      // Create a marker.
      if (type === 'marker') {

        let feature = layer.feature = layer.feature || {};
        feature.type = "Feature";
        feature.properties = feature.properties || {};
        feature.properties["markerIconsPath"] = "/assets/icons/";
       }
 });


Schließlich setze ich beim Anzeigen der Ebenen imagePath:

if(layer instanceof L.Marker) {
            L.Icon.Default.imagePath = layer.feature.properties.markerIconsPath;
            layer.setIcon(greenIcon);
 }

@codeofsumit sind diese Fixes in der neuesten Version 1.3.1 enthalten? Überraschenderweise verwende ich Version 1.3.1 und habe immer noch das gleiche Problem.

@vishalrajole meines Wissens ist die einzige PR, die eingereicht wurde, um dies zu

Wir haben auch die alternative Lösung #5771, die nett ist, aber mehr Änderungen beinhaltet.

Um es zusammenzufassen: Niemand hat eine akzeptierte PR eingereicht, um dies anzugehen, Hilfe ist willkommen!

@perliedman so wie es aussieht sind die beteiligten Änderungen von #5771 notwendig. Andernfalls wird dieses Problem unter anderen Umständen weiterhin auftreten. Warum das nicht einfach zusammenführen?

Hallo @mb21 ,

die damit verbundenen Änderungen von #5771 sind notwendig

Tatsächlich handelt es sich bei den vorgeschlagenen Änderungen um 2 Arten:

  • Lesen jedes Bildpfads statt nur des Bildordners, sodass URLs, die von Build-Engines (wie dem Webpack-Dateilader) geändert wurden, so gelesen werden, wie sie sind, anstatt rekonstruiert / erraten zu werden.
  • Lesen aller anderen Standardsymboloptionen von CSS, sodass die gesamte Konfiguration an einem einzigen Ort gesammelt wird.

Der 2. Punkt ist interessant, wenn sich der 1. nicht vermeiden lässt, auch wenn er einiges an Code hinzufügt.

Der erste ist eigentlich ein Gefallen für Entwickler, die eine Build-Engine verwenden, die mit URLs in CSS herumspielt. Es hält Leaflet _zero config spirit_ selbst in einer neuen Umgebung, in der der Entwickler einige Zeit damit verbringt, seine Konfiguration zu optimieren (wenn Sie den Webpack-Dateilader verwenden, benötigen Sie sowieso eine benutzerdefinierte Konfiguration), auf Kosten des Hinzufügens einiger Codes für alle anderen, was ist IMHO _gegen_ Leaflet-Geist (unterstützen die allgemeine Verwendung im Kern, delegieren Sie andere Anwendungsfälle an Plugins).
Sie können das Problem zunächst sehr einfach lösen, indem Sie die Bildpfade angeben, normalerweise mit require(image) wie in zahlreichen obigen Kommentaren gezeigt.

Obwohl ich diese PR verfasst habe, fühle ich mich daher persönlich unwohl, sie im Kern zusammenzuführen. Die Änderungen _sind für die Mehrheit nicht notwendig_.

Sie sind sicher nett, um das Leben der Entwickler zu erleichtern, aber das Problem wird hauptsächlich durch die Interaktion von Build-Engines / Framework-Wrappern verursacht, die alle ihre Besonderheiten haben und jeder eine einfache Möglichkeit bietet, Leaflet zu sagen, wo sich die Bilder jetzt befinden, indem die bereits vorhandenen verwendet werden API.

Vielleicht sollten wir dieses Problem eher mit einer besseren Dokumentation (zB einem Abschnitt über die Verwendung mit Build-Engines / Frameworks?) und/oder einem Plugin angehen?

Nun, ich bin mir nicht sicher, ob ich die Feinheiten verstehe. Aber es wäre sicher schön für alle möglichen Entwickler, wenn _alle_ Bildpfade in CSS angegeben werden könnten. Es sind nicht nur Webpack-Benutzer, sondern auch Leute wie ich, die die Rails- oder Django-Asset-Pipeline verwenden, die einen Hash an jedes statische Asset anhängt...

Ich habe genau das gleiche Problem erlebt:
data:image/png;base64,iVBORw0...AAAAAASUVORK5CYII=")marker-shadow.png net::ERR_INVALID_URL

Lösung ist zu ersetzen:

getIconUrl: function (name) {
        if (!IconDefault.imagePath) {   // Deprecated, backwards-compatibility only
            IconDefault.imagePath = this._detectIconPath();
        }

        // <strong i="8">@option</strong> imagePath: String
        // `Icon.Default` will try to auto-detect the location of the
        // blue icon images. If you are placing these images in a non-standard
        // way, set this option to point to the right path.
        return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name);
    },

mit:

 // ...
  const url = (this.options.imagePath || L.Icon.Default.imagePath);

  return url.slice(0, -2);

wie von codeofsumit vorgeschlagen.

Ich fand es wirklich ärgerlich und die Tatsache, dass es eine PR gibt, um das Problem zu beheben, aber nicht zusammengeführt, wegen des "Gefühls", dass "Die Änderungen für die Mehrheit nicht notwendig sind". Tut mir leid, aber ich habe gesehen, wie Leute in PHP, RoR, Python (Django) und node.js damit zu kämpfen haben, also wo ist Ihrer Meinung nach "die Mehrheit" außerhalb dieser Gruppen? Welches kompatible Framework würdet ihr empfehlen?

Ich stimme @macwis zu

Habe das gleiche Problem und dieser Thread ist sehr lang. Warum nicht die PR zusammenführen?

Das ist kein Gefühl, sondern Tatsache: Die meisten verwenden kein Framework oder solche, die nicht mit CSS herumspielen.
Als ich das letzte Mal nachgesehen habe, war Leaflet die Nr. 1, die von unpkg-CDN heruntergeladen wurde, dh entbündeltes und entfiddled CSS.

Die richtige Lösung besteht darin, die Standardsymboloptionen zu definieren, wie in vielen obigen Meldungen erläutert.
Viele Frameworks tun dies als Teil ihres Leaflet-Integrations-Plugins.

Wenn Sie eine automatischere Lösung wünschen, haben Sie immer noch die Möglichkeit, ein Plugin zu veröffentlichen.

Warum nicht die PR zusammenführen?

Lesen Sie die Kommentare, zB https://github.com/Leaflet/Leaflet/issues/4968#issuecomment -382639119

Ich möchte nur einen kleinen Hinweis hinzufügen: Sie können CDN auch verwenden, wenn Sie ein Framework verwenden. Das machen wir zum Beispiel mit unserer React App. Wir laden große Bibliotheken über CDN.

@googol7 danke für deinen Beitrag.

Bitte korrigieren Sie mich, wenn ich falsch liege: Wenn Sie Leaflet über das CDN laden, bedeutet dies sehr wahrscheinlich, dass Sie das CSS nicht ändern. Daher sind Ihre Benutzer in der Mehrheit.

@ghybs : Was ich tun musste, war Folgendes:

// Workaround: https://github.com/Leaflet/Leaflet/issues/4968#issuecomment-269750768
/* eslint-disable no-underscore-dangle, global-require */
delete L.Icon.Default.prototype._getIconUrl

L.Icon.Default.mergeOptions({
    iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
    iconUrl: require("leaflet/dist/images/marker-icon.png"),
    shadowUrl: require("leaflet/dist/images/marker-shadow.png"),
})
/* eslint-enable no-underscore-dangle, global-require */

unsere Webpack-Konfiguration sieht so aus:

module.exports = {
    externals: {
        leaflet: "L",
    },
}

@googol7 danke für die Details deiner Konfiguration.

Sie meinen also, dass Sie Leaflet JS aus dem CDN laden, aber CSS und Bilder in Ihrer App bündeln.

@ghybs ja, ich denke, das passiert hier.

Befolgen Sie unbedingt die ersten beiden Schritte: https://leafletjs.com/examples/quick-start/
Ich hatte ein ähnliches Problem, weil ich das CSS des Tutorials von jemand anderem verwendet habe, aber dieses muss verwendet werden

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>

und direkt danach das Leaflet-Skript

<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>

Hallo zusammen,

Ich habe das Leaflet-Plugin " leaflet-defaulticon-compatibility " veröffentlicht, das Code aus meiner PR https://github.com/Leaflet/Leaflet/pull/5771 nimmt.
Durch die Verwendung dieses Plugins versucht das Leaflet-Standardsymbol nicht mehr, die Symbolbildpfade neu zu erstellen, sondern verlässt sich vollständig auf das CSS. Auf diese Weise wird es vollständig kompatibel mit Build-Engines und Frameworks, die Assets basierend auf CSS automatisch verwalten (und normalerweise url() 's neu schreiben).

Laden Sie einfach das Plugin (CSS + JS) _nach_ Leaflet.
ZB im Webpack:

import 'leaflet/dist/leaflet.css'
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'
import * as L from 'leaflet'
import 'leaflet-defaulticon-compatibility'

( Demo )

Obwohl ich verstehen kann, dass viele Entwickler es vorgezogen hätten, diese Funktion direkt in den Leaflet-Kern zu integrieren, wurde argumentiert, dass der hinzugefügte Code für die Mehrheit der Endbenutzer nutzlos ist. Aus diesem Grund habe ich mich im Einklang mit dem Geist von Leaflet entschieden, den Kern einfach zu halten, und beschloss, es zu einem Plugin zu machen.

Bitte zögern Sie nicht, ein Problem im Plugin-Repository zu erstellen, wenn Sie Probleme oder Bedenken hinsichtlich der Funktionsweise haben.

Tatsache ist, dass Sie dieses Problem erhalten, wenn Sie Webpack verwenden. Ich sehe den Trend, dass immer mehr Websites Webpack verwenden. Dies als Plugin zu platzieren ist IMHO weniger als ideal, da ich nicht sehe, dass Leute nach einem Plugin suchen, um diese Art von Problem zu beheben (ähnlich wie ich es getan habe, als ich ein Dup geöffnet habe).
Ich würde diese Broschüre sehr gerne sehen, da es sich eher um eine Fehlerbehebung als um ein Feature handelt...

Wenn Sie dieses Problem in Angular 6 beheben möchten, geben Sie einfach angular.json :

 {
         "glob": "**/*",
         "input": "./node_modules/leaflet/dist/images/",
         "output": "./assets/leaflet/"
  }

Überschreiben Sie danach das Standardverhalten von Marker , wie einige der vorherigen Antworten vorschlagen:

import { Icon, icon, Marker, marker } from 'leaflet';

@Component({
   selector: 'app-something',
   templateUrl: './events.component.html',
   styleUrls: ['./events.component.scss']
})
export class SomeComponent implements OnInit {
  // Override default Icons
  private defaultIcon: Icon = icon({
    iconUrl: 'assets/leaflet/marker-icon.png',
    shadowUrl: 'assets/leaflet/marker-shadow.png'
  });

  ngOnInit() {
     Marker.prototype.options.icon = this.defaultIcon;
  }
}

Das Angular-Paket, das ich verwendet habe und das gleiche Problem wie hier hatte, ist: ngx-leaflet

HINWEIS:
Es gibt einen kleinen Haken in Angular 6, wie die Antwort von _t.animal_ auf StackOverflow sagt

Beachten Sie, dass es in Angular 6 zwei relevante Builder in den Architekten build und test .

Stellen Sie sicher, dass Sie es unter build .

@marko-jovanovic danke für die Info, aber was ist, wenn ich diese Assets nicht verwende und meine Paketgröße reduzieren möchte?
Ihr Vorschlag fällt immer noch unter meine Definition einer Problemumgehung, IMO.

@HarelM Nun, ich konnte keine andere Lösung finden, weil ich es eilig hatte, das Schulprojekt

@marko-jovanovic deine Lösung ist großartig und ich hoffe auch, dass sie anderen helfen kann. Ich hoffe nur auf eine Lösung, keinen Workaround :-)

@marko-jovanovic Hi, ich sitze auch an einem Schulprojekt (Angular 6) und kann nicht herausfinden, warum das Zeug bei mir nicht funktioniert. Um ehrlich zu sein, bin ich ein absoluter Noob für all diese Dinge hier.

Wenn ich Ihren Code in die ngOnInit -Funktion meiner Komponente einfüge, wird ein Fehler an dem Teil ausgegeben, in dem Sie iconUrl und shadowUrl :

Argument of type '{ iconUrl: (options: IconOptions) => Icon<IconOptions>; shadowUrl: any; }' is not assignable to parameter of type 'IconOptions'. Types of property 'iconUrl' are incompatible. Type '(options: IconOptions) => Icon<IconOptions>' is not assignable to type 'string'.

Verpasse ich etwas? Vielen Dank im Voraus!

@gittiker Ich habe eine Antwort mit den Importen, der Komponente und dem ngOnInit-Beispiel aktualisiert. Melde mich wenn alles gut gegangen ist. :)

@gittiker Ich habe eine Antwort mit den Importen, der Komponente und dem ngOnInit-Beispiel aktualisiert. Melde mich wenn alles gut gegangen ist. :)

Ja vielen Dank, endlich funktioniert es. Ich musste deine URL ein wenig manipulieren, damit es so ist
'assets/leaflet/images/marker-icon.png statt 'assets/leaflet/marker-icon.png', . Gleiches gilt für das Schattenbild.

@crob611 Vielen Dank, ich habe versucht, das Problem mit dieser Methode zu lösen.

@marko-jovanovic du hast mich gerettet! aber wie @HarelM sagt, gibt es keine Lösung?

vielen Dank, aber für mich hat es folgenden Code gedient: (Angular 6 und Faltblatt1.3.4)
Erster Schritt
(https://codehandbook.org/use-leaflet-in-angular/)
Aber dann wurde das Symbol nicht angezeigt
Fehler Symbolbild abrufen
net::ERR_INVALID_URL
lösen Sie es, indem Sie den folgenden Code in die Komponente einfügen
L.Icon.Default.prototype._getIconUrl löschen;`

L.Icon.Default.mergeOptions({
  iconRetinaUrl: '/assets/leaflet/dist/images/marker-icon-2x.png',
  iconUrl: '/assets/leaflet/dist/images/marker-icon.png',
  shadowUrl: '/assets/leaflet/dist/images/marker-shadow.png',
});`

Lösung nach Packungsbeilage 1.3.4 mit vue2-Beilage 1.2.3:

import { L, LControlAttribution, LMap, LTileLayer, LMarker, LGeoJson, LPopup } from 'vue2-leaflet'
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})

Meine 2 Cent: Mein Problem mit Webpack lag nur an den gehashten Dateinamen, also habe ich file-loader konfiguriert, um die Bilder der Broschüre nicht zu hashen:

use: [{
    loader: 'file-loader',
    options:
      {
        name(file) {
          console.log(file)
          if (file.match(/(layers-2x\.png|layers\.png|marker-icon\.png|marker-icon-2x\.png|marker-shadow\.png)/)) {
            return '[name].[ext]'
          }

          return '[name]-[hash].[ext]'
        },
        context: 'app/frontend' // <-- project specific
      }
  }]

Unhöfliches, aber effizientes AFAIK.

@ghybs danke für den Hotfix. Ich bin in verschiedenen Projekten ein paar Mal auf diesen Fehler gestoßen. Dieser gesamte Thread scheint absurd, dass er nicht behoben ist oder nicht als Problem angesehen wird.

Google hat mich hierher gebracht, weil bei der Verwendung der Bibliothek mit Webpack dieser Fehler aufgetreten ist.

Weiß jemand, warum diese Bilder nicht als SVG eingebettet sind?

Ich denke, dies könnte leicht mit postcss und postcss-inline-svg gelöst werden. Die Symbole würden zu Inline- svg Dateien anstelle von externen png . Die Symbole wären knackiger, wenn dieses Problem behoben ist.

Weiß jemand, warum diese Bilder nicht als SVG eingebettet sind?

Unterstützung für ältere Browser.

Danke @IvanSanchez

Dann sehe ich zwei mögliche Lösungen. Eine besteht darin, die Bilder als base64-kodiert .png einzubinden. Die andere Alternative besteht darin, .svg Symbole einzubinden und Entwickler, die auf Legacy-Plattformen abzielen, dazu zu bringen, die Standardsymbole zu überschreiben.

Ist eine dieser Lösungen einen Pull-Request wert?

Von allen Browsern, die von leaflet unterstützt werden, bieten die folgenden keine Unterstützung für svg ( caniuse ).

  • IE 7 und 8
  • Android-Browser 2.*

Inline die Bilder als base64

Siehe https://github.com/Leaflet/Leaflet/issues/4968#issuecomment -322422045

Musste auch Anker und Größe hinzufügen, damit es funktioniert, zB

   import icon from 'leaflet/dist/images/marker-icon.png';
   import iconShadow from 'leaflet/dist/images/marker-shadow.png';

   let DefaultIcon = L.icon({
      iconUrl: icon,
      shadowUrl: iconShadow,
      iconSize: [24,36],
      iconAnchor: [12,36]
    });

    L.Marker.prototype.options.icon = DefaultIcon; 

Ich habe auch das gleiche Problem (Webpack mit Flask, also sollten sich alle Elemente in einem statischen Ordner befinden), aber @giorgi-m Fix reicht nicht aus, da ich einen ''exports' is read-only' Fehler erhalte ( Firefox, scheint mit den PNG-Importen verknüpft zu sein?).
Ich sehe, dass das Problem behoben ist, aber wir sehen immer noch Probleme mit 1.4.0, also frage ich mich, was die Lösung ist.

Sehen dieses Problem mit vue2-Merkblatt 2.0.2 und Merkblatt 1.4.0.

dies scheint schon seit geraumer Zeit zu existieren, und die Hälfte der vorgestellten Lösungen scheint nicht zu funktionieren.

Hat jemand die Wurzel dieses Problems herausgefunden?

Ich habe das gleiche Problem mit den Versionen "vue2-leaflet": "2.0.3" leaflet "leaflet": "1.4.0".

läuft auch webpack.

Wir verwenden erfolgreich vue2-Merkblatt 2.0.3 und Merkblatt 1.4.0 mit einer Lösung, die in demselben Problem gefunden wurde:

import L from 'leaflet'
require('../../node_modules/leaflet/dist/leaflet.css')

// FIX leaflet's default icon path problems with webpack
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})

Ich denke, die bessere Frage, die gestellt werden muss, ist, warum dies nicht mit dem zusammengeführten Code behoben wurde, der dazu führte, dass das Problem geschlossen wurde? Da ein Workaround, der funktioniert, großartig ist, sollte dies jedoch sofort funktionieren und muss noch ein offenes Problem sein.

Hallo zusammen,

Leaflet funktioniert out-of-the-box.

Webpack (und andere Build-Engines) in Kombination mit Leaflet funktionieren nicht sofort einsatzbereit.

Siehe Lösungsvorschlag in https://github.com/Leaflet/Leaflet/issues/4968#issuecomment -399857656: leaflet- defaulticon

Obwohl ich verstehen kann, dass viele Entwickler es vorgezogen hätten, diese Funktion direkt in den Leaflet-Kern zu integrieren, wurde argumentiert, dass der hinzugefügte Code für die Mehrheit der Endbenutzer nutzlos ist. Aus diesem Grund habe ich mich im Einklang mit dem Geist von Leaflet entschieden, den Kern einfach zu halten, und beschloss, es zu einem Plugin zu machen.

Mit webpack, einer weiteren typischen Lösung , nachdem Sie Ihre Lader konfiguriert haben:

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

In diesem Thread werden weitere Lösungen für andere Build-Engines und Framework-Kombinationen vorgeschlagen.

Um zu verhindern, dass diese Lösungen weiter unter Kommentaren vergraben werden, werde ich diesen Thread sperren.

Vielen Dank für die gemeinsamen Lösungen! :+1:

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen