<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-60  評論-138  文章-1  trackbacks-0

    前言: 
          如果您對JTS這三個詞還是沒有一個概念,那么推薦您關注一下sinoly的博客。這個我能夠找到為數不多的關于jts的中文資料。
          http://m.tkk7.com/sinoly/archive/2007/02/09/99042.html
         下面這段話就是摘抄自sinoly老兄的博客: 
            ............它主要是完成了java對幾何對象、空間拓撲得核心操作算法。.......集成了java對幾何對象(點、線、面等)的對象管理外更大一部分工作是在完成對各種幾何對象的buffer、analyze以及空間索引.
          本文想要向您展示的就是一個空間索引的小小demo!
      
           jts本身有一個包就叫Index,當中分別給出了SpatialIndex接口的幾個實現。本文展現的就是quadtree的用法。
           quadtree翻譯過來就是四叉樹的意思,有一個很簡單的例子可以來理解四叉樹和空間索引的關系。那就是把中國的版圖來個十字型的分割,這樣就形成一個中心點和四個子節點。然后將每個子節點再次的進行十字分割。當分割到極小處時,整個中國的版圖就可以使用一個掛載很多節點的四叉樹來表示。每一個節點可以認為是一個具有經緯度及其描述信息的對象。
           當我們手中有很多點的時候,想要建立成一顆四叉樹,只要把上邊的思路反過來就可以了(對于每個節點之間的距離是否相等,目前我還沒有好的認識)。
           正如我們研發部local search的文斌而言,思路很簡單,但是不是每個人你都能夠實現。接下來,讓demo的代碼說話。

          1.建立一個對象,這個對象描述point除了經緯度外的其他信息(如果需要可以加上經緯度)。
         

     1/**
     2 * 
     3 * @author lang
     4 * @date 2007-12-17
     5 * @email lanfanss@126.com
     6 * @desc 代表point的信息
     7 * @since
     8 * 
     9 */

    10public class PointInfo {
    11    /**
    12     * 名稱
    13     */

    14    private String name;
    15    private String info;
    16
    17    public String getInfo() {
    18        return info;
    19    }

    20
    21    public void setInfo(String info) {
    22        this.info = info;
    23    }

    24
    25    public PointInfo(String name) {
    26        super();
    27        this.name = name;
    28    }

    29
    30    public String getName() {
    31        return name;
    32    }

    33
    34    public void setName(String name) {
    35        this.name = name;
    36    }

    37}

    2.接下來就是建立一顆樹,代碼如下
    public static void main(String[] args) {
            Quadtree quatree 
    = new Quadtree();
            
    // 構建幾個點
            PointInfo info1 = new PointInfo("故宮");
            quatree.insert(
    new Envelope(new Coordinate(116389373992178)), info1);
            PointInfo info2 
    = new PointInfo("太和殿");
            info2
                    .setInfo(
    "太和殿,俗稱金鑾殿,是宮殿群中最大的建筑。殿高36米,寬63米,面積為2380平方米。 “太和”語出《周易》,太和是“陰陽會和,沖和之氣也”,“混同宇內以玉太和”之意,即指宇宙萬物,和諧圓滿。太和殿坐落在“工”字形須彌座上,漢白玉雕成,分上中下三層,稱為丹墀或丹陛。雕欄稱為望柱,柱頭雕以云龍云圖案。那些伸出的為螭首,口中小孔為出水孔。共有螭首1142個。如遇雨天,可見千龍吐水之奇觀。 臺基上放置18個大銅爐,據說代表當時的18個省份。太和殿臺基上面的大平臺,放置銅龜、銅鶴各一對,象征“龜鶴千秋”,意為長壽。東有日晷西有喜量,象征皇權公正平允。這里是舉行大典奏九韶之樂的地方。");
            quatree.insert(
    new Envelope(new Coordinate(116390733991605)), info2);
            PointInfo info3 
    = new PointInfo("中和殿");
            info3
                    .setInfo(
    " 中和殿在太和殿后,平面呈方形。“中和”語出《禮記.中庸》,指不偏不倚,凡事做到恰如其分。 殿為方形攢尖頂,在三大殿中居中,也最小,是皇帝去太和殿大典之前休息的地方。皇帝去天、地、日、月四壇祭祀時,前一天也要在中和殿里看祭文。每年二月皇帝到先農壇舉行親耕儀式,前一天要來這里閱視種子、農具、祝文。這里現陳列的是乾隆年間的兩頂肩輿,即八抬大轎。 ");
            quatree.insert(
    new Envelope(new Coordinate(116390813991647)), info3);
            PointInfo info4 
    = new PointInfo("保和殿");
            info4
                    .setInfo(
    "保和殿,其意為“志不外馳,恬神守志”,就是說神志得專一,以保持宇內的和諧,才能福壽安樂,天下太平。 保和殿比太和殿規模小些,為重檐歇山頂。明朝冊立皇后,太子時,皇帝在此殿受賀。在清朝是舉行盛大宴會的地方。每年初一和十五在此宴請外族王公大臣,場面是十分壯觀的。公主下嫁時,也在這個殿里宴請附馬。這個殿最有名的事是舉行殿試。殿試就是皇帝本人親自監考、主考,是科舉考試的最高層次。前三名分別為狀元、榜眼、探花。 保和殿后是故宮最大的一塊雕石——云龍雕石,這塊苑葉青石長16.57米,寬3.07米,厚1.7米,總重二百多噸。上雕游龍,雙龍戲珠,游于云霧之中。 ");
            quatree.insert(
    new Envelope(new Coordinate(116390793991698)), info4);
            PointInfo info5 
    = new PointInfo("乾清宮");
            info5
                    .setInfo(
    "乾清宮明朝時為皇帝居住之處,皇帝在此處理政務、召見臣仆和外國使節。從清朝雍正皇帝之后,皇帝遷到養心殿居住,但仍在此批閱奏報,召見大臣。 乾清宮除是皇帝的寢宮和日常自理政務外,還舉行元旦、燈節、端午、中秋、冬至、萬壽等節的家宴。殿內寶座上方有一塊匾,上書“正大光明”四個漂亮的正楷字,其意為公正、光明磊落。這塊匾很有名氣,與秘密立儲關系密切。皇帝生前,親自從皇子中選一個德才兼備的作為皇太子——嗣皇帝,不予宣布,而是由皇帝秘密親書預立皇太子的名字的“御書”,密封匣內,茂于那塊匾后,等皇帝死后或死前,由御前大臣、軍機大臣等共同啟示,按御書所定,嗣皇帝即位。相傳雍正的第四子弘歷即乾隆皇帝,就是這…");
            quatree.insert(
    new Envelope(new Coordinate(116390673991873)), info5);
            PointInfo info6 
    = new PointInfo("坤寧宮");
            quatree.insert(
    new Envelope(new Coordinate(116390673991907)), info6);
            
    // 幾個離故宮較遠的點
            PointInfo info7 = new PointInfo("香山公園");
            quatree.insert(
    new Envelope(new Coordinate(116191513999031)), info7);
            PointInfo info8 
    = new PointInfo("香山寺");
            quatree.insert(
    new Envelope(new Coordinate(116191503999039)), info8);
            PointInfo info9 
    = new PointInfo("眼鏡湖");
            quatree.insert(
    new Envelope(new Coordinate(116181543999566)), info9);

    當中需要說明的部分如下: 
             quatree.insert(new Envelope(new Coordinate(11638937, 3992178)), info1);
              當中的Coordinate代表了一個只是包含經緯度的點(point)。在jts中,還有另外一個專門的對象表示點,就是point對象,但是這里我們只是想用經緯度來建立好節點之間的關系,故而只是采用了Coordinate。
              而Envelope,這個對象其實代表的是一個矩形框。可能是因為信封就是一個矩形框的原因,所以,加拿大人就用這個單詞來表示矩形了。Envelope的構造函數中需要給出矩形的對角坐標。但是我們這里只是有一個點,所以,jts會把這一個單獨的點也作為一個矩形。
             這就是說明,jts中結點不是簡單的point,而是一個矩形(Envelope)。
             至于最后的info,則是表示點的其他描述信息。
              需要補充的是,jts目前只是支持二維,三維的z坐標永遠是0。

     3. 建立一顆樹的目的不是等待他發芽,而是為了搜索(everyone has his purpose!)

         quatree 提供了三個搜索方法,簽名分別如下: 
             

    public List query(Envelope searchEnv) {
            
    /**
             * the items that are matched are the items in quads which overlap the
             * search envelope
             
    */

            ArrayListVisitor visitor 
    = new ArrayListVisitor();
            query(searchEnv, visitor);
            
    return visitor.getItems();
        }


        
    public void query(Envelope searchEnv, ItemVisitor visitor) {
            
    /**
             * the items that are matched are the items in quads which overlap the
             * search envelope
             
    */

            root.visit(searchEnv, visitor);
        }


        
    /**
         * Return a list of all items in the Quadtree
         
    */

        
    public List queryAll() {
            List foundItems 
    = new ArrayList();
            root.addAllItems(foundItems);
            
    return foundItems;
        }

      每個函數的含義也是很簡單的,分別表示搜索范圍搜索,范圍過濾搜索和全部搜索。
       接下來我們就分別嘗試分為搜索和范圍過濾搜索:
       范圍搜索很簡單,只要給出一個矩形框,然后傳入就可以了,代碼如下:
      

    // 看看在故宮旁邊能夠找到什么
            System.out.println("看看在故宮旁邊能夠找到什么");
            List
    <PointInfo> points = quatree.query(new Envelope(new Coordinate(
                    
    116389373992178)));
            
    for (PointInfo pointInfo : points) {
                
    // 結果是什么,居然就是故宮一個結果
                System.out.println(pointInfo.getName());
            }

            
    // 只能夠調整經緯度,來看看故宮周圍有什么
            System.out.println("=================================");
            System.out.println(
    "只能夠調整經緯度,來看看故宮周圍有什么,這個就相當于地圖上的周邊搜索的概念");
            points 
    = quatree.query(new Envelope(new Coordinate(116389373991605),
                    
    new Coordinate(116390813992178)));
            
    for (PointInfo pointInfo : points) {
                
    // 結果是什么?
                System.out.println(pointInfo.getName());
            }

       可以看到,當只是輸入故宮的點的時候,結果只是一個故宮。所以,我就找了一范圍來搜,模擬文斌在http://www.51ditu.com上實現的那個周邊搜索的概念。結果會是什么呢?
        說起周邊搜索,不可能沒有關鍵詞,比如我們經常在群里說得那個搜索模式,我想知道在上地周邊哪里有好的酒吧,下班后可以去喝一杯!
        這就是周邊過濾搜索的概念了。
         quadtree存在著這樣的一個方法:
         public void query(Envelope searchEnv, ItemVisitor visitor) ,這個當中的ItemVisitor 是一個接口。實現的類似于一個訪問者的功能,挨個詢問過路人:“你可見到戈多,我在等他”!我們可以看一下默認的ArrayListVisitor。看后,也會覺得jts在這個地方多此一舉了。
       
    /**
     * 
    @version 1.7
     
    */

    public class ArrayListVisitor
        
    implements ItemVisitor
    {

      
    private ArrayList items = new ArrayList();
      
    public ArrayListVisitor() {
      }


      
    public void visitItem(Object item)
      
    {
        items.add(item);
      }


      
    public ArrayList getItems() return items; }

    }


     可以看到,這個類對于過路人什么都沒有問。
     接下來,我就仿照著實現一個詢問器,問問那個宮殿中懸掛著“正大光明”牌匾。
     
    public void visitItem(Object item) {
            PointInfo info 
    = (PointInfo) item;
            
    if (info.getInfo() != null && !"".equals(info.getInfo())
                    
    && info.getInfo().contains("正大光明")) {
                items.add(item);
            }

        }

      最后在quatree中用法如下: 
       
    // 既然可以實現周邊搜索,那么就可以在故宮旁邊搜索那個宮殿中含有正大光明的牌匾
            System.out.println("=================================");
            System.out.println(
    "既然可以實現周邊搜索,那么就可以在故宮旁邊搜索那個宮殿中含有正大光明的牌匾");
            UseArrayListVisitor visitor 
    = new UseArrayListVisitor();
            quatree.query(
    new Envelope(new Coordinate(116389373991605),
                    
    new Coordinate(116390813992178)), visitor);
            points 
    = visitor.getItems();
            
    for (PointInfo pointInfo : points) {
                
    // 結果是什么?
                System.out.println(pointInfo.getName());
            }

             結果是什么呢,當然就是乾清宮!
            
             可以說,Jts是一個優雅的空間實用包,但是如果我在剛才過濾器中搜索的詞不是那么簡單呢,我想向文本搜索一樣牽涉到分詞,排序的概念呢。
            如果我真的要在中國范圍內找某一個酒吧呢?
            我對于這些問題的一個思路就是,讓lucene和jts合作!不過這是下一篇博客的內容了。
            
    posted on 2007-12-21 13:47 張氏兄弟 閱讀(3881) 評論(3)  編輯  收藏 所屬分類: 51ditu.com

    評論:
    # re: jts-空間索引 2007-12-21 13:55 | hidden
    寫得很詳細
    有研究鉆研下lucene...jts  回復  更多評論
      
    # re: jts-空間索引 2007-12-21 15:53 | stanley_xu
    對于任何一個gis查詢系統來說,用sptialIndex去索引多邊形是個必要過程。
    把不同類型的對象用多個si來索引,可以明顯提高搜索效率。  回復  更多評論
      
    # re: jts-空間索引 2007-12-21 18:08 | 祎恬凡
    to: stanley_xu
    兄弟我剛剛到靈圖來,很多東西都要學習。
    對于您說的用sptialIndex來索引多邊形,我還沒有想清楚怎么做!
    如果您肯賜教,不勝感激!
      回復  更多評論
      
    主站蜘蛛池模板: 亚洲精品无码成人AAA片| 亚洲人xxx日本人18| 最近在线2018视频免费观看| 亚洲国产精品综合久久20| 午夜无遮挡羞羞漫画免费| 一级视频在线免费观看| 久久精品亚洲中文字幕无码麻豆| 免费观看大片毛片| 污污网站18禁在线永久免费观看| 亚洲依依成人亚洲社区| 亚洲日韩aⅴ在线视频| 手机在线看永久av片免费| 老司机精品免费视频| 亚洲精品午夜国产va久久| 国产亚洲日韩一区二区三区| 成人免费AA片在线观看| a级毛片免费播放| 亚洲国产无线乱码在线观看| 亚洲激情在线观看| 亚洲国产精品自产在线播放 | 午夜精品一区二区三区免费视频| 亚洲人成网站在线播放2019| 无码乱人伦一区二区亚洲一| 国产区卡一卡二卡三乱码免费| 久久国产乱子免费精品| 日韩在线视频免费| 一本色道久久综合亚洲精品蜜桃冫 | 99热免费在线观看| free哆拍拍免费永久视频| 亚洲熟女精品中文字幕| 亚洲无删减国产精品一区| 国产亚洲精品a在线观看 | 国产在线观看免费视频播放器| 亚洲视频在线观看免费视频| a在线视频免费观看| 曰批免费视频播放免费| 大桥未久亚洲无av码在线| 亚洲人成网站18禁止久久影院| 国产亚洲一区二区手机在线观看 | 久久综合AV免费观看| 在线美女免费观看网站h|