基于SuperMap iObjects Java生成地圖瓦片

作者:dongyx

前言

在GIS領域,地圖瓦片技術作為GIS領域的關鍵技術,是提高地圖服務性能的關鍵手段之一。通過預先生成地圖的瓦片數據,可以顯著提升用戶訪問地圖時的響應速度和體驗。SuperMap iObjects for Java作為一款強大的GIS開發組件,為開發人員提供了豐富的地圖制圖、空間分析和數據處理功能,使得地圖瓦片的生成變得更加便捷高效。本文將詳細介紹如何使用SuperMap iObjects for Java從零開始生成地圖瓦片。

一、地圖瓦片的概念與優勢

地圖瓦片是指包含了一系列比例尺、一定地圖范圍內的地圖瓦片文件。地圖瓦片按照金字塔組織結構,為每張瓦片進行唯一的級別、行列號標記。在平移、縮放地圖時,瀏覽器根據金字塔規則,計算出所需的瓦片,從瓦片服務器獲取并拼接。
在這里插入圖片描述SuperMap提供的瓦片類型包括柵格瓦片和矢量瓦片。

柵格瓦片:

柵格瓦片是一種比較傳統的模式,其本質上是將空間數據(柵格數據和矢量數據)分別渲染為不同縮放級別的地圖圖片,然后將各個級別的圖片按照一定規則切分,一定的 “規則”存儲到硬盤或數據庫中,構成一幅完整的地圖。柵格瓦片通常以PNG、JPEG、Webp等圖像格式存儲。
在這里插入圖片描述

特點:

  • 兼容性強:幾乎所有的設備和瀏覽器都能夠顯示圖片,因此兼容性很好。
  • 渲染效率高:瓦片是預先渲染好的,客戶端不需要進行復雜的渲染計算,加載速度快。
  • 樣式固定:樣式在瓦片生成時已經確定,后續無法更改。
  • 數據量較大:相比矢量瓦片,柵格瓦片因為是圖片,所以數據量通常更大,尤其在高分辨率或大范圍地圖的情況下。

矢量瓦片:

以圖片為介質的柵格瓦片打開了互聯網地圖的大門,互聯網地圖得以迅速普及。但是,隨著地圖的移動化和應用的逐漸深入,柵格瓦片體積大、生成效率低等缺點愈加明顯,已經無法滿足應用需求,矢量瓦片應運而生。矢量瓦片是將地圖中的矢量圖層以瓦片的形式進行切分和存儲。
矢量瓦片在存儲時,其相對于柵格瓦片體積小,生成效率高,適用于地圖中時效性要求較高的地物要素的表達,如POI信息、路線信息等。如在天地圖中,POI圖層采用矢量瓦片技術,滿足數據的實時更新需求。同時,可以實現地圖離線,大幅提升了移動端地圖的瀏覽性能,提高了工作的可能性和有效性。
另外,矢量瓦片支持樣式修改,不再需要為不同的樣式而反復進行制圖、渲染、切圖、更新服務等過程。如在國土等行業涉及海量數據的應用中,當地圖樣式發生變化時,矢量瓦片可以直接更改樣式,省時省力。

特點:

  • 樣式靈活:矢量瓦片的樣式在客戶端動態應用,可以根據需求調整顏色、線寬、透明度等,甚至可以實現動態地圖。
  • 數據量小:MVT格式高效壓縮了矢量數據,使得瓦片體積小,易于快速傳輸。
  • 可交互性強:客戶端可以解析矢量瓦片中的幾何和屬性信息,實現點擊、高亮、提示框等交互功能。
  • 客戶端渲染:矢量瓦片需要客戶端進行渲染,這對客戶端的性能有一定要求,但隨著現代瀏覽器和硬件的發展,這通常不是問題。

選擇哪種瓦片格式主要取決于應用場景和需求。如果需要高度可定制的地圖樣式和豐富的用戶交互,則MVT矢量瓦片是更好的選擇。如果優先考慮兼容性和簡化客戶端負擔,或者沒有動態樣式和交互的需求,則柵格瓦片可能更加合適。

二、SuperMap iObjects Java從零開始生成地圖柵格瓦片

經常有客戶會有后臺自動化切圖的需求,該示例主要是通過一張tif影像從創建工作空間、創建數據源、創建鑲嵌數據集,然后進行切圖處理,后續也可以通過Java代碼通過POST請求發iServer地圖服務。

2.1 數據準備

2.1.1 創建工作空間

        //實例化一個WorkspaceWorkspace workspace = new Workspace();//實例化一個工作空間連接參數WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo();//設置工作空間類型workspaceConnectionInfo.setType(WorkspaceType.SMWU);String workspaceName = "t"+System.currentTimeMillis();//設置工作空間名稱workspaceConnectionInfo.setName(workspaceName);String workspacePath = workspaceDir.concat(File.separator).concat(workspaceName);//設置工作空間路徑workspaceConnectionInfo.setServer(workspacePath);boolean flag = workspace.saveAs(workspaceConnectionInfo);if (flag) {workspace.save();System.out.println("新建工作空間成功!"+ workspace.getConnectionInfo().getServer());} else {System.out.println("新建工作空間失敗!"+ workspace.getConnectionInfo().getServer());}

2.1.2 創建數據源

        WorkspaceConnectionInfo wInfo = workspace.getConnectionInfo();String workspaceDir = new File(wInfo.getServer()).getParent();String workspaceName = wInfo.getName();String udbPath = workspaceDir.concat(File.separator).concat(workspaceName);//實例化數據源連接參數DatasourceConnectionInfo dInfo = new DatasourceConnectionInfo();//設置數據源類型dInfo.setEngineType(EngineType.UDBX);//設置數據源文件路徑dInfo.setServer(udbPath);String udbName = "u"+System.currentTimeMillis();//設置數據源別名,別名在一個工作空間中是唯一的dInfo.setAlias(udbName);Datasource datasource = workspace.getDatasources().create(dInfo);if (datasource.isOpened()) {System.out.println("datasource.isReadOnly() = " + datasource.isReadOnly());} else {System.out.println("新建Udbx數據源失敗!");}

2.1.3 創建鑲嵌數據集

        Datasets datasets = datasource.getDatasets();PrjCoordSys prjCoordSys = new PrjCoordSys();prjCoordSys.fromEPSGCode(4326);//獲取一個可用的數據集名稱String datasetName = datasets.getAvailableDatasetName("mosaic", DatasetType.MOSAIC);//創建鑲嵌數據集DatasetMosaic datasetMosaic = datasets.createDatasetMosaic(datasetName, prjCoordSys);String files = "D:\\陜西省土壤數據.tif";//添加影像文件datasetMosaic.addFiles(new String[]{files}, null);//構建概視圖datasetMosaic.buildOverview("C:\\Users\\admin\\Desktop\\supermap", 512, 512, 3, false, 0.0);//構建統計信息boolean flag = datasetMosaic.buildStatistics();System.out.println("構建鑲嵌數據集統計信息=" + flag);

2.1.4 構建地圖

        //構建地圖對象com.supermap.mapping.Map map = new com.supermap.mapping.Map(workspace);Layers layers = map.getLayers();//將鑲嵌數據集添加到地圖中LayerMosaicGroup layerMosaicGroup = layers.addMosaicGroup(datasetMosaic, true);//設置邊界圖層不可見。 //設置輪廓圖層不可見。//標注圖層不可見for (int i = 0; i < layerMosaicGroup.getCount(); i++) {if (layerMosaicGroup.get(i).getSubLayerType() != LayerType.SUBLAYER_MOSAIC) {layerMosaicGroup.get(i).setVisible(false);}}//設置圖層風格LayerSettingImage layerSettingImage = layerMosaicGroup.getMosaicLayer().getLayerSettingImage();PixelFormat pixelFormat = datasetMosaic.getPixelFormat();if (PixelFormat.BIT16 == pixelFormat || PixelFormat.BIT32 == pixelFormat || PixelFormat.BIT64 == pixelFormat ||PixelFormat.DOUBLE == pixelFormat || PixelFormat.SINGLE == pixelFormat ||PixelFormat.UBIT16 == pixelFormat || PixelFormat.UBIT32 == pixelFormat ||PixelFormat.UNKONOWN == pixelFormat) {ImageStretchOption imageStretchOption = new ImageStretchOption();//設置影像拉伸方式imageStretchOption.setStretchType(ImageStretchType.STANDARDDEVIATION);layerSettingImage.setImageStretchOption(imageStretchOption);}map.viewEntire();Maps maps = workspace.getMaps();maps.add("mosaic", map.toXML());//保存地圖maps.setMapXML("mosaic", map.toXML());workspace.save();

2.2 創建地圖瓦片

        //構建Map對象com.supermap.mapping.Map map = new com.supermap.mapping.Map(workspace);String mapXML = workspace.getMaps().getMapXML(0);map.fromXML(mapXML);//設置緩存名稱String cacheName = "CTH" +System.currentTimeMillis();MapCacheBuilder mapCacheBuilder = new MapCacheBuilder();// 柵格瓦片參數設置mapCacheBuilder.setMap(map);mapCacheBuilder.setBounds(map.getBounds());mapCacheBuilder.setIndexBounds(mapCacheBuilder.getGlobalIndexBounds());mapCacheBuilder.setStorageType(StorageType.Compact);mapCacheBuilder.setOutputFolder("F:\\重點客戶數據\\");       mapCacheBuilder.setCacheName(cacheName);// 進度條輸出(公共)mapCacheBuilder.addSteppedListener(new SteppedListener() {@Overridepublic void stepped(SteppedEvent steppedEvent) {System.out.println(steppedEvent.getTitle() + ":" + steppedEvent.getMessage() + ":" + steppedEvent.getPercent() + "%");}});boolean build = false;mapCacheBuilder.computeOutputScales();mapCacheBuilder.setIgnoreInvalidDrawing(true);mapCacheBuilder.setTileFormat(TileFormat.JPG_PNG);mapCacheBuilder.setTilingMode(MapTilingMode.GLOBAL);HashMap<Double, String> scalesMaps = mapCacheBuilder.getGlobalLevelScales();Integer minScales = 6;Integer maxScales = 8;// 獲取比例尺double[] outputScales = getOutputScales(scalesMaps, minScales, maxScales);HashMap<Double, String>  doubleStringHashMap2 = new HashMap<>();doubleStringHashMap2.put(outputScales[0],"6");doubleStringHashMap2.put(outputScales[1],"7");doubleStringHashMap2.put(outputScales[2],"8");mapCacheBuilder.setOutputScales(outputScales);mapCacheBuilder.setOutputScaleCaptions(doubleStringHashMap2);mapCacheBuilder.resumable(false);// 開始切圖(柵格瓦片)build = mapCacheBuilder.build();// 公共if (build) {System.out.println("切圖成功"+cacheName);System.out.println(System.currentTimeMillis());} else {System.out.println("切圖失敗");}// 銷毀相關資源mapCacheBuilder.dispose();
  private static double[] getOutputScales(HashMap<Double, String> scalesMaps, Integer minScales, Integer maxScales) {int arraylength = maxScales - minScales + 1;double[] outputScales = new double[arraylength];String[] values = new String[arraylength];for (int i = 0; i < values.length; i++) {values[i] = String.valueOf(minScales + i);}for (int i = 0; i < outputScales.length; i++) {outputScales[i] = getMapKey(scalesMaps, values[i]);}return outputScales;}private static Double getMapKey(HashMap<Double, String> maps, String value) {Double key = 0.0;for (Map.Entry<Double, String> entry : maps.entrySet()) {if (entry.getValue().equals(value)) {key = entry.getKey();}}return key;}

結語

以上就是生成地圖瓦片的相關操作步驟,后續將會繼續分享如何使用SuperMap iObjects Java進行多任務切圖,相比單任務切圖,多任務切圖大大提升了切圖效率,敬請期待!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208149.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208149.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208149.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Docker, Docker-compose部署Sonarqube

參考文檔 鏡像地址: https://hub.docker.com/_/sonarqube/tags Docker部署文檔地址 Installing from Docker | SonarQube Docs Docker-compose文檔部署地址&#xff1a; Installing from Docker | SonarQube Docs 部署鏡像 2.1 docker部署 # 宿主機執行 $. vi /etc/sysctl.conf…

Java注解詳解

概述 注解是對程序代碼進行標注和解釋的一種方式。在Java中&#xff0c;注解提供了一種元數據形式&#xff0c;能夠在程序中嵌入有關程序的信息&#xff0c;以便進行進一步的處理。注解通過使用符號來聲明&#xff0c;如Override、Deprecated等。 注解和注釋的區別 注釋&…

Unity中Batching優化的GPU實例化(4)

文章目錄 前言一、構建需要實例化的額外數據二、在頂點著色器&#xff0c;將實例化 ID 從 appdata 存入 v2f 傳給片元著色器三、在片斷著色器中訪問具體的實例化變量三、使用代碼修改Shader材質屬性&#xff0c;實現GPU實例化后不同對象顏色不同的效果1、在C#測試腳本生成小板凳…

ReactJs筆記摘錄

前言 以前2018年搞過一段時間react antd開發&#xff0c;兜兜轉轉又回到react世界。 TODO中 Hook函數 JSX語法 根元素與斜杠 注意局部的jsx片段也要加根元素: return (<div>{items.map((item) > (// 此處只能有一個根元素!!!<>...<div className&quo…

要求CHATGPT高質量回答的藝術:提示工程技術的完整指南—第 23 章:命名實體識別提示

要求CHATGPT高質量回答的藝術&#xff1a;提示工程技術的完整指南—第 23 章&#xff1a;命名實體識別提示 命名實體識別&#xff08;NER&#xff09;是一種允許模型對文本中的命名實體&#xff08;如人物、組織、地點和日期&#xff09;進行識別和分類的技術。 要在 ChatGPT…

微前端介紹

目錄 微前端概念 微前端特性 場景演示 微前端方案 iframe 方案 qiankun 方案 micro-app 方案 EMP 方案 無界微前端 方案 無界方案 成本低 速度快 原生隔離 功能強大 總結 前言&#xff1a;微前端已經是一個非常成熟的領域了&#xff0c;但開發者不管采用哪個現…

Leetcode—290.單詞規律【簡單】

2023每日刷題&#xff08;五十一&#xff09; Leetcode—290.單詞規律 實現代碼 class Solution { public:bool wordPattern(string pattern, string s) {unordered_map<char, string> m1;unordered_map<string, char> m2;stringstream stro(s);string tmp;for(a…

(env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序

應公司需求&#xff0c;在特定情況下需要修改ip 在開發過程中出現的小插曲 1、第一種情況&#xff1a;重復聲明 2、第二種情況&#xff1a; 應官方要求&#xff0c;需要跳轉的 tabBar 頁面的路徑&#xff08;需在 pages.json 的 tabBar 字段定義的頁面&#xff09;&#xff0…

React中使用TypeScript代替prop-types

原文鏈接 公眾號-React中使用TypeScript代替prop-types 個人公眾號&#xff0c;嗚嗚嗚&#xff0c;求各位大佬們關注下&#xff0c;本人的公眾號主要寫React 跟NodeJs的 ?關于prop-types 對于部分的同學&#xff0c;不大了解為什么我們的代碼里面要用到prop-types這個庫&a…

ArkTS快速入門

一、概述 ArkTS是鴻蒙生態的應用開發語言。它在保持TypeScript&#xff08;簡稱TS&#xff09;基本語法風格的基礎上&#xff0c;對TS的動態類型特性施加更嚴格的約束&#xff0c;引入靜態類型。同時&#xff0c;提供了聲明式UI、狀態管理等相應的能力&#xff0c;讓開發者可以…

深度學習基礎回顧

深度學習基礎 淺層網絡 VS 深層網絡深度學習常用的激活函數Sigmoid 函數ReLU 函數Softplus 函數tanh函數 歸納偏置CNN適用數據歸納偏置 RNN適用數據歸納偏置 淺層網絡 VS 深層網絡 淺層神經網絡參數過多&#xff0c;導致模型的復雜度和計算量很高&#xff0c;難以訓練。而深層…

Redisson的基礎使用(2)

布隆過濾器&#xff08;Bloom Filter&#xff09; 布隆過濾器一般用于解決緩存穿透的問題。主要原理是使用一組哈希函數&#xff0c;將元素映射成一組位數組中的索引位置。如果要檢查某個元素是否在集合中時&#xff0c;將此元素通過所有的哈希函數&#xff0c;查看哈希值對應的…

硬件開發筆記(十五):RK3568底板電路VGA顯示接口原理圖分析

若該文為原創文章&#xff0c;轉載請注明原文出處 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134849296 紅胖子網絡科技博文大全&#xff1a;開發技術集合&#xff08;包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬…

多態和繼承復習

與其明天開始&#xff0c;不如現在行動&#xff01; 文章目錄 多態多態成立的條件細節 繼承&#x1f48e;總結 多態 多態成立的條件 存在繼承關系或者實現關系子類重寫父類的方法父類引用指向子類對象 細節 通過父類的引用調用子類的對象 Animal animal new Dog();animal…

C語言搭建項目-學生管理系統(非鏈表)

、 目錄 搭建offer.h文件 搭建offer.c中的main函數 密碼登入系統 搭建my_oferr.c中的接口函數 使用幫助菜單接口函數 增加學生信息接口函數 查詢學生信息接口函數 刪除學生信息接口函數 保存學生信息接口 打開文件fopen 關閉文件fclose 判斷是否保存文件fwrite 退出執行文件…

C++:const類型數據的修改問題

在C語言中const類型的數據嚴格意義上可以修改&#xff1a; const int a1; int*b&a; *b2;不同于C語言&#xff0c;C中指針類型是要嚴格對應的&#xff0c;對const類型的數據必須使用const類型的指針進行接收&#xff0c;從而避免修改&#xff1b; 但問題是c中同樣支持指針的…

年度工作總結怎么寫?掌握這些年終總結萬能公式,讓你的報告出彩無比!

光陰似箭&#xff0c;日月如梭&#xff0c;時間總是不疾不徐地向前奔去&#xff0c;轉眼就來到了2023年的最后一個月&#xff0c;12月一到&#xff0c;上班族和打工人又要開始忙活工作總結的事情~ 工作總結&#xff0c;不僅是一年工作的回顧&#xff0c;更是未來規劃的起點。你…

Springboot中的RestTemplate

Springboot中的RestTemplate 在Spring Boot應用程序中&#xff0c;RestTemplate是一個用于進行HTTP請求的強大工具。通常用于與RESTful API進行交互、調用其他服務或執行HTTP請求。它提供了各種方法來發送HTTP請求&#xff08;如GET、POST、PUT、DELETE等&#xff09;&#xf…

cuda lib 線程安全的要義

1, 概述 cuda lib 線程安全的幾個多線程的情景&#xff1a; 單卡多線程&#xff1b; 多卡多線程-每卡單線程&#xff1b; 多卡多線程-每卡多線程&#xff1b; 需要考慮的問題&#xff1a; 每個 cublasHandle_t 只能有一個stream么&#xff1f; 每個cusolverHandle_t 只能有一…

python3.5安裝教程及環境配置,python3.7.2安裝與配置

大家好&#xff0c;小編來為大家解答以下問題&#xff0c;python3.5安裝教程及環境配置&#xff0c;python3.7.2安裝與配置&#xff0c;現在讓我們一起來看看吧&#xff01; python 從爬蟲開始&#xff08;一&#xff09; Python 簡介 首先簡介一下Python和爬蟲的關系與概念&am…