Как: построить заданную широту и долготу на карте неподвижного изображения, используя четыре (4) координаты изображения? - PullRequest
3 голосов
/ 15 сентября 2011

Я создал этот пост -> нанесите карту реального мира под другим углом. Карта неподвижных изображений

, исходя из этого, я могу успешно пометить данный широту с учетом двух (2)координаты (верхний левый, нижний правый), но из-за неправильного угла на карте неподвижного изображения по сравнению с углом карты реального мира моя метка сместилась.

Теперь я думаю о , используя четыре (4)координаты (верхний левый, нижний левый, верхний правый, нижний правый) изображения.Таким образом, я мог бы построить данный широту без учета угла.

Я думаю, что даже без опыта Android мог бы ответить на этот вопрос.Я просто немного разбираюсь в математике.

Возможно ли это реализовать?если да, приветствуются любые подсказки и фрагменты кода.

UPDATES1 Основная цель - пометить данный широту на карте изображения, которая имеет другой угол относительно карты реального мира.

ОБНОВЛЕНИЯ2 Я использую приведенные ниже коды для расчета моего угла.Вы бы проверили это, если это надежно для получения угла.Затем преобразовать его в пиксель. ПРИМЕЧАНИЕ: в этих кодах используются только две координаты изображения плюс координата цели.

public static double[] calc_xy (double imageSize, Location target, Location upperLeft, Location upperRight) {
    double newAngle = -1;
    try {
        double angle = calc_radian(upperRight.getLongitude(), upperRight.getLatitude(), 
                upperLeft.getLongitude(), upperLeft.getLatitude(), 
                target.getLongitude(), target.getLatitude());
        newAngle = 180-angle;

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    double upperLeft_Target_dist = upperLeft.distanceTo(target);

    double upperLeft_Right_dist = upperLeft.distanceTo(upperRight);
    double distancePerPx = imageSize /upperLeft_Right_dist;

    double distance = upperLeft_Target_dist * distancePerPx;

    double radian = newAngle * Math.PI/180;

    double[] result = radToPixel(distance, radian);
    return result;
}

public static double[] radToPixel(double distance, double radian) {
    double[] result = {-1,-1};
    result[Functions.Location.PIXEL_X_LON] = distance * Math.cos(radian);
    result[Functions.Location.PIXEL_Y_LAT] = distance * Math.sin(radian);
    return result;
}

public static double calc_radian(Double x1, Double y1, Double x2, Double y2, Double x3, Double y3)
    throws Exception{

    double rad = 0.0;

    if((Double.compare(x1, x2) == 0 && Double.compare(y1, y2) == 0) ||
            (Double.compare(x3, x2) == 0 && Double.compare(y3, y2) == 0))
    {
        Log.d(tag, "Same place") ;
        return rad;
    }

    /* compute vector */
    double BAx = x2 - x1;
    double BAy = y2 - y1;

    double BCx = x3 - x2;
    double BCy = y3 - y2;

    double cosA =  BAx / Math.sqrt( BAx * BAx + BAy * BAy ) ;
    double cosC =  BCx / Math.sqrt( BCx * BCx + BCy * BCy ) ;

    double radA = Math.acos( cosA ) * 180.0 / Math.PI ;
    double radC = Math.acos( cosC ) * 180.0 / Math.PI ;
    if( BAy < 0.0 )
    {
        radA = radA * -1.0 ;
    }
    if( BCy < 0.0 )
    {
        radC = radC * -1.0 ;
    }

    rad = radC - radA ;


    if( rad > 180.0 )
    {
        rad = rad - 360;
    }

    if( rad < -180.0 )
    {
        rad = rad + 360;
    }

    return rad ;
}

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

Похоже, что вы хотите нанести текущее географическое местоположение пользователя на изображение, скажем, здания или кампуса. Исходя из этого, мой подход заключается в том, чтобы «отобразить» неподвижное изображение на экране, что, вероятно, потребует преобразования преобразования, преобразования вращения и преобразования масштабирования. Кроме того, вам нужно знать фактические координаты географического местоположения как минимум двух точек на вашем изображении. Учитывая изображение в вашем предыдущем посте, я бы предположил, что у вас есть географические координаты нижнего левого угла и нижнего правого угла. У вас уже есть информация для преобразования географической координаты в экранную координату, чтобы изображение можно было нарисовать в соответствии с нижним левым углом изображения с вычисленной вами пиксельной координатой. Я буду называть эту точку вашей точкой привязки.

На этом этапе у вас, вероятно, есть изображение с одним углом в правильном месте, но теперь его нужно уменьшить или увеличить, а затем повернуть вокруг точки привязки. Вы можете получить текущий уровень масштабирования из вашего mapView, или вы можете получить latitudeSpan, и вы можете рассчитать масштабный коэффициент, который будет применен к вашему изображению.

Наконец, если у вас есть географические координаты двух углов изображения, вы можете рассчитать угол поворота изображения. Это можно рассчитать с помощью Пифагора или вы можете преобразовать из декартовых координат в полярные координаты см. Здесь . Это вычисление не должно выполняться вашим приложением - его можно рассчитать отдельно и ввести как константу. Теперь вы можете применить преобразование поворота вокруг неподвижной точки крепления.

Вы также можете использовать удобные встроенные функции, такие как mapController.zoomInFixing (), которая принимает пиксельные координаты или одну из других функций zoomTo () или animateTo ().

Редактировать: Если вы не используете вид карты для управления своими гео-координатами, тогда вы можете применить преобразования изображения, используя такой код:

// create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // rotate the Bitmap
    matrix.postRotate(angle);

// recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 
                      width, height, matrix, true); 

    // make a Drawable from Bitmap to allow to set the BitMap 
    // to the ImageView, ImageButton or what ever
    BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

    ImageView imageView = new ImageView(this);

    // set the Drawable on the ImageView
    imageView.setImageDrawable(bmd);

Редактировать: Используя верхнюю левую и нижнюю правую координаты, вы можете рассчитать угол следующим образом:

angle = sin-1 ((right.x - left.y) / sqrt ((right.x - left.x) sq + (right.y - left.y) sq))

[где sqrt = квадратный корень; кв = квадрат

1 голос
/ 27 сентября 2011

Если вы знаете, что такое угол, это простое декартово вращение оси.

Пусть x будет старой долготой, y будет старой широтой, а b будетугол

новая долгота x '= x * cos (b) - y * sin (b)

новая широта y' = x * sin (b) + y * cos (b)) * +1010 *

0 голосов
/ 15 сентября 2011

Я не уверен, что понимаю, но мне кажется, что вы хотите рассчитать угол изображения, который вы хотите, используя две точки, затем поверните его и измените его размер на основе количества пикселей между точками a и b (два углы), используя метод перехода от широты к пикселям и формулу расстояния

...