/* -*- coding: utf-8 -*- */
/**
\ingroup geom
@{
\file dpeuckera.h
\brief Declaración de elementos y funciones auxiliares para el uso de la familia
       de algoritmos de Douglas-Peucker.
\author José Luis García Pallero, jgpallero@gmail.com
\date 18 de agosto de 2013
\copyright
Copyright (c) 2013-2014, José Luis García Pallero. All rights reserved.
\par
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
\par
- Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.
- Neither the name of the copyright holders nor the names of its contributors
  may be used to endorse or promote products derived from this software without
  specific prior written permission.
\par
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/******************************************************************************/
/******************************************************************************/
#ifndef _DPEUCKERA_H_
#define _DPEUCKERA_H_
/******************************************************************************/
/******************************************************************************/
#include<math.h>
#include"libgeoc/arco.h"
#include"libgeoc/errores.h"
#include"libgeoc/ptopol.h"
/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_DPEUCKER_BUFFER_PTOS
\brief Número de puntos para ir asignando memoria en bloques para el vector de
       salida de las funciones de aligerado de polilíneas.
\date 17 de agosto de 2013: Creación de la constante.
*/
#define GEOC_DPEUCKER_BUFFER_PTOS 1000
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_DPEUCKER_NO_INTERSEC
\brief Identificador de que dos segmentos o arcos no se cortan.
\date 18 de agosto de 2013: Creación de la constante.
*/
#define GEOC_DPEUCKER_NO_INTERSEC 0
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_DP_RECT_DISJ
\brief Comprueba si dos rectángulos son disjuntos.
\param[in] esf Identificador de trabajo sobre la superficie de la esfera. Dos
           posibilidades:
           - 0: No se trabaja sobre la superficie de la esfere, sino en el
             plano.
           - Distinto de 0: Se trabaja sobre la superficie de la esfera de radio
             unidad.
\param[in] tol Tolerancia angular, en radianes. Indica el valor por debajo del
           cual dos ángulos se consideran iguales. Este argumento ha de ser un
           número \b POSITIVO (no se comprueba internamente).
\param[in] xMin1 Coordenada X o longitud, en radianes, mínima del rectángulo 1.
\param[in] xMax1 Coordenada X o longitud, en radianes, máxima del rectángulo 1.
\param[in] yMin1 Coordenada Y o latitud, en radianes, mínima del rectángulo 1.
\param[in] yMax1 Coordenada Y o latitud, en radianes, máxima del rectángulo 1.
\param[in] xMin2 Coordenada X o longitud, en radianes, mínima del rectángulo 2.
\param[in] xMax2 Coordenada X o longitud, en radianes, máxima del rectángulo 2.
\param[in] yMin2 Coordenada Y o latitud, en radianes, mínima del rectángulo 2.
\param[in] yMax2 Coordenada Y o latitud, en radianes, máxima del rectángulo 2.
\return Dos posibilidades:
        - 0: Los rectángulos no son disjuntos, es decir, tienen alguna parte
             común (se cortan o se tocan) o uno está completamente contenido en
             el otro.
        - Distinto de 0: Los rectángulos son disjuntos.
\note Esta función asume que \em xMin1<xMax1, \em yMin1<yMax1, \em xMin2<xMax2 e
      \em yMin2<yMax2.
\note Si se trabaja sobre la esfera, esta macro utiliza internamente la función
      \ref ArcosCircMaxDisjuntos, mientras que si estamos en el plano se usa la
      macro \ref GEOC_RECT_DISJUNTOS.
\date 18 de agosto de 2013: Creación de la macro.
\date 23 de septiembre de 2013: Adición del argumento \em tol.
\todo Esta macro no está probada.
*/
#define GEOC_DP_RECT_DISJ(esf,tol, \
                          xMin1,xMax1,yMin1,yMax1,xMin2,xMax2,yMin2,yMax2)     \
((esf)                                                                         \
? (ArcosCircMaxDisjuntos(tol,xMin1,xMax1,xMin2,xMax2))                         \
: (GEOC_RECT_DISJUNTOS(xMin1,xMax1,yMin1,yMax1,xMin2,xMax2,yMin2,yMax2)))
/******************************************************************************/
/******************************************************************************/
/** \enum GEOC_DPEUCKER_ROBUSTO
\brief Aplicación o no del algoritmo robusto de aligerado de polilíneas.
\date 10 de julio de 2011: Creación del tipo.
\date 24 de mayo de 2011: Adición del la opción \em GeocDPeuckerOriginal.
*/
enum GEOC_DPEUCKER_ROBUSTO
{
    /** \brief Se usa el algoritmo original de Douglas-Peucker (no robusto). */
    GeocDPeuckerOriginal=111,
    /** \brief \b *NO* se realiza aligerado robusto (con mi algoritmo). */
    GeocDPeuckerRobNo=112,
    /** \brief \b *SÍ* se realiza aligerado robusto. */
    GeocDPeuckerRobSi=113,
    /** \brief Aligerado semi robusto con
        \ref DouglasPeuckerRobIntersecOrigPlano y
        \ref DouglasPeuckerRobIntersecOrigEsfera. */
    GeocDPeuckerRobOrig=114,
    /** \brief Aligerado semi robusto con
        \ref DouglasPeuckerRobAutoIntersecPlano y
        \ref DouglasPeuckerRobAutoIntersecEsfera. */
    GeocDPeuckerRobAuto=115
};
/******************************************************************************/
/******************************************************************************/
/**
\brief Comprueba algunos casos especiales antes del aligerado de vértices de una
       polilínea.
\param[in] x Vector que contiene las coordenadas X o las longitudes de los
           vértices de la polilínea de trabajo.
\param[in] y Vector que contiene las coordenadas Y o las latitudes de los
           vértices de la polilínea de trabajo.
\param[in] nPtos Número de elementos de los vectores \em x e \em y.
\param[in] incX Posiciones de separación entre los elementos del vector \em x.
           Este argumento siempre ha de ser un número positivo.
\param[in] incY Posiciones de separación entre los elementos del vector \em y.
           Este argumento siempre ha de ser un número positivo.
\param[in] tol Tolerancia para eliminar vértices. Este argumento sólo se tiene
           internamente en cuenta si vale 0.0.
\param[out] nPtosSal Número de puntos de la polilínea aligerada, si se ha
            encontrado algún caso especial.
\param[out] hayCasoEspecial Identificador de caso especial. Dos posibilidades:
            - 0: No se ha encontrado ningún caso especial.
            - Distinto de 0: Sí se ha encontrado algún caso especial.
\return Vector de \em nPtosSal elementos que contiene los índices en los
        vectores \em x e \em y de los vértices que formarán la polilínea
        aligerada, en el caso de que se haya encontrado algún caso especial. Si
        ocurre algún error de asignación de memoria se devuelve el valor
        \p NULL. Este argumento sólo tiene sentido si se ha devuelto un valor de
        \em hayCasoEspecial distinto de 0.
\note Esta función no comprueba si el número de elementos de los vectores \em x
      e \em y es congruente con el valor pasado en \em nPtos.
\note Esta función asume que \em nPtos es mayor que 0. En caso contrario,
      devuelve \p NULL, por lo que un valor de retorno igual a \p NULL sólo es
      indicativo de error cuando \em nPtos es mayor que 0.
\note Esta función comprueba los siguientes casos especiales:
      - Si sólo hay un punto de entrada: En este caso, \em nPtosSal vale 1 y el
        vector de salida contiene la posición de ese único punto.
      - Si hay dos puntos de entrada, y estos son el mismo: En este caso,
        \em nPtosSal vale 1 y el vector de salida contiene la posición
        únicamente del primero de ellos.
      - Si hay dos puntos de entrada, y estos son distintos: En este caso,
        \em nPtosSal vale 2 y el vector de salida contiene la posición de los
        dos puntos, aunque la distancia entre ellos sea menor que \em tol.
      - Si hay tres puntos de entrada, y el primero es el mismo que el tercero:
        En este caso, \em nPtosSal vale 2 y el vector de salida contiene la
        posición de los dos primeros.
        - En el caso en que el segundo punto también sea igual al primero,
          \em nPtosSal vale 1 y el vector de salida contiene la posición
          únicamente del primero.
      - Si \em tol vale 0.0: En este caso, se eliminan los posibles puntos
        repetidos en los vectores de coordenadas de entrada.
\date 08 de agosto de 2013: Creación de la función.
\todo Esta función todavía no está probada.
*/
size_t* CasosEspecialesAligeraPolilinea(const double* x,
                                        const double* y,
                                        const size_t nPtos,
                                        const size_t incX,
                                        const size_t incY,
                                        const double tol,
                                        size_t* nPtosSal,
                                        int* hayCasoEspecial);
/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
}
#endif
/******************************************************************************/
/******************************************************************************/
#endif
/******************************************************************************/
/******************************************************************************/
/** @} */
/******************************************************************************/
/******************************************************************************/
/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
/* kate: backspace-indents on; show-tabs on; */
/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
