복붙노트

[SQL] 쿼리 SQLite는 반경에 따라 기록을 얻으려면?

SQL

쿼리 SQLite는 반경에 따라 기록을 얻으려면?

내가 MySQL의에서 잘 작동을하지 않습니다이 쿼리를

SELECT ((ACOS(SIN(12.345 * PI() / 180) * SIN(lat * PI() / 180) +
         COS(12.345 * PI() / 180) * COS(lat * PI() / 180) * COS((67.89 - lon) * 
         PI() / 180)) * 180 / PI()) * 60 * 1.1515 * 1.609344) AS distance, poi.* 
FROM poi
WHERE lang='eng' 
HAVING distance<='30'

거리는 입력 위도 및 경도 = 12.345이다 킬로미터이고 = 67.89

SQLite는 3이며, 안드로이드에있어 나는 그것으로 사용자 정의 함수를 실행할 수 없습니다. 즉 표준 SQLite는의 일부가 아닌 것처럼 나 또한 ... 등) (ACOS이 없습니다.

어떻게 SQLite는 위의 쿼리 것입니까?

해결법

  1. ==============================

    1.당신은 죄와 위도와 경도의 COS되고, 4 개의 새로운 열을 만들 수 있습니다. B A COS COS COS (a + 나) = 때문에 - 죄 B 및 SIN 같은 죄 COS (12.345 * PI () / 180)의 다른 모습을 죄 쿼리를 실행하기 전에 프로그램으로 계산 될 수 있고, 큰 " 거리 "는 식 sqlite3를 처리 할 수있는 형태 SIN_LAT P * + * Q + ... COS_LAT 무언가를 감소시킨다.

    당신은 죄와 위도와 경도의 COS되고, 4 개의 새로운 열을 만들 수 있습니다. B A COS COS COS (a + 나) = 때문에 - 죄 B 및 SIN 같은 죄 COS (12.345 * PI () / 180)의 다른 모습을 죄 쿼리를 실행하기 전에 프로그램으로 계산 될 수 있고, 큰 " 거리 "는 식 sqlite3를 처리 할 수있는 형태 SIN_LAT P * + * Q + ... COS_LAT 무언가를 감소시킨다.

    BTW, SQLite는 안드로이드에 참조 : SQLite는 DIST의 DB 기능을 만드는 방법 - 거리 계산이 긴, 위도 사용하는 응용 프로그램에 사용되는.

  2. ==============================

    2.여기에 안드로이드 장치의 위치를 ​​기반으로 쿼리를 구축하기위한 자바 구현이다. 아이디어는 KennyTM에서 온다 (허용 응답 참조) 및 부비동 및 위도와 경도의 cosinus의 값을 저장 테이블 4 개 컬럼의 추가를 의미한다.

    여기에 안드로이드 장치의 위치를 ​​기반으로 쿼리를 구축하기위한 자바 구현이다. 아이디어는 KennyTM에서 온다 (허용 응답 참조) 및 부비동 및 위도와 경도의 cosinus의 값을 저장 테이블 4 개 컬럼의 추가를 의미한다.

    다음은 삽입시에 "쇼핑"테이블에 대한 데이터를 준비하는 코드는 다음과 같습니다

    public static void injectLocationValues(ContentValues values, double latitude, double longitude) {
        values.put(LocationColumns.LATITUDE, latitude);
        values.put(LocationColumns.LONGITUDE, longitude);
        values.put(LocationColumns.COSLAT, Math.cos(MathUtil.deg2rad(latitude)));
        values.put(LocationColumns.SINLAT, Math.sin(MathUtil.deg2rad(latitude)));
        values.put(LocationColumns.COSLNG, Math.cos(MathUtil.deg2rad(longitude)));
        values.put(LocationColumns.SINLNG, Math.sin(MathUtil.deg2rad(longitude)));
    }
    
    public static double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }
    

    그런 다음 다음과 같은 기능을 사용하여 투사를 구축 할 수 있습니다 :

    /**
     * Build query based on distance using spherical law of cosinus
     * 
     * d = acos(sin(lat1).sin(lat2)+cos(lat1).cos(lat2).cos(long2−long1)).R
     * where R=6371 and latitudes and longitudes expressed in radians
     * 
     * In Sqlite we do not have access to acos() sin() and lat() functions.
     * Knowing that cos(A-B) = cos(A).cos(B) + sin(A).sin(B)
     * We can determine a distance stub as:
     * d = sin(lat1).sin(lat2)+cos(lat1).cos(lat2).(cos(long2).cos(long1)+sin(long2).sin(long1))
     * 
     * First comparison point being fixed, sin(lat1) cos(lat1) sin(long1) and cos(long1)
     * can be replaced by constants.
     * 
     * Location aware table must therefore have the following columns to build the equation:
     * sinlat => sin(radians(lat))
     * coslat => cos(radians(lat))
     * coslng => cos(radians(lng))
     * sinlng => sin(radians(lng))
     *  
     * Function will return a real between -1 and 1 which can be used to order the query.
     * Distance in km is after expressed from R.acos(result) 
     *  
     * @param latitude, latitude of search
     * @param longitude, longitude of search
     * @return selection query to compute the distance
     */
    public static String buildDistanceQuery(double latitude, double longitude) {
        final double coslat = Math.cos(MathUtil.deg2rad(latitude));
        final double sinlat = Math.sin(MathUtil.deg2rad(latitude));
        final double coslng = Math.cos(MathUtil.deg2rad(longitude));
        final double sinlng = Math.sin(MathUtil.deg2rad(longitude));
        //@formatter:off
        return "(" + coslat + "*" + LocationColumns.COSLAT
                + "*(" + LocationColumns.COSLNG + "*" + coslng
                + "+" + LocationColumns.SINLNG + "*" + sinlng
                + ")+" + sinlat + "*" + LocationColumns.SINLAT 
                + ")";
        //@formatter:on
    }
    

    그것은 어떤에서 당신이 킬로미터로 변환하려면 다음 공식을 적용 할 필요가 거리와 응답 열을 삽입합니다 :

    public static double convertPartialDistanceToKm(double result) {
        return Math.acos(result) * 6371;
    }
    

    이 부분 거리를 사용하여 쿼리를 주문하려면 주문 DESC하지 ASC해야합니다.

  3. ==============================

    3.여기서 식으로 작은 재생 후, IOS sqlite3를위한에서 SQL 측 (의사 코드)에서 함수를 사용하지 않고 할 수있는 방법이된다 작업하는 동안 같은 문제가 있었다 :

    여기서 식으로 작은 재생 후, IOS sqlite3를위한에서 SQL 측 (의사 코드)에서 함수를 사용하지 않고 할 수있는 방법이된다 작업하는 동안 같은 문제가 있었다 :

  4. from https://stackoverflow.com/questions/3126830/query-to-get-records-based-on-radius-in-sqlite by cc-by-sa and MIT license