@Override
  public String scanQueryPoint(double latitude, double longitude) {
    this.getStatLog(STAT_FILE_NAME);

    long sTime = System.currentTimeMillis();
    // build up a raster
    XRaster raster = new XRaster(this.space, this.min_size_of_height, this.max_num_of_column);
    ResultScanner rScanner = null;

    try {
      // match rect to find the subspace it belongs to
      XBox match_box = raster.locate(latitude, Math.abs(longitude));
      System.out.println("match_box is : " + match_box.toString());
      String[] rowRange = new String[2];
      rowRange[0] = match_box.getRow();
      rowRange[1] = match_box.getRow() + "-*";

      // the version here is harded coded, because i cannot get how many
      // objects in one cell now
      rScanner =
          this.hbaseUtil.getResultSet(
              rowRange, null, this.familyName, new String[] {match_box.getColumn()}, 1000000);
      BixiReader reader = new BixiReader();
      int count = 0;
      int row = 0;
      String stationName = null;
      for (Result r : rScanner) {
        NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> resultMap =
            r.getMap();
        row++;
        for (byte[] family : resultMap.keySet()) {
          NavigableMap<byte[], NavigableMap<Long, byte[]>> columns = resultMap.get(family);
          for (byte[] col : columns.keySet()) {
            NavigableMap<Long, byte[]> values = columns.get(col);
            for (Long version : values.keySet()) {
              count++;
              // get the distance between this point and the given
              // point
              XStation station = reader.getStationFromJson(Bytes.toString(values.get(version)));

              if ((station.getLatitude() == latitude && station.getlongitude() == longitude)) {
                stationName = station.getId();
                break;
              }
            }
            if (stationName != null) break;
          }

          if (stationName != null) break;
        }
        if (stationName != null) break;
      }
      long eTime = System.currentTimeMillis();
      System.out.println(
          "count=>" + count + ";time=>" + (eTime - sTime) + ";result=>" + stationName);
      String outStr =
          "q=point;m=scan;count=>"
              + count
              + ";time=>"
              + (eTime - sTime)
              + ";row=>"
              + row
              + ";result=>"
              + stationName;
      this.writeStat(outStr);

      return stationName;

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      this.hbaseUtil.closeTableHandler();
      this.closeStatLog();
    }
    return null;
  }
  @Override
  public String copQueryPoint(final double latitude, final double longitude) {

    this.getStatLog(STAT_FILE_NAME);

    long s_time = System.currentTimeMillis();
    try {
      /** Step1** Call back class definition * */
      class BixiCallBack implements Batch.Callback<String> {
        String res = null;
        int count = 0;
        QueryAbstraction query = null;

        public BixiCallBack(QueryAbstraction query) {
          this.query = query;
        }

        @Override
        public void update(byte[] region, byte[] row, String result) {
          count++;
          String outStr =
              "endTime=>"
                  + System.currentTimeMillis()
                  + ";region=>"
                  + Bytes.toString(region)
                  + ";count=>"
                  + count
                  + ";result=>"
                  + result;
          this.query.writeStat(outStr);
          outStr = query.regions.get(Bytes.toString(region)).toString();
          this.query.writeStat(outStr);
          res = result;
        }
      }
      BixiCallBack callBack = new BixiCallBack(this);

      /** Step2** generate the scan ********** */
      // build up the Raster
      XRaster raster = new XRaster(this.space, this.min_size_of_height, this.max_num_of_column);
      XBox match_box = raster.locate(latitude, Math.abs(longitude));
      System.out.println("match_box is : " + match_box.toString());
      String[] rowRange = new String[2];
      rowRange[0] = match_box.getRow();
      rowRange[1] = match_box.getRow() + "0";

      // generate the scan
      final Scan scan =
          hbaseUtil.generateScan(
              rowRange,
              null,
              new String[] {BixiConstant.LOCATION_FAMILY_NAME},
              new String[] {match_box.getColumn()},
              100000);

      /** Step3** send out the query to trigger the corresponding function in Coprocessor*** */
      hbaseUtil
          .getHTable()
          .coprocessorExec(
              BixiProtocol.class,
              scan.getStartRow(),
              scan.getStopRow(),
              new Batch.Call<BixiProtocol, String>() {

                public String call(BixiProtocol instance) throws IOException {

                  return instance.copQueryPoint4LS2(scan, latitude, longitude);
                };
              },
              callBack);

      long e_time = System.currentTimeMillis();

      long exe_time = e_time - s_time;
      // TODO store the time into database
      System.out.println("exe_time=>" + exe_time + ";result=>" + callBack.res);
      String outStr = "q=point;m=>cop;" + ";exe_time=>" + exe_time + ";result=>" + callBack.res;
      this.writeStat(outStr);

      return callBack.res;

    } catch (Exception e) {
      e.printStackTrace();
    } catch (Throwable ee) {
      ee.printStackTrace();
    } finally {
      hbaseUtil.closeTableHandler();
      this.closeStatLog();
    }
    return null;
  }