百度地圖和solr展示資源和附近等功能的實現 二
這裏 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展示資源和附近等功能的實現 二