Why does this function run slower with CUDA vs parallel? - python

Ive create a bilateral filter in python and added numba to(in theory) run it on the my GPU. Yet when I set the mode to CUDA its extremely slow and doesn't seem to use my graphics card at all while putting it into parallel makes it very fast. The best reason I have is that my function just isn't optimized to run on my GPU very well because it can't apply one function to all elements at once(because it requires the x and y coordinate to work). So my question is, why does this run slow with target set to CUDA?
#guvectorize([(float64[:,:], float64[:,:])],'(n,m)->(n,m)',target='cuda',nopython =True)
def apply_filter(img, filteredImage):
imh, imw = img.shape[:2]
radius = diameter // 2
hd = int((diameter - 1) / 2)
#print("starting work in cuda")
for h in prange(hd, imh - hd):
for w in prange(hd, imw - hd):
Wp = 0
filteredPixel = 0
startX = h
startY = w
for x in prange(0, diameter):
for y in prange(0, diameter):
currentX = startX - (radius - x)
cureentY = startY - (radius - y)
intensityDifferent = img[currentX][cureentY] - img[startX][startY]
intensity = (1.0 / (2 * math.pi * (sIntesity ** 2)) * math.exp(- (intensityDifferent ** 2) / (2 * sIntesity ** 2)))
distance = ((currentX-startX)**2 + (cureentY-startY)**2)**(1/2)
smoothing = (1.0 / (2 * math.pi * (sSpace ** 2))) * math.exp(- (distance ** 2) / (2 * sSpace ** 2))
weight = intensity * smoothing;
filteredPixel += img[currentX][cureentY] * weight
Wp += weight
filteredImage[h][w] = int(round(filteredPixel / Wp))
#print("done!")

Related

Vedo 3D-Gyroid structures STL export

I need to generate a double 3D gyroid structure. For this, I'm using vedo
from matplotlib import pyplot as plt
from scipy.constants import speed_of_light
from vedo import *
import numpy as np
# Paramters
a = 5
length = 100
width = 100
height = 10
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
def gen_strut(start, stop):
'''Generate the strut parameter t for the gyroid surface. Create a linear gradient'''
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
plt = Plotter(shape=(1, 1), interactive=False, axes=3)
scale=0.5
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
threshold = 0
iso1 = Volume(U1).isosurface(threshold).c('silver').alpha(1)
cube = TessellatedBox(n=(int(length-1), int(width-1), int(height-1)), spacing=(1, 1, 1))
iso_cut = cube.cutWithMesh(iso1).c('silver').alpha(1)
# Combine the two meshes into a single mesh
plt.at(0).show([cube, iso1], "Double Gyroid 1", resetcam=False)
plt.interactive().close()
The result looks quite good, but now I'm struggling with exporting the volume. Although vedo has over 300 examples, I did not find anything in the documentation to export this as a watertight volume for 3D-Printing. How can I achieve this?
I assume you mean that you want to extract a watertight mesh as an STL (?).
This is a non trivial problem because it is only well defined on a subset of the mesh regions where the in/out is not ambiguous, in those cases fill_holes() seems to do a decent job..
Other cases should be dealt "manually". Eg, you can access the boundaries with mesh.boundaries() and try to snap the vertices to a closest common vertex. This script is not a solution, but I hope can give some ideas on how to proceed.
from vedo import *
# Paramters
a = 5
length = 100
width = 100
height = 10
def gen_strut(start, stop):
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
scale=0.5
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
iso = Volume(U1).isosurface(0).c('silver').backcolor("p5").lw(1).flat()
cube = TessellatedBox(n=(length-1, width-1, height-1)).c('red5').alpha(1)
cube.triangulate().compute_normals()
cube.cut_with_mesh(iso).compute_normals()
print(iso.boundaries(return_point_ids=True))
print(cube.boundaries(return_point_ids=True))
print(iso.boundaries().join().lines())
show(iso, cube).close()
merge(iso, cube).clean().backcolor("p5").show().close()
iso.clone().fill_holes(15).backcolor("p5").show().close()

Why is my code so slow using Numpy compared to Matlab

I'm sorry for my ignorance in using NumPy and python. I'm much more comfortable in Matlab however I've been required to convert my code from Matlab to Python. To run my script in Python takes 113 seconds meanwhile it takes 7 seconds in MATLAB. Both produce correct results albeit different due to stochasticity. The big culprit I believe is my derivative function. I profiled my python code and it says that this function accounts for 76% of the run time (It doesn't take up nearly as much percent-wise in MATLAB). I understand there is a lot of code so if anyone could help me with making my python derivative code perform more similarly to MATLAB that would be greatly appreciated! If you have any questions feel free to ask. Thank you!
Derivative6DOF.py
## Derivative6DOF Variables
# Input Variables
# x - vehicle state = [x, y, z, u, v, w, phi, theta, psi, p, q, r, omega1, omega2, omega3, omega4]'
# dt - time step
# bigOmegasTarget - commanded rotor speeds = [omega1, omega2, omega3, omega4]'
# batterySOC - percent battery charge remaining
# m - mass of vehicle
# g - gravitational acceleration constant
# I - moment of inertia = eye([I11, I22, I33]')
# Cd0 - Profile drag coefficient of each rotor
# pitch - pitch of blade
# rho - density of air
# a - lift curve slope of the airfoil
# b - number of blades
# c - chord length of blade
# R - total length of the rotor blade
# viGuessInitial - guess induced velocity
# posProps - position of propellers from center of gravity = [x, y, z]'
# A - area of propeller
# maxCapacity - max battery capacity
# powerDrawComponents - power drawn by components from battery
# Kv - voltage coefficient of motor [rad/sec/V]
# Kt - motor torque coefficent [N*m/A]
# voltMax - max voltage supplied
# resistanceMotor - resistance of motor
# PeMax - max power possible
# Jp - inertia about each motor (includes propellor and motor) [kg*m^2]
# Output Variables
# xdot - vehicle state derivative = [u, v, w, udot, vdot, zdot, p, q, r, pdot, qdot, rdot, omegadot1 omegadot2 omegadot3 omegadot4]'
# battery - battery state = [percentRemaining, dischargeRate]'
# k - thrust-to-omega coefficient (https://andrew.gibiansky.com/blog/physics/quadcopter-dynamics/#:~:text=Each#20rotor#20contributes#20some#20torque,CDAv2.)
# b_coeff - yaw-to-omega coefficient (https://andrew.gibiansky.com/blog/physics/quadcopter-dynamics/#:~:text=Each#20rotor#20contributes#20some#20torque,CDAv2.)
# Intermediate Variables
# DCM - rotation matrix from body frame to inertial frame
# UVWp - translational velocity at each propeller = [u, v, w]'
# theta0 - root blade angle
# theta1 - linear twist of blade
# T - thrust
# vi - induced velocity iterated guess
# vPrime - effective speed of flow at the rotor
# viCalc - induced velocity calculated
# Pinduced - induced power
# Pprofile - profile power
# Qp - rotor aerodynamic torque (current motor torque)
# totalThrust - sum of each rotor thrust
# QeMax - max electric motor torque possible
# PeMax - max electric power available
# Qe - electric motor torque (desired motor torque)
# ind - index
# Maero - aerodynamic pitching, rolling and yawing moments = [x, y, z]'
# H - hub forces = [x, y, z]'
# Mgyro - gyroscopic moments = [x, y, z]'
# Cl - coefficient of lift
# AR - aspect ratio
# Cd - coefficient of drag
# lx - distance of props in x-direction
# ly - distance of props in y-direction
# LScale - pitch scalar coefficient
# MScale - roll scalar coefficient
# NScale - yaw scalar coefficient
# MThrust - differential thrust = [x, y, z]'
# F - sum of all forces acting on vehicle
# M - sum of all moments acting on vehicle
# powerDrawMotors - sum of all power draw from all 4 motors
# totalPowerDraw - total power load on battery from all components (motors, camera, electronics, etc.)
# maxBatteryPower = maxCapacity*voltMax/1000; # (Whr) Max possible power from battery at start
# State Element Vector
# x - x-position
# y - y-position
# z - z-position
# u - x-velocity
# v - y-velocity
# w - z-velocity
# udot - x-acceleration
# vdot - y-acceleration
# wdot - z-acceleration
# phi - angle about y-axis
# theta - angle about x-axis
# psi - angle about z-axis
# p - angular velocity about y-axis
# q - angular velocity about x-axis
# r - angular velocity about z-axis
# pdot - angular acceleration about y-axis
# qdot - angular acceleration about x-axis
# rdot - angular acceleration about z-axis
# omega1 - angular speed of front left rotor
# omega2 - angular speed of back right rotor
# omega3 - angular speed of front right rotor
# omega4 - angular speed of back left rotor
# omegadot1 - angular acceleration of front left rotor
# omegadot2 - angular acceleration of back right rotor
# omegadot3 - angular acceleration of front right rotor
# omegadot4 - angular acceleration of back left rotor
# percentRemaining - percent battery charge remaining
# dischargeRate - discharge rate of battery
# Additional Notes
# Mgyro Derivation Code (Page 639)
# syms p q r Omega Jp
# omega = [0; 0; Jp*Omega]; rotation about positive z-axis
# skewMatrix = [0 -r q; r 0 -p; -q p 0];
# Mgyro = -skewMatrix*omega
import numpy as np
def Derivative6DOF(x,dt,bigOmegasTarget,batterySOC,m,g,I,Cd0,pitch,rho,a,b,c,R,viGuessInitial,posProps,A,maxCapacity,powerDrawComponents,Kv,Kt,voltMax,resistanceMotor,PeMax,Jp,processNoise,theta0,theta1):
# direction cosine matrix (from bodyframe to NED)
DCM = np.array([[np.cos(x[8]) * np.cos(x[7]),- np.sin(x[8]) * np.cos(x[6]) + np.cos(x[8]) * np.sin(x[7]) * np.sin(x[6]),np.sin(x[8]) * np.sin(x[6]) + np.cos(x[8]) * np.cos(x[6]) * np.sin(x[7])],[np.cos(x[7]) * np.sin(x[8]),np.cos(x[8]) * np.cos(x[6]) + np.sin(x[8]) * np.sin(x[7]) * np.sin(x[6]),- np.cos(x[8]) * np.sin(x[6]) + np.sin(x[8]) * np.cos(x[6]) * np.sin(x[7])],[- np.sin(x[7]),np.sin(x[6]) * np.cos(x[7]),np.cos(x[7]) * np.cos(x[6])]])
# propeller velocity
UVWp = np.zeros((4,3))
for i in range(0,4):
UVWp[i,:] = x[3:6] + np.cross(x[9:12],posProps[i,:])
T = np.zeros((4,))
vi = np.ones((4,)) * viGuessInitial
# induced velocity for each rotor
for i in range(0,4):
# induced velocity
vPrime = np.sqrt(UVWp[i,0] ** 2 + UVWp[i,1] ** 2 + (UVWp[i,2] - vi[i]) ** 2)
T[i] = rho * a * b * c * R / 4 * ((UVWp[i,2] - vi[i]) * x[12 + i] * R + 2 / 3 * (x[12 + i] * R) ** 2 * (theta0 + 0.75 * theta1) + (UVWp[i,0] ** 2 + (UVWp[i,1] ** 2)) * (theta0 + 0.5 * theta1))
viCalc = T[i] / (2 * rho * A * vPrime)
# converge iterated induced velocity and calculated induced velocity
while np.abs(vi[i] - viCalc) > 1e-05:
# induced velocity
vPrime = np.sqrt(UVWp[i,0] ** 2 + UVWp[i,1] ** 2 + (UVWp[i,2] - vi[i]) ** 2)
T[i] = rho * a * b * c * R / 4 * ((UVWp[i,2] - vi[i]) * x[12 + i] * R + 2 / 3 * (x[12 + i] * R) ** 2 * (theta0 + 0.75 * theta1) + (UVWp[i,0] ** 2 + (UVWp[i,1] ** 2)) * (theta0 + 0.5 * theta1))
viCalc = T[i] / (2 * rho * A * vPrime)
# increment the induced velocity guess
vi[i] = vi[i] + 0.1 * (viCalc - vi[i])
# calculate induced power, profile power, and rotor aerodynamic torque for each rotor
Pinduced = T*(vi-UVWp[:,2])
Pprofile = (rho*Cd0*b*c*x[12:16]*R**2/8 * ((x[12:16]*R)**2 + UVWp[:,0]**2 + UVWp[:,1]**2))
Qp = 1/x[12:16]*(Pinduced + Pprofile)
# calculate total thrust
totalThrust = np.array([[0],[0],[-np.sum(T)]]).reshape((3,))
# calculate electric motor torque
QeMax = PeMax / x[12:16]
Qe = (Kt / resistanceMotor) * (bigOmegasTarget - x[12:16]) / Kv
# confirm electric motor torque isn't exceeding limit
np.where(Qe > QeMax, Qe, QeMax)
# calculate aerodynamic pitching, rolling, and yawing moments
Maero = np.zeros((3,))
Maero[0] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * rho * a * b * c * R**2 * (x[12:16] * R**2 / 16 * x[9] + ((UVWp[:,2] - vi) / 8 + x[12:16] * R * theta0 / 6 + x[12:16] * R * theta1 / 8) * UVWp[:,0]))
Maero[1] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * rho * a * b * c * R**2 * (x[12:16] * R**2 / 16 * x[10] + ((UVWp[:,2] - vi) / 8 + x[12:16] * R * theta0 / 6 + x[12:16] * R * theta1 / 8) * UVWp[:,1]))
Maero[2] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * Qe)
# calculate hub force
H = -np.sign(x[3:6]) * np.sum(rho * Cd0 * b * c * x[12:16] * R**2 / 4 * np.array([UVWp[:,0],UVWp[:,1],np.array([[0],[0],[0],[0]]).reshape(4,)]))
# calculate gyroscopic moments
Mgyro = np.sum(x[12:16] * np.array([[-1],[-1],[1],[1]]).reshape(4,)) * Jp * np.array([-x[10], x[9], 0]).reshape((3,))
# calculate thrust-to-omega coefficient
k = T / x[12:16]**2
# calculate yaw-to-omega coefficient
Cl = 2 * T / (rho * R**2 * x[12:16]**2)
AR = R**2 / A
Cd = Cd0 + Cl**2 / (np.pi * AR * 1)
b_coeff = 0.5 * R ** 3 * rho * Cd * A
# calculate motor-mixer scalar coefficients
lx = np.abs(posProps[:,0])
ly = np.abs(posProps[:,1])
LScale = k * ly
MScale = k * lx
NScale = b_coeff
# calculate differential thrust
MThrust = np.zeros((3,))
MThrust[0] = np.sum(x[12:16]**2 * np.array([1,-1,-1,1]).reshape((4,)) * LScale)
MThrust[1] = np.sum(x[12:16]**2 * np.array([1,-1,1,-1]).reshape((4,)) * MScale)
MThrust[2] = np.sum(x[12:16]**2 * np.array([-1,-1,1,1]).reshape((4,)) * NScale)
# total force and moment acting on quadcopter in inertial frame
F = DCM # (totalThrust + H)
M = DCM # (Maero + Mgyro + MThrust)
# calculate state derivative
xdot = np.zeros((16,))
xdot[0:3] = np.array([x[3],x[4],x[5]])
xdot[3] = F[0] / m
xdot[4] = F[1] / m
xdot[5] = g + F[2] / m
xdot[6] = x[9] + np.tan(x[7]) * np.sin(x[6]) * x[10] + np.tan(x[7]) * np.cos(x[6]) * x[11]
xdot[7] = np.cos(x[6]) * x[10] - np.sin(x[6]) * x[11]
xdot[8] = 1/np.cos(x[7]) * np.sin(x[6]) * x[10] + 1/np.cos(x[7]) * np.cos(x[6]) * x[11]
xdot[9] = (M[0] + x[10] * x[11] * (I[1,1] - I[2,2])) / I[0,0]
xdot[10] = (M[1] + x[9] * x[11] * (I[2,2] - I[0,0])) / I[1,1]
xdot[11] = (M[2] + x[9] * x[10] * (I[0,0] - I[1,1])) / I[2,2]
xdot[12:16] = 1/Jp * (Qe - Qp)
xdot = xdot + np.random.randn(16,) * processNoise
# calculate battery state
powerDrawMotors = np.sum(Qp * x[12:16])
totalPowerDraw = powerDrawMotors + powerDrawComponents
maxBatteryPower = maxCapacity * voltMax / 1000
discharge = totalPowerDraw * dt / 3600 / maxBatteryPower * 100
batterySOC = batterySOC - discharge
battery = np.array([[batterySOC],[discharge]]).reshape((2,))
return xdot,battery,k,b_coeff,vi

Buffer dtype cannot be buffer in numba

Im trying to convert a bilateral filter I wrote to run on my GPU via numba but I can't seem to get it to work! Im getting the error
TypeError: Buffer dtype cannot be buffer, have dtype: array(float64, 2d, A)
from the following code.
#vectorize([(float64[:,:], float64[:,:])], target='cuda')
def apply_filter(img, filteredImage):
imh, imw = img.shape[:2]
hd = int((diameter - 1) / 2)
for h in range(hd, imh - hd):
for w in range(hd, imw - hd):
Wp = 0
filteredPixel = 0
radius = diameter // 2
for x in range(0, diameter):
for y in range(0, diameter):
currentX = w - (radius - x)
cureentY = h - (radius - y)
intensityDifferent = img[currentX][cureentY] - img[w][h]
intensity = (1.0/ (2 * math.pi * (sIntesity ** 2))* math.exp(-(intensityDifferent ** 2) / (2 * sIntesity ** 2)))
foo = (currentX - w) ** 2 + (cureentY - h) ** 2
distance = cmath.sqrt(foo)
smoothing = (1.0 / (2 * math.pi * (sSpace ** 2))) * math.exp( -(distance.real ** 2) / (2 * sSpace ** 2))
weight = intensity * smoothing
filteredPixel += img[currentX][cureentY] * weight
Wp += weight
filteredImage[h][w] = int(round(filteredPixel / Wp))
if __name__ == "__main__":
src = cv2.imread("messy2.png", cv2.IMREAD_GRAYSCALE)
src = src.astype(np.float64)
filtered_image_own = np.zeros(src.shape)
apply_filter(src, filtered_image_own)
filtered_image_own = filtered_image_own.astype(np.uint8)
cv2.imwrite("filtered_image4.png", filtered_image_own)
I've looked around and haven't found anything useless except that this error might be because a list is passed in? But both of my arguments are 2D arrays and the signature should be correct for that. Why am I getting this error?
To pass in arrays or take array outputs, it's better to use guvectorize().
Check it out at Numba docs or this blog for a detailed account of usage.

Double gaussian fit with common centroid Python

I am trying to fit some data with a double Gaussian function using scipy.optimization.curve_fit:
Double gaussian fit with two centroids
def _2gaussian(x, amp1, cen1, sigma1, amp2, cen2, sigma2):
g1 = amp1 * (1 / (sigma1 * (np.sqrt(2 * np.pi)))) * (np.exp((-1.0 / 2.0) * (((x - cen1) / sigma1) ** 2)))
g2 = amp2 * (1 / (sigma2 * (np.sqrt(2 * np.pi)))) * (np.exp((-1.0 / 2.0) * (((x - cen2) / sigma2) ** 2)))
return g1 + g2  # + cen2
So my problem is: my data are quite symmetric and I was trying to use a double Gaussian fit with a common/shared centroid for the two Gaussian functions. I have tried to write in the previous formula cen1 instead of cen2 (and keeping cen2 in the parameters) or also to just eliminate totally cen2 as a parameter. Nothing of these worked, so that the fit obtained is just a flat curve with a big spike in the middle. Do you have any suggestions on how to have just a shared centroid?
Double gaussian with cen1 only
The lowest points in your data start at around y = 4000. But your Gaussian function has no offset term, so it will always start at y = 0. You either need to normalize your data, or add an offset like this:
def _2gaussian(x, amp1, cen1, sigma1, amp2, cen2, sigma2, offset):
g1 = amp1 * (1 / (sigma1 * (np.sqrt(2 * np.pi)))) * (np.exp((-1.0 / 2.0) * (((x - cen1) / sigma1) ** 2)))
g2 = amp2 * (1 / (sigma2 * (np.sqrt(2 * np.pi)))) * (np.exp((-1.0 / 2.0) * (((x - cen2) / sigma2) ** 2)))
return g1 + g2 + offset # + cen2
Then I highly recommend using the p0 argument in curve_fit, which will let you specify an initial guess for each parameter in your fitting function. In your case, your guess for offset will be 4000.

Convert planar x/y to lat/long

Im trying to write a program that takes new york city x/y coords and turns them into lat/lng decimal points. Im new to planar/globe mapping. Ive included the constants that NYC has provided on their website. Also if there is a good article on how to do this I would love to learn! Below is the program I have written along with commented output at the bottom and also what the ideal values should be. Im kinda just stumbling in the dark on this.
#!/usr/bin/python
from math import *
"""
Supplied by NYC
Lambert Conformal Conic:
Standard Parallel: 40.666667
Standard Parallel: 41.033333
Longitude of Central Meridian: -74.000000
Latitude of Projection Origin: 40.166667
False Easting: 984250.000000
False Northing: 0.000000
"""
x = 981106 #nyc x coord
y = 195544 #nyc y coord
a = 6378137 #' major radius of ellipsoid, map units (NAD 83)
e = 0.08181922146 #' eccentricity of ellipsoid (NAD 83)
angRad = pi/180 #' number of radians in a degree
pi4 = pi/4 #' Pi / 4
p0 = 40.166667 * angRad #' latitude of origin
p1 = 40.666667 * angRad #' latitude of first standard parallel
p2 = 41.033333 * angRad #' latitude of second standard parallel
m0 = -74.000000 * angRad #' central meridian
x0 = 984250.000000 #' False easting of central meridian, map units
m1 = cos(p1) / sqrt(1 - ((e ** 2) * sin(p1) ** 2))
m2 = cos(p2) / sqrt(1 - ((e ** 2) * sin(p2) ** 2))
t0 = tan(pi4 - (p0 / 2))
t1 = tan(pi4 - (p1 / 2))
t2 = tan(pi4 - (p2 / 2))
t0 = t0 / (((1 - (e * (sin(p0)))) / (1 + (e * (sin(p0)))))**(e / 2))
t1 = t1 / (((1 - (e * (sin(p1)))) / (1 + (e * (sin(p1)))))**(e / 2))
t2 = t2 / (((1 - (e * (sin(p2)))) / (1 + (e * (sin(p2)))))**(e / 2))
n = log(m1 / m2) / log(t1 / t2)
f = m1 / (n * (t1 ** n))
rho0 = a * f * (t0 ** n)
x = x - x0
pi2 = pi4 * 2
rho = sqrt((x ** 2) + ((rho0 - y) ** 2))
theta = atan(x / (rho0 - y))
t = (rho / (a * f)) ** (1 / n)
lon = (theta / n) + m0
x = x + x0
lat0 = pi2 - (2 * atan(t))
part1 = (1 - (e * sin(lat0))) / (1 + (e * sin(lat0)))
lat1 = pi2 - (2 * atan(t * (part1 ** (e / 2))))
while abs(lat1 - lat0) < 0.000000002:
lat0 = lat1
part1 = (1 - (e * sin(lat0))) / (1 + (e * sin(lat0)))
lat1 = pi2 - (2 * atan(t * (part1 ^ (e / 2))))
lat = lat1 / angRad
lon = lon / angRad
print lat,lon
#output : 41.9266666432 -74.0378981653
#should be 40.703778, -74.011829
Im pretty stuck, I have a ton of these that need geo-coded
Thanks for any help!
One word answer: pyproj
>>> from pyproj import Proj
>>> pnyc = Proj(
... proj='lcc',
... datum='NAD83',
... lat_1=40.666667,
... lat_2=41.033333,
... lat_0=40.166667,
... lon_0=-74.0,
... x_0=984250.0,
... y_0=0.0)
>>> x = [981106.0]
>>> y = [195544.0]
>>> lon, lat = pnyc(x, y, inverse=True)
>>> lon, lat
([-74.037898165369015], [41.927378144152335])
These formulas should help you out:
http://www.linz.govt.nz/geodetic/conversion-coordinates/projection-conversions/lambert-conformal-conic#lbl3
owww. you'd be better using a library for this. a little searching suggests that should be the python interface to gdal
this question uses gdal, but not via the python api (they just call gdal via a command line from within python), but might help.
you might be best asking at gis stackexchange for more info.
i'm unclear where you got the code above from. if you link to it i/someone could check for obvious implementation errors.
Rather than trying to work through all the math, you could just pick a grid over your map surface and find out the lat/long of those grid points, then use interpolation to do the conversion. Depending on the linearity of the projection it might not take many points to get good accuracy.

Categories