lib/geo_swap.rb in geo_swap-0.1.0 vs lib/geo_swap.rb in geo_swap-0.2.0
- old
+ new
@@ -59,11 +59,25 @@
)
end
module_function :lat_long_to_utm
+ def utm_to_usng(easting, northing, zone_number, zone_letter, hemisphere = 'N')
+ precision = 10
+ if hemisphere == 'S'
+ northing += NORTHING_OFFSET
+ end
+ letters = find_grid_letters(zone_number, northing, easting)
+ usngNorthing = (northing % BLOCK_SIZE).round
+ usngEasting = (easting % BLOCK_SIZE).round
+
+ "#{zone_number}#{zone_letter} #{letters} #{usngEasting} #{usngNorthing}"
+ end
+
+ module_function :utm_to_usng
+
private
MAX_LATITUDE = 90.0
MIN_LATITUDE = -90.0
MAX_LONGITUDE = 180
@@ -77,10 +91,14 @@
MERIDIAN_SCALE = 0.9996
EASTING_OFFSET = 500000.0
NORTHING_OFFSET = 10000000.0
+ BLOCK_SIZE = 100000
+ GRIDSQUARE_SET_COL_SIZE = 8
+ GRIDSQUARE_SET_ROW_SIZE = 20
+
def self.validate_range(lat, long)
unless lat.between?(MIN_LATITUDE, MAX_LATITUDE) && long.between?(MIN_LONGITUDE, MAX_LONGITUDE)
raise InputError, 'Input coordinates are invalid'
end
@@ -90,9 +108,64 @@
end
def self.ecc(power, numerator, denominator)
ecc = ECC_SQUARED ** power
(numerator * ecc) / denominator
+ end
+
+ def self.find_grid_letters(zone_number, northing, easting)
+ row = 1
+ north_1m = northing.round
+ while north_1m >= BLOCK_SIZE do
+ north_1m = north_1m - BLOCK_SIZE
+ row += 1;
+ end
+ row = row % GRIDSQUARE_SET_ROW_SIZE
+
+ col = 0
+ east_1m = easting.round
+ while east_1m >= BLOCK_SIZE
+ east_1m = east_1m - BLOCK_SIZE
+ col += 1
+ end
+ col = col % GRIDSQUARE_SET_COL_SIZE
+
+ letters_helper(find_set(zone_number), row, col)
+ end
+
+ LETTERS_MAP = [
+ { cols: "ABCDEFGH", rows: "ABCDEFGHJKLMNPQRSTUV" },
+ { cols: "JKLMNPQR", rows: "FGHJKLMNPQRSTUVABCDE" },
+ { cols: "STUVWXYZ", rows: "ABCDEFGHJKLMNPQRSTUV" },
+ { cols: "ABCDEFGH", rows: "FGHJKLMNPQRSTUVABCDE" },
+ { cols: "JKLMNPQR", rows: "ABCDEFGHJKLMNPQRSTUV" },
+ { cols: "STUVWXYZ", rows: "FGHJKLMNPQRSTUVABCDE" }
+ ]
+
+ ZONE_TO_SET = [6, 1, 2, 3, 4, 5]
+
+ def self.find_set(zone_number)
+ zoneNum = zone_number % 6
+ ZONE_TO_SET[zoneNum.to_i] || -1
+ end
+
+ def self.letters_helper(set, row, col)
+ if row == 0
+ row = GRIDSQUARE_SET_ROW_SIZE - 1
+ else
+ row -= 1
+ end
+
+ if col == 0
+ col = GRIDSQUARE_SET_COL_SIZE - 1
+ else
+ col -= 1
+ end
+
+ l1 = l2 = nil
+
+ hash = LETTERS_MAP[set - 1]
+ hash[:cols][col] + hash[:rows][row]
end
end
class GeoSwap::InputError < StandardError; end