From 5995989a4a634ba3827a2815e6368e30672cba91 Mon Sep 17 00:00:00 2001 From: Cristine Guadelupe Date: Thu, 11 Jan 2024 14:09:59 -0300 Subject: [PATCH] Add terrain --- lib/maplibre.ex | 27 +++++++++++++++++++++------ test/maplibre_test.exs | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/maplibre.ex b/lib/maplibre.ex index 073d372..4c81090 100644 --- a/lib/maplibre.ex +++ b/lib/maplibre.ex @@ -442,7 +442,7 @@ defmodule MapLibre do validate_layer_id!(ml, id) validate_layer_type!(type) - if type != :background, do: validate_layer_source!(ml, source) + if type != :background, do: validate_source!(ml, source, :layer) end defp validate_layer_update!(index, id, layers, ml, opts) do @@ -456,7 +456,7 @@ defmodule MapLibre do type = opts[:type] source = opts[:source] if type, do: validate_layer_type!(type) - if source, do: validate_layer_source!(ml, source) + if source, do: validate_source!(ml, source, :layer) end defp validate_layer_id!(_ml, nil) do @@ -497,17 +497,17 @@ defmodule MapLibre do end end - defp validate_layer_source!(_ml, nil) do + defp validate_source!(_ml, nil, type) do raise ArgumentError, - "layer source is required" + "#{type} source is required" end - defp validate_layer_source!(ml, source) do + defp validate_source!(ml, source, type) do if not Map.has_key?(ml.spec["sources"], source) do sources = Map.keys(ml.spec["sources"]) |> Enum.map_join(", ", &inspect/1) raise ArgumentError, - "source #{inspect(source)} was not found. The source must be present in the style before it can be associated with a layer. Current available sources are: #{sources}" + "source #{inspect(source)} was not found. The source must be present in the style before it can be associated with a #{type}. Current available sources are: #{sources}" end end @@ -588,6 +588,21 @@ defmodule MapLibre do update_in(ml.spec, fn spec -> Map.put(spec, "transition", transition) end) end + @doc """ + Add 3D terrain to the map. + + The source must have been previously added to the map. + + See [the docs](https://maplibre.org/maplibre-style-spec/terrain/) for more + details. + """ + @spec terrain(t(), keyword()) :: t() + def terrain(ml, opts) do + validate_source!(ml, opts[:source], :terrain) + terrain = opts_to_ml_props(opts) + update_in(ml.spec, fn spec -> Map.put(spec, "terrain", terrain) end) + end + @doc """ Adds or updates the map metadata properties. Metadata are arbitrary properties useful to track with the style, but do not influence rendering. Properties should be prefixed to avoid diff --git a/test/maplibre_test.exs b/test/maplibre_test.exs index 87161e6..3bc8977 100644 --- a/test/maplibre_test.exs +++ b/test/maplibre_test.exs @@ -517,4 +517,32 @@ defmodule MapLibreTest do assert ml.spec["metadata"]["meta:data"] == "updated" end end + + describe "terrain/2" do + test "add a terrain to the map" do + ml = + Ml.new(style: %{}) + |> Ml.add_source("terrain", + type: :raster_dem, + url: "https://demotiles.maplibre.org/terrain-tiles/tiles.json" + ) + |> Ml.terrain(source: "terrain") + + assert ml.spec["terrain"] == %{"source" => "terrain"} + end + + test "raises an error if the terrain source does not exist" do + assert_raise ArgumentError, + ~s(source "invalid" was not found. The source must be present in the style before it can be associated with a terrain. Current available sources are: "crimea", "maplibre"), + fn -> + Ml.new() |> Ml.terrain(source: "invalid") + end + end + + test "raises an error if the terrain source is not given" do + assert_raise ArgumentError, "terrain source is required", fn -> + Ml.new() |> Ml.terrain(exaggeration: 1) + end + end + end end