बिंदु से अक्षांश / देशांतर X मील की गणना?


46

मैं एक अक्षांश और देशांतर बिंदु ढूंढना चाहता हूं जिसे एक असर, एक दूरी और एक शुरुआती अक्षांश और देशांतर दिया गया है।

यह इस प्रश्न के विपरीत प्रतीत होता है ( lat / long points के बीच की दूरी )।

मैंने पहले ही हावरसाइन फॉर्मूले पर गौर किया है और लगता है कि यह दुनिया का अनुमान है कि यह काफी करीब है।

मैं यह मान रहा हूं कि मुझे अपने अज्ञात लेट / लॉन्ग के लिए हैवरसिन सूत्र को हल करने की आवश्यकता है, क्या यह सही है? क्या कोई अच्छी वेबसाइट्स हैं जो इस तरह की बात करती हैं? ऐसा लगता है कि यह आम होगा, लेकिन मेरी गुगली ने ऊपर दिए गए सवालों के समान ही कर दिया है।

मैं वास्तव में जिस चीज की तलाश कर रहा हूं वह सिर्फ इसके लिए एक फार्मूला है। मैं इसे एक शुरुआती लैट / lng, एक असर, और एक दूरी (मील या किलोमीटर) देना चाहूंगा और मैं इसे एक अव्यक्त / lng जोड़ी से बाहर निकलना चाहूंगा जो यह दर्शाता है कि जहां एक ने समाप्त किया होगा, उन्होंने साथ यात्रा की थी वह मार्ग।


क्या आप एक ऐसे टूल की तलाश कर रहे हैं जो ऐसा करता हो (जैसे Esri का pe.dll) या एक फॉर्मूला?
कर्क कूकेन्डल

क्षमा करें, मैं विशिष्ट नहीं था ... मुझे एक सूत्र की तलाश है। मैं अपने प्रश्न को और अधिक विशिष्ट होने के लिए अपडेट करूंगा।
जेसन व्हाइटहॉर्न

काम किए गए गणित के नमूनों का गुच्छा यहाँ हैं <a href=" movable-type.co.uk/scripts/latlong.html"> अक्षांश / देशांतर बिंदुओं के बीच दूरी, असर और अधिक की गणना करें जिसमें "गंतव्य का समाधान शामिल है पॉइंट दी गई दूरी और स्टार्ट पॉइंट से बेअरिंग ”।
स्टीफन क्वान

1
बारीकी से संबंधित: gis.stackexchange.com/questions/2951/…
whuber

यहाँ पेज लिंक अक्षां के लिए / लंबे गणना [अक्षांश / लंबे गणना] (जो movable-type.co.uk/scripts/latlong.html ) भी इस पेज अक्षांश / लंबे गणना एक कोड + कैलकुलेटर वहाँ
Abo gaseem

जवाबों:


21

मुझे उत्सुकता होगी कि इस फॉर्मूले के परिणाम Esri के pe.dll के साथ कैसे तुलना करेंगे

( उद्धरण )

एक बिंदु {लाट, लोन} बिंदु 1 से tc रेडियल पर एक दूरी d है:

 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

यह एल्गोरिथ्म ऐसी दूरी तक सीमित है जो कि dlon <pi / 2 है, यानी जो देशांतर में पृथ्वी की परिधि के एक चौथाई से भी कम के आसपास का विस्तार करते हैं। पूरी तरह से सामान्य, लेकिन अधिक जटिल एल्गोरिथ्म आवश्यक है यदि अधिक से अधिक दूरी की अनुमति है:

 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

यहाँ परीक्षण के लिए एक html पृष्ठ है


त्वरित उत्तर के लिए धन्यवाद। मुझे इस जानकारी को पचाने दो, और मैं तुम्हारे साथ वापस आऊंगा। हालांकि, सतह पर, यह जगह पर दिखता है।
जेसन व्हाइटहॉर्न

1
मैंने 3200, 117W से 40N, 82W के लिए html पृष्ठ से दूरी और आगे azimuth को प्राप्त करने के बाद pe.dll (वास्तव में Solaris पर libpe.so) का उपयोग करके प्रत्यक्ष मामले की कोशिश की। 32N, 117W, d = 3255.056515890041, azi = 64.24498012065699 का उपयोग करके, मुझे 40N, 82W (वास्तव में 82.00000000064) मिला।
mkennedy

3
बहुत बढ़िया! एड विलियम्स द्वारा एविएशन फॉर्म्युलेरी लेख के लिंक के लिए बहुत-बहुत धन्यवाद, मैंने इससे पहले नहीं देखा था लेकिन यह अब तक एक बेहतरीन रीड साबित हुआ है। भविष्य में इसे देखने वाले किसी भी व्यक्ति के लिए बस एक नोट, इस सूत्र के इनपुट और आउटपुट सभी रेडियन में हैं, यहां तक ​​कि दूरी भी।
जेसन व्हाइटहॉर्न

1
इस सूत्र में दूरी की इकाई क्या है?
कार्तिक मुरुगन

1
@KarthikMurugan एड का परिचय कहता है कि दूरी इकाइयां एक महान सर्कल के साथ रेडियन में हैं।
कर्क कुक्केंडल

18

यदि आप एक समतल में थे, तो वह बिंदु जो उत्तर पूर्व से एक डिग्री की दूरी पर r मीटर की दूरी पर है , उत्तर दिशा में r * cos (a) और r * sin (a) से पूर्व दिशा में विस्थापित होता है। (ये कथन कमोबेश साइन और कोसाइन को परिभाषित करते हैं।)

यद्यपि आप एक विमान में नहीं हैं - आप एक घुमावदार दीर्घवृत्त की सतह पर काम कर रहे हैं जो पृथ्वी की सतह को मॉडल करता है - कुछ सौ किलोमीटर से कम की दूरी सतह के इतने छोटे हिस्से को कवर करती है जो कि अधिकांश व्यावहारिक उद्देश्यों के लिए हो सकता है फ्लैट माना जाता है। केवल शेष जटिलता यह है कि देशांतर का एक डिग्री अक्षांश के समान दूरी के समान दूरी को कवर नहीं करता है। एक गोलाकार पृथ्वी मॉडल में, देशांतर का एक डिग्री केवल अक्षांश (अक्षांश) होता है जब तक अक्षांश के एक डिग्री के रूप में। (एक दीर्घवृत्त मॉडल में, यह अभी भी एक उत्कृष्ट सन्निकटन है, लगभग 2.5 महत्वपूर्ण आंकड़ों के लिए अच्छा है।)

अंत में, अक्षांश का एक डिग्री लगभग 10 ^ 7/90 = 111,111 मीटर है। अब हमारे पास मीटर को डिग्री में बदलने के लिए आवश्यक सभी जानकारी है:

उत्तर की ओर विस्थापन r * cos (a) / 111111 डिग्री है;

पूर्व की ओर विस्थापन r * sin (a) / cos (अक्षांश) / 111111 डिग्री है।

उदाहरण के लिए, -0.31399 डिग्री के अक्षांश और उत्तर के पूर्व में 30 डिग्री की दूरी पर, हम गणना कर सकते हैं

cos(a) = cos(30 degrees) = cos(pi/6 radians) = Sqrt(3)/2 = 0.866025.
sin(a) = sin(30 degrees) = sin(pi/6 radians) = 1/2 = 0.5.
cos(latitude) = cos(-0.31399 degrees) = cos(-0.00548016 radian) = 0.999984984.
r = 100 meters.
east displacement = 100 * 0.5 / 0.999984984 / 111111 = 0.000450007 degree.
north displacement = 100 * 0.866025 / 111111 = 0.000779423 degree.

Whence, (-78.4437, -0.31399) से शुरू होकर, नया स्थान (-78.4437 + 0.00045, -0.31399 + 0.0007794) = (-78.4432, -0.31321111) पर है।

आधुनिक ITRF00 संदर्भ प्रणाली में एक अधिक सटीक उत्तर है, (-78.4433, -0.313207): यह अनुमानित उत्तर से 0.43 मीटर की दूरी पर है, इस मामले में सन्निकट खामियों का संकेत 0.43% है। उच्च सटीकता प्राप्त करने के लिए आपको या तो दीर्घवृत्त दूरी के फार्मूले (जो कहीं अधिक जटिल हैं) या शून्य विचलन के साथ एक उच्च-निष्ठा अनुरूप प्रक्षेपण का उपयोग करना चाहिए (ताकि असर सही हो)।


2
गणितीय संदर्भ (यानी, इसके स्थानीय विमान) को ठीक से समझने के लिए +1
फ्रैंक कॉन्री

4

यदि आपको एक जावास्क्रिप्ट समाधान की आवश्यकता है, तो इन पर functionsऔर इस पर विचार करें :

var gis = {
  /**
  * All coordinates expected EPSG:4326
  * @param {Array} start Expected [lon, lat]
  * @param {Array} end Expected [lon, lat]
  * @return {number} Distance - meter.
  */
  calculateDistance: function(start, end) {
    var lat1 = parseFloat(start[1]),
        lon1 = parseFloat(start[0]),
        lat2 = parseFloat(end[1]),
        lon2 = parseFloat(end[0]);

    return gis.sphericalCosinus(lat1, lon1, lat2, lon2);
  },

  /**
  * All coordinates expected EPSG:4326
  * @param {number} lat1 Start Latitude
  * @param {number} lon1 Start Longitude
  * @param {number} lat2 End Latitude
  * @param {number} lon2 End Longitude
  * @return {number} Distance - meters.
  */
  sphericalCosinus: function(lat1, lon1, lat2, lon2) {
    var radius = 6371e3; // meters
    var dLon = gis.toRad(lon2 - lon1),
        lat1 = gis.toRad(lat1),
        lat2 = gis.toRad(lat2),
        distance = Math.acos(Math.sin(lat1) * Math.sin(lat2) +
            Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLon)) * radius;

    return distance;
  },

  /**
  * @param {Array} coord Expected [lon, lat] EPSG:4326
  * @param {number} bearing Bearing in degrees
  * @param {number} distance Distance in meters
  * @return {Array} Lon-lat coordinate.
  */
  createCoord: function(coord, bearing, distance) {
    /** http://www.movable-type.co.uk/scripts/latlong.html
    * φ is latitude, λ is longitude, 
    * θ is the bearing (clockwise from north), 
    * δ is the angular distance d/R; 
    * d being the distance travelled, R the earth’s radius*
    **/
    var 
      radius = 6371e3, // meters
      δ = Number(distance) / radius, // angular distance in radians
      θ = gis.toRad(Number(bearing));
      φ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));
    // normalise to -180..+180°
    λ2 = (λ2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI; 

    return [gis.toDeg(λ2), gis.toDeg(φ2)];
  },
  /**
   * All coordinates expected EPSG:4326
   * @param {Array} start Expected [lon, lat]
   * @param {Array} end Expected [lon, lat]
   * @return {number} Bearing in degrees.
   */
  getBearing: function(start, end){
    var
      startLat = gis.toRad(start[1]),
      startLong = gis.toRad(start[0]),
      endLat = gis.toRad(end[1]),
      endLong = gis.toRad(end[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);
    }

    return (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; }
};

इसलिए यदि आप एक नए समन्वय की गणना करना चाहते हैं, तो यह ऐसा हो सकता है:

var start = [15, 38.70250];
var end = [21.54967, 38.70250];
var total_distance = gis.calculateDistance(start, end); // meters
var percent = 10;
// this can be also meters
var distance = (percent / 100) * total_distance;
var bearing = gis.getBearing(start, end);
var new_coord = gis.createCoord(icon_coord, bearing, distance);

2

मुझे यह ObjectiveC में काम कर रहा है। यहां कुंजी यह जान रही है कि आपको रेडियन में lat / lng अंक की आवश्यकता है और समीकरण को लागू करने के बाद आपको उन्हें lat / lng में बदलने की आवश्यकता है। यह भी जान लें कि दूरी और tc रेडियन में हैं।

यहाँ मूल समीकरण है:

 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

यहां इसे ओबीसी में लागू किया गया है जहां रेडियन एन (जैसे पीआई / 2 डब्ल्यू है, पीआई एस है, 2 पीआई / 3 ई है) से घड़ी की दूरी पर मापा गया एक रेडियन है और दूरी किलोमीटर में है।

+ (CLLocationCoordinate2D)displaceLatLng:(CLLocationCoordinate2D)coordinate2D withRadian:(double)radian
                            withDistance:(CGFloat)distance {
  double lat1Radians = coordinate2D.latitude * (M_PI / 180);
  double lon1Radians = coordinate2D.longitude * (M_PI / 180);
  double distanceRadians = distance / 6371;
  double lat = asin(sin(lat1Radians)*cos(distanceRadians)+cos(lat1Radians)*sin(distanceRadians)
      *cos(radian));
  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;
  }
  double newLat = lat * (180 / M_PI);
  double newLon = lon * (180 / M_PI);
  return CLLocationCoordinate2DMake(newLat, newLon);
}

मैं एक समाधान की तलाश में हूं जहां मैं 4 लाट प्राप्त करना चाहता हूं, उस बिंदु से लंबे समय तक जहां मैं 50 मील उत्तर, 50 मील पश्चिम, 50 मील पूर्व और इतने पर खड़ा हूं ... उपरोक्त उत्तर में आप बता सकते हैं कि मैं कैसे प्राप्त कर सकता हूं इस ?
राहुल व्यास

1

यदि आप बेहतर सटीकता में रुचि रखते हैं, तो विन्सेन्टी है । (लिंक 'प्रत्यक्ष' रूप में है, जो वास्तव में आपके बाद है)।

यदि आप कोड के बाद हैं, तो कुछ मौजूदा कार्यान्वयन हैं।

इसके अलावा, एक सवाल: आप यह नहीं मान रहे हैं कि यात्री पूरी यात्रा के लिए समान असर रखता है? यदि हां, तो ये विधियाँ सही प्रश्न का उत्तर नहीं दे रही हैं। (आप व्यापारी को पेश करने से बेहतर होंगे, एक सीधी रेखा खींचना, फिर परिणाम का अनुमान लगाना।)


बहुत अच्छा सवाल है, मेरे सवाल में शब्दांकन के बावजूद जो यह संकेत दे सकता है कि मैं एक यात्री के लिए एक गंतव्य की गणना कर रहा था, मैं नहीं हूं। हालांकि अच्छी बात है। यह मुख्य रूप से इतना था कि मैं एक सीमा क्षेत्र (एक छोटे से आदेश पर, 50 मील की दूरी पर) की गणना कर सकता था ... मुझे आशा है कि समझ में आता है।
जेसन व्हाइटहॉर्न 3

gis.stackexchange.com/questions/3264/… में एक ही सवाल था (एक बिंदु और दूरी से सीमा क्षेत्रों का निर्माण)
दान एस।

0

यहाँ एक पायथन समाधान है:

    def displace(self, theta, distance):
    """
    Displace a LatLng theta degrees counterclockwise and some
    meters in that direction.
    Notes:
        http://www.movable-type.co.uk/scripts/latlong.html
        0 DEGREES IS THE VERTICAL Y AXIS! IMPORTANT!
    Args:
        theta:    A number in degrees.
        distance: A number in meters.
    Returns:
        A new LatLng.
    """
    theta = np.float32(theta)

    delta = np.divide(np.float32(distance), np.float32(E_RADIUS))

    def to_radians(theta):
        return np.divide(np.dot(theta, np.pi), np.float32(180.0))

    def to_degrees(theta):
        return 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

    return LatLng(to_degrees(lat2), to_degrees(lng2))

-2

मैं नीचे दिए गए दृष्टिकोण का उपयोग करता हूं जो अगले समन्वय को निर्धारित करने के लिए दिया गया है जो पिछले समन्वय से असर और दूरी है। मुझे इंटरनेट से पढ़ने वाले अन्य दृष्टिकोण के साथ सटीकता पर समस्या है।

मैं इसका उपयोग भूमि के क्षेत्र को निर्धारित करने में करता हूं, जो एक बहुभुज है, और उस बहुभुज को गूगल अर्थ में प्लॉट करता है। एक लैंड टाइटल में इस तरह से बेयरिंग और डिस्टेंस लिखा होता है: "नॉर्थऑराउथ एक्स डिग्री वाई मिनट्स ईस्टऑरेस्ट, जेड मीटर टू पॉइंट एन"।

इसलिए, संदर्भ बिंदु के दिए गए निर्देशांक से शुरू करते हुए, मैं पहली बार प्रति डिग्री एक अक्षांश की दूरी और हैवेरिन सूत्र का उपयोग करके एक डिग्री देशांतर की गणना करता हूं क्योंकि यह स्थान के आधार पर भिन्न होता है। फिर मैं त्रिकोणमिति साइन और कोसाइन सूत्र से अगला समन्वय निर्धारित करता हूं।

नीचे जावास्क्रिप्ट है:

var mapCenter = new google.maps.LatLng(referencePointLatitude, referencePointLongitude); //the ref point lat and lon must be given, usually a land mark (BLLM)
var latDiv = latDiv(mapCenter); //distance per one degree latitude in this location
var lngDiv = lngDiv(mapCenter); //distance per one degree longitude in this location
var LatLng2 = NextCoord(PrevCoord,NorthOrSouth,x,y,EastOrWest,z); //next coordinate given the bearing and distance from previous coordinate
var Lat2 = LatLng2.lat(); //next coord latitude in degrees
var Lng2 = LatLng2.lng(); //next coord longitude in degrees
var polygon=[p1,p2,...,pn-1,pn,p1]; //p1,p2,etc. are the coordinates of points of the polygon, i.e. the land Title. Be sure to close the polygon to the point of beginning p1
var area = Area(polygon); //area of the polygon in sq.m.
function NextCoord(PrevCoord,NorthOrSouth,x,y,EastOrWest,z) {
  var angle = ( x + ( y / 60 ) ) * Math.PI / 180;
  var a = 1;
  var b = 1;
  if (NorthOrSouth == 'South') { a = -1; }
  if (EastOrWest == 'West') { b = -1; }
  var nextLat = PrevCoord.lat() +  ( a * z * Math.cos(angle) / latDiv );
  var nextLng = PrevCoord.lng() +  ( b * z * Math.sin(angle) / lngDiv );
  var nextCoord = new google.maps.LatLng(nextLat, nextLng);
  return nextCoord;
}
function latDiv(mapCenter) {
  var p1 = new google.maps.LatLng(mapCenter.lat()-0.5, mapCenter.lng());
  var p2 = new google.maps.LatLng(mapCenter.lat()+0.5, mapCenter.lng());
  return dist(p1,p2);
}
function lngDiv(mapCenter) {
  var p3 = new google.maps.LatLng(mapCenter.lat(), mapCenter.lng()-0.5);
  var p4 = new google.maps.LatLng(mapCenter.lat(), mapCenter.lng()+0.5);
  return dist(p3,p4);
}
function 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; //earth's radius
    var distance = R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return distance;
}
function Area(polygon) {
  var xPts=[];
  for (i=1; i&lt;polygon.length; i++) {
    xPts[i-1] = ( polygon[i].lat() - polygon[0].lat() ) * latDiv;
  }
  var yPts=[];
  for (i=1; i&lt;polygon.length; i++) {
    yPts[i-1] = ( polygon[i].lng() - polygon[0].lng() ) * lngDiv;
  }
  var area = 0;
  j = polygon.length-2;
  for (i=0; i&lt;polygon.length-1; i++) {
    area = area +  ( xPts[j] + xPts[i] ) * ( yPts[j] - yPts[i] );
    j = i;
  }
  area = Math.abs(area/2);
  return area;
}

1
बहुभुज क्षेत्र के लिए कार्टेशियन फॉर्मूला जिसे आप यहां लागू करने का प्रयास करते हैं, वह घुमावदार सतह (जैसे गोलाकार) पर गणना की गई दूरी और कोण पर लागू नहीं होता है। यह सूत्र अक्षांश और देशांतर का उपयोग करके एक अतिरिक्त त्रुटि करता है जैसे कि वे कार्टेशियन निर्देशांक थे। केवल उन परिस्थितियों में जिनके उपयोग पर विचार किया जा सकता है, वे बिल्कुल (बहुत छोटे बहुभुजों के लिए) होंगे जहां हावरसाइन सूत्र वैसे भी अनावश्यक है। कुल मिलाकर यह प्रतीत होता है कि यह कोड बिना किसी लाभ के बहुत अधिक मेहनत करता है।
whuber
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.