首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Servlet 手機 App 介面系列 (三):高德地圖雲圖存儲、周邊檢索與距離計算實戰

     編輯:Java 相關知識

本文實戰接入高德地圖雲圖 API,實現服務人員位置雲端存儲 (App 端上報)、Servlet 端條件檢索 (按類型/城市/關鍵字)、球面距離計算 (經緯度轉米級距離),附完整建表、上傳、檢索、計算代碼與常見坑點。

一、高德雲圖核心概念

  • Table (雲圖表):相當於資料表,含預設欄位 _id、_location (經緯度)、_name、_address 等,支援自定義欄位並建立篩選索引。
  • Key (Web 服務 Key):控制台建立應用獲取,分Web 服務 (Servlet 用) 與Android/iOS SDK (App 端用)。
  • 雲存儲 API:App 端調用,新增/更新/刪除單條數據 (POST /v3/datamanage/data/create)。
  • 雲檢索 API:Servlet 端調用,周邊/多邊形/行政區/關鍵字/ID 檢索 (GET /v3/datasearch/...)。

二、建表與索引設計 (控制台操作)

  1. 控制台 → 數據管理 → 新建雲圖表 → 下載 Excel 模板。
  2. 模板保留系統欄位 (_id、_location、_name...),新增業務欄位:
    type (服務類型:按摩師/護理師)、user_id (關聯業務用戶 ID)。
  3. 上傳模板 → 建表成功 → 欄位管理 → 設 type 為篩選索引 (支援 filter=type:按摩師)。

三、Servlet 端檢索封裝

@WebServlet("/api/provider/search")
public class ProviderSearchServlet extends HttpServlet {
  private static final String SEARCH_URL = "https://yuntuapi.amap.com/datasearch/around";
  private static final String KEY = "你的Web服務Key";
  private static final String TABLE_ID = "你的TableID";

  protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
    // 1. 參數:經度,緯度,半徑(米),類型,分頁
    String location = req.getParameter("location"); // "116.39,39.90"
    int radius = Integer.parseInt(req.getParameter("radius")); // 5000
    String type = req.getParameter("type"); // "按摩師"
    int page = Integer.parseInt(req.getParameter("page")); // 1
    int pageSize = Integer.parseInt(req.getParameter("page_size")); // 20

    // 2. 組裝請求
    String param = "key=" + KEY
                 + "&tableid=" + TABLE_ID
                 + "¢er=" + location
                 + "&radius=" + radius
                 + "&filter=type:" + URLEncoder.encode(type, "UTF-8")
                 + "&page=" + page
                 + "&pagesize=" + pageSize;

    // 3. 發送 GET (HttpClient/OkHttp/HttpURLConnection 均可)
    String json = HttpUtil.get(SEARCH_URL + "?" + param);
    
    // 4. 直接透傳或解析後回傳
    resp.setContentType("application/json;charset=UTF-8");
    resp.getWriter().write(json);
  }
}

四、球面距離計算 (Haversine 公式)

public class GeoUtil {
  private static final double EARTH_RADIUS = 6371000; // 米

  /** 計算兩點球面距離 (米) */
  public static double distance(double lat1, double lon1, double lat2, double lon2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLon/2) * Math.sin(dLon/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return EARTH_RADIUS * c;
  }

  /** 批次計算並按距離排序 */
  public static List<ProviderDTO> sortByDistance(double userLat, double userLon, 
                                                   List<ProviderDTO> providers) {
    providers.forEach(p -> p.setDistance(distance(userLat, userLon, p.getLat(), p.getLon())));
    providers.sort(Comparator.comparingDouble(ProviderDTO::getDistance));
    return providers;
  }
}

五、App 端上報位置 (雲存儲 API)

// Android/iOS SDK 同理,這裡用 HTTP 示範
public void updateLocation(String userId, double lat, double lon, String type) {
  String url = "https://yuntuapi.amap.com/datamanage/data/create";
  String param = "key=" + APP_KEY // Android/iOS Key
               + "&tableid=" + TABLE_ID
               + "&data={\"_location\":\"" + lon + "," + lat + "\","
               + "\"_name\":\"provider_" + userId + "\","
               + "\"type\":\"" + type + "\","
               + "\"user_id\":\"" + userId + "\"}";
  HttpUtil.post(url, param); // 非阻塞異步發送
}

六、關鍵坑點與最佳實踐

  1. 經緯度順序:高德 API 統一 經度在前,緯度在後 (lng,lat),別搞反。
  2. Key 分離:App 端用 Android/iOS Key,Servlet 端用 Web 服務 Key,**嚴禁混用洩露**。
  3. 索引必建:高頻 filter 欄位 (如 type) 必須在控制台設為篩選索引,否則全表掃描極慢。
  4. 坐標系一致:高德預設 GCJ-02 (火星坐標),App 端 GPS (WGS-84) 需轉換,或直接用高德定位 SDK 獲取 GCJ-02。
  5. 分頁與總數:檢索回傳 count 總數,前端分頁用;單次最大 100 條。
  6. 異步上報:App 端位置上報放入後台線程/WorkManager,不阻塞 UI,失敗指數退避重試。
  7. 距離計算選型:單次用 Haversine;大批量 (萬級+) 改用 MySQL 5.7+ ST_Distance_Sphere 或 PostgreSQL PostGIS 推算到 DB 層。

總結

高德雲圖以「Table 存儲 + 篩選索引 + 多模式檢索 + 球面距離」四大能力,快速實現 LBS 業務。掌握 Key 隔離、經緯度順序、索引建立、坐標系統一、異步上報、距離計算下推 六大工程細節,即可構建穩定高效的位置服務後端。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved