আমি তিনটি পয়েন্ট দ্বারা সংজ্ঞায়িত জিওডেসিক সাম্য বিস্ময়কর বিন্দুটি খুঁজতে আরকিজিআইএস 10.1 কীভাবে ব্যবহার করতে পারি?


12

উদাহরণস্বরূপ, উপকূলরেখার উপরে আমার তিনটি বেস পয়েন্টের জন্য স্থানাঙ্ক রয়েছে এবং উপকূলের বাইরে পয়েন্টের স্থানাঙ্কগুলি আমার সন্ধান করতে হবে যা তিনটি থেকে সমতুল্য। এটি জ্যামিতির ক্ষেত্রে একটি সাধারণ অনুশীলন, তবে সমস্ত পরিমাপ অবশ্যই জিওডেসিকে বিবেচনায় নিতে হবে।

আমি যদি এটি ইউক্লিডীয় পদ্ধতিতে পৌঁছে যাচ্ছিলাম, তবে আমি বেস পয়েন্টগুলি সংযুক্ত জিওডেসিক পাথগুলি পরিমাপ করতে পারতাম, ফলস্বরূপ ত্রিভুজের পাশের মিডপয়েন্টগুলি সন্ধান করতে পারি এবং path প্রতিটি পথের জন্য লম্ব গোঁড়া তৈরি করতে পারি। তিনটি লাক্সড্রোম সম্ভবত সমমানের স্থানে রূপান্তরিত করবে। যদি এটি সঠিক পদ্ধতি হয় তবে এটির জন্য আর্কে করার সহজ উপায় হতে পারে।

আমার ও খুঁজে পাওয়া দরকার


3 পয়েন্টের আপেক্ষিক পজিশনে বাধা আছে? পূর্ব উপকূলের চিত্র, মাঝের বিন্দুটি সবচেয়ে পূর্ব দিকে east আপনার দ্রবণগুলি কাজ করতে পারে না যেহেতু খণ্ডকগুলি অফশোরকে রূপান্তরিত করে না। আমি নিশ্চিত যে আমরা অন্যান্য খারাপ মামলা নিয়ে আসতে পারি!
মেকনেডি

আমি ভাবছি আপনি যদি প্রোজেকশন সংরক্ষণের জন্য কোনও দূরত্ব ব্যবহার করতে পারেন এবং সেখান থেকে গননাটি চালাতে পারেন? প্রগনোস / ফুরুতি / ম্যাপপ্রোজ / সাধারণ / কার্টপ্রপ / ডিস্টপ্রেস / it এটি করার জন্য অ্যালগরিদম সম্পর্কে নিশ্চিত নন, একটি অবশ্যই থাকতে হবে ... সম্ভবত এটি ব্যারেন্সেন্টার: en.wikedia.org/wiki/Barycentric_coordinate_system
অ্যালেক্স লিথ

একটি ঘনিষ্ঠভাবে সম্পর্কিত সমস্যার সমাধানের জন্য, "ত্রিপক্ষীয়" এর জন্য আমাদের সাইটটি অনুসন্ধান করুন । এছাড়াও, gis.stackexchange.com/questions/10332/… একটি সদৃশ তবে এর যথাযথ উত্তর নেই (সম্ভবত সম্ভবত প্রশ্নটি বিভ্রান্ত উপায়ে জিজ্ঞাসা করা হয়েছিল)।
whuber

@ মেকনেডি নীতিগতভাবে, কোনও খারাপ ক্ষেত্রে নেই, কেবল সংখ্যাগতভাবে অস্থিরতা রয়েছে। তিনটি বেস পয়েন্ট কলিনারি হলে এগুলি ঘটে; দুটি সমাধান (একটি গোলাকৃতির মডেলের উপর) সাধারণ জিওডেসিকের দুটি মেরুতে ঘটে; উপবৃত্তাকার মডেলটিতে এগুলি ঘটে যেখানে where খুঁটিগুলি প্রত্যাশিত হবে।
হুবুহু

এখানে লাক্সড্রোমগুলির ব্যবহার সঠিক হবে না: এগুলি লম্ব দ্বিখণ্ডক নয়। গোলকটিতে, এই রেখাগুলি দুর্দান্ত চেনাশোনাগুলির অংশ (জিওডিক্স) হবে তবে উপবৃত্তাকারে, তারা জিওডিক্স হতে কিছুটা দূরে চলে যাবে।
হোয়াট

উত্তর:


10

এই উত্তরটি একাধিক বিভাগে বিভক্ত:

  • "ক্যানড" রুটিনগুলির সাহায্যে কাঙ্ক্ষিত বিন্দুটি কীভাবে খুঁজে পাওয়া যায় তা দেখিয়ে সমস্যার বিশ্লেষণ এবং হ্রাস

  • উদাহরণ: একটি ওয়ার্কিং প্রোটোটাইপ , ওয়ার্কিং কোড দেয়।

  • উদাহরণ , সমাধানগুলির উদাহরণ দেখানো।

  • Pitfalls , সম্ভাব্য সমস্যার আলোচনা এবং কিভাবে তাদের সঙ্গে মানিয়ে নিতে।

  • আর্কজিআইএস বাস্তবায়ন , একটি কাস্টম আর্কজিআইএস সরঞ্জাম তৈরি করার বিষয়ে মন্তব্য এবং প্রয়োজনীয় রুটিনগুলি কোথায় পাবেন।


সমস্যাটির বিশ্লেষণ ও হ্রাস

এর যে নিরীক্ষক (পুরোপুরি বৃত্তাকার) গোলাকৃতি মডেল দ্বারা শুরু করা যাক সেখানে হবে সবসময় একটি সমাধান হতে সত্য --in, ঠিক দুই সমাধান। বেস পয়েন্টগুলি এ, বি এবং সি দেওয়া, প্রতিটি জুটি তার "লম্ব দ্বিখণ্ডক" নির্ধারণ করে, যা প্রদত্ত দুটি বিন্দু থেকে সমান পয়েন্টের সেট। এই দ্বিখণ্ডক একটি জিওডেসিক (দুর্দান্ত বৃত্ত)। গোলাকার জ্যামিতি উপবৃত্তাকার : যে কোনও দুটি জিওডেসিক ছেদ করে (দুটি অনন্য পয়েন্টে)। সুতরাং, এবি'র দ্বিখণ্ডক এবং বিসি-র দ্বিখণ্ডকের ছেদ পয়েন্টগুলি হ'ল সংজ্ঞা অনুসারে - এ, বি এবং সি থেকে সামঞ্জস্যপূর্ণ, যার ফলে সমস্যার সমাধান হয়। (নীচে প্রথম চিত্র দেখুন।)

উপবৃত্তাকারে বিষয়গুলি আরও জটিল দেখায়, তবে এটি গোলকের একটি ক্ষুদ্র ক্ষুদ্র অংশ, তাই আমরাও একইরকম আচরণ আশা করতে পারি। (এর বিশ্লেষণটি আমাদের অনেক বেশি দূরত্বে নিয়ে যাবে ll) উপবৃত্তাকারে সঠিক দূরত্ব গণনা করতে জটিল সূত্রগুলি (অভ্যন্তরীণভাবে একটি জিআইএসের অভ্যন্তরে) ধারণাগত জটিলতা নয়, যদিও: সমস্যাটি মূলত একই রকম। সমস্যাটি কতটা সহজ তা দেখতে, আসুন এটি কিছুটা বিমূর্তভাবে বলা যাক। এই বিবৃতিতে, "d (U, V)" U এবং V এর পয়েন্টগুলির মধ্যে সত্য, সম্পূর্ণ নির্ভুল দূরত্বকে বোঝায় this

উপবৃত্তাকারে তিনটি বিন্দু A, B, C (ল্যাট-লোন জোড়া হিসাবে) দেওয়া, একটি বিন্দু X সন্ধান করুন যার জন্য (1) d (X, A) = d (X, B) = d (X, C) এবং ( 2) এই সাধারণ দূরত্ব যতটা সম্ভব ছোট।

এই তিনটি দূরত্ব সমস্ত অজানা এক্স এর উপর নির্ভর করে । সুতরাং ইউ (এক্স) = ডি (এক্স, এ) - ডি (এক্স, বি) এবং ভি (এক্স) = ডি (এক্স, বি) - ডি (এক্স, সি) দূরত্বের পার্থক্যগুলি এক্স এর প্রকৃত মূল্যবান ফাংশন are আবার কিছুটা বিমূর্তভাবে আমরা এই পার্থক্যগুলিকে অর্ডারযুক্ত জোড়ায় একত্রিত করতে পারি। এক্স এর স্থানাঙ্ক হিসাবে আমরা (ল্যাট, লোন )ও ব্যবহার করব, এটিও একটি অর্ডারযুক্ত জোড় হিসাবে বিবেচনা করার অনুমতি দেই, এক্স = (ফাই, ল্যাম্বদা) বলুন। এই সেটআপে, ফাংশন

এফ (ফাই, ল্যাম্বদা) = (ইউ (এক্স), ভি (এক্স)

দ্বি-মাত্রিক স্থানের একটি অংশ থেকে দ্বি-মাত্রিক স্থানগুলিতে মান গ্রহণ করে আমাদের সমস্যাটি হ্রাস পায়

সমস্ত সম্ভাব্য (ফাই, ল্যাম্বদা) অনুসন্ধান করুন যার জন্য এফ (ফাই, ল্যাম্বদা) = (0,0)।

এখানে বিমূর্ততা প্রদান করে: এটি সমাধানের জন্য প্রচুর দুর্দান্ত সফ্টওয়্যার উপস্থিত রয়েছে (খাঁটি সংখ্যাটি বহুমাত্রিক মূল অনুসন্ধান) সমস্যাটি সমাধান করার জন্য। এটি যেভাবে কাজ করে তা হ'ল আপনি এফ গণনা করার জন্য একটি রুটিন লিখেছেন , তারপরে আপনি সফ্টওয়্যারটির সাথে তার ইনপুটটিতে বিধিনিষেধ সম্পর্কিত কোনও তথ্যও সরবরাহ করবেন ( ফাই অবশ্যই -90 এবং 90 ডিগ্রি এবং লাম্বডা অবশ্যই -180 এবং 180 এর মধ্যে থাকা উচিত ডিগ্রী). এটি একটি সেকেন্ডের ভগ্নাংশের জন্য দূরে সরে যায় এবং যদি এটির সন্ধান করতে পারে তবে (সাধারণত) কেবলমাত্র একটি ফাই ( ফাই , ল্যাম্বদা ) ফেরত দেয় ।

হ্যান্ডেল করার জন্য বিশদ রয়েছে, কারণ এটির একটি শিল্প রয়েছে: এফ "আচরণ করে" তার উপর নির্ভর করে বেছে নেওয়া বিভিন্ন সমাধান পদ্ধতি রয়েছে ; এটি তার অনুসন্ধানের জন্য যুক্তিসঙ্গত প্রারম্ভিক বিন্দু দিয়ে সফ্টওয়্যারটিকে "চালিত" করতে সহায়তা করে (এটি অন্য উপায়গুলির চেয়ে নিকটতম সমাধানটি পেতে পারি এমন এক উপায় ); এবং আপনি সাধারণত সমাধানটি কীভাবে সঠিক হতে চান তা নির্দিষ্ট করতে হবে (সুতরাং অনুসন্ধান কখন থামাতে হবে তা তা জানে)। (জিআইএস বিশ্লেষকদের এই জাতীয় বিবরণ সম্পর্কে যা জানা দরকার, যা জিআইএস সমস্যার ক্ষেত্রে প্রচুর পরিমাণে আসে, সে সম্পর্কে আরও তথ্যের জন্য দয়া করে জিওপ্যাটিয়াল টেকনোলজিস কোর্সের জন্য কম্পিউটার সায়েন্সে অন্তর্ভুক্ত করার জন্য বিষয়গুলি সুপারিশ করুন এবং শেষের নিকটে "বিবিধ" বিভাগটি দেখুন। )


উদাহরণ: একটি ওয়ার্কিং প্রোটোটাইপ

বিশ্লেষণে দেখা যায় যে আমাদের দুটি বিষয় প্রোগ্রাম করতে হবে: সমাধানের অশোধিত প্রাথমিক অনুমান এবং নিজেই এফের গণনা ।

প্রাথমিক অনুমানটি তিনটি বেস পয়েন্টের একটি "গোলাকার গড়" দ্বারা তৈরি করা যেতে পারে। এটি জিওসেন্ট্রিক কার্টেসিয়ান (এক্স, ওয়াই, জেড) স্থানাঙ্কগুলিতে তাদের প্রতিনিধিত্ব করে, সেই স্থানাঙ্কগুলির গড় গড়ে, এবং সেই গোলকে গোল করে গড় গড় উপস্থাপন করে এবং এটি অক্ষাংশ এবং দ্রাঘিমাংশে পুনরায় প্রকাশ করার মাধ্যমে প্রাপ্ত হয়। গোলকের আকার নিরবচ্ছিন্ন এবং গণনাগুলি এর মাধ্যমে সোজাভাবে তৈরি করা হয়: কারণ এটি কেবল একটি সূচনা পয়েন্ট, আমাদের উপবৃত্তাকার গণনার প্রয়োজন নেই।

এই ওয়ার্কিং প্রোটোটাইপের জন্য আমি ম্যাথেমেটিকা 8 ব্যবহার করেছি ।

sphericalMean[points_] := Module[{sToC, cToS, cMean},
  sToC[{f_, l_}] := {Cos[f] Cos[l], Cos[f] Sin[l], Sin[f]};
  cToS[{x_, y_, z_}] := {ArcTan[x, y], ArcTan[Norm[{x, y}], z]};
  cMean = Mean[sToC /@ (points Degree)];
  If[Norm[Most@cMean] < 10^(-8), Mean[points], cToS[cMean]] / Degree
  ]

(চূড়ান্ত Ifশর্তটি পরীক্ষা করে যে গড়টি দ্রাঘিমাংশ নির্দেশিত করতে স্পষ্টভাবে ব্যর্থ হতে পারে কিনা; যদি তা হয় তবে এটি এর ইনপুটটির অক্ষাংশ এবং দ্রাঘিমাংশের একটি সোজা গাণিতিক গড়ের দিকে ফিরে যায় - সম্ভবত কোনও দুর্দান্ত পছন্দ নয়, তবে কমপক্ষে একটি বৈধ মান রয়েছে। এই কোডটি প্রয়োগের গাইডেন্সের জন্য যারা ব্যবহার করছেন তাদের জন্য নোট করুন যে ম্যাথমেটিকার যুক্তিগুলি ArcTanঅন্যান্য অন্যান্য বাস্তবায়নের তুলনায় বিপরীত হয়েছে: এর প্রথম যুক্তিটি এক্স-কো-অর্ডিনেট, এটির দ্বিতীয়টি y- স্থানাঙ্ক এবং এটি ভেক্টরের দ্বারা তৈরি কোণটি ফিরিয়ে দেয় ( X, Y)।)

দ্বিতীয় অংশটি যতদূর যায়, কারণ গণিত - আর্কজিআইএস এবং প্রায় সমস্ত জিআইএস-এর মতো - উপবৃত্তের উপর সঠিক দূরত্ব গণনার কোড রয়েছে, লেখার মতো কিছুই নেই almost আমরা কেবল মূল অনুসন্ধানের রুটিনকে কল করি:

tri[a_, b_, c_] := Block[{d = sphericalMean[{a, b, c}], sol, f, q},
   sol = FindRoot[{GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, a] == 
                   GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, b] ==
                   GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, c]}, 
           {{f, d[[1]]}, {q, d[[2]]}}, 
           MaxIterations -> 1000, AccuracyGoal -> Infinity, PrecisionGoal -> 8];
   {Mod[f, 180, -90], Mod[q, 360, -180]} /. sol
   ];

এই প্রয়োগের সর্বাধিক লক্ষণীয় দিক হ'ল এটি কীভাবে যথাক্রমে যথাক্রমে 180 এবং 360 ডিগ্রি মডিউলগুলিকে গণনা করে অক্ষাংশ ( f) এবং দ্রাঘিমাংশ ( q) সীমাবদ্ধ করার প্রয়োজনকে ডজ করে । এটি সমস্যার সীমাবদ্ধতা এড়ানো এড়ায় (যা প্রায়শই জটিলতা সৃষ্টি করে)। নিয়ন্ত্রণের প্যারামিটারগুলি MaxIterationsইত্যাদি এই কোডটি যতটা সম্ভব যথাসম্ভব যথাযথতা সরবরাহ করতে তৈরি করা হয়েছে।

এটি কার্যকরভাবে দেখতে, আসুন এটি সম্পর্কিত প্রশ্নে প্রদত্ত তিনটি বেস পয়েন্টগুলিতে প্রয়োগ করুন :

sol = tri @@ (bases = {{-6.28530175, 106.9004975375}, {-6.28955287, 106.89573839}, {-6.28388865789474, 106.908087643421}})

{-6.29692, 106.907}

এই সমাধান এবং তিনটি পয়েন্টের মধ্যে গণিত দূরত্বগুলি

50 1450.23206979, 1450.23206979, 1450.23206978}

(এগুলি মিটার)। তারা একাদশ উল্লেখযোগ্য অঙ্কের মধ্য দিয়ে সম্মতি জানায় (এটি খুব নির্ভুল, আসলে, যেহেতু দূরত্বগুলি মিলিমিটার বা তার চেয়ে বেশি ভাল করার পক্ষে খুব কমই সঠিক)। এই তিনটি পয়েন্ট (কালো), তাদের তিনটি মিউচুয়াল বাইসেক্টর এবং সমাধান (লাল) এর চিত্র এখানে রয়েছে:

চিত্র 1


উদাহরণ

এই বাস্তবায়নটি পরীক্ষা করার জন্য এবং সমস্যাটি কীভাবে আচরণ করে তার আরও ভাল ধারণা পেতে, এখানে তিনটি বিস্তৃত ব্যবধানযুক্ত বেস পয়েন্টের জন্য দূরত্বের মূলের বর্গতুল্য পার্থক্যের মূল কনট্যুর প্লট রয়েছে। (আরএমএসের তফাতটি তিনটি ডিফ (এক্স, এ) -ডি (এক্স, বি), ডি (এক্স, বি) -ডি (এক্স, সি), এবং ডি (এক্স, সি) -ডি (এক্স) তিনটি পার্থক্য গণনা করে প্রাপ্ত হয় , ক), তাদের স্কোয়ারের গড় গড়ে এবং স্কোয়ার রুট গ্রহণ করা X এটি সমস্যাটি শূন্যের সমান যখন এক্স সমস্যা সমাধান করে এবং অন্যথায় এক্স সমাধান থেকে দূরে সরে যাওয়ার সাথে সাথে বৃদ্ধি পায় এবং সুতরাং যে কোনও স্থানে সমাধান হওয়ার জন্য আমরা কীভাবে "নিকটে" রয়েছি তা পরিমাপ করে। )

চিত্র ২

এই প্লেট ক্যারি প্রক্ষেপণে বেস পয়েন্টগুলি (60, -120), (10, -40) এবং (45,10) লাল দেখানো হয়েছে; সমাধান (49.2644488, -49.9052992) - যা গণনা করতে 0.03 সেকেন্ডের প্রয়োজন - হলুদ। সমস্ত প্রাসঙ্গিক দূরত্ব হাজার হাজার কিলোমিটার থাকা সত্ত্বেও এর আরএমএসের তাত্পর্যটি তিন ন্যানোমিটারের চেয়ে কম । অন্ধকার অঞ্চলগুলি আরএমএসের ছোট মানগুলি দেখায় এবং হালকা অঞ্চলগুলি উচ্চ মান দেখায়।

এই মানচিত্রটি পরিষ্কারভাবে আরেকটি সমাধান দেখায় (-49.2018206, 130.0297177) (প্রথম সমাধানের বিপরীতে প্রাথমিক অনুসন্ধানের মানটি ডায়ামেট্রিকভাবে সেট করে দুটি ন্যানোমিটারের একটি আরএমএসে গণনা করা হয়েছে))


pitfalls

সংখ্যাগত অস্থিতিশীলতা

যখন বেস পয়েন্টগুলি প্রায় সমান্তরাল হয় এবং একসাথে ঘনিষ্ঠ হয়, তখন সমস্ত সমাধান প্রায় অর্ধেক বিশ্ব দূরে থাকবে এবং সঠিকভাবে নিচে নামানো খুব কঠিন হবে। কারণটি হ'ল বিশ্বজুড়ে কোনও অবস্থানে ছোট পরিবর্তনগুলি - এটিকে বেস পয়েন্টগুলির দিকে বা দূরে সরিয়ে - দূরত্বের পার্থক্যের মধ্যে কেবল অবিশ্বাস্যরূপে ছোট্ট পরিবর্তন আনতে পারে। ফলাফলটি নীচে নেওয়ার জন্য জিওডেটিক দূরত্বের সাধারণ গণনায় যথেষ্ট যথার্থতা এবং নির্ভুলতা তৈরি হয়নি।

উদাহরণস্বরূপ, বেস পয়েন্টগুলি (45.001, 0), (45, 0) এবং (44.999,0) থেকে শুরু করে, যা প্রতিটি triমেরির মধ্যে কেবল 111 মিটার দ্বারা প্রাইম মেরিডিয়ান বরাবর পৃথক করা হয়েছে, সমাধানটি পান (11.8213, 77.745 )। এটি থেকে বেস পয়েন্টগুলির দূরত্বগুলি 8,127,964.998 77; 8,127,964.998 41; এবং যথাক্রমে 8,127,964.998 65 মিটার। তারা নিকটতম মিলিমিটারে সম্মত! এই ফলাফলটি কতটা যথাযথ হতে পারে তা সম্পর্কে আমি নিশ্চিত নই, তবে অন্য বাস্তবায়নগুলি যদি এর থেকে খুব দূরে অবস্থানগুলি ফিরে আসে তবে তিনটি দূরত্বের প্রায় সমানভাবে সমতা দেখায় তবে অবাক হওয়ার কিছু নেই।

গণনার সময়

এই গণনাগুলি, কারণ এগুলি জটিল দূরত্বের গণনা ব্যবহার করে যথেষ্ট অনুসন্ধানে জড়িত, দ্রুত নয়, সাধারণত একটি সেকেন্ডের লক্ষণীয় ভগ্নাংশের প্রয়োজন হয়। রিয়েল-টাইম অ্যাপ্লিকেশনগুলির এ সম্পর্কে সচেতন হওয়া প্রয়োজন।


আর্কজিআইএস বাস্তবায়ন

পাইথন হ'ল আর্কজিআইএসের জন্য পছন্দের স্ক্রিপ্টিং পরিবেশ (9 সংস্করণ দিয়ে শুরু করা)। Scipy.optimize প্যাকেজ একটি বহুচলকীয় rootfinder হয়েছে rootযা কি করা উচিত FindRootমধ্যে আছে ম্যাথামেটিকাল কোড। অবশ্যই আর্কজিআইএস নিজেই সঠিক উপবৃত্তাকার দূরত্ব গণনার অফার করে। তারপরে বাকী সমস্ত প্রয়োগকরণের বিবরণ: বেস পয়েন্ট স্থানাঙ্কগুলি কীভাবে প্রাপ্ত হবে (কোনও স্তর থেকে? ব্যবহারকারী দ্বারা টাইপ করা? একটি পাঠ্য ফাইল থেকে? মাউস থেকে?) কীভাবে আউটপুট উপস্থাপন করা হবে তা স্থির করুন (স্থানাঙ্ক হিসাবে) স্ক্রিনে প্রদর্শিত হয়? গ্রাফিক পয়েন্ট হিসাবে? একটি লেয়ারে নতুন পয়েন্ট অবজেক্ট হিসাবে?), ইন্টারফেসটি লিখুন, এখানে দেখানো ম্যাথেমেটিক কোডটি পোর্ট করুন (সোজা) এবং আপনি সমস্ত সেট হয়ে যাবেন।


3
+1 খুব পুঙ্খানুপুঙ্খ। আমি মনে করি আপনাকে এই জন্য @ চার্জ দিয়ে চার্জ শুরু করতে হতে পারে।
রাডার

2
@ রাডার ধন্যবাদ আমি আশা করছি লোকেরা যখন আমার বইটি কিনবে তখন (কখন) অবশেষে এটি উপস্থিত হবে :-)।
হোয়াট

1
বিল করবেন ... একটি খসড়া প্রেরণ করুন !!!

অসাধারণ! তবুও, দেখে মনে হচ্ছে কোনও বিশ্লেষণাত্মক সমাধান সম্ভব হবে। সমস্যাটি 3 ডি কার্তেসিয়ান স্পেসে 3 পয়েন্ট এ, বি, সি এবং ই দিয়ে নিয়ে যেখানে E পৃথিবীর কেন্দ্র। পরবর্তী দুটি প্লেন 1 এবং প্লেন 2 আবিষ্কার করুন find প্লেন 1 এমন বিমান হবে যা বিমানের পক্ষে স্বাভাবিক এবং ই, মিডপয়েন্ট (এ, বি) এর মধ্য দিয়ে যায়। তেমনিভাবে, প্লেন 2 বিমান সমতল থেকে ইআর, মিডপয়েন্ট (সি, ই) এর মধ্য দিয়ে সাধারণ হয়ে যাওয়া বিমান হবে। প্লেন 1 এবং প্লেন 2 ছেদ করে তৈরি লাইনও 3 পয়েন্টের সমতুল্য পয়েন্টগুলি উপস্থাপন করে। A (বা B বা C) দুটি পয়েন্টের আরও কাছাকাছি যেখানে লাইনও গোলকটি ছেদ করে point
কুইকেনডাল

এই বিশ্লেষণাত্মক সমাধান, কির্ক, কেবলমাত্র গোলকের ক্ষেত্রে প্রযোজ্য। (উপবৃত্ত সঙ্গে প্লেন চৌমাথা ঋজু bisectors কখনো হয় উপবৃত্ত মেট্রিক মধ্যে কয়েক সুস্পষ্ট ব্যতিক্রমী ক্ষেত্রে ছাড়া। যখন তারা মেরিডিয়ান বা নিরক্ষীয় হয়)
whuber

3

আপনারা যেমন লক্ষ্য করেছেন, সমুদ্রসীমা নির্ধারণে এই সমস্যা দেখা দেয়; এটিকে প্রায়শই "ত্রি-পয়েন্ট" সমস্যা হিসাবে উল্লেখ করা হয় এবং আপনি এটি গুগল করতে পারেন এবং এটি সম্পর্কিত বেশ কয়েকটি কাগজপত্র খুঁজে পেতে পারেন। এই কাগজপত্রগুলির মধ্যে একটি আমার দ্বারা (!) এবং আমি একটি সঠিক এবং দ্রুত অভিজাত সমাধান প্রস্তাব করি। Http://arxiv.org/abs/1102.1215 এর 14 অনুচ্ছেদ দেখুন

পদ্ধতিতে নিম্নলিখিত পদক্ষেপ রয়েছে:

  1. একটি ত্রি-পয়েন্ট হে অনুমান করুন
  2. আজিমুথাল ইক্যুডিস্টিটিভ প্রক্ষেপণের কেন্দ্র হিসাবে ও ব্যবহার করুন
  3. এই অভিক্ষেপে প্রকল্প এ, বি, সি,
  4. এই প্রক্ষেপণে ত্রি-পয়েন্টটি সন্ধান করুন, হে '
  5. প্রক্ষেপণের নতুন কেন্দ্র হিসাবে ও 'ব্যবহার করুন
  6. O 'এবং O একসাথে হওয়া পর্যন্ত পুনরাবৃত্তি করুন

প্রক্ষেপণে ত্রি-দফা সমাধানের প্রয়োজনীয় সূত্রটি কাগজে দেওয়া হয়েছে। যতক্ষণ আপনি একটি নির্ভুল আজিমুথাল ইক্যুডিস্টিটিভ প্রজেকশন ব্যবহার করছেন, উত্তরটি সঠিক হবে। কনভার্জেন্স হ'ল চতুর্ভুজ অর্থ যে কয়েকটি সংখ্যক পুনরাবৃত্তি প্রয়োজন। এটি প্রায় নিশ্চিতভাবেই @ হুবারের দ্বারা প্রস্তাবিত সাধারণ মূল-অনুসন্ধানের পদ্ধতিগুলিকে ছাড়িয়ে যাবে।

আমি আপনাকে সরাসরি অর্জজিআইএসে সহায়তা করতে পারি না। আপনি https://pypi.python.org/pypi/geographiclib থেকে জিওডেসিক গণনা করার জন্য আমার পাইথন প্যাকেজটি ধরতে পারেন এবং এর ভিত্তিতে প্রজেকশনটি কোডিং করা সহজ।


সম্পাদন করা

@ হুইবার্স ডিজেনারেট কেস (৪৫ + ইপিএস, ০) (৪৫,০) (৪৫-ইপিএস, ০)-তে ত্রি-পয়েন্ট সন্ধানের সমস্যাটি কেলে একটি ভোল্টের গোলক , ফিলের জিওডাসিক লাইনে বিবেচনা করেছিলেন । সাময়িক পত্রিকা। (1870), http://books.google.com/books?id=4XGIOoCMYYAC&pg=PA15

এই ক্ষেত্রে, ত্রি-পয়েন্টটি অ্যাজিমুথ 90 এর সাথে (45,0) জিওডেসিক অনুসরণ করে এবং জিওডেসিক স্কেলটি অদৃশ্য হওয়া বিন্দুটি সন্ধান করে প্রাপ্ত হয়। ডাব্লুজিএস 84 এলিপসয়েডের জন্য এই পয়েন্টটি (-0.10690908732248, 89.89291072793167)। (45.001,0), (45,0), (44.999) এর প্রত্যেকটির এই বিন্দু থেকে দূরত্ব 10010287.665788943 মি (একটি ন্যানোমিটারের মধ্যে) is এটি whuber এর অনুমানের চেয়ে প্রায় 1882 কিমি বেশি (এটি কেবল এই কেসটি কতটা অস্থির তা দেখায়)। একটি গোলাকার পৃথিবীর জন্য ত্রি-পয়েন্ট অবশ্যই (0,90) বা (0, -90) হবে।

অ্যাডেন্ডেন্ডাম: এখানে মাতলাব ব্যবহার করে আজিমুথাল সমীকরণ পদ্ধতিটি প্রয়োগ করা হচ্ছে

function [lat, lon] = tripoint(lat1, lon1, lat2, lon2, lat3, lon3)
% Compute point equidistant from arguments
% Requires:
%   http://www.mathworks.com/matlabcentral/fileexchange/39108
%   http://www.mathworks.com/matlabcentral/fileexchange/39366
  lats = [lat1, lat2, lat3];
  lons = [lon1, lon2, lon3];
  lat0 = lat1;  lon0 = lon1; % feeble guess for tri point
  for i = 1:6
    [x, y] = eqdazim_fwd(lat0, lon0, lats, lons);
    a = [x(1), y(1), 0];
    b = [x(2), y(2), 0];
    c = [x(3), y(3), 0];
    z = [0, 0, 1];
    % Eq. (97) of http://arxiv.org/abs/1102.1215
    o = cross((a*a') * (b - c) + (b*b') * (c - a) + (c*c') * (a - b), z) ...
        / (2 * dot(cross(a - b, b - c), z));
    [lat0, lon0] = eqdazim_inv(lat0, lon0, o(1), o(2))
  end
  % optional check
  s12 = geoddistance(lat0, lon0, lats, lons); ds12 = max(s12) - min(s12)
  lat = lat0; lon = lon0;
end

অক্টাভা ব্যবহার করে এটি পরীক্ষা করে দেখছি

অষ্টক: 1> ফর্ম্যাট দীর্ঘ
অষ্টম: 2> [ল্যাট0, লোন0] = ট্রিপয়েন্ট (41, -74,36,140, ​​-41,175)
ল্যাট0 = 15.4151378380375
lon0 = -162.479314381144
lat0 = 15.9969703299812
lon0 = -147.046790722192
ল্যাট0 = 16.2232960167545
lon0 = -147.157646039471
ল্যাট = 16.2233394851560
lon0 = -147.157748279290
ল্যাট = 16.2233394851809
lon0 = -147.157748279312
ল্যাট = 16.2233394851809
lon0 = -147.157748279312
ds12 = 3.72529029846191e-09
ল্যাট = 16.2233394851809
lon0 = -147.157748279312

নিউ ইয়র্ক, টোকিও এবং ওয়েলিংটনের ত্রি-পয়েন্ট হিসাবে as

এই পদ্ধতিটি প্রতিবেশী কলিনিয়ার পয়েন্টগুলির জন্য সঠিক নয়, উদাহরণস্বরূপ, [45.001,0], [45,0], [44.999,0]। সেক্ষেত্রে আজিমুথ 90-এ [45,0] থেকে উদ্ভূত একটি জিওডেসিকের ক্ষেত্রে আপনার 12 = 0 এর সমাধান করা উচিত following নীচের ফাংশনটি কৌশলটি করেছে (নিউটনের পদ্ধতিটি ব্যবহার করে):

function [lat2,lon2] = semiconj(lat1, lon1, azi1)
% Find the point where neighboring parallel geodesics emanating from
% close to [lat1, lon1] with azimuth azi1 intersect.

  % First guess is 90 deg on aux sphere
  [lat2, lon2, ~, ~, m12, M12, M21, s12] = ...
      geodreckon(lat1, lon1, 90, azi1, defaultellipsoid(), true);
  M12
  % dM12/ds2 = - (1 - M12*M21/m12)
  for i = 1:3
    s12 = s12 - M12 / ( -(1 - M12*M21)/m12 ); % Newton
    [lat2, lon2, ~, ~, m12, M12, M21] = geodreckon(lat1, lon1, s12, azi1);
    M12
  end
end

উদাহরণস্বরূপ, এটি দেয়:

[ল্যাট 2, লোন 2] = সেমিকঞ্জ (45, 0, 90)
এম 12 = 0.00262997817649321
এম 12 = -6.08402492665097e-09
এম 12 = 4.38017677684144e-17
এম 12 = 4.38017677684144e-17
ল্যাট 2 = -0.106909087322479
দীর্ঘ 2 = 89.8929107279317

+1 টি। তবে এটি অস্পষ্ট যে সাধারণ রুট সন্ধানকারী যে কোনও কম ভাল সম্পাদন করবে: ফাংশনটি তার সর্বোত্তম এবং নিউটনের পদ্ধতির কাছে খুব সুন্দরভাবে আচরণ করা হয়, উদাহরণস্বরূপ, চতুর্ভুজকেও রূপান্তরিত করবে। ( ম্যাথমেটেমিকা সাধারণত রূপান্তর করতে প্রায় চারটি পদক্ষেপ নিচ্ছে; প্রতিটি পদক্ষেপে জ্যাকবিয়ানদের অনুমানের জন্য চারটি মূল্যায়ন প্রয়োজন)) আপনার পদ্ধতিটি আমি দেখতে পাচ্ছি আসল সুবিধা হ'ল এটি কোনও রুট সন্ধানকারীর ব্যবহার না করেই সহজেই জিআইএস-এ স্ক্রিপ্ট করা যায়।
whuber

আমি রাজী. আমার পদ্ধতিটি নিউটনের সমতুল্য এবং তাই, ম্যাথমেটিকার মূল আবিষ্কার পদ্ধতির বিপরীতে, পার্থক্য নিয়ে ধরণের অনুমান করার দরকার নেই।
সিএফকেক

ঠিক - তবে আপনাকে প্রতিবার পুনরায় প্রত্যাশা করতে হবে, যা দেখে মনে হচ্ছে এটি প্রায় একই পরিমাণ কাজের কাজ। আমি আপনার পদ্ধতির সরলতা এবং কমনীয়তার প্রশংসা করি, যদিও: এটি অবিলম্বে সুস্পষ্ট যে এটি কাজ করা উচিত এবং দ্রুত রূপান্তরিত হবে।
whuber

আমি আমার উত্তরে একই পরীক্ষার পয়েন্টগুলির জন্য ফলাফল পোস্ট করেছি।
কर्क কুইকেনডাল

3

@ সিএফকে-এর পদ্ধতির সমাধানের দিকে কীভাবে রূপান্তরিত হয়েছিল তা দেখার জন্য আমি কৌতূহলী হয়েছিলাম, সুতরাং আমি আর্কোবজেক্টগুলি ব্যবহার করে একটি পরীক্ষা লিখেছিলাম, যা এই আউটপুটটি তৈরি করেছিল। দূরত্ব মিটারে:

0 longitude: 0 latitude: 90
    Distances: 3134.05443974188 2844.67237777542 3234.33025754997
    Diffs: 289.382061966458 -389.657879774548 -100.27581780809
1 longitude: 106.906152157596 latitude: -6.31307123035178
    Distances: 1450.23208989615 1450.23208089398 1450.23209429293
    Diffs: 9.00216559784894E-06 -1.33989510686661E-05 -4.39678547081712E-06
2 longitude: 106.906583669013 latitude: -6.29691590176649
    Distances: 1450.23206976414 1450.23206976408 1450.23206976433
    Diffs: 6.18456397205591E-11 -2.47382558882236E-10 -1.85536919161677E-10
3 longitude: 106.906583669041 latitude: -6.29691590154641
    Distances: 1450.23206976438 1450.23206976423 1450.23206976459
    Diffs: 1.47565515362658E-10 -3.61751517630182E-10 -2.14186002267525E-10
4 longitude: 106.906583669041 latitude: -6.29691590154641
    Distances: 1450.23206976438 1450.23206976423 1450.23206976459
    Diffs: 1.47565515362658E-10 -3.61751517630182E-10 -2.14186002267525E-10

সোর্স কোডটি এখানে। (সম্পাদনা) আজিমুথাল প্রজেকশনটির প্রান্ত থেকে পড়ে যাওয়া চৌরাস্তাগুলি (কেন্দ্রস্থলগুলি) পরিচালনা করতে ফাইন্ড সার্কেল সেন্টার পরিবর্তন করেছে:

public static void Test()
{
    var t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
    var srf = Activator.CreateInstance(t) as ISpatialReferenceFactory2;
    var pcs = srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_WGS1984N_PoleAziEqui)
        as IProjectedCoordinateSystem2;

    var pntA = MakePoint(106.9004975375, -6.28530175, pcs.GeographicCoordinateSystem);
    var pntB = MakePoint(106.89573839, -6.28955287, pcs.GeographicCoordinateSystem);
    var pntC = MakePoint(106.908087643421, -6.28388865789474, pcs.GeographicCoordinateSystem);

    int maxIter = 5;
    for (int i = 0; i < maxIter; i++)
    {
        var msg = string.Format("{0} longitude: {1} latitude: {2}", i, pcs.get_CentralMeridian(true), pcs.LatitudeOfOrigin);
        Debug.Print(msg);
        var newCenter = FindCircleCenter(ProjectClone(pntA, pcs), ProjectClone(pntB, pcs), ProjectClone(pntC, pcs));
        newCenter.Project(pcs.GeographicCoordinateSystem); // unproject
        var distA = GetGeodesicDistance(newCenter, pntA);
        var distB = GetGeodesicDistance(newCenter, pntB);
        var distC = GetGeodesicDistance(newCenter, pntC);
        Debug.Print("\tDistances: {0} {1} {2}", distA, distB, distC);
        var diffAB = distA - distB;
        var diffBC = distB - distC;
        var diffAC = distA - distC;
        Debug.Print("\tDiffs: {0} {1} {2}", diffAB, diffBC, diffAC);

        pcs.set_CentralMeridian(true, newCenter.X);
        pcs.LatitudeOfOrigin = newCenter.Y;
    }
}
public static IPoint FindCircleCenter(IPoint a, IPoint b, IPoint c)
{
    // from http://blog.csharphelper.com/2011/11/08/draw-a-circle-through-three-points-in-c.aspx
    // Get the perpendicular bisector of (x1, y1) and (x2, y2).
    var x1 = (b.X + a.X) / 2;
    var y1 = (b.Y + a.Y) / 2;
    var dy1 = b.X - a.X;
    var dx1 = -(b.Y - a.Y);

    // Get the perpendicular bisector of (x2, y2) and (x3, y3).
    var x2 = (c.X + b.X) / 2;
    var y2 = (c.Y + b.Y) / 2;
    var dy2 = c.X - b.X;
    var dx2 = -(c.Y - b.Y);

    // See where the lines intersect.
    var cx = (y1 * dx1 * dx2 + x2 * dx1 * dy2 - x1 * dy1 * dx2 - y2 * dx1 * dx2)
        / (dx1 * dy2 - dy1 * dx2);
    var cy = (cx - x1) * dy1 / dx1 + y1;

    // make sure the intersection point falls
    // within the projection.
    var earthRadius = ((IProjectedCoordinateSystem)a.SpatialReference).GeographicCoordinateSystem.Datum.Spheroid.SemiMinorAxis;

    // distance is from center of projection
    var dist = Math.Sqrt((cx * cx) + (cy * cy));
    double factor = 1.0;
    if (dist > earthRadius * Math.PI)
    {
        // apply a factor so we don't fall off the edge
        // of the projection
        factor = earthRadius / dist;
    }
    var outPoint = new PointClass() as IPoint;
    outPoint.PutCoords(cx * factor, cy* factor);
    outPoint.SpatialReference = a.SpatialReference;
    return outPoint;
}

public static double GetGeodesicDistance(IPoint pnt1, IPoint pnt2)
{
    var pc = new PolylineClass() as IPointCollection;
    var gcs = pnt1.SpatialReference as IGeographicCoordinateSystem;
    if (gcs == null)
        throw new Exception("point does not have a gcs");
    ((IGeometry)pc).SpatialReference = gcs;
    pc.AddPoint(pnt1);
    pc.AddPoint(pnt2);
    var t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
    var srf = Activator.CreateInstance(t) as ISpatialReferenceFactory2;
    var unit = srf.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;
    var pcGeodetic = pc as IPolycurveGeodetic;
    return pcGeodetic.get_LengthGeodetic(esriGeodeticType.esriGeodeticTypeGeodesic, unit);
}

public static IPoint ProjectClone(IPoint pnt, ISpatialReference sr)
{
    var clone = ((IClone)pnt).Clone() as IPoint;
    clone.Project(sr);
    return clone;
}

public static IPoint MakePoint(double longitude, double latitude, ISpatialReference sr)
{
    var pnt = new PointClass() as IPoint;
    pnt.PutCoords(longitude, latitude);
    pnt.SpatialReference = sr;
    return pnt;
}

এমএসডিএন ম্যাগাজিনের জুন ২০১৩ ইস্যুতে সি # ব্যবহার করে অ্যামিবা পদ্ধতিটি অপ্টিমাইজেশনের বিকল্প বিকল্পও রয়েছে ।


সম্পাদন করা

পূর্বে পোস্ট করা কোড কিছু ক্ষেত্রে অ্যান্টিপোডে রূপান্তরিত হয়েছিল। আমি কোডটি এমনভাবে পরিবর্তন করেছি যাতে এটি @ cffk এর পরীক্ষার পয়েন্টগুলির জন্য এই আউটপুট তৈরি করে।

এটি এখন উত্পাদিত আউটপুট এখানে:

0 0
0 longitude: 0 latitude: 0
    MaxDiff: 1859074.90170379 Distances: 13541157.6493561 11682082.7476523 11863320.2116807
1 longitude: 43.5318402621384 latitude: -17.1167429904981
    MaxDiff: 21796.9793742411 Distances: 12584188.7592282 12588146.4851222 12566349.505748
2 longitude: 32.8331167578493 latitude: -16.2707976739314
    MaxDiff: 6.05585224926472 Distances: 12577536.3369782 12577541.3560203 12577542.3928305
3 longitude: 32.8623898057665 latitude: -16.1374156408507
    MaxDiff: 5.58793544769287E-07 Distances: 12577539.6118671 12577539.6118666 12577539.6118669
4 longitude: -147.137582018133 latitude: 16.1374288796667
    MaxDiff: 1.12284109462053 Distances: 7441375.08265703 7441376.12671342 7441376.20549812
5 longitude: -147.157742373074 latitude: 16.2233413614432
    MaxDiff: 7.45058059692383E-09 Distances: 7441375.70752843 7441375.70752842 7441375.70752842
5 longitude: -147.157742373074 latitude: 16.2233413614432 Distance 7441375.70752843
iterations: 5

সংশোধিত কোডটি এখানে:

class Program
{
    private static LicenseInitializer m_AOLicenseInitializer = new tripoint.LicenseInitializer();

    [STAThread()]
    static void Main(string[] args)
    {
        //ESRI License Initializer generated code.
        m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeStandard },
        new esriLicenseExtensionCode[] { });
        try
        {
            var t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
            var srf = Activator.CreateInstance(t) as ISpatialReferenceFactory2;
            var pcs = srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_World_AzimuthalEquidistant)
                as IProjectedCoordinateSystem2;
            Debug.Print("{0} {1}", pcs.get_CentralMeridian(true), pcs.LatitudeOfOrigin);
            int max = int.MinValue;
            for (int i = 0; i < 1; i++)
            {
                var iterations = Test(pcs);
                max = Math.Max(max, iterations);
                Debug.Print("iterations: {0}", iterations);
            }
            Debug.Print("max number of iterations: {0}", max);
        }
        catch (Exception ex)
        {
            Debug.Print(ex.Message);
            Debug.Print(ex.StackTrace);
        }
        //ESRI License Initializer generated code.
        //Do not make any call to ArcObjects after ShutDownApplication()
        m_AOLicenseInitializer.ShutdownApplication();
    }
    public static int Test(IProjectedCoordinateSystem2 pcs)
    {
        var pntA = MakePoint(-74.0, 41.0, pcs.GeographicCoordinateSystem);
        var pntB = MakePoint(140.0, 36.0, pcs.GeographicCoordinateSystem);
        var pntC = MakePoint(175.0, -41.0, pcs.GeographicCoordinateSystem);


        //var r = new Random();
        //var pntA = MakeRandomPoint(r, pcs.GeographicCoordinateSystem);
        //var pntB = MakeRandomPoint(r, pcs.GeographicCoordinateSystem);
        //var pntC = MakeRandomPoint(r, pcs.GeographicCoordinateSystem);

        int maxIterations = 100;
        for (int i = 0; i < maxIterations; i++)
        {
            var msg = string.Format("{0} longitude: {1} latitude: {2}", i, pcs.get_CentralMeridian(true), pcs.LatitudeOfOrigin);
            Debug.Print(msg);
            var newCenter = FindCircleCenter(ProjectClone(pntA, pcs), ProjectClone(pntB, pcs), ProjectClone(pntC, pcs));
            var c = ((IClone)newCenter).Clone() as IPoint;
            newCenter.Project(pcs.GeographicCoordinateSystem); // unproject
            //newCenter = MakePoint(-147.1577482, 16.2233394, pcs.GeographicCoordinateSystem);
            var distA = GetGeodesicDistance(newCenter, pntA);
            var distB = GetGeodesicDistance(newCenter, pntB);
            var distC = GetGeodesicDistance(newCenter, pntC);
            var diffAB = Math.Abs(distA - distB);
            var diffBC = Math.Abs(distB - distC);
            var diffAC = Math.Abs(distA - distC);
            var maxDiff = GetMax(new double[] {diffAB,diffAC,diffBC});
            Debug.Print("\tMaxDiff: {0} Distances: {1} {2} {3}",maxDiff, distA, distB, distC);
            if (maxDiff < 0.000001)
            {
                var earthRadius = pcs.GeographicCoordinateSystem.Datum.Spheroid.SemiMinorAxis;
                if (distA > earthRadius * Math.PI / 2.0)
                {
                    newCenter = AntiPode(newCenter);
                }
                else
                {
                    Debug.Print("{0} longitude: {1} latitude: {2} Distance {3}", i, pcs.get_CentralMeridian(true), pcs.LatitudeOfOrigin, distA);
                    return i;
                }
            }
            //Debug.Print("\tDiffs: {0} {1} {2}", diffAB, diffBC, diffAC);

            pcs.set_CentralMeridian(true, newCenter.X);
            pcs.LatitudeOfOrigin = newCenter.Y;
        }
        return maxIterations;
    }

    public static IPoint FindCircleCenter(IPoint a, IPoint b, IPoint c)
    {
        // from http://blog.csharphelper.com/2011/11/08/draw-a-circle-through-three-points-in-c.aspx
        // Get the perpendicular bisector of (x1, y1) and (x2, y2).
        var x1 = (b.X + a.X) / 2;
        var y1 = (b.Y + a.Y) / 2;
        var dy1 = b.X - a.X;
        var dx1 = -(b.Y - a.Y);

        // Get the perpendicular bisector of (x2, y2) and (x3, y3).
        var x2 = (c.X + b.X) / 2;
        var y2 = (c.Y + b.Y) / 2;
        var dy2 = c.X - b.X;
        var dx2 = -(c.Y - b.Y);

        // See where the lines intersect.
        var cx = (y1 * dx1 * dx2 + x2 * dx1 * dy2 - x1 * dy1 * dx2 - y2 * dx1 * dx2)
            / (dx1 * dy2 - dy1 * dx2);
        var cy = (cx - x1) * dy1 / dx1 + y1;

        // make sure the intersection point falls
        // within the projection.
        var earthRadius = ((IProjectedCoordinateSystem)a.SpatialReference).GeographicCoordinateSystem.Datum.Spheroid.SemiMinorAxis;

        // distance is from center of projection
        var dist = Math.Sqrt((cx * cx) + (cy * cy));
        double factor = 1.0;
        if (dist > earthRadius * Math.PI)
        {
            // apply a factor so we don't fall off the edge
            // of the projection
            factor = earthRadius / dist;
        }
        var outPoint = new PointClass() as IPoint;
        outPoint.PutCoords(cx * factor, cy* factor);
        outPoint.SpatialReference = a.SpatialReference;
        return outPoint;
    }

    public static IPoint AntiPode(IPoint pnt)
    {
        if (!(pnt.SpatialReference is IGeographicCoordinateSystem))
            throw new Exception("antipode of non-gcs projection not supported");
        var outPnt = new PointClass() as IPoint;
        outPnt.SpatialReference = pnt.SpatialReference;
        if (pnt.X < 0.0)
            outPnt.X = 180.0 + pnt.X;
        else
            outPnt.X = pnt.X - 180.0;
        outPnt.Y = -pnt.Y;
        return outPnt;
    }

    public static IPoint MakeRandomPoint(Random r, IGeographicCoordinateSystem gcs)
    {
        var latitude = (r.NextDouble() - 0.5) * 180.0;
        var longitude = (r.NextDouble() - 0.5) * 360.0;
        //Debug.Print("{0} {1}", latitude, longitude);
        return MakePoint(longitude, latitude, gcs);
    }
    public static double GetMax(double[] dbls)
    {
        var max = double.MinValue;
        foreach (var d in dbls)
        {
            if (d > max)
                max = d;
        }
        return max;
    }
    public static IPoint MakePoint(IPoint[] pnts)
    {
        double sumx = 0.0;
        double sumy = 0.0;
        foreach (var pnt in pnts)
        {
            sumx += pnt.X;
            sumy += pnt.Y;
        }
        return MakePoint(sumx / pnts.Length, sumy / pnts.Length, pnts[0].SpatialReference);
    }
    public static double GetGeodesicDistance(IPoint pnt1, IPoint pnt2)
    {
        var pc = new PolylineClass() as IPointCollection;
        var gcs = pnt1.SpatialReference as IGeographicCoordinateSystem;
        if (gcs == null)
            throw new Exception("point does not have a gcs");
        ((IGeometry)pc).SpatialReference = gcs;
        pc.AddPoint(pnt1);
        pc.AddPoint(pnt2);
        var t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
        var srf = Activator.CreateInstance(t) as ISpatialReferenceFactory2;
        var unit = srf.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;
        var pcGeodetic = pc as IPolycurveGeodetic;
        return pcGeodetic.get_LengthGeodetic(esriGeodeticType.esriGeodeticTypeGeodesic, unit);
    }

    public static IPoint ProjectClone(IPoint pnt, ISpatialReference sr)
    {
        var clone = ((IClone)pnt).Clone() as IPoint;
        clone.Project(sr);
        return clone;
    }

    public static IPoint MakePoint(double longitude, double latitude, ISpatialReference sr)
    {
        var pnt = new PointClass() as IPoint;
        pnt.PutCoords(longitude, latitude);
        pnt.SpatialReference = sr;
        return pnt;
    }
}

সম্পাদন করা

আমি এএসআরএসপ্রোজসিএস_ডিজিএস 1984 এন_পোলএজিএকিউইয়ের সাথে প্রাপ্ত ফলাফলগুলি এখানে's

0 90
0 longitude: 0 latitude: 90
    MaxDiff: 1275775.91880553 Distances: 8003451.67666723 7797996.2370572 6727675.7578617
1 longitude: -148.003774863594 latitude: 9.20238223616225
    MaxDiff: 14487.6784785809 Distances: 7439006.46128994 7432752.45732905 7447240.13580763
2 longitude: -147.197808459106 latitude: 16.3073233548167
    MaxDiff: 2.32572609744966 Distances: 7441374.94409209 7441377.26981819 7441375.90768183
3 longitude: -147.157734641831 latitude: 16.2233338760411
    MaxDiff: 7.72997736930847E-08 Distances: 7441375.70752842 7441375.70752848 7441375.7075284
3 longitude: -147.157734641831 latitude: 16.2233338760411 Distance 7441375.70752842

এটি চিত্তাকর্ষকভাবে দ্রুত রূপান্তর! (+1)
whuber

আপনি নতুন কেন্দ্রে কেন্দ্রীভূত একটি সৎ-থেকে-সদর্থক আজিমুথাল সমীকরণীয় প্রজেকশন ব্যবহার করা উচিত। পরিবর্তে আপনি এন মেরুতে কেন্দ্রিক প্রজেকশনটি ব্যবহার করছেন এবং উত্সটিকে নতুন কেন্দ্রে স্থানান্তর করছেন। সুতরাং দুর্ঘটনাজনিত হতে পারে যে আপনি এই ক্ষেত্রে একটি শালীন সমাধান পান (সম্ভবত কারণ পয়েন্টগুলি একে অপরের কাছাকাছি?) এটি কয়েক হাজার কিলোমিটার দূরে 3 পয়েন্ট দিয়ে চেষ্টা করে দেখুন। আজিমুথাল ইক্যুইডিস্টিভ
ম্যাটলেবসেন্ট্রাল /

@cffk একটি নির্দিষ্ট পয়েন্টকে কেন্দ্র করে আজিমুথাল ইক্যুইডিস্টিভ প্রজেকশন তৈরি করতে দেখছি কেবল একই উপায় হ'ল এসিএসআরপ্রজসিএস_ওয়ার্ল্ড_আজিমুথাল একিউসিস্টেন্টের সাথে এসরিএসআরপ্রজসিএস_ডব্লিউ 1915 এনপোলএজিএকুই (বা এসএসআরএসপ্রোজিএসসিওজিআইজি 19) এর পরিবর্তে যদিও পার্থক্য কেবলমাত্র এটি 0,90 (বা 0, -90) এর পরিবর্তে 0,0 কেন্দ্রিক। "সৎ-থেকে-সদর্থকতা" প্রযোজনার থেকে এটি বিভিন্ন ফলাফল তৈরি করে কিনা তা দেখার জন্য আপনি গণিতগুলি নিয়ে পরীক্ষা চালাতে আমাকে গাইড করতে পারেন?
কर्क কুইকেনডাল

@ কির্ককুইএন্ডল: আমার প্রথম উত্তরের সংযোজন দেখুন।
সিএফকেক

1
@ কির্ককুইএন্ডল তাই সম্ভবত ইএসআরআই একটি "সৎ-থেকে-সদয়তা" প্রক্ষেপণটি বাস্তবায়ন করেছিল? এই অ্যালগরিদমটি কাজ করার জন্য প্রয়োজনীয় মূল সম্পত্তিটি হ'ল "সেন্টার পয়েন্ট" থেকে পরিমাপ করা দূরত্বগুলি সত্য। এবং এই সম্পত্তিটি চেক করা যথেষ্ট সহজ। (কেন্দ্র পয়েন্টের সাথে সম্পর্কিত আজিমুথাল সম্পত্তি গৌণ এবং এটি কেবল রূপান্তরকরণের হারকে প্রভাবিত করতে পারে))
সিএফকে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.