【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 urlString 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 );//获取图片,图片列的索引为8byte[] 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.mzph.cn/news/171502.shtml

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

相关文章

安卓吸顶效果

当列表滑动时&#xff0c;图片逐渐消失&#xff0c;toolBar悬停在头部。 <?xml version"1.0" encoding"utf-8"?><androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android"http://schemas.android.com/apk/res/android"x…

网络运维与网络安全 学习笔记2023.11.26

网络运维与网络安全 学习笔记 第二十七天 今日目标 NAT场景与原理、静态NAT、动态NAT PAT原理与配置、动态PAT之EasyIP、静态PAT之NAT Server NAT场景与原理 项目背景 为节省IP地址和费用&#xff0c;企业内网使用的都是“私有IP地址” Internet网络的组成设备&#xff0c…

Python自动化测试学习路线【进阶必看】

软件自动化测试的学习步骤 大概步骤如下&#xff1a; 1. 做好手工测试&#xff08;了解各种测试的知识&#xff09;-> 2. 学习编程语言-> 3. 学习Web基础&#xff08;HTML,HTTP,CSS,DOM,Javascript&#xff09;或者 学习Winform -> 4. 学习自动化测试工具 ->5.…

Cisco Packet Tracer配置命令——路由器篇

路由基础 路由器用于互联两个或多个网络&#xff0c;具有两项功能&#xff1a;为要转发的数据包选择最佳路径以及将数据包交换到正确的端口&#xff0c;概括为路由选择和分组转发。 路由选择 路由选择就是路由器根据目的IP地址的网络地址部分&#xff0c;通过路由选择算法确…

公司人事管理系统

1.问题描述 一个小公司包含四类人员&#xff1a;经理&#xff0c;技术人员&#xff0c;销售人员和销售经理&#xff0c;各类人员的工资计算方法如下&#xff1a;经理&#xff1a;固定月薪&#xff08;8000&#xff09;&#xff1b;技术人员&#xff1a;月薪按技术等级&#xf…

类与对象——(1)初识对象——C++中的string

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 或许不安或许迷惑&#xff0c;但…

Factory 工厂模式-C语言实现

说明&#xff1a; 均由 chatgpt生成&#xff0c;实例可以看出无法运行&#xff0c;仅供参考~ UML图&#xff1a; ‘ 表示public, - 表示private,“# 表示protected.” 一文掌握14种UML图-腾讯云开发者社区-腾讯云 (tencent.com) 五分钟带你读懂UML类图 - 知乎 (zhihu.com)…

SpringBoot 环境使用 Redis + AOP + 自定义注解实现接口幂等性

目录 一、前言二、主流实现方案介绍2.1、前端按钮做加载状态限制&#xff08;必备&#xff09;2.2、客户端使用唯一标识符2.3、服务端通过检测请求参数进行幂等校验&#xff08;本文使用&#xff09; 三、代码实现3.1、POM3.2、application.yml3.3、Redis配置类3.4、自定义注解…

U-boot(五):启动内核

本文主要探讨210的uboot启动内核过程。 嵌入式系统状态启动 未上电时bootloader、kernel、rootfs以镜像形式存储在启动介质中(X210为iNand/SD卡),运行时搬运到DDR中 未上电时u-boot.bin,zImage,rootfs在SD卡中各自对应的分区中,启动时去对应分区寻找(分区表一…

【Java】实现一个自己的定时器

上文讲了怎样使用Java自带的定时器【Java】定时器的简单应用 这篇博客就来讲如何来编写一个自己实现的定时器 1、代码框架 由定时器的使用方法得知&#xff0c;我们在使用定时器的时候会添加一个任务timerTask类&#xff0c;而timer类则是我们行使任务的类&#xff0c;因此可…

【Apache Doris】Manager极致丝滑地运维管理

【Apache Doris】Manager极致丝滑地运维管理 1.标准VS可视化运维管理2. 环境信息2.1.硬件信息2.2.软件信息 3.前置准备3.1.安装包准备3.2.文档手册准备 4.集群初始化4.1.系统参数预设4.2.Manager部署4.3.新集群部署4.4 监控告警4.4.1 监控4.4.2 告警 5. 集群升级5.1 新包准备5.…

人力资源管理后台 === 登陆+主页鉴权

目录 1. 分析登录流程 2. Vuex中用户模块的实现 3.Vue-cli代理解决跨域 4.axios封装 5.环境区分 6. 登录联调 7.主页权限验证-鉴权 1. 分析登录流程 传统思路都是登录校验通过之后&#xff0c;直接调用接口&#xff0c;获取token之后&#xff0c;跳转到主页。 vue-elemen…

【数据库基础】

目录&#xff1a; 前言什么是数据库主流数据库服务器&#xff0c;数据库&#xff0c;表关系MySQL架构SQL分类存储引擎 前言 剑指offer&#xff1a;一年又1天 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a;…

大量索引场景下 Easysearch 和 Elasticsearch 的吞吐量差异

最近有客户在使用 Elasticsearch 搜索服务时发现集群有掉节点&#xff0c;并且有 master 收集节点信息超时的日志&#xff0c;节点的负载也很高&#xff0c;不只是 data 节点&#xff0c;master 和协调节点的 cpu 使用率都很高&#xff0c;看现象集群似乎遇到了性能瓶颈。 查看…

算法设计与分析(贪心法)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

中国一年有457万人确诊癌症!医生提示:这4种食物,再爱吃也要管住嘴

癌症是威胁人类生命健康的重大疾病&#xff0c;癌症的发生因素一直以来都是专家学者重点探索的课题。据世卫组织最新公布的数据显示&#xff0c;食物或与癌症发生之间存在着密切的联系&#xff0c;某些食物的摄入过多可能会增加患癌症的风险&#xff0c;所以我们应该警惕&#…

IDEA中JDK21控制台打印的中文乱码

IDEA中&#xff0c;使用的JDK21&#xff0c;控制台打印中文乱码&#xff0c;解决办法是重装了一下JDK。 我之前安装的版本是“jdk-21_windows-x64_bin.exe”&#xff0c;我配置了多个JDK环境&#xff0c;所以使用的是安装文件进行安装的。这次解决乱码问题&#xff0c;我重新安…

代码随想录算法训练营第四十八天|121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II

LeetCode 121. 买卖股票的最佳时机 题目链接&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 直觉告诉我要贪心算法&#xff0c;章节告诉我得用DP来做&#xff0c;行&#xff0c;都做一下&#xff01; 贪心&#xff1a;只能买一次&#xff0c;所…

Vatee万腾的科技冒险:Vatee独特探索力量的数字化征程

在数字化时代的激流中&#xff0c;Vatee万腾以其独特的科技冒险精神&#xff0c;引领着一场前所未有的数字化征程。这不仅仅是一次冒险&#xff0c;更是对未知的深度探索&#xff0c;将科技的力量推向新的高度。 Vatee万腾在科技领域敢于挑战传统&#xff0c;积极探索未知的可能…

快速解决Navicat连接数据库报错:10061

目录 问题原因&#xff1a; 错误提示&#xff1a; 解决方案&#xff1a; 问题1&#xff1a;如何进入指定目录&#xff1f; 问题2&#xff1a;若出现&#xff1a;“服务名无效” 将MySQL注册到win服务中 问题原因&#xff1a; mysql服务没有开启&#xff08;可能会在更新windows…