عرض تراكب WebGL

عرض النموذج

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