0Pricing
R Academy · درس

أنظمة الإسناد والإسقاطات الإحداثية

حوّل بين أنظمة الإسناد الإحداثية CRS باستخدام st_crs() وst_transform() بطريقة صحيحة

أنظمة الإسناد والإسقاطات الإحداثية درس مجاني في R Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.

أهمية CRS

يخبر نظام الإسناد المكاني (CRS) لغة R بما تعنيه الأرقام في عمود الأشكال الهندسية — أدرجات خطوط الطول والعرض، أم أمتارًا في شبكة مسقطة، أم شيئًا آخر. ويؤدي دمج بيانات ذات أنظمة CRS مختلفة من دون إعادة إسقاطها إلى فشل عمليات الربط المكاني بصمت، وإلى أخطاء في حساب المسافات.

library(sf)

# Two sf objects in the same CRS: operations work
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# sf will error or warn when CRS do not match during operations
# This is the CRS metadata attached to the object
crs <- st_crs(nc)
cat('EPSG:', crs$epsg, '\n')
cat('Input is geographic (lon/lat)?', st_is_longlat(nc), '\n')
cat('Units:', crs$units_gdal, '\n')

st_crs: قراءة معلومات CRS

تعيد st_crs(sf_obj) كائن crs يحتوي على رمز EPSG وسلسلة WKT وسلسلة Proj4 ومعلومات الوحدات. ويمكنكم أيضًا تمرير رمز EPSG صحيح مباشرةً لاسترداد تعريف CRS.

library(sf)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Inspect the CRS object
crs <- st_crs(nc)
cat('Class:', class(crs), '\n')
cat('EPSG:', crs$epsg, '\n')
cat('Proj4:', substr(crs$proj4string, 1, 60), '...\n')

# Lookup a CRS by EPSG code
wgs84 <- st_crs(4326)
web_mercator <- st_crs(3857)

cat('\nWGS84 name:', wgs84$Name, '\n')
cat('Web Mercator name:', web_mercator$Name, '\n')

EPSG:4326 — WGS84

يمثل EPSG:4326 النظام الجيوديسي العالمي 1984، وهو المعيار لإحداثيات GPS. وتكون الإحداثيات بالدرجات العشرية: يتراوح خط الطول (X) بين −180 و180، وخط العرض (Y) بين −90 و90. وهو CRS جغرافي وليس مسقطًا.

library(sf)

# Create points in WGS84 (GPS coordinates)
cities <- data.frame(
  city = c('London', 'Tokyo', 'Sydney', 'New York'),
  lon  = c(-0.118, 139.692, 151.209, -74.006),
  lat  = c(51.509,  35.689, -33.869,  40.713)
)

cities_sf <- st_as_sf(cities,
  coords = c('lon', 'lat'),
  crs    = 4326
)

cat('CRS:', st_crs(cities_sf)$Name, '\n')
cat('Units:', st_crs(cities_sf)$units_gdal, '\n')

# Naive distance in degrees (not meaningful for real distances)
d <- st_distance(cities_sf[1, ], cities_sf[2, ])
cat('London-Tokyo distance (degrees):', round(as.numeric(d), 2), '\n')

EPSG:3857 — Web Mercator

يمثل EPSG:3857 إسقاط Web Mercator المستخدم في Google Maps وOpenStreetMap وLeaflet. وتكون الإحداثيات بالأمتار، ومتمركزة عند خط الطول الرئيسي وخط الاستواء. وهو يشوّه المساحات قرب القطبين، لكنه مناسب للتصور على الويب.

library(sf)

cities <- data.frame(
  city = c('London', 'Tokyo'),
  lon  = c(-0.118, 139.692),
  lat  = c(51.509,  35.689)
)
cities_sf <- st_as_sf(cities, coords = c('lon', 'lat'), crs = 4326)

# Transform to Web Mercator
cities_merc <- st_transform(cities_sf, 3857)

cat('WGS84 coords (degrees):\n')
print(st_coordinates(cities_sf))

cat('\nWeb Mercator coords (metres):\n')
print(st_coordinates(cities_merc))

# Distance is now in metres
d <- st_distance(cities_merc[1, ], cities_merc[2, ])
cat('\nLondon-Tokyo distance (km):', round(as.numeric(d) / 1000, 0), '\n')

st_set_crs: تعيين CRS

تقوم st_set_crs(sf_obj, crs) بتعيين CRS من دون تحويل الإحداثيات. استخدموها فقط عندما تكون بيانات CRS الوصفية مفقودة أو غير صحيحة. وإذا أردتم إعادة إسقاط الإحداثيات إلى CRS جديد، فاستخدموا st_transform() بدلًا منها.

library(sf)

# Create geometry with NO CRS
pts <- st_sfc(
  st_point(c(-74.006, 40.713)),
  st_point(c(-87.629, 41.878))
)
cat('CRS before:', is.na(st_crs(pts)), '(NA = no CRS)\n')

# Assign WGS84 (no coordinate transformation)
pts_wgs84 <- st_set_crs(pts, 4326)
cat('CRS after assignment:', st_crs(pts_wgs84)$epsg, '\n')

# Compare with st_transform (DOES transform coordinates)
pts_sf    <- st_sf(id = 1:2, geometry = pts_wgs84)
pts_merc  <- st_transform(pts_sf, 3857)
cat('Original lon:', st_coordinates(pts_sf)[1, 'X'], '\n')
cat('Mercator X:  ', st_coordinates(pts_merc)[1, 'X'], '\n')

st_transform: إعادة الإسقاط

تعيد st_transform(sf_obj, crs) إسقاط جميع الأشكال الهندسية من CRS الحالي إلى CRS الهدف، مع تطبيق التحويل الجيوديزي الكامل. وتقبل الوسيطة crs عدد EPSG صحيحًا أو سلسلة Proj4 أو سلسلة WKT.

library(sf)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))
cat('Original CRS:', st_crs(nc)$epsg, '\n')

# Re-project to WGS84
nc_wgs84 <- st_transform(nc, 4326)
cat('Transformed CRS:', st_crs(nc_wgs84)$epsg, '\n')

# Re-project to a local projected CRS (NC State Plane)
nc_stateplane <- st_transform(nc, 32119)  # NAD83 / North Carolina
cat('State Plane CRS:', st_crs(nc_stateplane)$Name, '\n')

# Area calculation is more accurate in a projected CRS
area_deg <- st_area(nc[1, ])
area_m2  <- st_area(nc_stateplane[1, ])
cat('Area (degrees^2):', format(area_deg, big.mark = ','), '\n')
cat('Area (m^2):      ', format(area_m2,  big.mark = ','), '\n')

اختيار الإسقاط المناسب

تحسّن الإسقاطات المختلفة خصائص مختلفة: فالإسقاطات متساوية المساحة مثل Mollweide، والإسقاطات المتطابقة الزوايا مثل Mercator، والإسقاطات متساوية المسافات. وللتحليل المحلي، استخدموا CRS مسقطًا بوحدات المتر؛ وللمناظير العالمية، يكفي WGS84؛ أما خرائط الويب فاستخدموا Web Mercator.

library(sf)

# Common EPSG codes cheat sheet
epsg_table <- data.frame(
  EPSG = c(4326, 3857, 4269, 32637, 27700),
  Name = c(
    'WGS84 (GPS, global)',
    'Web Mercator (web maps)',
    'NAD83 (North America geographic)',
    'UTM zone 37N (Middle East)',
    'British National Grid (UK)'
  ),
  Units = c('degrees', 'metres', 'degrees', 'metres', 'metres')
)

print(epsg_table, row.names = FALSE)

# Look up any EPSG online: https://epsg.io/<code>
cat('\nTip: use st_crs(epsg_code)$Name to verify a code\n')

سلاسل Proj4

قبل أن تصبح رموز EPSG معيارًا، كان تعريف CRS يتم باستخدام سلاسل Proj4، وهي سلاسل معلمات موجزة تُمرَّر إلى مكتبة PROJ. ولا يزال بإمكانكم استخدامها مع st_transform()، لكن يُفضَّل استخدام رموز EPSG لوضوحها وتوافقها المستقبلي.

library(sf)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# WGS84 as Proj4 string
wgs84_proj4 <- '+proj=longlat +datum=WGS84 +no_defs'
nc_wgs84 <- st_transform(nc, crs = wgs84_proj4)

cat('Using Proj4 string:\n', wgs84_proj4, '\n')
cat('Result CRS EPSG:', st_crs(nc_wgs84)$epsg, '\n')

# Compare: equivalent to st_transform(nc, 4326)
cat('Same as EPSG 4326?',
    identical(st_crs(nc_wgs84), st_crs(st_transform(nc, 4326))), '\n')

التحقق من تطابق CRS

قبل إجراء أي ربط مكاني أو عملية تراكب، تحققوا من أن الكائنين يشتركان في CRS نفسه باستخدام st_crs(a) == st_crs(b). وإذا اختلفا، فأعيدوا إسقاط أحدهما ليتطابق مع الآخر قبل المتابعة.

library(sf)

# Two objects in different CRS
nc_nad27  <- read_sf(system.file('shape/nc.shp', package = 'sf'))
nc_wgs84  <- st_transform(nc_nad27, 4326)

cat('Same CRS?', st_crs(nc_nad27) == st_crs(nc_wgs84), '\n')

# Always check before join/overlay
align_crs <- function(a, b) {
  if (st_crs(a) != st_crs(b)) {
    message('CRS mismatch! Transforming b to match a.')
    b <- st_transform(b, st_crs(a))
  }
  list(a = a, b = b)
}

aligned <- align_crs(nc_nad27, nc_wgs84)
cat('After alignment - same CRS?',
    st_crs(aligned$a) == st_crs(aligned$b), '\n')

حساب المسافات باستخدام CRS

المسافات المحسوبة في CRS جغرافي، أي بالدرجات، لا معنى لها. أعيدوا الإسقاط أولًا إلى CRS مسقط متساوي المسافات أو متساوي المساحة، أو استخدموا حساب المسافات الجيوديسية المدمج في sf، والذي يتعامل مع WGS84 بطريقة صحيحة عبر مكتبة PROJ.

library(sf)

# City points in WGS84
cities <- data.frame(
  city = c('Paris', 'Berlin', 'Madrid', 'Rome'),
  lon  = c(2.350, 13.404, -3.702, 12.496),
  lat  = c(48.865, 52.520,  40.417, 41.902)
)
cities_sf <- st_as_sf(cities, coords = c('lon', 'lat'), crs = 4326)

# sf computes geodesic distances on WGS84 automatically
dist_matrix <- st_distance(cities_sf)
rownames(dist_matrix) <- cities$city
colnames(dist_matrix) <- cities$city

# Convert to km
dist_km <- round(as.numeric(dist_matrix) / 1000)
mat_km <- matrix(dist_km, 4, 4, dimnames = list(cities$city, cities$city))
print(mat_km)

سير عمل كامل لـ CRS

إليكم سير عمل كاملًا: حمّلوا بيانات GPS الخام، وعيّنوا WGS84، وأعيدوا الإسقاط إلى CRS متري محلي لحساب المساحات والمسافات بدقة، وأجروا التحليل، ثم أعيدوا الإسقاط إلى WGS84 لإخراج البيانات على خرائط الويب.

library(sf)

# Load and assign CRS
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))
nc_wgs84 <- st_transform(nc, 4326)

# Re-project to NC State Plane (metres) for accurate areas
nc_proj <- st_transform(nc, 32119)

# Compute area per county in km2
nc_proj$area_km2 <- as.numeric(st_area(nc_proj)) / 1e6

# Top 5 largest counties
top5 <- nc_proj[order(-nc_proj$area_km2), c('NAME', 'area_km2')]
cat('5 Largest NC Counties (km2):\n')
print(head(as.data.frame(top5)[, c('NAME', 'area_km2')], 5))

# Back to WGS84 for output
nc_output <- st_transform(nc_proj, 4326)
cat('\nOutput CRS:', st_crs(nc_output)$epsg, '\n')

تحقق سريع

تحتاجون إلى حساب مساحات دقيقة، بالمتر المربع، لمعالم مضلعة موجودة حاليًا في WGS84 (EPSG:4326). ما الذي ينبغي فعله؟

مراجعة: CRS والإسقاطات

أهم النقاط:

  • تقرأ st_crs(sf_obj) البيانات الوصفية لـ CRS؛ وتُعد رموز EPSG الطريقة المفضلة لتحديد CRS
  • EPSG:4326 = WGS84، بالدرجات وملائم لـ GPS؛ وEPSG:3857 = Web Mercator، بالأمتار وملائم لخرائط الويب
  • تعيّن st_set_crs() CRS من دون تحويل؛ بينما تعيد st_transform() إسقاط الإحداثيات
  • تحققوا دائمًا من تطابق CRS باستخدام st_crs(a) == st_crs(b) قبل العمليات المكانية
  • للحصول على مسافات ومساحات دقيقة، أعيدوا الإسقاط أولًا إلى CRS مسقط متري
  • لا تزال سلاسل Proj4 تعمل، لكن رموز EPSG أوضح وأسهل قراءة
library(sf)
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# CRS pipeline
cat('Original:', st_crs(nc)$epsg, '\n')
nc_wgs84 <- st_transform(nc, 4326)
nc_proj  <- st_transform(nc_wgs84, 32119)
cat('WGS84:', st_crs(nc_wgs84)$epsg, '\n')
cat('Projected:', st_crs(nc_proj)$epsg, '\n')

الأسئلة الشائعة

هل درس «أنظمة الإسناد والإسقاطات الإحداثية» مجاني؟

نعم — نص درس «أنظمة الإسناد والإسقاطات الإحداثية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.

ماذا ستتعلم في «أنظمة الإسناد والإسقاطات الإحداثية»؟

حوّل بين أنظمة الإسناد الإحداثية CRS باستخدام st_crs() وst_transform() بطريقة صحيحة تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟

لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «أنظمة الإسناد والإسقاطات الإحداثية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟

نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. السمات البسيطة باستخدام حزمة sf
  2. أنظمة الإسناد والإسقاطات الإحداثية
  3. الضمليات والعمليات المكانية
  4. الخرائط التفاعلية باستخدام leaflet
← العودة إلى R Academy