public static byte[] GetBytesFromValue(decimal val, StCoordinatesSystem coordinatesSystem, StCoordType type)
        {
            if (type == StCoordType.M)
                throw new NotSupportedException("M Coordiante is not supported yet");

            bool isNegative = false;
            decimal valFromMin = val - coordinatesSystem.GetMin(type);
            if (valFromMin < 0)
            {
                // We have to encode a negative number
                isNegative = true;
                valFromMin = Math.Abs(valFromMin);
            }

            // Search how many bytes have to be encoded
            int maxIndex = coordinatesSystem.ByteFactors.Length - 1;
            while (maxIndex > 0 && valFromMin < coordinatesSystem.ByteFactors[maxIndex])
            {
                maxIndex--;
            }

            var bytes = new List<byte>();

            // Encode utlimate byte first
            decimal div = valFromMin / coordinatesSystem.ByteFactors[maxIndex];
            var byteValue = (byte)Math.Floor(div);
            decimal restVal = valFromMin - (byteValue * coordinatesSystem.ByteFactors[maxIndex]);
            bytes.Insert(0, byteValue);

            // Encode bytes from penultimate to first
            for (int i = maxIndex - 1; i >= 0; --i)
            {
                div = restVal / coordinatesSystem.ByteFactors[i];
                byteValue = (byte)Math.Floor(div);
                restVal -= byteValue * coordinatesSystem.ByteFactors[i];

                // byteValue cannot be < 128 (RestartValue)
                byteValue += coordinatesSystem.RestartValue;
                if (byteValue < coordinatesSystem.RestartValue || byteValue > 255)
                    throw new IndexOutOfRangeException();

                bytes.Insert(0, byteValue);
            }

            if (isNegative)
                SetNegative(bytes, coordinatesSystem);

            return bytes.ToArray();
        }
        /// <summary>
        /// Returns byte array from integer value
        /// </summary>
        /// <param name="val"></param>
        /// <param name="coordinatesSystem"></param>
        /// <returns></returns>
        public static byte[] GetBytesFromValue(int val, StCoordinatesSystem coordinatesSystem)
        {
            // Search how many bytes have to be encoded
            int maxIndex = coordinatesSystem.ByteFactors.Length - 1;
            long byteCoeff = 1;
            for (int i = 0; i < coordinatesSystem.ByteCoeff.Length; ++i)
            {
                byteCoeff *= coordinatesSystem.ByteCoeff[i];
            }

            while (maxIndex > 0 && val < byteCoeff)
            {
                byteCoeff /= coordinatesSystem.ByteCoeff[maxIndex];
                maxIndex--;
            }

            var bytes = new List<byte>();

            // Encode utlimate byte first
            decimal factor = coordinatesSystem.ByteFactors[maxIndex] / coordinatesSystem.Resolution;
            var byteValue = (byte)(val / factor);
            decimal restVal = val - (byteValue * factor);
            bytes.Insert(0, byteValue);

            // Encode bytes from penultimate to first
            for (int i = maxIndex - 1; i >= 0; --i)
            {
                factor = coordinatesSystem.ByteFactors[i] / coordinatesSystem.Resolution;
                byteValue = (byte)(restVal / factor);
                restVal -= byteValue * factor;

                // byteValue cannot be < 128 (RestartValue)
                byteValue += coordinatesSystem.RestartValue;
                if (byteValue < coordinatesSystem.RestartValue || byteValue > 255)
                    throw new IndexOutOfRangeException();

                bytes.Insert(0, byteValue);
            }

            if (val < 0)
                SetNegative(bytes, coordinatesSystem);

            return bytes.ToArray();
        }
        public static byte[] GetBytesFromDifference(byte[] initialBytes, byte[] previousBytes, StCoordinatesSystem coordinatesSystem, StCoordType type)
        {
            // Exemple : LINESTRING (-1 -1, 0 0)
            //  - initial bytes  : { 208 156 1 } ==> the value of the point is 0
            //                                       but the difference with the previous point is encoded => 1
            //  - previous bytes : { 176 139 197 186 141 17 } ==> this is the encoding for -1
            //

            // Here we get the value decoded from the bytes representing the difference
            decimal encodedDifference = GetValueFromBytes(initialBytes, coordinatesSystem, type);

            // Get The previous value
            decimal valuePrevious = GetValueFromBytes(previousBytes, coordinatesSystem, type);
            decimal encodedPrevious = valuePrevious - coordinatesSystem.GetMin(type);

            // Calculate new value
            decimal value = encodedPrevious + encodedDifference;

            return GetBytesFromValue(value, coordinatesSystem, type);
        }
        private static bool IsNegative(byte[] bytes, StCoordinatesSystem coordinatesSystem, out byte firstByteRealValue)
        {
            if (bytes.Length == 1)
            {
                // If there is only 1 encoding byte, then the value is negative if the value is bigger than coordinatesSystem.ByteCoeff[1]
                // Ex : 63 is positive ( = 63 )
                // but  65 is negative ( = -1 )
                if (bytes[0] >= coordinatesSystem.ByteCoeff[1])
                {
                    firstByteRealValue = (byte)(bytes[0] - coordinatesSystem.ByteCoeff[1]);
                    return true;
                }

                firstByteRealValue = bytes[0];
                return false;
            }

            // If there are many encoding bytes, then the value is negative if the value is bigger than coordinatesSystem.ByteCoeff[1] + RestartValue
            // Ex : 130 is positive ( = 2 )
            // but  193 is negative ( = -1 )
            int negativeValue = coordinatesSystem.ByteCoeff[1] + coordinatesSystem.RestartValue;
            if (bytes[0] >= negativeValue)
            {
                firstByteRealValue = (byte)(bytes[0] - negativeValue);
                return true;
            }

            firstByteRealValue = (byte)(bytes[0] - coordinatesSystem.RestartValue);
            return false;
        }
        public static void SetNegative(List<byte> bytes, StCoordinatesSystem coordinatesSystem)
        {
            if (bytes.Count == 1)
            {
                // If there is only 1 encoding byte, then the value is negative if the value is bigger than coordinatesSystem.ByteCoeff[1]
                // We can only encode this if the value of the first byte is < coordinatesSystem.ByteCoeff[1], otherwise we have a problem
                if (bytes[0] > coordinatesSystem.ByteCoeff[1])
                    throw new ArgumentException();

                bytes[0] += coordinatesSystem.ByteCoeff[1];
            }
            else
            {
                // If there are many encoding bytes, then the value is negative if the value is bigger than coordinatesSystem.ByteCoeff[1] + RestartValue
                // We can only encode this if : coordinatesSystem.RestartValue < first byte < coordinatesSystem.RestartValue + coordinatesSystem.ByteCoeff[1], otherwise we have a problem
                if (bytes[0] < coordinatesSystem.RestartValue || bytes[0] > coordinatesSystem.RestartValue + coordinatesSystem.ByteCoeff[1])
                    throw new ArgumentException();

                bytes[0] += coordinatesSystem.ByteCoeff[1];
            }
        }
        public static decimal GetValueFromBytes(byte[] bytes, StCoordinatesSystem coordinatesSystem, StCoordType type)
        {
            if (type == StCoordType.M)
                throw new NotSupportedException("M-Coordinates are not supported yet");

            decimal val = 0;

            // The first byte will give the sign
            byte b;
            bool isNegative = IsNegative(bytes, coordinatesSystem, out b);
            val += b * coordinatesSystem.ByteFactors[0];

            // Next bytes
            for (int i = 1; i < bytes.Length; ++i)
            {
                b = bytes[i];
                if (b >= coordinatesSystem.ByteCoeff[i + 1])
                    b = (byte)(b - coordinatesSystem.RestartValue);
                val += b * coordinatesSystem.ByteFactors[i];
            }

            if (isNegative)
                return coordinatesSystem.GetMin(type) - val;

            return val + coordinatesSystem.GetMin(type);
        }
        public static byte[] GetDifferenceFromBytes(byte[] initialBytes, byte[] previousBytes, StCoordinatesSystem coordinatesSystem, StCoordType type)
        {
            // We mut encode the difference with the previous coordinate instead of the real value
            decimal initialRealValue = GetValueFromBytes(initialBytes, coordinatesSystem, type);

            // Get The previous value
            decimal previousValue = GetValueFromBytes(previousBytes, coordinatesSystem, type);

            // Get the difference
            decimal difference = initialRealValue - previousValue;

            // Get the value to encode
            decimal valueToEncode = coordinatesSystem.GetMin(type) + difference;

            return GetBytesFromValue(valueToEncode, coordinatesSystem, type);
        }