SORU
12 EYLÜL 2010, Pazar


SQlite yerleri (enlem ve boylam)yakın Elde

Enlem ve boylam verileri SQLite veritabanı saklanan var, ve yakın yerlere koydum parametreleri (ör. gitmek istiyorum Benim şimdiki konumu - lat/lng, vs.).

Biliyorum ki bu mümkün MySQL ve yaptığım uzun bir araştırma bu SQLite ihtiyacı özel bir dış işlev için Haversine formül (hesaplama mesafe üzerinde bir küre), ama bir şey bulamadım henüz yazılmış Java ve çalışıyor.

Eğer özel işlevler eklemek istiyorum ayrıca, org.sqlite ihtiyacım var .uygulama için gereksiz bir boyut ekler kavanoz (org.sqlite.Function) ve.

Diğer taraftan bu, ihtiyacım sıraya göre işlevi, SQL, çünkü gösteriliyor mesafe yalnız değil o kadar bir sorun - ben zaten yaptım benim özel SimpleCursorAdapter, ama yapamam tür bir veri, çünkü ben yok mesafe sütununda benim veritabanı. Veritabanının konumunu değiştirir her zaman güncelleme ve pil ve performans kaybı. Eğer birisi veritabanında olmayan bir sütun ile imleci sıralama hakkında herhangi bir fikri olan varsa, minnettar olurdum!

Bu fonksiyonu kullanmak orada Android uygulamalar ton var biliyorum, ama birisi sihirli lütfen açıklayabilir.

Bu arada, bu alternatif buldum: Query to get records based on Radius in SQLite?

4 lat ve lng cos ve sin değerleri için yeni bir sütun yapmak için ima ediyor, ama orada değil, bu kadar gereksiz başka bir yolu var mı?

CEVAP
21 EKİM 2012, Pazar


1)İlk başta iyi bir yaklaşımla SQLite veri filtre ve java kodunuzda değerlendirmek için gereken veri miktarını azaltmak. Bu amaçla: aşağıdaki yordamı kullanın

Bir deterministik vareşikve veriler üzerinde daha hassas filtre, daha iyi hesaplamak için4 yerlerkuzey, batı, doğu radius metre ve merkezi noktası Güneyjava kodve sonrakontrol ve SQL daha az operatörleri (>tarafından kolayca <)eğer veritabanında noktaları olan dikdörtgenin içinde olup olmadığını belirlemek için.

Yöntemi calculateDerivedPosition(...) sizin için bu noktaları (p1, p2, p3, p4 resmi olarak) hesaplar.

enter image description here

/**
* Calculates the end-point from a given source at a given range (meters)
* and bearing (degrees). This methods uses simple geometry equations to
* calculate the end-point.
* 
* @param point
*            Point of origin
* @param range
*            Range in meters
* @param bearing
*            Bearing in degrees
* @return End-point from the source given the desired range and bearing.
*/
public static PointF calculateDerivedPosition(PointF point,
            double range, double bearing)
    {
        double EarthRadius = 6371000; // m

        double latA = Math.toRadians(point.x);
        double lonA = Math.toRadians(point.y);
        double angularDistance = range / EarthRadius;
        double trueCourse = Math.toRadians(bearing);

        double lat = Math.asin(
                Math.sin(latA) * Math.cos(angularDistance)  
                        Math.cos(latA) * Math.sin(angularDistance)
                        * Math.cos(trueCourse));

        double dlon = Math.atan2(
                Math.sin(trueCourse) * Math.sin(angularDistance)
                        * Math.cos(latA),
                Math.cos(angularDistance) - Math.sin(latA) * Math.sin(lat));

        double lon = ((lonA   dlon   Math.PI) % (Math.PI * 2)) - Math.PI;

        lat = Math.toDegrees(lat);
        lon = Math.toDegrees(lon);

        PointF newPoint = new PointF((float) lat, (float) lon);

        return newPoint;

    }

Ve şimdi sorgunuzu oluşturun:

PointF center = new PointF(x, y);
final double mult = 1; // mult = 1.1; is more reliable
PointF p1 = calculateDerivedPosition(center, mult * radius, 0);
PointF p2 = calculateDerivedPosition(center, mult * radius, 90);
PointF p3 = calculateDerivedPosition(center, mult * radius, 180);
PointF p4 = calculateDerivedPosition(center, mult * radius, 270);

strWhere =  " WHERE "
          COL_X   " > "   String.valueOf(p3.x)   " AND "
          COL_X   " < "   String.valueOf(p1.x)   " AND "
          COL_Y   " < "   String.valueOf(p2.y)   " AND "
          COL_Y   " > "   String.valueOf(p4.y)

COL_X enlem değerleri depolayan bir veritabanı sütun adı COL_Y boylam.

İyi bir yaklaşımla, merkez noktasına yakın olan bazı veriler var.

2)Şimdi bu süzülmüş verileri döngü ve eğer gerçekten nokta (daire içinde) yakın olup olmadığını belirlemek ya da aşağıdaki yöntemleri kullanarak değil

public static boolean pointIsInCircle(PointF pointForCheck, PointF center,
            double radius) {
        if (getDistanceBetweenTwoPoints(pointForCheck, center) <= radius)
            return true;
        else
            return false;
    }

public static double getDistanceBetweenTwoPoints(PointF p1, PointF p2) {
        double R = 6371000; // m
        double dLat = Math.toRadians(p2.x - p1.x);
        double dLon = Math.toRadians(p2.y - p1.y);
        double lat1 = Math.toRadians(p1.x);
        double lat2 = Math.toRadians(p2.x);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)   Math.sin(dLon / 2)
                * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = R * c;

        return d;
    }

Tadını çıkarın!

Ve this reference ve o zaman tamamlanmış kullanılan özelleştirilmiş.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • B3ASTTY™

    B3ASTTY™

    27 Mayıs 2013
  • Jon Reed

    Jon Reed

    14 AĞUSTOS 2006
  • Phandroid

    Phandroid

    26 Ocak 2009