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[] 包含数据库中的经度和纬度。

这是我做的select语句,问题是有一个错误说select语句的参数必须是(String, String[], String, String[], String, String, String) 但是我做了什么是(字符串,字符串 [],空,空,空,空,

我该怎么做?它将如何根据方程的结果对结果进行排序?

4

1 回答 1

0

首先,您的距离计算似乎不正确。有关distanceBetween()方法,请参见Location类的源代码。我建议你使用这个或同一类的distanceTo()

关于要使用的适配器。CursorAdapter如果您的数据来自数据库,BaseAdapter则使用,否则使用某些后代。你有两个选择。将 sql 表中的当前距离保存为新列(每次收到新位置或用户定义要搜索的位置),然后按它排序或ArrayAdapter使用ListView.

我将描述第二个选项,如果根据用户位置显示酒店并且位置更新非常频繁,因为它不会在每次收到新位置时访问数据库,但另一方面它会消耗更多内存因为酒店被存储为对象:

创建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 回答