How to retrieve a set of locations within particular range from user's location from SQLite database

后端 未结 2 934
灰色年华
灰色年华 2021-01-16 11:35

I have some location coordinates stored in my SQLite database table. I want to retrieve the locations within 1 km range from the use\'s current location. Right

相关标签:
2条回答
  • 2021-01-16 12:09

    Here is some code which should give you an idea how to get it working:

    public static double[] getNeighbourhoodArea(
                final double lat, final double lng, final int distInMtrs) {
    
            double[] area = new double[4];
    
            final double latRadian = Math.toRadians(lat);
    
            final double degLatKm = 110.574235;
            final double degLngKm = 110.572833 * Math.cos(latRadian);
            final double deltaLat = distInMtrs / 1000.0 / degLatKm;
            final double deltaLong = distInMtrs / 1000.0 / degLngKm;
    
            final double minLat = lat - deltaLat;
            final double minLng = lng - deltaLong;
            final double maxLat = lat + deltaLat;
            final double maxLng = lng + deltaLong;
    
            area[0] = minLat;
            area[1] = minLng;
            area[2] = maxLat;
            area[3] = maxLng;
    
            return area;
        }
    
    
        /**
         * search POIs in the neighbourhood
         */
        private PntInrtst collectPOIs(double lat, double lng) {
    
            if (mDb == null) return Const.NULL_POI;
    
            Cursor cursorStat = mDb.getPoisInArea(lat, lng, Const.SIDE_LENGTH_GEO_OFFSET);
    
            double area[] = Logic.getProtectionArea(lat, lng, Const.SIDE_LENGTH_GEO_OFFSET);
    
            ArrayList<PntInrtst> poiArray = new ArrayList<PntInrtst>();
    
            PntInrtst poi = Const.NULL_POI;
    
            if (cursorStat.moveToFirst()) {
                for (int i = 0; i < cursorStat.getCount(); i++) {
                    double potLat = cursorStat.getFloat(Const.COL_LA);
                    double potLng = cursorStat.getFloat(Const.COL_LO);
    
                    if ((potLat < area[Const.MAX_LAT] && potLat > area[Const.MIN_LAT])
                        && (potLng < area[Const.MAX_LNG] && potLng > area[Const.MIN_LNG])) {
    
                        poi = Logic.getPoiByCursor(getApplicationContext(), cursorStat);
                        poiArray.add(poi);
    
                    }
                    cursorStat.moveToNext();
                } // End "Cursor"
            }
            cursorStat.close();
    
            // more than once, fire the nearest
            if (poiArray.size() > 1) return closest(poiArray, lat, lng);
            else return poi; // one or null
        }
    
    
        /**
         * filter POIs which won't be useful (avoids flooding the cache)
         */
        public Cursor getPoisInArea(double latitude, double longitude, int range) {
    
            double area[] = getNeighbourhoodArea(latitude, longitude, range);
    
            String where = "la" + "<" + area[MAX_LAT] +
                           " AND " + "la" + ">" + area[MIN_LAT] +
                           " AND " + "lo" + "<" + area[MAX_LNG] +
                           " AND " + "lo" + ">" + area[MIN_LNG];
    
            SQLiteDatabase db = mDbHelper.getReadableDatabase();
            return db.query(Const.POI_DB_TABLE, null, where, null, null, null, null);
        }
    
    0 讨论(0)
  • 2021-01-16 12:25

    You can write a SQL query with following where condition :

    where ( (my_lat - LAT)*(my_lat - LAT) + (my_lon - LON)*(my_lon - LON) ) <= 1KM
    

    The idea is that use Pythagoras method to calculate approx location and filter based on that. Here I have not taken the square root because I guess SQL functions in SQLite don't have sqrt.

    This is good for approximate calculations ...

    I used following SQL and it worked ...

    // Table with columns as String and Float
    CREATE TABLE "locations" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "lat_string" VARCHAR, "long_string" VARCHAR, "lat_val" FLOAT, "long_val" FLOAT)
    
    // Insert example data
    INSERT INTO "locations" VALUES(1,'12.9587926','77.7477416',12.9587926,77.7477416);
    INSERT INTO "locations" VALUES(2,'12.9973486','77.6967362',12.9973486,77.69673619999999);
    INSERT INTO "locations" VALUES(3,'12.9715987','77.5945627',12.9715987,77.5945627);
    INSERT INTO "locations" VALUES(4,'12.9629354','77.7122996',12.9629354,77.7122996);
    
    // Select when column format is string. This works in SQLIte
    SELECT id, ( (77.7580827 - long_string)*(77.7580827 - long_string) + (12.9905542 - lat_string)*(12.9905542 - lat_string) ) as dist FROM locations
    
    // Select when column format is float. This works in SQLIte
    SELECT id, ( (77.7580827 - long_val)*(77.7580827 - long_val) + (12.9905542 - lat_val)*(12.9905542 - lat_val) ) as dist FROM locations
    
    0 讨论(0)
提交回复
热议问题