public Location[] 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).Latitude; double h_btm = Calculations.XyToLoc(h_x, h_y - h_deg * h_size).Latitude; double h_l = Calculations.XyToLoc(h_x - 2 * h_size, h_y).Longitude; double h_r = Calculations.XyToLoc(h_x + 2 * h_size, h_y).Longitude; double h_cl = Calculations.XyToLoc(h_x - 1 * h_size, h_y).Longitude; double h_cr = Calculations.XyToLoc(h_x + 1 * h_size, h_y).Longitude; return(new Location[] { new Location(h_l, h_lat), new Location(h_cl, h_top), new Location(h_cr, h_top), new Location(h_r, h_lat), new Location(h_cr, h_btm), new Location(h_cl, h_btm) }); }
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; Location z_loc = Calculations.XyToLoc(h_lon, h_lat); double z_loc_x = z_loc.Longitude; double z_loc_y = z_loc.Latitude; 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())); }
private static Zone GetZoneByCode(String code) { int level = code.Length; double h_size = Calculations.CalcHexSize(level); double unit_x = 6 * h_size; double unit_y = 6 * h_size * Constants.h_k; double h_x = 0; double h_y = 0; string h_dec9 = "" + (Constants.h_key.IndexOf(code[0]) * 30 + Constants.h_key.IndexOf(code[1].ToString()) + "") + code.Substring(2); if (h_dec9.Length >= 3) { if (RegMatch(h_dec9[0], INC15) && RegMatch(h_dec9[1], EXC125) && RegMatch(h_dec9[2], EXC125)) { if (h_dec9[0] == '5') { h_dec9 = "7" + h_dec9.Substring(1, h_dec9.Length - 1); } else if (h_dec9[0] == '1') { h_dec9 = "3" + h_dec9.Substring(1, h_dec9.Length - 1); } } } int d9xlen = h_dec9.Length; for (int i = 0; i < level + 1 - d9xlen; i++) { h_dec9 = "0" + h_dec9; d9xlen++; } StringBuilder h_dec3 = new StringBuilder(); for (int i = 0; i < d9xlen; i++) { String h_dec0 = BaseConverter.NumberToBaseString(h_dec9[i].ToString(), 3).ToString(); if (h_dec0.Length == 1) { h_dec3.Append("0"); } h_dec3.Append(h_dec0); } List <char> h_decx = new List <char>(); List <char> h_decy = new List <char>(); for (int i = 0; i < h_dec3.Length / 2; i++) { h_decx.Add(h_dec3[i * 2]); h_decy.Add(h_dec3[(i * 2 + 1)]); } for (int i = 0; i <= level; i++) { double h_pow = Math.Pow(3, level - i); if (h_decx[i] == '0') { h_x -= h_pow; } else if (h_decx[i] == '2') { h_x += h_pow; } if (h_decy[i] == '0') { h_y -= h_pow; } else if (h_decy[i] == '2') { h_y += h_pow; } } double h_lat_y = (Constants.h_k * h_x * unit_x + h_y * unit_y) / 2; double h_lon_x = (h_lat_y - h_y * unit_y) / Constants.h_k; Location h_loc = Calculations.XyToLoc(h_lon_x, h_lat_y); if (h_loc.Longitude > 180) { h_loc.Longitude -= 360; } else if (h_loc.Longitude < -180) { h_loc.Longitude += 360; } return(new Zone(h_loc.Latitude, h_loc.Longitude, h_x, h_y, code)); }