SWEREF99TM transform?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
kodar-holger
EF Sponsor
Inlägg: 916
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

SWEREF99TM transform?

Inlägg av kodar-holger »

Nån som har implementerat transformation från WGS84 lat/lon till SWEREF99TM och kan dela med sig?

Suttit och kollat på lantmäteriets hemsida en bra stund men det är väl värsta stället förstår jag för dom vill ju ha det rätt ner till mm. Jag bryr mig i bästa fall inom 10m och bryr mig inte så mycket om "eurasiska plattans interna deformationer i Norden", och det är ju nyårsdagen så vem orkar med A4-ark med matrismatematik...
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3743
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: SWEREF99TM transform?

Inlägg av Mickecarlsson »

janno
Inlägg: 403
Blev medlem: 11 oktober 2009, 07:34:45
Ort: Västerås

Re: SWEREF99TM transform?

Inlägg av janno »

Här finns färdiga bibliotek o program för att transformera alla vanliga system
https://proj.org/
det finns wrappers till de flesta språk
meconer
EF Sponsor
Inlägg: 491
Blev medlem: 27 april 2010, 20:07:46
Ort: Järfälla

Re: SWEREF99TM transform?

Inlägg av meconer »

Det här använder jag. Kommer inte riktigt ihåg var jag har fått det ifrån men jag har konverterat det till dart. Koden använder en hel del mattefunktioner så du behöver ett bra mattebibliotek med sinh och cosh. Jag använder
standardbibliotekt dart:math och ett paket complex/fastmath.dart

Kod: Markera allt

class SweRef99Coord {
  SweRef99Coord(this._nCoord, this._eCoord);

  SweRef99Coord.fromLatLng(LatLngCoords gpsCoord) {
    var ref99coord = latLngToSweref(gpsCoord);
    _nCoord = ref99coord._nCoord;
    _eCoord = ref99coord._eCoord;
  }

  double _nCoord = 0;
  double _eCoord = 0;

  double get nCoord => _nCoord;
  double get eCoord => _eCoord;

  double atanh(double z) {
    return (log(1.0 + z) - log(1.0 - z)) / 2.0;
  }

  SweRef99Coord latLngToSweref(LatLngCoords gpsCoord) {
    //Prepare ellipsoid-based stuff.
    const axis = 6378137.0; // GRS 80.
    const flattening = 1.0 / 298.257222101; // GRS 80.
    const centralMeridian = 15.00;
    const scale = 0.9996;
    const falseNorthing = 0.0;
    const falseEasting = 500000.0;

    const e2 = flattening * (2.0 - flattening);
    const n = flattening / (2.0 - flattening);
    const aRoof = axis / (1.0 + n) * (1.0 + n * n / 4.0 + n * n * n * n / 64.0);
    const a = e2;
    const b = (5.0 * e2 * e2 - e2 * e2 * e2) / 6.0;
    const c = (104.0 * e2 * e2 * e2 - 45.0 * e2 * e2 * e2 * e2) / 120.0;
    const d = (1237.0 * e2 * e2 * e2 * e2) / 1260.0;
    const beta1 = n / 2.0 -
        2.0 * n * n / 3.0 +
        5.0 * n * n * n / 16.0 +
        41.0 * n * n * n * n / 180.0;
    const beta2 = 13.0 * n * n / 48.0 -
        3.0 * n * n * n / 5.0 +
        557.0 * n * n * n * n / 1440.0;
    const beta3 = 61.0 * n * n * n / 240.0 - 103.0 * n * n * n * n / 140.0;
    const beta4 = 49561.0 * n * n * n * n / 161280.0;

    // Convert.
    const degToRad = pi / 180.0;
    var phi = gpsCoord.latitude * degToRad;
    var lam = gpsCoord.longitude * degToRad;
    const lambdaZero = centralMeridian * degToRad;

    var phiStar = phi -
        sin(phi) *
            cos(phi) *
            (a +
                b * pow(sin(phi), 2) +
                c * pow(sin(phi), 4) +
                d * pow(sin(phi), 6));

    var deltaLambda = lam - lambdaZero;
    var xiPrim = atan(tan(phiStar) / cos(deltaLambda));
    var etaPrim = atanh(cos(phiStar) * sin(deltaLambda));

    var nCoord = scale *
            aRoof *
            (xiPrim +
                beta1 * sin(2.0 * xiPrim) * cosh(2.0 * etaPrim) +
                beta2 * sin(4.0 * xiPrim) * cosh(4.0 * etaPrim) +
                beta3 * sin(6.0 * xiPrim) * cosh(6.0 * etaPrim) +
                beta4 * sin(8.0 * xiPrim) * cosh(8.0 * etaPrim)) +
        falseNorthing;
    var eCoord = scale *
            aRoof *
            (etaPrim +
                beta1 * cos(2.0 * xiPrim) * sinh(2.0 * etaPrim) +
                beta2 * cos(4.0 * xiPrim) * sinh(4.0 * etaPrim) +
                beta3 * cos(6.0 * xiPrim) * sinh(6.0 * etaPrim) +
                beta4 * cos(8.0 * xiPrim) * sinh(8.0 * etaPrim)) +
        falseEasting;
    return SweRef99Coord(nCoord, eCoord);
  }
}

class LatLngCoords {
  LatLngCoords(this.latitude, this.longitude);

  LatLngCoords.fromSweRef99(SweRef99Coord sweRef99Coord) {
    var latLong = swerefToLatLng(sweRef99Coord);
    latitude = latLong.latitude;
    longitude = latLong.longitude;
  }

  double latitude = 0;
  double longitude = 0;

  LatLngCoords swerefToLatLng(SweRef99Coord sweRef99Coord) {
    var axis = 6378137.0; // GRS 80.
    var flattening = 1.0 / 298.257222101; // GRS 80.
    const centralMeridian = 15.00;
    const scale = 0.9996;
    const falseNorthing = 0.0;
    const falseEasting = 500000.0;

    // Prepare ellipsoid-based stuff.
    var e2 = flattening * (2.0 - flattening);
    var n = flattening / (2.0 - flattening);
    var aRoof = axis / (1.0 + n) * (1.0 + n * n / 4.0 + n * n * n * n / 64.0);
    var delta1 = n / 2.0 -
        2.0 * n * n / 3.0 +
        37.0 * n * n * n / 96.0 -
        n * n * n * n / 360.0;
    var delta2 =
        n * n / 48.0 + n * n * n / 15.0 - 437.0 * n * n * n * n / 1440.0;
    var delta3 = 17.0 * n * n * n / 480.0 - 37 * n * n * n * n / 840.0;
    var delta4 = 4397.0 * n * n * n * n / 161280.0;

    var aStar = e2 + e2 * e2 + e2 * e2 * e2 + e2 * e2 * e2 * e2;
    var bStar =
        -(7.0 * e2 * e2 + 17.0 * e2 * e2 * e2 + 30.0 * e2 * e2 * e2 * e2) / 6.0;
    var cStar = (224.0 * e2 * e2 * e2 + 889.0 * e2 * e2 * e2 * e2) / 120.0;
    var dStar = -(4279.0 * e2 * e2 * e2 * e2) / 1260.0;

    // Convert.
    var degToRad = pi / 180;
    var lambdaZero = centralMeridian * degToRad;
    var xi = (sweRef99Coord.nCoord - falseNorthing) / (scale * aRoof);
    var eta = (sweRef99Coord.eCoord - falseEasting) / (scale * aRoof);
    var xiPrim = xi -
        delta1 * sin(2.0 * xi) * cosh(2.0 * eta) -
        delta2 * sin(4.0 * xi) * cosh(4.0 * eta) -
        delta3 * sin(6.0 * xi) * cosh(6.0 * eta) -
        delta4 * sin(8.0 * xi) * cosh(8.0 * eta);

    var etaPrim = eta -
        delta1 * cos(2.0 * xi) * sinh(2.0 * eta) -
        delta2 * cos(4.0 * xi) * sinh(4.0 * eta) -
        delta3 * cos(6.0 * xi) * sinh(6.0 * eta) -
        delta4 * cos(8.0 * xi) * sinh(8.0 * eta);

    var phiStar = asin(sin(xiPrim) / cosh(etaPrim));
    var deltaLambda = atan(sinh(etaPrim) / cos(xiPrim));
    var lonRadian = lambdaZero + deltaLambda;
    var latRadian = phiStar +
        sin(phiStar) *
            cos(phiStar) *
            (aStar +
                bStar * pow(sin(phiStar), 2) +
                cStar * pow(sin(phiStar), 4) +
                dStar * pow(sin(phiStar), 6));

    latitude = latRadian * 180.0 / pi;
    longitude = lonRadian * 180.0 / pi;
    return LatLngCoords(latitude, longitude);
  }
}

kodar-holger
EF Sponsor
Inlägg: 916
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: SWEREF99TM transform?

Inlägg av kodar-holger »

meconer skrev: 1 januari 2023, 11:46:18 Det här använder jag.
Tack. Gjorde en quick and dirty översättning till Delphi. Funkar U.A. Så nu kan jag klicka på en knapp på geotaggade bilder i mitt bildregister och få upp en nål i lantmäteriets karttjänst "minkarta".
lm_brag.png
janno skrev: 1 januari 2023, 10:25:05 Här finns färdiga bibliotek o program för att transformera alla vanliga system
https://proj.org/
Jotack. Jag känner till den där. TIllsammans med GDAL är det nog min största huvudvärk på jobbet just nu. I mitt hobbyfall var den overkill*2^10 och dessutom dåligt kompatibel med min gamla 32-bits Delphi.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
meconer
EF Sponsor
Inlägg: 491
Blev medlem: 27 april 2010, 20:07:46
Ort: Järfälla

Re: SWEREF99TM transform?

Inlägg av meconer »

Kul att du får nytta av den. Själv använder jag den i en mobilapp som används av besiktningsmän för att hitta till det som skall besiktas. Jag körde också delphi för många år sen. Hoppade över till att använda mest Java sen när de började ta kusligt betalt.
Skriv svar