欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Java中基于Geotools對PostGIS數(shù)據(jù)庫的空間查詢實踐教程

 更新時間:2025年05月27日 11:17:32   作者:夜郎king  
本文將深入探討這一實踐,從連接配置到復雜空間查詢操作,包括點查詢、區(qū)域范圍查詢以及空間關系判斷等,全方位展示如何在 Java 環(huán)境下借助 Geotools 駕馭 PostGIS 數(shù)據(jù)庫,實現(xiàn)高效精準的空間數(shù)據(jù)檢索,為相關領域開發(fā)者提供實用的技術路徑,助力空間數(shù)據(jù)應用的創(chuàng)新拓展

前言

在當今數(shù)字化浪潮下,空間數(shù)據(jù)的應用價值日益凸顯,從城市規(guī)劃到環(huán)境監(jiān)測,從物流配送到地理信息系統(tǒng)(GIS)開發(fā),精準、高效的空間數(shù)據(jù)查詢成為關鍵環(huán)節(jié)。而 Java 作為廣泛應用的編程語言,在與地理空間技術的融合中展現(xiàn)出獨特魅力。Geotools 作為開源的 Java GIS 庫,為 Java 開發(fā)者提供了強大的地理空間數(shù)據(jù)處理能力,猶如一把開啟空間數(shù)據(jù)寶藏之門的鑰匙。PostGIS 則是 PostgreSQL 數(shù)據(jù)庫的空間擴展,能夠存儲和處理復雜的空間數(shù)據(jù)類型,是空間數(shù)據(jù)存儲與管理的得力助手。將 Geotools 與 PostGIS 結(jié)合,意味著我們可以利用 Java 強大的編程生態(tài)和 Geotools 豐富的 GIS 功能,深度挖掘 PostGIS 中海量空間數(shù)據(jù)的潛力。

比如我們需要對某一個風景區(qū)的商業(yè)開發(fā)程度進行評價,需要做的第一件事就是根據(jù)風景區(qū)的范圍也就是AOI數(shù)據(jù),查詢這個AOI數(shù)據(jù)的范圍內(nèi)所有的POI數(shù)據(jù),然后根據(jù)不同的POI類型進行分類,從而計算不同的POI類型在景區(qū)內(nèi)的分布情況,加上一些空間分析和相關計算,從而可以對當前景區(qū)的一個商業(yè)情況進行初步的評估,從而為景區(qū)的優(yōu)質(zhì)發(fā)展提供指導和參考,以下圖為例:

本博客將深入探討這一實踐,從連接配置到復雜空間查詢操作,包括點查詢、區(qū)域范圍查詢以及空間關系判斷等,全方位展示如何在 Java 環(huán)境下借助 Geotools 駕馭 PostGIS 數(shù)據(jù)庫,實現(xiàn)高效精準的空間數(shù)據(jù)檢索,為相關領域開發(fā)者提供實用的技術路徑,助力空間數(shù)據(jù)應用的創(chuàng)新拓展。

一、相關技術背景介紹

這里以長沙岳麓山風景區(qū)為例,主要介紹如何得出岳麓山及風景區(qū)內(nèi)的POI數(shù)據(jù)的分布情況。從而為下一步對該風景區(qū)的商業(yè)及人文指數(shù)進行評價。由此我們需要對岳麓山風景區(qū)的空間范圍數(shù)據(jù),以及有了AOI范圍后對其范圍內(nèi)的POI數(shù)據(jù)進行檢索的流程進行簡單說明。

1、評價對象AOI

關于如何獲取AOI數(shù)據(jù),在之前的博文中我們曾經(jīng)進行過相應的說明。大家可以從相應的官方渠道獲取。也可以從互聯(lián)網(wǎng)圖源來獲取,比如從百度地圖或者高德地圖中也可以獲取數(shù)據(jù)。以高德地圖為例,在下面的查詢界面中可以查看到具體的數(shù)據(jù):

我們可以在網(wǎng)絡請求的地方對這個空間面數(shù)據(jù)進行調(diào)試,也可以將這個數(shù)據(jù)復制到我們的開發(fā)環(huán)境中,從而可以實現(xiàn)離線的空間計算。如下圖所示:

上面的數(shù)據(jù)也是本博客的目標AOI范圍,我們后續(xù)的所有工作都將圍繞這個區(qū)域來展開。 因此,如果對AOI數(shù)據(jù)不是很了解,建議先對相關知識又一個大體的認識以便于更好的掌握相關知識。

2、數(shù)據(jù)處理流程

為了讓大家對整個數(shù)據(jù)處理的流程有一個簡單的認識,這里將整個數(shù)據(jù)的處理流程給讀者進行分享,大致的流程步驟如下:

從整體來說,分為三個階段。第一個階段是AOI即空間查詢面的構建,第二界面是基于AOI面的POI檢索,第三階段就是將兩個圖層進行數(shù)據(jù)疊加后渲染出圖。 下面將結(jié)合流程圖對重要的處理節(jié)點的邏輯進行詳細的介紹。

二、對AOI空間范圍查詢實踐

本節(jié)將重點介紹如何對AOI數(shù)據(jù)進行空間范圍查詢的實現(xiàn)進行說明。對應前文提到的三個階段來分別展開,從查詢目標的空間查詢構建到空間樣式創(chuàng)建,最后對整體成果進行出圖逐級展開。

1、空間查詢構建

空間查詢的構建比較簡單,主要包含三個環(huán)節(jié)的工作,第一個是將字符串類型的AOI數(shù)據(jù)進行解析,剛開始是從高德地圖中獲取AOI字符串,由于是高德地圖的坐標,因此我們首先要對坐標進行轉(zhuǎn)換,將其轉(zhuǎn)換為我們熟悉的WGS84的地理坐標,最后再將轉(zhuǎn)換好的坐標來構建一個完整的查詢面,關鍵代碼如下所示:

/**
* - 將AOI字符串轉(zhuǎn)換成Polygon對象
* @return
*/
public static Polygon convertAoi2Polygon(String aoistr) {
	String [] AOI_Str_Array = aoistr.split(";");
	// 獲取GeometryFactory實例
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
    Coordinate[] coords = {};
    if( AOI_Str_Array.length > 0) {
        coords = new Coordinate[AOI_Str_Array.length];
    }
    //處理坐標
    for (int i = 0; i < AOI_Str_Array.length; i++) {
        String loc = AOI_Str_Array[i];
        String [] latlon = loc.split(",");
		double lng = Double.parseDouble(latlon[0]);
		double lat = Double.parseDouble(latlon[1]);
		//將高德坐標轉(zhuǎn)換成WGS84坐標
		double [] gcj284 = CoordinateTransformUtil.gcj02towgs84(lng, lat);
		//System.out.println("高德坐標轉(zhuǎn)wgs84坐標" + gcj284[0] + "=" + gcj284[1]);
		coords[i] = new Coordinate(gcj284[0], gcj284[1]);
	}
    LinearRing shell = geometryFactory.createLinearRing(coords);
    Polygon polygon = geometryFactory.createPolygon(shell, null);
    polygon.setSRID(4326);//設置4326的坐標
    return polygon;
}

經(jīng)過前面的步驟,我們已經(jīng)成功的合成了我們的查詢空間目標,接下來就需要基于Geotools來構建對PostGIS數(shù)據(jù)庫的空間查詢API, 為了演示我們本地的POI功能,這里我們使用本地的POI信息表,當然這張表的數(shù)據(jù)可能與實際情況有一定的出入,僅做參考。關鍵代碼如下:

// 2. 創(chuàng)建PostGIS數(shù)據(jù)存儲
DataStore dataStore = createPostgisDataStore();
// 3. 二次查詢:用該多邊形查詢點數(shù)據(jù)(如查詢橘子洲景區(qū)內(nèi)的POI)
String poiLayerName = "biz_poi_info";
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
PropertyName geomProperty = ff.property("geom"); // 點數(shù)據(jù)的幾何列名
// 4、空間關系:點在多邊形內(nèi)(WITHIN)或相交(INTERSECTS)
Filter spatialFilter = ff.within(geomProperty, ff.literal(aoiPolygon));
Query pointQuery = new Query(poiLayerName, spatialFilter);
FeatureSource pointSource = dataStore.getFeatureSource(poiLayerName);

為了方便查看是否成功的執(zhí)行了查詢,這里我們將查詢結(jié)果進行打印輸出。可以在控制臺看到很多的信息輸出,如下圖所示 :

System.out.println("POI數(shù)量:"+points.size());
// 6. 處理結(jié)果
try (FeatureIterator iterator = points.features()) {
    while (iterator.hasNext()) {
       Feature pointFeature = iterator.next();
       Geometry point = (Geometry) pointFeature.getDefaultGeometryProperty().getValue();
       System.out.println("POI坐標: " + point.getCoordinate());
       printSimpleFeatureAttributes((SimpleFeature)pointFeature); // 打印屬性
       System.out.println("------------------------------------------------------");
    }
}

運行后在IDE的控制臺中可以看到以下輸出:

能看到以上結(jié)果說明我們的空間查詢函數(shù)構建正確,可以正常執(zhí)行。 

2、空間樣式創(chuàng)建

為了能讓展示的效果更好,因此我們需要對獲取的AOI數(shù)據(jù)面和AOI數(shù)據(jù)面內(nèi)的POI數(shù)據(jù)進行標繪,這里我們需要使用SLD的方式來進行美化,兩個生成空間樣式的方法如下:

 public static Style createDashedBorderStyle() {
        StyleFactory sf = CommonFactoryFinder.getStyleFactory();
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
        PolygonSymbolizer symbolizer = sf.createPolygonSymbolizer(
        		sf.createStroke(ff.literal(Color.DARK_GRAY), ff.literal(0.8)),
                sf.createFill(ff.literal(Color.BLUE), ff.literal(0.8)), // 80%透明度
                null
        );
        Rule rule = sf.createRule();
        rule.symbolizers().add(symbolizer);
        FeatureTypeStyle fts = sf.createFeatureTypeStyle();
        fts.rules().add(rule);
        Style style = sf.createStyle();
        style.featureTypeStyles().add(fts);
        return style;
    }
    private static Style createPoiStyle() {
        StyleFactory sf = CommonFactoryFinder.getStyleFactory();
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
        // 創(chuàng)建圓形符號
        Mark mark = sf.createMark();
        mark.setWellKnownName(ff.literal("circle"));
        mark.setFill(sf.createFill(ff.literal(Color.RED)));
        mark.setStroke(sf.createStroke(ff.literal(Color.BLACK), ff.literal(1)));
        Graphic graphic = sf.createDefaultGraphic();
        graphic.graphicalSymbols().clear();
        graphic.graphicalSymbols().add(mark);
        PointSymbolizer pointSym = sf.createPointSymbolizer(graphic, null);
        // 新增震級標注
        Font font = sf.createFont(ff.literal("楷體"),ff.literal("Regular"),ff.literal("normal"),ff.literal(18));
        // 創(chuàng)建文本標注
       TextSymbolizer textSym = sf.createTextSymbolizer(
                sf.createFill(ff.literal(Color.WHITE)),
                new Font[] { font },
                null,
                ff.property("name"),  // 標注字段
                null,
                null
        );
        // 標注位置(點右側(cè)偏移)
        AnchorPoint anchor = sf.createAnchorPoint(ff.literal(-0.05), ff.literal(0.05));
        Displacement displacement = sf.createDisplacement(ff.literal(0.1), ff.literal(0));
        Fill textFill = sf.createFill(ff.literal(Color.RED));
        Halo halo = sf.createHalo(
            sf.createFill(ff.literal(Color.WHITE)),
            ff.literal(1)
        );
        textSym.setFont(font);
        textSym.setFill(textFill);
        textSym.setHalo(halo);
        //新的設置方法
        PointPlacement placement = sf.createPointPlacement(anchor, displacement, ff.literal(0));
        textSym.setLabelPlacement(placement);
        Rule rule = sf.createRule();
        rule.symbolizers().add(pointSym);
        rule.symbolizers().add(textSym);
        FeatureTypeStyle fts = sf.createFeatureTypeStyle();
        fts.rules().add(rule);
        Style style = sf.createStyle();
        style.featureTypeStyles().add(fts);
        return style;
    }

創(chuàng)建了以上的樣式之后,我們就可以將樣式和數(shù)據(jù)進行融合,這樣就能繪制出漂亮的地圖了。 

3、成果出圖

在完成查詢數(shù)據(jù)的轉(zhuǎn)換以及空間查詢的實現(xiàn)等,接下來就是揭曉答案的時候,我們在代碼層面實現(xiàn)了對岳麓山的AOI構建以及其AOI包圍的POI數(shù)據(jù),關鍵代碼如下:

SimpleFeatureCollection poiCollection = (SimpleFeatureCollection) pointSource.getFeatures(pointQuery);
// 7. 創(chuàng)建樣式
Style aoiStyle = createDashedBorderStyle();
 Style poiStyle = createPoiStyle();
// 8. 創(chuàng)建地圖內(nèi)容
MapContent mapContent = new MapContent();
SimpleFeatureSource aoiSfs = convert(aoiPolygon);
mapContent.addLayer(new FeatureLayer(aoiSfs, aoiStyle));
mapContent.addLayer(new FeatureLayer(poiCollection, poiStyle));
// 9. 設置輸出范圍和尺寸
ReferencedEnvelope mapBounds = poiCollection.getBounds();
mapBounds.expandBy(0.2); // 擴展邊界
// 10、輸出圖像大?。ɡ纾簩挾葂高度)
int width = 1920; // 可根據(jù)需求調(diào)整		
// 計算地理寬高比
double aspectRatio = mapBounds.getWidth() / mapBounds.getHeight();
//根據(jù)比例計算新高度
int height = (int) Math.round(width / aspectRatio);
// 渲染圖片
BufferedImage image = renderMap(mapContent, aoiSfs.getBounds(), width, height);
// 保存圖片
ImageIO.write(image, "png", new File("D:/AOI及其包含POI數(shù)據(jù)示意圖.png"));
System.out.println("finished");  
dataStore.dispose();

使用main函數(shù)或者測試用例都可以執(zhí)行以上的代碼,程序運行后可以在對應的磁盤目錄下看到以下的成果:

從上圖中可以明顯看到,在岳麓上上,一些POI的分布基本還是比較集中的,比如東北方向, 中間的區(qū)域也是非常多。當然,把POI數(shù)據(jù)展現(xiàn)在地圖上還只是一個階段,要想實現(xiàn)商業(yè)化,評估。在有了POI數(shù)據(jù)之后,還要結(jié)合數(shù)據(jù)量,聚類等方面進行空間的分析,且聽我們下回分解。

三、總結(jié)

以上就是本文的主要內(nèi)容,本博客將深入探討基于Geotools對PostGIS數(shù)據(jù)庫的空間查詢實踐,從連接配置到復雜空間查詢操作,包括點查詢、區(qū)域范圍查詢以及空間關系判斷等,全方位展示如何在 Java 環(huán)境下借助 Geotools 駕馭 PostGIS 數(shù)據(jù)庫,實現(xiàn)高效精準的空間數(shù)據(jù)檢索,為相關領域開發(fā)者提供實用的技術路徑,助力空間數(shù)據(jù)應用的創(chuàng)新拓展。如果您也需要對一個AOI數(shù)據(jù)進行范圍內(nèi)的POI進行分析查詢,并且使用的GeoTools的基礎PostGIS訪問功能,那么您可以使用以上實現(xiàn)過程和代碼進行調(diào)試。行文倉促,定有不足之處,歡迎各位朋友在評論區(qū)批評指正,不勝感激。

到此這篇關于在Java中基于Geotools對PostGIS數(shù)據(jù)庫的空間查詢實踐的文章就介紹到這了,更多相關java Geotools PostGIS空間查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • spring boot啟動時加載外部配置文件的方法

    spring boot啟動時加載外部配置文件的方法

    這篇文章主要給大家介紹了關于spring boot啟動時加載外部配置文件的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-02-02
  • SpringBoot實現(xiàn)前后端分離國際化的示例詳解

    SpringBoot實現(xiàn)前后端分離國際化的示例詳解

    Springboot國際化可以幫助使用者在不同語言環(huán)境中構建應用程序,這樣應用程序可以有效地適應不同語言文化背景下的用戶需求。本文主要介紹了SpringBoot實現(xiàn)前后端分離國際化的方法,需要的可以參考一下
    2023-02-02
  • Java常見報錯類型及解決方案詳細解析(從異常處理到錯誤排查)

    Java常見報錯類型及解決方案詳細解析(從異常處理到錯誤排查)

    這篇文章主要介紹了Java常見報錯類型及解決方案的相關資料,文中結(jié)合具體案例提供針對性解決方案,幫助開發(fā)者快速定位并修復問題,需要的朋友可以參考下
    2025-05-05
  • Java三大特性之封裝詳解

    Java三大特性之封裝詳解

    面向?qū)ο缶幊陶Z言是對客觀世界的模擬,客觀世界里成員變量都是隱藏在對象內(nèi)部的,外界無法直接操作和修改。?封裝可以被認為是一個保護屏障,防止該類的代碼和數(shù)據(jù)被其他類隨意訪問。本文將來和大家詳細說說Java中的封裝,需要的可以了解一下
    2022-10-10
  • Java獲取調(diào)用當前方法的類名或方法名(棧堆信息)的四種方式舉例

    Java獲取調(diào)用當前方法的類名或方法名(棧堆信息)的四種方式舉例

    在Java編程中我們經(jīng)常需要在運行時獲取當前執(zhí)行的方法名稱,這在日志記錄、性能監(jiān)控、調(diào)試等方面非常有用,這篇文章主要給大家介紹了關于Java獲取調(diào)用當前方法的類名或方法名(棧堆信息)的四種方式,需要的朋友可以參考下
    2024-09-09
  • Springboot的啟動原理詳細解讀

    Springboot的啟動原理詳細解讀

    這篇文章主要介紹了Springboot的啟動原理詳細解讀,springboot項目一般都是打包成jar包直接運行main方法啟動,當然也可以跟傳統(tǒng)的項目一樣打包war包放在tomcat里面啟動.那么springboot怎么直接通過main方法啟動呢,需要的朋友可以參考下
    2023-11-11
  • SpringCloud服務之間Feign調(diào)用不會帶上請求頭header的解決方法

    SpringCloud服務之間Feign調(diào)用不會帶上請求頭header的解決方法

    在Spring?Cloud中,使用Feign進行服務之間的調(diào)用時,默認情況下是不會傳遞header的,這篇文章給大家介紹SpringCloud服務之間Feign調(diào)用不會帶上請求頭header的解決方法,感興趣的朋友一起看看吧
    2024-01-01
  • Java建造者模式構建復雜對象的最佳實踐

    Java建造者模式構建復雜對象的最佳實踐

    建造者模式,是一種對象構建模式?它可以將復雜對象的建造過程抽象出來,使這個抽象過程的不同實現(xiàn)方法可以構造出不同表現(xiàn)的對象。本文將通過示例講解建造者模式,需要的可以參考一下
    2023-04-04
  • Java實現(xiàn)簡單文件過濾器功能

    Java實現(xiàn)簡單文件過濾器功能

    下面小編就為大家分享一篇Java實現(xiàn)簡單文件過濾器功能,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • zuul過濾器中轉(zhuǎn)發(fā)請求頭的解決方案

    zuul過濾器中轉(zhuǎn)發(fā)請求頭的解決方案

    這篇文章主要介紹了zuul過濾器中轉(zhuǎn)發(fā)請求頭的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論