Filter features by zoom level of map - mapbox-gl-js

This is what I am trying to do in Mapbox GL JS (I am new to it): I have a spatial dataset of US cities. Each city has a ranking attribute (1-5). At the default zoom level, I want only the major cities (rank 1) to be visible. As the user gradually zooms in, I want the cities to appear based on their rank (2,3,4,5). This way, only when the user is at the max zoom level can even the smallest cities (rank 5) be visible.
I appreciate any help!

In the Mapbox style specification (filter property on layer object documentation) you can filter the features in the US Cities spatial dataset like so:
{
"id": "layer.us-cities,
...
"filter": [
">=", ["zoom"],
["match", ["get", "rank"],
1, // rank
10, // minimum zoom level
2, // etc.
15,
3,
18,
4,
20,
23 // fallback for ranks > 4
]
]
}
The filter consists of 2 parts:
The expression to compare the map's current zoom level against
The minimum zoom level needed for a city (vector tile feature) of a specific rank
For example: let's say the map's current zoom level is 17. Features with rank 1 (minimum zoom level 10) and rank 2 (min. zoom level 15) will be displayed on the map. From rank 3 onwards the minimum zoom level is at least 18 for which the equation mapZoomLevel >= "city zoom level by rank" doesn't satisfy.

filter={[
"all",
[
"match",
["get", "level"],
["2", "3", "4", "5"],
[">", ["zoom"], 12.1],
["<=", ["zoom"], 16],
],
]}

Related

How to show/hide labels according to zoom levels with expressions in mapbox-gl-js / maplibre-gl?

I have a point layer with an icon, and I would like to display the labels in addition to the icon only from a certain zoom level (9). I would like to avoid creating a dedicated label layer. Looking at the expression documentation, Stet and Zoom should give me the desired result, but it doesn't work.
Following this answer, I try to change the size of the text depending on the zoom level, but no matter the zoom, the text will always have the default size (here 7)
Am I missing something or is it a bug? I'm using Maplibre
layout: {
"icon-image": "border_crossing",
"icon-size": 0.5,
"icon-allow-overlap": true,
'text-field': ['get', 'loc_type'],
'text-variable-anchor': ['top'],
'text-radial-offset': 0.5,
'text-justify': 'auto',
"text-size": [ "step",
["zoom"],
0,0,
9,15,
7
]
}
There are various ways. One would be:
'text-field`: ["step", ["zoom"], "", 9, ["get", "loc_type"]]
It looks like you had a bug in your step code.

Highcharts Pyramid - same size of segments - despite the data value

I was wondering if it would be possible to ignore the sizes of segments in highcharts pyramid. I would like all segments to be of the same size despite the value. The reason is that sometimes differences between values may be quite significant and value of 1 - even being extremely important, becomes invisible when the next value is 500. Also, would like to be able to add a legend if possible. It would be nice to set a minimum size of a segment if not possible to get dynamic sizing disabled.
Thanks for your help!
Pawel
Yes, you can add additional data according to which the height of the segment will be calculated. Next, use keys option to map the values and show the right one in a tooltip and data label:
tooltip: {
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.realY}</b><br/>'
},
series: [{
...
keys: ['name', 'realY', 'y'],
dataLabels: {
format: '<b>{point.name}</b> ({point.realY:,.0f})',
...
},
data: [
['Website visits', 15654, 1],
['Downloads', 4064, 1],
['Requested price list', 1987, 1],
['Invoice sent', 976, 1],
['Finalized', 846, 1]
]
}]
Live demo: https://jsfiddle.net/BlackLabel/e83fatk2/
API Reference: https://api.highcharts.com/highcharts/series.column.keys

Changing icon offset based on zoom level

I am trying to offset symbols of a symbol layer so that they don't interfere with a previous symbol layer (i.e. they don't overlap). I need to offset them as in both cases icon-allow-overlap needs to be set to true, as the symbols need to be viewable at all zoom levels. Ideally I'd like to do something like this:
"icon-offset": [
["zoom"],
12, [-16, 0],
22, [0, 0]
]
but that gives me an error:
array length 2 expected, length 5 found
Is there a way I can do what I want similar to what I was trying above? I know that icon-offset is not transitionable so that is why the above is failing.
Any help would be appreciated.
Thanks for your time.
The answer was to use a function:
"icon-offset": {
"stops": [
[12, [-16, 0]],
[22, [0, 0]]
]
}
More info on this can be found here

MongoDB Schema for ecommerce products that have variations with different SKUs, prices and stock

My goal is to have products that have some basic information like
Name
Description
Brand/Manufacturer
Dimensions & Weight
And optionally each product can have options based on
Size
Color
Material
I've read a few articles but couldn't find a suitable answer for my problem, which is how to reflect that all those possible combinations of options can have different SKUs, prices and amounts in stock.
And additionally I'd like to have different images for different colors of a product.
So my current thought is to have separate collections for all the options:
Size
Color
Material
Then have arrays of pointers for all those options within the product document and and additional array of variations which reflects every possible combination of options and adds a SKU, price and stock field.
{
_id: "12345",
name: "My Product",
...
colors: [
{
_id: "Color_1",
images: [
"http://myserver.com/images/product_12345_1",
"http://myserver.com/images/product_12345_2",
]
},
{
_id: "Color_3",
images: [
"http://myserver.com/images/product_12345_3",
"http://myserver.com/images/product_12345_4",
]
}
],
sizes: [
{
_id: "Size_5"
},
{
_id: "Size_9"
}
],
materials: [
{
_id: "Material_2"
}
],
variations: [
{
color: "Color_1",
size: "Size_5",
material: "Material_2",
SKU: "98765"
price: 10,
stock: 2
},
{
color: "Color_1",
size: "Size_9",
material: "Material_2",
SKU: "87654"
price: 11,
stock: 5
},
...
],
}
But somehow I feel that there might be an easier way to accomplish what I'm looking for.
Data modelling of Product information is more an art than a science.
It is very common to define Products as the entities sales thinks about. Let's say a car model or a cable. E.g. a "cat 5e Ethernet cable".
Such a product has attributes and dimensions. Attributes might be
standard / norm (e.g. EIA/TIA-586)
Manufacturer (Kabelwerk Eupen)
Number of Wires (8)
Packaging (Plastic Bag)
Tags (Network, Ethernet, Cabling, Infrastructure)
RHoS (Compliant)
etc.
Attributes tend to vary between industries and even between different product categories in the same company.
Dimensions distinguish between different variants of a Product. One or more Dimensions can define a concrete Product. Typical Dimensions are size and colour. For cables, we might have:
size / length (0.5, 1, 2, 5, 10 meters)
colour (green, red, blue)
flame retardant (yes, no)
So Products are the concept of one of your merchandise. In a paper catalogue a Product usually is described as a single thing (maybe on a single page). E.g. a jacket available in blue and brown in sizes S, M, L and XL.
What defines a single Product is somewhat fuzzy. The blue and green sneaker might be the same Product, but the orange and the golden might not be seen as the same product.
Before E-Commerce, we tended to expect the same price for all Dimensions of a Product - not long ago, people were scandalized if a size 8 shoe would be more expensive than a size 9 shoe.
Along some dimensions - colour mostly - users usually except pictures. Along other dimensions - e.g. shoe size - usually there is no expectation of specific pictures.
With some products the manufacturer might be considered an Dimension (cables), for others it might be considered irrelevant (cable ties) and for others two identical looking goods from different manufacturers might be considered completely different Products (e.g. sneakers).
The other concept are SKUs - the stock keeping units are the stuff which is actually in the warehouse. Usually per Product we have Dimensions multiplied with each other SKUs. So 5 sizes x 3 colours x 2 fire retardant variants - so there could be 30 SKUs. Usually each SKU has a distinct GTIN/UPC/EAN ("Barcode" 4423456789012).
Keeping SKUs and Products separate is best practice because they are related to different concerns: Products are of importance for marketing and sales. SKUs concern auditing, bookkeeping and logistics. Products represent concepts, SKUs represent physical goods. Amount of stock usually should be kept in or near the SKU - because on large commerce applications it might get updated several times per second. I would never design a system where transaction data - amount of stock - is mixed up with master data - product description, etc.
Pricing information has been historically attached to the product because product and price data is somewhat static but dynamic pricing might change that.
You seem to be asking for a Product Database. Schemaless Databases work nicely for this because it is very hard to anticipate all needed dimensions for the next few years. Normalizing the whole thing for a Relational Database can certainly be done, but tents to result in less than elegant, and slowish code.
{
name: "Cat 5e Cable",
…
dimensions: {
color: {
title: "Color",
red: {
title: "Red",
images: [
"http://myserver.com/images/product_12345_3",
"http://myserver.com/images/product_12345_4",
],
},
green: { … }
},
size: {
title: "Size"
s05: {
title: "0.5 m",
images: [],
},
s1: {...},
fireretardant:
title: "Size"
yes: {
title: "fire retardant",
images: [],
},
no: {
title: "not fire retardant",
images: [],
}
}
// here you need a stable way of generating keys from dimension data
variations: [
{
dimensions: {color: red, size: s1, fireretardant: no}
SKU: "98765"
price: 10,
},
{
dimensions: {color: red, size: s1, fireretardant: yes}
SKU: "98765"
price: 10,
},
},
…
]
I have implemented applications with such a schema. Usually you want to limit available dimensions and valid values per dimension in the Admin GUI so staff does not come up with obscure new dimensions all the time. But this should be an administrative restriction, not one of the underlying schema.
Non-existent combinations ("fire retardant is only available in green and not in 0.5 m), conflicting instructions ("make all 5 m cables 10 € and all red ones 8 €"), differing and inconsistent ideas what e.g. needs a image, what images should be shared between Dimensions, inconsistent definitions, what considered a separate product ("USB C) or just a Variant ("3.5 mm or 5.5 mm headphone jack"), translation and conversion (don't get me started with shoe sizes) makes real life database design and maintenance interesting …
this is what the so-called "domain knowledge" is about. You need to involve a shoe salesman to design a good shoe database.

Large gaps in GFlot bar chart with value series

I use GFLot 2.4.3 with GWT 2.4 and have a problem regarding a series of values, NOT a time series. x-axis shows several IDs and y-axis shows the corresponding values as bars.
The problem is that these IDs have large gaps in their numbering, for example 1, 9, 47 or 128 and up to above 4000. In a bar chart this is plotted as seen on the following image:
Can I somehow deactivate these interpolation of points and get all bars aligned next to each other without gaps?
The only solution I could find is to use a TickFormatter.
Add your points to the model using constant gap as x-axis (1, 2, 3, 4, 5, etc.) and add a TickFormatter to the x-axis option :
plotOptions.addXAxisOptions( new AxisOptions().setTickFormatter( new TickFormatter() {
#Override
public String formatTickValue( double tickValue, Axis axis )
{
// return the label you want ("1", "9", "47", "128", "4000", etc.) for the tickValue (1, 2, 3, 4, 5, etc.)
}
} ) );