Jeg ser, at mange konkurrencer, priser og andre genstande bruger gitterkvadrater som et middel til at identificere, hvor man er. Hvordan kan man finde ud af, hvad ens gitterkvadrat er, givet lat / lang?
Jeg ser, at mange konkurrencer, priser og andre genstande bruger gitterkvadrater som et middel til at identificere, hvor man er. Hvordan kan man finde ud af, hvad ens gitterkvadrat er, givet lat / lang?
Først og fremmest, hvis du ikke ønsker at lave matematik, så tjek et gitter kvadratisk kort, såsom denne.
Der er en fremragende proces på denne side og yderligere ressourcer fra ARRL. I det væsentlige indeholder gitterkvadrater 3 par, de første og sidste bogstaver og mellemtalene. Længdegrad er altid den første efterfulgt af breddegrad for hvert par. For nemheds skyld antager vi, at vest og syd er negative lat / lange, som det er en almindelig konvention. For eksempel vil jeg bruge 32,123 W, 14,321 N. Det vigtigste er at gøre følgende. :
Breddegrad
At sætte dem sammen parvis, og skiftevis først længdegrad og derefter breddegrad, giver gitterpladsen for 32,123 W, 14,321 N for at være HK34wh.
Hvis du gerne vil gøre det selv, kan du bruge dette Python-program, som jeg skrev.
# - * - kodning: utf-8 - * - import sys # Konverter breddegrad og længdegrad til Maidenhead gitterlokatorer. ## Argumenterne er i underskrevet decimalbredde og længdegrad. For eksempel er # placeringen af min QTH Palo Alto, CA: 37.429167, -122.138056 eller # i grader, minutter og sekunder: 37 ° 24 '49 "N 122 ° 6' 26" Wupper = 'ABCDEFGHIJKLMNOPQRSTUVWX'lower =' abcdefghijklmnopqrstuvwx'def to_grid (dec_lat, dec_lon): hvis ikke (-180< = dec_lon<180): sys.stderr.write ('længdegrad skal være -180< = lon<180, givet% f \ n) ikke (-90< = dec_lat<90): sys.stderr.write ('latitude must be -90< = lat<90, given% f \ n'% dec_lat) sys.exit (33) # kan ikke håndtere nordpolen, undskyld, [AR ] adj_lat = dec_lat + 90.0 adj_lon = dec_lon + 180.0 grid_lat_sq = øvre [int (adj_lat / 10)]; grid_lon_sq = øvre [int (adj_lon / 20)]; grid_lat_field = str (int (adj_lat% 10)) grid_lon_field = str (int ((adj_lon / 2)% 10)) adj_lat_remainder = (adj_lat - int (adj_lat)) * 60 adj_lon_remainder = ((adj_lon) - int (adj_lon / 2 ) * 2) * 60 grid_lat_subsq = lavere [int (adj_lat_remainder / 2.5)] grid_lon_subsq = lavere [int (adj_lon_remainder / 5)] returnere grid_lon_sq + grid_lat_sq + grid_lon_field + grid_lat_field + grid_lon_subsq + grid_lat_subsqdef-brug argumenter, decimalbreddegrad og længdegrad. ' print 'Eksempel på Newington, Connecticut (W1AW):' print 'python maidenhead.py 41.714775 -72.727260' print 'returnerer: FN31pr'def test (): # De første fire testeksempler er fra "Konvertering mellem geodetiske og gitterlokaliseringssystemer", # af Edmund T. Tyson N5JTY QST januar 1989 test_data = (('München', (48.14666,11.60833), 'JN58td'), ('Montevideo', (-34.91, -56.21166), 'GF15vc'), ('Washington , DC ', (38.92, -77.065),' FM18lw '),
('Wellington', (-41.28333,174.745), 'RE78ir'), ('Newington, CT (W1AW)', (41.714775, -72.727260), 'FN31pr'), ('Palo Alto (K6WRU)', (37.413708 , -122.1073236), 'CM87wj'),) print 'Kører selvtest \ n' bestået = Sand for navn, latlon, gitter i test_data: print 'Testing% s ved% f% f:'% (navn, latlon [0 ], latlon [1]) test_grid = to_grid (latlon [0], latlon [1]) if test_grid! = grid: print 'Failed' + test_grid + 'should be' + grid passed = False else: print 'Passed' + test_grid print '' hvis bestået: print 'Bestået!' ellers: udskriv 'Mislykket!' def main (argv = Ingen): hvis argv er Ingen: argv = sys.argv hvis len (argv)! = 3: brug () udskriv '' test () ellers: udskriv til_grid (float ( argv [1]), float (argv [2])) main ()
Mit første indlæg i SO. Her er en C-version ... lavet dette til et Arduino-projekt.
void calcLocator (char * dst, double lat, double lon) {int o1, o2, o3; int a1, a2, a3; dobbelt rest; // længdegrad resten = lon + 180,0; al = (int) (resten / 20,0); resten = resten - (dobbelt) o1 * 20.0; o2 = (int) (resten / 2,0); resten = resten - 2,0 * (dobbelt) o2; o3 = (int) (12,0 * rest); // breddegrad resten = lat + 90.0; al = (int) (resten / 10,0); resten = resten - (dobbelt) a1 * 10.0; a2 = (int) (resten); resten = resten - (dobbelt) a2; a3 = (int) (24,0 * resten); dst [0] = (char) o1 + 'A'; dst [1] = (char) al + 'A'; dst [2] = (char) o2 + '0'; dst [3] = (char) a2 + '0'; dst [4] = (char) o3 + 'A'; dst [5] = (char) a3 + 'A'; dst [6] = (char) 0;}
Dette hjalp mig. For alle der har brug for det, her er en port til Java:
public class Location {String latlon; String jomfruhoved; offentlig placering (streng p1, streng p2) {float lat = -100.0f; flyde lon = 0,0f; prøv {lat = Float.parseFloat (p1); lon = Float.parseFloat (p2); maidenhead = latLonToGridSquare (lat, lon); } fangst (Undtagelse e) {// TODO Auto-genereret fangstblok e.printStackTrace (); }} offentlig placering (float lat, float lon) {prøv {maidenhead = latLonToGridSquare (lat, lon); } fangst (Undtagelse e) {// TODO Auto-genereret fangstblok e.printStackTrace (); }} privat ugyldigt gridSquareToLatLon (String grid) {} offentlig String latLonToGridSquare (float lat, float lon) kaster Undtagelse {float adjLat, adjLon; char GLat, GLon; String nLat, nLon; char gLat, gLon; flyde rLat, rLon; Streng U = "ABCDEFGHIJKLMNOPQRSTUVWX"; Streng L = U.toLowerCase (); // support Chris Veness 2002-2012 LatLon-bibliotek og // andre objekter med lat / lon-egenskaber // egenskaber kan være getterfunktioner, tal eller strenge, hvis (Float.isNaN (lat)) smider nyt undtagelse ("lat er NaN" ); hvis (Float.isNaN (lon)) smider ny undtagelse ("lon er NaN"); hvis (Math.abs (lat) == 90.0) smider ny undtagelse ("gitterkvadrater ugyldige ved N / S-poler"); hvis (Math.abs (lat) > 90) smider ny undtagelse ("ugyldig breddegrad:" + lat); hvis (Math.abs (lon) > 180) smider ny undtagelse ("ugyldig længdegrad:" + lon); adjLat = lat + 90; adjLon = lon + 180; GLat = U.charAt ((int) (adjLat / 10)); GLon = U.charAt ((int) (adjLon / 20)); nLat = "" + (int) (adjLat% 10); nLon = "" + (int) ((adjLon / 2)% 10); rLat = (adjLat - (int) (adjLat)) * 60; rLon = (adjLon - 2 * (int) (adjLon / 2)) * 60; gLat = L.charAt ((int) (rLat / 2,5)); gLon = L.charAt ((int) (rLon / 5)); String locator = "" + GLon + GLat + nLon + nLat + gLon + gLat; returlokator }}
Og her er JUnit test case:
import statisk org.junit.Assert. *; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test ; public class LocationTest {@Test public void testLatLonToGridSquare () {Location loc = new Location (48.14666f, 11.60833f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "JN58td"); loc = ny placering ("- 34.91", "- 56.21166"); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "GF15vc"); loc = ny placering (38.92f, -77.065f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "FM18lw"); loc = ny placering (-41.28333f, 174.745f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "RE78ir"); loc = ny placering (41.714775f, -72.727260f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "FN31pr"); loc = ny placering (37.413708f, -122.1073236f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "CM87wj"); loc = ny placering (35.0542f, -85.1142f); System.out.println (loc.maidenhead); assertEquals (loc.maidenhead, "EM75kb"); }}
Jeg har inkluderet Locator-baserede beregninger i PyHamTools - et open source python-bibliotek, som er let at bruge:
Det er så let som dette:
fra pyhamtools .locator import calc_distance, latlong_to_locatorlocator1 = latlong_to_locator (48.52, 9.375) locator2 = latlong_to_locator (-32.77, 152.125) distance = calcul_heading (locator1, locator2) print ("%. 1fkm"% afstand) 16466km 46p For flere eksempler og dokumentationen, se: http://pyhamtools.readthedocs.org/da/latest/index.html
Du kan starte med at bruge et kort, men det går ud af hånd, når du kommer ud over det andet sæt cifre. Der er lommeregnere online, som denne fra QRZ eller denne kortbaserede lokalisering. Det er også muligt at beregne det manuelt - Wikipedia-artiklen har en god beskrivelse af, hvordan de fungerer.
Dybest set bygger de to første tegn et gitter, ligesom på ethvert andet kort. Det første tegn er længdegrad, det andet er bredde, og det første par er bogstaverne A-R, hvilket betyder, at verden er opdelt i 18 skiver. Da der er 360 ° længdegrad og 180 bredde, betyder det, at hver gitterkvadrat er ca. 18 grader bred og 9 grader høj. Det starter ved 180 grader vest og 90 grader syd, så hvis jeg er i det sjette gitter øst for 180 grader W (hvilket betyder, at min længde er mellem 72 vest og 90 W), er min første karakter F. Derefter det andet par cifre opdeler det i 10 lige store skiver osv.
Jeg kunne ikke se nogen svar, der havde den udvidede firkant, som der henvises til i Wikipedia -artiklen. Min Clojure-implementering (GitHub Gist Here) koder for det fjerde og femte par.
(defn to-maidenhead [lat long] (let [long (-> long ( + 180) (/ 2)) lat (-> lat (+ 90)) funs [# (* 10 (mod% 1)) # (* 24 (mod% 1)) # (* 10 (mod% 1)) # (* 24 (mod% 1))] biler [\ A \ 0 \ a \ 0 \ a]] (kort (fn [geo] (kort (fn [n bil] (char (+ (int bil) n) )) (reduktioner (fn [n sjov] (sjov n)) (/ geo 10) sjov) biler)) [lang lat]))) (def til-jomfruhoved-str (comp # (anvend str%) # (anvend interleave%) to-maidenhead))
En simpel testtest:
(kommentar (anvend str (anvend interleave (to-maidenhead 36.165926 -86.723285 = > "EM66pd39et" (og (= "EM66pd39et" (to-maidenhead-str 36.165926 -86.723285)) (= "OF86cx76ql" (to-maidenhead-str -33.014673 116.230695)) (= "FD54oq44oh" to-maidenhead-str -55.315349 -68.794971)) (= "PM85ge79vh" (til-ma idenhead-str 35.205535 136.56579))) ;; = > sandt ;; Bare en simpel test på forskellige koordinater over hele kloden. ;; Maidenhead Locator taget fra http://no.nonsense.ee/qth/map.html)
Se på numpy.meshgrid
http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.meshgrid.html
De løsninger, jeg har set, ser ud til at genopvaskes den samme kode med lidt tanke om, hvad der faktisk sker. Jeg besluttede at skrive en løsning, der løser den generelle sag, hvilket gør det til en enkel sag at udvide præcisionen af resultatet til enhver længde. Da jeg er en iOS-udvikler, er løsningen i Swift:
private let upper = "ABCDEFGHIJKLMNOPQRSTUVWX" private let lower = "abcdefghijklmnopqrstuvwx" public func maidenhead (latitude: Double, longitude: Double) - > String {var lonDegrees: Double = 360 var latDegrees: Double = 180 var lon = longitude + 180.0 var lat = latitude + 90.0 var lonRemainder = lon var latRemainder = lat func gridPair (divisioner: Double) -> (Double, Double) { lonDegrees = lonDegrees / divisioner latDegrees = latDegrees / divisioner lon = lonRemainder / lonDegrees lonRemainder = lonRemainder% lonDegrees lat = latRemainder / latDegrees latRemainder = latRemainder% latDegrees return (lon, lat)} let (gridLonField, gridLatField) = grid gridLonSquare, gridLatSquare) = gridPair (10) lad (gridLonSubSquare, gridLatSubSquare) = gridPair (24) lad (gridLonExtSquare, gridLatExtSquare) = gridPair (10) le t (gridLonSubExtSquare, gridLatSubExtSquare) = gridPair (24) return "\ (upper [Int (gridLonField)]) \ (upper [Int (gridLatField)]) \ (Int (gridLonSquare)) \ (Int (gridLatSquare)) \ (lower [Int (gridLonSubSquare)]) \ (lavere [Int (gridLatSubSquare)]) \ (Int (gridLonExtSquare)) \ (Int (gridLatExtSquare)) \ (lavere [Int (gridLonSubExtSquare)]) \ (lavere [Int (gridLatSubExtSquare)] ) "}
Her er dokumenterne om det. http://www.qrz.ru/vhf/qth_h.pdf
Og selvfølgelig fik du denne. https://en.wikipedia.org/wiki/Maidenhead_Locator_System
Se på
I Javascript fandt jeg ikke et gitter kvadratisk bibliotek med Google, selvom der selvfølgelig er eksisterende kode på flere relaterede skinkekortwebsteder.
Så jeg kodede op HamGridSquare.js delvis baseret på K6WRU's svar ovenfor.
Det består hans tests.
Funktionsdefinitionerne er kompatible med MeteorJS framework og understøtter forskellige input.
Et opkald til latLonFromGridSquare ()
kan have to numeriske eller strengparametre (lat, lon)
eller en enkelt parameter, der er en matrix eller et objekt med numeriske, streng- eller funktionsegenskaber ([lat, lon])
({lat: nnn, lon: nnn})
({lat: latGetterFunc, lon: lonGetterFunc})
. Sidstnævnte skal være kompatibel med LatLon-objekter oprettet af Chris Veness 'LatLon JS-bibliotek. Chris 'LatLon-bibliotek giver en måde at beregne afstande og lejer på.
// HamGridSquare.js // Copyright 2014 Paul Brewer KI6CQ // Licens: MIT License http://opensource.org/licenses / MIT eller CC-BY-SA //// Javascript-rutiner til konvertering fra lat-lon til Maidenhead Grid Squares // typisk brugt i Ham Radio-satellitoperationer og VHF-konkurrencer //// Inspireret delvist af K6WRU Walter Underwoods pythonsvar / / http://ham.stackexchange.com/a/244// til dette stackoverløbsspørgsmål: // Hvordan kan man konvertere fra Lat / Long til Grid Square // http://ham.stackexchange.com/questions/221 / hvordan-kan-en-konvertere-fra-lat-lang-til-gitter-kvadrat // latLonToGridSquare = funktion (param1, param2) {var lat = -100.0; var lon = 0,0; var adjLat, adjLon, GLat, GLon, nLat, nLon, gLat, gLon, rLat, rLon; var U = 'ABCDEFGHIJKLMNOPQRSTUVWX' var L = U.toLowerCase (); // support Chris Veness 2002-2012 LatLon-bibliotek og // andre objekter med lat / lon-egenskaber // egenskaber kan være getterfunktioner, tal eller stringsfunktion toNum (x) {if (typeof (x) === 'number' ) returnere x; hvis (typeof (x) === 'streng') returnerer parseFloat (x); hvis (typeof (x) === 'funktion') returnerer parseFloat (x ());
kast "HamGridSquare - toNum - kan ikke konvertere input:" + x; } if (typeof (param1) === 'objekt') {if (param1.length === 2) {lat = toNum (param1 [0]); lon = toNum (param1 [1]); } ellers hvis (('lat' i param1) && ('lon' i param1)) {lat = toNum (param1.lat); lon = toNum (param1.lon); } ellers hvis (('latitude' i param1) && ('longitude' i param1)) {lat = toNum (param1.latitude); lon = toNum (param1.længdegrad); } ellers {throw "HamGridSquare - kan ikke konvertere objekt -" + param1; }} andet {lat = toNum (param1); lon = toNum (param2); } hvis (isNaN (lat)) kaster "lat er NaN"; hvis (isNaN (lon)) smider "lon er NaN"; hvis (Math.abs (lat) === 90.0) kaster "gitterkvadrater ugyldige ved N / S-poler"; hvis (Math.abs (lat) > 90) kaster "ugyldig breddegrad:" + lat; hvis (Math.abs (lon) > 180) kaster "ugyldig længdegrad:" + lon; adjLat = lat + 90; adjLon = lon + 180; GLat = U [Math.trunc (adjLat / 10)]; GLon = U [Math.trunc (adjLon / 20)]; nLat = '' + Math.trunc (adjLat% 10); nLon = '' + Math.trunc ((adjLon / 2)% 10); rLat = (adjLat - Math.trunc (adjLat)) * 60; rLon = (adjLon - 2 * Math.trunc (adjLon / 2)) * 60; gLat = L [Math.trunc (rLat / 2.5)]; gLon = L [Math.trunc (rLon / 5)]; returnere GLon + GLat + nLon + nLat + gLon + gLat;} testGridSquare = function () {// De første fire testeksempler er fra "Konvertering mellem geodetiske og gitterlokaliseringssystemer", // af Edmund T. Tyson / originale testdata / citater af Walter Underwood K6WRU // sidste test og kodning i Javascript fra Python af Paul Brewer KI6CQ var testData = [['München', [48.14666,11.60833], 'JN58td'], ['Montevideo', [ [-34.91, -56.21166]], 'GF15vc'], ['Washington, DC', [{lat: 38.92, lon: -77.065}], 'FM18lw'], ['Wellington', [{latitude: -41.28333 , længdegrad: 174.745}], 'RE78ir'], ['Newington, CT (W1AW)', [41.714775, -72.727260], 'FN31pr'], ['Palo Alto (K6WRU)', [[37.413708, -122.1073236] ], 'CM87wj'],
['Chattanooga (KI6CQ / 4)', [{lat: funktion () {return "35.0542"; }, lon: function () {return "-85.1142"}}], "EM75kb"]]; var i = 0, l = testData.length, result = '', thisPassed = 0, totalPassed = 0; for (i = 0; i<l; ++ i) {resultat = latLonToGridSquare.apply ({}, testData [i] [1]); thisPassed = resultat === testData [i] [2]; console.log ("test" + i + ":" + testData [i] [0] + "" + JSON.stringify (testData [i] [1]) + "resultat =" + resultat + "forventet =" + testData [ i] [2] + "bestået =" + dettePassed); totalPassed + = thisPassed; } console.log (totalPassed + "af" + l + "test bestået"); return totalPassed === l;}
C # version
offentlig statisk String LatLonToGridSquare (dobbelt lat, dobbelt lon) {dobbelt adjLat, adjLon; char GLat, GLon; String nLat, nLon; char gLat, gLon; dobbelt rLat, rLon; Streng U = "ABCDEFGHIJKLMNOPQRSTUVWX"; Streng L = U.ToLower (); hvis (double.IsNaN (lat)) smider ny undtagelse ("lat er NaN"); hvis (double.IsNaN (lon)) smider ny undtagelse ("lon er NaN"); hvis (Math.Abs (lat) == 90.0) smider ny undtagelse ("gitterkvadrater ugyldige ved N / S-poler"); hvis (Math.Abs (lat) > 90) smider ny undtagelse ("ugyldig breddegrad:" + lat); hvis (Math.Abs (lon) > 180) smider ny undtagelse ("ugyldig længdegrad:" + lon); adjLat = lat + 90; adjLon = lon + 180; GLat = U [(int) (adjLat / 10)]; GLon = U [(int) (adjLon / 20)]; nLat = "" + (int) (adjLat% 10); nLon = "" + (int) ((adjLon / 2)% 10); rLat = (adjLat - (int) (adjLat)) * 60; rLon = (adjLon - 2 * (int) (adjLon / 2)) * 60; gLat = L [(int) (rLat / 2,5)]; gLon = L [(int) (rLon / 5)]; String locator = "" + GLon + GLat + nLon + nLat + gLon + gLat; return locator;}
Bare en forbedring af et af svarene ovenfor fra Ossi Väänänen startende med dette:
void calcLocator (char * dst, double lat, double lon) {[...] dst [ 0] = (char) o1 + 'A'; dst [1] = (char) al + 'A'; dst [2] = (char) o2 + '0'; dst [3] = (char) a2 + '0'; dst [4] = (char) o3 + 'A'; dst [5] = (char) a3 + 'A'; dst [6] = (char) 0; }
Overvej at konvertere dst-værdierne til ascii-tegn. Udskift dst-array-poster ovenfor med følgende:
dst [0] = char (o1 + 65); dst [1] = char (al + 65); dst [2] = char (o2 + 48); dst [3] = char (a2 + 48); dst [4] = char (o3 + 97); dst [5] = char (a3 + 97);
Plus 65 giver dig ascii-bogstavsværdier for store bogstaver, +48 for tal og +97 for små bogstaver.
Eksempelresultater som følger:
char grid [4]; calcLocator (grid, gps.location.lat (), gps.location.lng ()); Serial.print ( grid); // resultaterne vil være i følgende format: AB01ab
73's all