### Full Example: Mux-based Server in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md This snippet provides a complete, runnable example of a minimal web server built with Go and the Gorilla Mux router. It defines a simple handler and sets up the router to listen on a specific port. This serves as a foundational example for creating basic web services in Go. ```go package main import ( "net/http" "log" "github.com/gorilla/mux" ) func YourHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Gorilla!\n")) } func main() { r := mux.NewRouter() // Routes consist of a path and a handler function. r.HandleFunc("/", YourHandler) // Bind to a port and pass our router in log.Fatal(http.ListenAndServe(":8000", r)) } ``` -------------------------------- ### StartProvider Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md Starts a provider-style plugin executable and establishes an RPC connection. ```APIDOC ## func StartProvider(output io.Writer, path string, args ...string) ### Description Starts a provider-style plugin application at the given path and arguments. Returns an RPC client that communicates with the plugin using gob encoding over the plugin's Stdin and Stdout. ### Parameters - **output** (io.Writer) - Required - Writer to receive output from the plugin's stderr. - **path** (string) - Required - Filesystem path to the plugin executable. - **args** (...string) - Optional - Command line arguments for the plugin. ### Response - **rpc.Client** (object) - An RPC client instance to communicate with the plugin. - **error** (error) - Returns an error if the process fails to start. ``` -------------------------------- ### Start Magnacarto Web Server (magnaserv) Source: https://context7.com/omniscale/magnacarto/llms.txt These commands demonstrate how to start the `magnaserv` web frontend, which provides a live preview for CartoCSS development. Options include specifying the renderer backend, listening address, and port. ```bash magnaserv ``` ```bash magnaserv -builder mapserver -listen 127.0.0.1:8080 ``` ```bash magnaserv -config magnacarto.tml -builder mapnik ``` ```bash magnaserv -builder mapnik3-proj4 ``` -------------------------------- ### Go HTTP Middleware Example with Logging and Compression Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/handlers/README.md This example demonstrates how to use Gorilla Handlers to wrap an HTTP server with logging and response compression. It shows how to apply LoggingHandler for specific routes and CompressHandler for the entire application. Dependencies include Go's net/http package and the gorilla/handlers library. Inputs are HTTP requests, and outputs are logged requests and compressed responses. ```Go import ( "net/http" "github.com/gorilla/handlers" "os" ) func main() { r := http.NewServeMux() // Only log requests to our admin dashboard to stdout r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard))) r.HandleFunc("/", ShowIndex) // Wrap our server with our gzip handler to gzip compress all responses. http.ListenAndServe(":8000", handlers.CompressHandler(r)) } ``` -------------------------------- ### Start Gob Encoded Provider Plugin Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md Starts a provider-style plugin application. The main application uses this to launch a plugin executable and establish communication. It returns an RPC client to interact with the plugin, using gob encoding over the plugin's Stdin and Stdout. Output to the plugin's stderr is captured. ```go func StartProvider(output io.Writer, path string, args ...string) (*rpc.Client, error) ``` -------------------------------- ### Install Gorilla Mux Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Command to install the Gorilla Mux package using the Go toolchain. ```shell go get -u github.com/gorilla/mux ``` -------------------------------- ### Start Custom Codec Provider Plugin Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md Starts a provider-style plugin application with a custom RPC codec. The main application launches the plugin and sets up communication using a user-defined ClientCodec. It returns an RPC client for interaction, with stderr output captured. Closing the client shuts down the plugin. ```go func StartProviderCodec( f func(io.ReadWriteCloser) rpc.ClientCodec, output io.Writer, path string, args ...string, ) (*rpc.Client, error) ``` -------------------------------- ### Run Magnaserv Web Frontend Source: https://github.com/omniscale/magnacarto/blob/master/README.md Commands to start the magnaserv web interface with various configurations and builders. ```bash magnaserv magnaserv -builder mapserver -listen 127.0.0.1:8080 magnaserv -builder mapserver -config magnacarto.tml ``` -------------------------------- ### Start Plugin Consumer (Go) Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md StartConsumer initiates a plugin application process, directing its stderr to the provided output writer. It returns the Server for the host application, used for registering APIs that the plugin will consume. ```go func StartConsumer(output io.Writer, path string, args ...string) (Server, error) ``` -------------------------------- ### Render a Map to File using go-mapnik Source: https://github.com/omniscale/magnacarto/blob/master/render/mapnik/README.md This example demonstrates how to initialize a Mapnik instance, load a map configuration from an XML file, resize the canvas, set the zoom extent, and render the output to a PNG file. It requires a valid Mapnik XML configuration file as input. ```go 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) } } ``` -------------------------------- ### Install and Build Magnacarto Source: https://github.com/omniscale/magnacarto/blob/master/README.md Commands to compile the Magnacarto project from source using the Makefile. ```bash make install ``` -------------------------------- ### Walk Router to Visit All Registered Routes in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Provides an example of using the `Walk` function to iterate over all registered routes in a `mux.Router`. It demonstrates how to retrieve and print details for each route, including path templates, regexps, query templates, and methods. ```go package main import ( "fmt" "net/http" "strings" "github.com/gorilla/mux" ) func handler(w http.ResponseWriter, r *http.Request) { return } func main() { r := mux.NewRouter() r.HandleFunc("/", handler) r.HandleFunc("/products", handler).Methods("POST") r.HandleFunc("/articles", handler).Methods("GET") r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT") r.HandleFunc("/authors", handler).Queries("surname", "{surname}") err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { pathTemplate, err := route.GetPathTemplate() if err == nil { fmt.Println("ROUTE:", pathTemplate) } pathRegexp, err := route.GetPathRegexp() if err == nil { fmt.Println("Path regexp:", pathRegexp) } queriesTemplates, err := route.GetQueriesTemplates() if err == nil { fmt.Println("Queries templates:", strings.Join(queriesTemplates, ",")) } queriesRegexps, err := route.GetQueriesRegexp() if err == nil { fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ",")) } methods, err := route.GetMethods() if err == nil { fmt.Println("Methods:", strings.Join(methods, ",")) } fmt.Println() return nil }) if err != nil { fmt.Println(err) } http.Handle("/", r) } ``` -------------------------------- ### Install TOML Validator CLI Tool Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/BurntSushi/toml/README.md Instructions to install the TOML validator command-line interface tool. This tool helps in validating TOML files. ```bash go install github.com/BurntSushi/toml/cmd/tomlv@latest tomlv some-toml-file.toml ``` -------------------------------- ### Install OmniScale/Magnacarto TOML Package Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/BurntSushi/toml/README.md Instructions to add the OmniScale/Magnacarto TOML package to your Go project using go.mod. Requires Go 1.13 or newer. ```bash go get github.com/BurntSushi/toml@latest ``` -------------------------------- ### Go YAML Marshal and Unmarshal Example Source: https://github.com/omniscale/magnacarto/blob/master/vendor/gopkg.in/yaml.v2/README.md Demonstrates how to use the yaml.v2 package in Go to unmarshal YAML data into a struct and a map, and then marshal them back into YAML format. It covers basic data types and nested structures. ```Go package main import ( "fmt" "log" "gopkg.in/yaml.v2" ) var data = ` a: Easy! b: c: 2 d: [3, 4] ` // Note: struct fields must be public in order for unmarshal to // correctly populate the data. type T struct { A string B struct { RenamedC int `yaml:"c"` D []int `yaml:",flow"` } } func main() { t := T{} err := yaml.Unmarshal([]byte(data), &t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", t) d, err := yaml.Marshal(&t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t dump:\n%s\n\n", string(d)) m := make(map[interface{}]interface{}) err = yaml.Unmarshal([]byte(data), &m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m:\n%v\n\n", m) d, err = yaml.Marshal(&m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m dump:\n%s\n\n", string(d)) } ``` -------------------------------- ### Magnacarto TOML Configuration File Example Source: https://context7.com/omniscale/magnacarto/llms.txt This TOML file illustrates the configuration structure for Magnacarto. It centralizes settings for style directories, output paths, datasource locations, and rendering options like font directories and PostGIS connection parameters. ```toml # magnacarto.tml - Example configuration file # Directory containing .mml project files styles_dir = "/magnacarto-projects" # Output directory for generated .xml and .map files out_dir = "/tmp/magnacarto-styles" [datasources] # Directories to search for shapefiles shapefile_dirs = ["/data/shapefiles", "/osm/data"] # Directories to search for SQLite databases sqlite_dirs = ["/data/sqlites"] # Directories to search for image/marker files image_dirs = [ "/data/icons", "/data/patterns", ] # General data directory (fallback for all types) data_dirs = ["/data/general"] [mapnik] # Font directories for Mapnik rendering font_dirs = ["/usr/share/fonts/truetype", "/Library/Fonts"] # Cache timeout for loaded maps (for magnaserv) cache_wait_timeout = "5s" [postgis] # Default PostGIS connection parameters (overrides .mml settings) username = "osm" password = "osm" database = "osm" host = "localhost" port = "5432" srid = "3857" ``` -------------------------------- ### GET /api/v1/projects Source: https://context7.com/omniscale/magnacarto/llms.txt Retrieves a list of all available projects managed by Magnaserv. ```APIDOC ## GET /api/v1/projects ### Description Returns a list of all projects, including their MML file references and last modification timestamps. ### Method GET ### Endpoint /api/v1/projects ### Response #### Success Response (200) - **projects** (array) - A list of project objects containing name, mml file, and last_change date. #### Response Example { "projects": [ {"name": "world", "mml": "world.mml", "last_change": "2024-01-15T10:30:00Z"} ] } ``` -------------------------------- ### Define MML Project Configuration Source: https://context7.com/omniscale/magnacarto/llms.txt This JSON example demonstrates the structure of an MML project file. It includes global project settings, a list of stylesheet files, and an array of layer definitions with specific datasource configurations for various formats. ```json { "name": "My Map Project", "srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over", "format": "png", "Stylesheet": [ "base.mss", "roads.mss", "labels.mss" ], "Layer": [ { "id": "landuse", "name": "landuse", "geometry": "polygon", "srs": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs", "Datasource": { "type": "postgis", "host": "localhost", "port": "5432", "dbname": "osm", "user": "osm", "password": "osm", "table": "(SELECT * FROM osm_landusages) AS landuse", "geometry_field": "geometry", "srid": "3857", "extent": "-20037508,-20037508,20037508,20037508" } }, { "id": "roads", "name": "roads", "geometry": "linestring", "class": "highway major", "srs": "epsg:4326", "status": "on", "properties": { "minzoom": 10, "maxzoom": 18, "group-by": "layer" }, "Datasource": { "type": "shape", "file": "roads/osm_roads.shp", "srid": "4326" } }, { "id": "places", "name": "places", "geometry": "point", "Datasource": { "type": "sqlite", "file": "places.sqlite", "table": "places", "geometry_field": "geometry", "srid": "4326" } }, { "id": "terrain", "name": "terrain", "geometry": "raster", "Datasource": { "type": "gdal", "file": "terrain/hillshade.tif", "srid": "3857", "band": "1", "processing": ["SCALE=0,255"] } } ] } ``` -------------------------------- ### GET/PUT/PATCH /foo Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md An example endpoint demonstrating how to configure CORS headers using the middleware and an OPTIONS handler. ```APIDOC ## GET/PUT/PATCH /foo ### Description This endpoint demonstrates the implementation of CORS headers using the Gorilla Mux CORSMethodMiddleware. It requires an OPTIONS method matcher to function correctly. ### Method GET, PUT, PATCH, OPTIONS ### Endpoint /foo ### Parameters None ### Request Body None ### Request Example curl -X GET localhost:8080/foo -v ### Response #### Success Response (200) - **Access-Control-Allow-Methods** (string) - The allowed HTTP methods for this route. - **Access-Control-Allow-Origin** (string) - The origin allowed to access the resource. #### Response Example HTTP/1.1 200 OK Access-Control-Allow-Methods: GET,PUT,PATCH,OPTIONS Access-Control-Allow-Origin: * ``` -------------------------------- ### Basic TOML Decoding in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/BurntSushi/toml/README.md Example of decoding a simple TOML string into a Go struct. Demonstrates mapping TOML keys to struct fields. ```toml Age = 25 Cats = [ "Cauchy", "Plato" ] Pi = 3.14 Perfection = [ 6, 28, 496, 8128 ] DOB = 1987-07-05T05:45:00Z ``` ```go package main import ( "time" "github.com/BurntSushi/toml" ) type Config struct { Age int Cats []string Pi float64 Perfection []int DOB time.Time } func main() { var conf Config tomldata := ` Age = 25 Cats = [ "Cauchy", "Plato" ] Pi = 3.14 Perfection = [ 6, 28, 496, 8128 ] DOB = 1987-07-05T05:45:00Z ` _, err := toml.Decode(tomldata, &conf) if err != nil { panic(err) } // Use conf here } ``` -------------------------------- ### TOML Decoding with Struct Tags in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/BurntSushi/toml/README.md Example demonstrating how to use struct tags in Go to map TOML keys that do not directly match struct field names. ```toml some_key_NAME = "wat" ``` ```go package main import "github.com/BurntSushi/toml" type TOML struct { ObscureKey string `toml:"some_key_NAME"` } func main() { var t TOML tomldata := `some_key_NAME = "wat"` _, err := toml.Decode(tomldata, &t) if err != nil { panic(err) } // Use t.ObscureKey here } ``` -------------------------------- ### Go: Implement CORSMethodMiddleware for Access-Control-Allow-Methods Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md This Go code demonstrates how to use Gorilla Mux's CORSMethodMiddleware to set the Access-Control-Allow-Methods header. It requires specifying an OPTIONS method matcher and a custom handler to set other CORS headers like Access-Control-Allow-Origin. The example shows setting up a router, applying the middleware, and handling requests. ```go package main import ( "net/http" "github.com/gorilla/mux" ) func main() { r := mux.NewRouter() // IMPORTANT: you must specify an OPTIONS method matcher for the middleware to set CORS headers r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions) r.Use(mux.CORSMethodMiddleware(r)) http.ListenAndServe(":8080", r) } func fooHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") if r.Method == http.MethodOptions { return } w.Write([]byte("foo")) } ``` -------------------------------- ### Initialize Custom Codec Consumer Client Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md Initializes an RPC client for a plugin to consume an API from the host process using a custom codec. The codec is provided by a function that returns an rpc.ClientCodec. Communication occurs over the application's Stdin and Stdout. This is for plugin-side setup. ```go func NewConsumerCodec(f func(io.ReadWriteCloser) rpc.ClientCodec) *rpc.Client ``` -------------------------------- ### Register Basic Routes Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates how to initialize a new router and register basic URL paths to handler functions. ```go func main() { r := mux.NewRouter() r.HandleFunc("/", HomeHandler) r.HandleFunc("/products", ProductsHandler) r.HandleFunc("/articles", ArticlesHandler) http.Handle("/", r) } ``` -------------------------------- ### Create Server Instance (Go) Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md NewProvider creates a Server instance that communicates over the application's Stdin and Stdout. This function is intended for use by plugin applications. ```go func NewProvider() Server ``` -------------------------------- ### Define and Register Basic Middleware Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates the standard MiddlewareFunc signature and how to register a simple logging middleware using the Router.Use() method. ```go func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Println(r.RequestURI) next.ServeHTTP(w, r) }) } r := mux.NewRouter() r.HandleFunc("/", handler) r.Use(loggingMiddleware) ``` -------------------------------- ### GET /api/v1/map Source: https://context7.com/omniscale/magnacarto/llms.txt Renders a map image based on provided MML, bounding box, and dimensions. ```APIDOC ## GET /api/v1/map ### Description Generates a map image tile or snapshot based on the specified project and rendering parameters. ### Method GET ### Endpoint /api/v1/map ### Parameters #### Query Parameters - **mml** (string) - Required - The project MML file name. - **BBOX** (string) - Required - Bounding box coordinates (minx, miny, maxx, maxy). - **WIDTH** (integer) - Required - Image width in pixels. - **HEIGHT** (integer) - Required - Image height in pixels. - **RENDERER** (string) - Optional - The rendering engine to use (e.g., mapnik, mapserver). - **mss** (string) - Optional - Comma-separated list of MSS files to override. ### Response #### Success Response (200) - **image** (binary) - The rendered map image file (e.g., image/png). ``` -------------------------------- ### NewConsumer Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md Initializes a consumer-style plugin that connects to the host process API. ```APIDOC ## func NewConsumer() ### Description Returns an rpc.Client that will consume an API from the host process over this application's Stdin and Stdout using gob encoding. ### Method Internal Function Call ### Parameters None ### Response - **rpc.Client** (object) - An RPC client instance connected to the host process. ``` -------------------------------- ### Build URLs from Named Routes in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates how to define named routes and generate URLs by providing route variables. It covers basic URL building, including host, path, and query parameters, and shows how to extract required variable names. ```go r := mux.NewRouter() r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). Name("article") url, err := r.Get("article").URL("category", "technology", "id", "42") ``` ```go r := mux.NewRouter() r.Host("{subdomain}.example.com"). Path("/articles/{category}/{id:[0-9]+}"). Queries("filter", "{filter}"). HandlerFunc(ArticleHandler). Name("article") url, err := r.Get("article").URL("subdomain", "news", "category", "technology", "id", "42", "filter", "gorilla") ``` ```go r := mux.NewRouter() s := r.Host("{subdomain}.example.com").Subrouter() s.Path("/articles/{category}/{id:[0-9]+}"). HandlerFunc(ArticleHandler). Name("article") url, err := r.Get("article").URL("subdomain", "news", "category", "technology", "id", "42") ``` ```go r := mux.NewRouter() r.Host("{domain}"). Path("/{group}/{item_id}"). Queries("some_data1", "{some_data1}"). Queries("some_data2", "{some_data2}"). Name("article") fmt.Println(r.Get("article").GetVarNames()) ``` -------------------------------- ### Define Advanced Text Placement Source: https://github.com/omniscale/magnacarto/blob/master/README.md Example of using text-placement-list in CartoCSS to define multiple symbolizer configurations for labels. ```css #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]";}; } ``` -------------------------------- ### Implement Authentication Middleware Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Shows how to implement a stateful authentication middleware using a struct to map session tokens to users, and how to register it with the router. ```go type authenticationMiddleware struct { tokenUsers map[string]string } func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("X-Session-Token") if user, found := amw.tokenUsers[token]; found { log.Printf("Authenticated user %s\n", user) next.ServeHTTP(w, r) } else { http.Error(w, "Forbidden", http.StatusForbidden) } }) } amw := authenticationMiddleware{tokenUsers: make(map[string]string)} r.Use(amw.Middleware) ``` -------------------------------- ### Build Map Styles Programmatically Source: https://context7.com/omniscale/magnacarto/llms.txt Demonstrates how to initialize the Magnacarto builder, configure file locators, and generate Mapnik or MapServer styles from MML and MSS files. ```go package main import ( "log" "os" "github.com/omniscale/magnacarto/builder" "github.com/omniscale/magnacarto/builder/mapnik" "github.com/omniscale/magnacarto/config" ) func main() { conf, err := config.Load("magnacarto.tml") if err != nil { log.Fatal(err) } locator := conf.Locator() locator.SetBaseDir("/path/to/project") locator.SetOutDir("/path/to/output") mapnikMap := mapnik.New(locator) b := builder.New(mapnikMap) b.SetMML("/path/to/project.mml") b.AddMSS("/path/to/overrides.mss") if err := b.Build(); err != nil { log.Fatal("Build error:", err) } if err := mapnikMap.Write(os.Stdout); err != nil { log.Fatal("Write error:", err) } } ``` -------------------------------- ### Define Routes with Variables Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Shows how to define URL paths containing dynamic variables and regex patterns. ```go r := mux.NewRouter() r.HandleFunc("/products/{key}", ProductHandler) r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) ``` -------------------------------- ### Custom TOML Unmarshaling with Interfaces in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/BurntSushi/toml/README.md Example of implementing the `encoding.TextUnmarshaler` interface in Go to automatically parse complex values like mail addresses during TOML decoding. ```toml contacts = [ "Donald Duck ", "Scrooge McDuck ", ] ``` ```go package main import ( "fmt" "log" "net/mail" "github.com/BurntSushi/toml" ) // Create address type which satisfies the encoding.TextUnmarshaler interface. type address struct { *mail.Address } func (a *address) UnmarshalText(text []byte) error { var err error a.Address, err = mail.ParseAddress(string(text)) return err } func main() { blob := ` contacts = [ "Donald Duck ", "Scrooge McDuck ", ] ` var contacts struct { Contacts []address } _, err := toml.Decode(blob, &contacts) if err != nil { log.Fatal(err) } for _, c := range contacts.Contacts { fmt.Printf("%#v\n", c.Address) } } ``` -------------------------------- ### Serving Static Files Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Shows how to use PathPrefix and http.StripPrefix to serve static files from a directory. ```APIDOC ## GET /static/* ### Description Serves static files from a local directory mapped to the /static/ URL path. ### Method GET ### Endpoint /static/{filename} ### Request Example ```go r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) ``` ``` -------------------------------- ### Serve RPC Requests with Custom Codec (Go) Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/natefinch/pie/README.md ServeCodec starts the Server's RPC server using a custom encoding mechanism provided by the function f. This call blocks until the client disconnects. ```go func (s Server) ServeCodec(f func(io.ReadWriteCloser) rpc.ServerCodec) ``` -------------------------------- ### Run Unit Tests Source: https://github.com/omniscale/magnacarto/blob/master/README.md Command to execute the Go unit tests for the project. ```bash go test -short ./... ``` -------------------------------- ### Bash: Example cURL request for CORS testing Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md This bash script demonstrates how to make a cURL request to a local server endpoint that is configured with CORS headers. It is useful for testing the CORS implementation and observing the response headers, including Access-Control-Allow-Methods and Access-Control-Allow-Origin. ```bash curl localhost:8080/foo -v ``` -------------------------------- ### Magnaserv REST API Endpoints Source: https://context7.com/omniscale/magnacarto/llms.txt Provides examples of using the Magnaserv REST API to interact with map projects. This includes listing projects, retrieving and updating MML and MCP files, and rendering map tiles or images with various options like custom renderers and MSS file overrides. ```bash # List all available projects curl http://localhost:7070/api/v1/projects # Response: # { # "projects": [ # {"name": "world", "mml": "world.mml", "last_change": "2024-01-15T10:30:00Z"}, # {"name": "roads", "mml": "roads.mml", "last_change": "2024-01-14T09:00:00Z"} # ] # } # Get MML project file content curl http://localhost:7070/api/v1/projects/world.mml # Update MML project file curl -X POST -H "Content-Type: application/json" \ -d @world.mml \ http://localhost:7070/api/v1/projects/world.mml # Get project configuration (.mcp file) curl http://localhost:7070/api/v1/projects/world.mcp # Update project configuration curl -X POST -H "Content-Type: application/json" \ -d '{"bookmarks": [{"name": "Berlin", "bbox": [13.0, 52.3, 13.8, 52.7]}]}' \ http://localhost:7070/api/v1/projects/world.mcp # Render a map tile/image curl "http://localhost:7070/api/v1/map?mml=world.mml&BBOX=-20037508,-20037508,20037508,20037508&WIDTH=256&HEIGHT=256&FORMAT=image/png" \ -o tile.png # Render with specific renderer curl "http://localhost:7070/api/v1/map?mml=roads.mml&RENDERER=mapserver&BBOX=1120261,7086018,1122707,7088464&WIDTH=500&HEIGHT=500" \ -o map.png # Render with MSS files override curl "http://localhost:7070/api/v1/map?mml=project.mml&mss=custom.mss,overrides.mss&BBOX=-180,-90,180,90&WIDTH=800&HEIGHT=600" \ -o custom_map.png ``` -------------------------------- ### Configure Route Matchers in Gorilla Mux Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates various ways to restrict routes using host patterns, path prefixes, HTTP methods, schemes, headers, query parameters, and custom matcher functions. ```go r := mux.NewRouter() r.Host("www.example.com") r.Host("{subdomain:[a-z]+}.example.com") r.PathPrefix("/products/") r.Methods("GET", "POST") r.Schemes("https") r.Headers("X-Requested-With", "XMLHttpRequest") r.Queries("key", "value") r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { return r.ProtoMajor == 0 }) ``` -------------------------------- ### Basic Route Registration Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates how to register basic URL paths and handlers using mux.NewRouter(). ```APIDOC ## Basic Route Registration ### Description This example shows how to create a new router and register simple URL paths to their corresponding handlers. ### Method N/A (Illustrative Go code) ### Endpoint N/A (Illustrative Go code) ### Request Body N/A ### Request Example ```go func main() { r := mux.NewRouter() r.HandleFunc("/", HomeHandler) r.HandleFunc("/products", ProductsHandler) r.HandleFunc("/articles", ArticlesHandler) http.Handle("/", r) } ``` ### Response N/A (Illustrative Go code) ``` -------------------------------- ### Advanced CartoCSS Features Source: https://context7.com/omniscale/magnacarto/llms.txt Demonstrates advanced CartoCSS features supported by Magnacarto, including instances for symbolizer configurations, arithmetic expressions for dynamic styling, and extended text placement options. It also shows examples of regex filters, modulo filters, null comparisons, compositing operations, and geometry transforms. ```css #roads { a/line-color: #000000; a/line-width: 5; b/line-color: #ffffff; b/line-width: 3; } /* Arithmetic expressions */ @base_width: 2; #roads[zoom>=14] { line-width: @base_width * 1.5 + 1; } /* Text placement list (Magnacarto extension) */ #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 attribute (Magnacarto extension) */ #labels { text-name: "[name]"; text-lang: "[lang]"; text-face-name: "Noto Sans Regular"; text-size: 12; } /* Multiple classes on layers */ #roads.highway.major[zoom>=8] { line-color: #ff0000; line-width: 4; } /* Regex filter (supported in Mapnik) */ #places[name =~ ".*ville$"] { text-fill: #0000ff; } /* Modulo filter */ #grid[id % 2 = 0] { line-color: #cccccc; } /* Null comparison */ #features[name = null] { polygon-fill: #eeeeee; } /* Compositing operations */ #overlay { comp-op: multiply; polygon-fill: #ff0000; polygon-opacity: 0.5; } #roads::casing { line-comp-op: darken; line-color: #000000; line-width: 8; } /* Geometry transforms */ #buffers { line-geometry-transform: "translate(2, 2)"; polygon-geometry-transform: "scale(1.1, 1.1)"; } ``` -------------------------------- ### Subrouting and Namespacing Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Demonstrates how to group routes under a common prefix or host using subrouters to optimize matching and organize code. ```APIDOC ## Subrouting ### Description Subrouters allow grouping routes that share common requirements, such as a specific host or a base path prefix, which optimizes request matching. ### Method N/A (Router Configuration) ### Request Example ```go r := mux.NewRouter() s := r.PathPrefix("/products").Subrouter() s.HandleFunc("/", ProductsHandler) // Matches /products/ s.HandleFunc("/{key}/", ProductHandler) // Matches /products/{key}/ ``` ``` -------------------------------- ### Parse MML Project Files Source: https://context7.com/omniscale/magnacarto/llms.txt Demonstrates how to open and parse an MML file, access project metadata, and iterate through layers with their respective datasource configurations. ```go package main import ( "fmt" "log" "os" "github.com/omniscale/magnacarto/mml" ) func main() { file, err := os.Open("project.mml") if err != nil { log.Fatal(err) } defer file.Close() mmlData, err := mml.Parse(file) if err != nil { log.Fatal(err) } fmt.Println("Project name:", mmlData.Name) for _, layer := range mmlData.Layers { fmt.Printf("Layer: %s (type: %s, active: %v)\n", layer.ID, layer.Type, layer.Active) switch ds := layer.Datasource.(type) { case mml.PostGIS: fmt.Printf(" PostGIS: %s@%s:%s/%s\n", ds.Username, ds.Host, ds.Port, ds.Database) case mml.Shapefile: fmt.Println(" Shapefile:", ds.Filename) } } } ``` -------------------------------- ### Route Matching Configuration Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Explains how to apply various constraints to routes such as host patterns, path prefixes, HTTP methods, and custom matcher functions. ```APIDOC ## Route Matching ### Description Routes can be restricted by various criteria including domain, path prefix, HTTP method, URL scheme, headers, and query parameters. ### Method N/A (Router Configuration) ### Parameters - **Host** (string) - Optional - Pattern to match the request domain. - **PathPrefix** (string) - Optional - Matches the beginning of the request path. - **Methods** (...string) - Optional - Restricts to specific HTTP methods (e.g., GET, POST). - **Schemes** (...string) - Optional - Restricts to specific protocols (e.g., https). ### Request Example ```go r.HandleFunc("/products", ProductsHandler).Host("www.example.com").Methods("GET").Schemes("http") ``` ``` -------------------------------- ### Serve Static Files with Mux Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Configures a route to serve static files from a directory using http.StripPrefix and http.FileServer. ```go r := mux.NewRouter() r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) ``` -------------------------------- ### Implement Subrouting for Route Grouping Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Shows how to group routes under a common condition (like a host or path prefix) using subrouters to optimize matching and organize namespaces. ```go r := mux.NewRouter() s := r.PathPrefix("/products").Subrouter() s.HandleFunc("/", ProductsHandler) s.HandleFunc("/{key}/", ProductHandler) s.HandleFunc("/{key}/details", ProductDetailsHandler) ``` -------------------------------- ### Route Registration with Variables Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Illustrates how to define routes with path variables and access them using mux.Vars(). ```APIDOC ## Route Registration with Variables ### Description This example demonstrates defining routes with dynamic path segments (variables) and retrieving these variables within the handler. ### Method N/A (Illustrative Go code) ### Endpoint N/A (Illustrative Go code) ### Parameters #### Path Parameters - **key** (string) - Optional - The dynamic key in the URL path. - **category** (string) - Optional - The dynamic category in the URL path. - **id** (string) - Optional - The dynamic ID in the URL path, must be numeric. ### Request Body N/A ### Request Example ```go r := mux.NewRouter() r.HandleFunc("/products/{key}", ProductHandler) r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Category: %v\n", vars["category"]) } ``` ### Response #### Success Response (200) - **Category** (string) - The extracted category from the URL path. ``` -------------------------------- ### Route Header Regex Matching in Go Source: https://github.com/omniscale/magnacarto/blob/master/vendor/github.com/gorilla/mux/README.md Shows how to use regular expressions to match header values for a route, allowing a single route definition to match multiple Content-Type variations. ```go r := mux.NewRouter() r.HeadersRegexp("Content-Type", "application/(text|json)") ```