#!/usr/bin/env pytest
# -*- coding: utf-8 -*-
###############################################################################
# $Id: xyz.py 7fefb7ee5e6834d26f6fc96f54c2a4312b5bd507 2019-04-24 21:41:42 +0200 Even Rouault $
#
# Project:  GDAL/OGR Test Suite
# Purpose:  Test read/write functionality for XYZ driver.
# Author:   Even Rouault <even dot rouault at mines dash paris dot org>
#
###############################################################################
# Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################

import struct
from osgeo import gdal


import gdaltest

###############################################################################
# Test CreateCopy() of byte.tif


def test_xyz_1():

    tst = gdaltest.GDALTest('XYZ', 'byte.tif', 1, 4672)
    return tst.testCreateCopy(vsimem=1, check_gt=(-67.00041667, 0.00083333, 0.0, 50.000416667, 0.0, -0.00083333))

###############################################################################
# Test CreateCopy() of float.img


def test_xyz_2():

    src_ds = gdal.Open('data/float.img')
    ds = gdal.GetDriverByName('XYZ').CreateCopy('tmp/float.xyz', src_ds, options=['COLUMN_SEPARATOR=,', 'ADD_HEADER_LINE=YES'])
    got_cs = ds.GetRasterBand(1).Checksum()
    expected_cs = src_ds.GetRasterBand(1).Checksum()
    ds = None
    gdal.GetDriverByName('XYZ').Delete('tmp/float.xyz')
    assert got_cs == expected_cs or got_cs == 24387

###############################################################################
# Test random access to lines of imagery


def test_xyz_3():

    content = """Y X Z
0 0 65


0 1 66

1 0 67

1 1 68
2 0 69
2 1 70


"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)
    ds = gdal.Open('/vsimem/grid.xyz')
    buf = ds.ReadRaster(0, 2, 2, 1)
    assert struct.unpack('B' * 2, buf) == (69, 70)
    buf = ds.ReadRaster(0, 1, 2, 1)
    assert struct.unpack('B' * 2, buf) == (67, 68)
    buf = ds.ReadRaster(0, 0, 2, 1)
    assert struct.unpack('B' * 2, buf) == (65, 66)
    buf = ds.ReadRaster(0, 2, 2, 1)
    assert struct.unpack('B' * 2, buf) == (69, 70)
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')


###############################################################################
# Test regularly spaced XYZ but with missing values at beginning and/or end of lines
# and missing value in the middle. And a not so exact spacing

def xyz_4_checkline(ds, i, expected_bytes):
    buf = ds.ReadRaster(0, i, ds.RasterXSize, 1)
    return struct.unpack('B' * ds.RasterXSize, buf) == expected_bytes


def test_xyz_4():

    content = """
440750.001 3751290 1
440809.999 3751290 2

440690 3751170.001 3
440750.001 3751170.001 4
440870 3751170.001 6

440810 3751050 7"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)
    expected = [(0, 1, 2, 0), (3, 4, 0, 6), (0, 0, 7, 0)]

    ds = gdal.Open('/vsimem/grid.xyz')

    got_gt = ds.GetGeoTransform()
    expected_gt = (440660.0, 60.0, 0.0, 3751350.0, 0.0, -120.0)
    for i in range(6):
        assert abs(got_gt[i] - expected_gt[i]) <= 1e-5

    assert ds.GetRasterBand(1).GetMinimum() == 1
    assert ds.GetRasterBand(1).GetMaximum() == 7
    assert ds.GetRasterBand(1).GetNoDataValue() == 0
    for i in [0, 1, 2, 1, 0, 2, 0, 2, 0, 1, 2]:
        assert xyz_4_checkline(ds, i, expected[i])
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')


###############################################################################
# Test XYZ with only integral values and comma field separator

def test_xyz_5():

    content = """0,1,100
0.5,1,100
1,1,100
0,2,100
0.5,2,100
1,2,100
"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)

    ds = gdal.Open('/vsimem/grid.xyz')
    assert ds.RasterXSize == 3 and ds.RasterYSize == 2
    got_gt = ds.GetGeoTransform()
    expected_gt = (-0.25, 0.5, 0.0, 0.5, 0.0, 1.0)
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')

    for i in range(6):
        assert abs(got_gt[i] - expected_gt[i]) <= 1e-5

    

###############################################################################
# Test XYZ with comma decimal separator and semi-colon field separator

def test_xyz_6():

    content = """0;1;100
0,5;1;100
1;1;100
0;2;100
0,5;2;100
1;2;100
"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)

    ds = gdal.Open('/vsimem/grid.xyz')
    assert ds.RasterXSize == 3 and ds.RasterYSize == 2
    got_gt = ds.GetGeoTransform()
    expected_gt = (-0.25, 0.5, 0.0, 0.5, 0.0, 1.0)
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')

    for i in range(6):
        assert abs(got_gt[i] - expected_gt[i]) <= 1e-5

    

###############################################################################
# Test XYZ with not completely equal stepX and stepY

def test_xyz_7():

    content = """y x z
   51.500000  354.483333     54.721
   51.500000  354.516667     54.714
   51.500000  354.550000     54.705
   51.475000  354.483333     54.694
   51.475000  354.516667     54.687
   51.475000  354.550000     54.678
   51.450000  354.483333     54.671
   51.450000  354.516667     54.663
   51.450000  354.550000     54.654
   51.425000  354.483333     54.652
   51.425000  354.516667     54.642
   51.425000  354.550000     54.632
   51.400000  354.483333     54.636
   51.400000  354.516667     54.625
   51.400000  354.550000     54.614
"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)

    ds = gdal.Open('/vsimem/grid.xyz')
    assert ds.RasterXSize == 3 and ds.RasterYSize == 5
    got_gt = ds.GetGeoTransform()
    expected_gt = (354.46666625, 0.0333335, 0.0, 51.5125, 0.0, -0.025)
    cs = ds.GetRasterBand(1).Checksum()
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')

    for i in range(6):
        assert abs(got_gt[i] - expected_gt[i]) <= 1e-8

    assert cs == 146

###############################################################################
# Test particular case of XYZ file with missed samples (#6934)


def test_xyz_8():

    content = """0 500 50
750 500 100
500 750 150
750 750 200

"""
    gdal.FileFromMemBuffer('/vsimem/grid.xyz', content)

    ds = gdal.Open('/vsimem/grid.xyz')
    assert ds.RasterXSize == 4 and ds.RasterYSize == 2
    cs = ds.GetRasterBand(1).Checksum()
    ds = None
    gdal.Unlink('/vsimem/grid.xyz')

    assert cs == 35

###############################################################################
# Test case of XYZ file with header file with 3 columns not named X Y Z, and quoted


def test_xyz_9():

    content = """"A"    "B"     "C"
0 0 50
10 0 100
0 10 150
10 10 200
"""

    with gdaltest.tempfile('/vsimem/grid.xyz', content):
        ds = gdal.Open('/vsimem/grid.xyz')
        assert ds.RasterXSize == 2 and ds.RasterYSize == 2
        cs = ds.GetRasterBand(1).Checksum()

    assert cs == 22

###############################################################################
# Cleanup

def test_xyz_cleanup():

    pass


