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

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

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

前言

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

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

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

一、相關(guān)技術(shù)背景介紹

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

1、評(píng)價(jià)對(duì)象AOI

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

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

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

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

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

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

二、對(duì)AOI空間范圍查詢實(shí)踐

本節(jié)將重點(diǎn)介紹如何對(duì)AOI數(shù)據(jù)進(jìn)行空間范圍查詢的實(shí)現(xiàn)進(jìn)行說(shuō)明。對(duì)應(yīng)前文提到的三個(gè)階段來(lái)分別展開(kāi),從查詢目標(biāo)的空間查詢構(gòu)建到空間樣式創(chuàng)建,最后對(duì)整體成果進(jìn)行出圖逐級(jí)展開(kāi)。

1、空間查詢構(gòu)建

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

/**
* - 將AOI字符串轉(zhuǎn)換成Polygon對(duì)象
* @return
*/
public static Polygon convertAoi2Polygon(String aoistr) {
	String [] AOI_Str_Array = aoistr.split(";");
	// 獲取GeometryFactory實(shí)例
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
    Coordinate[] coords = {};
    if( AOI_Str_Array.length > 0) {
        coords = new Coordinate[AOI_Str_Array.length];
    }
    //處理坐標(biāo)
    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]);
		//將高德坐標(biāo)轉(zhuǎn)換成WGS84坐標(biāo)
		double [] gcj284 = CoordinateTransformUtil.gcj02towgs84(lng, lat);
		//System.out.println("高德坐標(biāo)轉(zhuǎn)wgs84坐標(biāo)" + 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);//設(shè)置4326的坐標(biāo)
    return polygon;
}

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

// 2. 創(chuàng)建PostGIS數(shù)據(jù)存儲(chǔ)
DataStore dataStore = createPostgisDataStore();
// 3. 二次查詢:用該多邊形查詢點(diǎn)數(shù)據(jù)(如查詢橘子洲景區(qū)內(nèi)的POI)
String poiLayerName = "biz_poi_info";
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
PropertyName geomProperty = ff.property("geom"); // 點(diǎn)數(shù)據(jù)的幾何列名
// 4、空間關(guān)系:點(diǎn)在多邊形內(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é)果進(jìn)行打印輸出??梢栽诳刂婆_(tái)看到很多的信息輸出,如下圖所示 :

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坐標(biāo): " + point.getCoordinate());
       printSimpleFeatureAttributes((SimpleFeature)pointFeature); // 打印屬性
       System.out.println("------------------------------------------------------");
    }
}

運(yùn)行后在IDE的控制臺(tái)中可以看到以下輸出:

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

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

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

 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)建圓形符號(hào)
        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);
        // 新增震級(jí)標(biāo)注
        Font font = sf.createFont(ff.literal("楷體"),ff.literal("Regular"),ff.literal("normal"),ff.literal(18));
        // 創(chuàng)建文本標(biāo)注
       TextSymbolizer textSym = sf.createTextSymbolizer(
                sf.createFill(ff.literal(Color.WHITE)),
                new Font[] { font },
                null,
                ff.property("name"),  // 標(biāo)注字段
                null,
                null
        );
        // 標(biāo)注位置(點(diǎn)右側(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);
        //新的設(shè)置方法
        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ù)進(jìn)行融合,這樣就能繪制出漂亮的地圖了。 

3、成果出圖

在完成查詢數(shù)據(jù)的轉(zhuǎn)換以及空間查詢的實(shí)現(xiàn)等,接下來(lái)就是揭曉答案的時(shí)候,我們?cè)诖a層面實(shí)現(xiàn)了對(duì)岳麓山的AOI構(gòu)建以及其AOI包圍的POI數(shù)據(jù),關(guān)鍵代碼如下:

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. 設(shè)置輸出范圍和尺寸
ReferencedEnvelope mapBounds = poiCollection.getBounds();
mapBounds.expandBy(0.2); // 擴(kuò)展邊界
// 10、輸出圖像大?。ɡ纾簩挾葂高度)
int width = 1920; // 可根據(jù)需求調(diào)整		
// 計(jì)算地理寬高比
double aspectRatio = mapBounds.getWidth() / mapBounds.getHeight();
//根據(jù)比例計(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ù)或者測(cè)試用例都可以執(zhí)行以上的代碼,程序運(yùn)行后可以在對(duì)應(yīng)的磁盤(pán)目錄下看到以下的成果:

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

三、總結(jié)

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

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

相關(guān)文章

  • spring boot啟動(dòng)時(shí)加載外部配置文件的方法

    spring boot啟動(dòng)時(shí)加載外部配置文件的方法

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

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

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

    Java常見(jiàn)報(bào)錯(cuò)類型及解決方案詳細(xì)解析(從異常處理到錯(cuò)誤排查)

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

    Java三大特性之封裝詳解

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

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

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

    Springboot的啟動(dòng)原理詳細(xì)解讀

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

    SpringCloud服務(wù)之間Feign調(diào)用不會(huì)帶上請(qǐng)求頭header的解決方法

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

    Java建造者模式構(gòu)建復(fù)雜對(duì)象的最佳實(shí)踐

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

    Java實(shí)現(xiàn)簡(jiǎn)單文件過(guò)濾器功能

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

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

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

最新評(píng)論