]> git.openstreetmap.org Git - rails.git/blob - lib/map_layers.rb
Merge remote-tracking branch 'upstream/pull/6798'
[rails.git] / lib / map_layers.rb
1 # frozen_string_literal: true
2
3 module MapLayers
4   def self.full_definitions(layers_filename, legends: nil)
5     legended_layers = YAML.load_file(Rails.root.join(legends)).keys if legends
6     YAML.load_file(Rails.root.join(layers_filename))
7         .filter_map do |layer|
8           begin
9             if layer["isVectorStyle"]
10               layer["style"] = insert_api_key(layer, "styleUrl")
11               layer["styleDark"] = insert_api_key(layer, "styleUrlDark") if layer["styleUrlDark"]
12             else
13               layer["style"] = style_from_tile_url(layer, "tileUrl")
14               layer["styleDark"] = style_from_tile_url(layer, "tileUrlDark") if layer["tileUrlDark"]
15               layer["url"] = insert_api_key(layer, "tileUrl")
16               layer["urlDark"] = insert_api_key(layer, "tileUrlDark") if layer["tileUrlDark"]
17               layer.delete "leafletOsmId"
18               layer.delete "leafletOsmDarkId"
19             end
20           rescue StandardError => e
21             Rails.logger.error "Error processing layer #{layer['layerId']}: #{e.message}"
22             next
23           end
24           layer["hasLegend"] = true if legended_layers&.include?(layer["layerId"])
25           layer.delete "apiKeyId"
26           layer.delete "styleUrl"
27           layer.delete "styleUrlDark"
28           layer.delete "tileUrl"
29           layer.delete "tileUrlDark"
30           layer
31         end
32   end
33
34   def self.embed_definitions(layers_filename)
35     full_definitions(layers_filename)
36       .select { |entry| entry["canEmbed"] }
37       .to_h { |entry| [entry["layerId"], entry.slice("url", "urlDark", "subdomains").compact] }
38   end
39
40   def self.insert_api_key(layer, key)
41     if layer[key].include?("{apikey}") && !Settings[layer["apiKeyId"]]
42       raise "API key for #{layer['apiKeyId']} is required but not set in settings."
43     elsif layer[key].include?("{apikey}")
44       layer[key].sub("{apikey}", Settings[layer["apiKeyId"]])
45     else
46       layer[key]
47     end
48   end
49
50   def self.style_from_tile_url(layer, key)
51     url_template = insert_api_key(layer, key)
52
53     tiles = if layer["subdomains"]
54               layer["subdomains"].map { |server| url_template.sub("{s}", server) }
55             else
56               [url_template]
57             end
58
59     {
60       :version => 8,
61       :sources => {
62         "raster-tiles-#{layer['layerId']}" => {
63           :type => "raster",
64           :tiles => tiles,
65           :tileSize => 256,
66           :maxzoom => layer["maxZoom"]
67         }
68       },
69       :layers => [
70         {
71           :id => "raster-tiles-layer-#{layer['layerId']}",
72           :type => "raster",
73           :source => "raster-tiles-#{layer['layerId']}"
74         }
75       ]
76     }
77   end
78 end