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