Определение ближайшего склада по адресу (в 7.X через Google API)

По просьбам трудящихся выкладываю информацию о том, как можно получать координаты объектов по адресу через Google API. Задача имеет место быть, когда необходимо определить ближайший к клиенту склад. У нас это задача возникла в проекте по автоматизации интернет-магазина.

Механизм состоит из 2х блоков:

  1. Определение координат по адресу склада
  2. Определение координат адреса доставки и определение ближайших складов

Определение координат по адресу склада

При создании и изменении склада необходимо сразу определять координаты по адресу, выглядит это так:

Непосредственно код работ с Google API:

string address = Page.AddressEdit.Text.Trim();
MessagePanel messagePanel = ControlUtilities.FindControl(Page.AspPage.Controls[0], "BaseMessagePanel", true) as MessagePanel;
if (address != "")
{
        GeoPoint p = GeoCodeHelper.ParseAddress(address);
        /*if (messagePanel != null)
        {
                messagePanel.AddMessage(Warning, "Найдено совпадений: " + p.Length, MessageType.Warning);
        }*/

        Page.LatEdit.Value = Convert.ToDecimal(p.Lat);
        Page.LngEdit.Value = Convert.ToDecimal(p.Lng);
}
return true;

Естественно, обрабатываются следующие ситуации (в этом случае появляется стандартное предупреждение):

  • Не найден адрес
  • Найдено более одного адреса (например "улица Ленина, 1" без указания города)

Определение координат адреса доставки и определение ближайших складов

Когда добавляется или изменяется контрагент (а точнее адрес с типом "Доставка" на детали адресов), то выполняется определение ближайшего склада:

Код аналогичен:

GeoPoint p = GeoCodeHelper.ParseAddress(address);
var centersESQ = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "DistributingCenter");
centersESQ.AddAllSchemaColumns();
var centers = centersESQ.GetEntityCollection(UserConnection);
var count = centers.Count;
if (count == 0) {
        return true;
}
var points = new GeoPoint[count];
GeoPoint defaultCenter = null;
for (int i = 0; i < count; i++) {
        points[i] = new GeoPoint {
                Id = centers[i].GetTypedColumnValue<Guid>("Id"),
                Lat = (double)centers[i].GetTypedColumnValue<decimal>("Lat"),
                Lng = (double)centers[i].GetTypedColumnValue<decimal>("Lng"),
                R = (int)(1000 * centers[i].GetTypedColumnValue<decimal>("Radius"))
        };
        string name = centers[i].GetTypedColumnValue<string>("Name");
        if (DefaultName.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                defaultCenter = points[i];
}

points = GeoCodeHelper.FilterPointsByRadius(points, p);
var distrCenters = new List<GeoPoint>();
if (points != null) {
        var pathes = GeoCodeHelper.GetPaths(points, p);
        if (pathes != null) {
                for (int i = 0; i < pathes.Length; i++) {
                        if (i >= MaxCenters)
                                break;
                        distrCenters.Add(pathes[i].origin);
                }
        }
}

if (distrCenters.Count == 0 && defaultCenter != null) {
        distrCenters.Add(defaultCenter);
}

Тут нужно учесть такие моменты:

  1. Выводим три ближайшие склада
  2. У каждого склада есть радиус охвата, поэтому даже если он ближайший, не факт что оттуда вообще можно доставить товар. Например в Большую Черниговку (Самарская область) товар должен доставляться не с ближайшего склада в Уральске (Казахстан, граница с Самарской областью), а из Самары
  3. Адрес доставки может попасть в мертвую зону, куда не выполняется доставка

Вложил файлом объектную модель взаимодействия с Google API.

Нравится

Поделиться

0 комментариев
Показать все комментарии