Magnacarto

repository·master·Indexed 41 days ago

https://github.com/omniscale/magnacarto

A CartoCSS map style processor that converts CartoCSS styles into Mapnik XML and MapServer map files. It includes the `magnacarto` CLI for style conversion and `magnaserv`, a web-based viewer and API for map inspection and rendering. The tool supports advanced CartoCSS features like text-placement-list and text-lang, and provides a Go wrapper for the Mapnik 3/4 API via go-mapnik.

Tokens
3.7K
Snippets
15
Records
19
Agent score
92%

What's inside Magnacarto

  1. Handle Proj4 compatibility for Mapnik 3

    master

    Recent versions of libproj no longer support the old +init=epsg:XXXX projection string style. By default, the mapnik3 builder emits the modern epsg:XXXX format.

    If you need to maintain compatibility with older libproj or proj4 versions, use the mapnik3-proj4 builder.

    Requirement: You must update the SRS (Spatial Reference System) of your layers in your .mml files to the new epsg:XXXX style. The mapnik3-proj4 builder will then automatically prepend the +init= prefix for you.

  2. Generate MapServer layers and symbols without a MAP block

    master

    To create a MapServer file that only contains LAYERS and SYMBOLS (omitting the top-level MAP block), use the -ms-no-map-block option. This is ideal for creating snippets that you intend to INCLUDE into existing MapServer map files that already have custom metadata or image format configurations.

    magnacarto -mml world.mml -builder mapserver -ms-no-map-block > layers.map
  3. Use advanced CartoCSS features in Magnacarto

    master

    Magnacarto supports several advanced features that extend the original CartoCSS specification.

    Text placement list

    You can replicate the Mapnik TextSymbolizer <Placement> list behavior using text-placement-list. This allows multiple styling definitions for a single label:

    #labels {
        text-name: "[name]";
        text-face-name: "DejaVu Sans Book";
        text-size: 16;
        text-placement: point;
        text-dy: 8;
        text-fill: blue;
        text-placement-list:
            {text-size: 10; text-dy: -8; text-fill: red;},
            {text-fill: green; text-name: "[abbreviated_name]";},
            {text-fill: orange; text-dy: 8; text-name: "[nr]";};
    }

    Text Language

    To set the <TextSymbolizer lang="[lang]"> attribute, use the text-lang property:

    #labels {
        text-lang: "en";
    }
  4. Install Magnacarto from source

    master

    To install Magnacarto, you need Go > 1.12 installed on your system.

    1. Clone or download the repository.
    2. Run make install to compile and install the binaries.

    Render Plugins

    Magnacarto supports rendering via Mapnik and MapServer through plugins:

    • Mapserver: Included in the default magnaserv installation. Requires the mapserv binary to be in your PATH at runtime.
    • Mapnik: Requires a separate compilation of the magnacarto-mapnik binary. You must have Mapnik (supporting version 3) installed with all header files, and mapnik-config must be in your PATH. Run make install to build this plugin binary.
    make install
  5. Install go-mapnik

    master

    go-mapnik is a Go wrapper for the Mapnik 3/4 API.

    Prerequisites

    You must have Mapnik installed on your system (libmapnik on Ubuntu/Debian, or mapnik via Homebrew on macOS).

    Build Configuration

    Since version 3, you must generate the system-dependent build flags manually. Run the following command in the package directory:

    go generate .

    This creates a build_config.go file containing the necessary flags.

    Note on Dependency Management: Because go generate must be run to create build_config.go, this package does not work correctly via standard go get or direct imports. It is highly recommended to manually vendorize the package into your repository (e.g., using git subtree).

    go generate .
  6. File watching and notification logic in magnaserv

    master

    The magnaserv component includes logic to monitor MapML (.mml) and Mapnik Stylesheet (.mss) files for changes. When a file is modified, the service can automatically trigger a rebuild of the map style to provide real-time updates during development.

    Key Behaviors

    • Automatic MSS Discovery: If no specific .mss files are provided, the service parses the .mml file to identify and watch all stylesheets referenced within it.
    • Editor Compatibility: The watcher includes a small delay (100ms) when detecting Rename operations to accommodate editors (like Vim) that perform atomic saves by renaming files, preventing
  7. Monitor style changes via WebSockets

    master

    The /changes endpoint provides a WebSocket connection that notifies clients when map style files (MML/MSS) are updated or when rendering errors occur.

    Workflow

    1. Connect to the /changes WebSocket.
    2. The server immediately sends a wsid (a random unique ID) to the client.
    3. When making subsequent rendering requests to /api/v1/map, include this wsid in the query parameters.
    4. If a render fails or a file changes, the server will push a JSON message to the WebSocket associated with that wsid.

    Message Types

    On File Update:

    {
      "updated_at": "2025-10-06T...",
      "updated_mml": true
    }

    On Rendering Error/Feedback:

    {
      "error": "error message",
      "mss": ["path/to/file.mss"],
      "mml": "path/to/file.mml",
      "warnings": ["warning 1", "warning 2"]
    }

    On Parser Errors (MSS): If an MSS file has a syntax error, the message includes detailed location info:

    {
      "full_error": "...",
      "error": "...",
      "filename": "...",
      "line": 10,
      "column": 5
    }
  8. Use the magnacarto CLI to convert CartoCSS to Mapnik or MapServer styles

    master

    The magnacarto command-line tool converts CartoCSS (.mss) files into Mapnik (.mml) or MapServer styles. It supports multiple builder types, including Mapnik 3, Mapnik 3 with Proj4 support, and MapServer.

    Basic Usage

    To convert a single MSS file to a Mapnik style, provide the -mml flag (for the output MML file) and the -mss flag for the input CartoCSS file.

    # Convert a single MSS file to Mapnik 3 style
    magnacarto -mml output.mml -mss input.mss
    
    # Convert multiple MSS files
    magnacarto -mml output.mml -mss file1.mss -mss file2.mss
    
    # Output to stdout
    magnacarto -mml - -mss input.mss
    magnacarto -mml output.mml -mss input.mss
  9. Render maps using go-mapnik

    master

    You can use the mapnik package to load map configurations and render them to files, []byte, or image.Image.

    Key capabilities include:

    • Setting the scale denominator or scale factor.
    • Enabling or disabling specific layers.
    • Resizing the output dimensions.
    • Using ZoomTo to define the geographic extent.

    To render a map, create a new instance with mapnik.New(), load an XML configuration file, and call RenderToFile with a mapnik.RenderOpts object.

    func Example() {
    	m := mapnik.New()
    	if err := m.Load("test/map.xml"); err != nil {
    		log.Fatal(err)
    	}
    	m.Resize(1000, 500)
    	m.ZoomTo(-180, -90, 180, 90)
    	opts := mapnik.RenderOpts{Format: "png32"}
    	if err := m.RenderToFile(opts, "/tmp/go-mapnik-example-1.png"); err != nil {
    		log.Fatal(err)
    	}
    }
  10. Reference: Magnacarto CLI flags for MapServer

    master

    The following flags are used when generating MapServer files via the magnacarto CLI:

    • -mml <file>: The input Mapnik Markup Language file.
    • -builder mapserver: Specifies that the output should be formatted for MapServer.
    • -ms-no-map-block: Prevents the creation of the MAP block, outputting only LAYERS and SYMBOLS.
    -mml <file>
    -builder mapserver
    -ms-no-map-block