@yandex/ymaps3-entity-tile-loader package
Yandex JS API package loading data by tiles.
Allows you to load and display on the map only those objects that are included in the tile areas
displayed on the map.
The data is loaded tile-by-tile, so you don't have to load all the data at once.
How use
The package is located in the dist
folder:
dist/types
TypeScript typesdist/esm
es6 modules for direct connection in your projectdist/index.js
Yandex JS Module
to use Yandex JS Module you need to add your module loading handler to JS API
Recommended use YMapEntityTileLoader
as usual npm package:
npm i @yandex/ymaps3-entity-tile-loader
and dynamic import
const {YMapEntityTileLoader} = await import('@yandex/ymaps3-entity-tile-loader/dist/esm/index');
But you can use CDN:
Development
ymaps3.import.loaders.unshift(async (pkg) => {
if (!pkg.startsWith('@yandex/ymaps3-entity-tile-loader')) {
return;
}
await ymaps3.import.script(`./node_modules/@yandex/ymaps3-entity-tile-loader/dist/index.js`);
return window[`${pkg}`];
});
Production
ymaps3.import.loaders.unshift(async (pkg) => {
if (!pkg.includes('@yandex/ymaps3-entity-tile-loader')) {
return;
}
await ymaps3.import.script(`https://unpkg.com/${pkg}/dist/index.js`);
return window[`${pkg}`];
});
and in your final code just use ymaps3.import
const {YMapFeature, YMapDefaultFeaturesLayer} = ymaps3;
const {YMapEntityTileLoader} = await ymaps3.import('@yandex/ymaps3-entity-tile-loader@1.0.0');
map.addChild(new YMapDefaultFeaturesLayer());
map.addChild(
new YMapEntityTileLoader({
removalDelay: 500,
tileSize: 256,
getFeatureId: (feature) => feature.id,
fetchTile: ({tx, ty, tz, sginal}) => {
return fetch(`https://geodata.example/${tx}/${ty}/${tz}`, {signal}).then((r) => r.json());
},
entity: (feature) =>
new YMapFeature({id: feature.id.toString(), geometry: feature.geometry, properties: feature.properties}),
onFeatureAdd: (feature) => {
console.log(feature);
},
onFeatureRemove: (feature) => {
console.log(feature);
}
})
);
API
Constructor parameters YMapEntityTileLoader
:
import type {GenericFeature, LngLat, YMapEntity} from '@yandex/ymaps3-types';
export type GeojsonFeature = GenericFeature<LngLat>;
export interface YMapEntityTileLoaderProps {
readonly tileSize: number;
fetchTile: (args: {tx: number; ty: number; tz: number; signal: AbortSignal}) => Promise<GeojsonFeature[]>;
getFeatureId: (feature: GeojsonFeature) => string;
entity: (feature: GeojsonFeature) => YMapEntity<unknown>;
onFeatureAdd: (feature: GeojsonFeature) => void | false;
onFeatureRemove: (feature: GeojsonFeature) => void | false;
removalDelay?: number;
}
And a React version:
const BOUNDS = [
[53.20890963521473, 25.52765018907181],
[57.444403818421854, 24.71096299361919]
];
const LOCATION = {bounds: BOUNDS};
const [ymaps3React] = await Promise.all([ymaps3.import('@yandex/ymaps3-reactify'), ymaps3.ready]);
const reactify = ymaps3React.reactify.bindTo(React, ReactDOM);
const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapControlButton, YMapControls, YMapFeature} =
reactify.module(ymaps3);
const {useState, useCallback} = React;
const {YMapZoomControl} = reactify.module(await ymaps3.import('@yandex/ymaps3-controls@0.0.1'));
const {YMapEntityTileLoader} = reactify.module(await ymaps3.import('@yandex/ymaps3-entity-tile-loader'));
function App() {
return (
<YMap location={LOCATION} ref={(x) => (map = x)}>
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
<YMapControls position="right">
<YMapZoomControl />
</YMapControls>
<YMapControls position="top">
<YMapControlButton text={`urban area in loaded tiles: ${total.toFixed(2)} km2`} />
</YMapControls>
<YMapEntityTileLoader
renderDelay={100}
tileSize={TILE_SIZE}
getFeatureId={useCallback((feature) => feature.id, [])}
fetchTile={fetchTile}
entity={useCallback(
(feature) => (
<YMapFeature id={feature.id.toString()} geometry={feature.geometry} properties={feature.properties} />
),
[]
)}
onFeatureAdd={useCallback((entity) => {
setTotal((total) => total + entity.properties.area_sqkm);
}, [])}
onFeatureRemove={useCallback((entity) => {
setTotal((total) => total - entity.properties.area_sqkm);
}, [])}
/>
</YMap>
);
}
For react version, you can use renderDelay
parameter, because react will call render
function for each feature.
To avoid unnecessary calls, you can set the delay for applying the changes.