1

ユーザーの場所に最も近いホテル (たとえば) を表示する必要があるアプリケーションに取り組んでいます。SQLite データベースには、経度と緯度とともにすべてのホテルが含まれています。これを行う最も簡単な方法は、selectステートメントの「Order By」に特定の式を記述することです。

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()));

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

これは私が作成した選択ステートメントです。問題は、選択ステートメントのパラメーターが (String, String[], String, String[], String, String, String) でなければならないというエラーがあることですが、私が行ったことis (String, String[], null, null, null, null, double )

どうすればいいですか?そして、方程式の結果によって結果をどのように順序付けますか?

4

1 に答える 1

0

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

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

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

AsyncTask含まれているホテルを取得するために作成しCursorます。カーソルを移動して、ホテルのリストを入力します。

@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()、目的の場所が変更されるたびに呼び出す必要があるメソッドが含まれていonLocationChanged(Location location)ます (LocationListener のように)。このメソッドは距離を更新し、アイテムを並べ替えます。

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;
            }
        }
    };
    ...
}

最後に、パラメータとして指定された場所までのホテルの距離を設定するクラスのsetDistance()メソッドを次に示します。Hotel

public void setDistance(Location location) {
    float results[] = new float[1];
    Location.distanceBetween(location.getLatitude(), location.getLongitude(),
        getLatitude(), getLongitude(), results);
    mDistance = results[0];
}
于 2012-04-29T09:56:23.810 に答える