이 글은 OSM(OpenStreetMap) 타일 서버 개발하는 예제를 간략히 다룬다.
타일 서버 개발 결과
OSM이란
OSM은 전세계 지도를 커버하는 사용자가 작성하는 맵이다. OSM은 매분 업데이트되고, 무료이다. 그리고, 상세한 데이터를 제공한다. 참고로, 이 예제는 우분투 기반으로 실습한다.
HW 환경
영국 지도만 4G RAM, 60GB 디스크가 필요하다. 전체 planet map은 32G RAM, 1TB SSD가 필요하다.
소프트웨어 준비
sudo apt update; sudo apt upgrade
PostgreSQL Database Server와 PostGIS Extension 설치
다음과 같은 명령을 통해 PostgreSQL DB와 PostGIS 확장을 설치한다.
sudo apt install postgresql postgresql-contrib postgis postgresql-10-postgis-2.4
sudo -u postgres -i
createuser osm
createdb -E UTF8 -O osm gis
psql -c "CREATE EXTENSION postgis;" -d gis
psql -c "CREATE EXTENSION hstore;" -d gis
Set osm as the table owner.
psql -c "ALTER TABLE spatial_ref_sys OWNER TO osm;" -d gis
Exit from the postgres user.
exit
sudo adduser osm
맵 스타일시트와 맵 데이터 다운로드
맵 데이터를 다음 명령으로 다운로드 한다.
su - osm
wget https://github.com/gravitystorm/openstreetmap-carto/archive/v4.20.0.tar.gz
tar xvf v4.20.0.tar.gz
만약 planet data 다운로드하려면 아래와 같이 진행한다.
wget -c http://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
다음은 영국지도이고 다운로드를 위해서는 985M 용량이 필요하다.
wget -c http://download.geofabrik.de/europe/great-britain-latest.osm.pbf
Exit from osm user.
exit
맵 데이터 임포트
맵 용량이 크므로 swap file을 조정한다.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
Output:
Setting up swapspace version 1, size = 2097148 KiB
no label, UUID=h32b3e10-0779-4865-9ea0-6e2af8f3kea9
Enable the swap file
sudo swapon /swapfile
sudo nano /etc/ssh/ssh_config
ServerAliveInterval 60
PostgreSQL에 맵 데이터 임포트
맵 데이터 임포트를 위해, osm2pgsql을 사용해 OSM 데이터를 postGIS 지원용 PostgreSQL DB로 변환한다.
sudo apt install osm2pgsql
su - osm
osm2pgsql --slim -d gis --hstore --multi-geometry --number-processes 8 --tag-transform-script /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.lua --style /home/osm/openstreetmap-carto-4.20.0/openstreetmap-carto.style -C 12000 /home/osm/great-britain-latest.osm.pbf
exit
mod_tile와 Renderd 설치
다음과 같이 mod-tile과 renderd를 설치한다.
sudo add-apt-repository ppa:osmadmins/ppa
sudo apt install libapache2-mod-tile renderd
systemctl status renderd
Mapnik Stylesheet 생성
다음과 같이 mapnik과 sytlesheet를 생성한다.
sudo apt install curl unzip gdal-bin mapnik-utils libmapnik-dev nodejs npm
sudo npm install -g carto
su - osm
cd /home/osm/openstreetmap-carto-4.20.0/
scripts/get-shapefiles.py
carto project.mml > style.xml
exit
Fonts 설치
맵에 사용될 폰트로 설치한다.
sudo apt install ttf-dejavu
sudo apt install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont
renderd 설정
renderd를 다음과 같이 설정한다.
sudo nano /etc/renderd.conf
num_threads=4
XML=/home/osm/openstreetmap-carto-4.20.0/style.xml
HOST=map.your-domain.com
plugins_dir=/usr/lib/mapnik/3.0/input/
mapnik-config --input-plugins
font_dir=/usr/share/fonts/truetype
font_dir_recurse=true
sudo nano /etc/init.d/renderd
RUNASUSER=osm
renderd를 실행한다.
sudo chown osm:osm /var/lib/mod_tile/ -R
sudo systemctl daemon-reload
sudo systemctl restart renderd
sudo journalctl -eu renderd
Apache 설정
아파치 웹 서버를 설정한다.
sudo nano /etc/apache2/sites-available/tileserver_site.conf
ServerName map.yourdomain.com
sudo systemctl restart apache2
map.your-domain.com/osm/0/0/0.png
osm-tile-for-world-map
Tiled Web Map 표시
openlayers를 다운로드해 설치한다.
cd /var/www/
sudo wget https://github.com/openlayers/openlayers/releases/download/v5.3.0/v5.3.0.zip
sudo unzip v5.3.0.zip
index.html file 생성
index파일을 아래와 같이 수정한다.
sudo nano /var/www/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Accessible Map</title>
<link rel="stylesheet" href="http://map.yourdomain.com/v5.3.0/css/ol.css" type="text/css">
<script src="http://map.yourdomain.com/v5.3.0/build/ol.js"></script>
<style>
a.skiplink {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
padding: 0;
border: 0;
height: 1px;
width: 1px;
overflow: hidden;
}
a.skiplink:focus {
clip: auto;
height: auto;
width: auto;
background-color: #fff;
padding: 0.3em;
}
#map:focus {
outline: #4A74A8 solid 0.15em;
}
</style>
</head>
<body>
<a class="skiplink" href="#map">Go to map</a>
<div id="map" class="map" tabindex="0"></div>
<button id="zoom-out">Zoom out</button>
<button id="zoom-in">Zoom in</button>
<script>
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: 'http://map.yourdomain.com/osm/{z}/{x}/{y}.png'
})
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: [244780.24508882355, 7386452.183179816],
zoom:5
})
});
document.getElementById('zoom-out').onclick = function() {
var view = map.getView();
var zoom = view.getZoom();
view.setZoom(zoom - 1);
};
document.getElementById('zoom-in').onclick = function() {
var view = map.getView();
var zoom = view.getZoom();
view.setZoom(zoom + 1);
};
</script>
</body>
</html>
다음과 같이 leaflet 패키지를 설치한다.
cd /var/www/
sudo wget http://cdn.leafletjs.com/leaflet/v1.4.0/leaflet.zip
sudo unzip leaflet.zip
index파일에 leaflet을 사용할 수 있도록 지정한다.
sudo nano /var/www/index.html
<html>
<head>
<meta charset="UTF-8">
<title>My first osm</title>
<link rel="stylesheet" type="text/css" href="leaflet.css"/>
<script type="text/javascript" src="leaflet.js"></script>
<style>
#map{width:100%;height:100%}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map').setView([53.555,9.899],5);
L.tileLayer('http://map.yourdomain.com/osm/{z}/{x}/{y}.png',{maxZoom:18}).addTo(map);
</script>
</body>
</html>
map.yourdomain.com/index.html
지도 타일을 렌더링한다.
render_list -m default -a -z 0 -Z 15 --num-threads=8
render_list -m default -a -z 0 -Z 15 --num-threads=8 --force
sudo add-apt-repository ppa:certbot/certbot
sudo apt install certbot
sudo apt install python3-certbot-apache
sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --must-staple --email
osm tile server ubuntu 18.04 install
sudo a2enmod http2
sudo nano /etc/apache2/sites-enabled/tileserver_site-le-ssl.conf
Protocols h2 http/1.1
sudo systemctl restart apache2
nano /home/osm/openstreetmap-carto-4.20.0/project.mml
osm2pgsql: &osm2pgsql
type: "postgis"
dbname: "gis"
key_field: ""
geometry_field: "way"
extent: "-20037508,-20037508,20037508,20037508"
Specify the IP address of PostgreSQL database server.
osm2pgsql: &osm2pgsql
type: "postgis"
host: "10.0.0.2"
dbname: "gis"
key_field: ""
geometry_field: "way"
extent: "-20037508,-20037508,20037508,20037508"
스타일을 설정하고, postgresql과 renderd를 재시작한다.
carto project.mml > style.xml
sudo nano /etc/postgresql/10/main/postgresql.conf
sudo nano /etc/postgresql/10/main/pg_hba.conf
host gis osm 10.0.0.1/32 trust
sudo systemctl restart postgresql
sudo systemctl restart renderd
sudo journalctl -eu renderd
sudo ufw allow in from 10.0.0.1 to any port 5432
레퍼런스
댓글 없음:
댓글 쓰기