 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andy Guest
|
Posted: Sun Oct 26, 2003 11:05 am Post subject: parsing / assignment assistance |
|
|
I have an assignment to read in a text file containing longitude and
latitude and convert to X,Y coordinates using the following formulas:
y = (latitude ' - 25 ) * 20 / 3 + latitude " * 11/100
x = 100 - ( (longitude '- 70 ) * 20 / 3 + longitude " * 11/100 )
25' 00" 70' 00"
25' 00" 85' 00"
40' 00" 85' 00"
40' 00" 70' 00"
30' 00" 80' 00"
32' 30" 77' 30"
How do I read in the latitude degree/minutes and the longitude
degree/minutes and assign them so they can be used in the conversion
formula?
What's the best way to parse the file and assign the degree/minutes
appropriately?
Any point in the right direction would be greatly appreciated.
Thanks,
Andy...
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Aniket Kulkarni Guest
|
Posted: Tue Oct 28, 2003 2:18 am Post subject: Re: parsing / assignment assistance |
|
|
Hi Andy,
Using the istream extraction operator>> for long datatype this can be
achieved.
e.g:
/*
* Lets use this structure 'LL' to represent either of longitude and
* latitude. The degrees and minutes (Hopefully ' is deg and " is min,
* but I am not sure) are represented by deg and min respectively
*/
typedef struct longitude_latitude {
longitude_latitude( int d=0, int m=0 ) : deg(d), min(m) {}
long deg, min;
}LL;
/*
* The data is a pair of 2 LL structures, one for longitude, one for
* latitude and the storage would be a vector of such pairs
*/
typedef std::pair<LL, LL> DATA;
typedef std::vector<DATA> VEC;
/*
* The extraction operator, that will parse one line of the file
* It assumes the format shown above, and reads the long, and ingnores
* the following single/double qoutes and goes on to the next
*/
std::istream& operator>> (std::istream& in, DATA& l )
{
char quotes[3];
in >> l.first.deg; in >> quotes;
in >> l.first.min; in >> quotes;
in >> l.second.deg; in >> quotes;
in >> l.second.min; in >> quotes;
return in;
}
/*
* Thus for parsing the entire file, the following code would do
*/
ifstream in( "parse.txt" );
DATA l; VEC v;
while (in >> l) v.push_back( l ) ;
Now that the vector "v" has the data nicely parsed, we can transform
the data using the std::transform
/*
* Transform one DATA from the vector
*/
inline DATA formula( const DATA& l )
{
return DATA(
100 - ((l.first.deg - 70 ) * 20 / 3+l.first.min * 11/100), // x
(l.second.deg - 25) * 20 / 3 + l.second.min * 11/100 ); // y
}
/*
* Apply transformation.
* This overwrites vector v, and it now contains the X,Y coordinates.
* The X coordinate is v[0].first.deg and Y coordinate is
* v[0].second.deg
*/
std::transform( v.begin(), v.end(), v.begin(), formula );
for (VEC::iterator i = v.begin(); i != v.end() ; i++ )
std::cout << "X: " << (*i).first.deg
<< " Y: " << (*i).second.deg << "n";
In the example you have mentioned, this prints
X: 400 Y: 300
X: 400 Y: 400
X: 300 Y: 400
X: 300 Y: 300
X: 366 Y: 366
X: 350 Y: 349
HTH
~ aniket
| Quote: | What's the best way to parse the file and assign the degree/minutes
appropriately?
Any point in the right direction would be greatly appreciated.
Thanks,
Andy...
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Werner Salomon Guest
|
Posted: Tue Oct 28, 2003 6:42 pm Post subject: Re: parsing / assignment assistance |
|
|
[email]anaylor (AT) nc (DOT) rr.com[/email] (Andy) wrote in message news:<cc436276.0310252153.411320d1 (AT) posting (DOT) google.com>...
| Quote: | I have an assignment to read in a text file containing longitude and
latitude and convert to X,Y coordinates using the following formulas:
y = (latitude ' - 25 ) * 20 / 3 + latitude " * 11/100
x = 100 - ( (longitude '- 70 ) * 20 / 3 + longitude " * 11/100 )
|
Hi Andy,
in a minute are 60 seconds, so the values for x,y should be the same,
if You set latitude' to 1 or set latitude" to 60.
But the result is dy/d(minute) = 20/3 on the one side and
dy/d(minute)=660/100 on the other side. That is similar, but not the
same!
First thing is - longitude and latitude are angles, so think about
angle as a value. I assume x and y are unit length. miles, kilometers
or inches.
Then try to change the formulas in a linear form - like this:
x = fx * longitude + x0
y = fy * latitude + y0
Have a look at the units - angle in [degree] (or radian?) and x,y in
?? I select degree for the angle, so I set
fx=fy= 60 (minutes in a degree) * 20 / 3 = 400 (or 3600*11/100 = 396?)
and x0 = -25 * 20 / 3 = -500/3
and y0 = 100 + 70 * 20 / 3 = 1700/3
| Quote: | 25' 00" 70' 00"
25' 00" 85' 00"
40' 00" 85' 00"
40' 00" 70' 00"
30' 00" 80' 00"
32' 30" 77' 30"
How do I read in the latitude degree/minutes and the longitude
degree/minutes ..
I assume minutes/seconds or degree/minutes/seconds |
| Quote: | .. and assign them so they can be used in the conversion
formula?
What's the best way to parse the file and assign the degree/minutes
appropriately?
Ok - think about an angle and make an angle class |
Angle longitude, latitude;
open a file (std::fstream) and read the angles from the stream
fstream file("Filename");
file >> longitude >> latitude;
to do this, it is necessary to have a operator>> -function with Angle
as second parameter. To handle the unit character (' or ") it is nice
to have a class like AngleUnit to do this.
The code could look like this:
// ----- 8< ----
#include
#include <sstream>
class AngleUnit {
public:
AngleUnit () : m_factor(1) {} // unit := degree
double toDegree( int x ) const {
return double(x) / m_factor;
}
friend std::istream& operator>>( std::istream& in,
AngleUnit& x ) {
char c;
if( in.get( c ) ) { // unformatted input
switch( c ) {
case '°': // degree
x.m_factor = 1;
break;
case ''': // minutes
x.m_factor = 60;
break;
case '"': // seconds
x.m_factor = 3600;
break;
default:
in.setstate( std::ios_base::failbit );
break;
}
}
return in;
}
bool isSeconds() const { return m_factor == 3600; }
private:
int m_factor;
};
class Angle {
public:
Angle() : m_degree( 0.0 ) {}
double Degree() const { return m_degree; }
friend std::istream& operator>>( std::istream& in, Angle& x ) {
double a = 0.0; // the angle
AngleUnit unit;
do {
int x;
if( in >> x >> unit )
a += unit.toDegree( x );
else
return in; // reading fails
} while( !unit.isSeconds() );
// Seconds MUST be the last one
x.m_degree = a;
return in;
}
private:
double m_degree;
};
int main() { // shows the use
using namespace std;
stringstream file( "25' 00" 1° 70' 30"" );
Angle longitude, latitude;
if( file >> longitude >> latitude )
{
// reading was ok
// y = (latitude ' - 25 ) * 20 / 3 + latitude " * 11/100
// x = 100 - ( (longitude '- 70 ) * 20 / 3 + longitude " * 11/100 )
double x = longitude.Degree() * 400. + (-500./3);
double y = latitude.Degree() * 400. + (1700./3);
}
return 0;
}
// ----- 8< ----
next step could be, to make a class Coordinate which can be read from
two angles and to calculate with like the pair (x,y). But that is
another thread ...
Greetings
Werner
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|