العرض المركّب باستخدام WebGL

عرض عيّنة

باستخدام WebGL Overlay View، يمكنك إضافة محتوى إلى خرائطك مباشرةً باستخدام WebGL أو مكتبات الرسومات الشائعة، مثل Three.js. توفّر WebGL Overlay View إمكانية الوصول المباشر إلى سياق عرض WebGL نفسه الذي تستخدمه "منصة خرائط Google" لعرض الخريطة الأساسية المتجهة. ويوفّر استخدام سياق العرض المشترك هذا مزايا، مثل حجب العمق باستخدام أشكال هندسية ثلاثية الأبعاد للمباني، وإمكانية مزامنة المحتوى الثنائي الأبعاد/الثلاثي الأبعاد مع عرض الخريطة الأساسية. يمكن أيضًا ربط العناصر المعروضة باستخدام WebGL Overlay View بإحداثيات خطوط الطول والعرض، وبالتالي تتحرّك هذه العناصر عند سحب الخريطة أو تكبيرها أو تصغيرها أو تحريكها أو إمالتها.

المتطلبات

لاستخدام WebGL Overlay View، يجب تحميل الخريطة باستخدام رقم تعريف خريطة مع تفعيل الخريطة المتجهة. ننصحك بشدة بتفعيل ميزة الإمالة والتدوير عند إنشاء معرّف الخريطة، وذلك للسماح بالتحكّم الكامل بالكاميرا الثلاثية الأبعاد. الاطّلاع على النظرة العامة للحصول على التفاصيل

إضافة العرض المركّب باستخدام 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 Overlay View سياق عرض 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 Overlay View دالة المساعدة 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);