top of page

Projeção Cartográfica

Python Online: Projeção TRANSVERSA de Mercator

-

Apresenta a transformação de coordenadas geodésicas na projeção Transversa de Mercator utilizando Python online.

Fundo branco em branco

Posts relacionados...

Design azul abstrato
Design azul abstrato
Design azul abstrato
Design azul abstrato
Design azul abstrato
Design azul abstrato

Python Online: Projeção TRANSVERSA de Mercator

Acesse o https://colab.research.google.com/, crie um novo "notebook" e teste o código abaixo:


import math
from math import sin
from math import cos
from math import sqrt
from math import tan
from math import atan

class Elipsoide:
    def __init__(self, nome, a, f):
        fi = 1 / f
        self.a = a
        self.b = a - a / f
        self.e = sqrt(2 * fi - fi ** 2)
        self.e2 = sqrt((a ** 2 - self.b ** 2) / self.b ** 2)
        self.Nome = nome

    def GrandeNormal(self, lat):
        e = self.e
        N = self.a / sqrt(1 -  e**2 * sin(lat)**2)
        return N

    def RaioCurvaturaSecaoMeridiana(self, lat):
        return self.a * (1 - self.e ** 2) / (1 - (self.e * sin(lat)) ** 2) ** (3/2)

    def ArcoDeElipseMeridiana(self, lat):
        a = self.a
        e = self.e
        A = 1 + (3 / 4) * e ** 2 + (45 / 64) * e ** 4 + (175 / 256) * e ** 6 + (11025 / 16384) * e ** 8 + (43659 / 65536) * e ** 10
        B = (3 / 4) * e ** 2 + (15 / 16) * e ** 4 + (525 / 512) * e ** 6 + (2205 / 2048) * e ** 8 + (72765 / 65536) * e ** 10
        C = (15 / 64) * e ** 4 + (105 / 256) * e ** 6 + (2205 / 4096) * e ** 8 + (10395 / 16384) * e ** 10
        D = (35 / 512) * e ** 6 + (315 / 2048) * e ** 8 + (31185 / 131072) * e ** 10
        E = (315 / 16384) * e ** 8 + (3465 / 65536) * e ** 10
        F = (693 / 131072) * e ** 10

        o2 = lat
        o1 = 0
        s0 = o2 - o1
        s1 = sin(2 * o2) - sin(2 * o1)
        s2 = sin(4 * o2) - sin(4 * o1)
        s3 = sin(6 * o2) - sin(6 * o1)
        s4 = sin(8 * o2) - sin(8 * o1)
        s5 = sin(10 * o2) - sin(10 * o1)

        S = a * (1 - e ** 2) * (A * s0 - 1 / 2 * B * s1 + 1 / 4 * C * s2 - 1 / 6 * D * s3 + 1 / 8 * E * s4 - 1 / 10 * F * s5)
        return S

class TransversaMercator:
    def __init__(self, el, lat, lon, m=0):
        lat *= math.pi / 180 #latitude convertida para radianos 
        lon *= math.pi / 180 #longitude convertida para radianos 
        m *= math.pi / 180 #meridiano central convertido para radianos 
        self.Elip = el #objeto Elipsoide 
        self.m = m
        self.dl = lon - m
        self.S = el.ArcoDeElipseMeridiana(lat)
        self.N = el.GrandeNormal(lat) #cálculo da Grande Normal
        e2 = el.e2 #segunda excentricidade do elipsóide
        t = tan(lat)
        na = e2 * cos(lat)
        self.x = self.N * (self.dl * cos(lat) +
                  1 / 6 * self.dl ** 3 * cos(lat) ** 3 * (1 - t ** 2 + na ** 2) +
                  1 / 120 * self.dl ** 5 * cos(lat) ** 5 * (5 - 18 * t ** 2 + t ** 4 + 14 * na ** 2 - 58 * t ** 2 * na ** 2 + 13 * na ** 4 + 4 * na ** 6 - 64 * na ** 4 * t ** 2 - 24 * na ** 6 * t ** 2) +
                  1 / 5040 * self.dl ** 7 * cos(lat) ** 7 * (61 - 479 * t ** 2 + 179 * t ** 4 - t ** 6))
        self.y = self.N * (self.S / self.N +
                  1 / 2 * self.dl ** 2 * sin(lat) * cos(lat) +
                  1 / 24 * self.dl ** 4 * sin(lat) * cos(lat) ** 3 * (5 - t ** 2 + 9 * na ** 2 + 4 * na ** 4) +
                  1 / 720 * self.dl ** 6 * sin(lat) * cos(lat) ** 5 * (61 - 58 * t ** 2 + t ** 4 + 270 * na ** 2 - 330 * t ** 2 * na ** 2 + 445 * na ** 4 + 324 * na ** 6 - 680 * na ** 4 * t ** 2 + 88 * na ** 8 - 600 * na ** 6 * t ** 2 - 192 * na ** 8 * t ** 2) +
                  1 / 40320 * self.dl ** 8 * sin(lat) * cos(lat) ** 7 * (1385 - 311 * t ** 2 + 543 * t ** 4 - t ** 6))
        c2 = (1 / math.sin(1 / 3600) * math.pi/180) ** 2
        self.c = self.dl * sin(lat) * (1 + (1 / (3 * c2) * (self.dl * cos(lat)) ** 2) * (1 + 3 * na ** 2 + 2 * na ** 4) + (1 / (15 * c2 ** 2) * (self.dl * cos(lat)) ** 4) * (2 - t ** 2))
        self.c *= 180/math.pi #convergência meridiana convertida para graus decimais
        self.c = round(self.c, 4)
        self.k = 1 + 1 / 2 * self.dl ** 2 * cos(lat) ** 2 * (1 + na ** 2) + 1 / 24 * self.dl ** 4 * cos(lat) ** 4 * (5 - 4 * t ** 2 + 14 * na ** 2 + 13 * na ** 4 - 28 * t ** 2 * na ** 2 + 4 * na ** 6 - 48 * t ** 2 * na ** 4 - 24 * t ** 2 * na ** 6) + 1 / 720 * self.dl ** 6 * cos(lat) ** 6 * (61 - 148 * t ** 2 + 16 * t ** 4)
        self.k = round(self.k, 4)
    def ProblemaInverso(el, x, y, m):
        a = el.a #semieixo maior do elipsóide 
        e = el.e #primeira excentricidade 
        e2 = el.e2 #segunda excentricidade 
        lat = [0] * 50
        lat[0] = y / a
        A0 = 1 - 1/4 * e ** 2 - 3/64 * e ** 4 - 5/256 * e ** 6 - 175/16384 * e ** 8
        A2 = 3/8 * (e ** 2 + 1/4 * e ** 4 + 15/128 * e ** 6 - 455/4096 * e ** 8)
        A4 = 15/256 * (e ** 4 + 3/4 * e ** 6 - 77/128 * e ** 8)
        A6 = 35/3072 * (e ** 6 - 41/32 * e ** 8)
        A8 = -315/131072 * e ** 8
        i = 0
        for i in range(1, 51):
            f = a * (A0 * lat[i - 1] - A2 * sin(2 * lat[i - 1]) + A4 * sin(4 * lat[i - 1]) - A6 * sin(6 * lat[i - 1]) + A8 * sin(8 * lat[i - 1])) - y
            fl = a * (A0 - 2 * A2 * cos(2 * lat[i - 1]) + 4 * A4 * cos(4 * lat[i - 1]) - 6 * A6 * cos(6 * lat[i - 1]) + 8 * A8 * cos(8 * lat[i - 1]))
            lat[i] = lat[i - 1] - f / fl
            if abs(lat[i] - lat[i - 1]) < 0.000000000001:
              break
        lat1 = lat[i]
        t1 = tan(lat1)
        na1 = e2 * cos(lat1)
        N1 = el.GrandeNormal(lat1)
        M1 = el.RaioCurvaturaSecaoMeridiana(lat1)

        lat2 = lat1 - (t1 * x ** 2 / (2 * M1 * N1)) + (t1 * x ** 4 / (24 * M1 * N1 ** 3)) * (5 + 3 * t1 ** 2 + na1 ** 2 - 4 * na1 ** 4 - 9 * na1 ** 2 * t1 ** 2) - (t1 * x ** 6 / (720 * M1 * N1 ** 5)) * (61 - 90 * t1 ** 2 + 46 * na1 ** 2 + 45 * t1 ** 4 - 252 * t1 ** 2 * na1 ** 2 - 3 * na1 ** 4 + 100 * na1 ** 6 - 66 * t1 ** 2 * na1 ** 4 - 90 * t1 ** 4 * na1 ** 2 + 88 * na1 ** 8 + 225 * t1 ** 4 * na1 ** 4 + 84 * t1 ** 2 * na1 ** 6 - 192 * t1 ** 2 * na1 ** 8) + (t1 * x ** 8 / (40320 * M1 * N1 ** 7)) * (1385 + 3633 * t1 ** 2 + 4095 * t1 ** 4 + 1575 * t1 ** 6) 
        lon2 = 1 / cos(lat1) * (x / N1 -
               1 / 6 * (x / N1) ** 3 * (1 + 2 * t1 ** 2 + na1 ** 2) +
               1 / 120 * (x / N1) ** 5 * (5 + 6 * na1 ** 2 + 28 * t1 ** 2 - 3 * na1 ** 4 + 8 * t1 ** 2 * na1 ** 2 + 24 * t1 ** 4 - 4 * na1 ** 6 + 4 * t1 ** 2 * na1 ** 4 + 24 * t1 ** 2 * na1 ** 6) -
               1 / 5040 * (x / N1) ** 7 * (61 + 662 * t1 ** 2 + 1320 * t1 ** 4 + 720 * t1 ** 6)) 
        c = atan(t1 / N1 * x -
                 t1 / 3 * (x / N1) ** 3 * (1 - na1 ** 2 - 2 * na1 ** 4) +
                 t1 / 15 * (x / N1) ** 5 * (2 + 2 * na1 ** 2 + 9 * na1 ** 4 + 6 * t1 ** 2 * na1 ** 2 + 20 * na1 ** 6 + 3 * t1 ** 2 * na1 ** 4 - 27 * t1 ** 2 * na1 ** 6 + 11 * na1 ** 8 - 24 * t1 ** 2 * na1 ** 8) -
                 17 * t1 / 315 * (x / N1) ** 7)  
        k = 1 + (1 + na1 ** 2) / 2 * (x / N1) ** 2 + 1 / 24 * (1 + 6 * na1 ** 2 + 9 * na1 ** 4 + 4 * na1 ** 6 - 24 * t1 ** 2 * na1 ** 4 - 24 * t1 ** 2 * na1 ** 6) * (x / N1) ** 4 + 1 / 720 * (x / N1) ** 6
        return [round(lat2 * 180 / math.pi,8), round(lon2 * 180 / math.pi + m,8), round(c * 180 / math.pi,4), round(k, 4)] #ângulos convertidos para graus decimais
lat = -7.5 #Latitude em graus decimais
lon = -34.2 #Longitude em graus decimais
m = -33.0 #Meridiano Central em graus decimais

el = Elipsoide("GRS80", 6378137, 298.257222101)
tmer = TransversaMercator(el, lat, lon, m)
tmer_inv = TransversaMercator.ProblemaInverso(el, tmer.x, tmer.y, m)
str = f"Coord. de Entrada (lat, lon, merid central):\n({lat},{lon},{m})"
print(str)
print("Problema Direto:")
str = f"(x, y, conv. meridiana, fator escala):\n({round(tmer.x,3)},{round(tmer.y,3)},{tmer.c},{tmer.k})"
print(str)
print("Problema Inverso:")
str = f"(lat, lon, conv. meridiana, fator escala):\n({tmer_inv[0]},{tmer_inv[1]},{tmer_inv[2]},{tmer_inv[3]})"
print(str)

Para acessar o formulário matemático da Projeção Transversa de Mercator clique aqui.


No código acima, altere as coordenadas de entrada e insira as suas. Neste exemplo as coordenadas de entrada foram latitude -7.5°, longitude -34.2° e Meridiano Central -33º. Considerada latitude de origem igual a zero.

Comentários


bottom of page