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>

个人比较喜欢leaflet这个GIS javascript库,使用leaflet加载GeoWebCache发布的这个服务:

<!DOCTYPE html>
<html>
<head>
<title>Leaflet - Offline Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.3/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服务,从数据库中读取切片数据返回给请求方。

切片请求地址类似: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地图服务,前端配合使用一些js插件,实现web下空间数据的检索。

在Github上开源了一些代码,包含自定义的Http地图服务,和一个简单的页面WebGISDemo。

地址:

https://github.com/luxiaoxun/MapDownloader

https://github.com/luxiaoxun/Code4Java

附件:

<?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

Web GIS离线解决方案的更多相关文章

  1. Web GIS 离线地图

    Web GIS 离线地图 1,基于瓦片的离线地图下载 博客园 阿凡卢 提供了离线地图的下载工具,下载地址:http://pan.baidu.com/s/1hqvQr7e 具体使用见 参考资料2 阿凡卢 ...

  2. Web GIS离线地图

    参考资料: http://www.cnblogs.com/luxiaoxun/p/5022333.html https://www.cnblogs.com/luxiaoxun/p/4454880.ht ...

  3. java离线地图web GIS制作

    因为项目需求,要做一个web地图,之前做过高德的在线地图,它提供了一系列的API,并且由于是国产的,所以开发起来比较容易,现在由于项目是内网使用的,所以需要使用离线地图,由此便开始了: Web GIS ...

  4. 符合我公司GIS开源解决方案的探讨

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 这一周,我对GIS开源解决方案中涉及到的开源软件以及相关技术 ...

  5. 2013Esri全球用户大会之解读Web GIS

    1 什么是Web GIS,它跟我有什么关系? Web GIS是传递GIS功能的一种新方式,在Esri把GIS作为平台进行实现的战略方向中位于中心位置.Web GIS为用户随时随地访问和使用地理信息提供 ...

  6. ArcGIS 10.5,打造智能的Web GIS平台

    2017年新年来临之际,ArcGIS 10.5正式发布.历经几个版本,ArcGIS 10.5已经革新为一个智能的以Web为中心的地理平台,推出更精细的分级授权.全新的i3S三维标准.大数据分析处理产品 ...

  7. 【转】关于 Web GIS

    以下部分选自2015-03-01出版的<Web GIS从基础到开发实践(基于ArcGIS API for JavaScript)>一书中的前言部分: Web GIS 概念于1994 年首次 ...

  8. 宣布发布 Windows Azure 导入/导出服务的预览版以及 Web 和移动解决方案场景的若干增强功能

    客户评估基于云的存储解决方案时,面临的挑战之一是以经济高效.安全快速的方式从 Blob 存储区移进和移出大量数据.今天,我们很高兴地宣布发布 Windows Azure 导入/导出的预览版,这款新服务 ...

  9. Esri:为Web GIS注入新内涵

    纵观近些年IT与空间技术的发展,云计算.大数据.实时信息.LBS.无人机.倾斜摄影等新技术层出不穷:互联网基础设施建设成绩瞩目,宽带成为国家战略性公共基础设施. GIS(地理信息系统)作为空间信息分析 ...

随机推荐

  1. Nginx笔记

    基础篇 关于Nginx Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.最早由俄罗斯的程序设计师Igor Sysoev所开发,并在一个BSD-like ...

  2. nginx--->高并发优化

    在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题. nginx配置文件和内核参数的优化,如有不妥,敬请指出 一.nginx的配置优化 1)nginx进程数 ...

  3. RabbitMQ学习系列(六): RabbitMQ 高可用集群

    前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用.不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/ca ...

  4. Request.Form接收不到post数据.

    Request.Form接收不到post数据. https://q.cnblogs.com/q/62635/ Content-Type 有没有设置为 application/x-www-form-ur ...

  5. jQuery知识点二 实现隔行变色

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  6. 多Form界面控件状态变化问题分析

    假定有frmA,frmB,frmC三个界面,当frmA中触发显示frmC与frmB触发显示frmC时显示界面不同,或者让frmC上的某个按钮不可用,此时应该在如何来控制frmC的显示.是采用在frmC ...

  7. php文件锁

    前言 1.锁机制之所以存在是因为并发问题导致的资源竞争,为了确保操作的有效性和完整性,可以通过锁机制将并发状态转换成串行状态.作为锁机制中的一种,PHP 的文件锁也是为了应对资源竞争.假设一个应用场景 ...

  8. 2016icpc大连站总结(呐 如果把这段回忆,起个名字珍藏起来,叫它“宝物”应该很合适吧)

    10月15号一早乘飞机去了大连,12点这样到了海事大学,是一所很大的学校,来往的学生有些穿着海军服.然后我们到体育馆领了衣服,就去食堂吃午饭,中间有段小插曲,就是我们队的餐券没领..不过那里的负责人让 ...

  9. 【Android自学日记】【转】Android Fragment 真正的完全解析(上)

    自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产 ...

  10. Javascript权威指南学习笔记

    第二章:词法结构 ;function a(){alert(2)};//前面的分号保证正确地语句解析 第三章:类型.值和变量 基本概念: 1.数据类型---能够表示并操作的值的类型叫做数据类型. 2.变 ...