1、背景
在離線環境下(區域網路中)的GIS系統中如何使用地圖?這裡的地圖主要指的是地圖底圖,有了底圖切片資料,我們就可以看到地圖,在上面加上自己的業務資料圖層,進行相關操作。
要在離線環境下看到GIS地圖,就要有底圖切片資料,地圖的底圖切片資料在一定時間内是不會變化的,可以使用一些地圖下載下傳器下載下傳地圖切片,如這個地圖下載下傳器。
在CS系統中可以基于GMap.Net來做,參考《百度谷歌離線地圖解決方案》。
下面介紹下Web系統如何使用GIS切片資料,開發web GIS系統。
2、使用GeoWebCache釋出WMS服務
Geowebcache是基于Java的Web開源項目,主要用于緩存各種WMS資料源的地圖瓦片,它實作了多種服務接口,包括WMS-C,WMTS,TMS,KML。
Geowebcache作為一個獨立的開源項目,在最近被Geosever的幾個版本所內建,主要是對釋出的WMS圖層建立緩存切片。
服務釋出步驟:
1)官網下載下傳 geowebcache-1.8.0-war.zip,直接解壓得到geowebcache.war檔案,将該檔案直接拷貝至tomcat目錄下的webapps下即可,啟動tomcat會對war包進行解壓。
2)修改geowebcache的配置檔案geowebcache-core-context.xml。該檔案在Tomcat的webapps\geowebcache\WEB-INF下,修改如下:
<bean id="gwcXmlConfig" class="org.geowebcache.config.XMLConfiguration">
<constructor-arg ref="gwcAppCtx" />
<!--<constructor-arg ref="gwcDefaultStorageFinder" />-->
<constructor-arg value="D:\\GisMap\\" />
<!-- By default GWC will look for geowebcache.xml in {GEOWEBCACHE_CACHE_DIR},
if not found will look at GEOSEVER_DATA_DIR/gwc/
alternatively you can specify an absolute or relative path to a directory
by replacing the gwcDefaultStorageFinder constructor argument above by the directory
path, like constructor-arg value="/etc/geowebcache"
-->
<property name="template" value="/geowebcache.xml">
<description>Set the location of the template configuration file to copy over to the
cache directory if one doesn't already exist.
</description>
</property>
</bean>
修改gwcXmlConfig執行個體化時使用固定路徑,該路徑可以為任意建立路徑檔案夾。Geowebcache啟動之後會檢查此檔案夾下是否存在gewebcache.xml檔案,如果不存在則按模闆建立立并讀取使用,如果存在則直接讀取使用。
3)修改第2步中的gewebcache.xml檔案:
<layers>
<arcgisLayer>
<name>ARCGIS-Demo</name>
<tilingScheme>D:\\GisMap\\Layer\\conf.xml</tilingScheme>
<tileCachePath>D:\\GisMap\\Layer\\_alllayers</tileCachePath>
</arcgisLayer>
</layers>
在layers節點裡添加arcgisLayer節點(預設生成的gewebcache.xml的layers節點有許多其他備援資料,可删除可保留)。Name節點表示待添加圖層的名稱(這裡配置為ARCGIS-Demo),titlingscheme節點為conf.xml檔案的路徑,tileCachePath為瓦片資料的路徑。
4)瓦片地圖的準備

其中conf.xml為配置檔案,conf.cdi為顯示區域限制檔案,_alllayers檔案夾下則存放了切片資料,Status.gdb為切片狀态情況記錄(可直接删除)。
通過瓦片下載下傳器下載下傳瓦片地圖,然後生成的切片資料_alllayers檔案夾:
L01-L10表示地圖縮放級數,按照ArcGIS切片目錄組織,切片命名規則也和ArcGIS切片資料命名規則一緻。(conf.xml、conf.cdi和_alllayers在同級目錄)。
5)啟動tomcat,繼而啟動Geowebcache服務,浏覽器通路 localhost:8080/geowebcache,如果一切正确的話可以看到下面的頁面
該頁面簡單說明了Geowebcache的一些情況。
點選“A list of all the layers and automatic demos”連接配接可以看到下面:
該頁面顯示了geowebcache.xml配置的圖層資訊。圖中可以看到隻配置了一個名字為ARCGIS-Demo的圖層,使用的EPSG3857坐标系,釋出的圖檔格式為png格式,點選png連結即可看到瓦片地圖。
這裡地圖顯示的級别和坐标系配置都來自conf.xml檔案。這裡的前端js使用的是Openlayers。檢視網頁源碼:
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="imagetoolbar" content="no">
<title>ARCGIS-Demo EPSG:3857_ARCGIS-Demo image/png</title>
<style type="text/css">
body { font-family: sans-serif; font-weight: bold; font-size: .8em; }
body { border: 0px; margin: 0px; padding: 0px; }
#map { width: 85%; height: 85%; border: 0px; padding: 0px; }
</style>
<script src="../openlayers/OpenLayers.js"></script>
<script type="text/javascript">
var map, demolayer;
// sets the chosen modifiable parameter
function setParam(name, value){
str = "demolayer.mergeNewParams({" + name + ": '" + value + "'})"
// alert(str);
eval(str);
}
OpenLayers.DOTS_PER_INCH = 96.0;
OpenLayers.Util.onImageLoadErrorColor = 'transparent';
function init(){
var mapOptions = {
resolutions: [156543.033928, 78271.5169639999, 39135.7584820001, 19567.8792409999, 9783.93962049996, 4891.96981024998, 2445.98490512499, 1222.99245256249, 611.49622628138, 305.748113140558, 152.874056570411, 76.4370282850732, 38.2185141425366, 19.1092570712683, 9.55462853563415, 4.77731426794937, 2.38865713397468, 1.19432856685505, 0.597164283559817, 0.298582141647617],
projection: new OpenLayers.Projection('EPSG:3857'),
maxExtent: new OpenLayers.Bounds(-20037508.342787,-20037508.342780996,20037508.342780996,20037508.342787),
units: "meters",
controls: []
};
map = new OpenLayers.Map('map', mapOptions );
map.addControl(new OpenLayers.Control.PanZoomBar({
position: new OpenLayers.Pixel(2, 15)
}));
map.addControl(new OpenLayers.Control.Navigation());
map.addControl(new OpenLayers.Control.Scale($('scale')));
map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));
demolayer = new OpenLayers.Layer.WMS(
"ARCGIS-Demo","../service/wms",
{layers: 'ARCGIS-Demo', format: 'image/png' },
{ tileSize: new OpenLayers.Size(256,256),
tileOrigin: new OpenLayers.LonLat(-2.0037508342787E7, 2.0037508342787E7)});
map.addLayer(demolayer);
map.zoomToExtent(new OpenLayers.Bounds(-20037497.2108,-19929239.113399997,20037497.2108,18379686.9965));
// The following is just for GetFeatureInfo, which is not cached. Most people do not need this
map.events.register('click', map, function (e) {
document.getElementById('nodelist').innerHTML = "Loading... please wait...";
var params = {
REQUEST: "GetFeatureInfo",
EXCEPTIONS: "application/vnd.ogc.se_xml",
BBOX: map.getExtent().toBBOX(),
X: e.xy.x,
Y: e.xy.y,
INFO_FORMAT: 'text/html',
QUERY_LAYERS: map.layers[0].params.LAYERS,
FEATURE_COUNT: 50,
Layers: 'ARCGIS-Demo',
Styles: '',
Srs: 'EPSG:3857',
WIDTH: map.size.w,
HEIGHT: map.size.h,
format: "image/png" };
OpenLayers.loadURL("../service/wms", params, this, setHTML, setHTML);
OpenLayers.Event.stop(e);
});
}
function setHTML(response){
document.getElementById('nodelist').innerHTML = response.responseText;
};
</script>
</head>
<body onload="init()">
<div id="params"></div>
<div id="map"></div>
<div id="nodelist"></div>
</body>
</html>
View Code
個人比較喜歡leaflet這個GIS javascript庫,使用leaflet加載GeoWebCache釋出的這個服務:
<!DOCTYPE html>
<html>
<head>
<title>Leaflet - Offline Demo</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
</head>
<body>
<div id="map" style="height:100vh;" ></div>
<script type="text/javascript">
var mapCenter = new L.LatLng(32.1280, 118.7742); //南京
var map = new L.Map('map', {
center : mapCenter,
zoom : 4
});
var wmsLayer = L.tileLayer.wms("http://localhost:8080/geowebcache/service/wms", {
layers: 'ARCGIS-Demo',
format: 'image/png'
});
wmsLayer.addTo(map);
var marker = new L.Marker(mapCenter);
map.addLayer(marker);
marker.bindPopup("<p>Hello! ;}</p>").openPopup();
</script>
</body>
</html>
3、使用自定義的Http服務
GeowebCache本質上就是個Http服務,通過請求參數擷取配置檔案中的路徑中的切片資料,傳回給請求方。
我們可以自己寫個獨立的Http服務,從資料庫中讀取切片資料傳回給請求方,參考這個項目:MapHttpService
切片請求位址類似:http://localhost:8899/1818940751/{z}/{x}/{y}
其中“1818940751”是下載下傳器下載下傳的地圖類型,z/x/y分别是zoom和地圖切片行列号。
前端js使用leaflet加載:
var amapNormalUrl = 'http://localhost:8899/788865972/{z}/{x}/{y}';
var amapNormalLayer = new L.TileLayer(amapNormalUrl, {
minZoom : 1,
maxZoom : 18,
attribution : '高德普通地圖'
});
var mapCenter = new L.LatLng(32.1280, 118.7742); //南京
var map = new L.Map('map', {
center : mapCenter,
zoom : 9,
minZoom: 1,
maxZoom: 18,
layers : [ amapNormalLayer ]
});
前端js可以自定義投影Projection算法,而國内google地圖、高德地圖和騰訊地圖都是标準的墨卡托投影,可以直接用leaflet加載。
配合一些畫圖插件,再配合一些背景POI檢索服務,如:
《使用Lucene索引和檢索POI資料》
《使用Solr進行空間搜尋》
則能做出如下效果:
離線web GIS搭建步驟:
1、使用 MapDownloader 下載下傳地圖切片。
2、使用 MapHttpService 啟動地圖切片服務。
3、運作 WebGisDemo (基于Springboot):http://localhost:9090/map/map,通路地圖
總結:介紹了如何使用下載下傳的離線切片資料在區域網路環境下釋出Web GIS地圖服務,前端配合使用一些js插件,實作web下空間資料的檢索。
在Github上開源了一些代碼,包含自定義的Http地圖服務,和一個簡單的頁面WebGISDemo。
位址:
https://github.com/luxiaoxun/MapDownloader
https://github.com/luxiaoxun/Code4Java
更新于2020年08月:
- 使用springboot重構了 WebGisDemo
- 添加了一種POI資料源“station”
- 整理了IndexSearchService、MapHttpService的代碼
附件:
<?xml version="1.0" encoding="utf-8" ?>
<EnvelopeN xsi:type='typens:EnvelopeN'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.1'>
<XMin>-20037497.2108</XMin>
<YMin>-19929239.113399997</YMin>
<XMax>20037497.2108</XMax>
<YMax>18379686.9965</YMax>
</EnvelopeN>
conf.cdi
<?xml version="1.0" encoding="utf-8"?>
<CacheInfo xsi:type="typens:CacheInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://www.esri.com/schemas/ArcGIS/10.1">
<TileCacheInfo xsi:type="typens:TileCacheInfo">
<SpatialReference xsi:type="typens:ProjectedCoordinateSystem">
<WKT>PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",3857]]</WKT>
<XOrigin>-20037700</XOrigin>
<YOrigin>-30241100</YOrigin>
<XYScale>148923141.92838538</XYScale>
<ZOrigin>-100000</ZOrigin>
<ZScale>10000</ZScale>
<MOrigin>-100000</MOrigin>
<MScale>10000</MScale>
<XYTolerance>0.001</XYTolerance>
<ZTolerance>0.001</ZTolerance>
<MTolerance>0.001</MTolerance>
<HighPrecision>true</HighPrecision>
<WKID>3857</WKID>
</SpatialReference>
<TileOrigin xsi:type="typens:PointN">
<X>-20037508.342787001</X>
<Y>20037508.342787001</Y>
</TileOrigin>
<TileCols>256</TileCols>
<TileRows>256</TileRows>
<DPI>96</DPI>
<LODInfos xsi:type="typens:ArrayOfLODInfo">
<LODInfo xsi:type="typens:LODInfo">
<LevelID>0</LevelID>
<Scale>591657527.591555</Scale>
<Resolution>156543.03392799999</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>1</LevelID>
<Scale>295828763.79577702</Scale>
<Resolution>78271.516963999893</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>2</LevelID>
<Scale>147914381.89788899</Scale>
<Resolution>39135.758482000099</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>3</LevelID>
<Scale>73957190.948944002</Scale>
<Resolution>19567.879240999901</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>4</LevelID>
<Scale>36978595.474472001</Scale>
<Resolution>9783.9396204999593</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>5</LevelID>
<Scale>18489297.737236001</Scale>
<Resolution>4891.9698102499797</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>6</LevelID>
<Scale>9244648.8686180003</Scale>
<Resolution>2445.9849051249898</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>7</LevelID>
<Scale>4622324.4343090001</Scale>
<Resolution>1222.9924525624899</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>8</LevelID>
<Scale>2311162.2171550002</Scale>
<Resolution>611.49622628138002</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>9</LevelID>
<Scale>1155581.108577</Scale>
<Resolution>305.74811314055802</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>10</LevelID>
<Scale>577790.55428899999</Scale>
<Resolution>152.874056570411</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>11</LevelID>
<Scale>288895.27714399999</Scale>
<Resolution>76.437028285073197</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>12</LevelID>
<Scale>144447.638572</Scale>
<Resolution>38.218514142536598</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>13</LevelID>
<Scale>72223.819285999998</Scale>
<Resolution>19.109257071268299</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>14</LevelID>
<Scale>36111.909642999999</Scale>
<Resolution>9.5546285356341496</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>15</LevelID>
<Scale>18055.954822</Scale>
<Resolution>4.7773142679493699</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>16</LevelID>
<Scale>9027.9774109999998</Scale>
<Resolution>2.38865713397468</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>17</LevelID>
<Scale>4513.9887049999998</Scale>
<Resolution>1.1943285668550501</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>18</LevelID>
<Scale>2256.994353</Scale>
<Resolution>0.59716428355981699</Resolution>
</LODInfo>
<LODInfo xsi:type="typens:LODInfo">
<LevelID>19</LevelID>
<Scale>1128.4971760000001</Scale>
<Resolution>0.29858214164761698</Resolution>
</LODInfo>
</LODInfos>
</TileCacheInfo>
<TileImageInfo xsi:type="typens:TileImageInfo">
<CacheTileFormat>PNG</CacheTileFormat>
<CompressionQuality>0</CompressionQuality>
<Antialiasing>false</Antialiasing>
</TileImageInfo>
<CacheStorageInfo xsi:type="typens:CacheStorageInfo">
<StorageFormat>esriMapCacheStorageModeExploded</StorageFormat>
<PacketSize>0</PacketSize>
</CacheStorageInfo>
</CacheInfo>
conf.xml
參考:
http://leafletjs.com/
http://leafletjs.com/examples/quick-start/
http://www.cnblogs.com/luxiaoxun/p/4454880.html
http://www.cnblogs.com/luxiaoxun/p/5020247.html
作者:阿凡盧
出處:http://www.cnblogs.com/luxiaoxun/
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。