Клуб API Карт

Как выделить область кольцевой автодороги (КАД)?

Пост в архиве.

Добрый вечер, уважаемые участники!

 

Собственно мой вопрос. Есть задача реализовать стоимость расчета доставки товара клиенту из пункта А (адрес компании) до пункта Б (местонахождение клиента). Алгоритм расчета следующий:

 

ЕСЛИ клиент находится на расстоянии меньше 30 км от местонахождения конторы, ТО 1 км доставки стоит 20 руб.; ЕСЛИ расстояние от компании до клиента превышает 30 км, ТО 1 км становится равным 30 руб. И (в то же время) ЕСЛИ клиент находится в пределах КАД (СПБ), ТО доставка должна быть для него 0 руб. ЕСЛИ он за пределами кольца, ТО рассчитываем стоимость по вышенаписанному (<= 30 км - 20 руб./км; > 30 км - 30 руб./км.)


Как мне этого добиться? Собственно нужно как-то выделить на карте область КАД и уже исходить из этой области, т.е. как-то ее обозначить (захватить по периметру). Но с помощью чего это сделать я не знаю. Буду рад любой помощи.


Привожу код (взял с саппорта), который считает расстояние стоимость при < 30 км, я сделал, что она равна нулю (параметр MINIMUM_COST) и > 30 км рассчитываем по тому же принципу но только с помощью функции Math.max

return Math.max(len * DELIVERY_TARIF_OUTSIDE_KAD, MINIMUM_COST);

 

 

<!DOCTYPE html>

<html>

<head>

    <title>Расчет стоимости доставки</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"></script>

 

<script type="text/javascript">

 

function init() {

    var myMap = new ymaps.Map('Dostavka', {

            center: [59.923367, 30.392303],

            zoom: 12,

            type: 'yandex#map',

            behaviors: ['scrollZoom', 'drag']

        }),

        search = new ymaps.control.SearchControl({

            useMapBounds: true,

            noCentering: true,

            noPlacemark: true

        }),

        calculator = new DeliveryCalculator(myMap, myMap.getCenter());

 

    myMap.controls.add(search, { right: 5, top: 5 });

 

    search.events.add('resultselect', function (e) {

        var results = search.getResultsArray(),

            selected = e.get('resultIndex'),

            point = results[selected].geometry.getCoordinates();

 

        calculator.setStartPoint(point);

    });

}

 

function DeliveryCalculator(map, finish) {

    this._map = map;

    this._start = null;

    this._finish = new ymaps.Placemark(finish, { iconContent: 'ДГ' });

    this._route = null;

 

    map.events.add('click', this._onStartPointChange, this);

    map.geoObjects.add(this._finish);

}

 

var ptp = DeliveryCalculator.prototype;

 

ptp._onStartPointChange = function (e) {

    this.setStartPoint(e.get('coordPosition'));

};

 

ptp.getDirections = function () {

    var self = this,

        start = this._start.geometry.getCoordinates(),

        finish = this._finish.geometry.getCoordinates();

 

    if(this._route) {

        this._map.geoObjects.remove(this._route);

    }

 

    ymaps.geocode(start, { results: 1 })

        .then(function (geocode) {

            var address = geocode.geoObjects.get(0) &&

                geocode.geoObjects.get(0).properties.get('balloonContentBody') || '';

 

            ymaps.route([start, finish])

                .then(function (router) {

                    var distance = Math.round(router.getLength() / 1000),

                        message = '<span>Расстояние: ' + distance + 'км.</span><br/>' +

                            '<span style="font-weight: bold; font-style: italic">Стоимость доставки: %sр.</span>';

 

                    self._route = router.getPaths();

                    self._route.options.set({ strokeWidth: 5, strokeColor: '0000ffff', opacity: 0.5 });

                    self._map.geoObjects.add(self._route);

                    self._start.properties.set('balloonContentBody', address + message.replace('%s', self.calculate(distance)));

                    self._start.balloon.open();

                });

        });

};

 

ptp.setStartPoint = function (position) {

    if(this._start) {

        this._start.geometry.setCoordinates(position);

    }

    else {

        this._start = new ymaps.Placemark(position, { iconContent: 'Я' }, { draggable: true });

        this._start.events.add('dragend', this._onStartPointChange, this);

        this._map.geoObjects.add(this._start);

    }

    this.getDirections();

};

 

ptp.calculate = function (len) {

    // Константы.

    var DELIVERY_TARIF_INSIDE_KAD = 20,

DELIVERY_TARIF_OUTSIDE_KAD = 30,

        MINIMUM_COST = 0;

 

   if(len<=30) return Math.min(len * DELIVERY_TARIF_INSIDE_KAD, MINIMUM_COST);

if(len>30) return Math.max(len * DELIVERY_TARIF_OUTSIDE_KAD, MINIMUM_COST);

};

 

ymaps.ready(init);

 

</script>

</head>

<body>

    <div id="Dostavka" style="width: 800px; height: 600px"></div>

</body>

</html>

 

15 комментариев

Этот пример я писал давным-давно.

Есть более новый вариант с тарификацией по зонам.

Отрисовка зон делается просто, - добавляете полигон на карту и включаете режим редактирования, затем накликиваете нужное кол-во точек по периметру зоны, и завершаете редактирование.

Геометрию можно получить вызвав myPolygon.geometry.getCoordinates()

 

Если все это очень сложно, можно все зоны обрисовать на maps.yandex.ru и экспортировать в YMapsML, затем из него вытащить геометрию.

К сожалению я в этом практически полный профан :(

Я извиняюсь, но не могли бы вы поподробнее описать, как выделить область питерской КАД на примере моего кода, того который я взял с сапорта? У меня почему-то даже некоторые коды с сапорта не работают, например, вот этот

http://api.yandex.ru/maps/jsbox/route_inside_polygon

Просто копирую код, в ссылки http: дописываю, все равно не хочет работать через Macromedia DreamWeaver...

 

Но можно хотя бы как определить границы КАД (не обязательно визуально), на примере моего кода? Буду признателен за полезный ответ.

 

Если все это очень сложно, можно все зоны обрисовать на maps.yandex.ru и экспортировать в YMapsML, затем из него вытащить геометрию.

Ваша задача скажем так не самая простая ее без знаний в программировании решить не получится

Я понимаю, раньше немного упражнялся с javascrip, теперь жезабыл его почти полностью...

затем из него вытащить геометрию

 - это опять же с помощью myPolygon.geometry.getCoordinates() делается?

да

YMapsML-экспорт вернет вам коллекцию, в которой будет лежать ваш полигон

Хорошо, спасибо!

 

А почему вот этот ваш пример у меня не работает?

view-source:http://dimik.github.io/ymaps/examples/delivery-calculator/

У меня работает.

Что пишет в консоли?

Я через Dreamweaver делаю. Просто ваш код скопировал, он показывает обычную карту, но никаких отметок на ней нет и ничего отмеить не получается...

Там много файлов. Вы наверное скопировали только код страницы.

Спасибо. Это я конечно здорово облажался. :-D

 

А как мне такие координаты в mo.json и moscow.json получить, только для питера?

Вы можете сделать это на maps.yandex.ru

Вот я карту нарисовал - отметил там КАД

http://n.maps.yandex.ru/?oid=42591858

 

Из нее можно как-то координаты КАД вытащить?

можно только с той что на maps.yande.ru

из народной нет.

Вот ссылка на YMapsML

http://maps.yandex.ru/export/usermaps/Rk1-FvmkZxFHDtsRqIcaRXNcSojZCIda/

но где взять массив координат...

да,я взял с обычной карты.

 

странно, все 8 файлов взял, пробую - все равно не работает, не считает маршрут :(