1. 程式人生 > >百度地圖和solr展示資源和附近等功能的實現 二

百度地圖和solr展示資源和附近等功能的實現 二

its 會有 坐標系 sta color 精度 ring 名稱 坐標

這裏 solr 這塊主要說說如何實現附近功能,主要實現的方法有下面幾種

1.使用LatLonType(用於平面坐標,而不是大地坐標)版本比較老 好像不怎麽用了

2.SpatialRecursivePrefixTreeFieldType(縮寫為RPT) 我用的就是這個 下面主要講這個部分

3.BBoxField(用於邊界索引查詢) 沒用這個 具體的還不太了解

因為我主要使用的是第2種方式來做的 所以主要寫第2種方式RPT

首先的話需要在solr的配置文件中加上經緯度的配置 比如我的經緯度起的名稱叫latitude_longitude 那麽在配置中就需要加上這個的配置

<field name="latitude_longitude" type="location_rpt" indexed="true" stored="true"/>
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"  geo="true" distErrPct="0.025" maxDistErr="0.000009" units="degrees" />

這裏的type類型為location_rpt 然後下面的class引用就是我們的第2種-——SpatialRecursivePrefixTreeFieldType

對solr.SpatialRecursivePrefixTreeFieldType的配置說明:SpatialRecursivePrefixTreeFieldType 用於深度遍歷前綴樹的FieldType,主要用於獲得基於Lucene中的RecursivePrefixTreeStrategy。

geo默認為true,值為true的情況下坐標基於球面坐標系,采用Geohash的方式;值為false的情況下坐標基於2D平面的坐標系,采用Euclidean/Cartesian的方式。

distErrPct 定義非Point圖形的精度,範圍在0-0.5之間。該值決定了非Point的圖形索引或查詢時的level(如geohash模式時就是geohash編碼的長度)。當為0時取maxLevels,即精度最大,精度越大將花費更多的空間和時間去建索引。

maxDistErr/maxLevels:maxDistErr

定義了索引數據的最高層maxLevels,上述定義為0.000009,根據 GeohashUtils.lookupHashLenForWidthHeight(0.000009, 0.000009)算出編碼長度為11位,精度在1米左右,直接決定了Point索引的term數。maxLevels優先級高於maxDistErr, 即有maxLevels的話maxDistErr失效。詳見SpatialPrefixTreeFactory.init()方法。不過一般使用 maxDistErr。
units 單位是degrees。

接下來經緯度的數據從數據庫讀取出來 會有一個精度和一個緯度的字段,而在solr當中我們需要把這2個字段組合在一起 可以使用2種表達方式 比如114.31,30.52 或者114.31 30.52 一種是使用逗號隔開,另一種是使用空格的方式隔開 這裏要記住一點 精度和緯度不要弄反了 不然會報錯的 我之前就是因為把這2個值組合在一起寫反了 然後報的異常信息:

Can‘t parse point ‘30.570000 114.020000‘ because: Bad Y value 114.02 is not in boundary Rect(minX=-180.0,maxX=180.0,minY=-90.0,maxY=90.0)

報錯也非常的明顯 就是超出了正常範圍的值。所以在這裏提一個醒 註意一下就行了。

接下來看代碼

Map<String, Object> params = new HashMap<String, Object>(); // 查詢參數
        solrServer = SolrServerClient.getInstance(ConstantUtil.getResourceString("solr_core_map2"));
        
        params.put("keyword", queryString);
        params.put("pageNo", pageNo);
        params.put("pageSize", pageSize);
        params.put("facet", true); // 分類統計數量
        params.put("facet.mincount", 1); // 至少有一條記錄的分類才返回
        params.put("facet.field", new String[] {"instrSort"});
        if (!StringUtil.isNull(Latitude_longitude)) {
            params.put("fq", "{!geofilt}");//距離過濾函數
            params.put("pt", Latitude_longitude);//當前經緯度
            params.put("sfield", "latitude_longitude");  //經緯度的字段
            params.put("d", 30+""); //就近 30 km的所有數據
            params.put("sort", "geodist() asc");//距離排序
            params.put("fl","*,dist:geodist()");//返回的距離數據
        }
        params.put("defType", "edismax");
        params.put("qf", "instrName^1.5  text^1");
        params.put("mm", "2<70% 4<-45% 7<-30%");
        params.put("pf", "instrName^1.5");
        
        // 高亮
        params.put("hl", true);
        params.put("hl.fl", "instrName");
        params.put("hl.simple.pre", "<em style=\"color: #e72028;font-style: normal;\">");
        params.put("hl.simple.post", "</em>");
        
        
        params.put("resultClass", SearchOrgnInstr.class); // 指定返回結果的類型
        Map queryResult =  solrServer.query(params);
        return queryResult;

主要是這段代碼

 if (!StringUtil.isNull(Latitude_longitude)) {
            params.put("fq", "{!geofilt}");//距離過濾函數
            params.put("pt", Latitude_longitude);//當前經緯度
            params.put("sfield", "latitude_longitude");  //經緯度的字段
            params.put("d", 30+""); //就近 30 km的所有數據
            params.put("sort", "geodist() asc");//距離排序
            params.put("fl","*,dist:geodist()");//返回的距離數據
        }

最後返回的應該就是你需要的數據了。數據出來了,那怎麽在地圖上去繪制點了。請看下一章節

百度地圖和solr展示資源和附近等功能的實現 二