Создание линии

Open in CodeSandbox

<!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/@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="../variables.ts"
    ></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 {InfoMessage} from './common';
      import {LINESTRING, LOCATION} from '../variables';

      window.map = null;

      main();
      async function main() {
        // Waiting for all api elements to be loaded
        await ymaps3.ready;
        const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapFeature, YMapControls} = ymaps3;

        // Initialize the map
        map = new YMap(
          // Pass the link to the HTMLElement of the container
          document.getElementById('app'),
          // Pass the map initialization parameters
          {location: LOCATION, showScaleInCopyrights: true},
          [
            // Add a map scheme layer
            new YMapDefaultSchemeLayer({}),
            // Add a layer of geo objects to display the line
            new YMapDefaultFeaturesLayer({})
          ]
        );

        // Create a line object, set its coordinates and styles, and add it to the map
        const line = new YMapFeature({
          geometry: {
            type: 'LineString',
            coordinates: LINESTRING.coordinates
          },
          style: {stroke: [{color: LINESTRING.color, width: 4}]}
        });
        map.addChild(line);

        /* Create and add a shared container for controls to the map.
Using YMapControls you can change the position of the control */
        const topRightControls = new YMapControls({position: 'top left'});
        map.addChild(topRightControls);

        // Add a custom information message control to the map
        topRightControls.addChild(new InfoMessage({text: LINESTRING.tooltipText}));
      }
    </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>
    <link rel="stylesheet" href="./common.css" />
  </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="typescript"
      type="text/babel"
      src="../variables.ts"
    ></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="react, typescript" type="text/babel">
      import {InfoMessage} from './common';
      import {LINESTRING, LOCATION} from '../variables';

      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} =
          reactify.module(ymaps3);

        // Using ymaps3-rectify, we turn a custom InfoMessage into a React component
        const {InfoMessage: InfoMessageR} = reactify.module({InfoMessage});

        function App() {
          return (
            // Initialize the map and pass initialization parameters
            <YMap location={LOCATION} showScaleInCopyrights={true} ref={(x) => (map = x)}>
              {/* Add a map scheme layer */}
              <YMapDefaultSchemeLayer />
              {/* Add a layer of geo objects to display the line */}
              <YMapDefaultFeaturesLayer />

              {/* Add a line object to the map, set its coordinates and styles */}
              <YMapFeature
                geometry={{
                  type: 'LineString',
                  coordinates: LINESTRING.coordinates
                }}
                style={{stroke: [{color: LINESTRING.color, width: 4}]}}
              />

              {/* Add a shared container for controls to the map.
                Using YMapControls you can change the position of the control */}
              <YMapControls position="top left">
                {/* Add a custom information message control to the map */}
                <InfoMessageR text={LINESTRING.tooltipText} />
              </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>
    <link rel="stylesheet" href="./common.css" />
  </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="../variables.ts"
    ></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 {InfoMessage} from './common';
      import {LINESTRING, LOCATION} from '../variables';

      window.map = null;

      async function main() {
        const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]);
        const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
        const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapFeature, YMapControls} =
          vuefy.module(ymaps3);

        const {InfoMessage: InfoMessageV} = vuefy.module({InfoMessage});

        const App = Vue.createApp({
          components: {
            YMap,
            YMapDefaultSchemeLayer,
            YMapDefaultFeaturesLayer,
            YMapFeature,
            YMapControls,
            InfoMessageV
          },
          setup() {
            const refMap = (ref) => {
              window.map = ref?.entity;
            };

            return {
              refMap,
              LOCATION,
              LINESTRING
            };
          },
          template: `
      <YMap
        :location="LOCATION"
        :ref="refMap"
        :showScaleInCopyrights="true"
      >
        <YMapDefaultSchemeLayer />
        <YMapDefaultFeaturesLayer />
        
        <YMapFeature
          :geometry="{
            type: 'LineString',
            coordinates: LINESTRING.coordinates
          }"
          :style="{ stroke: [{ color: LINESTRING.color, width: 4 }] }"
        />
        
        <YMapControls position="top left">
          <InfoMessageV :text="LINESTRING.tooltipText" />
        </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>
    <link rel="stylesheet" href="./common.css" />
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
.info_window {
  padding: 8px 12px 8px 40px;
  border-radius: 12px;
  background-color: #313133;
  background-image: url('./info-icon.svg');
  background-position: 10px 8px;
  background-repeat: no-repeat;
  color: #f2f5fa;
  font-size: 14px;
  line-height: 20px;
  min-width: max-content;
}
// Create a custom information message control
export let InfoMessage = null;

interface InfoMessageProps {
  text: string;
}

// Wait for the api to load to access the entity system (YMapComplexEntity)
ymaps3.ready.then(() => {
  class InfoMessageClass extends ymaps3.YMapComplexEntity<InfoMessageProps> {
    private _element!: HTMLDivElement;
    private _detachDom!: () => void;

    // Method for create a DOM control element
    _createElement(props: InfoMessageProps) {
      // Create a root element
      const infoWindow = document.createElement('div');
      infoWindow.classList.add('info_window');
      infoWindow.innerHTML = props.text;

      return infoWindow;
    }

    // Method for attaching the control to the map
    _onAttach() {
      this._element = this._createElement(this._props);
      this._detachDom = ymaps3.useDomContext(this, this._element, this._element);
    }

    // Method for detaching control from the map
    _onDetach() {
      this._detachDom();
      this._detachDom = undefined;
      this._element = undefined;
    }
  }

  InfoMessage = InfoMessageClass;
});
import type {LngLat, YMapLocationRequest} from '@yandex/ymaps3-types';

export const LOCATION: YMapLocationRequest = {
  center: [39.9579, 43.4075], // starting position [lng, lat]
  zoom: 14 // starting zoom
};

export const LINESTRING: {
  color: string;
  tooltipText: string;
  coordinates: LngLat[];
} = {
  color: '#007afce6',
  tooltipText: 'Расположение:<br>Сочи Автодром, Адлер',
  coordinates: [
    [39.968066, 43.409699],
    [39.966723, 43.408191],
    [39.966421, 43.407965],
    [39.966007, 43.407734],
    [39.965551, 43.407555],
    [39.9649, 43.407408],
    [39.963177, 43.407074],
    [39.96062, 43.406574],
    [39.957886, 43.406046],
    [39.957708, 43.40606],
    [39.957643, 43.406098],
    [39.957602, 43.406221],
    [39.957531, 43.406395],
    [39.957418, 43.406522],
    [39.956181, 43.407399],
    [39.955737, 43.407635],
    [39.955187, 43.407795],
    [39.954524, 43.407837],
    [39.953879, 43.407743],
    [39.953334, 43.407536],
    [39.952908, 43.407248],
    [39.952648, 43.406965],
    [39.95244, 43.406621],
    [39.952363, 43.406249],
    [39.952399, 43.405834],
    [39.952547, 43.405481],
    [39.953316, 43.404321],
    [39.953334, 43.404189],
    [39.953263, 43.404085],
    [39.953086, 43.403991],
    [39.948996, 43.402223],
    [39.948871, 43.402186],
    [39.948676, 43.402181],
    [39.948534, 43.402242],
    [39.948439, 43.402332],
    [39.947427, 43.403977],
    [39.947332, 43.404255],
    [39.947309, 43.404481],
    [39.947338, 43.404731],
    [39.947599, 43.405688],
    [39.947646, 43.405768],
    [39.947747, 43.405806],
    [39.947877, 43.405834],
    [39.951209, 43.406197],
    [39.951292, 43.406221],
    [39.951369, 43.406268],
    [39.951428, 43.406329],
    [39.951635, 43.406928],
    [39.951653, 43.407017],
    [39.951665, 43.40713],
    [39.951647, 43.407229],
    [39.950612, 43.409346],
    [39.950612, 43.409431],
    [39.950653, 43.409506],
    [39.95073, 43.409581],
    [39.950842, 43.409638],
    [39.951884, 43.409944],
    [39.952363, 43.410025],
    [39.952813, 43.410086],
    [39.953429, 43.410119],
    [39.953973, 43.410114],
    [39.954595, 43.410067],
    [39.955181, 43.409987],
    [39.956211, 43.409864],
    [39.956761, 43.409761],
    [39.957324, 43.409614],
    [39.957933, 43.409435],
    [39.960028, 43.408742],
    [39.960603, 43.408596],
    [39.961123, 43.408516],
    [39.961703, 43.408478],
    [39.962301, 43.408497],
    [39.962858, 43.408573],
    [39.96371, 43.408752],
    [39.96387, 43.408724],
    [39.963935, 43.408648],
    [39.964201, 43.407988],
    [39.964326, 43.407894],
    [39.964539, 43.407837],
    [39.964769, 43.407847],
    [39.965101, 43.407903],
    [39.965474, 43.40804],
    [39.965805, 43.408257],
    [39.966078, 43.408535],
    [39.966681, 43.409167],
    [39.966711, 43.409242],
    [39.966699, 43.409303],
    [39.966587, 43.409369],
    [39.966036, 43.409666],
    [39.965935, 43.40977],
    [39.9659, 43.409916],
    [39.965965, 43.410048],
    [39.966841, 43.411033],
    [39.967622, 43.411962],
    [39.96825, 43.412664],
    [39.968392, 43.41273],
    [39.968569, 43.412693],
    [39.969972, 43.41224],
    [39.970102, 43.412183],
    [39.97015, 43.412099],
    [39.970114, 43.412004],
    [39.968066, 43.409699]
  ]
};