How to use a custom style in Maplibre with Kino for Livebook

I’m trying to figure out how to use different json style spec in the Maplibre integration with Kino for Livebook. This works in Livebook:

map = Ml.new(
    style: "https://api.maptiler.com/maps/basic/style.json?key=Q4UbcekCfyvXvZcWRoU"
)

Here is the setup I’m using in the notebook:

Mix.install([:poison, :httpoison, :kino,
  {:maplibre, "~> 0.1.8"},
  {:kino_maplibre, "~> 0.1.11"},
  {:req, "~> 0.4"}])

alias MapLibre, as: Ml

So when that url is used as the value for style it works no problems.

I’m trying to use my own json style spec and I can’t figure out the correct format to us to make the map display.

The guide for Kino Maplibre says I can use either an URL, a map, or preset style :terrain or :streets

So I used :req to retrieve the json that the above working example is using like this:

styleUrl = "https://api.maptiler.com/maps/basic/style.json?key=Q4UbchekCfyvXvZcWRoU"

styleJsonResp = Req.get!(styleUrl)

The body of this response looks like a map that should work as a value for the style key.

styleJson = styleJsonResp.body returns this

    %{
      "filter" => ["==", "class", "grass"],
      "id" => "landcover_grass",
      "paint" => %{"fill-color" => "rgba(192, 213, 169, 1)", "fill-opacity" => 0.4},
      "source" => "openmaptiles",
      "source-layer" => "landcover",
      "type" => "fill"
    },
...

I only included the first few lines so you could get an idea of the format.

This map of the style json looks like it is in the same data structure format as the default style defined in livebook-dev/maplibre/lib/maplibre/styles.ex.

Here’s the first few lines of that style:

 @default %{
    "bearing" => 0,
    "center" => [17.65431710431244, 32.954120326746775],
    "glyphs" => "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
    "id" => "43f36e14-e3f5-43c1-84c0-50a9c80dc5c7",
    "layers" => [
      %{
        "filter" => ["all"],
        "id" => "background",
        "layout" => %{"visibility" => "visible"},
        "maxzoom" => 24,
        "paint" => %{"background-color" => "#D8F2FF"},
        "type" => "background"
      },
      %{
        "filter" => ["all"],
        "id" => "coastline",
        "layout" => %{
          "line-cap" => "round",
          "line-join" => "round",
          "visibility" => "visible"
        },
        "maxzoom" => 24,
        "minzoom" => 0,
        "paint" => %{
          "line-blur" => 0.5,
          "line-color" => "#198EC8",
          "line-width" => %{"stops" => [[0, 2], [6, 6], [14, 9], [22, 18]]}
        },
        "source" => "maplibre",
        "source-layer" => "countries",
        "type" => "line"
      },

My problem comes when I try to use that styleJson in a new Maplibre instance, it displays a canvas where the map should be but the canvas is blank

Ml.new(
  style: styleJson
)

When I look in the browser console, I’m getting errors stating that I’m missing required property “sources” and that I’m missing required property “layers”. These are both in the map of the style json.

I’m not sure how I need to modify the format of this map in order for Maplibre in Kino to properly use it. The style json should be valid as the url to this json file is working. It’s just not displaying anything when I provide the map of the style json to the style key in the Ml.new(XXX) function.

I’m hoping someone can shed some light on this for me.

Thanks,
Leo

You’re not doing anything wrong. It’s just not working as it should. I’ll work on that soon. Or feel free to send a PR!
Thank you!