Saya baru di dunia GIS yang menakjubkan, dan saya telah meneliti seluruh topik selama beberapa hari terakhir. Tujuan saya adalah melayani peta seluruh dunia dengan data OSM di server saya sendiri.
Tumpukan saya adalah:
- Postgres + Postgis - Untuk menyimpan, mengubah dan memproses data GIS.
- Mapnik - Perpustakaan untuk membuat ubin
- Tilestache - Sajikan dan tembolok ubin
- Nginx - Membalikkan proxy ke Tilestache
- Leaflet ( klien peta Slippy )
Untuk mengimpor dan menata data OSM, saya menggunakan
- File PBF (Ekstrak / Planet)
- osm2pgsql
- CartoCSS
- openstreetmap-carto
- Kosmtik - GUI Peta untuk pengembangan / debugging
Karena file planet lengkap sangat besar, saya saat ini menggunakan ekstrak Sao Paulo , yang bagus / cukup kecil untuk pengujian.
Sebelum saya mencapai masalah yang saya alami, saya akan memandu melalui langkah-langkah yang saya ambil sejauh ini:
Apa yang berhasil
PostgreSQL dan PostGIS terinstal dengan benar. Saya menggunakan 9,6 untuk yang pertama, 2,3 untuk yang terakhir. Saya juga telah menambahkan postgis_topology
dan hstore
ekstensi, yang akan digunakan nanti.
Saya telah menginstal osm2pgsql 0.92.0. Untuk mengimpor ekstrak Sao Paulo, saya menggunakan
osm2pgsql -G U <user> -d <db> -C 1000 -W --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua <pbf>
The hstore
, style
dan tag-transform-script
argumen yang diperlukan untuk pemanfaatan yang tepat dari gaya OSM, seperti dijelaskan di sini .
Seperti dijelaskan pada instalasi openstreetmap-carto, saya juga menambahkan indeks khusus dan mengunduh bentuk dan huruf yang diperlukan (kecuali untuk emoji).
Saya memverifikasi data ekstrak dimuat dengan benar di database dengan menggunakan QGIS. Saya dapat melihat dan meminta dengan semua titik, poligon, garis, dan jalan. Semua ada di sana.
Masalah
Langkah selanjutnya adalah merender ubin, dan di situlah saya mengalami kesulitan. Saya memiliki mapnik dan python-mapnik 3.x, serta carto 0.18.2.
Dari project.mml OSM , saya telah menghasilkan project.xml saya sendiri carto
. Saya telah membuat perubahan berikut pada hasilnya:
- Tambahkan nama pengguna Postgres (Parameter
user
pada Mapnik's XML ). Info koneksi yang tersisa diambil dari ~ / .pgpass . - Ganti direktori relatif
data/<shape>.shp
ke/full/path/data/<shape>.shp
- Ganti direktori relatif
symbols/<symbol>.svg
ke/full/path/symbols/<symbol>.svg
Saya mengurutkan unit yang menguji perubahan ini: direktori yang salah untuk shapefile dan simbol akan memunculkan kesalahan ketika Mapnik mencoba memuat gaya. Hal yang sama berlaku untuk informasi DB yang salah.
Dan inilah masalahnya: setiap ubin yang diberikan oleh Mapnik adalah "kosong" (latar belakang blue-ish, yang merupakan latar belakang yang ditentukan untuk OSM). Inilah yang saya coba untuk memperbaiki masalah ini:
Hal yang sudah saya coba
Mungkin entah bagaimana gaya yang dihasilkan tidak valid. Mungkin beberapa poligon / bentuk (lautan?) Menutupi yang lain.
Saya telah menginstal Kosmtik, dan itu berfungsi dengan baik! Saya dapat menelusuri ekstrak, memeriksa data, memperbesar dan memperkecil pada semua tingkatan.
Mungkin saya menghasilkan ubin di lokasi yang salah
Saya telah menyiapkan TileStache dengan Mapnik sebagai penyedia. Kemudian, saya telah menyiapkan aturan redirect dari http://[abc].tile.openstreetmap.org
ke http://myserver/<layer>
menggunakan switcheroo, seperti yang dijelaskan di sini . Ini berarti bahwa mengakses openstreetmaps.org
semua ubin akan diberikan di server saya.
Yang menarik, zoom 1 berfungsi (yang memiliki 4 ubin). Saya kira itu hanya menggunakan shapefile planet / dunia, yang diunduh dengan gaya. Semua yang lain, apa pun zoom atau lokasinya, menjadikan "kosong". Jadi, bahkan ketika menjelajah di lokasi ekstrak, itu tidak akan merender dengan benar.
Perhatikan bahwa, ketika menggunakan Kosmtik, saya dapat melihat nama ekstrak dari serendah zoom 4.
Mungkin aku sedang menghasilkan ubin di lokasi yang salah
Proyeksi sulit. Mungkin ada sesuatu yang "salah diterjemahkan" di suatu tempat.
Jadi saya menganalisis permintaan yang dibuat Kosmtik (karena ini berfungsi). Ini menggunakan perpustakaan Modestmaps, yang diterjemahkan ke format Slippy ( <zoom>/<x>/<y>
), format yang sama yang digunakan oleh Leaflet, TileStache dan openstreetmap.org
.
Misalnya, meminta 17/48561/74357.png
karya Kosmtik, tetapi ubin yang sama kembali sebagai "kosong" di TileStache. Teori saya adalah entah bagaimana TileStache menerjemahkannya ke koordinat lain, di luar area ekstrak. (Meskipun TileStache menggunakan "spherical mercator" sebagai proyeksi).
Jadi saya telah memutuskan untuk menggunakan binding python Mapnik secara langsung. Sejauh ini saya sudah menangani tiga jenis proyeksi, inilah yang saya tahu tentang mereka. Harap perbaiki saya jika saya salah:
- EPSG4326 / WGS84 - Proyeksi lon / lat biasa, sama seperti yang digunakan pada GPS. Unit adalah derajat.
- EPSG3857 / {Web, Google, Pseudo} mercator / 900913 - Digunakan pada sebagian besar peta web ubin. Unit dalam meter (bukan "nyata" meter, karena sangat terdistorsi di dekat kutub).
- "Slippy format" - Bukan proyeksi, tetapi format lain yang harus diterjemahkan.
Jadi, Slippy 17/48561/74357
akan dekat -46.632(lon), -23.531(lat)
pada EPSG4326, dan dekat -5191050.49, -2696361.67
pada EPSG3875 / Google mercator.
Menggunakan python, saya telah menghasilkan petak koordinat ini langsung di Mapnik. Hasilnya selalu ubin kosong. Saya percaya saya menggunakan proyeksi yang benar (lebih lanjut tentang ini nanti).
Pertama, satu hal yang perlu diperhatikan. Jelas masalahnya bukan di Mapnik, atau gaya. Pertama, Kosmtik menggunakan Mapnik sebagai backend, dan berfungsi dengan baik. Kedua, jika saya sengaja membuat ubin di luar area ekstrak di Kostmik, saya mendapatkan ubin kosong, seperti yang diharapkan.
Ini membuat saya percaya bahwa saya menggunakan proyeksi yang salah pada skrip python dan TileStache Mapnik. Sebelum menunjukkan kode, satu komentar tentang OSM (sekali lagi, tolong perbaiki saya jika saya salah):
- Data "asli" OSM disimpan dalam EPSG4326
- osm2pgsql mengimpor data OSM sebagai EPSG3857, dan itulah proyeksi pada Postgis.
- Gaya Mapnik (XML) memiliki dua proyeksi, input dan output, dijelaskan di sini :
- Input proyeksi didefinisikan pada objek Peta, dan merupakan "sistem koordinat di mana peta diberikan"
- Proyeksi keluaran didefinisikan pada objek Layer, dan harus sama dengan data saya.
XML Mapnik saya yang dihasilkan memiliki:
<Map 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" background-color="#b5d0d0">
#snip#
<Layer name="world" #snip# 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">
Jadi, seperti yang saya lihat, proyeksi input dan output dalam "merc" (3857), dan itu benar! Data saya disimpan dengan 3857, dan peta yang dihasilkan diharapkan pada 3857.
Akhirnya, inilah beberapa panggilan Mapnik berbeda yang pernah saya coba:
Box2d dengan 3857 koordinat:
map = mapnik.Map(800, 800)
bbox = Box2d(-5191050.49, -2696361.67, -5191059.49, -2696370.70)
mapnik.load_map(map, '/path/to/style.xml')
map.zoom_to_box(bbox)
mapnik.render_to_file(map, 'output.png') # Blank
Box2d dengan 4326 koordinat diubah menjadi 3857
merc = mapnik.Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
bbox = mapnik.Box2d(-23.53, -46.63, -24.03, -47.03)
transform = mapnik.ProjTransform(longlat, merc)
merc_bbox = transform.forward(bbox)
# load, zoom, render -> Blank
Saya juga sudah mencoba dengan gaya yang berbeda. Hasilnya selalu kosong, tetapi itu tidak terduga karena saya percaya koordinat ini akan berada dalam ekstrak saya. Saat mencoba membuat koordinat di luar ekstrak, itu benar dirender sebagai kosong.
Lagi pula, saya tersesat dan saya bertanya-tanya apakah ada yang bisa menjelaskan, saya pasti kehilangan sesuatu. Namun sejauh ini, saya telah berjuang dengan masalah ini selama lebih dari 24 jam dan saya tidak tahu apa yang salah.