diff --git a/docs/README.md b/docs/README.md index ace9800a370..5e5bfcdf03a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -104,7 +104,7 @@ deck.gl is developed in parallel with a number of companion modules, including: * [luma.gl](https://luma.gl/) - A general purpose WebGL2/WebGPU library designed to be interoperable both with the raw browser APIs and (as far as possible) with other WebGL2/WebGPU libraries. In particular, luma.gl does not claim ownership of the WebGL2/WebGPU context, and can work with any supplied context, including contexts created by the application or other libraries. * [loaders.gl](https://loaders.gl) - a suite of framework-independent loaders for file formats focused on visualization of big data, including point clouds, 3D geometries, images, geospatial formats as well as tabular data. -* [react-map-gl](https://visgl.github.io/react-map-gl/) - A React wrapper around Mapbox GL which works seamlessly with deck.gl. +* [react-map-gl](https://visgl.github.io/react-map-gl/) - A React wrapper around Mapbox GL which works seamlessly with deck.gl. There are two integration modes to choose from depending on which features you need, see [Using With Mapbox](./developer-guide/base-maps/using-with-mapbox.md#react-map-gl) for details. * [nebula.gl](https://nebula.gl/) - A high-performance feature editing framework for deck.gl. diff --git a/docs/api-reference/core/map-view.md b/docs/api-reference/core/map-view.md index 23c9dbbf4fe..c266c04f4c4 100644 --- a/docs/api-reference/core/map-view.md +++ b/docs/api-reference/core/map-view.md @@ -66,6 +66,7 @@ To render, `MapView` needs to be used together with a `viewState` with the follo - `minZoom` (Number, optional) - min zoom level. Default `0`. - `maxPitch` (Number, optional) - max pitch angle. Default `60`. - `minPitch` (Number, optional) - min pitch angle. Default `0`. +- `position` (Array, optional) - Viewport center offsets from lng, lat in meters. Default: `[0,0,0]`. ## Controller diff --git a/docs/api-reference/mapbox/mapbox-overlay.md b/docs/api-reference/mapbox/mapbox-overlay.md index 94bf6194f39..6856b8b6398 100644 --- a/docs/api-reference/mapbox/mapbox-overlay.md +++ b/docs/api-reference/mapbox/mapbox-overlay.md @@ -133,7 +133,7 @@ new MapboxOverlay(props); The constructor additionally accepts the following option: -- `interleaved` (Boolean) - If `false`, a dedicated deck.gl canvas is added on top of the base map. If `true`, deck.gl layers are inserted into mapbox-gl's layer stack, and share the same WebGL2RenderingContext as the base map. Default is `false`. +- `interleaved` (Boolean) - If `false`, a dedicated deck.gl canvas is added on top of the base map. If `true`, deck.gl layers are inserted into mapbox-gl's layer stack, and share the same `WebGL2RenderingContext` as the base map. Default is `false`. Note that interleaving with basemaps such as mapbox-gl-js v1 that only support WebGL 1 is not supported, see [compatibility](./overview#compatibility). When using `interleaved: true`, you may optionally add a `beforeId` prop to a layer to specify its position in the Mapbox layer stack. If multiple deck.gl layers have the same `beforeId`, they are rendered in the order that is passed into the `layers` array. diff --git a/docs/api-reference/mapbox/overview.md b/docs/api-reference/mapbox/overview.md index f3e4f4fb4fb..777f60dc956 100644 --- a/docs/api-reference/mapbox/overview.md +++ b/docs/api-reference/mapbox/overview.md @@ -1,9 +1,18 @@ # @deck.gl/mapbox -This module makes it easy to use deck.gl as native layers and controls in the Mapbox GL JS ecosystem. +This module integrates deck.gl into the Mapbox GL JS API-compatible ecosystem. -- It allows deck.gl to be used with other mapbox-gl controls such as `NavigationControl`, `GeolocateControl` and `mapbox-gl-geocoder`. -- You may choose to interleave deck.gl layers with the base map layers, such as drawing behind map labels, z-occlusion between deck.gl 3D objects and Mapbox buildings, etc. +- It synchronizes a deck.gl `MapView` with the [mapbox-gl camera](https://docs.mapbox.com/mapbox-gl-js/guides/#camera). +- It allows deck.gl to be used with mapbox-gl [controls](https://docs.mapbox.com/mapbox-gl-js/api/markers) and [plugins](https://docs.mapbox.com/mapbox-gl-js/plugins/) such as `NavigationControl`, `GeolocateControl` and `mapbox-gl-geocoder`. +- It adds the option to interleave deck.gl layers with the base map layers, such as drawing behind map labels, z-occlusion between deck.gl 3D objects and Mapbox buildings, etc. + +This module may be used in the React, Pure JS, and Scripting Environments. Visit the [mapbox base map developer guide](../../developer-guide/base-maps/using-with-mapbox.md) for examples of each option. + +When you use this module, Mapbox is the root HTML element and deck.gl is the child, with Mapbox handling all user inputs. Some of deck.gl's features are therefore unavailable due to limitations of mapbox-gl's API, see [limitations](#limitations). + +It may be easier to understand the concepts of the module if you are already a mapbox-gl developer. + +> This module is compatible with Mapbox GL JS forks. Known exceptions will be clearly marked. For more, see [Compatibility with Mapbox GL JS forks](../../developer-guide/base-maps/using-with-mapbox.md#compatibility-with-mapbox-gl-js-forks) @@ -13,8 +22,8 @@ This module makes it easy to use deck.gl as native layers and controls in the Ma ### Include the Standalone Bundle ```html - - + + @@ -30,33 +39,48 @@ npm install @deck.gl/mapbox import {MapboxOverlay} from '@deck.gl/mapbox'; ``` +### Camera Syncronization between deck.gl and Mapbox -## Use Cases +This module keeps a deck.gl `MapView` in sync with the mapbox-gl camera so that the base map and deck layers are always geospactially aligned. Some `Deck` props, such as `viewState`, are ignored or have different behavior. See `MapboxOverlay` constructor notes. Also, some camera features are unable to be fully synchronized due to mapbox-gl API limitations, see [limitations](#limitations). -One should note that this module is *not required* to use mapbox-gl as a base map for deck.gl. When you use this module, Mapbox is the root element and deck.gl is the child, with Mapbox handling all user inputs. Some of deck.gl's features are therefore unavailable due to limitations of mapbox-gl's API, see [limitations](#limitations) below. If you just want the base map as a back drop, and do not need mapbox-gl's UI controls or mixing deck and Mapbox layers, it is recommended that you use deck.gl as the root element. Visit the [mapbox base map developer guide](../../developer-guide/base-maps/using-with-mapbox.md) for examples of each option. +### Using mapbox-gl controls and plugins with deck.gl + +The Mapbox ecosystem offers many well-designed controls, from the basic functionalities of `NavigationControl`, `Popup` and `GeolocateControl`, to vendor-service-bound UI implementations such as `mapbox-gl-geocoder` and `mapbox-gl-directions`. These libraries require that the Mapbox Map holds the source of truth of the camera state, instead of the normal [state management](../../developer-guide/interactivity.md) by `Deck`. When you use the `MapboxOverlay` classes from this module, deck.gl plays nice with all the mapbox-gl peripherals. -It may be easier to understand the concepts of the module if you are already a mapbox-gl developer. ### Mixing deck.gl layers and Mapbox layers -One major use case for interleaving deck.gl and Mapbox is that some important information in the Mapbox map could be hidden by a deck.gl visualization layer, and controlling opacity is not enough. A typical example of this is labels and roads, where it is desirable to have a deck.gl visualization layer render on top of the Mapbox geography, but where one might still want to see e.g. labels and/or roads. Alternatively, the deck.gl visualization should cover the ground, but not the roads and labels. +Some important information in the Mapbox map could be hidden by a deck.gl visualization layer, and controlling opacity is not enough. A typical example of this is labels and roads, where it is desirable to have a deck.gl visualization layer render on top of the Mapbox geography, but where one might still want to see e.g. labels and/or roads. Alternatively, the deck.gl visualization should cover the ground, but not the roads and labels. -To inject a deck layer into the Mapbox stack add a `beforeId` prop to any layer passed to the [MapboxOverlay](./mapbox-overlay.md) control. +To inject a deck layer into the Mapbox stack add an `interleaved: true` props to the [MapboxOverlay](./mapbox-overlay.md) control and add a `beforeId` prop to any layer passed to the [MapboxOverlay](./mapbox-overlay.md) control. Mapbox provides an example of [finding the first label layer](https://www.mapbox.com/mapbox-gl-js/example/geojson-layer-in-stack/). For more sophisticated injection point lookups, refer to Mapbox' documentation on the format of Mapbox style layers, see [Mapbox Style Spec](https://www.mapbox.com/mapbox-gl-js/style-spec/#layers). In some cases, the application wants to add a deck.gl 3D layer (e.g. ArcLayer, HexagonLayer, GeoJsonLayer) on top of a Mapbox basemap, while seamlessly blend into the z-buffer. This will interleave the useful visualization layers from both the deck.gl and Mapbox layer catalogs. In this case, a `beforeId` is not needed. +#### Interleaved Renderer Compatibility + +The following table details renderer support across different versions of mapbox-gl and maplibre-gl. See [base map renderers](../../get-started/using-with-map.md#base-maps-renderers) to learn about the differences between overlaid and interleaved renderers. -### Using mapbox-gl controls with deck.gl +| Library | Overlaid (default) | Interleaved | +|-------------------------------|--------------------|-------------------| +| mapbox-gl-js (before v2.13) | ✓ | | +| mapbox-gl-js v2.13+ | ✓ | ✓ with `useWebGl2: true` | +| mapbox-gl-js v3+ | ✓ | ✓ | +| maplibre-gl-js (before v3) | ✓ | | +| maplibre-gl-js v3+ | ✓ | ✓* | -The Mapbox ecosystem offers many well-designed controls, from the basic functionalities of `NavigationControl`, `Popup` and `GeolocateControl`, to vendor-service-bound UI implementations such as `mapbox-gl-geocoder` and `mapbox-gl-directions`. These libraries require that the Mapbox Map holds the source of truth of the camera state, instead of the normal [state management](../../developer-guide/interactivity.md) by `Deck`. When you use the `MapboxOverlay` class from this module, deck.gl plays nice with all the mapbox-gl peripherals. +> *will fallback to WebGL1 if WebGL2 is not available +## Alternative Mapbox Integrations + +If you're using deck.gl in a React or Scripting environment, you just want the base map as a back drop, and do not need mapbox-gl's UI controls or need to mix deck.gl and Mapbox layers, it is recommended that you do not use this module and instead use deck.gl as the root HTML element. Visit [Using Deck.gl as the root HTML element](../../developer-guide/base-maps/using-with-mapbox.md#using-deckgl-as-the-root-html-element) for an example. ## Limitations * When using deck.gl's multi-view system, only one of the views can match the base map and receive interaction. See [using MapboxOverlay with multi-views](./mapbox-overlay.md#multi-view-usage) for details. * When using deck.gl as Mapbox layers or controls, `Deck` only receives a subset of user inputs delegated by `Map`. Therefore, certain interactive callbacks like `onDrag`, `onInteractionStateChange` are not available. * Mapbox/Maplibre's terrain features are partially supported. When a terrain is used, the camera of deck.gl and the base map should synchronize, however the deck.gl data with z=0 are rendered at the sea level and not aligned with the terrain surface. - +* Only Mercator projection is supported. Mapbox adaptive projection is not supported as their API doesn't expose the projection used. +* The `position` property in `viewState` has no equivalent in mapbox-gl. \ No newline at end of file diff --git a/docs/developer-guide/base-maps/using-with-mapbox.md b/docs/developer-guide/base-maps/using-with-mapbox.md index 50a855a1e9e..0cd412ea5a6 100644 --- a/docs/developer-guide/base-maps/using-with-mapbox.md +++ b/docs/developer-guide/base-maps/using-with-mapbox.md @@ -4,29 +4,110 @@ | ----- | ----- | ----- | ----- | | ✓ | ✓ | [example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/mapbox) | [example](https://deck.gl/gallery/mapbox-overlay) | +![deck.gl interleaved with Mapbox layers](https://raw.github.com/visgl/deck.gl-data/master/images/whats-new/mapbox-layers.jpg) + [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) is a powerful open-source map renderer from [Mapbox](https://mapbox.com). deck.gl's `MapView` is designed to sync perfectly with the camera of Mapbox, at every zoom level and rotation angle. When using deck.gl and Mapbox, there are three options you can choose from: -- Using the Deck canvas as a overlay on top of the Mapbox map, and Deck as the root element. In this option, deck.gl handles all user input, and holds the source of truth of the camera state. The [React get-started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/react/mapbox/) illustrates the basic pattern. This is the most tested and robust use case, as you can find in all the [examples on this website](https://deck.gl/examples/website). It supports all the features of Deck. -- Using the Deck canvas as a overlay on top of the Mapbox map, and Mapbox as the root element. In this option, mapbox-gl handles all user input, and holds the source of truth of the camera state. The [vanilla JS get-started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/mapbox/) illustrates this pattern. The `MapboxOverlay` class in [@deck.gl/mapbox](../../api-reference/mapbox/overview.md) implements the mapbox-gl control interface to insert deck into the map container. This is favorable if you need to use other mapbox-gl controls and plugins in addition to deck.gl. -- Using deck.gl layers interleaved with Mapbox layers in the same WebGL2 context, using either the `MapboxOverlay` or `MapboxLayer` from the [@deck.gl/mapbox](../../api-reference/mapbox/overview.md) module. This allows you to mix deck.gl layers with base map layers, e.g. below text labels or occlude each other correctly in 3D. Be cautious that this feature subjects to bugs and limitations of mapbox-gl's custom layer interface. +1. All deck.gl environments support deep integration with Mapbox features using the [@deck.gl/mapbox](../../api-reference/mapbox/overview.md) module. This is recommended approach as it supports interleaved and overlaid rendering, as well as Mapbox controls and plugins. See [Inserting deck.gl into the Mapbox container](#inserting-deckgl-into-the-mapbox-container). +2. The deck.gl React API supports an additional configuration when you just need a map backdrop and prefer to use the Deck API for [interactivity](../../developer-guide/interactivity.md). See [Inserting Mapbox into the deck.gl container](#inserting-mapbox-into-the-deckgl-container). +3. Finally, deck.gl offers out-of-the-box integration with Mapbox when using the [Scripting API](https://deck.gl/docs/get-started/using-standalone#using-the-scripting-api). -![deck.gl interleaved with Mapbox layers](https://raw.github.com/visgl/deck.gl-data/master/images/whats-new/mapbox-layers.jpg) +## Inserting deck.gl into the Mapbox container + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +```jsx +import Map, {useControl} from 'react-map-gl'; +import { MapboxOverlay } from '@deck.gl/mapbox'; + +function DeckGLOverlay(props) { + const overlay = useControl(() => new MapboxOverlay(props)); + overlay.setProps(props); + return null; +} + + + + +``` + + + + +```js +import mapboxgl from 'mapbox-gl'; +import { MapboxOverlay as DeckOverlay } from '@deck.gl/mapbox'; + +const map = new mapboxgl.Map({ + center: [-74.5, 40], + zoom: 12 +}) +map.addControl(new DeckOverlay({ interleaved: true, layers: [] })) +``` + + + + +If you want to use features of mapbox-gl, such as controls like `NavigationControl` or plugins, then need to insert Deck into the Mapbox map container using [MapboxOverlay](../../api-reference/mapbox/mapbox-overlay) from the [@deck.gl/mapbox](../../api-reference/mapbox/overview.md) module, which allows you to construct a Deck instance and apply it to a map using the [IControl](https://docs.mapbox.com/mapbox-gl-js/api/markers/#icontrol) API. In this configuration mapbox-gl handles all user input, holds the source of truth of the camera state, and is the root HTML element of your map. + +There are two renderers to pick from, overlaid or interleaved. + +### Overlaid + +If want to use the base map as a backdrop, the recommended approach is to use the Deck canvas as a overlay on top of the Mapbox map using [MapboxOverlay](../../api-reference/mapbox/mapbox-overlay) in its default mode (overlaid, which corresponds to `interleaved: false`). The [react get-started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/react/mapbox/) and [pure js get-started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/mapbox/) illustrates this pattern. + +### Interleaved + +If you also need to mix deck.gl layers with base map layers, e.g. having deck.gl surfaces below text labels or objects occluding each other correctly in 3D, then you have to use deck.gl layers interleaved with Mapbox layers in the same WebGL2 context. In addition to using [MapboxOverlay](../../api-reference/mapbox/mapbox-overlay#using-with-react-map-gl) to insert Deck into the map container, you have to use interleaved mode (`interleaved: true`). Be cautious that this feature subjects to bugs and limitations of mapbox-gl's custom layer interface, and is only compatible with WebGL2 (See [interleaved renderer compatibility](../../api-reference/mapbox/overview#interleaved-renderer-compatibility)). The [pure js gallery example](https://github.com/visgl/deck.gl/blob/master/examples/gallery/src/mapbox-overlay.html) illustrates this pattern. + +## Inserting Mapbox into the deck.gl container + +```jsx +import DeckGL from '@deck.gl/react'; +import Map from 'react-map-gl'; + + + + +``` + +If you're using deck.gl in a React environment and just need a map backdrop, then you may use Deck as the root HTML element with its canvas as an overlay on top of the child Mapbox map. The [Minimap example](https://deck.gl/examples/multi-view) illustrates the basic pattern. This is a well tested and robust use case with respect to Deck's functionality, as you can find it in most of the [layer examples on this website](https://deck.gl/examples). You can't use all the features of mapbox-gl like controls (e.g. `NavigationControl`) and plugins, but you can instead use [@deck.gl/widgets](../../api-reference/widgets/overview). + +> Note: This usage is not supported in the Pure JS environment. ## react-map-gl [react-map-gl](https://github.com/visgl/react-map-gl) is a React wrapper around mapbox-gl. If you'd like to use deck.gl with React, this component is the recommended companion. -All the [examples on this website](https://github.com/visgl/deck.gl/tree/master/examples/website) are implemented using the React integration. The `DeckGL` React component works especially well as the parent of a react-map-gl [Map](https://visgl.github.io/react-map-gl/docs/api-reference/map), which automatically interprets the deck.gl view state (i.e. latitude, longitude, zoom etc). In this configuration your deck.gl layers will render as a perfectly synchronized geospatial overlay over the underlying map. +All the [examples on this website](https://github.com/visgl/deck.gl/tree/master/examples/website) are implemented using the React integration. + +When you choose the react-map-gl `Map` React component as the root component, using [MapboxOverlay](../../api-reference/mapbox/mapbox-overlay#using-with-react-map-gl) with react-map-gl `useControl` works especially well to insert perfectly synchronized deck.gl layers in the map container. -> `react-map-gl` v5 and v6 exports React controls (`NavigationControl`, `GeolocateControl` etc.) that can be used with `DeckGL` with or without a base map. See [ContextProvider](../../api-reference/react/deckgl.md#contextprovider) for an example. +When you choose the `DeckGL` React component as the root component, react-map-gl [Map](https://visgl.github.io/react-map-gl/docs/api-reference/map) as a child automatically interprets the deck.gl view state (i.e. latitude, longitude, zoom etc). In this configuration your deck.gl layers will still render as a synchronized geospatial overlay over the underlying map. -> To use deck.gl with `react-map-gl` v7's controls, you must use [MapboxOverlay](https://deck.gl/docs/api-reference/mapbox/mapbox-overlay#using-with-react-map-gl). +> Using `DeckGL` as the root component is not compatible with `react-map-gl` controls (`NavigationControl`, `GeolocateControl` etc.) because of `react-map-gl` decisions to prioritize its own maintainability, performance, and compatibility when used standalone. ## Using Mapbox basemap service (with Mapbox token) -The mapbox-gl library is open source and free to use. However, to load the map styles and tiles from Mapbox's data service, you will need to register on their website in order to retrieve an [access token](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/) required by the map component, which will be used to identify you and start serving up map tiles. The service will be free until a [certain level](https://www.mapbox.com/pricing/) of traffic is exceeded. +The mapbox-gl library is a popular commercial basemap with a free tier. To use Mapbox, you will need to register on their website in order to retrieve an [access token](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/) required by the map component, which will be used to identify you and start serving up map tiles. The service will be free until a [certain level](https://www.mapbox.com/pricing/) of traffic is exceeded. If you are using mapbox-gl without React, check out [Mapbox GL JS API](https://docs.mapbox.com/mapbox-gl-js/api/#accesstoken) for how to apply the token. @@ -34,17 +115,19 @@ If you are using react-map-gl, there are several ways to provide a token to your * Set the `MapboxAccessToken` environment variable. You may need to add additional set up to the bundler ([example](https://webpack.js.org/plugins/environment-plugin/)) so that `process.env.MapboxAccessToken` is accessible at runtime. * Provide it in the URL, e.g `?access_token=TOKEN` -* Pass it as a prop to the ReactMapGL instance `` +* Pass it as a prop to the react-map-gl `Map` instance `` ## Compatibility with Mapbox GL JS forks As of v2.0, Mapbox GL JS [went proprietary](https://github.com/mapbox/mapbox-gl-js/blob/main/CHANGELOG.md#200) and requires a Mapbox account to use even if you don't load tiles from the Mapbox data service. Community forks of the v1 code base such as [MapLibre GL JS](https://maplibre.org) can generally be used as a drop-in replacement of mapbox-gl. If you are using react-map-gl, see [their Get Started guide](http://visgl.github.io/react-map-gl/docs/get-started) for more details. +We provide get-started examples with Maplibre GL JS for [pure js](https://github.com/visgl/deck.gl/tree/master/examples/get-started/pure-js/maplibre/) and [react](https://github.com/visgl/deck.gl/tree/master/examples/get-started/react/maplibre/), and an interleaved rendering example in our [gallery](https://github.com/visgl/deck.gl/blob/master/examples/gallery/src/maplibre-overlay.html). + If the forked libraries and Mapbox API diverge in the future, compatibility issues may arise. deck.gl intends to support open source efforts wherever reasonable. Please report any issue on GitHub. ## Using with other basemap services -It is possible to use the map component without the Mapbox service, you need a URL that conforms to the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec) and pass it to `ReactMapGL` using the `mapStyle` prop. +It is possible to use the map component without the Mapbox service, you need a URL that conforms to the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec) and pass it to the `mapStyle` prop in mapbox-gl `Map` constructor or react-map-gl `Map` component. You can use existing free vector tile services: @@ -63,4 +146,4 @@ Some useful resources for creating your own map service: - [Mapbox Vector Tile Spec](https://www.mapbox.com/developers/vector-tiles/) - [Open source tools](https://github.com/mapbox/awesome-vector-tiles) -- [Maputnik Style editor](https://maputnik.github.io) \ No newline at end of file +- [Maputnik Style editor](https://maputnik.github.io) diff --git a/docs/get-started/using-with-map.md b/docs/get-started/using-with-map.md index 6446eb38bab..7cbdc8c4280 100644 --- a/docs/get-started/using-with-map.md +++ b/docs/get-started/using-with-map.md @@ -12,7 +12,9 @@ There are two types of integration between deck.gl and a base map renderer: ![Deck as overlay on top of the base map](https://miro.medium.com/max/1600/0*K3DVssEhnv5VaDCp) -- **Interleaved**: Deck renders into the WebGL2 context of the base map. This allows for occlusion between deck.gl layers and the base map's labels and/or 3D features. The availability of this option depends on whether the base map solution exposes certain developer APIs, and may subject the user to bugs/limitations associated with such APIs. +- **Interleaved**: Deck renders into the WebGL2 context of the base map. This allows for occlusion between deck.gl layers and the base map's labels and/or 3D features. The availability of this option depends on whether the base map solution exposes certain developer APIs, and may subject the user to bugs/limitations associated with such APIs. + +> Note: Deck cannot render into a WebGL1 context. Check your base map solution for WebGL2 compatibility. ![Deck interleaved with base map layers](https://miro.medium.com/max/1600/0*faYL1UbVD4af5qzy)