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

   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.mfbz.cn/a/191596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

印度客户来访广东育菁装备考察桌面型数控机床

印度客户来访广东育菁装备考察桌面型数控机床&#xff0c;这是一个重要的商业活动&#xff0c;对于育菁装备来说&#xff0c;这是一个展示产品和技术实力&#xff0c;拓展国际市场的好机会。 在接待印度客户的过程中&#xff0c;育菁装备需要做好充分的准备&#xff0c;包括&am…

YOLOv8改进 | SAConv可切换空洞卷积(附修改后的C2f+Bottleneck)

论文地址&#xff1a;官方论文地址 代码地址&#xff1a;官方代码地址 一、本文介绍 本文给大家带来的改进机制是可切换的空洞卷积&#xff08;Switchable Atrous Convolution, SAC&#xff09;是一种创新的卷积网络机制&#xff0c;专为增强物体检测和分割任务中的特征提取而…

Linux socket编程(6):IO复用之select原理及例子

文章目录 1 五种I/O模型1.1 阻塞I/O模型1.2 非阻塞I/O模型1.3 I/O复用模型1.4 信号驱动I/O模型1.5 异步I/O模型 2 select函数3 select实战&#xff1a;实现多个套接字监听3.1 客户端3.2 服务端3.3 实验结果3.4 完整代码 在之前的网络编程中&#xff0c;我们遇到了一个问题&…

初识数据结构

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 熬过了我们不想要的生活&#xf…

RT-DETR论文阅读笔记(包括YOLO版本训练和官方版本训练)

论文地址&#xff1a;RT-DETR论文地址 代码地址&#xff1a;RT-DETR官方下载地址 大家如果想看更详细训练、推理、部署、验证等教程可以看我的另一篇博客里面有更详细的介绍 内容回顾&#xff1a;详解RT-DETR网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署 目录 一…

【计算机网络笔记】多路访问控制(MAC)协议——轮转访问MAC协议

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

HCIA-RS基础-RIP路由协议

前言&#xff1a; RIP路由协议是一种常用的距离矢量路由协议&#xff0c;广泛应用于小规模网络中。本文将详细介绍RIP路由协议的两个版本&#xff1a;RIPv1和RIPv2&#xff0c;并介绍RIP的常用配置命令。通过学习本文&#xff0c;您将能够掌握RIP协议的基本原理、RIPv1和RIPv2的…

软件工程期末复习(选择+填空+判断)

文章目录 软件工程期末复习一、 选择题 软件工程期末复习 一、 选择题 1.“软件危机”的表现不包括&#xff1a;&#xff08;c&#xff09; A、软件产品不能按期交付 B、用户对“已完成的”软件产品时常不满意 C、程序员越来越供不应求 D、软件项目难以管理&#xff0c;维护困…

Java Thread 介绍

线程是操作系统调度的最小单元, 也叫轻量级进程。它被包含在进程之中, 是进程中的实际运作单位。 同一进程可以创建多个线程, 每个线程都有自己独立的一块内存空间, 并且能够访问共享的内存变量。 1 线程的分类 在 Java 中, 线程可以分为 2 种 守护线程: 守护线程是为用户线程…

kali linux英文改中文

如果英语基础较好的同学可以不用调整 反之则需要 找到终端&#xff08;就是输入命令的那个地方 如下&#xff09;点击它出现命令终端 切换为root用户&#xff0c;命令为&#xff1a; sudo dpkg-reconfigure locales 然后回车 找到这个zh_CN 然后回车 鼠标下键选中并且回车 输…

耶鲁博弈论笔记

编辑记录&#xff1a; 1126&#xff1a;开个新坑&#xff0c;耶鲁大学的博弈论课程&#xff0c; 和专业相关不大&#xff0c;纯兴趣&#xff0c;尽量写好一点吧 1. 首先指出博弈论是一种研究策略形式的方法&#xff0c;对于经济学中&#xff0c;完全竞争市场只能被动接受均衡…

IT问题解答类型网站源码

问答网是一款为IT工程师提供的问答平台&#xff0c;旨在帮助用户在线获取专业知识和相关问题的答案。在问答网&#xff0c;用户可以轻松找到其他人的问答问题&#xff0c;并在这里寻求解答。如果您有任何想要解决的问题&#xff0c;都可以在此发布问题并得到其他同行的解答。 …

【STL】string类 (下)

目录 1&#xff0c;insert 2&#xff0c;erase 3&#xff0c;find 4&#xff0c;replace 5&#xff0c;rfind 6&#xff0c;substr 7&#xff0c;find_first_of 8&#xff0c;find_first_not_of 9&#xff0c;find_last_of 10&#xff0c;operator 11&#xff0c;ge…

Qt TCP网络上位机的设计(通过网络编程与下位机结合)

目录 TCP 协议基础 QTcpServer 和 QAbstractSocket 主要接口函数 TCP 应用程序 1.服务端 2.客户端 上位机通过网络编程与下位机实现通信 TCP 协议基础 传输控制协议&#xff08;TCP&#xff0c;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于…

Camtasia Studio2024专业的屏幕录制和视频剪辑软件

Camtasia2024专业的屏幕录制和视频剪辑软件3000多万专业人士在全球范围内使用Camtasia展示产品&#xff0c;教授课程&#xff0c;培训他人&#xff0c;以更快的速度和更吸引人的方式进行沟通和屏幕分享。使您在Windows和Mac上进行录屏和剪辑创作专业外观的视频变得更为简单。 …

BGP选路实验

要求 1 使用PreVal策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2 使用AS_Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3 配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4 使用Local Preference策略&#xff0c;确保R1通过R2到达192.168.1.0/24 5 使…

【古诗生成AI实战】之五——加载模型进行古诗生成

回顾上一篇博客&#xff0c;我们已经成功地训练了我们的模型&#xff0c;并将其保存下来。这是一个重要的里程碑&#xff0c;因为训练好的模型是我们进行文本生成的基础。 现在&#xff0c;接下来的步骤是加载这个训练好的模型&#xff0c;然后使用它来生成古诗。 本章的内容属…

打印菱形-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第9讲。 打印菱形&#xff…

Android 虚拟机与类加载机制

1、Dalvik 虚拟机 Android 应用程序运行在 Dalvik/Art 虚拟机上&#xff0c;并且每一个应用程序都有一个单独的 Dalvik/Art 虚拟机实例。 1.1 JVM 与 Dalvik Dalvik 虚拟机也算是一个 Java 虚拟机&#xff0c;它是按照 JVM 虚拟机规范实现的&#xff0c;二者的特性差不多&am…

爬楼梯(力扣LeetCode)动态规划

爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示…
最新文章