باستخدام العرض المركّب باستخدام WebGL، يمكنك إضافة محتوى إلى خرائطك مباشرةً باستخدام WebGL أو مكتبات الرسومات الشائعة، مثل Three.js. يتيح العرض المركّب باستخدام WebGL الوصول المباشر إلى سياق عرض WebGL نفسه الذي تستخدمه "منصة خرائط Google" لعرض الخريطة الأساسية المتّجهة. ويوفّر استخدام سياق عرض مشترك مزايا، مثل حجب العمق باستخدام هندسة المباني الثلاثية الأبعاد، وإمكانية مزامنة المحتوى الثنائي الأبعاد/الثلاثي الأبعاد مع عرض الخريطة الأساسية. يمكن أيضًا ربط العناصر المعروضة باستخدام العرض المركّب باستخدام WebGL بإحداثيات خط العرض/خط الطول، ما يعني أنّها تتحرّك عند سحب الخريطة أو تكبيرها أو تصغيرها أو تحريكها أو إمالتها.
المتطلبات
لاستخدام العرض المركّب باستخدام WebGL، يجب تحميل الخريطة باستخدام معرّف خريطة تم تفعيل الخريطة المتّجهة فيه. ننصحك بشدة بتفعيل الإمالة والتدوير عند إنشاء معرّف الخريطة للسماح بالتحكّم الكامل في الكاميرا الثلاثية الأبعاد. راجِع النظرة العامة للحصول على التفاصيل.
إضافة العرض المركّب باستخدام WebGL
لإضافة العرض المركّب إلى خريطتك، عليك تنفيذ google.maps.WebGLOverlayView، ثم تمرير مثيل الخريطة إليه باستخدام setMap:
// Create a map instance.
const map = new google.maps.Map(mapDiv, mapOptions);
// Create a WebGL Overlay View instance.
const webglOverlayView = new google.maps.WebGLOverlayView();
// Add the overlay to the map.
webglOverlayView.setMap(map);
خطافات مراحل النشاط
يوفّر العرض المركّب باستخدام WebGL مجموعة من الخطافات التي يتم استدعاؤها في أوقات مختلفة من مراحل نشاط سياق عرض WebGL للخريطة الأساسية المتّجهة. تُستخدم خطافات مراحل النشاط هذه لإعداد أي عنصر تريد عرضه في العرض المركّب ورسمه وإزالته.
- يتم استدعاء
onAdd()عند إنشاء العرض المركّب. استخدِم هذه الدالة لجلب بُنى البيانات الوسيطة أو إنشائها قبل رسم العرض المركّب، والتي لا تتطلّب الوصول الفوري إلى سياق عرض WebGL. - يتم استدعاء
onContextRestored({gl})عندما يصبح سياق العرض متاحًا. استخدِم هذه الدالة لتهيئة أي حالة WebGL أو ربطها، مثل التظليلات وعناصر المخزن المؤقت GL وما إلى ذلك.onContextRestored()تأخذWebGLStateOptionsمثيلاً، الذي يحتوي على حقل واحد:glهو مؤشر إلىWebGLRenderingContextالذي تستخدمه الخريطة الأساسية.
- تعرض الدالة
onDraw({gl, transformer})المشهد على الخريطة الأساسية. المَعلمات الخاصة بالدالةonDraw()هي كائنWebGLDrawOptions، الذي يحتوي على حقلَين:glهو مؤشر إلىWebGLRenderingContextالذي تستخدمه الخريطة الأساسية.- توفّر السمة
transformerدوال مساعِدة للتحويل من إحداثيات الخريطة إلى مصفوفة عرض النموذج والإسقاط، والتي يمكن استخدامها لترجمة إحداثيات الخريطة إلى مساحة العالم ومساحة الكاميرا ومساحة الشاشة.
- يتم استدعاء
onContextLost()عندما يتم فقدان سياق العرض لأي سبب، ويجب استخدام هذه الدالة لتنظيف أي حالة GL حالية، لأنّها لم تعُد مطلوبة. - تعدِّل الدالة
onStateUpdate({gl})حالة GL خارج حلقة العرض، ويتم استدعاؤها عند استدعاءrequestStateUpdate. تأخذ هذه الدالة مثيلاً منWebGLStateOptions، الذي يحتوي على حقل واحد:glهو مؤشر إلىWebGLRenderingContextالذي تستخدمه الخريطة الأساسية.
- يتم استدعاء
onRemove()عندما تتم إزالة العرض المركّب من الخريطة باستخدامWebGLOverlayView.setMap(null)، ويجب استخدام هذه الدالة لإزالة جميع الكائنات الوسيطة.
على سبيل المثال، في ما يلي تنفيذ أساسي لجميع خطافات مراحل النشاط:
const webglOverlayView = new google.maps.WebGLOverlayView();
webglOverlayView.onAdd = () => {
// Do setup that does not require access to rendering context.
}
webglOverlayView.onContextRestored = ({gl}) => {
// Do setup that requires access to rendering context before onDraw call.
}
webglOverlayView.onStateUpdate = ({gl}) => {
// Do GL state setup or updates outside of the render loop.
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Render objects.
}
webglOverlayView.onContextLost = () => {
// Clean up pre-existing GL state.
}
webglOverlayView.onRemove = () => {
// Remove all intermediate objects.
}
webglOverlayView.setMap(map);
إعادة ضبط حالة GL
يعرض العرض المركّب باستخدام WebGL سياق عرض WebGL للخريطة الأساسية. لهذا السبب، من المهم للغاية إعادة ضبط حالة GL إلى حالتها الأصلية عند الانتهاء من عرض الكائنات. من المرجّح أن يؤدي عدم إعادة ضبط حالة GL إلى حدوث تعارضات في حالة GL، ما سيؤدي إلى تعذُّر عرض كل من الخريطة وأي كائنات تحدّدها.
تتم عادةً معالجة إعادة ضبط حالة GL في خطاف onDraw(). على سبيل المثال، توفّر مكتبة Three.js دالة مساعِدة تزيل أي تغييرات في حالة GL:
webglOverlayView.onDraw = ({gl, transformer}) => {
// Specify an object to render.
renderer.render(scene, camera);
renderer.resetState();
}
إذا تعذّر عرض الخريطة أو الكائنات، من المرجّح أنّه لم تتم إعادة ضبط حالة GL.
تحويلات الإحداثيات
يتم تحديد موضع الكائن على الخريطة المتّجهة من خلال توفير مجموعة من إحداثيات خط العرض وخط الطول، بالإضافة إلى الارتفاع. في المقابل، يتم تحديد الرسومات الثلاثية الأبعاد في مساحة العالم أو مساحة الكاميرا أو مساحة الشاشة.
لتسهيل تحويل إحداثيات الخريطة إلى هذه المساحات الأكثر شيوعًا، يوفّر العرض المركّب باستخدام WebGL الدالة المساعِدة coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr,
scalarArr) في موضع الإدراج onDraw() الذي يأخذ ما يلي ويعرض Float64Array:
latLngAltitude: إحداثيات خط العرض/خط الطول/الارتفاع إما كـLatLngAltitudeأوLatLngAltitudeLiteral.rotationArr:Float32Arrayمن زوايا التدوير في نظام إحداثيات أويلر المحدّدة بالدرجات.scalarArr:Float32Arrayمن القيم العددية التي سيتم تطبيقها على المحور الأساسي.
على سبيل المثال، يستخدم ما يلي fromLatLngAltitude() لإنشاء مصفوفة إسقاط الكاميرا في Three.js:
const camera = new THREE.PerspectiveCamera();
const matrix = coordinateTransformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
مثال
في ما يلي مثال بسيط على استخدام Three.js، وهي مكتبة WebGL شائعة ومفتوحة المصدر، لوضع كائن ثلاثي الأبعاد على الخريطة. للحصول على شرح كامل حول استخدام العرض المركّب باستخدام WebGL لإنشاء المثال الذي يظهر في أعلى هذه الصفحة، جرِّب الدرس التطبيقي حول الترميز إنشاء تجارب خرائط مُحسَّنة باستخدام WebGL.
const webglOverlayView = new google.maps.WebGLOverlayView();
let scene, renderer, camera, loader;
webglOverlayView.onAdd = () => {
// Set up the Three.js scene.
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera();
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.75 ); // Soft white light.
scene.add(ambientLight);
// Load the 3D model with GLTF Loader from Three.js.
loader = new GLTFLoader();
loader.load("pin.gltf");
}
webglOverlayView.onContextRestored = ({gl}) => {
// Create the Three.js renderer, using the
// maps's WebGL rendering context.
renderer = new THREE.WebGLRenderer({
canvas: gl.canvas,
context: gl,
...gl.getContextAttributes(),
});
renderer.autoClear = false;
}
webglOverlayView.onDraw = ({gl, transformer}) => {
// Update camera matrix to ensure the model is georeferenced correctly on the map.
const matrix = transformer.fromLatLngAltitude({
lat: mapOptions.center.lat,
lng: mapOptions.center.lng,
altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
// Request a redraw and render the scene.
webglOverlayView.requestRedraw();
renderer.render(scene, camera);
// Always reset the GL state.
renderer.resetState();
}
// Add the overlay to the map.
webglOverlayView.setMap(map);