[Решено] Геокодирование и запись в базу
Назрел вопрос, по поводу геокидирования яндекс карт.
Есть проект в котором в ресурсах есть яндекс карта (mapex).
Логика такая: в ресурсе указывается адрес, он находится и ставится метка, после чего через модифицированный pdoField вытаскивается pagetitle, introtext, uri и координаты из mapex. На странице с картой выводятся все ресурсы с наличием координат, добавляются в группы и кластеризуются.
Проблема
В день api позволяет создать 25000 запросов, т.е. каждый человек зашедший на сайт геокодирует координаты всех ресурсов (в данный момент около 100), т.е. при посещении 250 человек — карта ляжет.
Необходимо как-то записывать в базу координаты (адрес должен переводится в координаты и постится в базу, привязываться к id ресурса, желательно несколько адресов), после чего их вытаскивать из базы.
Есть у кого идеи? Искал решения на php для геокодирования адреса, но толком ничего не нашел.
Могу выложить рабочий пример своей реализации если кому интересно.
У яндекса есть ответ геокодера:
Есть проект в котором в ресурсах есть яндекс карта (mapex).
Логика такая: в ресурсе указывается адрес, он находится и ставится метка, после чего через модифицированный pdoField вытаскивается pagetitle, introtext, uri и координаты из mapex. На странице с картой выводятся все ресурсы с наличием координат, добавляются в группы и кластеризуются.
Проблема
В день api позволяет создать 25000 запросов, т.е. каждый человек зашедший на сайт геокодирует координаты всех ресурсов (в данный момент около 100), т.е. при посещении 250 человек — карта ляжет.
Необходимо как-то записывать в базу координаты (адрес должен переводится в координаты и постится в базу, привязываться к id ресурса, желательно несколько адресов), после чего их вытаскивать из базы.
Есть у кого идеи? Искал решения на php для геокодирования адреса, но толком ничего не нашел.
Могу выложить рабочий пример своей реализации если кому интересно.
У яндекса есть ответ геокодера:
http://geocode-maps.yandex.ru/1.x/?geocode=Москва,+Тверская+улица,+дом+7
из которого нужно получить первый featureMember<Point xmlns="http://www.opengis.net/gml">
<pos>37.611006 55.757962</pos>
</Point>
и pos записать в базу Комментарии: 14
берете адрес с ресурса, отправляете (плагином на сохранение допустим) к api для получения координат, ответ сохраняет в поле (тв или еще где), ну а дальше вытягиваете и строите по этим данным карту…
Про запись в тв нашел, не подкинете документации на «плагином на сохранение допустим»? Заранее благодарен
switch ($modx->event->name) {
case 'OnDocFormSave':
$param = array(
'place' => $resource->get('pagetitle'), // допустим адрес у вас в pagetitle
'id' => $resource->get('id')
);
$modx->runSnippet('getcoord',$param);
break;
}
ну и сниппет getcoord — там запрос к апи и сохранение координат
Спасибо!
plugin: getadres
snippet: geocoords
В тв «adres» забивается адрес (санкт-петербург, невский проспект 1/3), в тв «coords» выводятся координаты
$param = array(
'adres' => $resource->getTVValue('adres'),
'id' => $resource->get('id')
);
$modx->runSnippet('geocoords',$param);
Почему-то с вашим кодом плагин не заработал, пока не разбиралсяsnippet: geocoords
<?php
$doc = $modx->getObject('modResource', $id);
$replace = array(' ', '/');
$adres_new = str_replace($replace, '', $adres);
$dataCoords = simplexml_load_file('http://geocode-maps.yandex.ru/1.x/?geocode='.$adres_new);
foreach ($dataCoords->GeoObjectCollection->featureMember[0]->GeoObject->Point->pos as $coords) {
$array = explode(' ',$coords);
$coords = $array[1].','.$array[0];
$doc->setTVValue('coords', $coords);
}
$doc->save();
В тв «adres» забивается адрес (санкт-петербург, невский проспект 1/3), в тв «coords» выводятся координаты
Остались следующие вопросы:
1) если изменен ресурс (любое поле) а тв adres не изменен или создан ресурс без заполнения тв adres — не запускать сниппет/плагин
2) если изменен тв adres или создан ресурс с заполнением тв adres — запустить сниппет/плагин
3) запускать все это только при определенном шаблоне (как понимаю можно задать системный параметр и в нем проставить template для которых будет запускаться сниппет/плагин)
1) если изменен ресурс (любое поле) а тв adres не изменен или создан ресурс без заполнения тв adres — не запускать сниппет/плагин
2) если изменен тв adres или создан ресурс с заполнением тв adres — запустить сниппет/плагин
3) запускать все это только при определенном шаблоне (как понимаю можно задать системный параметр и в нем проставить template для которых будет запускаться сниппет/плагин)
«кластеризируются»))))
api.yandex.ru/maps/features/?p=cluster
чего смешного?
чего смешного?
switch ($modx->event->name) {
case 'OnDocFormPrerender':
$before = $resource->getTVValue('adres'); // адрес при загрузке
break;
case 'OnDocFormSave':
$after = $resource->getTVValue('adres'); // адрес при сохранении
break;
}
if($after == $before){
$modx->event->output('равны');
}else{
$modx->event->output('не равны');
}
Почему-то не получается. Должно выводить если тв не изменен — «равны», если изменен «не равны».При загрузке ресурса сразу пишет — «не равны», при сохранении — «равны»
В какую сторону копать?
Плагин запускается отдельно на каждое событие, то есть значение есть только в одной переменной каждый раз.
Нужно сохранять данные или в сессию, или в $modx.
Нужно сохранять данные или в сессию, или в $modx.
switch ($modx->event->name) {
case 'OnDocFormPrerender':
$modx->before = $resource->getTVValue('adres'); // адрес при загрузке
break;
case 'OnDocFormSave':
$after = $resource->getTVValue('adres'); // адрес при сохранении
if($after == $modx->before){
$modx->event->output('равны');
}else{
$modx->event->output('не равны');
}
break;
}
Не отрабатывает, пишет «не равны» все время.
Не подскажете документации по сохранение в модкс/сессию?
Не подскажете документации по сохранение в модкс/сессию?
Должно вот так работать.
switch ($modx->event->name) {
case 'OnDocFormPrerender':
$_SESSION['before'] = $resource->getTVValue('adres'); // адрес при загрузке
break;
case 'OnDocFormSave':
$after = $resource->getTVValue('adres'); // адрес при сохранении
if($after == $_SESSION['before']){
$modx->event->output('равны');
}else{
$modx->event->output('не равны');
}
break;
}
Работает, спасибо!
Напиши инструкцию, будет полезно поколениям
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.