يوضح لك هذا البرنامج التعليمي كيفية إضافة خريطة Google إلى تطبيق Android، واستخدام الخطوط المتعددة والمضلعات لتمثيل المسارات والمناطق على الخريطة.
اتبع البرنامج التعليمي لإنشاء تطبيق Android باستخدام حزمة SDK للخرائط لنظام التشغيل Android. بيئة التطوير الموصى بها هي Android Studio.
الحصول على الرمز
نسخ أو تنزيل الإصدار 2 من مستودع نماذج Google Maps Android API من GitHub.
عرض إصدار جافا من النشاط:
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.example.polygons; import android.os.Bundle; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CustomCap; import com.google.android.gms.maps.model.Dash; import com.google.android.gms.maps.model.Dot; import com.google.android.gms.maps.model.Gap; import com.google.android.gms.maps.model.JointType; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.Polygon; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.RoundCap; import java.util.Arrays; import java.util.List; /** * An activity that displays a Google map with polylines to represent paths or routes, * and polygons to represent areas. */ public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.setTag("A"); // Style the polyline. stylePolyline(polyline1); Polyline polyline2 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-29.501, 119.700), new LatLng(-27.456, 119.672), new LatLng(-25.971, 124.187), new LatLng(-28.081, 126.555), new LatLng(-28.848, 124.229), new LatLng(-28.215, 123.938))); polyline2.setTag("B"); stylePolyline(polyline2); // Add polygons to indicate areas on the map. Polygon polygon1 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-27.457, 153.040), new LatLng(-33.852, 151.211), new LatLng(-37.813, 144.962), new LatLng(-34.928, 138.599))); // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.setTag("alpha"); // Style the polygon. stylePolygon(polygon1); Polygon polygon2 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-31.673, 128.892), new LatLng(-31.952, 115.857), new LatLng(-17.785, 122.258), new LatLng(-12.4258, 130.7932))); polygon2.setTag("beta"); stylePolygon(polygon2); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); } private static final int COLOR_BLACK_ARGB = 0xff000000; private static final int POLYLINE_STROKE_WIDTH_PX = 12; /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private void stylePolyline(Polyline polyline) { String type = ""; // Get the data object stored with the polyline. if (polyline.getTag() != null) { type = polyline.getTag().toString(); } switch (type) { // If no type is given, allow the API to use the default. case "A": // Use a custom bitmap as the cap at the start of the line. polyline.setStartCap( new CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10)); break; case "B": // Use a round cap at the start of the line. polyline.setStartCap(new RoundCap()); break; } polyline.setEndCap(new RoundCap()); polyline.setWidth(POLYLINE_STROKE_WIDTH_PX); polyline.setColor(COLOR_BLACK_ARGB); polyline.setJointType(JointType.ROUND); } private static final int PATTERN_GAP_LENGTH_PX = 20; private static final PatternItem DOT = new Dot(); private static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX); // Create a stroke pattern of a gap followed by a dot. private static final List<PatternItem> PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT); /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ @Override public void onPolylineClick(Polyline polyline) { // Flip from solid stroke to dotted stroke pattern. if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) { polyline.setPattern(PATTERN_POLYLINE_DOTTED); } else { // The default pattern is a solid stroke. polyline.setPattern(null); } Toast.makeText(this, "Route type " + polyline.getTag().toString(), Toast.LENGTH_SHORT).show(); } /** * Listens for clicks on a polygon. * @param polygon The polygon object that the user has clicked. */ @Override public void onPolygonClick(Polygon polygon) { // Flip the values of the red, green, and blue components of the polygon's color. int color = polygon.getStrokeColor() ^ 0x00ffffff; polygon.setStrokeColor(color); color = polygon.getFillColor() ^ 0x00ffffff; polygon.setFillColor(color); Toast.makeText(this, "Area type " + polygon.getTag().toString(), Toast.LENGTH_SHORT).show(); } private static final int COLOR_WHITE_ARGB = 0xffffffff; private static final int COLOR_DARK_GREEN_ARGB = 0xff388E3C; private static final int COLOR_LIGHT_GREEN_ARGB = 0xff81C784; private static final int COLOR_DARK_ORANGE_ARGB = 0xffF57F17; private static final int COLOR_LIGHT_ORANGE_ARGB = 0xffF9A825; private static final int POLYGON_STROKE_WIDTH_PX = 8; private static final int PATTERN_DASH_LENGTH_PX = 20; private static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX); // Create a stroke pattern of a gap followed by a dash. private static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH); // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private static final List<PatternItem> PATTERN_POLYGON_BETA = Arrays.asList(DOT, GAP, DASH, GAP); /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private void stylePolygon(Polygon polygon) { String type = ""; // Get the data object stored with the polygon. if (polygon.getTag() != null) { type = polygon.getTag().toString(); } List<PatternItem> pattern = null; int strokeColor = COLOR_BLACK_ARGB; int fillColor = COLOR_WHITE_ARGB; switch (type) { // If no type is given, allow the API to use the default. case "alpha": // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA; strokeColor = COLOR_DARK_GREEN_ARGB; fillColor = COLOR_LIGHT_GREEN_ARGB; break; case "beta": // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA; strokeColor = COLOR_DARK_ORANGE_ARGB; fillColor = COLOR_LIGHT_ORANGE_ARGB; break; } polygon.setStrokePattern(pattern); polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX); polygon.setStrokeColor(strokeColor); polygon.setFillColor(fillColor); } }
عرض إصدار Kotlin من النشاط:
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.example.polygons import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.GoogleMap.OnPolygonClickListener import com.google.android.gms.maps.GoogleMap.OnPolylineClickListener import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.BitmapDescriptorFactory import com.google.android.gms.maps.model.CustomCap import com.google.android.gms.maps.model.Dash import com.google.android.gms.maps.model.Dot import com.google.android.gms.maps.model.Gap import com.google.android.gms.maps.model.JointType import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.Polygon import com.google.android.gms.maps.model.PolygonOptions import com.google.android.gms.maps.model.Polyline import com.google.android.gms.maps.model.PolylineOptions import com.google.android.gms.maps.model.RoundCap /** * An activity that displays a Google map with polylines to represent paths or routes, * and polygons to represent areas. */ class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.tag = "A" // Style the polyline. stylePolyline(polyline1) val polyline2 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-29.501, 119.700), LatLng(-27.456, 119.672), LatLng(-25.971, 124.187), LatLng(-28.081, 126.555), LatLng(-28.848, 124.229), LatLng(-28.215, 123.938))) polyline2.tag = "B" stylePolyline(polyline2) // Add polygons to indicate areas on the map. val polygon1 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-27.457, 153.040), LatLng(-33.852, 151.211), LatLng(-37.813, 144.962), LatLng(-34.928, 138.599))) // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.tag = "alpha" // Style the polygon. stylePolygon(polygon1) val polygon2 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-31.673, 128.892), LatLng(-31.952, 115.857), LatLng(-17.785, 122.258), LatLng(-12.4258, 130.7932))) polygon2.tag = "beta" stylePolygon(polygon2) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) } private val COLOR_BLACK_ARGB = -0x1000000 private val POLYLINE_STROKE_WIDTH_PX = 12 /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private fun stylePolyline(polyline: Polyline) { // Get the data object stored with the polyline. val type = polyline.tag?.toString() ?: "" when (type) { "A" -> { // Use a custom bitmap as the cap at the start of the line. polyline.startCap = CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10f) } "B" -> { // Use a round cap at the start of the line. polyline.startCap = RoundCap() } } polyline.endCap = RoundCap() polyline.width = POLYLINE_STROKE_WIDTH_PX.toFloat() polyline.color = COLOR_BLACK_ARGB polyline.jointType = JointType.ROUND } private val PATTERN_GAP_LENGTH_PX = 20 private val DOT: PatternItem = Dot() private val GAP: PatternItem = Gap(PATTERN_GAP_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dot. private val PATTERN_POLYLINE_DOTTED = listOf(GAP, DOT) /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ override fun onPolylineClick(polyline: Polyline) { // Flip from solid stroke to dotted stroke pattern. if (polyline.pattern == null || !polyline.pattern!!.contains(DOT)) { polyline.pattern = PATTERN_POLYLINE_DOTTED } else { // The default pattern is a solid stroke. polyline.pattern = null } Toast.makeText(this, "Route type " + polyline.tag.toString(), Toast.LENGTH_SHORT).show() } /** * Listens for clicks on a polygon. * @param polygon The polygon object that the user has clicked. */ override fun onPolygonClick(polygon: Polygon) { // Flip the values of the red, green, and blue components of the polygon's color. var color = polygon.strokeColor xor 0x00ffffff polygon.strokeColor = color color = polygon.fillColor xor 0x00ffffff polygon.fillColor = color Toast.makeText(this, "Area type ${polygon.tag?.toString()}", Toast.LENGTH_SHORT).show() } private val COLOR_WHITE_ARGB = -0x1 private val COLOR_DARK_GREEN_ARGB = -0xc771c4 private val COLOR_LIGHT_GREEN_ARGB = -0x7e387c private val COLOR_DARK_ORANGE_ARGB = -0xa80e9 private val COLOR_LIGHT_ORANGE_ARGB = -0x657db private val POLYGON_STROKE_WIDTH_PX = 8 private val PATTERN_DASH_LENGTH_PX = 20 private val DASH: PatternItem = Dash(PATTERN_DASH_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dash. private val PATTERN_POLYGON_ALPHA = listOf(GAP, DASH) // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private val PATTERN_POLYGON_BETA = listOf(DOT, GAP, DASH, GAP) /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private fun stylePolygon(polygon: Polygon) { // Get the data object stored with the polygon. val type = polygon.tag?.toString() ?: "" var pattern: List<PatternItem>? = null var strokeColor = COLOR_BLACK_ARGB var fillColor = COLOR_WHITE_ARGB when (type) { "alpha" -> { // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA strokeColor = COLOR_DARK_GREEN_ARGB fillColor = COLOR_LIGHT_GREEN_ARGB } "beta" -> { // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA strokeColor = COLOR_DARK_ORANGE_ARGB fillColor = COLOR_LIGHT_ORANGE_ARGB } } polygon.strokePattern = pattern polygon.strokeWidth = POLYGON_STROKE_WIDTH_PX.toFloat() polygon.strokeColor = strokeColor polygon.fillColor = fillColor } }
إعداد مشروع التطوير
اتبع الخطوات التالية لإنشاء المشروع التعليمي في Android Studio.
- تنزيل وتثبيت "استوديو Android"
- أضِف حزمة خدمات Google Play إلى "استوديو Android".
- استنساخ مستودع نماذج API الإصدار 2 من خرائط Google أو تنزيله إذا لم تفعل ذلك عند بدء قراءة هذا البرنامج التعليمي.
استيراد مشروع البرنامج التعليمي:
- في Android Studio، حدد ملف > جديد > استيراد المشروع.
- انتقل إلى الموقع الذي حفظت فيه عينات الإصدار 2 من واجهة برمجة تطبيقات خرائط Google لنظام التشغيل Android بعد تنزيله.
- ابحث عن مشروع المضلعات في هذا الموقع:
PATH-TO-SAVED-REPO/android-samples/tutorials/java/Polygons
(جافا) أو
PATH-TO-SAVED-REPO/android-samples/tutorials/kotlin/Polygons
(كوتلين) - اختَر دليل المشروع، ثم انقر على فتح. ينشئ Android Studio الآن مشروعك باستخدام أداة إنشاء Gradle.
تفعيل واجهات برمجة التطبيقات اللازمة والحصول على مفتاح واجهة برمجة تطبيقات
لإكمال هذا البرنامج التعليمي، يلزمك مشروع في Google Cloud تم تمكين واجهات برمجة التطبيقات اللازمة له ومفتاح واجهة برمجة التطبيقات الذي تم تفويضه لاستخدام خرائط SDK لنظام التشغيل Android. لمزيد من التفاصيل، راجع:
إضافة مفتاح واجهة برمجة التطبيقات إلى تطبيقك
- افتح ملف مشروعك
local.properties
. أضف السلسلة التالية ثم استبدل
YOUR_API_KEY
بقيمة مفتاح واجهة برمجة التطبيقات:MAPS_API_KEY=YOUR_API_KEY
عند إنشاء تطبيقك، سيعمل Secrets Gradle Plugin for Android على نسخ مفتاح واجهة برمجة التطبيقات وتوفيره كمتغيّر إصدار في بيان Android على النحو الموضّح أدناه.
إنشاء تطبيقك وتشغيله
لإنشاء التطبيق وتشغيله:
وصِّل جهاز Android بجهاز الكمبيوتر. اتبع التعليمات لتمكين خيارات المطورين على جهاز Android وتهيئة النظام لاكتشاف الجهاز.
بدلاً من ذلك، يمكنك استخدام مدير جهاز Android الافتراضي (AVD) لتهيئة جهاز افتراضي. عند اختيار المحاكي، تأكد من اختيار صورة تتضمن واجهات برمجة تطبيقات Google. للحصول على المزيد من التفاصيل، يمكنك الاطّلاع على إعداد مشروع في "استوديو Android".
في "استوديو Android"، انقر على خيار القائمة تشغيل (أو على رمز زر التشغيل). اختر جهازًا كما هو مطلوب.
يستدعي Android Studio أداة Gradle لإنشاء التطبيق، ثم يشغل التطبيق على الجهاز أو على المحاكي.
ستشاهد خريطة بها مضلعان متراكبان فوق أستراليا، على غرار الصورة الموجودة في هذه الصفحة.
تحرّي الخلل وإصلاحه:
- إذا لم تظهر لك خريطة، فتأكد من أنك حصلت على مفتاح واجهة برمجة تطبيقات وأضفته إلى التطبيق، كما هو موضح أعلاه. اطّلع على السجلّ في أداة مراقبة Android على Android Studio بحثًا عن رسائل الخطأ المتعلقة بمفتاح واجهة برمجة التطبيقات.
- استخدم أدوات تصحيح الأخطاء في استوديو Android لعرض السجلات وتصحيح أخطاء التطبيق.
فهم الشفرة
يوضح هذا الجزء من البرنامج التعليمي الأجزاء المهمة في تطبيق Polygons، لمساعدتك في فهم كيفية إنشاء تطبيق مماثل.
الاطّلاع على بيان Android
لاحظ العناصر التالية في ملف AndroidManifest.xml
لتطبيقك:
أضف عنصر
meta-data
لتضمين إصدار خدمات Google Play الذي تم تجميع التطبيق معه.<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
أضِف عنصر
meta-data
يحدِّد مفتاح واجهة برمجة التطبيقات. يعيّن النموذج المصاحب لهذا البرنامج التعليمي قيمة مفتاح واجهة برمجة التطبيقات لمتغير تصميم يتطابق مع اسم المفتاح الذي حدّدته سابقًا،MAPS_API_KEY
. عند إنشاء تطبيقك، سيعمل المكوّن الإضافي Secrets Gradle Plugin for Android على إتاحة المفاتيح في ملفlocal.properties
على أنها متغيّرات إصدار البيان.<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
في الملف
build.gradle
، يمرّ السطر التالي مفتاح واجهة برمجة التطبيقات إلى بيان Android.id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
في ما يلي مثال كامل لبيان:
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2020 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.polygons"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <!-- The API key for Google Maps-based APIs. --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" /> <activity android:name="com.example.polygons.PolyActivity" android:exported="true" android:label="@string/title_activity_maps"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
إضافة خريطة
يمكنك عرض خريطة باستخدام حزمة SDK للخرائط لنظام التشغيل Android.
أضِف عنصر
<fragment>
إلى ملف تنسيق نشاطك،activity_maps.xml
. يحدّد هذا العنصرSupportMapFragment
ليكون بمثابة حاوية للخريطة وتوفير الوصول إلى العنصرGoogleMap
. ويستخدم البرنامج التعليمي إصدار مكتبة دعم Android لجزء الخريطة لضمان التوافق مع الإصدارات السابقة من إطار عمل Android.<!-- Copyright 2020 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.polygons.PolyActivity" />
في طريقة
onCreate()
لنشاطك، اضبط ملف التنسيق على أنه عرض المحتوى. احصل على مؤشر لجزء الخريطة عن طريق الاتصال بـFragmentManager.findFragmentById()
. بعد ذلك، استخدِمgetMapAsync()
للتسجيل في معاودة الاتصال بالخريطة:لغة Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); }
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) }
نفِّذ واجهة
OnMapReadyCallback
وألغِ طريقةonMapReady()
. تستدعي واجهة برمجة التطبيقات معاودة الاتصال هذه عندما يكون كائنGoogleMap
متاحًا، لذا يمكنك إضافة كائنات إلى الخريطة وتخصيصها بشكل أكبر لتطبيقك:لغة Java
public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); }
Kotlin
class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) }
إضافة خط متعدد لرسم خط على الخريطة
Polyline
هي سلسلة من أجزاء الخطوط المتصلة. الخطوط المتعددة
مفيدة لتمثيل المسارات أو المسارات أو أي اتصالات أخرى بين المواقع على الخريطة.
أنشئ كائن
PolylineOptions
وأضِف نقاطًا إليه. تمثّل كل نقطة موقعًا على الخريطة يمكنك تحديده باستخدام كائنLatLng
يحتوي على قيم خطوط الطول والعرض. ينشئ نموذج الرمز التالي خطًا متعدد الأضلاع مكونًا من 6 نقاط.اتصل بـ
GoogleMap.addPolyline()
لإضافة الخط المتعدد إلى الخريطة.لغة Java
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309)));
Kotlin
val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309)))
يمكنك ضبط خيار clickable
في الخطوط المتعددة على true
إذا كنت تريد معالجة أحداث النقر على الخط المتعدد. هناك المزيد حول التعامل مع الأحداث لاحقًا في هذا البرنامج التعليمي.
تخزين البيانات العشوائية باستخدام الخطوط المتعددة
يمكنك تخزين كائنات البيانات العشوائية باستخدام الخطوط المتعددة والكائنات الهندسية الأخرى.
يمكنك استدعاء
Polyline.setTag()
لتخزين كائن البيانات باستخدام الخط المتعدد. يحدّد الرمز أدناه علامة عشوائية (A
) تشير إلى نوع من الخطوط المتعددة.لغة Java
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.setTag("A");
Kotlin
val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.tag = "A
استرجع البيانات باستخدام
Polyline.getTag()
، كما يظهر في القسم التالي.
إضافة نمط مخصص إلى خطك المتعدد
يمكنك تحديد خصائص التصميم المختلفة في الكائن
PolylineOptions
. تتضمن خيارات التصميم لون الشطب وعرض الشطب ونمط الشطب وأنواع المفاصل وأغطية البداية والنهاية. إذا لم تحدد موقعًا معينًا، فستستخدم واجهة برمجة التطبيقات خاصية افتراضية لذلك الموقع.
يطبّق الرمز التالي غطاءً دائريًا على نهاية السطر، بالإضافة إلى سقف مختلف للبداية بناءً على نوع الخط متعدد الخطوط، حيث يكون النوع خاصية عشوائية يتم تخزينها في كائن البيانات للخط المتعدد. يحدد النموذج أيضًا عرض الشطب، ولون الشطب، ونوع المفصل:
لغة Java
private static final int COLOR_BLACK_ARGB = 0xff000000; private static final int POLYLINE_STROKE_WIDTH_PX = 12; /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private void stylePolyline(Polyline polyline) { String type = ""; // Get the data object stored with the polyline. if (polyline.getTag() != null) { type = polyline.getTag().toString(); } switch (type) { // If no type is given, allow the API to use the default. case "A": // Use a custom bitmap as the cap at the start of the line. polyline.setStartCap( new CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10)); break; case "B": // Use a round cap at the start of the line. polyline.setStartCap(new RoundCap()); break; } polyline.setEndCap(new RoundCap()); polyline.setWidth(POLYLINE_STROKE_WIDTH_PX); polyline.setColor(COLOR_BLACK_ARGB); polyline.setJointType(JointType.ROUND); }
Kotlin
private val COLOR_BLACK_ARGB = -0x1000000 private val POLYLINE_STROKE_WIDTH_PX = 12 /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private fun stylePolyline(polyline: Polyline) { // Get the data object stored with the polyline. val type = polyline.tag?.toString() ?: "" when (type) { "A" -> { // Use a custom bitmap as the cap at the start of the line. polyline.startCap = CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10f) } "B" -> { // Use a round cap at the start of the line. polyline.startCap = RoundCap() } } polyline.endCap = RoundCap() polyline.width = POLYLINE_STROKE_WIDTH_PX.toFloat() polyline.color = COLOR_BLACK_ARGB polyline.jointType = JointType.ROUND }
يحدد الرمز البرمجي أعلاه صورة نقطية مخصصة لغطاء البدء من النوع المتعدد A، ويحدد عرضًا شطبًا مرجعيًا بقيمة 10 بكسل. تعمل واجهة برمجة التطبيقات على تغيير حجم الصورة النقطية استنادًا إلى عرض شطب المرجع. عند تحديد عرض شطب المرجع، قدّم العرض الذي استخدمته عند تصميم الصورة النقطية في البعد الأصلي للصورة. تلميح: افتح الصورة النقطية بنسبة تكبير 100% في محرر الصور، وارسم العرض المطلوب لشطب الخط وفقًا للصورة.
تعرَّف على المزيد من المعلومات عن الحد الأقصى من الأسطر والخيارات الأخرى لتخصيص الأشكال.
التعامل مع أحداث النقر على الخط المتعدد
جعل الخطوط المتعددة قابلة للنقر من خلال الاتصال
Polyline.setClickable()
. (بشكل افتراضي، الخطوط المتعددة غير قابلة للنقر، ولن يتلقى تطبيقك إشعارًا عندما ينقر المستخدم على أحد الخطوط المتصلة.)نفِّذ واجهة
OnPolylineClickListener
واتصل بالرقمGoogleMap.setOnPolylineClickListener()
لضبط المستمع على الخريطة:لغة Java
public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); }
Kotlin
class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) }
يمكنك إلغاء طريقة رد الاتصال في
onPolylineClick()
. يستبدل المثال التالي نمط شطب الخط بين متصل ومنقط، في كل مرة ينقر المستخدم على الخطوط المتعددة:لغة Java
private static final int PATTERN_GAP_LENGTH_PX = 20; private static final PatternItem DOT = new Dot(); private static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX); // Create a stroke pattern of a gap followed by a dot. private static final List<PatternItem> PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT); /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ @Override public void onPolylineClick(Polyline polyline) { // Flip from solid stroke to dotted stroke pattern. if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) { polyline.setPattern(PATTERN_POLYLINE_DOTTED); } else { // The default pattern is a solid stroke. polyline.setPattern(null); } Toast.makeText(this, "Route type " + polyline.getTag().toString(), Toast.LENGTH_SHORT).show(); }
Kotlin
private val PATTERN_GAP_LENGTH_PX = 20 private val DOT: PatternItem = Dot() private val GAP: PatternItem = Gap(PATTERN_GAP_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dot. private val PATTERN_POLYLINE_DOTTED = listOf(GAP, DOT) /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ override fun onPolylineClick(polyline: Polyline) { // Flip from solid stroke to dotted stroke pattern. if (polyline.pattern == null || !polyline.pattern!!.contains(DOT)) { polyline.pattern = PATTERN_POLYLINE_DOTTED } else { // The default pattern is a solid stroke. polyline.pattern = null } Toast.makeText(this, "Route type " + polyline.tag.toString(), Toast.LENGTH_SHORT).show() }
إضافة مضلّعات لتمثيل المناطق على الخريطة
Polygon
هو شكل يتكون من سلسلة من الإحداثيات في تسلسل مرتَّب، على غرار Polyline
. الفرق هو أن المضلّع يحدد منطقة مغلقة ذات تصميم داخلي قابل للملء، في حين أن المضلع مفتوح.
أنشئ كائن
PolygonOptions
وأضِف نقاطًا إليه. تمثّل كل نقطة موقعًا على الخريطة يمكنك تحديده باستخدام كائنLatLng
يحتوي على قيم خطوط الطول والعرض. ينشئ نموذج الشفرة أدناه مضلعًا بأربع نقاط.جعل المضلع قابلاً للنقر بالاتصال بـ
Polygon.setClickable()
. (بشكل افتراضي، لا تكون المضلعات قابلة للنقر، ولن يتلقى تطبيقك إشعارًا عندما ينقر المستخدم على المضلع). إن معالجة أحداث النقر المضلّع مماثلة لمعالجة الأحداث على الخطوط المتصلة، كما هو موضح سابقًا في هذا البرنامج التعليمي.اتصل بـ
GoogleMap.addPolygon()
لإضافة المضلع إلى الخريطة.يمكنك استدعاء
Polygon.setTag()
لتخزين عنصر بيانات باستخدام المضلّع. يحدد الرمز أدناه نوعًا عشوائيًا (alpha
) للمضلع.لغة Java
// Add polygons to indicate areas on the map. Polygon polygon1 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-27.457, 153.040), new LatLng(-33.852, 151.211), new LatLng(-37.813, 144.962), new LatLng(-34.928, 138.599))); // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.setTag("alpha");
Kotlin
// Add polygons to indicate areas on the map. val polygon1 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-27.457, 153.040), LatLng(-33.852, 151.211), LatLng(-37.813, 144.962), LatLng(-34.928, 138.599))) // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.tag = "alpha" // Style the polygon.
إضافة نمط مخصص إلى المضلع
يمكنك تحديد عدد من خصائص التصميم في الكائن
PolygonOptions
. تتضمن خيارات التصميم لون الشطب وعرض الشطب ونمط الشطب وأنواع وصلات الشطب ولون التعبئة. إذا لم تحدد موقعًا معينًا، فستستخدم واجهة برمجة التطبيقات خاصية افتراضية لذلك الموقع.
تطبّق الشفرة التالية ألوانًا وأنماطًا محددة للشطب بناءً على نوع المضلّع، حيث يكون النوع عبارة عن خاصية عشوائية مخزنة في كائن البيانات للمضلعات:
لغة Java
private static final int COLOR_WHITE_ARGB = 0xffffffff; private static final int COLOR_DARK_GREEN_ARGB = 0xff388E3C; private static final int COLOR_LIGHT_GREEN_ARGB = 0xff81C784; private static final int COLOR_DARK_ORANGE_ARGB = 0xffF57F17; private static final int COLOR_LIGHT_ORANGE_ARGB = 0xffF9A825; private static final int POLYGON_STROKE_WIDTH_PX = 8; private static final int PATTERN_DASH_LENGTH_PX = 20; private static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX); // Create a stroke pattern of a gap followed by a dash. private static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH); // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private static final List<PatternItem> PATTERN_POLYGON_BETA = Arrays.asList(DOT, GAP, DASH, GAP); /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private void stylePolygon(Polygon polygon) { String type = ""; // Get the data object stored with the polygon. if (polygon.getTag() != null) { type = polygon.getTag().toString(); } List<PatternItem> pattern = null; int strokeColor = COLOR_BLACK_ARGB; int fillColor = COLOR_WHITE_ARGB; switch (type) { // If no type is given, allow the API to use the default. case "alpha": // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA; strokeColor = COLOR_DARK_GREEN_ARGB; fillColor = COLOR_LIGHT_GREEN_ARGB; break; case "beta": // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA; strokeColor = COLOR_DARK_ORANGE_ARGB; fillColor = COLOR_LIGHT_ORANGE_ARGB; break; } polygon.setStrokePattern(pattern); polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX); polygon.setStrokeColor(strokeColor); polygon.setFillColor(fillColor); }
Kotlin
private val COLOR_WHITE_ARGB = -0x1 private val COLOR_DARK_GREEN_ARGB = -0xc771c4 private val COLOR_LIGHT_GREEN_ARGB = -0x7e387c private val COLOR_DARK_ORANGE_ARGB = -0xa80e9 private val COLOR_LIGHT_ORANGE_ARGB = -0x657db private val POLYGON_STROKE_WIDTH_PX = 8 private val PATTERN_DASH_LENGTH_PX = 20 private val DASH: PatternItem = Dash(PATTERN_DASH_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dash. private val PATTERN_POLYGON_ALPHA = listOf(GAP, DASH) // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private val PATTERN_POLYGON_BETA = listOf(DOT, GAP, DASH, GAP) /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private fun stylePolygon(polygon: Polygon) { // Get the data object stored with the polygon. val type = polygon.tag?.toString() ?: "" var pattern: List<PatternItem>? = null var strokeColor = COLOR_BLACK_ARGB var fillColor = COLOR_WHITE_ARGB when (type) { "alpha" -> { // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA strokeColor = COLOR_DARK_GREEN_ARGB fillColor = COLOR_LIGHT_GREEN_ARGB } "beta" -> { // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA strokeColor = COLOR_DARK_ORANGE_ARGB fillColor = COLOR_LIGHT_ORANGE_ARGB } } polygon.strokePattern = pattern polygon.strokeWidth = POLYGON_STROKE_WIDTH_PX.toFloat() polygon.strokeColor = strokeColor polygon.fillColor = fillColor }
مزيد من المعلومات حول أنماط الشطب والخيارات الأخرى لتخصيص الأشكال.
الخطوات التالية
تعرّف على معلومات عن الكائن الدائرة. تشبه الدوائر المضلعات ولكن لها خصائص تعكس شكل الدائرة.