【SAS Planet 下载地图瓦片-读取】

news2024/11/25 16:43:35

   SAS Planet下载地图瓦片请看上一篇 详细介绍了下载方法

 【SAS Planet 下载地图瓦片】-CSDN博客

准备工作:

1.提前下载好地图瓦片数据

 SAS Planet下载地图瓦片默认存储路径如下

   默认存储格式为 .sqlitedb

2.提前准备好 java开发环境和开发工具,新建 一个 spring boot 工程,集成 maven。

 在pom.xml 下新增sqlite3驱动包配置,然后更新工程 maven

<!-- sqlite3驱动包 -->
<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.32.3.2</version>
</dependency>

  读取SAS Planet下载的地图瓦片后台代码如下:

package com.api.controller;

import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Api(value="读取sqlite文件瓦片",tags={"读取sqlite文件瓦片"})
@CrossOrigin  // 允许跨域访问
@RestController
public class sqliteTilesController {

    @GetMapping(value = "/getCacheTiles/{layerName}/{level}/{x}/{y}")
    public ResponseEntity<byte[]> getCacheTiles(@PathVariable("layerName")String layerName, @PathVariable("level")Integer level, @PathVariable("x")Integer x, @PathVariable("y")Integer y) {
        ResponseEntity<byte[]> response=null;

        Statement stmt = null;
        Connection conn = null;
        try {
            //String path="E:\\WJ_Data\\SAS.Planet.Release.200606\\cache_sqlite\\Google_Sat_RU_SD\\"+layerName+"\\z"+level+"\\0\\0\\0.0.sqlitedb";

            String basePath="E:\\WJ_Data\\SAS.Planet.Release.200606\\cache_sqlite\\";


            //地图下载(SAS.Planet) 下载的瓦片存储在sqlitedb文件里 路径规则 规则计算
            // 将十进制数转换为二进制字符串再右移后还原成十进制数
            Integer shrX1= shrnNumberValue(x,10);//
            Integer shrY1= shrnNumberValue(y,10);//

            Integer shrX2= shrnNumberValue(x,8);//
            Integer shrY2= shrnNumberValue(y,8);//
            String  fullPath=basePath+layerName+"\\z"+level+"\\"+shrX1+"\\"+shrY1+"\\"+shrX2+"."+shrY2+".sqlitedb";
            //jdbc url
            String urlStr="jdbc:sqlite:"+fullPath;

            conn = DriverManager.getConnection(urlStr);
            conn.setAutoCommit(false);

            System.out.println("Opened database successfully");
            stmt = conn.createStatement();
            //ResultSet rs = stmt.executeQuery( "SELECT * FROM 't'" );
            String sqlStr="SELECT * FROM  't' where x="+x+" and y="+y;//"SELECT * FROM 't'
            ResultSet rs = stmt.executeQuery(sqlStr);
            while ( rs.next() ) {
                int tilesX = rs.getInt("x");
                int tilesY = rs.getInt("y");
                int v= rs.getInt("v");
                String c= rs.getString("c");
                long h= rs.getLong("h");
                long d= rs.getLong("d");

                String Str="瓦片信息  level:"+level+", x:"+x+", y="+y;
                System.out.println( Str );

                //获取图片,图片列的索引为8
                byte[] bytes = (byte[] )rs.getObject(8);
                response= ResponseEntity.ok().contentType(MediaType.parseMediaType("image/jpg")).body(bytes);

            }
            rs.close();
            stmt.close();
            conn.close();
        } catch ( Exception e ) {
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        }
        System.out.println("Operation done successfully");
        return response;
    }

    //将十进制数转换为二进制字符串再右移后还原成十进制数
    public int shrnNumberValue(int value,int shr) {
        // value 十进制数
        // shr  将一个数在二进制上右位移位数
        String binary = Integer.toString(value, 2); // 十进制转换为二进制字符串
        int length= binary.length();
        if(length>shr){
            String  newBinary=binary.substring(0,binary.length()-shr);
            int decimal = Integer.parseInt(newBinary, 2); // 二进制字符串解析为十进制数
            return  decimal;
        }else{
            return  0;
        }
    }

}

 获取瓦片接口:"http://localhost:2022/getCacheTiles/Google_Sat_RU_SD/{z}/{x}/{y}"

  前端页面调用代码如下

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Custom LERC Layer | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>
    <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <script>
      var dojoConfig = {
        paths: {
          // see https://github.com/Esri/lerc
          lerc: "https://cdn.jsdelivr.net/gh/Esri/lerc@b0650ff915a05b2a045641235323d59b26a40550/OtherLanguages/js/"
        }
      };
    </script>

    <script src="https://js.arcgis.com/4.28/"></script>
    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/BaseTileLayer",
        "esri/request",
        "lerc/LercDecode"
      ], (Map, MapView, BaseTileLayer, esriRequest, LercDecode) => {
       
        const LercLayer = BaseTileLayer.createSubclass({        
          properties: {
            urlTemplate: null,
            minElevation: 0,
            maxElevation: 4000
          },

          // Generates the URL to an image to be requested from the server
          getTileUrl: function(level, row, col) {
            return this.urlTemplate
              .replace("{z}", level)
              .replace("{x}", col)
              .replace("{y}", row);
          },

          // fetch tiles visible in the view
          fetchTile: function(level, row, col, options) {
            const url = this.getTileUrl(level, row, col);

            // requested encoded elevation information
            // the signal option ensures that obsolete requests are aborted
            return esriRequest(url, {
              responseType: "array-buffer",
              signal: options && options.signal
            }).then((response) => {
                // create a canvas to draw the processed image
                const canvas = document.createElement("canvas");
                const context = canvas.getContext("2d");
                const width = this.tileInfo.size[0];
                const height = this.tileInfo.size[1];

                canvas.width = width;
                canvas.height = height;
                const lerc = LercDecode.decode(response.data, { noDataValue: 0 });

              
                const pixels = lerc.pixels[0];
                const stats = lerc.statistics[0];

                const min = this.minElevation;
                const max = this.maxElevation;
                const noDataValue = stats.noDataValue;
                const imageData = context.createImageData(width, height);
                
                const data = imageData.data;
                const factor = 256 / (max - min);
                let value = 0;
                let j;

            
                for (let i = 0; i < width * height; i++) {        
                  j = i + Math.floor(i / width);                
                  value = (pixels[j] - min) * factor;
                  data[i * 4] = value; // r
                  data[i * 4 + 1] = value; // g
                  data[i * 4 + 2] = 0; // b
                  data[i * 4 + 3] = pixels[i] === noDataValue ? 0 : value; // a
                }
                context.putImageData(imageData, 0, 0);

                return canvas;
              }
            );
          }
        });
        
        var  vUrl="http://localhost:2022/getCacheTiles/Google_Sat_RU_SD/{z}/{x}/{y}";
        const lercLayer = new LercLayer({
          urlTemplate:vUrl,
          title: "Google_Sat_RU_SD"
        });

        const map = new Map({
          basemap: "dark-gray-vector",
          layers: [lercLayer]
        });

        const view = new MapView({
          container: "viewDiv",
          map: map
          zoom: 5
        });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

效果如下

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1255426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux的基本指令(三)

目录 前言 echo指令&#xff08;简述&#xff09; Linux的设计理念 输出重定向操作符 > 追加输出重定向操作符 >> 输入重定向操作符 < 补充知识 学前补充 more指令 less指令 head指令 tail指令 查看文件中间的内容 利用输出重定向实现 利用管道“ |…

在Linux环境如何启动和redis数据库?

Linux中连接redis数据库&#xff1a; 前台启动&#xff1a; 第一步&#xff1a;redis-server:服务器启动命令 当我们启动改窗口后&#xff0c;出现如下所示&#xff1a; 该窗口就不能关闭&#xff0c;否则会出现redis无法使用的情况&#xff0c;重新打开一个窗口&#xff0c…

每日一题2023.11.26——打印沙漏【PTA】

题目要求&#xff1a; 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”&#xff0c;要求按下列格式打印 ************ *****所谓“沙漏形状”&#xff0c;是指每行输出奇数个符号&#xff1b;各行符号中心对齐&#xff1b;相邻两行符号数差2&#xff1b;…

数据结构—树

文章目录 9.树(1).树的基本概念#1.基本定义#2.树的广义表表示法#3.基本术语 (2).树的存储结构#1.标准形式(常用)#2.逆存储形式#3.孩子兄弟存储法 (3).并查集#1.我们到底想解决什么问题#2.并查集结点#2.Find(查)#3.Union(并)#4.例子 (4).树的遍历#1.前序遍历#2.后序遍历#3.遍历的…

[Linux]进程等待

文章目录 3.进程等待3.1什么是进程等待3.2为什么要进程等待3.3如何进行进程等待?1.wait2.waitpid2.1函数的讲解2.2status的理解2.3代码理解 3.4学后而思1.直接用全局变量获取子进程退出码可以吗?如下2.进程具有独立性 退出码是子进程的数据 父进程是如何拿到退出码的3.对内存…

3DCAT为华东师大设计学院打造元宇宙数字虚拟学院

6月11日&#xff0c;华东师范大学设计学院在chi K11美术馆举办了一场别开生面的 2023 年本科毕业设计暨项目实践教学现场演示展。其中&#xff0c;元宇宙数字虚拟学院&#xff08;一期&#xff09;的现场发布会引起了现场震撼&#xff0c;吸引了众多观众的目光和参与。 该元宇宙…

CSS清除浮动的八种方法

我们为什么需要清除浮动&#xff0c;如果我们不清除浮动会发生什么呢&#xff1f; 基础样式&#xff0c;没清除浮动之前代码&#xff1a; 可复制也可以自己手动布局&#xff0c;后可尝试使用下面介绍的方法练习清除浮动 <!DOCTYPE html> <html lang"en">…

Python中的下划线使用教程:单下划线、双下划线和头尾双下划线详解

概要 Python是一种简单、易学、功能强大的编程语言&#xff0c;被广泛应用于各种领域。在Python中&#xff0c;下划线的使用有其特殊的含义和用途。本文将详细介绍Python中的单下划线、双下划线和头尾双下划线的使用教程&#xff0c;帮助读者更好地理解和应用这些特性。 一、单…

如何在Ubuntu系统上安装YApi

简单介绍 YApi是高效、易用、功能强大的api管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护API&#xff0c;YApi还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平台提供的接口数据写入工具以及简单的…

会声会影2024中文旗舰版配置最低要求及会声会影2024旗舰版新增哪些新功能?

会声会影&#xff08;Corel VideoStudio&#xff09;2024旗舰版为加拿大Corel公司发布的一款功能丰富的视频编辑软件。会声会影2024简单易用&#xff0c;具有史无前例的强大功能&#xff0c;拖放式标题、转场、覆叠和滤镜&#xff0c;色彩分级、动态分屏视频和新增强的遮罩创建…

什么是客户自助服务?综合指南献上~

《哈佛商业评论》曾报道过&#xff0c;81%的消费者在找客服之前会自己先去找办法解决。 如今&#xff0c;客户希望得到更快的响应。他们不想排队去等信息。他们想要的只是一个更快、更可靠的自助服务解决方案。作为企业&#xff0c;应该注意到他们的期望。企业需要做的就是通过…

Vite -构建优化 - 分包策略 + 打包压缩

什么是分包策略 分包策略 就是把不会常规更新的文件&#xff0c;单独打包处理。问 &#xff1a;什么是不会常规更新的文件&#xff1f; 答 &#xff1a; 就是基本上不会改的文件&#xff0c;比如我们引入的第三方的依赖包&#xff0c;例如 lodash工具包&#xff0c;这些工具包…

Gee教程2.上下文Context

先来看看Gin框架的简单例子 func main() {engine : gin.Default()engine.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "hello World!")})//监听并启动服务&#xff0c;默认 http://localhost:8080/engine.Run() }//我们自己写的 func main()…

PRD学习

产品经理零基础入门&#xff08;五&#xff09;产品需求文档PRD&#xff08;全16集&#xff09;_哔哩哔哩_bilibili 1. PRD的2种表现形式 ① RP格式 &#xff08;1&#xff09;全局说明 ② 文档格式 2. 交互说明撰写 ① 维度 ② 步骤 ③ 规则 &#xff08;1&#xff09;单位…

通达信视频教程的下载地址

百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com/s/12yNV62ROERRzmyqm9u22aQ?pwdgmdx

Leetcode 1727. 具有重排的最大子矩阵

题目要求&#xff1a; 给定一个大小为 m x n 的二进制矩阵&#xff0c;并且允许您以任意顺序重新排列矩阵的列。 对列进行最佳重新排序后&#xff0c;返回矩阵中每个元素都为 1 的最大子矩阵的面积。 输入&#xff1a;矩阵 [[0,0,1],[1,1,1],[1,0,1]] 输出&#xff1a;4 说明…

2017年五一杯数学建模B题自媒体时代的消息传播问题解题全过程文档及程序

2017年五一杯数学建模 B题 自媒体时代的消息传播问题 原题再现 电视剧《人民的名义》中人物侯亮平说&#xff1a;“现在是自媒体时代&#xff0c;任何突发性事件几分钟就传播到全世界。”相对于传统媒体&#xff0c;以互联网技术为基础的自媒体以其信息传播的即时性、交往方式…

x大网校登录接口js逆向分析

网站&#xff1a; import base64 # 解码 result base64.b64decode(aHR0cHM6Ly91c2VyLndhbmd4aWFvLmNuL2xvZ2lu.encode(utf-8)) websiteresult.decode(utf-8) # print(result) print(website)思路&#xff1a; 模拟登录&#xff0c;得到token值&#xff0c;才能对内部数据进行…

【YOLOv5入门】目标检测

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍YOLOv5入门-目标检测的任务、性能指标、yolo算法基本思想、yolov5网络架构图。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一篇…

利用 LD_PRELOAD 环境变量

文章目录 原理LD_PRELOAD介绍如何上传.so文件 例题 [虎符CTF 2022]ezphp 原理 LD_PRELOAD介绍 LD_PRELOAD是Linux系统的一个环境变量&#xff0c;它可以影响程序的运行时的链接&#xff08;Runtime linker&#xff09;&#xff0c;它允许你定义在程序运行前优先加载的动态链接…