在我的应用程序中,我有用于源坐标(用户位置)和目标坐标的文本字段。我想知道我的数据库(公交车站)中是否有任何靠近这些坐标的记录。本质上,我想找到哪些公交车站距离用户位置和目的地位置最近,因为我正在使用以下代码。
来源
public ArrayList<String> countDatabase(Double LAT, Double LNG) {
String sourcename=null;
double min_distance=99999999;
ArrayList<String> sList = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
mCount.moveToFirst();
while (mCount.moveToNext()) {
double Latitude = mCount.getDouble(2);
double Longitude = mCount.getDouble(3);
double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
if (dis<min_distance){
sourcename=mCount.getString(1);
sList.add(sourcename);
}
}
mCount.close();
return sList;
}
最后我得到一个数组列表(slist),其中包含使用欧拉距离公式计算出的靠近用户位置的所有站点的名称。相同的过程适用于目的地以获取列表(dlist)。 现在我想知道该列表中的任何电台是否位于我的数据库中的同一行
for(int i=0;i<ssize;i++){
String source = ssList.get(i);
for(int j=0;j<dsize;j++) {
String destination = ddList.get(j);
Boolean b = myDb.findBus(source, destination);
if(b){
TextView tvv = (TextView) findViewById(R.id.textView7);
tvv.setText(source+" and "+destination);
}
}
}
查找总线
public Boolean findBus(String sourcename, String desname){
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount= db.rawQuery("select count(*) from search_table where name='" + sourcename + "' AND dname='"+desname+"'", null);
mCount.moveToFirst();
int count= mCount.getInt(0);
mCount.close();
if (count>0) return true;
else return false;
}
但我似乎无法运行此代码,在
中遇到错误 Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
错误提示
java.lang.IllegalStateException: Could not execute method for android:onClick
完整代码
数据库助手
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Nearby.db";
public static final String TABLE_NAME = "halt_details";
public static final String COL_2 = "snme";
public static final String COL_3 = "slati";
public static final String COL_4 = "slong";
public static final String COL_5 = "dnme";
public static final String COL_6 = "dlati";
public static final String COL_7 = "dlong";
public static final String COL_8 = "buses";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, snme VARCHAR, slati DOUBLE, slong DOUBLE, dnme VARCHAR, dlati DOUBLE, dlong DOUBLE, buses VARCHAR)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public void insertData(String sname, Double slat, Double slng, String dname, Double dlat, Double dlng, String bus) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("snme",sname);
contentValues.put("slati",slat);
contentValues.put("slong",slng);
contentValues.put("dnme",dname);
contentValues.put("dlati",dlat);
contentValues.put("dlong",dlng);
contentValues.put("buses",bus);
db.insert(TABLE_NAME,null ,contentValues);
}
public void clearDatabase() {
SQLiteDatabase db = this.getWritableDatabase();
String clearDBQuery = "DELETE FROM "+TABLE_NAME;
db.execSQL(clearDBQuery);
}
public ArrayList<String> countDatabase(Double LAT, Double LNG) {
String sourcename=null;
double min_distance=99999999;
ArrayList<String> sList = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
mCount.moveToFirst();
while (mCount.moveToNext()) {
double Latitude = mCount.getDouble(2);
double Longitude = mCount.getDouble(3);
double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
if (dis<min_distance){
sourcename=mCount.getString(1);
sList.add(sourcename);
}
}
mCount.close();
return sList;
}
public ArrayList<String> countDatabase1(Double LAT, Double LNG) {
String destinationname=null;
ArrayList<String> dList = new ArrayList<>();
double min_distance=99999999;
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
mCount.moveToFirst();
while (mCount.moveToNext()) {
double Latitude = mCount.getDouble(2);
double Longitude = mCount.getDouble(3);
double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
if (dis<min_distance){
destinationname = mCount.getString(4);
dList.add(destinationname);
}
}
mCount.close();
return dList;
}
public Boolean findBus(String sourcename, String desname){
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCount= db.rawQuery("select count(*) from search_table where name='" + sourcename + "' AND dname='"+desname+"'", null);
mCount.moveToFirst();
int count= mCount.getInt(0);
mCount.close();
if (count>0) return true;
else return false;
}
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
return res;
}
}
结果.java
public class result extends Activity {
DatabaseHelper myDb;
@Override
protected void onCreate(Bundle savedInstanceState) {
myDb = new DatabaseHelper(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_result);
String url = getIntent().getExtras().getString("username");
String url1 = getIntent().getExtras().getString("username1");
TextView tv= (TextView)findViewById(R.id.textView2);
TextView tv1= (TextView)findViewById(R.id.textView5);
tv.setText(url);
tv1.setText(url1);
String[] separated = url.split("_");
String srclat = separated[0];
Double dsrclat= Double.parseDouble(srclat);
String srclng = separated[1];
Double dsrclng= Double.parseDouble(srclng);
String[] separated1 = url.split("_");
String deslat = separated1[0];
Double ddeslat= Double.parseDouble(deslat);
String deslng = separated1[1];
Double ddeslng= Double.parseDouble(deslng);
}
public void Database(View view){
Intent intent = new Intent(result.this, feeder.class);
startActivity(intent);
}
public void NearestValue(View view){
TextView tv= (TextView)findViewById(R.id.textView2);
String s1 = tv.getText().toString();
String[] separated = s1.split("_");
String deslat = separated[0];
Double Lat= Double.parseDouble(deslat);
String deslng = separated[1];
Double Lng= Double.parseDouble(deslng);
ArrayList<String> ssList = new ArrayList<>();
ssList = myDb.countDatabase(Lat,Lng);
int ssize = ssList.size();
TextView tvvv = (TextView) findViewById(R.id.textView8);
for(int i=0;i<ssize;i++) {
tvvv.setText(ssList.get(i));
}
TextView tv1= (TextView)findViewById(R.id.textView5);
String s11 = tv1.getText().toString();
String[] separated1 = s11.split("_");
String deslat1 = separated1[0];
Double Lat1= Double.parseDouble(deslat1);
String deslng1 = separated1[1];
Double Lng1= Double.parseDouble(deslng1);
ArrayList<String> ddList = new ArrayList<>();
ddList = myDb.countDatabase1(Lat1,Lng1);
int dsize = ddList.size();
TextView tvvvv = (TextView) findViewById(R.id.textView9);
for(int i=0;i<dsize;i++) {
tvvv.setText(ddList.get(i));
}
for(int i=0;i<ssize;i++){
String source = ssList.get(i);
for(int j=0;j<dsize;j++) {
String destination = ddList.get(j);
Boolean b = myDb.findBus(source, destination);
if(b){
TextView tvv = (TextView) findViewById(R.id.textView7);
tvv.setText(source+" and "+destination);
}
}
}
}
}
结果,xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="136dp"
android:layout_marginTop="84dp"
android:text="TextView"
android:textColor="@color/colorAccent" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/textView2"
android:layout_below="@+id/textView2"
android:layout_marginTop="97dp"
android:text="TextView"
android:textColor="@color/colorAccent" />
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/nearest"
android:layout_marginEnd="14dp"
android:layout_marginTop="88dp"
android:layout_toStartOf="@+id/nearest"
android:textColor="@color/colorAccent"
android:textSize="30sp"
tools:text="tv" />
<Button
android:id="@+id/nearest"
android:layout_width="130sp"
android:layout_height="50dp"
android:onClick="NearestValue"
android:layout_alignStart="@+id/gotodb"
android:layout_alignTop="@+id/gotodb"
android:layout_marginTop="76dp"
android:background="@drawable/buttonshape"
android:shadowColor="#6C74A8"
android:shadowDx="6"
android:shadowDy="0"
android:shadowRadius="9"
android:text="nearest bus stop"
android:textColor="#43456B"
android:textColorLink="@android:color/holo_blue_bright"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.95" />
<TextView
android:id="@+id/gotodb"
android:layout_width="130sp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_below="@+id/textView5"
android:onClick="Database"
android:text="database"
android:textColor="@android:color/background_light"
android:textColorLink="@android:color/holo_blue_bright"
android:textSize="15sp" />
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/nearest"
android:layout_marginEnd="38dp"
android:layout_marginTop="20dp"
android:layout_toStartOf="@+id/textView5"
android:text="TextView" />
<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/textView8"
android:layout_alignTop="@+id/textView7"
android:layout_marginTop="31dp"
android:text="TextView" />
最佳答案
以下内容,假设 LAT 为 10,LNG 为 30,:-
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
等于:-
SELECT snme FROM halt_details
WHERE slati BETWEEN '10- 0.1' AND '10+ 0.1'
AND slng BETWEEN '30- 0.1' AND '30+ 0.1';
您遇到的第一个问题是没有列 slng 它实际上应该是 slong (至少根据您显示的代码)。
进行此更改将导致查询运行,但结果不太可能是所需的(很可能什么也不检索)。这是因为您已将数值括在单引号中,使它们成为整个字符串,例如 10- 0.1。范围将在字符串之间,因此不会执行算术运算。
最终的 SQL 应该类似于:-
SELECT snme FROM halt_details
WHERE slati BETWEEN 10-0.1 AND (10+0.1)
AND slong BETWEEN (30-0.1) AND (30+0.1);
所以代码是:-
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN (" +LAT+"- 0.1) AND "+LAT+" + 0.1) AND slong BETWEEN (" +LNG+"- 0.1) AND ("+LNG+" + 0.1)", null);
但是,如果您使用保存列名称的可用变量,则不会遇到第一个错误。所以上面的内容可能是:-
Cursor mCount= db.rawQuery("SELECT " + DatabaseHelper.COL_2 + " FROM " + DatabaseHelper.TABLE_NAME + "s WHERE " + DatabaseHelper.COL_3 + " BETWEEN (" +LAT+"- 0.1) AND "+LAT+" + 0.1) AND " + DatabaseHelper.COL_4 + " BETWEEN (" +LNG+"- 0.1) AND ("+LNG+" + 0.1)", null);
- 当然,这种依赖单一定义的方法可以在整个过程中采用。
在移动结果光标以及尝试提取数据时,您似乎也会出现错误。以代码为例:-
Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
mCount.moveToFirst();
while (mCount.moveToNext()) {
double Latitude = mCount.getDouble(2);
double Longitude = mCount.getDouble(3);
double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
if (dis<min_distance){
destinationname = mCount.getString(4);
dList.add(destinationname);
}
}
mCount.close();
查询将返回一个包含 2 行的游标。每行都有一个名为 snme 的列。
首先移动到第一行,然后移动到下一行。因此,2 行现在为 1 行。(删除行 mCount.moveToFirst();
将导致所有行都被处理)。
然后,您尝试获取偏移量 2 处的光标列(第三列)。但是,光标只有一列,因此您会收到错误。与偏移量 3 相同。游标中存在的唯一列是偏移量 0。
假设您需要额外的列,最简单的解决方法可能是编码:-
Cursor mCount= db.rawQuery("SELECT * FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
- 相当于获取所有列。
- 注意上面提到的更正尚未包含在上面。上面显示的是如何获取所有列。
注意上述代码尚未经过测试,仅作为原则使用。
关于java - 在android中的sqlite数据库中查找属于同一行的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49420554/