2012-04-29 7 views
1

私は、ユーザーの場所に(例えば)最も近いホテルを表示する必要があるアプリケーションに取り組んでいます。 SQLiteデータベースには、すべてのホテルが経度と緯度とともに表示されます。私は検索し、これを行う最も簡単な方法は、Selectステートメントの "Order By"に特定の式を書くことであることがわかりました。Select文をOrder by Orderにする方法はありますか? (最短距離で注文する)

Cursor cursor = database.query(MySQLiteHelper.TABLE_Hotel, hotelsNames, null, null, null, null, ((lat - Double.valueOf(hotelsLat[0].trim()).doubleValue()) * (lat - Double.valueOf(hotelsLat[0].trim()).doubleValue()) + 
      (lon - Double.valueOf(hotelsLong[0].trim()).doubleValue()) * (lon - Double.valueOf(hotelsLong[0].trim()).doubleValue())); 

注意:LONGとhotelsLatは、データベースの経度と緯度を含むString []です。

これはselect文ですが、select文のパラメータは(String、String []、String、String []、String、String、String)でなければならないというエラーがありますが、私がやったのである(文字列、String []型、NULL、NULL、NULL、NULL、ダブル

私はそれをどのようにすればよいですか?方程式の結果によって結果をどのように並べるのでしょうか?

+0

あなたがユーザーをより遠くに送り出す場合があるかもしれないので、 "距離 - 距離"よりも短くしてください。ああ、Google Maps APIには2つのポイント間の距離を取得する機能があります – CAA

+0

これは最も近いホテルを(絶対的に)見つけることができますが、必ずしも最も簡単なものにはなりません(例えば、狭い湖、反対側のホテル) –

+0

しかし、この部分では、結果を地図に表示したくないです。私は検索ページのように検索したいものを選択し、結果はリストビューで表示され、最も近い結果が一番上に表示され、最も遠い結果がリストの最後に表示されます – MahaK

答えて

0

まず、距離計算が正しくないように見えます。 distanceBetween()メソッドについては、Locationクラスのソースを参照してください。これを使用するか、同じクラスのdistanceTo()を使用することをお勧めします。

使用するアダプタについて。データベースからのデータの場合はCursorAdapterが使用され、それ以外の場合はBaseAdapterの子孫が使用されます。あなたには2つの選択肢があります。現在の距離を新しい列として(新しい場所を受け取るか、ユーザーが検索する場所を定義するたびに)sqlテーブルに保存し、並べ替えるか、ListViewArrayAdapterを使用します。

2つ目のオプションについて説明します。ユーザーの場所に応じてホテルが表示され、新しい場所を受け取るたびにデータベースにアクセスしないため、場所の更新が頻繁に行われる場合はスムーズにする必要がありますホテルはオブジェクトとして格納されているため、メモリを消費します。

Cursorのホテルを取得するには、AsyncTaskを作成します。カーソルを移動してホテルのリストを記入してください:

@Override 
protected List<Hotel> doInBackground(Void... unused) { 
    final Cursor c = database.query(getting hotels); 
    if (c == null) { 
     return null; 
    } 
    List<Hotel> hotels = new ArrayList<Hotel>(); 
    try { 
     for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 
      Hotel hotel = new Hotel(); 
      hotel.fillFromCursor(c); // fills data from cursor 
      hotels.add(hotel); 
     } 
    } finally { 
     c.close(); 
    } 
    return hotels; 
} 

@Override 
protected void onPostExecute(List<Hotels> hotels) { 
    if (hotels != null) { 
     mHotelsAdapter.clear(); 
     for (Hotel h : hotels) { 
      mHotelsAdapter.add(h); 
     } 
     // mLocation is our current location, if we have one, set the distance, see below 
     mHotelsAdapter.updateDistance(mLocation); 
    } 
} 

mHotelsAdapterはListView用のアダプタです。アダプタにはupdateDistance()メソッドが含まれています。このメソッドは、(LocationListenerのonLocationChanged(Location location)のように)必要な場所が変更されるたびに呼び出される必要があります。メソッドは距離を更新し、アイテムをソートします。ここで

mHotelsAdapter = new HotelAdapter(this); 
getListView().setAdapter(mHotelsAdapter); 
... 

public class HotelsAdapter extends ArrayAdapter<Hotel> { 
    ... 
    public void updateDistance(Location location) { 
     if (location != null) { 
      for (int i = 0; i < getCount(); i++) { 
       Hotel hotel = getItem(i); 
       hotel.setDistance(location); 
      } 
      sort(mComparator); 
      notifyDataSetChanged(); 
     } 
    } 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // implement getView 
    } 

    private static final Comparator<Hotel> mComparator = new Comparator<Hotel>() { 
     @Override 
     public int compare(Hotel lhs, Hotel rhs) { 
      if (lhs.getDistance() > rhs.getDistance()) { 
       return 1; 
      } else if (lhs.getDistance() < rhs.getDistance()) { 
       return -1; 
      } else { 
       return 0; 
      } 
     } 
    }; 
    ... 
} 

、最終的にパラメータとして指定された場所にホテルの距離を設定HotelクラスのsetDistance()方法である:oehm、二点間の直線距離があってもよい

public void setDistance(Location location) { 
    float results[] = new float[1]; 
    Location.distanceBetween(location.getLatitude(), location.getLongitude(), 
     getLatitude(), getLongitude(), results); 
    mDistance = results[0]; 
} 
関連する問題