How to have different filters based on region in CartoCSS stylesheets?

For some object types I’d like to have different filters based on the region. For example: in a mountainous region like the Alps I might show only peaks over 3800m. In a less mountainous region I might want to show peaks over 1000m. I’m using CartoCSS stylesheets with KOSMTIK and Mapnik. Alternatively are there other ways to display an object type without having “too many” appear. My current thinking is to preprocess and add my own “score” to items.

You cannot do this in CartoCSS but you can modify the underlying SQL queries in the .mml file.

Example:

Your query for peaks:

SELECT
    name, ele, way
  FROM planet_osm_point
  WHERE "natural" = 'peak'
  ORDER BY ele DESC NULLS LAST;

Your table of mountainous regions:

CREATE TABLE mountainous_regions (gid INTEGER, geom Geometry(Geometry, 3857));

Joining them:

SELECT
    name,
    ele,
    way,
    m.geom IS NULL AS is_mountainous
  FROM planet_osm_point AS p
  LEFT OUTER JOIN mountainous_regions AS m
    ON ST_Intersects(p.way, m.geom)
  GROUP BY name, ele, is_mountainous, way
  ORDER BY ele DESC NULLS LAST;

A left outer join instead of an inner join is required if you want to get all peaks, not only those peaks intersecting with the polygons of table mountainous_regions. GROUP BY is necessary if a peak could intersect multiple geometries in mountainous_regions (e.g. overlapping polygons).

To avoid a low performance, you should use spatial indexes:

CREATE INDEX mountainous_regions_geom_idx ON mountainous_regions USING gist(geom);
CREATE INDEX planet_osm_point_peak_idx ON planet_osm_point USING gist(way) WHERE "natural" = 'peak';

In addition, you should avoid geometries with many vertices in mountainous_regions or split them into smaller areas.

However, I guess that scoring and a SELECT statement with ORDER BY could lead to better results.

This is fantastic! Thanks.