• 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。请求的结果例如以下所看到的:



    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%;
                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区分其为离线还是在线。


    完毕后效果:





  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7397976.html
Copyright © 2020-2023  润新知