はじめに
Google Maps API関連の契約が大きく変更され、Open Street Map(以下、OSM)を使うサイトが増えたかなと感じる今日この頃。
OSMは無料で使えるのだけど、少し日本人離れしているデザインなので、自前で環境構築した方がOSM本家に迷惑もかからないし、便利かなと思います。
この記事のサーバ環境は、Amazon Elastic Container Service(以下、ECS)を使っています。
オンプレミスのサーバやローカル環境でも、Dockerが使える環境であれば動かせます。
ベースとなるコンテナイメージは、海外の方が作られたものを、クローンさせて使わさせていただいております。
また、この記事で対象にしているOSMのリージョンは北海道です。
OSMタイルサーバをECSで動かしている記事が見当たらなかったので、思い切って記事にしました。
仕上がりイメージ
北海道大学付近です。めちゃくちゃ賑やかですね。
タイル画像は、ズームレベル20までレンダリングする設定になっていますので、拡大しても綺麗です。
事前準備
ある程度の知識と技術、用意するものが必要です。
Dockerコンテナイメージは、私が用意してあるものをお使いいただけます。
必要な知識
- Dockerに関する知識
- AWSに関する知識
用意するもの
- Dockerコンテナ実行環境
- AWS環境 (VPCやIAM周りの設定が事前に必要なので、各自で用意してくださいね)
マシンスペックは、1コア、2GB程度のメモリが必要です。
サーバ準備
実行環境であるサーバを用意します。
コンソールからやるか、CloudFormation(CFn)でサクッと用意しちゃいましょう。
ECSのクラスタ名は、「osm-tile」にしました。
高スペックなマシーンは不要ですし、お安いスポットインスタンスを有効に使いましょう。
t2.smallくらいのスペックで十分かと思います。
ケチってt2.microにすると、osm2pgsqlでエラーになりました。
ECSは仮想メモリ割り当て設定がないので、ごにょごにょすれば行けそうな気もします。
インポート時のメモリ割り当てを変更するでも良いと思います。
最初のレンダリングには若干時間がかかりますが、キャッシュしてしまえばレスポンスも良いです。
ディスクは、12GBを割り当てています。
リージョンによってはもっと大きい容量が必要ですので、ご注意ください。
北海道は、インポート後5GBくらい、タイルのキャッシュに数GB必要になりますので、不要なタイル画像はクリーニングしましょう。
EBSは、オンラインで拡張することが出来ますので、あまり気にならないかもしれません。
ガチで運用するなら、リザーブドインスタンスにするとか、Blue/Green Deploymentとか、色々とやることはあるのですが、リバースプロキシのキャッシュ機能を使うことも出来るので、要件に応じて各自でいろいろとご検討ください。
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Open Street Map Tile Service ECS Template Spot Instance.'
Parameters:
Ec2KeyName:
Description: EC2 SSH KEY
Type: AWS::EC2::KeyPair::KeyName
Default: HOGEFUGA-KEY
Ec2InstanceType:
Description: EC2 Instance type
Type: String
Default: t2.small
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
ConstraintDescription: must be a valid EC2 instance type.
Ec2ImageId:
Description: amzn-ami-2018.03.h-amazon-ecs-optimized
Type: String
Default: ami-0edf19001c48838c7
Resources:
Ec2InstanceLaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
InstanceType: !Ref 'Ec2InstanceType'
KeyName: !Ref 'Ec2KeyName'
ImageId: !Ref 'Ec2ImageId'
IamInstanceProfile: 'arn:aws:iam::************:instance-profile/ecsInstanceRole'
BlockDeviceMappings:
- DeviceName: '/dev/xvdcz'
Ebs:
VolumeSize: 22
VolumeType: gp2
- DeviceName: '/dev/xvda'
Ebs:
VolumeSize: 12
VolumeType: gp2
SecurityGroups:
- sg-********
AssociatePublicIpAddress: 'false'
InstanceMonitoring: 'false'
SpotPrice: "0.02"
UserData:
Fn::Base64: |
#!/bin/bash
# Specify the cluster that the container instance should register into
cluster=osm-tile
echo ECS_CLUSTER=$cluster >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
# yum
yum -y install jq wget aws-cli
Ec2InstanceAutoScalingGroup2:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- 'subnet-********'
LaunchConfigurationName: !Ref 'Ec2InstanceLaunchConfig'
MinSize: 0
MaxSize: 1
DesiredCapacity: 1
TerminationPolicies:
- OldestInstance
ECSClusterFront:
Type: AWS::ECS::Cluster
Properties:
ClusterName: osm-tile
awscliでスタックを作成します。
コマンドがよく分からない方は、Webコンソール画面からでも利用できます。
$ aws cloudformation create-stack \
--stack-name osm-tile \
--template-body file:///Users/******/osm-tile.yml \
--tags Key=Name,Value=osm-tile \
Key=Author,Value=hogefuga \
--parameters ParameterKey=Ec2KeyName,ParameterValue=HOGEFUGA-KEY \
ParameterKey=Ec2InstanceType,ParameterValue=t2.small
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:************:stack/osm-tile/d04f2e50-f8fb-11e8-ac84-0e2c94******"
}
インスタンス起動まで待ちましょう。3分くらいかかります。
ダッシュボードの表示にインスタンスが増えればOKです。
Dockerコンテナの定義
コンテナイメージは以下のものを使います。
あれ?北海道しかないじゃん!!
そうです。
北海道エリアだけインポートしているので、使用する地域に合わせてDockerfileを変更してください。
ECSを使うので、タスク定義を作成しましょう。
docker-compose.ymlから作成することも出来ます。
- 公式ドキュメント ecs-cli compose
コマンド例
$ ecs-cli compose \
-f docker-compose.yml \
--project-name osm-tile-project \
--cluster osm-tile \
create
リポジトリに置いてありますので、参考にしてください。
https://github.com/akikinyan/melbourne-map/blob/develop/docker-compose.yml
ECSは、相対ディレクトリ指定運用が難しいので、最新のコンテナイメージは相対パス指定を不要にしています。
コンテナ内に、config.jsonファイルを追加しただけなんですけどね。
「./data」はデータボリュームでもOKです。
最近、ECSもデータボリュームが使えるようになりました。
「./renderer」は記述不要としました。
とりあえずそのまま載せておきます。
version: '2'
services:
postgis:
build: ./postgis
image: akikinyan/osm-postgis:latest
volumes:
- ./data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=gis
renderer:
build: ./renderer
image: akikinyan/osm-renderer:latest
volumes:
- ./renderer/map_data:/map_data
- ./renderer/scripts:/scripts
volumes_from:
- postgis:ro
ports:
- "8080:8080"
- "9090:9090"
depends_on:
- postgis
web:
image: nginx:1.11-alpine
volumes:
- ./web:/usr/share/nginx/html
ports:
- "8888:80"
タスク定義
最終的なイメージを載せておきます。
Webコンテナは、別な環境からアクセスするため、作成しませんでした。
最近は、Blue-Green Deploymentの方がいいかなぁと思うので、レンダリング部分とデータベース部分を分離しておいた方が良いかもしれませんが、このOSMコンテナは一緒でも良いような気もします。
ちなみに、Application Load Balancer配下に環境を設置する場合は、ポート番号を適宜変更してください。
試した感じでは、レンダリングサーバが、コンテキストパスを良い感じで処理してくれるようなので、コンテキストパスは任意のもので良さそうです。
(時間の都合でどういう仕組みなのかは把握してないです)
{
"ipcMode": null,
"executionRoleArn": null,
"containerDefinitions": [
{
"dnsSearchDomains": [],
"logConfiguration": {
"logDriver": "none",
"options": null
},
"entryPoint": [],
"portMappings": [],
"command": [],
"linuxParameters": {
"capabilities": {
"add": null,
"drop": null
},
"sharedMemorySize": null,
"tmpfs": null,
"devices": null,
"initProcessEnabled": null
},
"cpu": 0,
"environment": [
{
"name": "POSTGRES_DB",
"value": "gis"
}
],
"ulimits": null,
"dnsServers": [],
"mountPoints": [
{
"readOnly": false,
"containerPath": "/var/lib/postgresql/data",
"sourceVolume": "volume-0"
}
],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": [],
"memory": null,
"memoryReservation": 256,
"volumesFrom": [],
"image": "akikinyan/osm-postgis:latest",
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": [],
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": false,
"dockerLabels": null,
"systemControls": null,
"privileged": false,
"name": "postgis"
},
{
"dnsSearchDomains": [],
"logConfiguration": {
"logDriver": "none",
"options": null
},
"entryPoint": [],
"portMappings": [
{
"hostPort": 8080,
"protocol": "tcp",
"containerPort": 8080
}
],
"command": [],
"linuxParameters": {
"capabilities": {
"add": null,
"drop": null
},
"sharedMemorySize": null,
"tmpfs": null,
"devices": null,
"initProcessEnabled": null
},
"cpu": 0,
"environment": [],
"ulimits": null,
"dnsServers": [],
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": [],
"memory": null,
"memoryReservation": 256,
"volumesFrom": [
{
"sourceContainer": "postgis",
"readOnly": true
}
],
"image": "akikinyan/osm-renderer:latest",
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": [
"postgis:postgis"
],
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": false,
"dockerLabels": null,
"systemControls": null,
"privileged": false,
"name": "renderer"
}
],
"placementConstraints": [],
"memory": null,
"taskRoleArn": null,
"compatibilities": [
"EC2"
],
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:************:task-definition/osm-tile-service:1",
"family": "osm-tile-service",
"requiresAttributes": [
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.25"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "ecs.capability.docker-plugin.local"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
}
],
"pidMode": null,
"requiresCompatibilities": [
"EC2"
],
"networkMode": null,
"cpu": null,
"revision": 1,
"status": "ACTIVE",
"volumes": [
{
"name": "volume-0",
"host": null,
"dockerVolumeConfiguration": {
"autoprovision": true,
"labels": null,
"scope": "shared",
"driver": "local",
"driverOpts": null
}
}
]
}
タスク起動
Dockerコンテナを起動します。
うっかりECSのログ設定を忘れてしまったので、docker-compose upコマンドで起動したログを載せておきます。
t2.mediumインスタンスでテストした時のログですが、データロードまで少し時間がかかります。
[ec2-user@ip-10-1-*-*** melbourne-map]$ docker-compose up
Creating network "melbourne-map_default" with the default driver
Creating volume "melbourne-map_osm-data" with default driver
Pulling web (nginx:1.11-alpine)...
1.11-alpine: Pulling from library/nginx
709515475419: Pull complete
4b21d71b440a: Pull complete
c92260fe6357: Pull complete
ed383a1b82df: Pull complete
Creating melbourne-map_postgis_1_60c7123978a5 ... done
Creating melbourne-map_web_1_1fadfe7b920b ... done
Creating melbourne-map_renderer_1_70ada7233ba7 ... done
Attaching to melbourne-map_postgis_1_6a59f2e4f643, melbourne-map_web_1_c83180b5cf64, melbourne-map_renderer_1_6702d8636309
postgis_1_6a59f2e4f643 | The files belonging to this database system will be owned by user "postgres".
postgis_1_6a59f2e4f643 | This user must also own the server process.
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | The database cluster will be initialized with locale "en_US.utf8".
postgis_1_6a59f2e4f643 | The default database encoding has accordingly been set to "UTF8".
postgis_1_6a59f2e4f643 | The default text search configuration will be set to "english".
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Data page checksums are disabled.
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgis_1_6a59f2e4f643 | creating subdirectories ... ok
postgis_1_6a59f2e4f643 | selecting default max_connections ... 100
postgis_1_6a59f2e4f643 | selecting default shared_buffers ... 128MB
postgis_1_6a59f2e4f643 | selecting dynamic shared memory implementation ... posix
postgis_1_6a59f2e4f643 | creating configuration files ... ok
postgis_1_6a59f2e4f643 | creating template1 database in /var/lib/postgresql/data/base/1 ... ok
postgis_1_6a59f2e4f643 | initializing pg_authid ... ok
postgis_1_6a59f2e4f643 | setting password ... ok
postgis_1_6a59f2e4f643 | initializing dependencies ... ok
postgis_1_6a59f2e4f643 | creating system views ... ok
postgis_1_6a59f2e4f643 | loading system objects' descriptions ... ok
postgis_1_6a59f2e4f643 | creating collations ... ok
postgis_1_6a59f2e4f643 | creating conversions ... ok
postgis_1_6a59f2e4f643 | creating dictionaries ... ok
postgis_1_6a59f2e4f643 | setting privileges on built-in objects ... ok
postgis_1_6a59f2e4f643 | creating information schema ... ok
postgis_1_6a59f2e4f643 | loading PL/pgSQL server-side language ... ok
postgis_1_6a59f2e4f643 | vacuuming database template1 ... ok
postgis_1_6a59f2e4f643 | copying template1 to template0 ... ok
postgis_1_6a59f2e4f643 | copying template1 to postgres ... ok
postgis_1_6a59f2e4f643 | syncing data to disk ...
postgis_1_6a59f2e4f643 | WARNING: enabling "trust" authentication for local connections
postgis_1_6a59f2e4f643 | You can change this by editing pg_hba.conf or using the option -A, or
postgis_1_6a59f2e4f643 | --auth-local and --auth-host, the next time you run initdb.
postgis_1_6a59f2e4f643 | ok
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Success. You can now start the database server using:
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | ****************************************************
postgis_1_6a59f2e4f643 | WARNING: No password has been set for the database.
postgis_1_6a59f2e4f643 | This will allow anyone with access to the
postgis_1_6a59f2e4f643 | Postgres port to access your database. In
postgis_1_6a59f2e4f643 | Docker's default configuration, this is
postgis_1_6a59f2e4f643 | effectively any other container on the same
postgis_1_6a59f2e4f643 | system.
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Use "-e POSTGRES_PASSWORD=password" to set
postgis_1_6a59f2e4f643 | it in "docker run".
postgis_1_6a59f2e4f643 | ****************************************************
postgis_1_6a59f2e4f643 | waiting for server to start....LOG: database system was shut down at 2018-12-06 03:29:20 UTC
postgis_1_6a59f2e4f643 | LOG: MultiXact member wraparound protections are now enabled
postgis_1_6a59f2e4f643 | LOG: database system is ready to accept connections
postgis_1_6a59f2e4f643 | LOG: autovacuum launcher started
postgis_1_6a59f2e4f643 | done
postgis_1_6a59f2e4f643 | server started
postgis_1_6a59f2e4f643 | CREATE DATABASE
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | /usr/local/bin/docker-entrypoint.sh: sourcing /docker-entrypoint-initdb.d/postgis.sh
postgis_1_6a59f2e4f643 | CREATE DATABASE
postgis_1_6a59f2e4f643 | UPDATE 1
postgis_1_6a59f2e4f643 | Loading PostGIS extensions into template_postgis
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | Loading PostGIS extensions into gis
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | CREATE EXTENSION
postgis_1_6a59f2e4f643 | osm2pgsql version 0.92.0 (64 bit id space)
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Using built-in tag processing pipeline
postgis_1_6a59f2e4f643 | Using projection SRS 3857 (Spherical Mercator)
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_point
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_line
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_polygon
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_roads
postgis_1_6a59f2e4f643 | Allocating memory for dense node cache
postgis_1_6a59f2e4f643 | Allocating dense node cache in one big chunk
postgis_1_6a59f2e4f643 | Allocating memory for sparse node cache
postgis_1_6a59f2e4f643 | Sharing dense sparse
postgis_1_6a59f2e4f643 | Node-cache: cache=800MB, maxblocks=12800*65536, allocation method=11
postgis_1_6a59f2e4f643 | Mid: pgsql, scale=100 cache=800
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_nodes
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_ways
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_rels
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Reading in file: /hokkaido-latest.osm.pbf
postgis_1_6a59f2e4f643 | Using PBF parser.
Processing: Node(5880k 294.0k/s) Way(0k 0.00k/s) Relation(0 0.00/s)LOG: checkpoints are occurring too frequently (25 seconds apart)
postgis_1_6a59f2e4f643 | HINT: Consider increasing the configuration parameter "max_wal_size".
Processing: Node(12180k 276.8k/s) Way(0k 0.00k/s) Relation(0 0.00/s)LOG: checkpoints are occurring too frequently (23 seconds apart)
postgis_1_6a59f2e4f643 | HINT: Consider increasing the configuration parameter "max_wal_size".
Processing: Node(18530k 276.6k/s) Way(0k 0.00k/s) Relation(0 0.00/s)LOG: checkpoints are occurring too frequently (23 seconds apart)
postgis_1_6a59f2e4f643 | HINT: Consider increasing the configuration parameter "max_wal_size".
Processing: Node(19702k 281.5k/s) Way(2357k 84.20k/s) Relation(9850 351.79/s) parse time: 126s
postgis_1_6a59f2e4f643 | Node stats: total(19702672), max(6120021395) in 70s
postgis_1_6a59f2e4f643 | Way stats: total(2357510), max(652949469) in 28s
postgis_1_6a59f2e4f643 | Relation stats: total(9853), max(9077199) in 28s
postgis_1_6a59f2e4f643 | Committing transaction for planet_osm_point
postgis_1_6a59f2e4f643 | Committing transaction for planet_osm_line
postgis_1_6a59f2e4f643 | Committing transaction for planet_osm_polygon
postgis_1_6a59f2e4f643 | Committing transaction for planet_osm_roads
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_nodes
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_ways
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_rels
postgis_1_6a59f2e4f643 | Using built-in tag processing pipeline
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_nodes
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_ways
postgis_1_6a59f2e4f643 | Setting up table: planet_osm_rels
postgis_1_6a59f2e4f643 | Using built-in tag processing pipeline
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Going over pending ways...
postgis_1_6a59f2e4f643 | 1860907 ways are pending
postgis_1_6a59f2e4f643 |
postgis_1_6a59f2e4f643 | Using 2 helper-processes
renderer_1_6702d8636309 | Waiting while database is initializing...
renderer_1_6702d8636309 | Waiting while database is initializing...
renderer_1_6702d8636309 | Waiting while database is initializing...
renderer_1_6702d8636309 | Starting renderer
動作確認
URLにアクセスして確認します。
HTML内のタイルの接続先を変更してから接続してみてください。
ローカルにHTMLファイルを作ってアクセスしても良いです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
<script type="text/javascript" src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js"></script>
<style type="text/css">
html, body, #map {
width: 100%;
height: 100%;
margin: 0 !important;
overflow: hidden;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
<script type="text/javascript">
var map = L.map('map').setView([43.06, 141.34], 12);
L.tileLayer('http://localhost:8080/{z}/{x}/{y}.png', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>',
maxZoom: 18
}).addTo(map);
</script>
</html>
リポジトリに上がっている緯度経度の設定が、なぜか南半球になっているので、北半球に移動してください(笑)
カスタマイズ
タイルのカスタマイズについて記載しておきます。
リージョンの変更
ダウンロードするファイルは、Download OpenStreetMap data for this regionから検索可能です。
postgisのDockerfileを修正します。
Dockerイメージが大きくなるので、pbfをコンテナ内に入れなくてもと思っているのですが、元々作ってくれた方の意図をそのままにしています。
ちなみに、北海道と東北、関東と関西のようなリージョンが複数必要な場合、2つ指定してもうまく動きませんのでご注意ください。
FROM mdillon/postgis:9.5
WORKDIR /
RUN apt-get update && \
apt-get install -y osm2pgsql git wget && \
rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/akikinyan/openstreetmap-carto.git
RUN wget http://download.geofabrik.de/asia/japan/hokkaido-latest.osm.pbf
#Overriding init script to add hstore extension that osm2pgsql requires
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/postgis.sh
タイルの細かい変更
Dockerfileファイルを見ると、コンパイルしてからレンダリングエンジンを起動しています。
いろいろ弄りたい方は、別のリポジトリからcloneしている方を弄りましょう。
https://github.com/akikinyan/openstreetmap-carto
Dockerファイルの中を書いておきます。
sh /scripts/compile_style.sh
while [ ! -e /var/lib/postgresql/data/DB_INITED ]
do
sleep 5
echo "Waiting while database is initializing..."
done
#Have to wait because once DB created then osm2pgsql restarting postgres.
#TODO: Using pg_isready
echo "DB successfully created, waiting for restart"
sleep 10
echo "Starting renderer"
sh /scripts/run_render.sh
#!/usr/bin/env bash
# Compiling carto css style and generates OSM xml
# that can be passed to mapnik.
carto /openstreetmap-carto/project.mml > /map_data/stylesheet_.xml
DS='<Parameter name=\"dbname\"><![CDATA[gis]]><\/Parameter>\
<Parameter name=\"host\"><![CDATA[postgis]]><\/Parameter>\
<Parameter name=\"port\"><![CDATA[5432]]><\/Parameter>\
<Parameter name=\"user\"><![CDATA[postgres]]><\/Parameter>\
<Parameter name=\"password\"><![CDATA[postgres]]><\/Parameter>'
sed "s/<Parameter name=\"dbname\">.*<\/Parameter>/${DS}/" /map_data/stylesheet_.xml > /map_data/stylesheet.xml
rm /map_data/stylesheet_.xml
例えば、道路の設定はroads.mssです。
@moterway-fill
とかの部分は、OSMのWikipediaで調べると何者か分かります。
/* For the main linear features, such as roads and railways. */
//road colors for major roads were generated with scripts/generate_road_colors.py
@motorway-fill: #e892a2; // Lch(70,35,10), error 0.5
@trunk-fill: #f9b29c; // Lch(79,33,42), error 0.7
@primary-fill: #fcd6a4; // Lch(88,31,74), error 1.7
@secondary-fill: #f7fabf; // Lch(97,29,106), error 1.7
@tertiary-fill: #ffffff;
@residential-fill: #ffffff;
@service-fill: @residential-fill;
@living-street-fill: #ededed;
@pedestrian-fill: #dddde8;
@raceway-fill: pink;
@road-fill: #ddd;
@footway-fill: salmon;
@steps-fill: @footway-fill;
@cycleway-fill: blue;
@bridleway-fill: green;
@track-fill: #996600;
@aeroway-fill: #bbc;
@runway-fill: @aeroway-fill;
@taxiway-fill: @aeroway-fill;
@helipad-fill: @aeroway-fill;
データの取得はproject.mml
で処理をしているので、ズームレベルに応じた描画以外にも、こちらのファイルの修正が必要となる場合があります。properties
の部分がそれです。
{
"name": "roads-text-name",
"srs-name": "900913",
"geometry": "linestring",
"class": "",
"id": "roads-text-name",
"srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
"Datasource": {
"extent": "-20037508,-20037508,20037508,20037508",
"table": "(SELECT way,\n CASE WHEN substr(highway, length(highway)-3, 4) = 'link' THEN substr(highway, 0, length(highway)-4) ELSE highway END,\n CASE WHEN (tunnel = 'yes' OR tunnel = 'building_passage' OR covered = 'yes') THEN 'yes' ELSE 'no' END AS tunnel,\n CASE WHEN construction IN ('service', 'footway', 'cycleway', 'bridleway', 'path', 'track') THEN 'yes' ELSE 'no' END AS int_construction_minor,\n name\n FROM planet_osm_line\n WHERE highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary', \n 'tertiary_link', 'residential', 'unclassified', 'road', 'service', 'pedestrian', 'raceway', 'living_street', 'construction')\n AND name IS NOT NULL\n) AS roads_text_name",
"geometry_field": "way",
"type": "postgis",
"key_field": "",
"dbname": "gis"
},
"extent": [
-180,
-85.05112877980659,
180,
85.05112877980659
],
"properties": {
"minzoom": 13
},
"advanced": {}
},
反映させるため、プロセス(コンテナ)再起動が必要です。
ECS環境で反映する場合は、最新のコンテナイメージにデプロイし直します。
OSMでルート案内
ルート案内のroutinoを使ってみましたが、時間帯の通行禁止が反映されていないので、地域によっては交通違反になる可能性大です。ご注意ください。
ルート検索を試してみたい方は、私のDockerコンテナイメージをお使いいただけます。
https://hub.docker.com/r/akikinyan/routino-docker
さいごに
GoogleMapの商用利用が安かったら良かったのだけど、実際に見積もってみたら結構な金額になってしまいました。
OSMは、下図としてはそれなりに使えるのですが、検索やルート案内などの機能が弱いです。
それを補うためのインタフェースがあれば、地域によっては十分じゃないかなと言った印象です。