الجغرافيا المكانية والخرائط في C++: مكتبات libcurl، nlohmann/json، Leaflet

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الجغرافيا المكانية والخرائط في C++: نظرة عامة على الأدوات وأمثلة التنفيذ



في العالم الحديث، أصبحت بيانات الجغرافيا المكانية والخرائط التفاعلية جزءًا لا يتجزأ من العديد من التطبيقات - من خدمات الملاحة إلى الألعاب وأنظمة المراقبة. التطوير بلغة C++ ليس استثناءً: على الرغم من أن اللغة نفسها لا توفر أدوات مدمجة للعمل مع البيانات الجغرافية، إلا أن هناك نظامًا بيئيًا قويًا من المكتبات يسمح بدمج الجغرافيا المكانية والخرائط في مشاريعك. في هذه المقالة، سنستعرض الأدوات الرئيسية: libcurl لطلبات HTTP، nlohmann/json لتحليل استجابات JSON من واجهات API، وLeaflet (من خلال توليد HTML/JavaScript) لعرض الخرائط.



1. المكتبات الأساسية للعمل مع الجغرافيا المكانية



libcurl هي مكتبة قوية ومجربة لنقل البيانات عبر بروتوكولات مختلفة، بما في ذلك HTTP/HTTPS. وهي مثالية لإرسال الطلبات إلى واجهات API الجغرافية المكانية (مثل OpenStreetMap Nominatim أو Google Maps Geocoding).



nlohmann/json هي مكتبة حديثة وخفيفة الوزن وبديهية للعمل مع JSON. تتيح لك بسهولة تسلسل وإلغاء تسلسل البيانات المستلمة من خدمات الجغرافيا المكانية.



Leaflet هي مكتبة JavaScript الرائدة لإنشاء خرائط تفاعلية. في مشروع C++، يمكنك توليد ملف HTML يستخدم Leaflet لعرض البيانات التي تم الحصول عليها بواسطة تطبيق C++ الخاص بك.



2. تثبيت المكونات الضرورية



للبدء، ستحتاج إلى تثبيت المكتبات. في معظم توزيعات Linux، يتم ذلك من خلال مدير الحزم:



# تثبيت libcurl و nlohmann-jsonsudo apt-get install libcurl4-openssl-dev nlohmann-json3-dev  # Debian/Ubuntusudo dnf install libcurl-devel json-devel                    # Fedora


للعمل مع Leaflet، يكفي تنزيل أحدث إصدار وتضمين ملفات CSS/JS في ملف HTML المُنشأ.



3. مثال: الحصول على الإحداثيات من عنوان (Geocoding)



سنقوم بتنفيذ دالة تأخذ اسم مدينة وتعيد خط العرض وخط الطول باستخدام واجهة API Nominatim (OpenStreetMap).



#include <iostream>#include <string>#include <curl/curl.h>#include <nlohmann/json.hpp>

using json = nlohmann::json;

// دالة رد الاتصال لكتابة استجابة CURL في سلسلة نصيةsize_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) { size_t totalSize = size * nmemb; output->append(static_cast<char*>(contents), totalSize); return totalSize;}

std::pair<double, double> getCoordinates(const std::string& address) { CURL* curl = curl_easy_init(); if (!curl) throw std::runtime_error("خطأ في تهيئة CURL");

std::string response; std::string url = "https://nominatim.openstreetmap.org/search?q=" + curl_easy_escape(curl, address.c_str(), address.length()) + "&format=json&limit=1";

curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); curl_easy_setopt(curl, CURLOPT_USERAGENT, "CppGeoApp/1.0"); // إلزامي لـ Nominatim

CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl);

if (res != CURLE_OK) throw std::runtime_error(curl_easy_strerror(res));

json jsonData = json::parse(response); if (jsonData.empty()) throw std::runtime_error("العنوان غير موجود");

double lat = jsonData[0]["lat"].get<double>(); double lon = jsonData[0]["lon"].get<double>(); return {lat, lon};}

int main() { try { auto [lat, lon] = getCoordinates("موسكو، الكرملين"); std::cout << "

توصيات