Reputation: 93
I've been trying to get the same layer as you can see here. But I can't find a right type and options for it. For now I was only using a circle, but I can't give a different padding to X and Y axis.
This is the expected layer (For unclustered-point)
And this is my code:
map.addLayer({
id: 'unclustered-point',
type: 'circle',
source: 'places',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#486fd1',
'circle-radius': 20,
}
});
map.addLayer({
id: 'unclustered-point-count',
type: 'symbol',
source: 'places',
filter: ['!', ['has', 'point_count']],
layout: {
'text-field': ['get', 'price'],
'text-font': ['DIN Offc Pro Bold'],
'text-size': 11,
},
paint: {
'text-color': "#fff",
}
});
And this is what I have at the moment:
Upvotes: -1
Views: 722
Reputation: 1
You need to use a stretchable image as a background for text: https://docs.mapbox.com/mapbox-gl-js/example/add-image-stretchable/
Upvotes: 0
Reputation: 11
I had a similar case, I didn't find a way to do it with a mapbox SDK, so I decided to dig other ways and that's how I solved it:
Also, it'll look pixelized on MacBooks and iPhones because of the device pixel ratio, so we need to consider this
const dpr = window.devicePixelRatio;
const getRoundedRectangleImage = async ({color, width, height, radius}) => {
// Make the image not pixelized on devices with high DPR
const canvas = document.createElement('canvas');
canvas.width = width * dpr;
canvas.height = height * dpr;
const ctx = canvas.getContext('2d')!;
ctx.scale(dpr, dpr);
// Draw a rounded rectangle
ctx.fillStyle = color;
ctx.beginPath();
ctx.roundRect(0, 0, width, height, [radius]);
ctx.fill();
const image = await createImageBitmap(canvas);
return image;
}
// ...
// Add the image to the map
getRoundedRectangleImage({
width: 68,
height: 36,
color: '#486fd1',
radius: 100,
}).then((image) => {
map.addImage('rounded-rectangle', image);
});
// Add layer to display rounded rectangles
map.addLayer({
id: 'rounded-rectangle-layer',
type: 'symbol',
source: 'YOUR_SOURCE',
filter: ['!', ['has', 'point_count']],
layout: {
'icon-image': 'rounded-rectangle',
'icon-size': 1 / dpr, // compensate device pixel ratio
'icon-allow-overlap': true,
'text-allow-overlap': true,
},
});
// Display text over rounded rectangles
map.addLayer({
id: 'count-text',
type: 'symbol',
source: 'YOUR_SOURCE',
filter: ['!', ['has', 'point_count']],
layout: {
'text-field': ['get', 'price'],
'text-font': ['DIN Offc Pro Medium'],
'text-size': 11,
'text-justify': 'center',
},
paint: {
'text-color': '#fff',
},
});
Upvotes: 1
Reputation: 41
Not sure but I think this can work.
'circle-radius': {
'base': 1,
'stops': [[0, 10], [20, 30]]
},
Upvotes: -1