Определение ближайшего склада по адресу (в 7.X через Google API)
По просьбам трудящихся выкладываю информацию о том, как можно получать координаты объектов по адресу через Google API. Задача имеет место быть, когда необходимо определить ближайший к клиенту склад. У нас это задача возникла в проекте по автоматизации интернет-магазина.
Механизм состоит из 2х блоков:
- Определение координат по адресу склада
- Определение координат адреса доставки и определение ближайших складов
Определение координат по адресу склада
При создании и изменении склада необходимо сразу определять координаты по адресу, выглядит это так:
Непосредственно код работ с Google API:
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" без указания города)
Определение координат адреса доставки и определение ближайших складов
Когда добавляется или изменяется контрагент (а точнее адрес с типом "Доставка" на детали адресов), то выполняется определение ближайшего склада:
Код аналогичен:
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].GetTypedColumnValueGuid>("Id"),
Lat = (double)centers[i].GetTypedColumnValuedecimal>("Lat"),
Lng = (double)centers[i].GetTypedColumnValuedecimal>("Lng"),
R = (int)(1000 * centers[i].GetTypedColumnValuedecimal>("Radius"))
};
string name = centers[i].GetTypedColumnValuestring>("Name");
if (DefaultName.Equals(name, StringComparison.InvariantCultureIgnoreCase))
defaultCenter = points[i];
}
points = GeoCodeHelper.FilterPointsByRadius(points, p);
var distrCenters = new ListGeoPoint>();
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);
}
Тут нужно учесть такие моменты:
- Выводим три ближайшие склада
- У каждого склада есть радиус охвата, поэтому даже если он ближайший, не факт что оттуда вообще можно доставить товар. Например в Большую Черниговку (Самарская область) товар должен доставляться не с ближайшего склада в Уральске (Казахстан, граница с Самарской областью), а из Самары
- Адрес доставки может попасть в мертвую зону, куда не выполняется доставка
Вложил файлом объектную модель взаимодействия с Google API.