Ограничение области просмотра карты
vanilla.html
react.html
vue.html
common.ts
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
import {
BIG_RESTRICT_AREA,
LITTLE_RESTRICT_AREA,
BIG_ZOOM_RANGE,
LITTLE_ZOOM_RANGE,
boundsToPolygonCoordinates
} from './common';
window.map = null;
main();
async function main() {
// Waiting for all api elements to be loaded
await ymaps3.ready;
const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapFeature, YMapControls, YMapControlButton} =
ymaps3;
// Initialize the map
map = new YMap(
// Pass the link to the HTMLElement of the container
document.getElementById('app'),
// Pass the map initialization parameters, set the map location bounds with the current restricted area
{
location: {bounds: LITTLE_RESTRICT_AREA},
restrictMapArea: LITTLE_RESTRICT_AREA,
zoomRange: LITTLE_ZOOM_RANGE
},
// Add a map schema layer and a geo objects layer
[new YMapDefaultSchemeLayer({}), new YMapDefaultFeaturesLayer({})]
);
// Create and add a polygon to the map that will mark the border of the map restrict area
const borderPolygon = new YMapFeature({
id: 'polygon',
geometry: {
type: 'Polygon',
coordinates: [boundsToPolygonCoordinates(LITTLE_RESTRICT_AREA)]
},
style: {
stroke: [{width: 12, color: '#007afce6'}],
fill: 'rgba(0, 0, 0, 0)'
}
});
map.addChild(borderPolygon);
// Add a container for YMapControlButton and add it to the map
const controls = new YMapControls({position: 'bottom'});
map.addChild(controls);
// Flag to increase/decrease the restricted area on the map
let isBigRestrictArea = false;
function changeViewFieldBtnHandler() {
isBigRestrictArea = !isBigRestrictArea;
// The selection of the restricted area and other map parameters depends on the flag's value
const currentRestrictArea = isBigRestrictArea ? BIG_RESTRICT_AREA : LITTLE_RESTRICT_AREA;
const currentZoomRange = isBigRestrictArea ? BIG_ZOOM_RANGE : LITTLE_ZOOM_RANGE;
const currentBtnText = isBigRestrictArea ? 'Decrease The Field Of View' : 'Increase The Field Of View';
// Update the map with the current restricted area and zoom range
map.update({
restrictMapArea: currentRestrictArea,
zoomRange: currentZoomRange
});
// Update the map location bounds with the current restricted area
map.update({location: {bounds: currentRestrictArea}});
// Update the border polygon coordinates depending on the current restricted area
borderPolygon.update({
geometry: {
type: 'Polygon',
coordinates: [boundsToPolygonCoordinates(currentRestrictArea)]
}
});
changeViewFieldBtn.update({text: currentBtnText});
}
// Add YMapControlButton that changes the restricted area
const changeViewFieldBtn = new YMapControlButton({
text: 'Increase The Field Of View',
color: '#fff',
background: '#007afce6',
onClick: changeViewFieldBtnHandler
});
controls.addChild(changeViewFieldBtn);
}
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/react-dom@17/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="react, typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="react, typescript" type="text/babel">
import {
BIG_RESTRICT_AREA,
LITTLE_RESTRICT_AREA,
BIG_ZOOM_RANGE,
LITTLE_ZOOM_RANGE,
boundsToPolygonCoordinates
} from './common';
window.map = null;
main();
async function main() {
// For each object in the JS API, there is a React counterpart
// To use the React version of the API, include the module @yandex/ymaps3-reactify
const [ymaps3React] = await Promise.all([ymaps3.import('@yandex/ymaps3-reactify'), ymaps3.ready]);
const reactify = ymaps3React.reactify.bindTo(React, ReactDOM);
const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapFeature, YMapControls, YMapControlButton} =
reactify.module(ymaps3);
const {useState, useCallback} = React;
function App() {
// Flag to increase/decrease the restricted area on the map
const [isBigRestrictArea, setIsBigRestrictArea] = useState(false);
// Define states for map parameters
const [restrictArea, setRestrictArea] = useState(LITTLE_RESTRICT_AREA);
const [zoomRange, setZoomRange] = useState(LITTLE_ZOOM_RANGE);
const [btnText, setBtnText] = useState('Increase The Field Of View');
const changeViewFieldBtnHandler = useCallback(() => {
const syncIsBigRestrictArea = !isBigRestrictArea;
setIsBigRestrictArea((prevState) => !prevState);
// The selection of the restricted area and other map parameters depends on the flag's value
const currentRestrictArea = syncIsBigRestrictArea ? BIG_RESTRICT_AREA : LITTLE_RESTRICT_AREA;
const currentZoomRange = syncIsBigRestrictArea ? BIG_ZOOM_RANGE : LITTLE_ZOOM_RANGE;
const currentBtnText = syncIsBigRestrictArea ? 'Reduce The Field Of View' : 'Increase The Field Of View';
// Update the map states with the current restricted area
setRestrictArea(currentRestrictArea);
setZoomRange(currentZoomRange);
setBtnText(currentBtnText);
}, [isBigRestrictArea]);
return (
// Initialize the map and pass initialization parameters, set the map location bounds with the current restricted area
<YMap
location={{bounds: restrictArea}}
restrictMapArea={restrictArea}
zoomRange={zoomRange}
ref={(x) => (map = x)}
>
{/* Add a map schema layer and a geo objects layer */}
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
{/* Add a polygon to the map that will mark the border of the map restrict area */}
<YMapFeature
geometry={{
type: 'Polygon',
coordinates: [boundsToPolygonCoordinates(restrictArea)]
}}
style={{
stroke: [{width: 12, color: '#007afce6'}],
fill: 'rgba(0, 0, 0, 0)'
}}
/>
{/* Add YMapControlButton that changes the restricted area */}
<YMapControls position="bottom">
<YMapControlButton
text={btnText}
color="#fff"
background="#007afce6"
onClick={changeViewFieldBtnHandler}
/>
</YMapControls>
</YMap>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('app')
);
}
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
import {
BIG_RESTRICT_AREA,
LITTLE_RESTRICT_AREA,
BIG_ZOOM_RANGE,
LITTLE_ZOOM_RANGE,
boundsToPolygonCoordinates
} from './common';
window.map = null;
async function main() {
// For each object in the JS API, there is a Vue counterpart
// To use the Vue version of the API, include the module @yandex/ymaps3-vuefy
const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]);
const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapFeature, YMapControls, YMapControlButton} =
vuefy.module(ymaps3);
const App = Vue.createApp({
components: {
YMap,
YMapDefaultSchemeLayer,
YMapDefaultFeaturesLayer,
YMapFeature,
YMapControls,
YMapControlButton
},
setup() {
const isBigRestrictArea = Vue.ref(false);
const restrictArea = Vue.computed(() =>
isBigRestrictArea.value ? BIG_RESTRICT_AREA : LITTLE_RESTRICT_AREA
);
const zoomRange = Vue.computed(() => (isBigRestrictArea.value ? BIG_ZOOM_RANGE : LITTLE_ZOOM_RANGE));
const btnText = Vue.computed(() =>
isBigRestrictArea.value ? 'Reduce The Field Of View' : 'Increase The Field Of View'
);
const refMap = (ref) => {
window.map = ref?.entity;
};
const changeViewFieldBtnHandler = () => {
isBigRestrictArea.value = !isBigRestrictArea.value;
};
return {
refMap,
restrictArea,
zoomRange,
btnText,
changeViewFieldBtnHandler,
boundsToPolygonCoordinates
};
},
template: `
<YMap
:location="{ bounds: restrictArea }"
:restrictMapArea="restrictArea"
:zoomRange="zoomRange"
:ref="refMap"
>
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
<YMapFeature
:geometry="{
type: 'Polygon',
coordinates: boundsToPolygonCoordinates(restrictArea)
}"
:style="{
stroke: [{ width: 12, color: '#007afce6' }],
fill: 'rgba(0, 0, 0, 0)'
}"
/>
<YMapControls position="bottom">
<YMapControlButton
:text="btnText"
color="#fff"
background="#007afce6"
@click="changeViewFieldBtnHandler"
/>
</YMapControls>
</YMap>
`
});
App.mount('#app');
}
main();
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
import type {ZoomRange, LngLatBounds, LngLat} from '@yandex/ymaps3-types';
export const LITTLE_ZOOM_RANGE: ZoomRange = {min: 14, max: 20};
export const BIG_ZOOM_RANGE: ZoomRange = {min: 7, max: 14};
// Bounding box - bottom left and top right corners
export const LITTLE_RESTRICT_AREA: LngLatBounds = [
[37.523, 55.702],
[37.723, 55.802]
];
export const BIG_RESTRICT_AREA: LngLatBounds = [
[26.298, 47.019],
[48.28, 64.453]
];
// From the coordinates of bottom left and top right corners, we make 4 coordinates of the rectangle
export function boundsToPolygonCoordinates(bounds: LngLatBounds): LngLat[] {
return [bounds[0], [bounds[1][0], bounds[0][1]], bounds[1], [bounds[0][0], bounds[1][1]]];
}