Openlayers离线载入天地图
概述:
经过一个春节的休整,今天最终開始了!
任何时候。都不要忘记学习。学习是一辈子的事情!今天,我来说说怎样实现天地图的离线以及Openlayers载入离线数据实现天地图数据的展示。
实现:
1、获取天地图的数据
能够通过网络上下载各大地图的工具将天地图的数据下载下来。并制作成mbtiles文件。制作过程在此就不详述,将已经制作好的一个文件上传到了百度网盘。须要的童鞋能够下载哦~~~~
下载链接:http://pan.baidu.com/s/1dEmNtnF password:xqd8
2、读取mbtiles并返回到页面
mbtiles事实上就是一个sqllite数据库, 其具体可移步至http://www.cnblogs.com/i-gps/p/3919475.html查看具体。
在此方案中,我用了一个servlet。具体的实现代码例如以下:
package com.lzugis.web; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by Administrator on 2016/2/27.
*/
@WebServlet(description = "tian ditu tile", urlPatterns = {"/tdttile"})
public class TiandituTile extends HttpServlet {
private String tilepath = "D:/data/tdt/";
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String tile_column = request.getParameter("X");
String tile_row = request.getParameter("Y");
String zoom_level = request.getParameter("L");
String layer = request.getParameter("T");
// TODO Auto-generated method stub
try {
Class.forName("org.sqlite.JDBC");
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
System.out.println("数据库驱动未找到!");
}
// 得到连接 会在你所填写的文件夹建一个你命名的文件数据库
Connection conn;
try {
String conurl = "jdbc:sqlite:"+tilepath+layer+".mbtiles";
conn = DriverManager.getConnection(conurl,null,null);
// 设置自己主动提交为false
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
//推断表是否存在
ResultSet rsTables = conn.getMetaData().getTables(null, null, "tiles", null);
if(!rsTables.next()){
System.out.println("表不存在");
}
// 得到结果集
String sql = "SELECT * FROM tiles WHERE zoom_level = "+zoom_level+
" AND tile_column = "+tile_column+
" AND tile_row = "+tile_row;
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()) {
byte[] imgByte = (byte[]) rs.getObject("tile_data");
InputStream is = new ByteArrayInputStream(imgByte);
OutputStream os = response.getOutputStream();
try {
int count = 0;
byte[] buffer = new byte[1024 * 1024];
while ((count = is.read(buffer)) != -1) {
os.write(buffer, 0, count);
}
os.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
os.close();
is.close();
}
}
else{
System.out.println(sql);
System.out.println("未找到图片! ");
}
rs.close();
conn.close();
}
catch (SQLException e) {
e.printStackTrace();
System.out.println("SQL异常!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
当中,请求地址为:http://localhost:8081/lzugis/tdttile?
T=vec_c&L=5&X=25&Y=3。请求的结果例如以下所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
3、openlayers调用
从网上拔了下openlayers载入天地图的代码。并稍作改动。扩展了一个openlayers图层TiandituLayer。其代码例如以下:
OpenLayers.Layer.TiandituLayer = OpenLayers.Class(OpenLayers.Layer.Grid,{
mapType : null,
mirrorUrls : null,
topLevel : null,
bottomLevel : null,
//用于标识是本地天地图切片库还是訪问在线天地图
isOnline:true,
topLevelIndex : 0,
bottomLevelIndex : 20,
topTileFromX : -180,
topTileFromY : 90,
topTileToX : 180,
topTileToY : -270,
isBaseLayer : true,
initialize : function(name, url, options) {
options.topLevel = options.topLevel ? options.topLevel
: this.topLevelIndex;
options.bottomLevel = options.bottomLevel ?
options.bottomLevel
: this.bottomLevelIndex;
options.maxResolution = this
.getResolutionForLevel(options.topLevel);
options.minResolution = this
.getResolutionForLevel(options.bottomLevel);
var newArguments = [ name, url, {}, options ];
OpenLayers.Layer.Grid.prototype.initialize.apply(this,
newArguments);
},
clone : function(obj) {
if (obj == null) {
obj = new OpenLayers.Layer.TiandituLayer(this.name,
this.url, this.options);
}
obj = OpenLayers.Layer.Grid.prototype.clone
.apply(this, [ obj ]);
return obj;
},
getURL : function(bounds) {
var level = this.getLevelForResolution(this.map.getResolution());
var coef = 360 / Math.pow(2, level);
var x_num = this.topTileFromX < this.topTileToX ?
Math
.round((bounds.left - this.topTileFromX) / coef) : Math
.round((this.topTileFromX - bounds.right) / coef);
var y_num = this.topTileFromY < this.topTileToY ?
Math
.round((bounds.bottom - this.topTileFromY) / coef)
: Math.round((this.topTileFromY - bounds.top) / coef);
var type = this.mapType;
var url = this.url;
if (this.mirrorUrls != null) {
url = this.selectUrl(x_num, this.mirrorUrls);
}
return this.getFullRequestString({
T : type,
X : x_num,
Y : y_num,
L : level
}, url);
},
getFullRequestString: function(params, url){
url = url+'?T='+params.T+'&L='+params.L+'&X='+params.X+'&Y='+params.Y;
return url;
},
selectUrl : function(a, b) {
return b[a % b.length]
},
getLevelForResolution : function(res) {
var ratio = this.getMaxResolution() / res;
if (ratio < 1)
return 0;
for ( var level = 0; ratio / 2 >= 1;) {
level++;
ratio /= 2;
}
return level;
},
getResolutionForLevel : function(level) {
return 360 / 256 / Math.pow(2, level);
},
getMaxResolution : function() {
return this.getResolutionForLevel(this.topLevelIndex)
},
getMinResolution : function() {
return this.getResolutionForLevel(this.bottomLevelIndex)
},
CLASS_NAME : "OpenLayers.Layer.TiandituLayer"
});
在代码中新建一个TiandituLayer。并加入到map中就可以实现,代码例如以下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>OpenLayers MapQuest Demo</title>
<link rel="stylesheet" href="../../../../plugin/OpenLayers-2.13.1/theme/default/style.css" type="text/css">
<script src="../../../../plugin/OpenLayers-2.13.1/OpenLayers.js"></script>
<script src="TiandituLayer-src.js"></script>
<style type="text/css">
html, body, #map{
padding:0;
margin:0;
height:100%;
width:100%;
overflow: hidden;
}
</style>
<script type="text/javascript">
var map;
function init(){
var vec_c = new OpenLayers.Layer.TiandituLayer("vec_c", "http://localhost:8081/lzugis/tdttile",{
mapType:"vec_c",
topLevel: 2,
bottomLevel: 10,
isBaseLayer:true,
isOnline:false
});
var cva_c = new OpenLayers.Layer.TiandituLayer("cva_c", "http://t0.tianditu.com/DataServer",{
mapType:"cva_c",
topLevel: 0,
bottomLevel: 18,
isBaseLayer:false,
isOnline:true
});
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:4326",
layers: [cva_c,vec_c,img_c],
numZoomLevels:20,
center: [103.847, 36.0473],
zoom: 2
});
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
说明:
1、代码中vec_c为天地图矢量层。cva_c为天地图标注层,与天地图的名称相一致;
2、vec_c为离线的地图,cva_c为在线的,通过參数isOnline区分其为离线还是在线。
完毕后效果:
Openlayers离线载入天地图的更多相关文章
- Arcgis for js载入天地图
综述:本节讲述的是用Arcgis for js载入天地图的切片资源. 天地图的切片地图能够通过esri.layers.TiledMapServiceLayer来载入.在此将之进行了一定的封装,例如以下 ...
- openlayers加载天地图过程中遇到跨域问题
// 采用openlayers加载天地图 var layer = new ol.layer.Tile({ source: new ol.source.XYZ({ // crossOrigin: 'An ...
- OpenLayers加载天地图
openlayer 是基于JavaScript的webGIS库 ,通过openlayer可以很容易的调用地图,并做相应的操作. 在head中载入openlayer的js文件: <link rel ...
- openlayers离线瓦片地图开发
近期业务繁忙...待更新
- nginx代理天地图做缓存解决跨域问题
作为一个GISer开发者,天地图是经常在项目中以底图的形式出现,其加载地址如: 天地图矢量:http://t{0-6}.tianditu.com/DataServer?T=vec_w&x={x ...
- Android插件化(二):使用DexClassLoader动态载入assets中的apk
Android插件化(二):使用DexClassLoader动态载入assets中的apk 简单介绍 上一篇博客讲到.我们能够使用MultiDex.java载入离线的apk文件.须要注意的是,apk中 ...
- OL记载Arcgis Server切片
概述: 本文讲述怎样在OpenLayers中调用Arcgis Server切片并显示. 思路: 在OpenLayers中载入Arcgis Server切片用XYZ图层,Arcgis Server的切片 ...
- OpenLayers学习笔记(一)—在线加载谷歌影像地图&离线加载本地瓦片地图
实现根据在线离线判断加载地图, 在线加载谷歌影响地图, 离线加载本地瓦片地图 作者: 狐狸家的鱼 Github: 八至 html代码 <div id="map" tabind ...
- 使用openlayers 3 在线加载天地图及GeoServer发布的地图
使用openlayers3来加载天地图卫星图和标注图层,GeoServer发布地图,一并用openlayers测试加载出来,顺便实现了7种地图控件.下面直接贴代码: <!DOCTYPE html ...
随机推荐
- 【Ray Tracing in One Weekend 超详解】 光线追踪1-5
一天一篇,今天来学习第7章 (散射)漫反射材质 Chapter7: Diffuse Materials Preface 从这一章开始,我们将通过光线追踪制作一些逼真的材质. 我们将从漫射(磨砂)材料开 ...
- [Web安全] XXE漏洞攻防学习(中)
0x00.XXE漏洞攻击实例 攻击思路: 1. 引用外部实体远程文件读取 2. Blind XXE 3. Dos 0x01.外部实体引用,有回显 实验操作平台:bWAPP平台上的XXE题目 题目: 进 ...
- JAVA编码 —— 字符串关键字内容替换
前言 工作中,我们可能遇到字符串内容替换的场景.例如:我们需要将一个字符串凡是 “#” 标注的,分别替换为不同的内容,那我们应该怎么做呢? 分析,一个字符串可能含有多个“#”,每个 “#”又对应不同的 ...
- BZOJ.1468.Tree(点分治)
BZOJ1468 POJ1741 题意: 计算树上距离<=K的点对数 我们知道树上一条路径要么经过根节点,要么在同一棵子树中. 于是对一个点x我们可以这样统计: 计算出所有点到它的距离dep[] ...
- Java并发程序设计(十一)设计模式与并发之生产者-消费者模式
设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程. ...
- SQL LOAD TABLE tbl_name FROM MASTER语法 把表的拷贝从主服务器转移到从属服务器。
用于把表的拷贝从主服务器转移到从属服务器.本语句的主要作用是调试LOAD DATA FROM MASTER.它要求用于连接主服务器的帐户拥有对主服务器的RELOAD和SUPER权限,并拥有对要载入的主 ...
- C++ 友元函数总结
1.为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率 具体来说:为了使其他类的成员函数直接访问该类的私有变量 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同 ...
- NOIP2013 花匠解题报告
//<NOIP2013> 花匠 /* 最优子结构性质,可以用动规.注意到存在30%的变态数据(1 ≤ n ≤ 100,000, 0 ≤ h_i ≤1,000,000),因此应当找到线性的算 ...
- Docker 容器生命周期管理命令
docker run 命令 -d: 后台运行容器,并返回容器ID: -i: 以交互模式运行容器,通常与 -t 同时使用: -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用: --name= ...
- 使用 IntraWeb (36) - TIWServerControllerBase
每个应用须有且只有一个 Server Controller. TIWServerControllerBase 所在单元及继承链: IWServerControllerBase.TIWServerCon ...