用過美團外賣的小夥伴們都知道,美團通過收貨位址來為我們推薦附近的商品或者商家,如下:

要想實作這個業務,需要:
知道收貨位址的坐标點
知道店鋪的坐标點
根據收貨位址來檢索附近的店鋪。
上一次,我們介紹了百度LBS地圖的Web端開發實戰,主要介紹了百度地圖的地圖展示、本地檢索、逆/地理編碼、覆寫物、城市清單等關鍵功能;實作了店鋪的坐标點定位。
那麼這一次我們着重介紹通過百度LBS雲存儲和雲檢索實作“根據收貨位址來檢索附近的店鋪”的功能。
LBS.雲是百度地圖針對LBS開發者推出的平台級服務,結合已有的地圖API和SDK服務,通過開放服務端存儲和計算能力,提供海量位置資料的實時存儲、檢索、展示一體化解決方案。
這個解決方案讓我們能夠很輕松地實作上述功能。
0.簡介
LBS雲提供了關鍵的nearby API,這個API主要是通過上傳一個Point的坐标到LBS雲,通過nearby的檢索功能實作對附近10000米範圍的Point點檢索,通過json資料傳遞給我們開發者。
LBS雲為我們提供了一個可擴充列的位置資料表(geotable),裡面可以存儲我們想要儲存的關鍵字段,比如店鋪ID。
這樣,我們開發者隻需要關注如何存儲資料和擷取資料了。
1.LBS雲存儲
首先,申請一個百度LBS的密鑰(ak)。
然後到虎鲸資料管理平台建立自己的table。
我的table名為ym_shop_lbs,自定義字段為shop_id。
我現在要做的就是将店鋪的point和ID存儲到LBS雲。
百度LBS地圖的Web端開發實戰教程中介紹到了如何存儲店鋪的Point,我們接着講。
通過ajax将point的資訊傳遞的controller。
$.showConfirm("您确定要将 " + rs.address + " 設為目前位址嗎?", function() {
// 通過ajax進行位址點的更新
$.ajax({
type : 'POST',
url : common.ctx + "/seller/updateShopLocation",
dataType : "json",
cache : false,
data : {
lbs_point : point.lng + "," + point.lat,
lbs_address : rs.address,
},
success : function(json) {
},
error : function(xhr, ajaxOptions, thrownError) {
$.showErr("更新店鋪坐标失敗,稍後再試");
}
});
接下來的代碼,篇幅比較長,考慮到每個人的項目需求都不一樣,就不貼具體的代碼了,我把幾個關鍵的代碼,都送出到了CSDN的代碼庫 bd_lbs_yun ,可參照。
public ModelAndView updateShopLocation() {
Shops shop = mem.get("shop");
String lbs_point = getPara("lbs_point");
String lbs_address = getPara("lbs_address");
shop.setAddress(lbs_address);
if (StringUtils.isEmpty(shop.getLbs_point())) {
shop.setLbs_point(lbs_point);
// 增加坐标值
message = this.shopService.addLocation(shop);
} else {
shop.setLbs_point(lbs_point);
// 更新坐标值
message = this.shopService.updateLocation(shop);
}
}
增加坐标點和更新坐标點。
private Map<String, Object> createLBSParams(Shops shop) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("ak", Variables.baidu_map_key);
params.put("geotable_id", Variables.baidu_map_table_id);
params.put("title", shop.getPusername());// 店鋪名稱
String[] lbs_points = shop.getLbs_point().split(",");
// 經度
params.put("longitude", lbs_points[0]);
params.put("latitude", lbs_points[1]);// 店鋪緯度
params.put("coord_type", "3");
return params;
}public String addLocation(Shops shop) {
Map<String, Object> params = createLBSParams(shop);
// 自定義列
params.put("shop_id", shop.getPid());// 放入使用者id,或者店鋪倉庫id使用者後期檢索
/*
* 參數名 參數含義 類型 備注 status 狀态碼 int32 0代表成功,其它取值含義另行說明 message 響應的資訊
* string(50) 狀态碼描述 id 新增的資料的id string
*/
String jsonStr = BaiduLBSUtil.createPOI(params);// 傳回
CreateResData resData = JSON.parseObject(jsonStr, CreateResData.class);
if (!resData.isSuccessed()) {
throw new OrderException(resData.getMessage());
}
return "店鋪位置設定成功";// 傳回新增列的id
}
BaiduLBSUtil的具體内容,可從CSDN的代碼庫 bd_lbs_yun 下載下傳。
3.LBS雲檢索
通過nearby方法檢索。
// 擷取清單資訊
// http://api.map.baidu.com/geosearch/v3/nearby?ak=您的ak&geotable_id=****&location=116.395884,39.932154&radius=1000&tags=酒店&sortby=distance:1|price:1&filter=price:200,300
Map<String, Object> params = new HashMap<String, Object>();
params.put("ak", Variables.baidu_map_key);
params.put("geotable_id", Variables.baidu_map_table_id);
params.put("location", lbs_point);// 收貨位址的坐标點
params.put("radius", 10000);// 檢索半徑
params.put("page_index", vo.getPageNum() - 1);// 百度從0開始
params.put("page_size", vo.getNumPerPage());// 百度預設為10,最多50
String jsonStr = BaiduLBSUtil.nearby(params);// 傳回
NearbyResData resData = JSON.parseObject(jsonStr, NearbyResData.class);
ArrayList<ContentData> shop_ids = resData.getContents();
需要注意的是,百度LBS雲的nearby方法本身提供了分頁功能,并且下表從0開始,不是從1開始。
擷取到shop_id後,表示大功告成了。
接下來就隻需要将shop_id和自己的表進行關聯,擷取到對應的資料就可以了。
如果要顯示距離,可通過ContentData中的distance字段來擷取。
限于篇幅、以及各自項目的不同,本文提供的代碼隻能作為參照,如果還需要幫助,可以通過技術交流群和我聯系。