Объединение плагина "Яндекс-карт" и "Компании"

Приветствую!

По мотивам ветки дискуссии здесь, и с учетом некоторой осведомлённости тех, кому это нужно в плагине «Компании», как и обещал, рассказываю о совмещении моего плагина «Яндекс-карт» и платного «Компании».

Что получим в итоге?

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

Итак, приступим!
Много кода под катом ↓


Оговорюсь сразу, что плагин «Компании» платный, и я не являюсь его автором, а потому указаний на конкретные файлы давать не буду, а лишь ограничусь терминологией движка.

Для хранения координат широты и долготы, а также категории компании, потребуется создать дополнительные поля в профиле компании. Как это сделать «обсуждается» :) тут.

После этого, в шаблоне вывода профиля компании нужно добавить следующее:

{literal}
		
		<script src="http://api-maps.yandex.ru/1.1/index.xml?key={/literal}{$aOptions->getKey()}{literal}" type="text/javascript"></script>
		<script type="text/javascript">
		var globalmaptopic;

		YMaps.jQuery(function () {
            var maptopic = new YMaps.Map(YMaps.jQuery("#YMapsTopic")[0]);
			{/literal}
            maptopic.setCenter(new YMaps.GeoPoint({$aOptions->getCenter()}), {$aOptions->getZoom()});
			{if ($aOptions->getEnablescrollzoom())}
            maptopic.enableScrollZoom();
			{/if}
			{if ($aOptions->getShowtoolbar())}
            maptopic.addControl(new YMaps.ToolBar());
			{/if}
			{if ($aOptions->getShowtypecontrol())}
            maptopic.addControl(new YMaps.TypeControl());
			{/if}
			{if ($aOptions->getShowzoom())}
            maptopic.addControl(new YMaps.Zoom());
			{/if}
			{if ($aOptions->getShowsearchcontrol())}
			maptopic.addControl(new YMaps.SearchControl());
			{/if}
			
			{literal}

			var anchorStyle = new YMaps.Style();
            anchorStyle.iconStyle = new YMaps.IconStyle();
            anchorStyle.iconStyle.href = "http://api-maps.yandex.ru/i/0.4/micro/pmrds.png";
            anchorStyle.iconStyle.size = new YMaps.Point(28, 28);
            anchorStyle.iconStyle.offset = new YMaps.Point(-7, -28);
			
			{/literal}
			{if ($oCompany->getLongitude() != '')}
			{literal}
			
			var clickPoint  = new YMaps.GeoPoint( {/literal} {$oCompany->getLongitude()} {literal}, {/literal} {$oCompany->getLatitude()} {literal});
			var	clickPlace = new YMaps.Placemark(clickPoint, {style: anchorStyle});
			clickPlace.name = "{/literal}{$oCompany->getName()}{literal}";
			clickPlace.description = "{/literal}{if $oCompany->getCountry()}{$oCompany->getCountry()|escape:'html'}{/if}{if $oCompany->getCity()} , {$oCompany->getCity()|escape:'html'}{/if}{if $oCompany->getAddress()} , {$oCompany->getAddress()|escape:'html'}{/if}{literal}";
            maptopic.addOverlay(clickPlace);
			clickPlace.openBalloon();
			
			{/literal}
			{/if}
			{literal}
			
			});

        
		</script>
		{/literal}
		{if ($oCompany->getLongitude() != '')}
		<div id="YMapsTopic" style="width:{$aOptions->getWidth()};height:{$aOptions->getHeight()};"></div>
		{/if}


Переменная $aOptions — это настройки карты, которые указаны в плагине карты. Их также необходимо передать в шаблон профиля следующим образом:

/**
		 * Настройки карты с точкой компании
		 */	
		$aOptions=$this->PluginYmap_Ymapoptions_GetYmapoptions();
		if (count($aOptions)==0) {
			$aOptions=$this->PluginYmap_Ymapoptions_GetYmapoptions();
		}
		$this->Viewer_Assign('aOptions',$aOptions);


Аналогично, те же настройки нужно передать и в шаблон редактирования компании. Кроме того, следует добавить скрипт для слежения за точкой на карте и передачи координат в форму.
Карта со скриптом выглядит так:

{literal}
		
		<script src="http://api-maps.yandex.ru/1.1/index.xml?key={/literal}{$aOptions->getKey()}{literal}" type="text/javascript"></script>
		<script type="text/javascript">
		var globalmaptopic;

		YMaps.jQuery(function () {
            var maptopic = new YMaps.Map(YMaps.jQuery("#YMapsTopic")[0]);
			{/literal}
            maptopic.setCenter(new YMaps.GeoPoint({$aOptions->getCenter()}), {$aOptions->getZoom()});
			{if ($aOptions->getEnablescrollzoom())}
            maptopic.enableScrollZoom();
			{/if}
			{if ($aOptions->getShowtoolbar())}
            maptopic.addControl(new YMaps.ToolBar());
			{/if}
			{if ($aOptions->getShowtypecontrol())}
            maptopic.addControl(new YMaps.TypeControl());
			{/if}
			{if ($aOptions->getShowzoom())}
            maptopic.addControl(new YMaps.Zoom());
			{/if}
			{if ($aOptions->getShowsearchcontrol())}
			maptopic.addControl(new YMaps.SearchControl());
			{/if}
			
			{literal}
			var informationControl = new InformationControl();
			maptopic.addControl(informationControl);
			
			var anchorStyle = new YMaps.Style();
            anchorStyle.iconStyle = new YMaps.IconStyle();
            anchorStyle.iconStyle.href = "http://api-maps.yandex.ru/i/0.4/micro/pmrds.png";
            anchorStyle.iconStyle.size = new YMaps.Point(28, 28);
            anchorStyle.iconStyle.offset = new YMaps.Point(-7, -28);
			
			{/literal}
			{if ($oCompanyEdit->getLongitude() != '')}
			{literal}
			
			var clickPoint  = new YMaps.GeoPoint( {/literal} {$oCompanyEdit->getLongitude()} {literal}, {/literal} {$oCompanyEdit->getLatitude()} {literal});
			var	clickPlace = new YMaps.Placemark(clickPoint, {style: anchorStyle});
			clickPlace.name = "Вы находитесь здесь";
			clickPlace.description = "Чтобы изменить местоположение, просто кликните в нужном месте на карте";
            maptopic.addOverlay(clickPlace);
			clickPlace.openBalloon();
			
			{/literal}
			{/if}
			{literal}
			
			});
			function InformationControl () {
            var geoResult, clickPlace, listener, maptopic;
            this.onAddToMap = function (parentMap) {
                maptopic = parentMap;
                maptopic.addCursor(YMaps.Cursor.HELP);
                listener = YMaps.Events.observe(maptopic, maptopic.Events.Click, function (maptopic, mEvent) {
				
				maptopic.removeAllOverlays();
				var clickPoint  = mEvent.getGeoPoint();
				clickPlace = new YMaps.Placemark(clickPoint, {style: anchorStyle});
                maptopic.addOverlay(clickPlace);
				
				YMaps.jQuery("#map_marker_latitude").attr("value", clickPoint.getLat());
				YMaps.jQuery("#map_marker_longitude").attr("value", clickPoint.getLng());
			
                }, this);

            }

            var anchorStyle = new YMaps.Style();
            anchorStyle.iconStyle = new YMaps.IconStyle();
            anchorStyle.iconStyle.href = "http://api-maps.yandex.ru/i/0.4/micro/pmrds.png";
            anchorStyle.iconStyle.size = new YMaps.Point(28, 28);
            anchorStyle.iconStyle.offset = new YMaps.Point(-7, -28);
            var markStyle = new YMaps.Style();
            markStyle.iconStyle = new YMaps.IconStyle();
            markStyle.iconStyle.href = "http://maps.yandex.ru/css/b-location-balloon/b-location-balloon.mark.png";
            markStyle.iconStyle.size = new YMaps.Point(21, 19);
            markStyle.iconStyle.offset = new YMaps.Point(-1, -18);
        }
		</script>
		{/literal}
		<div id="YMapsTopic" style="width:{$aOptions->getWidth()};height:{$aOptions->getHeight()};"></div>
		<p>
			</br>
		</p>
       		<input type="hidden" id="map_marker_latitude" name="map_marker_latitude" value="{$oCompanyEdit->getLatitude()|escape:'html'}"  class="w100p" />  
       		<input type="hidden" id="map_marker_longitude" name="map_marker_longitude" value="{$oCompanyEdit->getLongitude()|escape:'html'}"  class="w100p" />


Два последних спрятанных поля нужны для хранения координат:

<input type="hidden" id="map_marker_latitude" name="map_marker_latitude" value="{$oCompanyEdit->getLatitude()|escape:'html'}"  class="w100p" />  
<input type="hidden" id="map_marker_longitude" name="map_marker_longitude" value="{$oCompanyEdit->getLongitude()|escape:'html'}"  class="w100p" />


Также не забудьте о третьем добавленном поле — поле категории, которую также нужно будет указать.

Что же, теперь первая часть готова — карта с маркером будет отображаться в профиле компании.

Перейдем ко второй части. Нам нужно выводить карту компаний с категориями.

Для начала, в файле ymap/classes/actions/ActionBuildymap.class.php добавим передачу компаний в шаблон:

/**
		 * Получаем список компаний
		 */
		$aResult=$this->PluginCompany_Company_GetCompaniesRating(1,10000);		
		$aCompany=$aResult['collection']; 
		$this->Viewer_Assign("aCompany",$aCompany);
		
		$this->SetTemplateAction('buildymap');


Затем изменим шаблон генерации карты ymap/templates/skin/default/actions/ActionBuildymap/buildymap.tpl на такой:

{php}
header("Content-type: text/xml");
{/php}
<?xml version="1.0" encoding="utf-8"?>
<ymaps:ymaps xmlns:ymaps="http://maps.yandex.ru/ymaps/1.x"
			xmlns:repr="http://maps.yandex.ru/representation/1.x"
			xmlns:gml="http://www.opengis.net/gml"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:schemaLocation="http://maps.yandex.ru/schemas/ymaps/1.x/ymaps.xsd">
	<repr:Representation>
		<repr:Style gml:id="commonStyle">
			<repr:balloonContentStyle>
				<repr:template>#balloonTemplate</repr:template>
			</repr:balloonContentStyle>
		</repr:Style>
{foreach from=$aMarkercats item=oYmapcat}
		<repr:Style gml:id="{$oYmapcat->getCatstylename()}">
			<repr:parentStyle>#commonStyle</repr:parentStyle>
			<repr:iconStyle>
				<repr:href>http://{$oYmapcat->getCaticon()}</repr:href>
			</repr:iconStyle>
		</repr:Style>
{/foreach}
		<repr:Template gml:id="balloonTemplate">
			<repr:text>
				<div style="font-size:12px;">
					<table style="padding: 0; margin: 0;">
					<tbody>
						<tr>
						<td width="80">
						<div>
						<img style="margin:0; padding:0; border: solid 2px #dddddd;" width="48" height="48" src="http://$[metaDataProperty.AnyMetaData.img]"/>
						</div>
						</td>
						<td>
						<div style="color:blue;font-weight:bold">$[name]</div>
						<div>Адрес: $[metaDataProperty.AnyMetaData.address]</div>
						<a href="http://$[metaDataProperty.AnyMetaData.link]" target="_blank">Подробнее</a>
						</td>
						</tr>
					</tbody>
					</table>
				</div>
			</repr:text>
		</repr:Template>
	</repr:Representation>
	<ymaps:GeoObjectCollection> 
		<gml:featureMembers>
{foreach from=$aMarkercats item=oYmapcat}
			<ymaps:GeoObjectCollection>
				<gml:name>{$oYmapcat->getCatname()}</gml:name>
				<gml:description>//{$oYmapcat->getCaticon()}</gml:description>
				<gml:featureMembers>
{foreach from=$aCompany item=oCompany}
{if $oCompany->GetCompanyCategory() == $oYmapcat->getCatstylename()}
	{if $oCompany->getLatitude() != ''}
					<ymaps:GeoObject> 
						<gml:name>{$oCompany->getName()}</gml:name>
						<gml:metaDataProperty>
							<ymaps:AnyMetaData>
							<address>{$oCompany->getCountry()}, {$oCompany->getCity()} {$oCompany->getAddress()}</address>
							<link>{$oCompany->getUrlFull()|replace:'http://':''}</link>
							<img>{$oCompany->getLogoPath(48)|replace:'http://':''}</img>
							</ymaps:AnyMetaData>
						</gml:metaDataProperty>
						<gml:Point> 
							<gml:pos>{$oCompany->getLongitude()} {$oCompany->getLatitude()}</gml:pos>
						</gml:Point> 
					</ymaps:GeoObject>
	{/if}
{/if}
{/foreach}
				</gml:featureMembers>
				<ymaps:style>#{$oYmapcat->getCatstylename()}</ymaps:style>
			</ymaps:GeoObjectCollection>
{/foreach}
		</gml:featureMembers>
	</ymaps:GeoObjectCollection>
</ymaps:ymaps>


Заметили строчку
{if $oCompany->GetCompanyCategory() == $oYmapcat->getCatstylename()}
?
Здесь происходит разбивка на категории. Помните о третьем добавленном поле в профиле компании?
Вы должны добавить категории в плагине карт ($oYmapcat->getCatstylename()) и указать нужное имя стиля в профиле компании ($oCompany->GetCompanyCategory()). Эти имена должны быть написаны латиницей, без пробелов.

Если всё сделано правильно, то на этом всё. Теперь у вас будет карта со всеми компаниями по категориям и карта с одной точкой в профиле компании.

Удачи!

4 комментария

avatar
Отлично. Теперь нужно найти кто это мне всё сделает)
avatar
А координаты вручную вводятся?
avatar
нет, пользователь выбирает точку на карте
avatar
Может опишите создание полей подробнее? Все были бы очень благодарны.

По поводу упоминания файлов плагина компаний отправил запрос автору.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.