--- /dev/null
+#
+# Cookbook:: imagery
+# Recipe:: za_ngi_aerial
+#
+# Copyright:: 2024, OpenStreetMap Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe "imagery::tiler"
+
+imagery_site "aerial.openstreetmap.org.za" do
+ title "OpenStreetMap - NGI - Aerial Imagery"
+ aliases ["aerial.osm.org.za"]
+ bbox [[-35.12, 16.23], [-22.1, 33.18]]
+ uses_tiler true
+end
+
+imagery_layer "ngi-aerial" do
+ site "aerial.openstreetmap.org.za"
+ uses_tiler true
+ title "NGI Aerial 25cm/50cm"
+ source "https://tiler.openstreetmap.org/za-25cm/mosaic-tiler-https.json"
+ copyright 'State Copyright © 2024 <a href="http://www.ngi.gov.za/">Chief Directorate: National Geo-spatial Information</a>'
+ max_zoom 20
+ extension jpg
+ default_layer true
+ url_aliases ["/ngi-aerial"]
+end
property :revision, Integer, :default => 0
property :overlay, [true, false], :default => false
property :default_layer, [true, false], :default => false
+property :uses_tiler, [true, false], :default => false
action :create do
file "/srv/imagery/layers/#{new_resource.site}/#{new_resource.layer}.yml" do
mode "644"
content YAML.dump(:name => new_resource.layer,
:title => new_resource.title || new_resource.layer,
- :url => "//#{new_resource.site}/layer/#{new_resource.layer}/{z}/{x}/{y}.png",
+ :url => "//#{new_resource.site}/layer/#{new_resource.layer}/{z}/{x}/{y}.#{new_resource.extension}",
:attribution => new_resource.copyright,
:default => new_resource.default_layer,
:maxZoom => new_resource.max_zoom,
group "root"
mode "644"
variables new_resource.to_hash
+ not_if { new_resource.uses_tiler }
end
directory "/srv/imagery/nginx/#{new_resource.site}" do
property :title, String, :required => [:create]
property :aliases, [String, Array], :default => []
property :bbox, Array, :required => [:create]
+property :uses_tiler, [true, false], :default => false
action :create do
directory "/srv/#{new_resource.site}" do
restrict_address_families "AF_UNIX"
# Terminate service after 30mins. Service is socket activated
runtime_max_sec 1800
+ not_if { new_resource.uses_tiler }
end
systemd_socket "mapserv-fcgi-#{new_resource.site}" do
socket_user "imagery"
socket_group "imagery"
listen_stream "/run/mapserver-fastcgi/layer-#{new_resource.site}.socket"
+ not_if { new_resource.uses_tiler }
end
# Ensure service is stopped because otherwise the socket cannot reload
action :nothing
subscribes :stop, "systemd_service[mapserv-fcgi-#{new_resource.site}]"
subscribes :stop, "systemd_socket[mapserv-fcgi-#{new_resource.site}]"
+ not_if { new_resource.uses_tiler }
end
systemd_unit "mapserv-fcgi-#{new_resource.site}.socket" do
action [:enable, :start]
subscribes :restart, "systemd_socket[mapserv-fcgi-#{new_resource.site}]"
+ not_if { new_resource.uses_tiler }
end
ssl_certificate new_resource.site do
service "mapserv-fcgi-#{new_resource.site}" do
provider Chef::Provider::Service::Systemd
action [:stop, :disable]
+ not_if { new_resource.uses_tiler }
end
systemd_service "mapserv-fcgi-#{new_resource.site}" do
action :delete
+ not_if { new_resource.uses_tiler }
end
nginx_site new_resource.site do
return 301 https://$host$request_uri;
}
+<% if @uses_tiler -%>
+upstream tiler_backend {
+ server 127.0.0.1:8080;
+
+ keepalive 32;
+}
+<% else -%>
upstream <%= @name %>_fastcgi {
server "unix:/var/run/mapserver-fastcgi/layer-<%= @name %>.socket" max_fails=0;
# Use default round-robin to distribute requests, rather than pick "fast" but maybe faulty.
# Do not use keepalive
}
+<% end -%>
server {
listen 443 ssl http2;
+<% require 'uri' %>
# DO NOT EDIT - This file is being maintained by Chef
location ~* "^/layer/<%= @layer %>/(\d+)/(\d+)/(\d+)\.(png|jpg|jpeg)$" {
+<% if @uses_tiler -%>
+ set $args "";
+ rewrite ^/layer/<%= @layer %>/(\d+)/(\d+)/(\d+)\.jpg /mosaicjson/tiles/WebMercatorQuad/$1/$2/$3@1x?url=<%= URI.encode_www_form_component(@source) %>&pixel_selection=first&tile_format=jpeg break;
+ rewrite ^/layer/<%= @layer %>/(\d+)/(\d+)/(\d+)\.jpeg /mosaicjson/tiles/WebMercatorQuad/$1/$2/$3@1x?url=<%= URI.encode_www_form_component(@source) %>&pixel_selection=first&tile_format=jpeg break;
+ rewrite ^/layer/<%= @layer %>/(\d+)/(\d+)/(\d+)\.png /mosaicjson/tiles/WebMercatorQuad/$1/$2/$3@1x?url=<%= URI.encode_www_form_component(@source) %>&pixel_selection=first&tile_format=png break;
+ proxy_pass http://tiler_backend;
+ proxy_set_header Host $host;
+ proxy_set_header Referer $http_referer;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto https;
+ proxy_set_header X-Forwarded-SSL on;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ proxy_set_header Cache-Control "";
+ proxy_set_header Pragma "";
+ proxy_redirect off;
+ proxy_cache_key "<%= @layer %><%= @revision %> $request_method $1 $2 $3";
+ proxy_cache proxy_cache_zone;
+ proxy_cache_valid 200 204 180d;
+ proxy_cache_use_stale error timeout updating http_502 http_503 http_504;
+ proxy_cache_background_update on;
+
+<% else -%>
# Override QUERY_STRING to force mapserver query parameters
fastcgi_param QUERY_STRING "map=/srv/imagery/mapserver/layer-<%= @layer %>.map&mode=tile&layers=<%= @layer %>&tilemode=gmap&tile=$2+$3+$1";
fastcgi_pass "<%= @site %>_fastcgi";
fastcgi_next_upstream error timeout invalid_header http_500 http_503;
fastcgi_next_upstream_tries 8;
+<% end -%>
# Do not GZIP tiles
gzip off;
}
}
-upstream tiler_backend {
- server 127.0.0.1:8080;
-
- keepalive 32;
-}
-
-proxy_cache_path /var/cache/nginx-cache levels=1:2 keys_zone=ngi-aerial:64m;
-
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-SSL on;
proxy_http_version 1.1;
- proxy_set_header "Connection" "";
+ proxy_set_header Connection "";
proxy_redirect off;
}
-
- location /ngi-aerial {
- set $args "";
- rewrite ^/ngi-aerial/(\d+)/(\d+)/(\d+)\.jpg /mosaicjson/tiles/WebMercatorQuad/$1/$2/$3@1x?url=https%3A%2F%2Ftiler.openstreetmap.org%2Fza-25cm%2Fmosaic-tiler-https.json&pixel_selection=first&tile_format=jpeg break;
- proxy_pass http://tiler_backend;
- proxy_set_header Host $host;
- proxy_set_header Referer $http_referer;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto https;
- proxy_set_header X-Forwarded-SSL on;
- proxy_http_version 1.1;
- proxy_set_header "Connection" "";
- proxy_redirect off;
- proxy_cache_key "$scheme$proxy_host$uri";
- proxy_cache ngi-aerial;
- proxy_cache_valid 200 204 180d;
- proxy_cache_use_stale error timeout updating http_502 http_503 http_504;
- proxy_cache_background_update on;
- proxy_ignore_headers Cache-Control;
- expires max;
- add_header X-Proxy-Cache $upstream_cache_status;
-
- }
}
}
}
},
+ :nginx => {
+ :proxy => {
+ :enable => true,
+ :keys_zone => "proxy_cache_zone:256M",
+ :inactive => "180d",
+ :max_size => "51200M"
+ }
+ },
:rsyncd => {
:modules => {
:logs => {
"role[gateway]",
"recipe[rsyncd]",
"recipe[dhcpd]",
- "recipe[imagery::tiler]"
+ "recipe[imagery::za_ngi_aerial]"
)