Vue2Leaflet: L.Icon.Default errors using vue-loader and webpack | Duplicated Marker

System Information | Affected Versions

leaflet: 1.0.3
vue2-leaflet: 0.0.47
vue: 2.2.6
chrome: 58.0.3029.81 (64-bit)

Description

In v.0.0.47, I have noticed an issue with the Marker component being duplicated/shadowed when rendered in the map.

Code

<v-map :zoom=15 :center="[organization.latitude, organization.longitude]">
    <v-tilelayer :token="mapboxAPIKey" url="https://api.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token={token}"></v-tilelayer>
    <v-marker :lat-lng="{'lat': organization.latitude, 'lng': organization.longitude}">
        <v-popup :content="organization.name"></v-popup>
    </v-marker>
</v-map>

edit: fixed code copy paste error

Fix

If I remove the transform: translate3d(395px, 200px, 0px) style from the img.leaflet-marker-icon, then the issue is resolved.

Edit: This change seems to move the “clickable” marker out of the pane, so it cannot be used as the trigger for a popup. The incorrect “fat” marker is the one that remains. I will look into other possible “full” resolutions.

Attachments

screen shot 2017-04-28 at 4 47 52 pm

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (6 by maintainers)

Most upvoted comments

I’ve got it working by deleting the _getIconUrl prototype first.

Here is my complete working component:

<template>
  <div>
    <v-map class="mini-map" :zoom=13 :center="[47.413220, -1.219482]">
      <v-tilelayer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"></v-tilelayer>
      <v-marker :lat-lng="[47.413220, -1.219482]"></v-marker>
    </v-map>
  </div>
</template>

<script>
import L from 'leaflet'
import Vue2Leaflet from 'vue2-leaflet'

// Build icon assets.
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.imagePath = ''
L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('../assets/markers/marker-icon-2x.png'),
  iconUrl: require('../assets/markers/marker-icon.png'),
  shadowUrl: require('../assets/markers/marker-shadow.png')
})

export default {
  components: {
    'v-map': Vue2Leaflet.Map,
    'v-tilelayer': Vue2Leaflet.TileLayer,
    'v-marker': Vue2Leaflet.Marker
  }
}
</script>

<style lang="scss">
@import "~leaflet/dist/leaflet.css";

.mini-map {
  width:100%;
  height:250px !important;
}
</style>

Okay, I found where the Leaflet people are discussing this issue with webpack: https://github.com/Leaflet/Leaflet/issues/4968

They proposed this solution:

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

@MichalKrakow @KoRiGaN

I can confirm that my issue has been fixed by adding the following code to one of my single file components:

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

I assume that this would break the normal browser use case if this change was made to the repo. Do ya’ll think we should just close this ticket and leave it to the Leaflet/Webpack community to come up with a better fix on their ends?

Thanks a ton for the help guys!

If I set display:none on leaflet-pane leaflet-shadow-pane, the incorrect marker will disappear.

with me: `import Vue2Leaflet from ‘vue2-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’), });`

did the trick. Probably it’s not best practise to keep relative path in js but it have to do for now.

There’s now a plug-in, at the Leaflet level, to solve this: https://github.com/ghybs/leaflet-defaulticon-compatibility.

It’s working well for me. And I’m also using Vue2Leaflet.

Maybe it’s worth adding it to the docs?

I’ve setup my project using laravel mix (basically webpack with some extra config on top of it) the shadow image url is: http://localhost:3000/images/vendor/leaflet/dist/marker-icon.png?2273e3d8ad9264b7daa5bdbf8e6b47f8&quot;)marker-shadow.png so it uses the icon as shadow 😃.

With this level of f.ups i think webpack will not be here for very long. So if it looks familiar to someone please throw a hint.