2012-06-29 02:59:14 +08:00
# CartoCSS
2011-02-01 06:34:10 +08:00
2012-06-19 05:11:47 +08:00
[![Build Status ](https://secure.travis-ci.org/mapbox/carto.png )](http://travis-ci.org/mapbox/carto)
2012-05-22 02:07:14 +08:00
Is a stylesheet renderer for Mapnik. It's an evolution of the
[Cascadenik ](https://github.com/mapnik/Cascadenik ) idea and language,
with an emphasis on speed and flexibility.
2011-02-01 06:34:10 +08:00
2012-05-22 02:07:14 +08:00
## Reference Documentation
2011-02-03 06:26:38 +08:00
2012-05-22 02:07:14 +08:00
* [mapbox.com/carto ](http://mapbox.com/carto/ )
2011-02-03 06:26:38 +08:00
2011-02-01 06:34:10 +08:00
## MML
_incompatibility_
2012-05-22 02:07:14 +08:00
* MML files are assumed to be JSON, not XML. The files are near-identical
to the XML files accepted by Cascadenik, just translated into JSON.
2012-06-29 02:59:14 +08:00
* CartoCSS will not embed files or download URLs for you. Stylesheets should
2012-05-22 02:07:14 +08:00
be embedded directly into your MML JSON and any datasources should be
paths (relative or absolute) that would be acceptable in Mapnik XML.
2011-09-09 01:27:23 +08:00
The [millstone project ](https://github.com/mapbox/millstone ) aims to fill this need.
2011-02-01 06:34:10 +08:00
2012-10-10 09:44:59 +08:00
CartoCSS MML:
2011-02-03 05:58:33 +08:00
{
2012-03-08 04:42:16 +08:00
"srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
2011-02-03 05:58:33 +08:00
"Stylesheet": [{"id":"style.mss","data":"Map {\n background-color: #fff ;\n}\n\n#world {\n line-color: #ccc ;\n line-width: 0.5;\n polygon-fill: #eee ;\n}"}],
"Layer": [{
"id": "world",
"name": "world",
"srs": "+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs",
"Datasource": {
"file": "world_borders",
"type": "shape"
}
}]
}
Cascadenik MML
2011-02-01 23:04:41 +08:00
< pre > < Stylesheet> < ![CDATA[
2012-10-10 09:42:40 +08:00
Map {
2011-02-03 05:58:33 +08:00
map-bgcolor: #69f ;
}
2011-02-01 23:04:41 +08:00
2012-10-10 09:42:40 +08:00
Layer {
2011-02-03 05:58:33 +08:00
line-width: 1;
line-color: #696 ;
polygon-fill: #6f9 ;
}
]]> < /Stylesheet>
< Layer srs=" +proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs" >
< Datasource>
< Parameter name=" type" > shape< /Parameter>
< Parameter name=" file" > world_borders< /Parameter>
< /Datasource>
< /Layer>
2011-02-01 23:04:41 +08:00
< /Map> < / pre >
2011-02-01 06:34:10 +08:00
2011-09-12 17:05:49 +08:00
## Attachments and Instances
2011-02-01 06:34:10 +08:00
_new_
2012-10-10 09:44:59 +08:00
In CSS, a certain object can only have one instance of a property. A `<div>` has a specific border width and color, rules that match better than others (#id instead of .class) override previous definitions. `CartoCSS` acts the same way normally for the sake of familiarity and organization, but Mapnik itself is more powerful.
2011-02-01 06:34:10 +08:00
2012-10-10 09:44:59 +08:00
Layers in Mapnik can have multiple [borders ](http://trac.mapnik.org/wiki/LineSymbolizer ) and multiple copies of other attributes. This ability is useful in drawing line outlines, like in the case of road borders or 'glow' effects around coasts. `CartoCSS` makes this accessible by allowing attachments to styles:
2011-02-01 06:34:10 +08:00
#world {
line-color: #fff ;
line-width: 3;
}
#world::outline {
line-color: #000 ;
line-width: 6;
}
2012-10-10 09:44:59 +08:00
Attachments are optional: if you don't define them, CartoCSS does overriding of styles just like Cascadenik.
2011-02-01 06:34:10 +08:00
This brings us to another _incompatibility_ : `line-inline` and `line-outline` have been removed from the language, because attachments are capable of the same trick.
2011-09-12 17:05:49 +08:00
While attachments allow creating implicit "layers" with the same data, using **instances** allows you to create multiple symbolizers in the same style/layer:
#roads {
casing/line-width: 6;
casing/line-color: #333 ;
line-width: 4;
line-color: #666 ;
}
This makes Mapnik first draw the line of color #333 with a width of 6, and then immediately afterwards, it draws the same line again with width 4 and color #666 . Contrast that to attachments: Mapnik would first draw all casings before proceeding to the actual lines.
2011-02-01 06:34:10 +08:00
## text-name
_incompatibility_
2011-02-01 23:04:41 +08:00
Instead of the name attribute of the [TextSymbolizer ](http://trac.mapnik.org/wiki/TextSymbolizer ) and [ShieldSymbolizer ](http://trac.mapnik.org/wiki/ShieldSymbolizer ) being a part of the selector, it is a property of a rule. Thus the evaluation is less complex and one can use expressions in names.
2011-02-01 06:34:10 +08:00
< table >
< tr >
< th > cascadenik< / th >
2012-10-10 09:44:59 +08:00
< th > CartoCSS< / th >
2011-02-01 06:34:10 +08:00
< / tr >
< tr >
2011-02-03 05:58:33 +08:00
< td valign = 'top' >
2011-02-01 06:34:10 +08:00
< pre >
#world NAME {
text-face-name: "Arial";
}< / pre >
< / td >
2011-02-03 05:58:33 +08:00
< td valign = 'top' >
2011-02-01 06:34:10 +08:00
< pre >
#world {
text-name: "NAME";
text-face-name: "Arial";
}< / pre >
< / td >
< / tr >
< / table >
## Mapnik2
2011-02-01 06:41:48 +08:00
_new_
2011-02-01 06:34:10 +08:00
2012-10-10 09:42:40 +08:00
CartoCSS is only compatible with [Mapnik2 ](http://trac.mapnik.org/wiki/Mapnik2 ). Compatibility with Mapnik 0.7.x is not planned.
2011-02-01 06:34:10 +08:00
## Rasters and Buildings
2011-02-01 06:41:48 +08:00
_new_
2011-02-01 06:34:10 +08:00
2012-10-10 09:44:59 +08:00
Rasters are supported in CartoCSS - it knows how to download `.vrt` , `.tiff` , and soon other raster formats, and the properties of the [RasterSymbolizer ](http://trac.mapnik.org/wiki/RasterSymbolizer ) are exposed in the language.
2011-02-01 06:34:10 +08:00
2012-10-10 09:44:59 +08:00
The [BuildingSymbolizer ](http://trac.mapnik.org/wiki/BuildingSymbolizer ) is also supported in `CartoCSS` . The code stores symbolizer types and properties in a JSON file (in `tree/reference.json` ), so new Mapnik features can be quickly implemented here.
2011-02-01 06:34:10 +08:00
## Variables & Expressions
2011-02-01 06:41:48 +08:00
_new_
2011-02-01 06:34:10 +08:00
2012-10-10 09:42:40 +08:00
CartoCSS inherits from its basis in [less.js ](http://lesscss.org/ ) some new features in CSS. One can define variables in stylesheets, and use expressions to modify them.
2011-02-01 06:34:10 +08:00
@mybackground: #2B4D2D ;
Map {
background-color: @mybackground
}
#world {
polygon-fill: @mybackground + #222 ;
line-color: darken(@mybackground, 10%);
}
2011-02-01 23:04:41 +08:00
## Nested Styles
_new_
2012-10-10 09:42:40 +08:00
CartoCSS also inherits nesting of rules from less.js.
2011-02-01 23:04:41 +08:00
/* Applies to all layers with .land class */
.land {
line-color: #ccc ;
line-width: 0.5;
polygon-fill: #eee ;
/* Applies to #lakes .land */
#lakes {
polygon-fill: #000 ;
}
}
This can be a convenient way to group style changes by zoom level:
[zoom > 1] {
/* Applies to all layers at zoom > 1 */
polygon-gamma: 0.3;
#world {
polygon-fill: #323 ;
}
#lakes {
polygon-fill: #144 ;
}
}
2011-02-01 06:34:10 +08:00
## FontSets
2012-10-10 09:42:40 +08:00
2011-02-01 06:41:48 +08:00
_new_
2011-02-01 06:34:10 +08:00
2012-10-10 09:44:59 +08:00
By defining multiple fonts in a `text-face-name` definition, you create [FontSets ](http://trac.mapnik.org/wiki/FontSet ) in `CartoCSS` . These are useful for supporting multiple character sets and fallback fonts for distributed styles.
2011-02-01 06:34:10 +08:00
2011-02-01 06:41:48 +08:00
< table >
< tr >
2011-02-08 00:22:14 +08:00
< th > carto< / th > < th > XML< / th >
2011-02-01 06:41:48 +08:00
< / tr >
< tr >
2011-02-03 05:58:33 +08:00
< td valign = 'top' >
2011-02-01 06:41:48 +08:00
< pre > #world {
text-name: "[NAME]";
text-size: 11;
text-face-name: "Georgia Regular", "Arial Italic";
}< / pre >
2011-02-03 05:58:33 +08:00
< / td >
< td valign = 'top' >
2011-02-01 06:41:48 +08:00
< pre > < FontSet name=" fontset-0" >
2011-02-08 01:50:41 +08:00
< Font face-name=" Georgia Regular" />
< Font face-name=" Arial Italic" />
2011-02-01 06:41:48 +08:00
< /FontSet>
< Style name=" world-text" >
< Rule>
2011-02-08 01:50:41 +08:00
< TextSymbolizer fontset-name=" fontset-0"
2011-02-01 06:41:48 +08:00
size=" 11"
name=" [NAME]" />
< /Rule>
< /Style> < / pre >
< / td >
< tr >
< / table >
2012-05-09 03:44:30 +08:00
## Filters
2012-06-29 02:59:14 +08:00
CartoCSS supports a variety of filter styles:
2012-05-09 03:44:30 +08:00
Numeric comparisons:
```
#world[population > 100]
#world[population < 100]
#world[population >= 100]
#world[population <= 100]
```
General comparisons:
```
#world[population = 100]
#world[population != 100]
```
String comparisons:
```
/* a regular expression over name */
#world[name =~ "A.*"]
```
2011-02-01 06:34:10 +08:00
2012-05-22 02:07:14 +08:00
## Developers
#### Installation
If you're using [TileMill ](http://mapbox.com/tilemill/ ), you're already
2012-06-29 02:59:14 +08:00
using CartoCSS and don't need to do a thing.
2012-05-22 02:07:14 +08:00
If you're a developer-type and want to use the `carto` binary with
`node.js` (and you have [npm ](http://npmjs.org/ ) installed),
npm install carto
2011-02-01 06:34:10 +08:00
2012-05-22 02:07:14 +08:00
#### From the binary
2011-02-01 06:34:10 +08:00
2011-08-03 23:50:08 +08:00
Install `millstone` to enable support for localizing external resources (URLs and local files) referenced in your mml file.
npm install millstone
2011-02-08 23:09:47 +08:00
carto map_file.json
2011-02-01 06:34:10 +08:00
2012-05-22 02:07:14 +08:00
#### From code
2011-02-03 06:08:05 +08:00
2012-10-10 09:42:40 +08:00
Currently CartoCSS is designed to be invoked from [node.js ](http://nodejs.org/ ).
2011-02-03 06:08:05 +08:00
The `Renderer` interface is the main API for developers, and it takes an MML file as a string as input.
// defined variables:
// - input (the name or identifier of the file being parsed)
// - data (a string containing the MML or an object of MML)
2011-02-08 00:22:14 +08:00
var carto = require('carto');
2011-02-03 06:08:05 +08:00
2011-02-08 00:22:14 +08:00
new carto.Renderer({
2011-02-03 06:08:05 +08:00
filename: input,
local_data_dir: path.dirname(input),
}).render(data, function(err, output) {
if (err) {
if (Array.isArray(err)) {
err.forEach(function(e) {
2011-02-08 00:22:14 +08:00
carto.writeError(e, options);
2011-02-03 06:08:05 +08:00
});
} else { throw err; }
} else {
sys.puts(output);
}
});
2012-01-06 00:17:49 +08:00
### Vim
To install, download or clone this repository, then add the `vim-carto`
directory located at `build/vim-carto` to your `~/.vim` file.
2011-02-03 06:29:04 +08:00
## Credits
2012-10-10 09:42:40 +08:00
CartoCSS is based on [less.js ](https://github.com/cloudhead/less.js ), a CSS compiler written by Alexis Sellier.
2011-02-03 06:29:04 +08:00
2011-02-07 23:07:40 +08:00
It depends on:
2011-02-03 06:29:04 +08:00
* [underscore.js ](https://github.com/documentcloud/underscore/ )
2011-02-07 23:07:40 +08:00
Only for running tests:
2012-05-22 02:07:14 +08:00
* [mocha ](https://github.com/visionmedia/mocha )
2011-02-07 23:07:40 +08:00
* [sax-js ](https://github.com/isaacs/sax-js/ )
2011-02-03 06:29:04 +08:00
2011-02-01 06:34:10 +08:00
## Authors
* Tom MacWright (tmcw)
* Konstantin Käfer (kkaefer)
2011-02-01 23:04:41 +08:00
* AJ Ashton (ajashton)
2012-05-22 02:07:14 +08:00
* Dane Springmeyer (springmeyer)