
/****************************************************************************
 *
 * MODULE:       d.where
 * AUTHOR(S):    James Westervelt and Michael Shapiro (CERL) 
                  (original contributors)
 *               Bernhard Reiter <bernhard intevation.de>, 
 *               Markus Neteler <neteler itc.it>,
 *               Eric G. Miller <egm2 jps.net>, 
 *               Glynn Clements <glynn gclements.plus.com>, 
 *               Hamish Bowman <hamish_b yahoo.com>, 
 *               Jan-Oliver Wagner <jan intevation.de>, 
 *               Paul Kelly <paul-grass stjohnspoint.co.uk>
 * PURPOSE:      interactive query of location in active display
 * COPYRIGHT:    (C) 1999-2006 by the GRASS Development Team
 *
 *               This program is free software under the GNU General Public
 *               License (>=v2). Read the file COPYING that comes with GRASS
 *               for details.
 *
 *****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/gprojects.h>
#include <grass/display.h>
#include "local_proto.h"
#include <grass/glocale.h>

struct pj_info iproj, oproj, tproj;

int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *coords, *file;
    struct Flag *decimal, *latlong, *wgs84, *dcoord;
    int have_spheroid = 0;
    FILE *fp;

    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("sampling"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    module->description =
	_("Identifies the geographic coordinates associated with "
	  "point locations given in display coordinates.");

    coords = G_define_option();
    coords->key = "at";
    coords->key_desc = "x,y";
    coords->type = TYPE_DOUBLE;
    coords->required = NO;
    coords->multiple = YES;
    coords->description =
	_("Display coordinates to convert");

    file = G_define_standard_option(G_OPT_F_INPUT);
    file->required = NO;
    file->description =
	_("File from which to read coordinates (\"-\" to read from stdin)");

    decimal = G_define_flag();
    decimal->key = 'd';
    decimal->description = _("Output lat/long in decimal degree");

    latlong = G_define_flag();
    latlong->key = 'l';
    latlong->description =
	_("Output lat/long referenced to current ellipsoid");

    wgs84 = G_define_flag();
    wgs84->key = 'w';
    wgs84->description =
	_("Output lat/long referenced to WGS84 ellipsoid using datum "
	  "transformation parameters defined in current location (if available)");

    dcoord = G_define_flag();
    dcoord->key = 'f';
    dcoord->description =
	_("Output frame coordinates of current display monitor (percentage)");


    /* if (G_parser(argc,argv)) */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (latlong->answer && wgs84->answer)
	G_fatal_error(_("Ambiguous request for lat/long ellipsoids"));

    if (decimal->answer && !(latlong->answer || wgs84->answer))
	G_fatal_error(_("Please specify a lat/long ellipsoid with -l or -w"));

    if (((G_projection() == PROJECTION_LL) && wgs84->answer) ||
	((G_projection() != PROJECTION_LL) &&
	 (latlong->answer || wgs84->answer)))
	have_spheroid = 1;

    if (have_spheroid == 1) {
	struct Key_Value *in_proj_info, *in_unit_info;

	/* read current projection info */
	if ((in_proj_info = G_get_projinfo()) == NULL)
	    G_fatal_error(_("Can't get projection info of current location"));

	if ((in_unit_info = G_get_projunits()) == NULL)
	    G_fatal_error(_("Can't get projection units of current location"));

	if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
	    G_fatal_error(_("Can't get projection key values of current location"));

	oproj.pj = NULL;

	if (wgs84->answer) {
	    struct Key_Value *out_proj_info, *out_unit_info;

	    out_proj_info = G_create_key_value();
	    out_unit_info = G_create_key_value();

	    /* set output projection to lat/long */
	    G_set_key_value("proj", "ll", out_proj_info);

	    /* Check that datumparams are defined for this location (otherwise
	     * the WGS84 values would be meaningless), and if they are set the 
	     * output datum to WGS84 */
#if PROJ_VERSION_MAJOR < 6
            char buff[100], dum[100];

	    /* PROJ6+ has its own datum transformation parameters */
	    if (G_get_datumparams_from_projinfo(in_proj_info, buff, dum) < 0)
		G_fatal_error(_("WGS84 output not possible as this location does not contain\n"
			       "datum transformation parameters. Try running g.setproj."));
	    else
#endif
		G_set_key_value("datum", "wgs84", out_proj_info);

	    G_set_key_value("unit", "degree", out_unit_info);
	    G_set_key_value("units", "degrees", out_unit_info);
	    G_set_key_value("meters", "1.0", out_unit_info);

	    if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0)
		G_fatal_error(_("Unable to set up lat/long projection parameters"));

	    G_free_key_value(out_proj_info);
	    G_free_key_value(out_unit_info);
	}
	/* else the latlong equivalent is generated by GPJ_init_transform() */

	G_free_key_value(in_proj_info);
	G_free_key_value(in_unit_info);

	tproj.def = NULL;

	if (GPJ_init_transform(&iproj, &oproj, &tproj) < 0)
	    G_fatal_error(_("Unable to initialize coordinate transformation"));
    }

    if (file->answer) {
	if (strcmp(file->answer, "-") == 0)
	    fp = stdin;
	else {
	    fp = fopen(file->answer, "r");
	    if (!fp)
		G_fatal_error(_("Unable to open input file <%s>"), file->answer);
	}
    }
    else
	fp = stdin;

    D_open_driver();

    D_setup(0);

    where_am_i(coords->answers, fp, have_spheroid, decimal->answer,
               dcoord->answer);
    
    D_close_driver();

    exit(EXIT_SUCCESS);
}
