পাঠ ৪৩ · ৫৭-এর মধ্যে · মডিউল ১০
Home / Courses / Mobile App Development / লোকেশন ও GPS

লোকেশন ও GPS

Location and GPS
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • L41-এর পারমিশন গেট একটি concrete লোকেশন অ্যাকশনে কীভাবে প্রয়োগ করতে হয়
  • Foreground বনাম background লোকেশন পারমিশনের পার্থক্য
  • হ্যাভারসিন সূত্র দিয়ে দুটো lat/lng স্থানাঙ্কের মধ্যে প্রকৃত দূরত্ব গণনা
  • কীভাবে একটি গণনাকৃত ফলাফল real-world sense-check করে যাচাই করতে হয়

১ · লোকেশনও একটি পারমিশন-গেটেড ফিচার

GPS/নেটওয়ার্ক-ভিত্তিক লোকেশন অ্যাক্সেসও ঠিক ক্যামেরার মতোই একটি রানটাইম পারমিশনের পেছনে থাকে — L41-এ তৈরি তিন-স্টেট (not_requested/granted/denied) মডেলই এখানে প্রযোজ্য। তবে লোকেশনের একটি অতিরিক্ত স্তর আছে — foreground বনাম background লোকেশনঅ্যাপ খোলা ও দৃশ্যমান থাকা অবস্থায় লোকেশন পাওয়া (foreground) সাধারণ একটি পারমিশনে হয়, কিন্তু অ্যাপ ব্যাকগ্রাউন্ডে চলে যাওয়ার পরেও লোকেশন ট্র্যাক করতে (background) আলাদা, আরও কড়াভাবে যাচাই করা একটি পারমিশন প্রয়োজন হয় — ব্যাটারি ও প্রাইভেসি উভয় কারণে। — যেখানে background অ্যাক্সেস ব্যাটারি ও প্রাইভেসি উভয় কারণে আরও কড়াভাবে নিয়ন্ত্রিত।

২ · একটি সত্যিকারের get_current_location() অ্যাকশন

L42-এর take_photo-এর ঠিক একই আকৃতি অনুসরণ করে — কল হওয়ার মুহূর্তে প্রকৃত পারমিশন স্ট্যাটাস চেক করে, not_requested হলে একটি রিকোয়েস্ট ধাপ ট্রিগার করে।

Python
# L41-এর পারমিশন গেট পুনরায় ব্যবহার করে একটি concrete get_current_location() অ্যাকশন

def request_permission(permissions, name, outcome):
    """outcome ডিটারমিনিস্টিকভাবে দেওয়া হয় -- real OS পারমিশন ডায়ালগের ফলাফল সিমুলেট করতে"""
    if outcome not in ("granted", "denied"):
        raise ValueError(f"অবৈধ outcome: {outcome}")
    permissions[name] = outcome
    print(f"  [request] location -> {outcome}")
    return outcome

def get_current_location(permissions, auto_request_outcome=None):
    """location পারমিশনের প্রকৃত স্ট্যাটাস কল হওয়ার মুহূর্তে চেক করে"""
    status = permissions["location"]
    if status == "not_requested":
        print("  [get_current_location] location permission not_requested -- OS পারমিশন ডায়ালগ দেখানো হচ্ছে")
        status = request_permission(permissions, "location", auto_request_outcome)
    if status == "granted":
        lat, lon = 23.7333, 90.4167  # মতিঝিল, ঢাকা -- সিমুলেটেড বর্তমান লোকেশন
        print(f"  [get_current_location] সফল -- বর্তমান লোকেশন: ({lat}, {lon}), permission: {status}")
        return (lat, lon)
    else:
        print(f"  [get_current_location] ব্লকড -- লোকেশন পাওয়া যায়নি, location permission: {status}")
        return None

print("== দৃশ্য ১: not_requested ==")
s1 = {"location": "not_requested"}
get_current_location(s1, auto_request_outcome="granted")

print("\n== দৃশ্য ২: denied ==")
s2 = {"location": "denied"}
get_current_location(s2)

print("\n== দৃশ্য ৩: granted ==")
s3 = {"location": "granted"}
get_current_location(s3)

    

৩ · দুটো স্থানাঙ্কের মধ্যে প্রকৃত দূরত্ব — হ্যাভারসিন সূত্র

লোকেশন পাওয়ার পর প্রায়ই দুটো বিন্দুর মধ্যে দূরত্ব বের করতে হয় (যেমন "নিকটতম দোকান কতদূর")। পৃথিবী গোলাকার, তাই lat/lng-কে সরাসরি ইউক্লিডিয়ান দূরত্ব হিসেবে গণনা করলে ভুল ফলাফল আসে — এর বদলে হ্যাভারসিন সূত্র ব্যবহার করা হয়, যা গোলকের বক্রতা বিবেচনা করে:

$$a = \sin^2\!\left(\frac{\Delta\varphi}{2}\right) + \cos\varphi_1 \cos\varphi_2 \sin^2\!\left(\frac{\Delta\lambda}{2}\right), \quad c = 2 \cdot \operatorname{atan2}\!\left(\sqrt{a}, \sqrt{1-a}\right), \quad d = R \cdot c$$

এখানে $\varphi$ = ল্যাটিটিউড (রেডিয়ানে), $\lambda$ = লঙ্গিটিউড (রেডিয়ানে), এবং $R$ = পৃথিবীর গড় ব্যাসার্ধ (৬৩৭১ কিমি)। নিচের কোডে এই সূত্রটি হুবহু বাস্তবায়ন করে ঢাকার দুটো real এলাকার — মতিঝিল ও উত্তরার — মধ্যে দূরত্ব গণনা করা হবে।

Python
# হ্যাভারসিন সূত্র দিয়ে দুটো real lat/lng স্থানাঙ্কের মধ্যে দূরত্ব (কিমি)
import math

def haversine_km(lat1, lon1, lat2, lon2):
    R = 6371.0  # পৃথিবীর গড় ব্যাসার্ধ, কিমি
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    d_phi = math.radians(lat2 - lat1)
    d_lambda = math.radians(lon2 - lon1)

    a = (math.sin(d_phi / 2) ** 2
         + math.cos(phi1) * math.cos(phi2) * math.sin(d_lambda / 2) ** 2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    return R * c

# দুটো real এলাকা, ঢাকা
motijheel = (23.7333, 90.4167)   # মতিঝিল -- বাণিজ্যিক এলাকা
uttara = (23.8759, 90.3795)      # উত্তরা -- উত্তর ঢাকা

distance_km = haversine_km(motijheel[0], motijheel[1], uttara[0], uttara[1])
print(f"মতিঝিল {motijheel} -> উত্তরা {uttara}")
print(f"হ্যাভারসিন সরলরৈখিক দূরত্ব: {distance_km:.2f} কিমি")

    
উপরের কোড ≈ ১৬.৩ কিমি প্রিন্ট করে। বাস্তবে মতিঝিল থেকে উত্তরার সরলরৈখিক (আকাশপথে) দূরত্ব প্রায় এই পরিসরেই — সড়কপথে এটি একটু বেশি হবে যেহেতু রাস্তা সরলরেখায় চলে না। এই sense-check-টি গুরুত্বপূর্ণ — একটি ভুল সূত্র প্রয়োগ করলে (যেমন ডিগ্রিকে রেডিয়ানে রূপান্তর না করে সরাসরি ব্যবহার করলে) ফলাফল বাস্তবতার ধারেকাছেও থাকতো না।
মূল কথা · Key takeaway

লোকেশন অ্যাক্সেস পারমিশন-গেটিং-এর ক্ষেত্রে ক্যামেরার মতোই আচরণ করে, কিন্তু এর ওপর নির্ভরশীল গণনাগুলো (দূরত্ব, নৈকট্য) সঠিক হতে হলে পৃথিবীর গোলাকার আকৃতি বিবেচনা করতে হয় — এখানেই হ্যাভারসিন সূত্রের প্রয়োজন, এবং যেকোনো real-world গণনার ফলাফল সবসময় sense-check করে দেখা উচিত।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ একটি ম্যাপ অ্যাপের সবসময়, এমনকি অ্যাপ বন্ধ থাকা অবস্থায়ও ব্যবহারকারীকে ট্র্যাক করার জন্য কেন আলাদা, আরও কড়া পারমিশন প্রয়োজন হয়?

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

প্র ০২ হ্যাভারসিন সূত্রে ডিগ্রিকে রেডিয়ানে রূপান্তর (math.radians) না করলে কী ভুল হতো?

math.sin/math.cos/math.atan2 সব রেডিয়ান একক আশা করে। ডিগ্রি মান সরাসরি দিলে sin/cos-এর ফলাফল সম্পূর্ণ ভুল হতো (যেমন sin(90) রেডিয়ানে প্রায় ০.৮৯, অথচ sin(90°) হওয়া উচিত ১) — ফলে চূড়ান্ত দূরত্ব বাস্তবতার ধারেকাছেও থাকতো না, হয়তো কয়েক হাজার কিমি ভুল দেখাতো।

প্র ০৩ মতিঝিল ও উত্তরার প্রকৃত দূরত্ব যদি কোডে হঠাৎ ১৬৩০ কিমি প্রিন্ট হতো (১৬.৩ কিমির বদলে), সেটা কীভাবে বুঝতেন কোথাও ভুল আছে?

কারণ ঢাকা শহরের ভেতরের দুটো এলাকার মধ্যে দূরত্ব কখনো হাজার কিমি হতে পারে না — এটি একটি sense-check। বাস্তব-জগতের প্রেক্ষাপট জানা থাকলে (ঢাকা শহরের ব্যাস কয়েক দশ কিমির মধ্যেই) ভুল সূত্র বা এককের গরমিল তাৎক্ষণিকভাবে ধরা পড়ে — এটিই এই পাঠের কোড লেখার আগে "বাস্তবসম্মত মান" যাচাই করার গুরুত্ব।

অনুশীলন

  1. চিন্তা করুন: একটি ফুড-ডেলিভারি অ্যাপ কি foreground নাকি background লোকেশন পারমিশন চাইবে বলে আপনার মনে হয় — এবং কেন?

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

  2. পরীক্ষা করুন: কোড সেলে uttara-এর বদলে চট্টগ্রামের স্থানাঙ্ক (22.3569, 91.7832) ব্যবহার করে haversine_km(motijheel[0], motijheel[1], 22.3569, 91.7832) কল করে দেখুন ফলাফল কেমন আসে, এবং সেটা ঢাকা-চট্টগ্রামের প্রকৃত দূরত্বের (সড়কপথে প্রায় ২৪০-২৫০ কিমি, আকাশপথে কিছুটা কম) কাছাকাছি কিনা যাচাই করুন।

    হ্যাভারসিন সূত্র সরলরৈখিক (আকাশপথের) দূরত্ব দেয়, তাই ফলাফল প্রায় ২০০-২২০ কিমির কাছাকাছি আসা উচিত — সড়কপথের দূরত্বের চেয়ে সামান্য কম, যেহেতু রাস্তা সরলরেখায় চলে না। এটি এখনও বাস্তবসম্মত পরিসরে, যা নিশ্চিত করে সূত্রটি সঠিকভাবে কাজ করছে দূরত্ব যতই বড় হোক না কেন।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • Full-Stack Web Frameworks কোর্স সহোদর কোর্স ওয়েবে navigator.geolocation দিয়ে সীমিত, ব্রাউজার-অনুমোদন-ভিত্তিক লোকেশন মেলে — মোবাইলে foreground/background উভয় ধরনের লোকেশন OS-লেভেল পারমিশনসহ অনেক বেশি নিয়ন্ত্রিতভাবে মেলে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks ও Mobile App Development — সব এক জায়গায়।
আগের পাঠ
ক্যামেরা ও মিডিয়া অ্যাক্সেস