رسم الخطوط المتعددة والمضلعات
رسم الخطوط المتعددة والمضلعات
يتيح لك Google Maps Flutter عرض طبقات متجهية مباشرةً على الخريطة. أكثر نوعَي طبقات فائدةً هما Polyline — سلسلة متصلة من شرائح الخطوط — وPolygon — شكل مغلق يمكن تلوينه من الداخل. يُعرَّف كلاهما بقائمة إحداثيات LatLng ويُرسم بتمريرهما إلى ودجت GoogleMap.
فهم نموذج الطبقات
تُدار الطبقات في Maps SDK كـ Sets: تحتفظ بـ Set<Polyline> أو Set<Polygon> في حالة الودجت، ثم تمررهما إلى معاملَي polylines / polygons في GoogleMap. يُعرَّف كل طبقة بمعرّف فريد PolylineId أو PolygonId. عند استدعاء setState بمجموعة محدَّثة، تعيد الخريطة رسم الطبقات المتغيّرة فقط مما يجعل التحديثات التدريجية فعّالة.
Polyline وPolygon معرّفاً فريداً داخل مجموعته. إعادة استخدام نفس المعرّف تستبدل الطبقة السابقة بصمت، وهو في الواقع النمط الصحيح لتحديث طبقة موجودة.رسم Polyline
تربط Polyline قائمة نقاط LatLng بمقاطع مستقيمة. تشمل خصائص الإعداد الرئيسية:
polylineId— المعرّف الفريد (مطلوب)points—List<LatLng>من الإحداثيات (مطلوب)color— لون الخط (الافتراضي: أسود)width— عرض الخط بالبكسل (الافتراضي: 10)patterns— أنماط متقطعة أو منقطة عبرPatternItemgeodesic— ما إذا كان الخط يتبع انحناء سطح الأرض بين النقاطvisible— تبديل الرؤية دون إزالة الطبقة من المجموعة
مثال Polyline — مسار بين مدينتين
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class RouteMapPage extends StatefulWidget {
const RouteMapPage({super.key});
@override
State<RouteMapPage> createState() => _RouteMapPageState();
}
class _RouteMapPageState extends State<RouteMapPage> {
final Set<Polyline> _polylines = {};
static const CameraPosition _initial = CameraPosition(
target: LatLng(24.7136, 46.6753), // الرياض
zoom: 6,
);
@override
void initState() {
super.initState();
_buildRoute();
}
void _buildRoute() {
final List<LatLng> routePoints = const [
LatLng(24.7136, 46.6753), // الرياض
LatLng(23.8859, 45.0792), // الدوادمي
LatLng(22.3372, 43.1225), // بيشة
LatLng(21.4858, 39.1925), // جدة
];
setState(() {
_polylines.add(
Polyline(
polylineId: const PolylineId('riyadh_to_jeddah'),
points: routePoints,
color: Colors.blue,
width: 5,
geodesic: true,
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('خريطة المسار')),
body: GoogleMap(
initialCameraPosition: _initial,
polylines: _polylines,
),
);
}
}
رسم Polygon
الـ Polygon شكل مغلق تتصل نقطته الأخيرة ضمنياً بالنقطة الأولى. إضافةً إلى الخصائص المشتركة مع Polyline، تدعم المضلعات:
fillColor— لون التعبئة الداخلية (استخدم قيمة ألفا للشفافية)strokeColor— لون الحدودstrokeWidth— سُمك الحدود بالبكسلholes— قوائمList<LatLng>تعرّف فتحات داخل المضلع
مثال Polygon — إبراز منطقة توصيل
class ZoneMapPage extends StatefulWidget {
const ZoneMapPage({super.key});
@override
State<ZoneMapPage> createState() => _ZoneMapPageState();
}
class _ZoneMapPageState extends State<ZoneMapPage> {
final Set<Polygon> _polygons = {};
@override
void initState() {
super.initState();
_addZone();
}
void _addZone() {
const List<LatLng> zonePoints = [
LatLng(25.2048, 55.2708),
LatLng(25.2060, 55.2780),
LatLng(25.1990, 55.2810),
LatLng(25.1960, 55.2730),
];
setState(() {
_polygons.add(
Polygon(
polygonId: const PolygonId('delivery_zone_1'),
points: zonePoints,
strokeColor: Colors.red,
strokeWidth: 3,
fillColor: Colors.red.withOpacity(0.25),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('مناطق التوصيل')),
body: GoogleMap(
initialCameraPosition: const CameraPosition(
target: LatLng(25.2048, 55.2708),
zoom: 14,
),
polygons: _polygons,
),
);
}
}
دمج Polylines وPolygons
يمكنك تمرير polylines وpolygons معاً إلى نفس ودجت GoogleMap في آنٍ واحد. من أشيع الأنماط الواقعية عرض خط مسار جانب مضلعات مناطق التوصيل، أو رسم حدود نطاق جغرافي (مضلع) مع تاريخ المسار (خط) بداخله.
Colors.someColor.withOpacity(0.3) لقيمة fillColor كي تظل بلاطات الخريطة مرئية تحت المضلع. التعبئة الكاملة الشفافية تحجب الخريطة كلياً.تحديث الطبقات وإزالتها
نظراً لأن الطبقات مخزّنة في Set، يمكنك إضافتها أو استبدالها أو حذفها في أي وقت:
- الإضافة: استدعِ
setState(() => _polylines.add(...)) - الاستبدال: احذف القديم بالمعرّف ثم أضف المُحدَّث داخل
setStateواحد - الحذف:
setState(() => _polylines.removeWhere((p) => p.polylineId.value == 'my_id'))
Polyline وPolygon غير قابلة للتعديل بعد إنشائها. لا يمكنك تغيير خاصية في مكانها. أنشئ دائماً نسخة جديدة بالقيم المُحدَّثة واستبدل القديمة في المجموعة داخل setState.اعتبارات الأداء
رسم نقاط كثيرة في خط أو مضلع واحد قد يُبطئ معدل الإطارات على الأجهزة ذات المواصفات المنخفضة. طبّق هذه الاستراتيجيات عند التعامل مع مجموعات بيانات كبيرة:
- استخدم خوارزمية Ramer-Douglas-Peucker لتبسيط قوائم الإحداثيات الكثيفة قبل الرسم.
- قسّم المسارات الطويلة جداً إلى خطوط أقصر متعددة لتحميل المقاطع المرئية فقط.
- عيّن
geodesic: falseإن لم تحتج تحليق دائرة كبرى — أرخص حسابياً. - فضّل منشئات
constلـPolylineIdوPolygonIdلتجنب تخصيص كائنات غير ضرورية عند كل إعادة بناء.
ملخص
توفّر طبقات Polyline وPolygon تحكماً دقيقاً في تصوير المسارات وتحديد المناطق على خريطة Google. يعتمد كلاهما على List<LatLng> ويُضبط عبر خصائص اللون والعرض والتعبئة. أدِرهما في Set ضمن حالة الودجت، وحدّثهما بشكل غير قابل للتعديل عن طريق الاستبدال، وحسّن مجموعات الإحداثيات الكبيرة بخوارزميات التبسيط. في الدرس القادم ستضيف معالجات لمس تفاعلية لهذه الطبقات حتى يتمكن المستخدمون من تحديدها وفحصها.