12. تمارين العلاقات المكانية¶
إليك تذكيرًا بالدوال التي رأيناها في القسم السابق. ستكون مفيدة في التمارين!
sum(expression) دالة تجميعية تعيد مجموعًا لمجموعة من السجلات
count(expression) دالة تجميعية تعيد حجم مجموعة من السجلات
ST_Contains(geometry A, geometry B) تعيد true إذا كان الشكل الهندسي A يحتوي الشكل الهندسي B
ST_Crosses(geometry A, geometry B) تعيد true إذا كان الشكل الهندسي A يعبر الشكل الهندسي B
ST_Disjoint(geometry A , geometry B) تعيد true إذا كانت الأشكال الهندسية "لا تتقاطع مكانيًا"
ST_Distance(geometry A, geometry B) تعيد أدنى مسافة بين الشكل الهندسي A والشكل الهندسي B
ST_DWithin(geometry A, geometry B, radius) تعيد true إذا كان الشكل الهندسي A على مسافة radius أو أقل من الشكل الهندسي B
ST_Equals(geometry A, geometry B) تعيد true إذا كان الشكل الهندسي A مطابقًا للشكل الهندسي B
ST_Intersects(geometry A, geometry B) تعيد true إذا كان الشكل الهندسي A يتقاطع مع الشكل الهندسي B
ST_Overlaps(geometry A, geometry B) تعيد true إذا كان الشكلان الهندسيان A و B يشتركان في حيّز، لكن لا يحتوي أحدهما الآخر بالكامل.
ST_Touches(geometry A, geometry B) تعيد true إذا كانت حدود الشكل الهندسي A تلامس الشكل الهندسي B
ST_Within(geometry A, geometry B) تعيد true إذا كان الشكل الهندسي A يقع داخل الشكل الهندسي B
وتذكّر أيضًا الجداول المتاحة لدينا:
nyc_census_blocksblkid, popn_total, boroname, geom
nyc_streetsname، type، geom
nyc_subway_stationsname, geom
nyc_neighborhoodsname، boroname، geom
12.1. التمارين¶
ما قيمة الشكل الهندسي للشارع المسمى 'Atlantic Commons'؟
SELECT ST_AsText(geom) FROM nyc_streets WHERE name = 'Atlantic Commons';
MULTILINESTRING((586781.701577724 4504202.15314339,586863.51964484 4504215.9881701))
في أي حي ومقاطعة يقع Atlantic Commons؟
SELECT n.name, n.boroname FROM nyc_neighborhoods AS n JOIN nyc_streets AS s ON ST_Intersects(n.geom, s.geom) WHERE s.name = 'Atlantic Commons';
name | boroname ------------+---------- Fort Green | Brooklyn
ملاحظة
"مهلًا، لماذا غيّرت من 'MULTILINESTRING' إلى 'LINESTRING'؟" مكانيًا يصفان الشكل نفسه، لذا فإن الانتقال من شكل متعدد ذي عنصر واحد إلى شكل مفرد يوفّر بضع ضغطات على لوحة المفاتيح.
والأهم من ذلك أننا قرّبنا الإحداثيات أيضًا لتسهيل قراءتها، وهذا يغيّر النتائج فعلًا: فلم نتمكن من استخدام المسند ST_Touches() لمعرفة الطرق التي تتصل بـ Atlantic Commons، لأن الإحداثيات لم تعد متطابقة تمامًا.
ما الشوارع التي يتصل بها Atlantic Commons؟
SELECT s.name FROM nyc_streets AS s JOIN nyc_streets AS ac ON ST_DWithin(s.geom, ac.geom, 0.1) WHERE ac.name = 'Atlantic Commons' AND s.gid <> ac.gid;
name ------------------ S Oxford St Cumberland St
كم عدد الأشخاص تقريبًا الذين يعيشون على Atlantic Commons (ضمن 50 مترًا منه)؟
SELECT Sum(popn_total) FROM nyc_census_blocks WHERE ST_DWithin( geom, ST_GeomFromText('LINESTRING(586782 4504202,586864 4504216)', 26918), 50 );
1438