    /*******************************************************************************
    * CRU CL 2.0 Data Extraction Routines  - retrieves site based readings from 10'x10'
    * Global climate data set available at http://www.cru.uea.ac.uk/cru/data/hrg.htm
    * Date   : 22/5/05
    * Copyright (C) 2005 Daniel Falster
    *
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License
    * as published by the Free Software Foundation; either version 2
    * of the License, or (at your option) any later version.
    * 
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * GNU General Public License for more details.
    * 
    * The GNU General Public License can be viewed at http://www.gnu.org/copyleft/gpl.html
    * or obtained from the Free Software Foundation, 
    * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
    *
    * Contact details: Daniel Falster, dfalster@bio.mq.edu.au
    * ARC-NZ Research Network for vegetation Function
    * Dept Biological Sciences, Macquarie University 2109, Australia
    * http://www.bio.mq.edu.au/ecology/vegfunction/
    ***********************************************************************************/

#include <stdio.h>
#include <iostream>
#include <math.h>
#include <vector>
#include <string>
#include <fstream>
using namespace std;

float StrToFloat(string one);
string read(ifstream& File, char stop);
string read_no(ifstream& File, int length);
double distance(double x1, double y1, double x2, double y2);

struct site_data{string locality; float lat; float lon;  int row; double dist; string data;}; //data to hold site data

int main(int argc, char *argv[])
 {
 long int i,j,s;  string line; double dist;
 
 //Open data files
 cout<<"Enter climate data filename: ";  cin >>line;   
 ifstream inFile(line.c_str());    if(!inFile){cerr<<"File "<<line<<" no opened"<<endl; system("pause"); exit(EXIT_FAILURE);}
 
// open output file
 cout<<"Enter Output file name: ";   cin >>line; 
 ofstream outFile( line.c_str());  if(!outFile) {cerr<<"OUTFile not opened"<<endl;system("pause"); exit(EXIT_FAILURE);}

//open lat lon file
 cout<< "Enter lat-lon list filename: ";  cin >> line;
 ifstream latlonFile(line.c_str());  if(!latlonFile) {cerr<<"File not opened"<<endl;system("pause"); exit(EXIT_FAILURE);}
 getline(latlonFile,line); //get rid of title line

//Read in site data
vector<site_data> sites;    site_data site;
while ((latlonFile >> ws) && (! latlonFile.eof()) )
      {latlonFile >> site.locality >> site.lat >> site.lon; site.dist=1000000.0;
      sites.push_back(site);}
//PRINT sites to screen: 
cout<<"Sites\n";for(i=0; i<sites.size(); i++) cout<<sites[i].locality<<" "<<sites[i].lat<<"  "<<sites[i].lon<<endl;

//Read climate data
cout<<"\n\nPlease wait.........searching climate data "<<endl;
vector<double> lat, lon;   vector<string> data;   // vectors hold file info for seraching
while(!inFile.eof())
    {lat.push_back(StrToFloat(read_no(inFile, 9)));
    lon.push_back(StrToFloat(read_no(inFile, 9)));
    data.push_back(read(inFile, '\n'));}

//Find closest location for each site
for(j=0; j<lat.size(); j++)     
    for(s=0; s<sites.size(); s++)
        {dist= distance(lat[j],lon[j], sites[s].lat,sites[s].lon);   //calvulate distance from location and record minimum
        if(dist<sites[s].dist){sites[s].dist = dist; sites[s].row = j;}}
  
//Print data to file
outFile<<"Location\tLat\tLon\tRef_lat\tRef_lon\tData"<<endl;
for(s=0; s<sites.size(); s++) 
  {outFile<<sites[s].locality<<"\t"<<sites[s].lat<<"\t"<<sites[s].lon<<"\t"<<lat[sites[s].row]<<"\t"<<lon[sites[s].row];
  //Print data string in tab delim format, ignoring white spaces
  line=data[sites[s].row];
  for(i=0; i<line.size(); i++)
    {if(line[i]!=' ') outFile<<line[i];
     else {outFile<<"\t";  while(line[i+1]==' ') i++;}
    }         
  outFile<<endl;}

inFile.close(); outFile.close(); latlonFile.close();
cout<<"Finished! Goobye.......\n"<<endl;
return 1;
}

//Calculates Euclidean distance between pairs of points
double distance(double x1, double y1, double x2, double y2)
    {return sqrt(pow(x1-x2,2)+pow(y1-y2,2));}

//converts a string to floating point number, ignores white spaces
float StrToFloat(string one)
    {char temp[12]; int i, w=0;
    for(i=0; i<one.length(); i++)
             if(one[i]!=' ') temp[i-w]=one[i];  else w++;
    temp[i]='\0';
    return atof(temp);}

//scans a sequence from file until stop character is reached
string read(ifstream& File, char stop)
    {string temp;
    char ch=File.get();
    while(!File.eof() && ch!=stop)
        {temp+=ch; ch=File.get();}
    return temp+'\0';}

//scans a sequence of given length from file
string read_no(ifstream& File, int length)
    {string temp;
    for(int i=0; i<length; i++)
        temp+=File.get();
    return temp+='\0';}

