I've asked this once before without my understanding what to do but I thought that I would try again. Someone has written a routine in C Sharp which is used as a library for the Android RAD Basic4android: I have successfully used this library with a Basic4android app that I have written. I would like to be able to use this library in Gambas. Is this possible with just a small amount of changes to the code (which I have attached)? If so, could someone give me the steps (which must be easy as I have no knowledge of C or how to 'integrate' a C 'program' into a Gambas app?
//version: 1.2
/***********************************************************************
*                               GPStoOSGB                              *
*  http://www.codeproject.com/KB/cs/NMEAtoOSG.aspx                     * 
*  A class to generate Ordinance Survey Grid References                *
*  Lat, Lon from a GPS based on the WGS84 elipsoid                     *
*        calculations were derived (i.e. copied) from the work of      *
*               Roger Muggleton (http://www.carabus.co.uk/)            *
***********************************************************************/

using System;

namespace GPS
{

    public class GPStoOSGB
    {
        private static double deg2rad = Math.PI / 180;
        private static double rad2deg = 180.0 / Math.PI;
        private double deciAlt;
        private double deciLat;
        private double deciLon;
        private double easting;
        private double northing;


        // constructor
        public GPStoOSGB()
        {
        }

        // convert Northing and Easting to NGR
        public String NEtoNGR(double easting, double northing)
        {
            return NE2NGR(easting, northing);
        }

        // converts OS national grid reference to OSGB36 lat and long
        // also converts to Northing and Easting
        public String NGRtoOSGB36(String ngr) 
        {
            ngr = ngr.Replace(" ", "");
            if (ngr.Length > 12 || ngr.Length <= 4 || ngr.Length % 2 != 0
                || !Char.IsLetter(ngr[0]) || !Char.IsLetter(ngr[1]))
                throw new Exception("Invalid grid reference");
            int digits = (ngr.Length -2) / 2 ;
            double metres = Math.Pow(10, 5 - digits);
            double north = double.Parse(ngr.Substring(2 + digits, digits)) * metres;
            double east = double.Parse(ngr.Substring(2, digits)) * metres;

            double t1 = Char.ToUpper(ngr[0]) - 65;
            if (t1 > 8)
                t1 = t1 - 1;
            double t2 = Math.Floor(t1 / 5);
            north = north + 500000 * (3 - t2);
            east = east + 500000 * (t1 - 5 * t2 - 2);

            t1 = Char.ToUpper(ngr[1]) - 65;
            if (t1 > 8)
                t1 = t1 - 1;
            t2 = Math.Floor(t1 / 5);
            north = north + 100000 * (4 - t2);
            east = east + 100000 * (t1 - 5 * t2);

            easting = east;
            northing = north;


             // converts NGR easting and nothing to lat, lon.
             // input metres, output radians
            double nX = north;
            double eX = east;
            double a = 6377563.396;       // OSGB semi-major
            double b = 6356256.91;        // OSGB semi-minor
            double e0 = 400000;           // OSGB easting of false origin
            double n0 = -100000;          // OSGB northing of false origin
            double f0 = 0.9996012717;     // OSGB scale factor on central meridian
            double e2 = 0.0066705397616;  // OSGB eccentricity squared
            double lam0 = -0.034906585039886591;  // OSGB false east
            double phi0 = 0.85521133347722145;    // OSGB false north
            double af0 = a * f0;
            double bf0 = b * f0;
            double n = (af0 - bf0) / (af0 + bf0);
            double Et = east - e0;
            double phid = InitialLat(north, n0, af0, phi0, n, bf0);
            double nu = af0 / (Math.Sqrt(1 - (e2 * (Math.Sin(phid) * Math.Sin(phid)))));
            double rho = (nu * (1 - e2)) / (1 - (e2 * (Math.Sin(phid)) * (Math.Sin(phid))));
            double eta2 = (nu / rho) - 1;
            double tlat2 = Math.Tan(phid) * Math.Tan(phid);
            double tlat4 = Math.Pow(Math.Tan(phid), 4);
            double tlat6 = Math.Pow(Math.Tan(phid), 6);
            double clatm1 = Math.Pow(Math.Cos(phid), -1);
            double VII = Math.Tan(phid) / (2 * rho * nu);
            double VIII = (Math.Tan(phid) / (24 * rho * (nu * nu * nu))) * (5 + (3 * tlat2) + eta2 - (9 * eta2 * tlat2));
            double IX = ((Math.Tan(phid)) / (720 * rho * Math.Pow(nu, 5))) * (61 + (90 * tlat2) + (45 * Math.Pow(Math.Tan(phid), 4) ));
            double phip = (phid - ((Et * Et) * VII) + (Math.Pow(Et, 4) * VIII) - (Math.Pow(Et, 6) * IX)); 
            double X = Math.Pow(Math.Cos(phid), -1) / nu;
            double XI = (clatm1 / (6 * (nu * nu * nu))) * ((nu / rho) + (2 * (tlat2)));
            double XII = (clatm1 / (120 * Math.Pow(nu, 5))) * (5 + (28 * tlat2) + (24 * tlat4));
            double XIIA = clatm1 / (5040 * Math.Pow(nu, 7)) * (61 + (662 * tlat2) + (1320 * tlat4) + (720 * tlat6));
            double lambdap = (lam0 + (Et * X) - ((Et * Et * Et) * XI) + (Math.Pow(Et, 5) * XII) - (Math.Pow(Et, 7) * XIIA));
            phip = phip * rad2deg;
            lambdap = lambdap * rad2deg;
            deciLat = phip;
            deciLon = lambdap;
            return phip.ToString() + ',' + lambdap.ToString();;
        } 

        // converts OSGB36/ODN lat,long and alt to WGS84 with S and W as -ve
        public String OSGB36toWGS84(double OSGBlat, double OSGBlong, double OSGBalt)
        {
            //first off convert to radians
            double radWGlat = OSGBlat * deg2rad;
            double radWGlon = OSGBlong * deg2rad;

            /* these calculations were derived from the work of
             * Roger Muggleton (http://www.carabus.co.uk/) */

            /* quoting Roger Muggleton :-
             * There are many ways to convert data from one system to another, the most accurate 
             * being the most complex! For this example I shall use a 7 parameter Helmert 
             * transformation.
             * The process is in three parts: 
             * (1) Convert latitude and longitude to Cartesian coordinates (these also include height 
             * data, and have three parameters, X, Y and Z). 
             * (2) Transform to the new system by applying the 7 parameters and using a little maths.
             * (3) Convert back to latitude and longitude.
             * For the example we shall transform a GRS80 location to Airy, e.g. a GPS reading to 
             * the Airy spheroid.
             * The following code converts latitude and longitude to Cartesian coordinates. The 
             * input parameters are: WGS84 latitude and longitude, axis is the GRS80/WGS84 major 
             * axis in metres, ecc is the eccentricity, and height is the height above the 
             *  ellipsoid.
             *  v = axis / (Math.sqrt (1 - ecc * (Math.pow (Math.sin(lat), 2))));
             *  x = (v + height) * Math.cos(lat) * Math.cos(lon);
             * y = (v + height) * Math.cos(lat) * Math.sin(lon);
             * z = ((1 - ecc) * v + height) * Math.sin(lat);
             * The transformation requires the 7 parameters: xp, yp and zp correct the coordinate 
             * origin, xr, yr and zr correct the orientation of the axes, and sf deals with the 
             * changing scale factors. */

            //these are the values for OSGB36(Airy)/ODN to WGS86(GRS80)  
            double a2 = 6378137;              // WGS84_AXIS
            double e2 = 0.00669438037928458;  // WGS84_ECCENTRIC
            double h = OSGBalt;               // height above datum  (from GPS GGA sentence)
            double a = 6377563.396;         //OSGB_AXIS
            double e = 0.0066705397616;     // OSGB_ECCENTRIC 
            double xp = 446.448;
            double yp = -125.157;
            double zp = 542.06;
            double xr = 0.1502;
            double yr = 0.247;
            double zr = 0.8421;
            double s = -20.4894;

            // convert to cartesian; lat, lon are radians
            double sf = s * 0.000001;
            double v = a / (Math.Sqrt(1 - (e * (Math.Sin(radWGlat) * Math.Sin(radWGlat)))));
            double x = (v + h) * Math.Cos(radWGlat) * Math.Cos(radWGlon);
            double y = (v + h) * Math.Cos(radWGlat) * Math.Sin(radWGlon);
            double z = ((1 - e) * v + h) * Math.Sin(radWGlat);

            // transform cartesian
            double xrot = (xr / 3600) * deg2rad;
            double yrot = (yr / 3600) * deg2rad;
            double zrot = (zr / 3600) * deg2rad;
            double hx = x + (x * sf) - (y * zrot) + (z * yrot) + xp;
            double hy = (x * zrot) + y + (y * sf) - (z * xrot) + yp;
            double hz = (-1 * x * yrot) + (y * xrot) + z + (z * sf) + zp;

            // Convert back to lat, lon
            double newLon = Math.Atan(hy / hx);
            double p = Math.Sqrt((hx * hx) + (hy * hy));
            double newLat = Math.Atan(hz / (p * (1 - e2)));
            v = a2 / (Math.Sqrt(1 - e2 * (Math.Sin(newLat) * Math.Sin(newLat))));
            double errvalue = 1.0;
            double lat0 = 0;
            while (errvalue > 0.001)
            {
                lat0 = Math.Atan((hz + e2 * v * Math.Sin(newLat)) / p);
                errvalue = Math.Abs(lat0 - newLat);
                newLat = lat0;
            }

            deciAlt = p / Math.Cos(lat0) - v;

            //convert back to degrees
            newLat = newLat * rad2deg;
            deciLat = newLat;
            newLon = newLon * rad2deg;
            deciLon = newLon;

            return deciLat.ToString() + ',' + deciLon.ToString();
        }

        //converts OSGB36 lat and long to OS national grid reference
        public String OSGB36toNGR(double OSGBlat, double OSGBlong)
        {
            deciLat = OSGBlat;
            deciLon = OSGBlong;
            double phi = OSGBlat * deg2rad;          // convert latitude to radians
            double lam = OSGBlong * deg2rad;          // convert longitude to radians
            double a = 6377563.396;              // OSGB semi-major axis
            double b = 6356256.91;               // OSGB semi-minor axis
            double e0 = 400000;                  // easting of false origin
            double n0 = -100000;                 // northing of false origin
            double f0 = 0.9996012717;            // OSGB scale factor on central meridian
            double e2 = 0.0066705397616;         // OSGB eccentricity squared
            double lam0 = -0.034906585039886591; // OSGB false east
            double phi0 = 0.85521133347722145;   // OSGB false north
            double af0 = a * f0;
            double bf0 = b * f0;

            // easting
            double slat2 = Math.Sin(phi) * Math.Sin(phi);
            double nu = af0 / (Math.Sqrt(1 - (e2 * (slat2))));
            double rho = (nu * (1 - e2)) / (1 - (e2 * slat2));
            double eta2 = (nu / rho) - 1;
            double p = lam - lam0;
            double IV = nu * Math.Cos(phi);
            double clat3 = Math.Pow(Math.Cos(phi), 3);
            double tlat2 = Math.Tan(phi) * Math.Tan(phi);
            double V = (nu / 6) * clat3 * ((nu / rho) - tlat2);
            double clat5 = Math.Pow(Math.Cos(phi), 5);
            double tlat4 = Math.Pow(Math.Tan(phi), 4);
            double VI = (nu / 120) * clat5 * ((5 - (18 * tlat2)) + tlat4 + (14 * eta2) - (58 * tlat2 * eta2));
            double east = e0 + (p * IV) + (Math.Pow(p, 3) * V) + (Math.Pow(p, 5) * VI);

            // northing
            double n = (af0 - bf0) / (af0 + bf0);
            double M = Marc(bf0, n, phi0, phi);
            double I = M + (n0);
            double II = (nu / 2) * Math.Sin(phi) * Math.Cos(phi);
            double III = ((nu / 24) * Math.Sin(phi) * Math.Pow(Math.Cos(phi), 3)) * (5 - Math.Pow(Math.Tan(phi), 2) + (9 * eta2));
            double IIIA = ((nu / 720) * Math.Sin(phi) * clat5) * (61 - (58 * tlat2) + tlat4);
            double north = I + ((p * p) * II) + (Math.Pow(p, 4) * III) + (Math.Pow(p, 6) * IIIA);

            // make whole number values
            east = Math.Round(east);   // round to whole number
            north = Math.Round(north); // round to whole number

            easting = east;
            northing = north;
            // convert to nat grid ref
             return NE2NGR(east, north);
        }

        // converts WGS84 lat, long and alt to OSGB36/ODN with S and W as -ve
        public String WGS84toOSGB36(double WGSlat, double WGSlong, double WGSalt)
        {
            //first off convert to radians
            double radWGlat = WGSlat * deg2rad;
            double radWGlon = WGSlong * deg2rad;

            /* these calculations were derived from the work of
             * Roger Muggleton (http://www.carabus.co.uk/) */

            /* quoting Roger Muggleton :-
             * There are many ways to convert data from one system to another, the most accurate 
             * being the most complex! For this example I shall use a 7 parameter Helmert 
             * transformation.
             * The process is in three parts: 
             * (1) Convert latitude and longitude to Cartesian coordinates (these also include height 
             * data, and have three parameters, X, Y and Z). 
             * (2) Transform to the new system by applying the 7 parameters and using a little maths.
             * (3) Convert back to latitude and longitude.
             * For the example we shall transform a GRS80 location to Airy, e.g. a GPS reading to 
             * the Airy spheroid.
             * The following code converts latitude and longitude to Cartesian coordinates. The 
             * input parameters are: WGS84 latitude and longitude, axis is the GRS80/WGS84 major 
             * axis in metres, ecc is the eccentricity, and height is the height above the 
             *  ellipsoid.
             *  v = axis / (Math.sqrt (1 - ecc * (Math.pow (Math.sin(lat), 2))));
             *  x = (v + height) * Math.cos(lat) * Math.cos(lon);
             * y = (v + height) * Math.cos(lat) * Math.sin(lon);
             * z = ((1 - ecc) * v + height) * Math.sin(lat);
             * The transformation requires the 7 parameters: xp, yp and zp correct the coordinate 
             * origin, xr, yr and zr correct the orientation of the axes, and sf deals with the 
             * changing scale factors. */

            //these are the values for WGS86(GRS80) to OSGB36(Airy)/ODN
            double a = 6378137;              // WGS84_AXIS
            double e = 0.00669438037928458;  // WGS84_ECCENTRIC
            double h = WGSalt;               // height above datum  (from GPS GGA sentence)
            double a2 = 6377563.396;         //OSGB_AXIS
            double e2 = 0.0066705397616;     // OSGB_ECCENTRIC 
            double xp = -446.448;
            double yp = 125.157;
            double zp = -542.06;
            double xr = -0.1502;
            double yr = -0.247;
            double zr = -0.8421;
            double s = 20.4894;

            // convert to cartesian; lat, lon are radians
            double sf = s * 0.000001;
            double v = a / (Math.Sqrt(1 - (e * (Math.Sin(radWGlat) * Math.Sin(radWGlat)))));
            double x = (v + h) * Math.Cos(radWGlat) * Math.Cos(radWGlon);
            double y = (v + h) * Math.Cos(radWGlat) * Math.Sin(radWGlon);
            double z = ((1 - e) * v + h) * Math.Sin(radWGlat);

            // transform cartesian
            double xrot = (xr / 3600) * deg2rad;
            double yrot = (yr / 3600) * deg2rad;
            double zrot = (zr / 3600) * deg2rad;
            double hx = x + (x * sf) - (y * zrot) + (z * yrot) + xp;
            double hy = (x * zrot) + y + (y * sf) - (z * xrot) + yp;
            double hz = (-1 * x * yrot) + (y * xrot) + z + (z * sf) + zp;

            // Convert back to lat, lon
            double newLon = Math.Atan(hy / hx);
            double p = Math.Sqrt((hx * hx) + (hy * hy));
            double newLat = Math.Atan(hz / (p * (1 - e2)));
            v = a2 / (Math.Sqrt(1 - e2 * (Math.Sin(newLat) * Math.Sin(newLat))));
            double errvalue = 1.0;
            double lat0 = 0;
            while (errvalue > 0.001)
            {
                lat0 = Math.Atan((hz + e2 * v * Math.Sin(newLat)) / p);
                errvalue = Math.Abs(lat0 - newLat);
                newLat = lat0;
            }

            deciAlt = p / Math.Cos(lat0) - v;

            //convert back to degrees
            newLat = newLat * rad2deg;
            deciLat = newLat;
            newLon = newLon * rad2deg;
            deciLon = newLon;

            return deciLat.ToString() + ',' + deciLon.ToString();
        }


        // public properties

        // 1.1 added Easting and Northing properties
        //     removed error on square SV due to string < 5 characters in NE2NGR
        //     allowed lower case for grid references in NGRtoOSGB36
        // 1.2 added Altitude to the ellipsoid conversions
        //     addded NEtoNGR method and NewAltitude property 
        public double DllVersion
        { get { return 1.2; } }

        public double Easting
        { get { return easting; } }

        public double NewAltitude
        { get { return deciAlt; } }

        public double NewLatitude
        { get { return deciLat; } }

        public double NewLongitude
        { get { return deciLon; } }

        public double Northing
        { get { return northing; } }

        // a function used in NGR to OSGB36
        private double InitialLat(double north, double n0, double af0, double phi0, double n, double bf0)
        {
            double phi1 = ((north - n0) / af0) + phi0;
            double M = Marc(bf0, n, phi0, phi1);
            double phi2 = ((north - n0 - M) / af0) + phi1;
            double ind = 0;
            while ((Math.Abs(north - n0 - M) > 0.00001) && (ind < 20))  // max 20 iterations in case of error
            {  
                ind = ind + 1;
                phi2 = ((north - n0 - M) / af0) + phi1;
                M = Marc(bf0, n, phi0, phi2);
                phi1 = phi2;
            }
            return(phi2);  
        }

        // a function used in OSGB36toNGR and NGR to OSGB36
        private double Marc(double bf0, double n, double phi0, double phi)
        {
            return bf0 * (((1 + n + ((5 / 4) * (n * n)) + ((5 / 4) * (n * n * n))) * (phi - phi0))
               - (((3 * n) + (3 * (n * n)) + ((21 / 8) * (n * n * n))) * (Math.Sin(phi - phi0)) * (Math.Cos(phi + phi0)))
               + ((((15 / 8) * (n * n)) + ((15 / 8) * (n * n * n))) * (Math.Sin(2 * (phi - phi0))) * (Math.Cos(2 * (phi + phi0))))
               - (((35 / 24) * (n * n * n)) * (Math.Sin(3 * (phi - phi0))) * (Math.Cos(3 * (phi + phi0)))));
        }

        //convert 12 (6e & 6n) figure numeric to letter and number grid system
        private String NE2NGR(double east, double north)
        {
            double eX = east / 500000;
            double nX = north / 500000;
            double tmp = Math.Floor(eX) - 5.0 * Math.Floor(nX) + 17.0;  //Math.Floor Returns the largest integer less than or equal to the specified number.
            nX = 5 * (nX - Math.Floor(nX));
            eX = 20 - 5.0 * Math.Floor(nX) + Math.Floor(5.0 * (eX - Math.Floor(eX)));
            if (eX > 7.5) eX = eX + 1;
            if (tmp > 7.5) tmp = tmp + 1;
            string eing = "0000" + Convert.ToString(east);
            string ning = "0000" + Convert.ToString(north);
            // padding ensures minimum length of 5 characters
            int lnth = eing.Length;
            eing = eing.Substring(lnth - 5);
            lnth = ning.Length;
            ning = ning.Substring(lnth - 5);
            return Convert.ToString((char)(tmp + 65)) + Convert.ToString((char)(eX + 65)) + eing + ning;

        }


    }

}
------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user

Reply via email to