OpenLayer+PostGIS+GeoServer--無額外後臺實現地理分析與查詢框架
OpenLayer+PostGIS+GeoServer--無額外後臺實現地理分析與查詢框架
1.1 傳統流程
在一般情況下,人們使用PostGIS儲存空間資料,以Geoserver釋出資料服務,以OpenLayer客戶端展示地圖。客戶端操作與地理查詢,如果查詢等比較複雜,一般會使用ajax將ol的請求引數傳給後臺,由後臺完成操作後返回前端。流程如下:
1.2 框架問題說明
1 GeoServer只是簡單釋出了地理資料,單個圖層,只能接受簡單的wms顯示,wfs查詢,wps分析。產生的問題是,面對多個圖層的疊加分析與查詢,幾乎做不到,所以很多圖層的分析只能交由後臺伺服器完成。
2 使用後臺伺服器處理地理資料,產生的問題是,對資料庫的訪問比較頻繁,分析的結果,由於是空間資料,對資料的解析儲存有要求,工作量增大。
3 作為GIS專業開發人員的苦惱是我曾加入一個j2ee專案組,作為Java的門外漢,我做一個哪怕最簡單的查詢,都要寫好多個java類檔案與資料結構類檔案,為了滿足j2ee框架需求。這令我感到很苦惱,在我看來,作為業務開發人員,他們需要這個框架,但作為地圖開發人員,我的精力都在研究各個地圖技術和框架上而不是語言本身,既不必要也無精力。能不能有個gis開發框架,使我專注於地理資料的查詢與分析而脫離業務框架本身的束縛,這讓我感到很有必要。
二 獨立於業務的地理資料操作框架
結構說明:1 複雜的多圖層的分析,全是在資料庫中以function指令碼編寫。
2 geoserver釋出要顯示地圖表。釋出function作為檢視引數。 對geoserver來說,table,view,function本質都是資料來源,是一樣的,所以都可以釋出。
3 使用時,普通的表用來顯示地圖,function用來分析地圖。
優勢:無論加入哪個專案組,我根本不用關心他們的框架與資料結構,整合時,自己負責地圖,業務負責業務,各司其職。
原來後臺服務全被改寫到資料庫中,這樣,在運算速度上也比驅動的快且少了一個額外的後臺。
三 框架使用示例
以最最簡單的需求作為說明示例:
需求: 我要根據道路名稱,查詢道路某個距離的緩衝區內的興趣點。
3.1 實現具體分析功能的資料庫function指令碼
[sql] view plain copy print?
- CREATE OR REPLACE FUNCTION queryplottingbyroad(
- IN roadname text,
- in distance double precision,
- OUT gid int,
- OUT shapearea double precision,
- out swglm text,
- out idcode text,
- out gljg_dm text,
- out editdate timestamp without time zone,
- out geom geometry
- )
- returns SETOF record AS
- $BODY$
- DECLARE
- queryGeom geometry;
- rec record;
- sql text;
- BEGIN
- --依據道路名稱查詢道路圖形
- sql:='select geom from road where name='''||roadname||'''';
- raise notice 'sql:%',sql;
- EXECUTE sql into rec;
- --對查詢的道路進行緩衝
- queryGeom:=ST_Buffer(rec.geom,distance);
- --查詢落在緩衝區內或與緩衝區相交的指定圖層資料
- sql:='select * from plottingwithqx t where ST_Within(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857)) or ST_Intersects(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857))';
- raise notice 'sql:%',sql;
- --查詢資料蒐集返回呼叫者
- for rec in execute sql loop
- gid:= rec.gid;
- shapearea:= rec.shapearea;
- swglm:= rec.swglm;
- idcode:= rec.idcode;
- gljg_dm:= rec.gljg_dm;
- editdate:= rec.editdate;
- geom:= rec.geom;
- return next;
- end loop;
- return;
- END;
- $BODY$
- LANGUAGE 'plpgsql' VOLATILE STRICT;
CREATE OR REPLACE FUNCTION queryplottingbyroad(
IN roadname text,
in distance double precision,
OUT gid int,
OUT shapearea double precision,
out swglm text,
out idcode text,
out gljg_dm text,
out editdate timestamp without time zone,
out geom geometry
)
returns SETOF record AS
$BODY$
DECLARE
queryGeom geometry;
rec record;
sql text;
BEGIN
--依據道路名稱查詢道路圖形
sql:='select geom from road where name='''||roadname||'''';
raise notice 'sql:%',sql;
EXECUTE sql into rec;
--對查詢的道路進行緩衝
queryGeom:=ST_Buffer(rec.geom,distance);
--查詢落在緩衝區內或與緩衝區相交的指定圖層資料
sql:='select * from plottingwithqx t where ST_Within(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857)) or ST_Intersects(t.geom,ST_GeomFromText('''||st_astext(queryGeom)||''',3857))';
raise notice 'sql:%',sql;
--查詢資料蒐集返回呼叫者
for rec in execute sql loop
gid:= rec.gid;
shapearea:= rec.shapearea;
swglm:= rec.swglm;
idcode:= rec.idcode;
gljg_dm:= rec.gljg_dm;
editdate:= rec.editdate;
geom:= rec.geom;
return next;
end loop;
return;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE STRICT;
3.2 Geoserer釋出function
在 圖層》釋出檢視服務中釋出一個檢視服務,具體參照geoserver官網。
3 客戶端呼叫
以wms查詢為例:
[plain] view plain copy print?
- http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'東方紅路';distance:100&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=
http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'東方紅路';distance:100&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=
viewparams是客戶端把引數放這個裡面,傳給geoserver,然後伺服器解析引數,查詢資料庫並返回結果。上方的url請求返回 道路名稱為'東方紅路'的100米範圍內的查詢圖層的符合要求資料。
查詢 200米範圍內的指定圖層符號要求資料
[plain] view plain copy print?
- http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'東方紅路';distance:200&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=
http://localhost:8090/geoserver/nkstarTax/wms?LAYERS=nkstarTax:queryPlottingbyroad&TRANSPARENT=TRUE&VIEWPARAMS=name:'東方紅路';distance:200&BBOX=1.3304724687752E7,3812889.1757509,1.3323585520889E7,3829641.4938807&WIDTH=512&HEIGHT=434&SRS=EPSG:900913&format=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=
效果如下,範圍擴大之後,多了一條記錄。
使用wfs查詢也是一樣的,使用viewparams將引數傳給伺服器,伺服器查詢資料庫。
總的來說,將傳統流程的複雜分析,摒棄了後臺,直接放在資料庫中的function中完成,由geoserver作為後臺,響應客戶端請求,無論wms,wfs都可以,並根據引數返回圖片或資料。
文章來源:http://blog.csdn.net/freeland1/article/details/42171949