4

I'm using the angular-leaflet-directive and geojson to create map markers using leaflet and mapbox. The popups on the markers aren't correctly aligned on the marker.

offset problem

angular.extend($scope, { // Map data
                geojson: {
                    data: $scope.filteredShows,
                    onEachFeature: function (feature, layer) {
                        layer.bindPopup(feature.properties.artist + ' · ' + feature.properties.venue);
                        layer.setIcon(defaultMarker);
                        layer.on({
                            mouseover: pointMouseover,
                            mouseout: pointMouseout
                        });
                        layers[feature.properties.id] = layer;
                    }
                }

            });

How do I change the offset on the markers?

Kyle Pennell
  • 5,747
  • 4
  • 52
  • 75

2 Answers2

7

Using popupAnchor: [-10, -10], in L.Icon. See http://leafletjs.com/reference.html#icon

vitalik_74
  • 4,573
  • 2
  • 19
  • 27
0

If you're using the default images, but they're placed at a different location with different filenames because you're using a Rails server to serve the assets, for example, here's a tip so you don't have to hard code in the values from the default icon.

In my case, I injected the actual values into the proper location.

<script type="text/javascript">
  var injectedData = {
    paths: {
      leafletIcon: {
        iconRetinaUrl: '<%= image_url "leaflet-1.3.4/marker-icon-2x.png" %>',
        iconUrl: '<%= image_url "leaflet-1.3.4/marker-icon.png" %>',
        shadowUrl: '<%= image_url "leaflet-1.3.4/marker-shadow.png" %>',
      },
    },
  };
</script>

Then, I created an instance of Icon that uses the default values for image offsets directly from the Icon.Default prototype.

import { Icon } from 'leaflet';

const defaultIcon = new Icon({
  ...Icon.Default.prototype.options,
  ...injectedData.paths.leafletIcon,
});

That's the same as injecting your data directly. Do as is appropriate for your particular use case.

const defaultIcon = new Icon({
  ...Icon.Default.prototype.options,
  {
    iconRetinaUrl: "/assets/leaflet-1.3.4/marker-icon-2x-00179c4c1ee830d3a108412ae0d294f55776cfeb085c60129a39aa6fc4ae2528.png",
    iconUrl: "/assets/leaflet-1.3.4/marker-icon-574c3a5cca85f4114085b6841596d62f00d7c892c7b03f28cbfa301deb1dc437.png",
    shadowUrl: "/assets/leaflet-1.3.4/marker-shadow-264f5c640339f042dd729062cfc04c17f8ea0f29882b538e3848ed8f10edb4da.png",
  },
});

In my case, I was using the react-leaflet library with React, not Angular, but I'm sure you can adapt your use-case appropriately. In my case, I used the defaultIcon as a prop for the Marker component.

<Map center={position} zoom={zoom}>
  <TileLayer
    attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
  />
  <Marker icon={defaultIcon} position={position}>
    <Popup>
      <span>{this.props.location}</span>
    </Popup>
  </Marker>
</Map>

I know this doesn't answer your question directly, but your question and vitalik_74's answer got me on the road to what I needed for my particular use-case, which was an easy but reliable way to provide different image URLs for the default icon set (including altered filenames) while also reusing the default offset numbers without having to hard code them in. I hope my answer can help someone else who comes across this question with this issue in the future.