Viac

Výpočet zemepisnej šírky a dĺžky x míľ od bodu?

Výpočet zemepisnej šírky a dĺžky x míľ od bodu?


Chcem nájsť bod zemepisnej šírky a dĺžky s ohľadom na smer, vzdialenosť a začiatočnú zemepisnú šírku a dĺžku.

Toto sa javí ako opak tejto otázky (vzdialenosť medzi lat / dlhými bodmi).

Už som sa pozrel na Haversinov vzorec a myslím si, že jeho aproximácia so svetom je pravdepodobne dosť blízko.

Predpokladám, že musím vyriešiť haversinov vzorec pre moju neznámu šírku / dĺžku, je to správne? Existujú nejaké dobré webové stránky, ktoré o tom hovoria? Zdá sa, že by to bolo bežné, ale moje googlenie ukázalo iba podobné otázky ako vyššie.

To, čo skutočne hľadám, je iba vzorec pre toto. Chcel by som mu dať začiatočný lat / lng, ložisko a vzdialenosť (míle alebo kilometre) a chcel by som z toho dostať pár lat / lng, ktorý predstavuje miesto, kde by človek skončil, keby spolu cestovali tej trase.


Zaujímalo by ma, ako sú výsledky tohto vzorca v porovnaní s Esriho pe.dll.

(citácia).

Bod {lat, lon} je vzdialenosť d na radiále tc od bodu 1, ak:

lat = asin (sin (lat1) * cos (d) + cos (lat1) * sin (d) * cos (tc)) IF (cos (lat) = 0) lon = lon1 // endpoint a pole ELSE lon = mod (lon1-asin (sin (tc) * sin (d) / cos (lat)) + pi, 2 * pi) -pi ENDIF

Tento algoritmus je obmedzený na vzdialenosti také, že dlon

lat = asin (sin (lat1) * cos (d) + cos (lat1) * sin (d) * cos (tc)) dlon = atan2 (sin (tc) * sin (d) * cos (lat1), cos ( d) -sin (lat1) * sin (lat)) lon = mod (lon1-dlon + pi, 2 * pi) -pi

Tu je stránka html na testovanie.


Keby ste boli v lietadle, tak bod, ktorý je r metrov ďalej pri ložisku a stupňa na východ od severu je posunutý o r * cos (a) v severnom smere a r * sin (a) o východný smer. (Tieto vyhlásenia viac-menej definovať sínus a kosínus.)

Aj keď nie ste v rovine - pracujete na povrchu zakriveného elipsoidu, ktorý modeluje zemský povrch - akákoľvek vzdialenosť menšia ako niekoľko stoviek kilometrov pokrýva tak malú časť povrchu, že pre väčšinu praktických účelov dokáže byť považovaný za plochý. Jedinou zostávajúcou komplikáciou je, že jeden stupeň zemepisnej dĺžky nepokrýva rovnakú vzdialenosť ako stupeň zemepisnej šírky. V sférickom modeli Zeme je jeden stupeň zemepisnej dĺžky iba cos (zemepisná šírka), pokiaľ je stupeň zemepisnej šírky. (V elipsoidnom modeli je to stále vynikajúca aproximácia, dobrá až okolo 2,5 platných číslic.)

Nakoniec, jeden stupeň zemepisnej šírky je približne 10 ^ 7/90 = 111 111 metrov. Teraz máme všetky informácie potrebné na prevod metrov na stupne:

Posun na sever je r * cos (a) / 111111 stupňov;

Posun na východ je r * sin (a) / cos (zemepisná šírka) / 111111 stupňov.

Napríklad pri zemepisnej šírke -0,31399 stupňov a smeru a = 30 stupňov východne od severu môžeme vypočítať

cos (a) = cos (30 stupňov) = cos (pi / 6 radiánov) = Sqrt (3) / 2 = 0,866025. sin (a) = sin (30 stupňov) = sin (pi / 6 radiánov) = 1/2 = 0,5. cos (zemepisná šírka) = cos (-0,31399 stupňov) = cos (-0,00548016 radián) = 0,999984984. r = 100 metrov. východný posun = 100 * 0,5 / 0,999984984 / 111111 = 0,000450007 stupňa. severný posun = 100 * 0,866025 / 111111 = 0,000779423 stupňa.

Odkedy (-78,4437, -0,31399), nové umiestnenie je na (-78,4437 + 0,00045, -0,31399 + 0,0007794) = (-78,4432, -0,313211).

Presnejšia odpoveď v modernom referenčnom systéme ITRF00 je (-78,4433, -0,313207): je to 0,43 metra od približnej odpovede, čo v tomto prípade znamená chyby aproximácie o 0,43%. Na dosiahnutie vyššej presnosti musíte použiť buď vzorce elipsoidnej vzdialenosti (ktoré sú oveľa komplikovanejšie), alebo vysoko verný konformný priemet s nulovou divergenciou (aby bolo ložisko správne).


Ak potrebujete riešenie JavaScriptu, zvážte tietofunkciea toto husle:

var gis = {/ ** * Očakávané všetky súradnice EPSG: 4326 * @param {Array} start Očakávané [lon, lat] * @param {Array} koniec Očakávané [lon, lat] * @return {number} Vzdialenosť - meter. * / countDistance: function (start, end) {var lat1 = parseFloat (start [1]), lon1 = parseFloat (start [0]), lat2 = parseFloat (end [1]), lon2 = parseFloat (end [0]) ); návrat gis.sphericalCosinus (lat1, lon1, lat2, lon2); }, / ** * Očakávané všetky súradnice EPSG: 4326 * @param {number} lat1 Start Latitude * @param {number} lon1 Start Longitude * @param {number} lat2 End Latitude * @param {number} lon2 End Longitude * @ spať {number} Vzdialenosť - metre. * / sphericalCosinus: function (lat1, lon1, lat2, lon2) {var radius = 6371e3; // metre var dLon = gis.toRad (lon2 - lon1), lat1 = gis.toRad (lat1), lat2 = gis.toRad (lat2), vzdialenosť = Math.acos (Math.sin (lat1) * Math.sin ( lat2) + Math.cos (lat1) * Math.cos (lat2) * Math.cos (dLon)) * polomer; spiatočná vzdialenosť; }, / ** * @param {Array} coord Očakávané [lon, lat] EPSG: 4326 * @param {number} ložisko Ložisko v stupňoch * @param {number} vzdialenosť Vzdialenosť v metroch * @return {Array} Lon-lat koordinovať. * / createCoord: function (coord, bearing, distance) {/ ** http://www.movable-type.co.uk/scripts/latlong.html * φ je zemepisná šírka, λ je zemepisná dĺžka, * θ je ložisko ( v smere hodinových ručičiek od severu), * δ je uhlová vzdialenosť d / R; * d je prejdená vzdialenosť, R zemský polomer * ** / variačný polomer = 6371e3, // metre δ = počet (vzdialenosť) / polomer, // uhlová vzdialenosť v radiánoch θ = gis.toRad (počet (ložisko)); φ1 = gis.toRad (coord [1]), λ1 = gis.toRad (coord [0]); var φ2 = Math.asin (Math.sin (φ1) * Math.cos (δ) + Math.cos (φ1) * Math.sin (δ) * Math.cos (θ)); var λ2 = λ1 + Math.atan2 (Math.sin (θ) * Math.sin (δ) * Math.cos (φ1), Math.cos (δ) -Math.sin (φ1) * Math.sin (φ2) ); // normalizovať na -180… + 180 ° λ2 = (λ2 + 3 * Math.PI)% (2 * Math.PI) - Math.PI; návrat [gis.toDeg (λ2), gis.toDeg (φ2)]; }, / ** * Očakávané všetky súradnice EPSG: 4326 * @param {Array} start Očakávané [lon, lat] * @param {Array} koniec Očakávané [lon, lat] * @return {number} Ložisko v stupňoch. * / getBearing: function (start, end) {var startLat = gis.toRad (start [1]), startLong = gis.toRad (start [0]), endLat = gis.toRad (end [1]), endLong = gis.toRad (koniec [0]), dLong = endLong - startLong; var dPhi = Math.log (Math.tan (endLat / 2.0 + Math.PI / 4.0) / Math.tan (startLat / 2.0 + Math.PI / 4.0)); if (Math.abs (dLong)> Math.PI) {dLong = (dLong> 0,0)? - (2,0 * Math.PI - dLong): (2,0 * Math.PI + dLong); } návrat (gis.toDeg (Math.atan2 (dLong, dPhi)) + 360,0)% 360,0; }, toDeg: function (n) {return n * 180 / Math.PI; }, toRad: function (n) {return n * Math.PI / 180; }};

Ak teda chcete vypočítať novú súradnicu, môže to byť takto:

var štart = [15, 38,70250]; var koniec = [21,54967, 38,70250]; var total_distance = gis.calculateDistance (začiatok, koniec); // metre var percent = 10; // to môžu byť aj metre var distance = (percentá / 100) * total_distance; var bearing = gis.getBearing (začiatok, koniec); var new_coord = gis.createCoord (ikona_koord, ložisko, vzdialenosť);

Túto prácu mám v ObjectiveC. Kľúčom je vedomie, že potrebujete body lat / lng v radiánoch a musíte ich po uplatnení rovnice previesť späť na lat / lng. Vedzte tiež, že vzdialenosť a tc sú v radiánoch.

Tu je pôvodná rovnica:

lat = asin (sin (lat1) * cos (d) + cos (lat1) * sin (d) * cos (tc)) IF (cos (lat) = 0) lon = lon1 // endpoint a pole ELSE lon = mod (lon1-asin (sin (tc) * sin (d) / cos (lat)) + pi, 2 * pi) -pi ENDIF

Tu je implementovaný v ObjC, kde radián je radián meraný proti smeru hodinových ručičiek od N (napr. PI / 2 je W, PI je S, 2 PI / 3 je E) a vzdialenosť je v kilometroch.

+ (CLLocationCoordinate2D) displaceLatLng: (CLLocationCoordinate2D) coordinate2D withRadian: (double) radian withDistance: (CGFloat) distance {double lat1Radians = coordinate2D.latitude * (M_PI / 180); double lon1Radians = coordinate2D.longitude * (M_PI / 180); dvojitá vzdialenosťRadians = vzdialenosť / 6371; double lat = asin (sin (lat1Radians) * cos (distanceRadians) + cos (lat1Radians) * sin (distanceRadians) * cos (radián)); double lon; if (cos (lat) == 0) {lon = lon1Radians; } else {lon = fmodf ((float) (lon1Radians - asin (sin (radian) * sin (distanceRadians) / cos (lat)) + M_PI), (float) (2 * M_PI)) - M_PI; } dvojitý newLat = lat * (180 / M_PI); dvojitý newLon = lon * (180 / M_PI); návrat CLLocationCoordinate2DMake (newLat, newLon); }

Ak vás zaujíma lepšia presnosť, je tu Vincenty. (Odkaz je na „priamy“ formulár, čo je presne to, čo hľadáte).

Existuje pomerne veľa existujúcich implementácií, ak hľadáte kód.

Tiež otázka: Nepredpokladáte, že si cestovateľ udržiava rovnakú orientáciu počas celej cesty, však? Ak je to tak, potom tieto metódy neodpovedajú na správnu otázku. (Bolo by lepšie premietnuť na obchodníka, nakresliť rovnú čiaru a potom premietnuť výsledok.)


Tu je riešenie pre Python:

def displace (self, theta, distance): "" "Premiestniť LatLng theta stupne proti smeru hodinových ručičiek a niekoľko metrov v tomto smere. Poznámky: http://www.movable-type.co.uk/scripts/latlong.html 0 STUPŇOV JE VERTIKÁLNA OSA Y! DÔLEŽITÉ! Args: theta: číslo v stupňoch. Vzdialenosť: číslo v metroch. Výnosy: Nový LatLng. "" "Theta = np.float32 (theta) delta = np.divide (np.float32 ( vzdialenosť), np.float32 (E_RADIUS)) def to_radians (theta): návrat np.divide (np.dot (theta, np.pi), np.float32 (180.0)) def to_degrees (theta): návrat np.divide ( np.dot (theta, np.float32 (180.0)), np.pi) theta = to_radians (theta) lat1 = to_radians (self.lat) lng1 = to_radians (self.lng) lat2 = np.arcsin (np.sin ( lat1) * np.cos (delta) + np.cos (lat1) * np.sin (delta) * np.cos (theta)) lng2 = lng1 + np.arctan2 (np.sin (theta) * np.sin ( delta) * np.cos (lat1), np.cos (delta) - np.sin (lat1) * np.sin (lat2)) lng2 = (lng2 + 3 * np.pi)% (2 * np.pi) - np.pi návrat LatLng (to_degrees (lat2), to_degrees (lng2))

Nasledujúci postup používam pri určovaní nasledujúcej súradnice vzhľadom na smer a vzdialenosť od predchádzajúcej súradnice. S iným prístupom, ktorý som čítal z internetu, mám problém s presnosťou.

Používam to pri určovaní oblasti pôdy, ktorá je mnohouholníkom, a vykreslím tento mnohouholník do aplikácie Google Earth. Názov krajiny má zameranie a vzdialenosti napísané týmto spôsobom: „Severný Juh x stupňov y minút Východných Západov, z metrov do bodu n;“.

Takže počnúc danými súradnicami referenčného bodu najskôr vypočítam vzdialenosť na jeden stupeň zemepisnej šírky a jeden stupeň zemepisnej dĺžky pomocou vzorca Haversine, pretože ten sa líši v závislosti od polohy. Potom určím ďalšiu súradnicu z trigonometrického sínusového a kosínového vzorca.

Nižšie je uvedený javascript:

var mapCenter = nový google.maps.LatLng (referencePointLatitude, referencePointLongitude); // je potrebné uviesť ref point lat a lon, zvyčajne značku (BLLM) var latDiv = latDiv (mapCenter); // vzdialenosť na jeden stupeň zemepisnej šírky na tomto mieste var lngDiv = lngDiv (mapCenter); // vzdialenosť na jeden stupeň zemepisnej dĺžky v tomto mieste var LatLng2 = NextCoord (PrevCoord, NorthOrSouth, x, y, EastOrWest, z); // ďalšia súradnica vzhľadom na smer a vzdialenosť od predchádzajúcej súradnice var Lat2 = LatLng2.lat (); // ďalšia zemepisná šírka súradnice v stupňoch var Lng2 = LatLng2.lng (); // ďalšia zemepisná dĺžka súradnice v stupňoch var polygón = [p1, p2, ..., pn-1, pn, p1]; // p1, p2 atď. sú súradnice bodov mnohouholníka, teda nadpis pozemku. Nezabudnite uzavrieť mnohouholník k počiatočnému bodu p1 var area = Area (polygon); // plocha mnohouholníka v sq.m. funkcia NextCoord (PrevCoord, NorthOrSouth, x, y, EastOrWest, z) {var uhol = (x + (y / 60)) * Math.PI / 180; var a = 1; var b = 1; if (NorthOrSouth == 'Juh') {a = -1; } if (EastOrWest == 'Západ') {b = -1; } var nextLat = PrevCoord.lat () + (a * z * Math.cos (uhol) / latDiv); var nextLng = PrevCoord.lng () + (b * z * Math.sin (uhol) / lngDiv); var nextCoord = nový google.maps.LatLng (nextLat, nextLng); návrat nextCoord; } funkcia latDiv (mapCenter) {var p1 = nový google.maps.LatLng (mapCenter.lat () - 0,5, mapCenter.lng ()); var p2 = nový google.maps.LatLng (mapCenter.lat () + 0,5, mapCenter.lng ()); spiatočná vzdialenosť (p1, p2); } funkcia lngDiv (mapCenter) {var p3 = nový google.maps.LatLng (mapCenter.lat (), mapCenter.lng () - 0,5); var p4 = nový google.maps.LatLng (mapCenter.lat (), mapCenter.lng () + 0,5); spiatočná vzdialenosť (p3, p4); } funkcia dist (pt1, pt2) {var dLat = (pt2.lat () - pt1.lat ()) * Math.PI / 180; var dLng = (pt2.lng () - pt1.lng ()) * Math.PI / 180; var a = Math.sin (dLat / 2) * Math.sin (dLat / 2) + Math.cos (rad (pt1.lat ())) * Math.cos (rad (pt2.lat ())) * Math .sin (dLng / 2) * Math.sin (dLng / 2); var R = 6372800; // zemský polomer var vzdialenosť = R * 2 * Math.atan2 (Math.sqrt (a), Math.sqrt (1-a)); spiatočná vzdialenosť; } funkcia Plocha (mnohouholník) {var xPts = []; pre (i = 1; i

Pozri si video: doc. RNDr. Zbyněk KUBÁČEK, CSc. Dve tváre matematiky