開源軟體在地圖資料處理中的應用
作為開源軟體的受益者,在享受開源帶來的技術便利同時,我們也積極擁抱開源,同時也回饋開源。城市交通指數(TTI)作為公司第16個開源專案,透過蓋亞計劃對外開放了脫敏資料,下載人員分佈於127個高校或科研機構,覆蓋了70%的雙一流高校。
在地圖資料處理中,能經常看到開源軟體的身影,常見的有以下幾項:
- GDAL (Geospatial Data Abstraction Library)
GDAL是一個在X/MIT許可協議下的空間柵格資料轉換庫,OGR是GDAL專案的一個分支,其提供對向量資料的支援。柵格資料和向量資料是地圖資料中兩種較為常見的資料格式,通俗的理解,柵格資料用畫素來表達,向量資料用座標點來表達。常見的柵格資料有遙感影像、掃描地圖等。常見的向量資料有各種點、線、面資料,如POI、路網、水系或湖泊。GDAL可以很方便的對柵格或向量資料進行讀寫操作。
GDAL讀取遙感影像示例程式碼:
GDALDataset* pDataSet = (GDALDataset*)GDALOpen("/Users/didi/Desktop/test.img",GA_ReadOnly);
//仿射變換6引數
double geoTransform[6] = {0};
pDataSet->GetGeoTransform(geoTransform);
//影像寬
int nWidth = pDataSet->GetRasterXSize();
//影像高
int nHeight = pDataSet->GetRasterYSize();
//畫素值矩陣
unsigned char* pPixelValue = (unsigned char *)malloc(sizeof(unsigned char) * nWidth * nHeight);
memset(pPixelValue,0,nWidth * nHeight);
CPLErr err = pDataSet->RasterIO(GF_Read,0,0,nWidth,nHeight,pPixelValue,nWidth,nHeight,GDT_Byte,1,NULL,0,0,0);
free(pPixelValue);
GDALClose(pDataSet);
GDAL中有一些很實用的影像處理演算法,如GDALSimpleSURF類可以實現特徵點檢測以及匹配,GDALSieveFilter可以刪除4連通或8連通的畫素多邊形(具有相同畫素值的連通區域),如砂眼噪聲。如下圖所示
圖1 處理前
圖2 處理後
OGR讀取向量資料示例程式碼:
GDALDataset* pDS = (GDALDataset*) GDALOpenEx("/Users/didi/Desktop/test.shp", GDAL_OF_VECTOR | GDAL_OF_READONLY, NULL, NULL, NULL );
OGRLayer* pLayer = pDS->GetLayer(0);
OGRFeature *pFeature = NULL;
pLayer->ResetReading();
while((pFeature = pLayer->GetNextFeature()) != NULL ){
//獲取幾何資訊
OGRGeometry* pGeom = pFeature->GetGeometryRef();
//獲取欄位Length的值
double dfLength = pFeature->GetFieldAsDouble("Length");
OGRFeature::DestroyFeature(pFeature);
}
//關閉資料集
GDALClose(pDS);
-
GEOS(Geometry Engine Open Source)
GEOS是非常經典的空間拓撲關係運算庫,一些演算法效能不亞於商業GIS軟體。GDAL讀取到向量資料的幾何資訊後,在進行空間運算或拓撲判斷時,就需要GEOS的支援了。一般情況下,在編譯GDAL原始碼時直接將GEOS編譯進去,也可以把GDAL中的幾何類轉換成GEOS的幾何類,這樣就可以直接使用GEOS庫進行資料處理。使用GEOS可以很方便的計算兩個幾何物件的差集、交集、對稱差、緩衝區。有時候我們需要將多個相鄰的多邊形合併成一個多邊形,常規用法是使用union方法,將其合併,當待合併的多邊形個數較多時,效率就會非常的低,這裡我們可以使用計算緩衝區的方法進行處理,效率會提升很多。
圖3 待合併多邊形
圖4 合併結果圖
示例程式碼:
//藍色多邊形
char* szWKT_1 = "POLYGON ((113.885 22.6815, 113.9425 22.6585, 113.91 22.7, 113.885 22.6815))";
//橙色多邊形
char* szWKT_2 = "POLYGON ((113.91 22.7, 113.9425 22.6585, 113.9675 22.689, 113.91 22.7))";
OGRGeometry* pGeom_1 = NULL;
OGRGeometry* pGeom_2 = NULL;
OGRGeometryFactory::createFromWkt(&szWKT_1, NULL, &pGeom_1);
OGRGeometryFactory::createFromWkt(&szWKT_2, NULL, &pGeom_2);
OGRMultiPolygon* pMultiPolygon = (OGRMultiPolygon*)OGRGeometryFactory::createGeometry(wkbMultiPolygon);
pMultiPolygon->addGeometryDirectly(pGeom_1);
pMultiPolygon->addGeometryDirectly(pGeom_2);
//用Buffer替代Union,緩衝距離設定為0
//pUnion為紫色多邊形
OGRGeometry* pUnion = pMultiPolygon->Buffer(0);
- PROJ.4
Proj.4是開源GIS中最著名的地圖投影庫,許多GIS開源軟體的投影都直接使用Proj.4的庫檔案。主要功能有投影座標與地理座標的轉換,座標系的轉換,基準變換等。WGS84座標系是我們最常用的座標系,GPS軌跡點就是地理座標系。有些時候我們需要基於投影座標系做一些數學運算,即高斯正算。如長度計算。這裡取以3°分帶,中央經線為117°的區域內的一條link來說明:
圖5 3度分帶圖
siwei_id:9000025617988
地理座標:LINESTRING (116.9710037 36.6434771,116.97049 36.64324,116.97014 36.64304,116.96921 36.64244,116.96787 36.64177)
投影座標:LINESTRING (497406.947036178 4057018.36084719,497361.000282045 4056992.06317016,497329.693821681 4056969.87826856,497246.504857284 4056903.32080414,497126.64614413 4056829.00824338),在投影座標下,我們可以直接使用兩點之間距離公式來計算這條link的長度,length=339米。
- libSpatialindex
libspatialindex是一種高效的C++空間索引庫。支援複雜查詢,如範圍查詢、點位置查詢、 最近鄰查詢、K鄰近查詢以及引數化查詢。建立記憶體空間索引示例程式碼:
IStorageManager* diskfile = StorageManager::createNewMemoryStorageManager();
StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
double fillFactor = 0.7;
uint32_t indexCapacity = 10;
uint32_t leafCapacity = 10;
uint32_t dimension = 2;
RTree::RTreeVariant variant = RTree::RV_RSTAR;
id_type indexIdentifier;
ISpatialIndex* tree = RTree::createNewRTree(*file, fillFactor, indexCapacity, leafCapacity, dimension, variant, indexIdentifier);
x1 = enve.MinX;
y1 = enve.MinY;
x2 = enve.MaxX;
y2 = enve.MaxY;
plow[0] = x1;
plow[1] = y1;
phigh[0] = x2;
phigh[1] = y2;
//r為幾何物件的外接矩形,id為唯一的識別符號,為長整型
Region r = Region(plow, phigh, 2);
tree->insertData(0, 0, r, id);
delete tree;
delete file;
delete diskfile;
- SpatiaLite
SQLite是一款很小巧的關聯式資料庫,經常被整合在各種移動應用程式中,為了擴充SQLite的空間資料儲存功能,基於SQLite的核心,增加了空間SQL功能。 SpatiaLite使用RTree作為空間索引,對一張表建立空間索引後,可以進行高效的空間查詢處理。建立空間索引示例程式碼:select CreateSpatialIndex('table_name', 'column_name')
- PCL(Point Cloud Library)
鐳射點雲是近些年使用較多一種地圖向量資料,可以高效獲取目標的三維座標。由於其高昂的配套裝置價格,只有少數圖商能玩的起。對於3D點雲處理來說,PCL完全是一個模組化的C++模板庫,基於第三方庫實現點雲相關的獲取、濾波、分割、配準、檢索、特徵提取、識別、追蹤、曲面重建、視覺化等。
- PostGIS
PostGIS只是PostgreSQL的一個外掛,但是它將PostgreSQL變成了一個強大的空間資料庫。PostGIS具有優異的空間查詢效能,如果說Spatialite、libspatialindex等空間資料儲存工具是一艘軍艦,那麼PostGIS就是一艘航空母艦。其中pgRouting增加了路由功能,實現了導航路徑規劃中的經典演算法,如Dijkstra演算法、A*演算法、旅行商演算法。將地圖資料整理成符合其規格的格式後,可以很快打造出一個簡易的路徑規劃計算服務。在空間查詢中,PostGIS可以實現即查即所得的效果。圖6中,如果要獲取橙色多邊形內的路網資料,普通空間查詢結果為綠色查詢結果集合,如果要獲取多邊形內的資料,需要在查詢結果集中做二次空間拓撲判斷。在PostGIS中,由於其特有的GiST空間索引,一次空間查詢即可,大大提高查詢效率。
圖6 空間查詢效果圖
- GeoServer
GeoServer 是 OpenGIS Web 伺服器規範的 J2EE 實現,利用 GeoServer 可以方便的釋出地圖資料,允許使用者對特徵資料進行更新、刪除、插入操作。其資料來源支援PostGIS、MySQL、GeoMesa等。使用者編輯SLD檔案可以自定義地圖繪製風格,製作各種專題地圖。下圖為使用不同的SLD檔案,釋出WMS服務示意圖。
圖7 軌跡圖
圖8 軌跡熱力圖
- OpenLayer、Mapbox
OpenLayer和MapBox應用場景較為類似,為Web GIS 客戶端開發提供的JavaScript 類庫包,用於實現標準格式釋出的地圖資料訪問。基於OpenLayer和MapBox可以讓前端地圖顯示的更加漂亮。
- QGIS
QGIS是一個免費的、開源的、跨平臺(Linux/Windows/Mac/Android)的地理資訊系統桌面版軟體,基於QT C++開發。它提供強大的空間資料顯示、編輯和分析功能。QGIS和很多開源專案一樣,使用CMake進行編譯,由於QGIS整合了大部分的第三方軟體,基於原始碼編譯出可執行的QGIS,這是一個考驗耐心的活,如同自己蓋一座大樓,每一塊磚頭都需要自己造。編譯出Debug版本的QGIS後,就能除錯其原始碼,並且可以基於SDK進行二次開發。QGIS的設計架構,很精妙,很值得學習。
- Mapnik
Mapnik是一款開源的地圖渲染引擎,它能夠為PostGIS,Shapefile,Geojson,SQLite等在內的多種資料來源提供空間資料計算與視覺化服務,包括png瓦片,向量瓦片,同時它支援自定義渲染樣式配置,具有很高的靈活性,提供了C++,python,node介面。Open Street Map主地圖層就是用Mapnik渲染得到的。
- GRASS GIS
在地理資訊系統行業中,如果說ArcGIS(作業系統行當中的windows)是閉源軟體中喬峰,GRASS GIS就是開源軟體中的慕容復。GRASS可處理向量、影像資料,並且進行時空分析、空間建模、空間分析、地圖視覺化等操作。GRASS中的某些影像處理演算法,無論從效能還是效果,完全可以媲美專業商業軟體。雖然GRASS提供了一些視覺化操作介面,但是大部分功能需用命令方式進行互動,對於普通使用者來說,使用時有一定困難,比較適合科研人員或高校教師。
- JTS
Java版本的GEOS,請參考GEOS部分。在路網操作中,會遇到將首尾相連的多條道路合併成一條道路的情況,使用JTS中的LineMerger類,可以很好的完成這個操作,示例程式碼:
WKTReader reader = new WKTReader();
Geometry geom_1 = reader.read("LINESTRING (116.96832000000000562 36.64882000000000062, 116.96849000000000274 36.64882000000000062)");
Geometry geom_2 = reader.read("LINESTRING (116.96849000000000274 36.64882000000000062, 116.96862000000000137 36.64882000000000062)");
Geometry geom_3 = reader.read("LINESTRING (116.96862000000000137 36.64882000000000062, 116.96877999999999531 36.64880999999999744)");
LineMerger lineMerger = new LineMerger();
//新增幾何物件不需要按照順序,只要道路首尾座標點重合即可
lineMerger.add(geom_1);
lineMerger.add(geom_2);
lineMerger.add(geom_3);
Collection mergedLineStrings = lineMerger.getMergedLineStrings();
System.out.println(mergedLineStrings.toString());
列印結果:[LINESTRING (116.96832 36.64882, 116.96849 36.64882, 116.96862 36.64882, 116.96878 36.64881)]
- GeoTools
功能和GDAL類似,空間拓撲演算法使用JTS來實現。
- GeoMesa
GeoMesa是一個開源的進行時空資料處理的工具包,可以支援大資料場景下的地理資訊分析和分散式計算。能較好的相容大資料處理框架,如HBase、Spark,公司大資料架構部提供了完整的GeoMesa解決方案,可參考內網相關資訊
作者:張深圳
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559758/viewspace-2674631/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OA軟體中人力資源管理模組在企業中的具體應用?
- 值得關注的12大開源大資料分析應用軟體大資料
- 探討敏捷開發在軟體開發中的應用敏捷
- 影像處理開源資料集
- 3D組合地圖在資料視覺化大屏中的應用3D地圖視覺化
- 58.7%的中國企業使用開源軟體應用於資料庫方向資料庫
- 在軟體開發中應用80:20原則
- 資訊科技在CRM軟體中的應用
- 平安科技資料庫總經理汪洋:開源資料庫在平安的應用實踐資料庫
- 在Linux中,開源軟體和自由軟體的區別?Linux
- 一套用來處理海量資料的軟體工具應運而生,這就是大資料!大資料
- 大資料技術在應急事件處理中的啟示大資料事件
- 在Docker容器中執行GUI圖形應用的開源專案DockerGUI
- 軟體專案管理在小軟體專案中的應用專案管理
- 11g包dbms_parallel_execute在海量資料處理過程中的應用Parallel
- 50款教育類開源應用軟體
- 處理XML資料應用實踐XML
- 傅立葉在影像處理應用
- 外部資料在資料分析中的應用
- 提取應用程式中的圖示資源 (轉)
- Koa 應用中使用錯誤處理中介軟體
- Mac raw圖片處理軟體Mac
- Photoshop類圖片處理軟體
- Flask 應用中的 URL 處理Flask
- 地圖開發資源集合貼地圖
- 十年期貨股票行情資料輕鬆處理——TDengine在同心源基金的應用
- 專案管理軟體在企業中的應用專案管理
- 用例設計在軟體開發專案計劃中的應用(轉)
- 軟體專案管理的研究及在專案開發中的應用專案管理
- Calendar類在Java中的應用與日期時間處理Java
- SAP CRM Product Sales status在中介軟體中的處理邏輯
- 應用:資料預處理-缺失值填充
- 手把手教你從資料預處理開始體驗圖資料庫資料庫
- 用開源軟體管理資料中心(轉)
- 童欣:資料驅動方法在圖形學中的應用
- 應用中的錯誤處理概述
- Docker在公有云的應用處理能力Docker
- 地圖用得好,資料更直觀!bi軟體都有哪些地圖圖表?地圖