import os

import numpy as np
import pytest
import easyidp
from easyidp.core.objects import ReconsProject, Points
from easyidp.io import metashape

module_path = os.path.join(easyidp.__path__[0], "io/tests")


def test_init_reconsproject():
    attempt1 = ReconsProject("agisoft")
    assert attempt1.software == "metashape"

    attempt2 = ReconsProject("Metashape")
    assert attempt2.software == "metashape"

    with pytest.raises(LookupError):
        attempt3 = ReconsProject("not_supported_sfm")


def test_local2world2local():
    attempt1 = ReconsProject("agisoft")
    attempt1.transform.matrix = np.asarray([[-0.86573098, -0.01489186, 0.08977677, 7.65034123],
                                            [0.06972335, 0.44334391, 0.74589315, 1.85910928],
                                            [-0.05848325, 0.74899678, -0.43972184, -0.1835615],
                                            [0., 0., 0., 1.]], dtype=np.float)
    w_pos = Points([0.5, 1, 1.5])
    l_pos = Points([7.960064093299587, 1.3019528769064523, -2.6697181763370965])
    w_pos_ans = Points([0.4999999999999978, 0.9999999999999993, 1.5])

    world_pos = attempt1.local2world(l_pos)
    np.testing.assert_array_almost_equal(w_pos_ans.values, world_pos.values, decimal=6)

    local_pos = attempt1.world2local(w_pos)
    np.testing.assert_array_almost_equal(l_pos.values, local_pos.values, decimal=6)


def test_metashape_project_local_points_on_raw():
    test_project_folder = easyidp.test_full_path("data/metashape/goya_test.psx")
    chunks = metashape.open_project(test_project_folder)

    chunk = chunks[0]

    # test for single point
    l_pos = Points([7.960064093299587, 1.3019528769064523, -2.6697181763370965])

    p_dis_out = chunk.project_local_points_on_raw(l_pos, 0, distortion_correct=False)
    p_undis_out = chunk.project_local_points_on_raw(l_pos, 0, distortion_correct=True)

    # pro_api_out = np.asarray([2218.883386793118, 1991.4709388015149])
    my_undistort_out = Points([2220.854889556147, 1992.6933680261686])
    my_distort_out = Points([2218.47960556, 1992.46356322])

    np.testing.assert_array_almost_equal(p_dis_out.values, my_distort_out.values)
    np.testing.assert_array_almost_equal(p_undis_out.values, my_undistort_out.values)

    # test for multiple points
    l_pos_points = Points([[7.960064093299587, 1.3019528769064523, -2.6697181763370965],
                           [7.960064093299587, 1.3019528769064523, -2.6697181763370965]])

    p_dis_outs = chunk.project_local_points_on_raw(l_pos_points, 0, distortion_correct=False)
    p_undis_outs = chunk.project_local_points_on_raw(l_pos_points, 0, distortion_correct=True)

    my_undistort_outs = Points([[2220.854889556147, 1992.6933680261686],
                                [2220.854889556147, 1992.6933680261686]])
    my_distort_outs = Points([[2218.47960556, 1992.46356322],
                              [2218.47960556, 1992.46356322]])

    np.testing.assert_array_almost_equal(p_dis_outs.values, my_distort_outs.values)
    np.testing.assert_array_almost_equal(p_undis_outs.values, my_undistort_outs.values)


def test_world2crs_and_on_raw_images():
    test_project_folder = easyidp.test_full_path("data/metashape/wheat_tanashi.psx")
    chunks = metashape.open_project(test_project_folder)

    chunk = chunks[0]

    local = Points([11.870130675203006, 0.858098777517136, -12.987136541275])
    geocentric = Points([-3943658.7087006606, 3363404.124223561, 3704651.3067566575])
    geodetic = Points([139.54033578028609, 35.73756358928734, 96.87827569602781], columns=['lon', 'lat', 'alt'])

    idp_world = chunk.local2world(local)
    np.testing.assert_array_almost_equal(idp_world.values, geocentric.values, decimal=1)

    idp_crs = chunk.world2crs(idp_world)
    np.testing.assert_array_almost_equal(idp_crs.values, geodetic.values)

    camera_id = 56   # camera_label = 'DJI_0057'
    camera_pix_ans = Points([2391.7104647010146, 1481.8987733175165])

    idp_cam_pix = chunk.project_local_points_on_raw(local, camera_id, distortion_correct=True)
    np.testing.assert_array_almost_equal(camera_pix_ans.values, idp_cam_pix.values)



[((162, 207), 'os.path.join', 'os.path.join', (['easyidp.__path__[0]', '"""io/tests"""'], {}), "(easyidp.__path__[0], 'io/tests')\n", (174, 207), False, 'import os\n'), ((256, 280), 'easyidp.core.objects.ReconsProject', 'ReconsProject', (['"""agisoft"""'], {}), "('agisoft')\n", (269, 280), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((341, 367), 'easyidp.core.objects.ReconsProject', 'ReconsProject', (['"""Metashape"""'], {}), "('Metashape')\n", (354, 367), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((551, 575), 'easyidp.core.objects.ReconsProject', 'ReconsProject', (['"""agisoft"""'], {}), "('agisoft')\n", (564, 575), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((608, 821), 'numpy.asarray', 'np.asarray', (['[[-0.86573098, -0.01489186, 0.08977677, 7.65034123], [0.06972335, \n    0.44334391, 0.74589315, 1.85910928], [-0.05848325, 0.74899678, -\n    0.43972184, -0.1835615], [0.0, 0.0, 0.0, 1.0]]'], {'dtype': 'np.float'}), '([[-0.86573098, -0.01489186, 0.08977677, 7.65034123], [0.06972335,\n    0.44334391, 0.74589315, 1.85910928], [-0.05848325, 0.74899678, -\n    0.43972184, -0.1835615], [0.0, 0.0, 0.0, 1.0]], dtype=np.float)\n', (618, 821), True, 'import numpy as np\n'), ((953, 974), 'easyidp.core.objects.Points', 'Points', (['[0.5, 1, 1.5]'], {}), '([0.5, 1, 1.5])\n', (959, 974), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((987, 1055), 'easyidp.core.objects.Points', 'Points', (['[7.960064093299587, 1.3019528769064523, -2.6697181763370965]'], {}), '([7.960064093299587, 1.3019528769064523, -2.6697181763370965])\n', (993, 1055), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((1072, 1125), 'easyidp.core.objects.Points', 'Points', (['[0.4999999999999978, 0.9999999999999993, 1.5]'], {}), '([0.4999999999999978, 0.9999999999999993, 1.5])\n', (1078, 1125), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((1175, 1262), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['w_pos_ans.values', 'world_pos.values'], {'decimal': '(6)'}), '(w_pos_ans.values, world_pos.values,\n    decimal=6)\n', (1211, 1262), True, 'import numpy as np\n'), ((1308, 1387), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['l_pos.values', 'local_pos.values'], {'decimal': '(6)'}), '(l_pos.values, local_pos.values, decimal=6)\n', (1344, 1387), True, 'import numpy as np\n'), ((1466, 1520), 'easyidp.test_full_path', 'easyidp.test_full_path', (['"""data/metashape/goya_test.psx"""'], {}), "('data/metashape/goya_test.psx')\n", (1488, 1520), False, 'import easyidp\n'), ((1534, 1577), 'easyidp.io.metashape.open_project', 'metashape.open_project', (['test_project_folder'], {}), '(test_project_folder)\n', (1556, 1577), False, 'from easyidp.io import metashape\n'), ((1642, 1710), 'easyidp.core.objects.Points', 'Points', (['[7.960064093299587, 1.3019528769064523, -2.6697181763370965]'], {}), '([7.960064093299587, 1.3019528769064523, -2.6697181763370965])\n', (1648, 1710), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((1981, 2028), 'easyidp.core.objects.Points', 'Points', (['[2220.854889556147, 1992.6933680261686]'], {}), '([2220.854889556147, 1992.6933680261686])\n', (1987, 2028), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((2050, 2088), 'easyidp.core.objects.Points', 'Points', (['[2218.47960556, 1992.46356322]'], {}), '([2218.47960556, 1992.46356322])\n', (2056, 2088), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((2094, 2171), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['p_dis_out.values', 'my_distort_out.values'], {}), '(p_dis_out.values, my_distort_out.values)\n', (2130, 2171), True, 'import numpy as np\n'), ((2176, 2262), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['p_undis_out.values', 'my_undistort_out.values'], {}), '(p_undis_out.values, my_undistort_out.\n    values)\n', (2212, 2262), True, 'import numpy as np\n'), ((2309, 2446), 'easyidp.core.objects.Points', 'Points', (['[[7.960064093299587, 1.3019528769064523, -2.6697181763370965], [\n    7.960064093299587, 1.3019528769064523, -2.6697181763370965]]'], {}), '([[7.960064093299587, 1.3019528769064523, -2.6697181763370965], [\n    7.960064093299587, 1.3019528769064523, -2.6697181763370965]])\n', (2315, 2446), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((2684, 2779), 'easyidp.core.objects.Points', 'Points', (['[[2220.854889556147, 1992.6933680261686], [2220.854889556147, \n    1992.6933680261686]]'], {}), '([[2220.854889556147, 1992.6933680261686], [2220.854889556147, \n    1992.6933680261686]])\n', (2690, 2779), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((2829, 2901), 'easyidp.core.objects.Points', 'Points', (['[[2218.47960556, 1992.46356322], [2218.47960556, 1992.46356322]]'], {}), '([[2218.47960556, 1992.46356322], [2218.47960556, 1992.46356322]])\n', (2835, 2901), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((2937, 3016), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['p_dis_outs.values', 'my_distort_outs.values'], {}), '(p_dis_outs.values, my_distort_outs.values)\n', (2973, 3016), True, 'import numpy as np\n'), ((3021, 3109), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['p_undis_outs.values', 'my_undistort_outs.values'], {}), '(p_undis_outs.values, my_undistort_outs\n    .values)\n', (3057, 3109), True, 'import numpy as np\n'), ((3173, 3231), 'easyidp.test_full_path', 'easyidp.test_full_path', (['"""data/metashape/wheat_tanashi.psx"""'], {}), "('data/metashape/wheat_tanashi.psx')\n", (3195, 3231), False, 'import easyidp\n'), ((3245, 3288), 'easyidp.io.metashape.open_project', 'metashape.open_project', (['test_project_folder'], {}), '(test_project_folder)\n', (3267, 3288), False, 'from easyidp.io import metashape\n'), ((3325, 3390), 'easyidp.core.objects.Points', 'Points', (['[11.870130675203006, 0.858098777517136, -12.987136541275]'], {}), '([11.870130675203006, 0.858098777517136, -12.987136541275])\n', (3331, 3390), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((3408, 3476), 'easyidp.core.objects.Points', 'Points', (['[-3943658.7087006606, 3363404.124223561, 3704651.3067566575]'], {}), '([-3943658.7087006606, 3363404.124223561, 3704651.3067566575])\n', (3414, 3476), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((3492, 3594), 'easyidp.core.objects.Points', 'Points', (['[139.54033578028609, 35.73756358928734, 96.87827569602781]'], {'columns': "['lon', 'lat', 'alt']"}), "([139.54033578028609, 35.73756358928734, 96.87827569602781], columns=\n    ['lon', 'lat', 'alt'])\n", (3498, 3594), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((3636, 3724), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['idp_world.values', 'geocentric.values'], {'decimal': '(1)'}), '(idp_world.values, geocentric.values,\n    decimal=1)\n', (3672, 3724), True, 'import numpy as np\n'), ((3767, 3836), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['idp_crs.values', 'geodetic.values'], {}), '(idp_crs.values, geodetic.values)\n', (3803, 3836), True, 'import numpy as np\n'), ((3908, 3956), 'easyidp.core.objects.Points', 'Points', (['[2391.7104647010146, 1481.8987733175165]'], {}), '([2391.7104647010146, 1481.8987733175165])\n', (3914, 3956), False, 'from easyidp.core.objects import ReconsProject, Points\n'), ((4057, 4136), 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['camera_pix_ans.values', 'idp_cam_pix.values'], {}), '(camera_pix_ans.values, idp_cam_pix.values)\n', (4093, 4136), True, 'import numpy as np\n'), ((422, 448), 'pytest.raises', 'pytest.raises', (['LookupError'], {}), '(LookupError)\n', (435, 448), False, 'import pytest\n'), ((469, 503), 'easyidp.core.objects.ReconsProject', 'ReconsProject', (['"""not_supported_sfm"""'], {}), "('not_supported_sfm')\n", (482, 503), False, 'from easyidp.core.objects import ReconsProject, Points\n')]