# Path: attitude/error/axes.py
# def hyperbolic_axes(fit, **kwargs):
#     type = kwargs.pop('type', 'noise')
#     try:
#         if type == 'noise':
#             return noise_axes(fit, **kwargs)
#         else:
#             return sampling_axes(fit, **kwargs)
#     except:
#         return fit.hyperbolic_axes
# 
# Path: attitude/stereonet.py
# def plane_errors(axes, covariance_matrix, sheet='upper',**kwargs):
#     """
#     kwargs:
#     traditional_layout  boolean [True]
#         Lay the stereonet out traditionally, with north at the pole of
#         the diagram. The default is a more natural and intuitive visualization
#         with vertical at the pole and the compass points of strike around the equator.
#         Thus, longitude at the equator represents strike and latitude represents
#         apparent dip at that azimuth.
#     """
# 
#     level = kwargs.pop('level',1)
#     traditional_layout = kwargs.pop('traditional_layout',True)
# 
#     d = covariance_matrix
# 
#     ell = ellipse(**kwargs)
#     bundle = dot(ell, d[:2])
#     res = d[2]*level*2
# 
#     # Switch hemispheres if PCA is upside-down
#     # Normal vector is always correctly fit
#     #if traditional_layout:
#     #if axes[2,2] > 0:
# 
#     if axes[2,2] > 0:
#         res *= -1
# 
#     if sheet == 'upper':
#         bundle += res
#     elif sheet == 'lower':
#         bundle -= res
# 
#     _ = dot(bundle,axes).T
# 
#     if traditional_layout:
#         lon,lat = stereonet_math.cart2sph(_[2],_[0],_[1])
#     else:
#         lon,lat = stereonet_math.cart2sph(-_[1],_[0],_[2])
# 
#     return list(zip(lon,lat))
# 
# def normal_errors(axes, covariance_matrix, **kwargs):
#     """
#     Currently assumes upper hemisphere of stereonet
#     """
#     level = kwargs.pop('level',1)
#     traditional_layout = kwargs.pop('traditional_layout',True)
#     d = N.diagonal(covariance_matrix)
#     ell = ellipse(**kwargs)
# 
#     if axes[2,2] < 0:
#         axes *= -1
# 
#     # Not sure where this factor comes from but it
#     # seems to make things work better
#     c1 = 2
#     axis_lengths = d[:2]
#     f = N.linalg.norm(
#         ell*axis_lengths,axis=1)
# 
#     e0 = -ell.T*d[2]*c1
#     e = N.vstack((e0,f))
# 
#     _ = dot(e.T,axes).T
# 
#     if traditional_layout:
#         lon,lat = stereonet_math.cart2sph(_[2],_[0],-_[1])
#     else:
#         lon,lat = stereonet_math.cart2sph(-_[1],_[0],_[2])
#     return list(zip(lon,lat))


import numpy as N
from cartopy import crs, feature
from shapely.geometry import Polygon
from ..error.axes import hyperbolic_axes
from ..stereonet import plane_errors, normal_errors
"""
Functions to plot data using the `cartopy` library.
These require the `shapely` and `cartopy` libraries to be installed.
CartoPy is sometimes difficult to install.
"""


def fix_stereonet_coords(coords):
    coords[:,1] *= -1
    return coords

def cartopy_girdle(fit, **kw):
    d = hyperbolic_axes(fit,**kw)
    cm = N.diag(d)
    sheets = {i: N.degrees(plane_errors(fit.axes, cm, sheet=i))
        for i in ('upper','lower')}
    geom = Polygon(sheets['upper'], [sheets['lower'][::-1]])
    geometries = [geom]
    return feature.ShapelyFeature(geometries, crs.PlateCarree())

def cartopy_normal(fit, **kw):

# Path: attitude/error/axes.py
# def hyperbolic_axes(fit, **kwargs):
#     type = kwargs.pop('type', 'noise')
#     try:
#         if type == 'noise':
#             return noise_axes(fit, **kwargs)
#         else:
#             return sampling_axes(fit, **kwargs)
#     except:
#         return fit.hyperbolic_axes
# 
# Path: attitude/stereonet.py
# def plane_errors(axes, covariance_matrix, sheet='upper',**kwargs):
#     """
#     kwargs:
#     traditional_layout  boolean [True]
#         Lay the stereonet out traditionally, with north at the pole of
#         the diagram. The default is a more natural and intuitive visualization
#         with vertical at the pole and the compass points of strike around the equator.
#         Thus, longitude at the equator represents strike and latitude represents
#         apparent dip at that azimuth.
#     """
# 
#     level = kwargs.pop('level',1)
#     traditional_layout = kwargs.pop('traditional_layout',True)
# 
#     d = covariance_matrix
# 
#     ell = ellipse(**kwargs)
#     bundle = dot(ell, d[:2])
#     res = d[2]*level*2
# 
#     # Switch hemispheres if PCA is upside-down
#     # Normal vector is always correctly fit
#     #if traditional_layout:
#     #if axes[2,2] > 0:
# 
#     if axes[2,2] > 0:
#         res *= -1
# 
#     if sheet == 'upper':
#         bundle += res
#     elif sheet == 'lower':
#         bundle -= res
# 
#     _ = dot(bundle,axes).T
# 
#     if traditional_layout:
#         lon,lat = stereonet_math.cart2sph(_[2],_[0],_[1])
#     else:
#         lon,lat = stereonet_math.cart2sph(-_[1],_[0],_[2])
# 
#     return list(zip(lon,lat))
# 
# def normal_errors(axes, covariance_matrix, **kwargs):
#     """
#     Currently assumes upper hemisphere of stereonet
#     """
#     level = kwargs.pop('level',1)
#     traditional_layout = kwargs.pop('traditional_layout',True)
#     d = N.diagonal(covariance_matrix)
#     ell = ellipse(**kwargs)
# 
#     if axes[2,2] < 0:
#         axes *= -1
# 
#     # Not sure where this factor comes from but it
#     # seems to make things work better
#     c1 = 2
#     axis_lengths = d[:2]
#     f = N.linalg.norm(
#         ell*axis_lengths,axis=1)
# 
#     e0 = -ell.T*d[2]*c1
#     e = N.vstack((e0,f))
# 
#     _ = dot(e.T,axes).T
# 
#     if traditional_layout:
#         lon,lat = stereonet_math.cart2sph(_[2],_[0],-_[1])
#     else:
#         lon,lat = stereonet_math.cart2sph(-_[1],_[0],_[2])
#     return list(zip(lon,lat))


# Path: attitude/display/cartopy.py
import numpy as N
from cartopy import crs, feature
from shapely.geometry import Polygon
from ..error.axes import hyperbolic_axes
from ..stereonet import plane_errors, normal_errors

"""
Functions to plot data using the `cartopy` library.
These require the `shapely` and `cartopy` libraries to be installed.
CartoPy is sometimes difficult to install.
"""


def fix_stereonet_coords(coords):
    coords[:,1] *= -1
    return coords

def cartopy_girdle(fit, **kw):
    d = hyperbolic_axes(fit,**kw)
    cm = N.diag(d)
    sheets = {i: N.degrees(plane_errors(fit.axes, cm, sheet=i))
        for i in ('upper','lower')}
    geom = Polygon(sheets['upper'], [sheets['lower'][::-1]])
    geometries = [geom]
    return feature.ShapelyFeature(geometries, crs.PlateCarree())

def cartopy_normal(fit, **kw):

    d = hyperbolic_axes(fit,**kw)