Ejemplo n.º 1
0
        public Loc[] getHexCoords()
        {
            double h_lat  = this.lat;
            double h_lon  = this.lon;
            XY     h_xy   = Calculations.Loc2Xy(h_lon, h_lat);
            double h_x    = h_xy.x;
            double h_y    = h_xy.y;
            double h_deg  = Math.Tan(Math.PI * (60.0 / 180.0));
            double h_size = this.getHexSize();
            double h_top  = Calculations.XyToLoc(h_x, h_y + h_deg * h_size).lat;
            double h_btm  = Calculations.XyToLoc(h_x, h_y - h_deg * h_size).lat;

            double h_l  = Calculations.XyToLoc(h_x - 2 * h_size, h_y).lon;
            double h_r  = Calculations.XyToLoc(h_x + 2 * h_size, h_y).lon;
            double h_cl = Calculations.XyToLoc(h_x - 1 * h_size, h_y).lon;
            double h_cr = Calculations.XyToLoc(h_x + 1 * h_size, h_y).lon;

            return(new Loc[]
            {
                new Loc(h_l, h_lat),
                new Loc(h_cl, h_top),
                new Loc(h_cr, h_top),
                new Loc(h_r, h_lat),
                new Loc(h_cr, h_btm),
                new Loc(h_cl, h_btm)
            });
        }
Ejemplo n.º 2
0
        private static Zone GetZoneByLocation(double lon, double lat, int level)
        {
            if (lat < -90 || lat > 90 || lon < -180 || lon > 180 || level < 0 || level > 15)
            {
                return(null);
            }

            level += 2;
            double h_size = Calculations.CalcHexSize(level);

            XY     z_xy     = Calculations.Loc2Xy(lon, lat);
            double lon_grid = z_xy.x;
            double lat_grid = z_xy.y;
            double unit_x   = 6 * h_size;
            double unit_y   = 6 * h_size * Constants.h_k;
            double h_pos_x  = (lon_grid + lat_grid / Constants.h_k) / unit_x;
            double h_pos_y  = (lat_grid - Constants.h_k * lon_grid) / unit_y;
            double h_x_0    = Math.Floor(h_pos_x);
            double h_y_0    = Math.Floor(h_pos_y);
            double h_x_q    = h_pos_x - h_x_0;
            double h_y_q    = h_pos_y - h_y_0;

            double h_x = Math.Round(h_pos_x);
            double h_y = Math.Round(h_pos_y);

            if (h_y_q > -h_x_q + 1)
            {
                if ((h_y_q < 2 * h_x_q) && (h_y_q > 0.5 * h_x_q))
                {
                    h_x = h_x_0 + 1;
                    h_y = h_y_0 + 1;
                }
            }
            else if (h_y_q < -h_x_q + 1)
            {
                if ((h_y_q > (2 * h_x_q) - 1) && (h_y_q < (0.5 * h_x_q) + 0.5))
                {
                    h_x = h_x_0;
                    h_y = h_y_0;
                }
            }

            double h_lat = (Constants.h_k * h_x * unit_x + h_y * unit_y) / 2;
            double h_lon = (h_lat - h_y * unit_y) / Constants.h_k;

            Loc    z_loc   = Calculations.XyToLoc(h_lon, h_lat);
            double z_loc_x = z_loc.lon;
            double z_loc_y = z_loc.lat;

            if (Constants.h_base - h_lon < h_size)
            {
                z_loc_x = 180;
                double h_xy = h_x;
                h_x = h_y;
                h_y = h_xy;
            }

            StringBuilder h_code  = new StringBuilder();
            List <Int32>  code3_x = new List <Int32>();
            List <Int32>  code3_y = new List <Int32>();
            StringBuilder code3   = new StringBuilder();
            StringBuilder code9   = new StringBuilder();
            double        mod_x   = h_x;
            double        mod_y   = h_y;

            for (int i = 0; i <= level; i++)
            {
                double h_pow = Math.Pow(3, level - i);

                if (mod_x >= Math.Ceiling(h_pow / 2))
                {
                    code3_x.Add(2);
                    mod_x -= h_pow;
                }
                else if (mod_x <= -Math.Ceiling(h_pow / 2))
                {
                    code3_x.Add(0);
                    mod_x += h_pow;
                }
                else
                {
                    code3_x.Add(1);
                }

                if (mod_y >= Math.Ceiling(h_pow / 2))
                {
                    code3_y.Add(2);
                    mod_y -= h_pow;
                }
                else if (mod_y <= -Math.Ceiling(h_pow / 2))
                {
                    code3_y.Add(0);
                    mod_y += h_pow;
                }
                else
                {
                    code3_y.Add(1);
                }
            }

            for (int i = 0; i < code3_x.Count; i++)
            {
                code3.Append("" + code3_x[i] + code3_y[i]);
                //Convert to terneral (Base 3) not standard supported in .Net
                code9.Append(BaseConverter.BaseStringToValue(code3.ToString(), 3));
                h_code.Append(code9);
                code9.Length = 0;
                code3.Length = 0;
            }

            String h_2  = h_code.ToString(3, (h_code.Length) - 3);
            int    h_1  = Convert.ToInt32(h_code.ToString(0, 3));
            int    h_a1 = (int)Math.Floor((double)h_1 / 30);
            int    h_a2 = h_1 % 30;

            StringBuilder h_code_r = new StringBuilder();

            h_code_r.Append(Constants.h_key[h_a1]).Append(Constants.h_key[h_a2]).Append(h_2.ToString());

            return(new Zone(z_loc_y, z_loc_x, h_x, h_y, h_code_r.ToString()));
        }