http://www.cnblogs.com/LBSer/p/4451471.html
圖 利用OSM資料簡單釋出的北京地圖服務
一、OSM是什麼
開放街道圖(OpenStreetMap,簡稱OSM)是一個網上地圖協作計劃,目標是創造一個內容自由且能讓所有人編輯的世界地圖(wiki:http://wiki.openstreetmap.org/wiki/Main_Page)。尤其值得稱道的是,osm資料開源,可以自由下載使用。
二、OSM資料結構
OpenStreetMap包括空間資料以及屬性資料。其中空間資料主要包括三種:點(Nodes)、路(Ways)和關係(Relations),這三種原始構成了整個地圖畫面。其中,Nodes定義了空間中點的位置;Ways定義了線或區域;Relations(可選的)定義了元素間的關係。
屬性資料Tags用於描述上述向量資料基元。(http://wiki.openstreetmap.org/wiki/Elements)
2.1. Node
node通過經緯度定義了一個地理座標點。同時,還可以height=*標示物體所海拔;通過layer=* 和 level=*,可以標示物體所在的地圖層面與所在建築物內的層數;通過place=* and name=*來表示物件的名稱。同時,way也是通過多個點(node)連線成線(面)來構成的。
2.2. Way
通過2-2000個點(nodes)構成了way。way可表示如下3種圖形事物(非閉合線(Open polyline )、閉合線(Closed polyline)、區域(Area ))。對於超過2000 nodes的way,可以通過分割來處理。
a)Open polyline
非閉合線:收尾不閉合的線段。通常可用於表示現實中的道路、河流、鐵路等。
b)Closed polyline
閉合線:收尾相連的線。例如可以表示現實中的環線地鐵。
c)Area
區域:閉合區域。通常使用landuse=* 來標示區域等。
2.3. Relation
一個Relation是用來描述兩個或多個基元的相互關係(nodes, ways 或者其他的relations),相互的關係通過role來定義,包括:
a)route :定義公路、自行車道、鐵路等
b)多個多邊形:定義area例如建築、河堤等
c)邊界:裝門用來定義行政邊界
d)限制:用於描述限制比如“非左轉”
2.4. Tag
標籤不是地圖基本元素,但是各元素都通過tag來記錄資料資訊。通過'key' and a 'value'來對資料進行記錄(瞭解xml或者資料庫的應該都比較清楚了吧?)。例如,可以通過highway=residential來定義居住區道路;同時,可以使用附加的名稱空間來新增附加資訊,例如:maxspeed:winter=*就表示冬天的最高限速。
三、OSM資料及下載
osm資料格式主要有以下幾種,可以通過以下網站下載資料。
osm資料格式:
OSM XML – xml-format provided by the API PBF – highly compressed, optimized binary format similar to the API o5m – for high-speed processing, uses PBF coding, has same structure as XML format OSMJSON – json variant of OSM XML |
---|
osm資料下載網站:
GeoFabrik:http://www.geofabrik.de/ Metro Extracts:http://metro.teczno.com/ HOT Exports:http://hot.openstreetmap.org/ BBBike:http://extract.bbbike.org/ |
---|
四、基於OSM資料搭建一個地圖服務
OSM wiki提供了張架構圖,很有價值,我們可以按此架構圖一步步進行探索。
4.1. 資料庫
Postgresql+外掛PostGIS非常適合儲存地理空間資料,上面架構圖的底層資料庫也是此搭配,因此我們也使用此搭配。
a)下載postgresql+postGIS外掛
sudo apt-get install postgresql postgresql-contrib postgis postgresql-9.1-postgis 安裝完畢,我們需要更改postgres使用者的密碼,否則我們就沒法使用這個資料庫伺服器。以postgres這個系統使用者的身份執行psql命令,在終端中輸入如下: sudo su postgres -c psql template1 這時候會出現新的提示符,輸入下面兩個命令,用新密碼替換 <***password***>: ALTER USER postgres WITH PASSWORD ' <***password***> '; |
---|
b)建立使用者及資料庫
postgres# CREATE USER zhanlijun WITH PASSWORD 'xxxx'; postgres# CREATE DATABASE osm; postgres# GRANT ALL PRIVILEGES ON DATABASE osm to zhanlijun; |
---|
c)為資料庫新增空間擴充套件
CREATE EXTENSION postgis; -- Enable Topology CREATE EXTENSION postgis_topology; -- fuzzy matching needed for Tiger CREATE EXTENSION fuzzystrmatch; -- 地理編碼 CREATE EXTENSION postgis_tiger_geocoder; -- 用於儲存屬性tags,key-value CREATE EXTENSION hstore; |
---|
4.2. 匯入資料
從網站上下載的osm資料一般是檔案格式(如xml、pbf等),為了使用我們需要將其匯入到資料庫中,這就需要匯入工具,架構圖使用了osmpsis,但是使用起來並不友好,推薦使用osm2pgsql。
a)安裝osm2pgsql
Run sudo apt-get install software-properties-common to install the command add-apt-repository if the command can't be found. Run sudo add-apt-repository ppa:kakrueger/openstreetmap to add the PPA Run sudo apt-get update to update your packaging system. Run sudo apt-get install osm2pgsql to install the osm2pgsql package. |
---|
b)安裝protobuf(為了匯入pbf格式資料)
sudo apt-get install libprotobuf-c0-dev protobuf-c-compiler |
---|
c)匯入資料庫
osm2pgsql -s -U zhanlijun -d osm /Users/zhanlijun/Downloads/planet_116.104,39.667_116.892,40.066.osm.pbf -H localhost -W; |
---|
注:osm2pgsql匯入資料有兩種模式, normal and slim mode。
normal mode會在記憶體中產生如下三張中間表,並在匯入結束後丟棄,因此速度較快。
- planet_osm_nodes
- planet_osm_ways
- planet_osm_rels
而slim mode則將中間結果完全放置到資料庫中。slim模式的好處是方便更新。
兩者使用的區別在於是否加“-s”,加了表示slimmode,本文使用slim mode。
使用slim mode匯入資料後在資料庫中會產生如下表。
4.3. 渲染
資料已經匯入到postgresql了,下面需要將資料渲染出來,也就是將postgresql中的向量資料渲染成圖片。
4.3.1 使用Mapnik進行渲染
目前最出名的開源地圖渲染引擎莫過於Mapnik。
Mapnik可以渲染多種資料來源,包括資料庫如postgresql,以及檔案格式資料例如shapefile、osm.xml格式等。
這裡以shapefile格式資料為例,下載需要渲染的向量資料:http://www.naturalearthdata.com/
1)開啟python編輯器
1 python
2)匯入mapnik python bindings
1 import mapnik
3)建立地圖
1 m = mapnik.Map(600,300) #建立一個地圖:寬600 高300 2 #m.srs 是該地圖的投影,預設是'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' 3 m.background = mapnik.Color('steelblue') #設定背景色
4)建立樣式
根據我們需求設定樣式,樣式決定了最終渲染的結果。
1 s = mapnik.Style() #style物件 2 r = mapnik.Rule() #rule物件來管理符號 3 #多邊形填充符號 4 polygon_symbolizer = mapnik.PolygonSymbolizer(mapnik.Color('#f2eff9')) 5 r.symbols.append(polygon_symbolizer) 6 #多邊形邊界填充符號 7 line_symbolizer = mapnik.LineSymbolizer(mapnik.Color('rgb(50%,50%,50%)'),0.1) 8 r.symbols.append(line_symbolizer) 9 s.rules.append(r) 10 #將樣式加入地圖 11 m.append_style('My Style',s)
5) 建立資料來源
1 ds=mapnik.Shapefile(file='Users/zhanlijun/Downloads/110m-admin-0-countries/ne_110m_admin_0_countries.shp')
6)建立圖層
mapnik的layer是資料的基礎容器。
1 layer = mapnik.Layer('world')#新建一個叫world的圖層 2 #layer.srs 預設是'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' 3 layer.datasource = ds 4 layer.styles.append('My Style')
7)準備map渲染
1 m.layers.append(layer) #將layer加到地圖 2 m.zoom_all() #將資料zoom_all,如果不用,結果將是空白
8)渲染地圖
最後我們得到一張png格式的世界地圖:world.png
4.3.2 使用TileMill進行渲染
Mapnik使用起來並不容易,尤其是配置樣式的時候,下面我們使用TileMill進行渲染,TileMill的核心是Mapnik。
TileMill的好處是所見即所得,右邊配置樣式,左邊能馬上顯示出結果。此外還可以將結果展示出來(下圖就是利用TileMill渲染北京osm資料的結果)。
4.4 一體化解決方案
GeoServer + OpenLayers +PostGIS疊加顯示動態向量資料。
安裝geoserver
sudo apt-get update sudo apt-get install unzip openjdk-6-jre echo "export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64" >> ~/.bashrc source ~/.bashrc wget -c http://sourceforge.net/projects/geoserver/files/GeoServer/2.3.5/geoserver-2.3.5-bin.zip unzip -a geoserver-2.3.5-bin.zip cd geoserver-2.3.5/bin ./startup.sh & |
---|