переход плоск-сферич Формула 25 действующего ГОСТа

Не знаете, где задать вопрос? Задавайте здесь.
trir
Гуру
Сообщения: 5355
Зарегистрирован: 09 апр 2010, 19:30
Репутация: 1021
Ваше звание: просто мимо прохожу
Откуда: Ё-бург

Re: переход плоск-сферич Формула 25 действующего ГОСТа

Сообщение trir » 07 мар 2019, 10:44

но мне бы в формате proj всё
блин, ну я тебе три раза про статью сказал и даже намекнул про последнию строчку - там ссылка на файл download/file.php?id=10124
Значит, я правильно выбрал 2-ю зону, поскольку у меня коорд. по долготе около 43?
да

ivkomn
Интересующийся
Сообщения: 36
Зарегистрирован: 04 мар 2019, 14:08
Репутация: 0
Откуда: Саров

Re: переход плоск-сферич Формула 25 действующего ГОСТа

Сообщение ivkomn » 07 мар 2019, 10:52

trir писал(а):
07 мар 2019, 10:44
да
Ура, ура!!! На выходных попробую построить ключ(в точности которого сильно сомневаюсь) и посчитать пару точек из моей СК в GPS
Алгоритм должен быть:
1 Построить ключ по http://gis-lab.info/qa/helmert2d.html
2. Ключом перейти в МСК52-2
3. при помощи org.locationtech.proj4j:proj4j:1.0.0 перйти из МСК52-2 в GPS

Спасибо!

ivkomn
Интересующийся
Сообщения: 36
Зарегистрирован: 04 мар 2019, 14:08
Репутация: 0
Откуда: Саров

Re: переход плоск-сферич Формула 25 действующего ГОСТа

Сообщение ivkomn » 10 мар 2019, 18:03

что-то получилось
Спасибо!!
извините за качество кода под спойлером :-)
Спойлер

Код: Выделить всё

package ru.mySrv;

import ch.obermuhlner.math.big.BigDecimalMath;
import org.locationtech.proj4j.*;
import ru.model.ConvertKey;

import java.math.BigDecimal;
import java.math.MathContext;

public class Converter {
    private final MathContext mc;
    private final ConvertKey ck;

    public Converter(int mc) {
        this.mc = new MathContext(mc);
        this.ck = getKey();
    }

    public BigDecimal[][] convert(BigDecimal[][] gskPoints){
        BigDecimal[][] mskPoints = new BigDecimal[gskPoints.length][2];

        for (int i=0;i<gskPoints.length;i++) {
            mskPoints[i] = gskToMsk(gskPoints[i],ck);
        }

        return mskToGPS(mskPoints);
    }

    private ConvertKey getKey(){
        double[][] gps = new double[4][2];
        
        BigDecimal[][] msk = gpsToMSK52_2(gps);
        BigDecimal[][] gsk = new BigDecimal[4][2];
        


//        gsk[0][0] = new BigDecimal(1334.71,mc);
//        gsk[0][1] = new BigDecimal(285.94,mc);
//        gsk[1][0] = new BigDecimal(563.67,mc);
//        gsk[1][1] = new BigDecimal(-5197.34,mc);
//        gsk[2][0] = new BigDecimal(4444.27,mc);
//        gsk[2][1] = new BigDecimal(1153.79,mc);
//        gsk[3][0] = new BigDecimal(-252.07,mc);
//        gsk[3][1] = new BigDecimal(2881.90,mc);
//
//        msk[0][0] = new BigDecimal(83477.64,mc);
//        msk[0][1] = new BigDecimal(87377.60,mc);
//        msk[1][0] = new BigDecimal(82557.14,mc);
//        msk[1][1] = new BigDecimal(81916.51,mc);
//        msk[2][0] = new BigDecimal(86610.19,mc);
//        msk[2][1] = new BigDecimal(88160.39,mc);
//        msk[3][0] = new BigDecimal(81962.05,mc);
//        msk[3][1] = new BigDecimal(90016.34,mc);


        BigDecimal[] gskC = init2Darr(2);
        BigDecimal[] mskC = init2Darr(2);
        /*
        Шаг 1: вычисление взвешенных средних
         */
        for (int i=0;i<msk.length;i++){
            gskC[0] = gskC[0].add(gsk[i][0],mc);
            gskC[1] = gskC[1].add(gsk[i][1],mc);

            mskC[0] = mskC[0].add(msk[i][0],mc);
            mskC[1] = mskC[1].add(msk[i][1],mc);

            //System.out.println(i+"- gskX: "+gsk[i][0]+ " gskY: "+gsk[i][1]+" MSKx: "+msk[i][0]+ " MSKy: "+msk[i][1]);
        }
        gskC[0] = gskC[0].divide(new BigDecimal(4),mc);
        gskC[1] = gskC[1].divide(new BigDecimal(4),mc);
        mskC[0] = mskC[0].divide(new BigDecimal(4),mc);
        mskC[1] = mskC[1].divide(new BigDecimal(4),mc);

        //System.out.println("Step 1> gskX: "+gskC[0]+ " gskY: "+gskC[1]+" MSKx: "+mskC[0]+ " MSKy: "+mskC[1]);

        /*
        Шаг 2: перенос осей в центр масс
         */
        BigDecimal[][] gskDelta = new BigDecimal[4][2];
        BigDecimal[][] mskDelta = new BigDecimal[4][2];

        for (int i=0; i < msk.length;i++){
            gskDelta[i][0] = gsk[i][0].subtract(gskC[0],mc);
            gskDelta[i][1] = gsk[i][1].subtract(gskC[1],mc);

            mskDelta[i][0] = msk[i][0].subtract(mskC[0],mc);
            mskDelta[i][1] = msk[i][1].subtract(mskC[1],mc);
        }

        /*
        Шаг 3: вычисление a1 и b1
         */
        BigDecimal a1,b1;
        BigDecimal[] S = init2Darr(5);
        for (int i=0;i<msk.length;i++){
            S[0] = S[0].add(mskDelta[i][0].multiply(gskDelta[i][0],mc),mc);

            S[1] = S[1].add(mskDelta[i][1].multiply(gskDelta[i][1],mc),mc);

            S[2] = S[2].add(mskDelta[i][1].multiply(gskDelta[i][0],mc),mc);

            S[3] = S[3].add(mskDelta[i][0].multiply(gskDelta[i][1],mc),mc);

            S[4] = S[4].add(gskDelta[i][0].pow(2,mc).add(gskDelta[i][1].pow(2,mc),mc));
        }
        a1=S[0].add(S[1],mc).divide(S[4],mc);
        b1=S[2].subtract(S[3],mc).divide(S[4],mc);

        /*
        Шаг 4: вычисление a0 и b0
         */
        BigDecimal a0,b0;
        a0 = mskC[0].subtract(a1.multiply(gskC[0],mc),mc).add(b1.multiply(gskC[1],mc),mc);

        b0 = mskC[1].subtract(b1.multiply(gskC[0],mc),mc).subtract(a1.multiply(gskC[1],mc),mc);

//        System.out.println("a0:>"+a0+"<");
//        System.out.println("b0:>"+b0+"<");
//        System.out.println("a1:>"+a1+"<");
//        System.out.println("b1:>"+b1+"<");

        /*
        Шаг 5: вычисление невязок
         */
//        System.out.println("Step 5 >>");
        for (int i=0;i<msk.length;i++) {
            BigDecimal[] gskBuf = new BigDecimal[2];
            BigDecimal[] mskBuf = new BigDecimal[2];
            gskBuf[0] = gsk[i][0].subtract(gskC[0]);
            gskBuf[1] = gsk[i][1].subtract(gskC[1]);

            mskBuf[0] = gskBuf[0].multiply(a1,mc).subtract(gskBuf[1].multiply(b1,mc),mc);
            mskBuf[1] = gskBuf[0].multiply(b1,mc).add(gskBuf[1].multiply(a1,mc),mc);


//            System.out.println(i
//                    +" "
//                    +msk[i][0].subtract(mskC[0],mc).subtract(mskBuf[0],mc)
//                    + "  "
//                    +msk[i][1].subtract(mskC[1],mc).subtract(mskBuf[1],mc));
        }

        /*
        Шаг 6: вычисление ключа
         */
        BigDecimal m,tat;
        m= BigDecimalMath.sqrt(a1.pow(2,mc).add(b1.pow(2,mc),mc),mc);
        tat = BigDecimalMath.atan2(b1,a1,mc);//.multiply(new BigDecimal(180),mc).divide(BigDecimalMath.pi(mc),mc);
        //System.out.println("M "+m+" tat "+tat);
        int nev = 2;
        return new ConvertKey(gsk[nev],msk[nev],m,tat);

    }




    private BigDecimal[] gskToMsk(BigDecimal[] gsk, ConvertKey k) {
        BigDecimal[] msk = init2Darr(2);
        BigDecimal[] gskDelta = init2Darr(2);

        gskDelta[0] = gsk[0].subtract(k.getGsk()[0],mc);
        gskDelta[1] = gsk[1].subtract(k.getGsk()[1],mc);

        msk[0] = k.getMsk()[0].add(k.getM().multiply(
                gskDelta[0].multiply(k.getCos(),mc).subtract(gskDelta[1].multiply(k.getSin(),mc),mc),mc),mc);

        msk[1] = k.getMsk()[1].add(k.getM().multiply(
                gskDelta[0].multiply(k.getSin(),mc).add(gskDelta[1].multiply(k.getCos(),mc),mc),mc),mc);
        return msk;
    }

    private BigDecimal[] init2Darr(int c) {
        BigDecimal[] out = new BigDecimal[c];
        for (int i=0;i<out.length;i++){
            out[i]=BigDecimal.ZERO;
        }
        return out;
    }

    private BigDecimal[][] gpsToMSK52_2(double[][] gps) {
        BigDecimal[][] msk = new BigDecimal[gps.length][2];
        CRSFactory factory = new CRSFactory();

        CoordinateReferenceSystem srcCrs = factory.createFromName("EPSG:4326");

        String param = "+proj=tmerc +ellps=krass +towgs84=23.57,-140.95,-79.8,0,0.35,0.79,-0.22 +units=m +lon_0=44.55 +lat_0=0 +k_0=1 +x_0=2250000 +y_0=-5714743.504";
        CoordinateReferenceSystem dstCrs =
                factory.createFromParameters("MSK52", param);
        CoordinateTransform coordinateTransform = new CoordinateTransformFactory().createTransform(srcCrs, dstCrs);

        for (int i = 0; i < gps.length; i++) {
            ProjCoordinate srcCoord = new ProjCoordinate(gps[i][1], gps[i][0]);
            ProjCoordinate dstCoord = new ProjCoordinate();

            coordinateTransform.transform(srcCoord, dstCoord);

            msk[i][0] = new BigDecimal(dstCoord.y);
            msk[i][1] = new BigDecimal(dstCoord.x);
        }
        return msk;
    }

    private BigDecimal[][] mskToGPS(BigDecimal[][] msk) {
        BigDecimal[][] gps = new BigDecimal[msk.length][2];
        CRSFactory factory = new CRSFactory();

        CoordinateReferenceSystem dstCrs = factory.createFromName("EPSG:4326");

        String param = "+proj=tmerc +ellps=krass +towgs84=23.57,-140.95,-79.8,0,0.35,0.79,-0.22 +units=m +lon_0=44.55 +lat_0=0 +k_0=1 +x_0=2250000 +y_0=-5714743.504";
        CoordinateReferenceSystem srcCrs =
                factory.createFromParameters("MSK52", param);
        CoordinateTransform coordinateTransform = new CoordinateTransformFactory().createTransform(srcCrs, dstCrs);

        for (int i = 0; i < msk.length; i++) {
            ProjCoordinate srcCoord = new ProjCoordinate(msk[i][1].doubleValue(), msk[i][0].doubleValue());
            ProjCoordinate dstCoord = new ProjCoordinate();

            coordinateTransform.transform(srcCoord, dstCoord);

            gps[i][0] = new BigDecimal(dstCoord.y);
            gps[i][1] = new BigDecimal(dstCoord.x);
        }
        return gps;
    }
}



package ru.model;

import ch.obermuhlner.math.big.BigDecimalMath;

import java.math.BigDecimal;
import java.math.MathContext;

public class ConvertKey {
    private final BigDecimal[] gsk;
    private final BigDecimal[] msk;
    private final BigDecimal m;
    private final BigDecimal tat;
    private final BigDecimal sin;
    private final BigDecimal cos;

    public ConvertKey(BigDecimal[] gsk, BigDecimal[] msk, BigDecimal m, BigDecimal tat) {
        MathContext mc = new MathContext(100);
        this.gsk = gsk;
        this.msk = msk;
        this.m = m;
        this.tat = tat;
        this.sin = BigDecimalMath.sin(tat,mc);
        this.cos = BigDecimalMath.cos(tat,mc);
    }

    public BigDecimal[] getGsk() {
        return gsk;
    }

    public BigDecimal[] getMsk() {
        return msk;
    }

    public BigDecimal getM() {
        return m;
    }

    public BigDecimal getTat() {
        return tat;
    }

    public BigDecimal getSin() {
        return sin;
    }

    public BigDecimal getCos() {
        return cos;
    }


}


Ответить

Вернуться в «Я новичок!»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость