GithubHelp home page GithubHelp logo

mapbox / carto Goto Github PK

View Code? Open in Web Editor NEW
655.0 156.0 129.0 20.72 MB

fast CSS-like map stylesheets

Home Page: https://cartocss.readthedocs.io/

License: Apache License 2.0

JavaScript 75.71% CartoCSS 20.54% Vim Script 3.75%
cartocss javascript mapnik mml

carto's Introduction

CartoCSS

Build Status Build status Coverage Status Package Version Dependencies Documentation Status

CartoCSS (short: Carto) is a language for map design. It is similar in syntax to CSS, but builds upon it with specific abilities to filter map data and by providing things like variables. It targets the Mapnik renderer and is able to generate Mapnik XML and a JSON variant of Mapnik XML. It can run from the command line or in the browser.

Carto is an evolution of the Cascadenik idea and language, with an emphasis on speed and flexibility.

Documentation

The best place to start is to review the CartoCSS documentation.

Tutorials like the Mapbox Getting started with CartoCSS guide are a great place to start to learn the basics of CartoCSS.

For more advanced topics see the Studio style quickstart guide and Studio style manual. The links below reference the Tilemill application, which preceded Mapbox Studio Classic, but still contain useful and relevant information.

Installation

If you are using a map design application like Kosmtik, Mapbox Studio Classic or Tilemill you already have CartoCSS installed and might be more interested in the language reference.

Else you can install the carto binary with NPM by running:

npm install -g carto

You should consider using a Node.js version manager like NVM. Optionally you may also want to install millstone which is required for resolving data in the same way as Mapbox Studio Classic does:

npm install -g millstone

Having millstone installed specifically enable support for localizing external resources (URLs and local files) referenced in your mml file, and detecting projections (using node-srs)

Usage

Now that Carto is installed you should have a carto command line tool available that can be run on a CartoCSS project:

carto project.mml > mapnik.xml

Available parameters:

  • -a / --api VERSION - Specify Mapnik API version (e.g. --api 3.0.10) (default: latest Mapnik API version)
  • -b / --benchmark - Outputs total compile time
  • -f / --file - Outputs to the specified file instead of stdout
  • -h / --help - Display help message
  • -l / --localize - Use millstone to localize resources when loading an MML (default: off)
  • -n / --nosymlink - Use absolute paths instead of symlinking files
  • -o / --output - Specify output format, possible values are mapnik and json (default: mapnik)
  • -ppi RESOLUTION - Pixels per inch used to convert m, mm, cm, in, pt, pc to pixels (default: 90.714)
  • -q / --quiet - Do not output any warnings (default: off)
  • -v / --version - Display version information

Alternatively, Carto can be used from JavaScript. 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)
var carto = require('carto');

try {
    var data = fs.readFileSync(input, 'utf-8');
    var mml = new carto.MML({});
    mml.load(path.dirname(input), data, function (err, data) {
        var output = {};

        if (!err) {
            output = new carto.Renderer({
                filename: input
            }).render(data);
        }

        if (output.msg) {
            output.msg.forEach(function (v) {
                if (v.type === 'error') {
                    console.error(carto.Util.getMessageToPrint(v));
                }
                else if (v.type === 'warning') {
                    console.warn(carto.Util.getMessageToPrint(v));
                }
            });
        }

        // output content (if no errors)
        if (output.data) {
            console.log(output.data);
        }
    });
} catch (err) {
    // program failures
    ...
}

If you want to use CartoCSS within the browser you should not use MML loading via carto.MML.load. Instead you should supply the JSON of the MML including the Stylesheet strings directly to carto.Renderer.render.

Vim

To install, download or clone this repository, then copy the vim-carto directory located at build/vim-carto to your ~/.vim directory.

cp build/vim-carto/* ~/.vim -R

Credits

CartoCSS is based on less.js, a CSS compiler written by Alexis Sellier.

See also a list of dependencies.

Similar projects

  • Magnacarto (Go implementation of CartoCSS for Mapnik and Mapserver)

Authors

  • Tom MacWright (tmcw)
  • Konstantin Käfer (kkaefer)
  • AJ Ashton (ajashton)
  • Dane Springmeyer (springmeyer)
  • Michael Glanznig (nebulon42)

carto's People

Contributors

ajashton avatar c0nk avatar danzel avatar dbergey avatar dboze avatar dependabot[bot] avatar felixge avatar flippmoke avatar glarrain avatar gravitystorm avatar hiddewie avatar indutny avatar jamesfoster avatar kant avatar kapouer avatar kkaefer avatar midnightcomm avatar nebulon42 avatar onecrayon avatar pnorman avatar samanpwbb avatar sk1p avatar stefanklug avatar theel0ja avatar tmcw avatar tomhughes avatar unibasil avatar wrynearson avatar yhahn avatar yohanboniface avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

carto's Issues

Inspecting Massive Data in Layers

So, it looks like you can't really see all of the data in a layer if the layer has about 1,000 rows or more. You can see the first 1,000, but it stops after that right now. How can we allow people to see all the rows of their data?

Zoom levels 19+ are off

With the following test code, the rule for zoom=18 gets applied to zoom level 19 as well (in TileMill). The rules for zoom=19 and above are then all off by one in the preview. Zoom level 22 is blank. I suspect this is due to incorrect zoom level definitions in Carto.

#world {
  polygon-fill: grey;
  line-color: black;
  [zoom=22] { polygon-fill: white; }
  [zoom=21] { polygon-fill: magenta; }
  [zoom=20] { polygon-fill: blue; }
  [zoom=19] { polygon-fill: green; }
  [zoom=18] { polygon-fill: yellow; }
  [zoom=17] { polygon-fill: red; }
}

Feature request: let Map{} handle default values

It would be cool if we could treat Map{} like body{} is popularly handled in CSS: A place to set up default text sizes, line heights, text-color ... and zoom level?

It would help to elevate map rendering issues when a text face or size (one or the other) is not defined in the layer id.

Possibly suboptimal translation to XML

I'm not sure whether this is a bug, but I managed to create ~50 lines of Carto that get translated into something like 12,000 lines of XML. I probably should just be breaking things up differently, but perhaps there's room for optimization on Carto's side as well.

The offending style is at https://gist.github.com/859095 and the data to go with it is http://dl.dropbox.com/u/2398828/country-labels.geojson

Not the main issue, but I noticed many identical fontsets are created as well.

text-face-name validation not aligned

super minor issue, but recording here nonetheless in case it might point to other fixes needed. Image below should illustrate that the validation line is 6 lines below where is should be:

Output warnings, not just errors

Carto should tolerate some problems, like #29 - styles for layers that don't exist. It might also be interesting to go with a warnings-only mode that throws away incorrect content instead of preventing save.

pretty printing output

It would be really nice if carto and cartox output could be pretty printed to be more readable. Ideally both the json and the css could be printed properly as part of the output process if --indent or --pretty is passed as a command line arg to the tools. I took a quick stab at a python script to postprocess things, but obviously it should be part of the tools themselves:

#!/usr/bin/env python

import os
import sys
import json


inputFile = open(sys.argv[1])
input = json.load(inputFile)
inputFile.close()
mss = input["Stylesheet"][0].pop('data')
name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
input["Stylesheet"][0] = '%s.mss' % name
open('%s.mss' % name, "w").write(mss)
outputFile = open('%s.mml' % name, "w")
json.dump(input, outputFile, sort_keys = False, indent = 4)
outputFile.close()

Double Double Quote Crashes

This syntax error causes a complete crash of TileMill.

Ex:

{
    text-face-name: ""Helvetica Neue UltraLight"";
}

and returns only this error in the terminal:

node.js:63
    throw e;
    ^

text-fill-opacity ?, text-halo-opacity?

I would like the label of sub county to appear to the same level opacity as I have done the county borders. Thus it is text that I would like to have but it should not feature as prominent as other text. Having the opacity styles that I mention above would be a great addition for that purpose.

Better syntax for custom strings.

Currently to achieve custom strings from Carto you have to wrap it in double quotes then single quotes like so:

#world{
  text-name: "'Some label name'";
}

I propose changing this to support a more CSS like format

#world {
  text-name: "Some label here";
}

Avoid duplicate fontsets

In the current iteration of a stylesheet I'm working on, I'm only using a single font, but Carto compiles over 800 identical fontsets for all the different rules.

Intended overrides creating new symbolizers

The last two rules should merge into the first, but instead new symbolizers are created.

#world {
  polygon-opacity:0.5;
}

#world[LAT>0] { polygon-fill:#0DA; }
#world[LAT<0] { polygon-fill:#0AD; }

These even happens with explicit attachment specification:

#world::foo {
  line-opacity:0.5;
}

#world::foo[LAT >= 0] { line-color:#0DA; }
#world::foo[LAT <= 0] { line-color:#0AD; }

upcoming formats

Here are the datasource formats that currently may start coming in:

.zip|.json|.geojson|.shp|.vrt|.tiff

We handle .zip well, everything else I think needs (re) visiting.

From springmeyer

We don't quite support zip well yet. If more than one shapefile is inside a zip, we only take the first (natural earth has multiple shapefiles per zip I noticed). Also, .tiff|.vrt and other in the future future may need to come inside a zip for compression benefits in upload and if they have multiple files.

Support rgb, rgba color syntax

Mapnik's internal color storage is rgba and accepts the creation of colors like:

'rgba(0,0,0,0)'

'rgb(0,0,0)'

'rgba(50%,50%,50%,.5)'

Is this something we could support?

'Shield' bug?

This block of code will throw e in TileMill:

#roads [FCODE_DESC='Expressway'][zoom>10]{
  shield-name: "[LF_NAME]";
  shield-face-name: @sans_bold;
  shield-size: 15;
  shield-fill: #000;
  shield-file:  url(../resources/icons/shield.png);
}

And to confirm @sans_bold is defined and FCODE_DESC, LF_NAME exist as columns.
I can use the same block of code as a text property and it works:

#roads[FCODE_DESC='Expressway'][zoom>10] {
   text-name: "[LF_NAME]";
   text-face-name: @sans_bold;
   text-fill: #000;
   text-size: 8;
}

Support path expressions for remote images

This is something that likely will needs to be addressed in Mapnik core, but I wanted to document it here. Path expressions currently only support local paths. Adding support for remote paths would enable dynamic image generation based on web services, such as using Google Charts API to generate marker files.

Support default creation of symbolizers using 'auto' syntax

Say I want to create a point without supplying a png/svg file. I know that Mapnik supports creating a PointSymbolizer without any arguments and will internally just create a simple black square. We should have a simple way to request this in carto that can be used for other symbolizers that have a no-arg default contructor, including line, polygon, and markers symbolizer (and perhaps more in the future). Maybe something like:

    #city {
        point: auto;
    }

or

    #city {
        point-visibility: auto;
    }

Support metawriters

Currently we output metawriters within styles but not xml. Ideally we're going to stream the output of metawriters instead of mapnik writing to disk, but we need to figure out a plan here at some point.

Deferred: ideally this is after node-mapnik support, which might also affect the XML taken by Mapnik and output here.

Issue with non-closed comment

Documents with comments that are not closed properly, such as this example, cause node to hang and take up significant CPU.

At first glance this seems like a carto issue, but I'm testing from within TileMill.

Carto is unable to do numeric multiplication in rules

Hi,

I'm unable to do multiplication within a carto style - is this part of the spec?. This would be useful for example for using scalar variables to size elements uniformly at different zoom levels.

working carto
---------------

#land {
  polygon-fill:#0A202A;
  line-width:1.2;
}


non-working carto
------------------

#land {
  polygon-fill:#0A202A;
  line-width:1.2 * 2;    # note multiplication
}

and (possibly as a result of the above)

@line_width_multiple:2;

#land {
  polygon-fill:#0A202A;
  line-width:1.2 * @line_width_multiple;
}

Thanks!

Unhelpful error message

This may be me not understanding something, but the error message produced from the latest code off github (01/05/2011) is not helping me find it.
I have the following definition in my .mml file:
"Stylesheet":[ "map_background.mss", "errtest_style.mss"],

Now with map_background.mss empty, and the following in errtest_style.mss, carto works fine:

Map {
  background-color: #aaaaff;
}

#highways {
  ::outline {
      line-color: #000000;
      line-width: 8.0;
    }
  line-color: #ffffff;
  line-width: 6.0;
}

What I am trying to do is separate styles into different files. If I cut out the Map definition above and put it into map_background.mss, I get the following error.

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
TypeError: Object Map {
  background-color: #aaaaff;
}

 has no method 'toList'
    at /home/graham/OSM/code/carto/lib/carto/renderer.js:368:36
    at Array.map (native)
    at Object.template (/home/graham/OSM/code/carto/lib/carto/renderer.js:367:50)
    at /home/graham/OSM/code/carto/lib/carto/renderer.js:478:34
    at Function.waitForCompilation (/home/graham/OSM/code/carto/lib/carto/renderer.js:227:21)
    at next (/usr/local/lib/node/.npm/step/0.0.4/package/lib/step.js:51:23)
    at check (/usr/local/lib/node/.npm/step/0.0.4/package/lib/step.js:73:14)
    at /usr/local/lib/node/.npm/step/0.0.4/package/lib/step.js:86:20
    at Array.check (/usr/local/lib/node/.npm/step/0.0.4/package/lib/step.js:101:9)
    at EventEmitter._tickCallback (node.js:126:26)

This may well be something wrong with my style definition, but the error is not giving any clue about where it is (as far as I can tell!).

Crash: TypeError: Cannot call method 'pop' of undefined

A fresh installation of TileMill on ubuntu 11.04 crashes upon attempting to load a project with the following output:

Started TileMill on port 8889.

/home/aj/devseed/tm-head/lib/node/carto/external.js:123
    var cb = function(err, files) { callback(null, files.pop()); };
                                                         ^
TypeError: Cannot call method 'pop' of undefined
    at /home/aj/devseed/tm-head/lib/node/carto/external.js:123:58
    at /home/aj/devseed/tm-head/lib/node/carto/external.js:138:17
    at node.js:773:9

@tristen is seeing the same issue after a fresh ndistro on OS X.

srs.parse() results cacheable?

In tilemill when a layer's projection is set to AUTODETECT this triggers autodetectSRS() within carto. But this appears to be called everytime a stylesheet is compiled even if the layer definition did not change.

Carto style reference

Hi,

Where can I find a complete set of Carto styles. For example ::outline is mentioned in the overall presentation of Attachments but ::inline is not. Neither is ::inline mentioned anywhere else. but yes ofcourse you find out when watching the Tilemill Demo movie.

Thus are there other equally interesting features I am missing out on :-)

Regards,

Leverage map 'maximum-extent'

Recent mapnik now accepts (and in some cases ideally needs) a 'maximum-extent' parameter that can be set on the map. See http://lists.berlios.de/pipermail/mapnik-devel/2011-April/001376.html for lots of gory details.

The "ideally needs" case is for maps that use mercator datasources, but whose projections do not exactly match the map. What happens is that proj4 is used to transform the tile/query BBOX into the layer srs and it fails to properly reproject all four corners. Instead of sending back an error it simply returns insane values and so when the mapnik datasource is queried a stupid bbox is used the large chunks of data go missing. This can be fixed in an expensive way but the simpler approach is just to use the maximum-extent to clip the box to valid extents.

I should mention however that in 99% of cases in tilemill so far the unequal projections (map merc != layer merc) are an error - which is what we've been fixing at https://github.com/mapbox/tilemill/issues/330 and https://github.com/mapbox/tilemill/issues/338.

Blue sky: data constants, calculations for filters

This is a total blue sky request -- curious to see whether it's feasible/elegant to do or a total dead end. Currently our web projects use complex code to generate styles specific to the datasource, e.g. a choropleth map might need styles rendered like:

#layer[FIELD <= 10000] { ... }
#layer[FIELD > 10001] { ... }

Where 10000 is some value specific to the datasource.

I'm wondering if carto could represent certain values as pseudo-constants/calculations, e.g. MAX(FIELD), MIN(FIELD) and furthermore evaluate calculations in filters like this:

/* Choropleth of 5 colors */
#layer[FIELD >= MIN(FIELD)][FIELD < MAX(FIELD) * .2] { ... }
#layer[FIELD >= MAX(FIELD) * .2][FIELD < MAX(FIELD) * .4] { ... }
#layer[FIELD >= MAX(FIELD) * .4][FIELD < MAX(FIELD) * .6] { ... }
#layer[FIELD >= MAX(FIELD) * .6][FIELD < MAX(FIELD) * .8] { ... }
#layer[FIELD >= MAX(FIELD) * .8][FIELD < MAX(FIELD)] { ... }

So that the styles can be reused/applied easily to any datasource. The idea here is to make visualizations much simpler to express and not require hardcoded values/external calculations.

Just close if this is totally crazy.

Silent failure for shapefiles with invalid/unescaped characters in path

Using latest tilemill 0.2.0 tag (so carto 0.1.8).

If I load this point shapefile: http://www.spc.noaa.gov/gis/svrgis/Hail_2inches_and_greater.zip it downloads fine and loads as a layer fine in tilemill with no warnings/errors. And then when I go to style it the map appears transparent and without errors.

(in the terminal GDAL does spit out "ERROR 6: No translation for Lambert_Conformal_Conic to PROJ.4 format is known." but this is harmless and just means that the .prj used an ESRI syntax and carto loads each srs a second time with 'ESRI::' appended to catch this initial failiure.)

So, no output at all. But internally mapnik is failing because the unzipped path becomes:

/Users/dane/projects/TileMill/files/.cache/c9b0207498c4cc5fe2cc1fb1934066a8/Hail_2inches_&_greater.shp

the & is interpreted as an XML entity and mapnik throws during XML loading.

I know this because the error is clear if we hit mapnik directly:

$ ./bin/mapnik-render.js /Users/dane/projects/tilemill/files/.cache/05bd2d942fe7153401a5a4fa17a6dce6.xml  t.png

node.js:63
    throw e;
    ^
Error: XML document not well formed: 
EntityRef: expecting ';' (encountered in file '/Users/dane/projects/tilemill/files/.cache/05bd2d942fe7153401a5a4fa17a6dce6.xml' at line 26)
    at renderMap (/Users/dane/projects/TileMill/bin/mapnik-render.js:25:9)
    at Object. (/Users/dane/projects/TileMill/bin/mapnik-render.js:58:5)
    at Module._compile (node.js:462:23)
    at Module._loadScriptSync (node.js:469:10)
    at Module.loadSync (node.js:338:12)
    at Object.runMain (node.js:522:24)
    at Array. (node.js:756:12)
    at EventEmitter._tickCallback (node.js:55:22)
    at node.js:773:9

Filter layer values

There should be an effort to make output non-dangerous in XML even if people tack on extra values to layers.

re-push on browser compatibility

We should have carto running in the browser, at least for subsets of what it does. Possibly just the .style() stack should be compatible at first, but this is key to creating a better validation experience.

new color function: hexa()

A few Mapnik styles accept colors in RGBA format. It would be cool to have a function that could convert a hex number into rgba(), so we could do things like:

hexa(#ACE, 0.75) /* type less, in a more familiar format */
hexa(@park, 0.5) /* add transparency to color variables */
hexa(#aacceec0) /* maybe even do Inkscape-style hex values */

support reverse-debugging of expressions in Mapnik

It would be helpful if an error like this:

Deprecation Warning: symbolizer value now an expression, please wrap properly in brackets like "[LF_NAME]"

Could provide a file path and line-number for helpful debugging.

No error raised if stylesheet does not exist

If your .mml file contains the following:

"Stylesheet":[ "map_background.mss", "errtest_style.mms"
],

but "map_background.mss" does not exist, an empty xml output file is generated, but carto does not generate any errors or warnings - I think it should be an error?

carto can't render its own output from mml2json

mml2json appears to miss adding an 'id' to a layer such that when carto goes to render the mml nothing happens, no errors, no output. It appears that localizeStyle() just never returns and this is due to the assumption of an External 'complete' event after an 'id' is not found.

I'm testing with local files, so I gather that this has not been tested yet. To replicate download Cascadenik and use mml2json on Cascadenik/doc/example1.mml then run carto on the file output mml2json and you'll see that carto does nothing due to this problem.

Tests need CDATA support

We're going to wrap parameter values in CDATA to fix #44, but the currently XML parser implementation chokes on it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.