Skip to content

Instantly share code, notes, and snippets.

@maximzasorin
Created January 13, 2016 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximzasorin/d435e5d29dc04750ac9b to your computer and use it in GitHub Desktop.
Save maximzasorin/d435e5d29dc04750ac9b to your computer and use it in GitHub Desktop.
Визуализация объектов на карте Яндекса (HostCMS)
<?php
/*
* Получение координат объекта по адресу с помощью Яндекс.Карты API
*
* В bootstrap.php:
*
// Получение координат объекта по адресу с помощью Яндекс.Карты API
Core_Event::attach('property_value_text.onAfterSave', array('Kad_Informationsystem_Observer_GetCoordinates', 'onAfterAddressSave'));
Core_Event::attach('property_value_string.onAfterSave', array('Kad_Informationsystem_Observer_GetCoordinates', 'onAfterCoordinatesSave'));
*
*/
defined('HOSTCMS') || exit('HostCMS: access denied.');
class Kad_Informationsystem_Observer_GetCoordinates
{
const INFORMATIONSYSTEM_ID = 26;
static protected function validCoordinates($coordinates)
{
// $coordinats = preg_replace('/\s/g', '', $coordinats);
// $aCoords = explode(',', $coordinates);
return (
is_object($coordinates) &&
$coordinates->value != ''
);
}
static protected function getCoordinates($address)
{
$params = array(
'geocode' => $address,
'format' => 'json',
'results' => 1,
);
$content = @file_get_contents('https://geocode-maps.yandex.ru/1.x/?' . http_build_query($params, '', '&'));
$response = @json_decode($content);
if ($response->response->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found > 0)
{
$coordinates = $response->response->GeoObjectCollection->featureMember[0]->GeoObject->Point->pos;
$aCoords = explode(' ', $coordinates);
$aCoords = array_reverse($aCoords);
$coordinates = implode(', ', $aCoords);
return $coordinates;
}
}
static public function onAfterAddressSave($object, $args)
{
if ($object->Property->tag_name == 'address')
{
if ($object->value != '')
{
$oInformationsystem_Item = Core_Entity::factory('Informationsystem_Item', $object->entity_id);
$oCoordinatesProperty = Core_Entity::factory('Property')->getByTagName('coordinates');
$coordinates = self::getCoordinates('Москва, ' . $object->value);
// Сохраняем координаты в массив
//
Core_Registry::instance()->set('coordinates_from_address', $coordinates);
// Kad_Property::setValue($oInformationsystem_Item, $oCoordinatesProperty->id, $coordinates);
}
}
}
static public function onAfterCoordinatesSave($object, $args)
{
if ($object->Property->tag_name == 'coordinates')
{
// Берем координаты из массива
$coordinates = Core_Registry::instance()->get('coordinates_from_address');
if ($object->value == '' && $coordinates)
{
$object->value = $coordinates;
$object->save();
Core_Registry::instance()->delete('coordinates_from_address');
}
}
}
}
<?php
/**
* Бэкенд для карты объектов по сервисному обслуживанию окон
*/
if ($Informationsystem_Controller_Show->item && Core_Array::getGet('get-objects'))
{
$oInformationsystem_Item = Core_Entity::factory('Informationsystem_Item', $Informationsystem_Controller_Show->item);
$oGroupProperty = Kad_Property::getValue($oInformationsystem_Item, 'objects_group_id');
$objectGroupId = $oGroupProperty ? $oGroupProperty->value : 0;
$oInformationsystem_Group = Core_Entity::factory('Informationsystem_Group', $objectGroupId);
$response = new StdClass;
if ($oInformationsystem_Group->id)
{
$oObjects = $oInformationsystem_Group->Informationsystem_Groups;
$oObjects->queryBuilder()
->where('active', '=', '1')
->where('deleted', '=', '0');
$aoObjects = $oObjects->findAll();
if (count($aoObjects) > 0)
{
// Иконка для меток
$oIconValue = Kad_Property::getValue($oInformationsystem_Item, 'objects_icon');
if ($oIconValue)
{
$oIconValue->setHref($oInformationsystem_Item->getItemHref());
$oIconValue->setDir($oInformationsystem_Item->getItemPath());
$path = $oIconValue->getLargeFilePath();
$href = $oIconValue->getLargeFileHref();
if (/*$fileSize > 12 && */Core_Image::instance()->exifImagetype($path))
{
$response->icon = new StdClass;
$response->icon->url = $href;
$picsize = @getimagesize($path);
if ($picsize)
{
$response->icon->width = $picsize[0];
$response->icon->height = $picsize[1];
}
}
}
// Объекты
$response->objects = array();
foreach ($aoObjects as $oObject)
{
$oAddressValue = Kad_Property::getValue($oObject, 'address');
$oCoordinatesValue = Kad_Property::getValue($oObject, 'coordinates');
$address = $oAddressValue ? $oAddressValue->value : '';
$coordinates = $oCoordinatesValue ? $oCoordinatesValue->value : '';
$coordinates = preg_replace('/\s/', '', $coordinates);
if ($coordinates != '')
{
$oProjects = $oObject->Informationsystem_Items;
$oProjects->queryBuilder()
->where('active', '=', '1')
->where('deleted', '=', '0');
$aoProjects = $oProjects->findAll();
if (count($aoProjects) > 0)
{
// Переводим координаты в числа
$aCoords = explode(',', $coordinates);
foreach ($aCoords as $i => $coord)
{
$aCoords[$i] = (float)$coord;
}
$responseObject = new StdClass;
$responseObject->name = $oObject->name;
$responseObject->address = $address;
$responseObject->coordinates = $aCoords;
$responseObject->projects = array();
$response->objects[] = $responseObject;
// Проекты
foreach ($aoProjects as $oProject)
{
$responseProject = new StdClass;
$responseProject->name = $oProject->name;
$responseProject->link = $oProject->Informationsystem->Structure->getPath() . $oProject->getPath();
$responseObject->projects[] = $responseProject;
}
}
}
}
}
}
header('Content-Type: text/html; charset=utf-8');
exit(json_encode($response));
}
<script src="/js/projects-map.js" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(function() {
var projectsMap = new ProjectsMap({
mapId: 'objects_map',
center: [55.76, 37.64],
zoom: 10,
renderProjects: function(projects) {
$('.projects').removeClass('projects_hidden');
$('.projects__list').empty();
if (projects.length > 0) {
$.each(projects, function() {
$('.projects__list').append(
$('<li />', { class: 'projects__item' })
.append(
$('<a />', { class: 'projects__item-link', href: this.link, text: this.name })
)
);
});
} else {
console.log('empty projects list');
}
}
});
projectsMap.start();
});
</script>
/*
* Фронтед для карты объектов по сервисному обслуживанию окон
*/
var ProjectsMap = function(options) {
this.mapId = options.mapId;
this.renderProjects = options.renderProjects;
this.center = options.center;
this.zoom = options.zoom;
};
ProjectsMap.prototype.start = function() {
var projectsMap = this;
this.objects = [];
this.map();
this.fetch(function(data) {
// После получения проектов отрисовываем их на карте
projectsMap.render(data);
});
}
ProjectsMap.prototype.map = function() {
this.map = new ymaps.Map(this.mapId, {
center: this.center,
zoom: this.zoom,
controls:[
'zoomControl',
'searchControl',
'typeSelector',
'fullscreenControl'
]
});
}
ProjectsMap.prototype.fetch = function(callback) {
$.ajax({
url: '?get-objects=1',
dataType: 'json',
success: function(data) {
callback(data);
}
});
}
ProjectsMap.prototype.render = function(data) {
var projectsMap = this;
var activeOptions;
var defaultOptions;
if (!data.icon) {
activeOptions = { preset: 'islands#darkBlueStretchyIcon' };
defaultOptions = { preset: 'islands#blueStretchyIcon' };
} else {
var iconContentLayout = ymaps.templateLayoutFactory.createClass('<div class="object-placemark">{{ properties.iconContent }}</div>');
var icon = data.icon;
activeOptions = {
iconLayout: 'default#imageWithContent',
iconImageHref: icon.url,
iconContentLayout: iconContentLayout,
iconImageSize: [icon.width, icon.height],
iconImageOffset: [-icon.width / 2, -icon.height], // позиция иконки
}
defaultOptions = activeOptions;
}
var collection = new ymaps.GeoObjectCollection({}, defaultOptions);
$.each(data.objects, function(i, object) {
collection.add(
new ymaps.Placemark(object.coordinates, {
iconContent: object.name,
defaultOptions: defaultOptions,
activeOptions: activeOptions,
projects: object.projects
})
);
});
projectsMap.map.geoObjects.add(collection);
collection.events.add('click', function (e) {
var activeGeoObject = e.get('target');
activeGeoObject.options.set(activeGeoObject.properties.get('activeOptions'));
collection.each(function (geoObject) {
if (geoObject !== activeGeoObject) {
geoObject.options.set(geoObject.properties.get('defaultOptions'));
}
});
var projects = activeGeoObject.properties.get('projects');
projectsMap.renderProjects(projects);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment