Используем карту OpenStreetMap в компоненте SOBI2 для Joomla 1.5.

Читатели моего блога задали мне вопрос, а как можно использовать карту OpenStreetMap в компоненте SOBI2 для Joomla 1.5?

В этой заметке я расскажу как это сделать.

С начала рассмотрим как это сделать, используя API Google Maps v2, который используется в компоненте SOBI2 по умолчанию.

По умолчанию код функции showGoogleMaps для вывода карты Google в файле entry.functions.php, который расположен по адресу:

<папка установки Joomla>/components/com_sobi2/ncludes/ имеет вид:

function showGoogleMaps($mySobi, $config)
    {
 
		if( !$config->useGoogleMaps || !isset( $config->googleMapsApiKey ) ) {
			return null;
		}
		$map_url = $config->key( "google_maps", "google_map_url", "http://maps.google.com");
		$map_api_version = $config->key("google_maps", "google_map_apiversion", "2");
 
		$title = $config->jsAddSlashes( $mySobi->title );
		$GeoPos = $config->getGeoPosition( $mySobi->id );
		if( $GeoPos['lat'] && $GeoPos['long'] && is_numeric( $GeoPos['lat'] ) && is_numeric( $GeoPos['lat'] ) ) {
			?>
						<div style="width: <?php echo $config->googleMapsWidth; ?>px; height: <?php echo $config->googleMapsHeight; ?>px;" id="sobi2GoogleMaps"></div>
						<script src="<?php echo $map_url?>/maps?file=api&amp;v=<?php echo $map_api_version?>&amp;key=<?php echo $config->googleMapsApiKey ?>" type="text/javascript"></script>
						<script type="text/javascript">
				//<![CDATA[
				function loadmap(){
                    if (GBrowserIsCompatible()) {
                        var center = new GLatLng(<?php echo $GeoPos['lat']; ?>, <?php echo $GeoPos['long']; ?>);
                        //var SobiGeoMap = new GMap2(document.getElementById("sobi2GoogleMaps"));
                        var SobiGeoMap = new GMap2(document.getElementById("sobi2GoogleMaps"), { size: new GSize(<?php echo $config->googleMapsWidth; ?>, <?php echo $config->googleMapsHeight; ?>) } );
					<?php
					if( $config->key( "google_maps", "small_map_control", true ) ) {
						echo "SobiGeoMap.addControl(new GSmallMapControl());n";
					}
					if( $config->key( "google_maps", "map_type_control", false ) ) {
//						echo "SobiGeoMap.addControl(new GMapTypeControl());n";
						echo "var mapControl = new GHierarchicalMapTypeControl();";
						echo "SobiGeoMap.addMapType(G_PHYSICAL_MAP);";
 
						// Set up map type menu relationships
						echo "mapControl.clearRelationships();";
						echo "mapControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, '"._SOBI2_GOOGLEMAPS_LABEL."', true);";
 
						echo "SobiGeoMap.addControl(mapControl);";
					}
					if( $config->key( "google_maps", "large_map_control", false ) ) {
						echo "SobiGeoMap.addControl(new GLargeMapControl());n";
					}
					if( $config->key( "google_maps", "small_zoom_control", false ) ) {
						echo "SobiGeoMap.addControl(new GSmallZoomControl());n";
					}
					if( $config->key( "google_maps", "scale_control", false ) ) {
						echo "SobiGeoMap.addControl(new GScaleControl());n";
					}
					if( $config->key( "google_maps", "overview_map_control", false ) ) {
						echo "SobiGeoMap.addControl(new GOverviewMapControl());n";
					}
					if( !$config->googleMapsBubble) {
						echo "var marker = new GMarker(center);n";
					}
					else {
						echo "var marker = new DirectionMarker(center, '{$title}', '{$title}'); n";
					}
					echo "SobiGeoMap.setCenter(center, {$config->googleMapsZoom}); n";
					echo "SobiGeoMap.addOverlay(marker); n";
					if( $config->googleMapsBubble == 2 ) {
						echo "marker.openInfo(); n";
					}
					if( $mtype = $config->key( "google_maps", "map_type", false ) ) {
						echo "SobiGeoMap.setMapType({$mtype}); n";
					}
					echo "n}n}n";
				?>
						if(window.attachEvent){
							window.attachEvent('onload', loadmap);
						}
						else if(window.addEventListener){
							window.addEventListener('load', loadmap, false);
						}
				<?php if( $config->googleMapsBubble){ ?>
					function extend(subclass, superclass) {
						function Dummy() {}
						Dummy.prototype = superclass.prototype;
						subclass.prototype = new Dummy();
						subclass.prototype.constructor = subclass;
						subclass.superclass = superclass;
						subclass.superproto = superclass.prototype;
					}
					extend( DirectionMarker, GMarker);
					function DirectionMarker( point, name, html ){
						DirectionMarker.superclass.call(this, point);
						this.point = point;
						this.name = name;
						this.html = html +
							   '<form action="http://maps.google.com/maps" method="get" target="_blank" onsubmit="DirectionMarker.submit(this);return false;">' +
						       '<br /><?php echo _SOBI2_GOOGLEMAPS_DIR ?><input type="radio" checked name="dir" value="to"> <b><?php echo _SOBI2_GOOGLEMAPS_TO; ?></b> <input type="radio" name="dir" value="from"><b><?php echo _SOBI2_GOOGLEMAPS_FROM; ?></b>' +
						       '<br /><?php echo _SOBI2_GOOGLEMAPS_ADDR ?><input type="text" class="inputbox" size="20" name="saddr" id="saddr" value="" /><br />' +
						       '<input value="<?php echo _SOBI2_GOOGLEMAPS_GET_DIR ?>" class="button" type="submit" style="margin-top: 2px;">' +
						       '<input type="hidden" name="daddr" value="' +
						       this.point.y + ',' + this.point.x + "(" + this.name + ")" + '"/></form>';
						       // The info window version with the "to here" form open
						 GEvent.addListener(this, "click", function() {
							 this.openInfoWindowHtml('<div style="white-space:nowrap; text-align: left;">'+this.html+'</div>');
						 });
					}
					DirectionMarker.prototype.openInfo = function() {
						this.openInfoWindowHtml('<div style="white-space:nowrap; text-align: left;">'+this.html+'</div>');
					}
					DirectionMarker.submit = function( formObj ){
						if(formObj.dir[1].checked ){
							tmp = formObj.daddr.value;
							formObj.daddr.value = formObj.saddr.value;
							formObj.saddr.value = tmp;
						}
						formObj.submit();
					}
					<?php } ?>
				//]]>
						</script>
<?php
		}
		elseif ((strlen(trim($GeoPos['lat'])) && strlen(trim($GeoPos['long']))) && (!is_numeric($GeoPos['lat']) || !is_numeric($GeoPos['lat']))) {
			trigger_error("HTML_SOBI::showGoogleMaps(): Given cooordinates ({$GeoPos['lat']}, {$GeoPos['long']}) are not correct. Please enter float values");
		}
    }

Для отображения карты OpenStreetMap, мы внесем в нее следующие изменения.

После строки var SobiGeoMap = new GMap2(document.getElementById("sobi2GoogleMaps"), { size: new GSize(<?php echo $config->googleMapsWidth; ?>, <?php echo $config->googleMapsHeight; ?>) } );

добавляем код:

CustomGetTileUrl=function(a,b){
return 'http://a.tile.openstreetmap.org/'+b+'/'+a.x+'/'+a.y+'.png';
}
 
var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, "");
 
var copyrightCollection = new GCopyrightCollection('');
 
copyrightCollection.addCopyright(copyright);
 
var tilelayers = [new GTileLayer(copyrightCollection,1,17)];
 
tilelayers[0].getTileUrl = CustomGetTileUrl;
 
var osmmap = new GMapType(tilelayers, G_SATELLITE_MAP.getProjection(), "OSM");
 
SobiGeoMap.addMapType(osmmap);

В самом начале мы пишем функцию для запроса тайлов с сервера openstreetmap.org.

Затем создаем объект copyrightCollection и новый тип карты osmmap.

Добавляем новый тип к карте.

После этого редактируем строку echo "SobiGeoMap.setMapType({$mtype}); n";

Новый вид строки echo "SobiGeoMap.setMapType(osmmap); n";

В результате функция showGoogleMaps имеет вид:

    function showGoogleMaps($mySobi, $config)
    {
 
		if( !$config->useGoogleMaps || !isset( $config->googleMapsApiKey ) ) {
			return null;
		}
		$map_url = $config->key( "google_maps", "google_map_url", "http://maps.google.com");
		$map_api_version = $config->key("google_maps", "google_map_apiversion", "2");
 
		$title = $config->jsAddSlashes( $mySobi->title );
		$GeoPos = $config->getGeoPosition( $mySobi->id );
		if( $GeoPos['lat'] && $GeoPos['long'] && is_numeric( $GeoPos['lat'] ) && is_numeric( $GeoPos['lat'] ) ) {
			?>
						<div style="width: <?php echo $config->googleMapsWidth; ?>px; height: <?php echo $config->googleMapsHeight; ?>px;" id="sobi2GoogleMaps"></div>
						<script src="<?php echo $map_url?>/maps?file=api&amp;v=<?php echo $map_api_version?>&amp;key=<?php echo $config->googleMapsApiKey ?>" type="text/javascript"></script>
						<script type="text/javascript">
				//<![CDATA[
				function loadmap(){
                    if (GBrowserIsCompatible()) {
                        var center = new GLatLng(<?php echo $GeoPos['lat']; ?>, <?php echo $GeoPos['long']; ?>);
                        //var SobiGeoMap = new GMap2(document.getElementById("sobi2GoogleMaps"));
                        var SobiGeoMap = new GMap2(document.getElementById("sobi2GoogleMaps"), { size: new GSize(<?php echo $config->googleMapsWidth; ?>, <?php echo $config->googleMapsHeight; ?>) } );
 
						CustomGetTileUrl=function(a,b){
						return 'http://a.tile.openstreetmap.org/'+b+'/'+a.x+'/'+a.y+'.png';
						}
 
						var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, "");
 
						var copyrightCollection = new GCopyrightCollection('');
 
						copyrightCollection.addCopyright(copyright);
 
						var tilelayers = [new GTileLayer(copyrightCollection,1,17)];
 
						tilelayers[0].getTileUrl = CustomGetTileUrl;
 
						var osmmap = new GMapType(tilelayers, G_SATELLITE_MAP.getProjection(), "OSM");
 
						SobiGeoMap.addMapType(osmmap);
 
					<?php
					if( $config->key( "google_maps", "small_map_control", true ) ) {
						echo "SobiGeoMap.addControl(new GSmallMapControl());n";
					}
					if( $config->key( "google_maps", "map_type_control", false ) ) {
//						echo "SobiGeoMap.addControl(new GMapTypeControl());n";
						echo "var mapControl = new GHierarchicalMapTypeControl();";
						echo "SobiGeoMap.addMapType(G_PHYSICAL_MAP);";
 
						// Set up map type menu relationships
						echo "mapControl.clearRelationships();";
						echo "mapControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, '"._SOBI2_GOOGLEMAPS_LABEL."', true);";
 
						echo "SobiGeoMap.addControl(mapControl);";
					}
					if( $config->key( "google_maps", "large_map_control", false ) ) {
						echo "SobiGeoMap.addControl(new GLargeMapControl());n";
					}
					if( $config->key( "google_maps", "small_zoom_control", false ) ) {
						echo "SobiGeoMap.addControl(new GSmallZoomControl());n";
					}
					if( $config->key( "google_maps", "scale_control", false ) ) {
						echo "SobiGeoMap.addControl(new GScaleControl());n";
					}
					if( $config->key( "google_maps", "overview_map_control", false ) ) {
						echo "SobiGeoMap.addControl(new GOverviewMapControl());n";
					}
					if( !$config->googleMapsBubble) {
						echo "var marker = new GMarker(center);n";
					}
					else {
						echo "var marker = new DirectionMarker(center, '{$title}', '{$title}'); n";
					}
					echo "SobiGeoMap.setCenter(center, {$config->googleMapsZoom}); n";
					echo "SobiGeoMap.addOverlay(marker); n";
					if( $config->googleMapsBubble == 2 ) {
						echo "marker.openInfo(); n";
					}
					if( $mtype = $config->key( "google_maps", "map_type", false ) ) {
						echo "SobiGeoMap.setMapType(osmmap); n";
					}
					echo "n}n}n";
				?>
						if(window.attachEvent){
							window.attachEvent('onload', loadmap);
						}
						else if(window.addEventListener){
							window.addEventListener('load', loadmap, false);
						}
				<?php if( $config->googleMapsBubble){ ?>
					function extend(subclass, superclass) {
						function Dummy() {}
						Dummy.prototype = superclass.prototype;
						subclass.prototype = new Dummy();
						subclass.prototype.constructor = subclass;
						subclass.superclass = superclass;
						subclass.superproto = superclass.prototype;
					}
					extend( DirectionMarker, GMarker);
					function DirectionMarker( point, name, html ){
						DirectionMarker.superclass.call(this, point);
						this.point = point;
						this.name = name;
						this.html = html +
							   '<form action="http://maps.google.com/maps" method="get" target="_blank" onsubmit="DirectionMarker.submit(this);return false;">' +
						       '<br /><?php echo _SOBI2_GOOGLEMAPS_DIR ?><input type="radio" checked name="dir" value="to"> <b><?php echo _SOBI2_GOOGLEMAPS_TO; ?></b> <input type="radio" name="dir" value="from"><b><?php echo _SOBI2_GOOGLEMAPS_FROM; ?></b>' +
						       '<br /><?php echo _SOBI2_GOOGLEMAPS_ADDR ?><input type="text" class="inputbox" size="20" name="saddr" id="saddr" value="" /><br />' +
						       '<input value="<?php echo _SOBI2_GOOGLEMAPS_GET_DIR ?>" class="button" type="submit" style="margin-top: 2px;">' +
						       '<input type="hidden" name="daddr" value="' +
						       this.point.y + ',' + this.point.x + "(" + this.name + ")" + '"/></form>';
						       // The info window version with the "to here" form open
						 GEvent.addListener(this, "click", function() {
							 this.openInfoWindowHtml('<div style="white-space:nowrap; text-align: left;">'+this.html+'</div>');
						 });
					}
					DirectionMarker.prototype.openInfo = function() {
						this.openInfoWindowHtml('<div style="white-space:nowrap; text-align: left;">'+this.html+'</div>');
					}
					DirectionMarker.submit = function( formObj ){
						if(formObj.dir[1].checked ){
							tmp = formObj.daddr.value;
							formObj.daddr.value = formObj.saddr.value;
							formObj.saddr.value = tmp;
						}
						formObj.submit();
					}
					<?php } ?>
				//]]>
						</script>
<?php
		}
		elseif ((strlen(trim($GeoPos['lat'])) && strlen(trim($GeoPos['long']))) && (!is_numeric($GeoPos['lat']) || !is_numeric($GeoPos['lat']))) {
			trigger_error("HTML_SOBI::showGoogleMaps(): Given cooordinates ({$GeoPos['lat']}, {$GeoPos['long']}) are not correct. Please enter float values");
		}
    }

Сохраняем сделанные изменения.

В браузере открываем страницу с записью и наблюдаем:

Можно использовать для отображения карты OpenStreetMap API Google Maps v3.

Код для карты Google мы возьмем из заметки «Совместное использование Google Maps v3 и Яндекс.Карт в компоненте SOBI2 для Joomla 1.5», а код для отображения OpenStreetMap с помощью API Google Maps v3 из заметки «Знакомство с проектом OpenStreetMap».

Конечный код функции showGoogleMaps:

   function showGoogleMaps($mySobi, $config)
    {
 
		if( !$config->useGoogleMaps) {
			return null;
		}
 
		$title = $config->jsAddSlashes( $mySobi->title );
		$GeoPos = $config->getGeoPosition( $mySobi->id );
		if( $GeoPos['lat'] && $GeoPos['long'] && is_numeric( $GeoPos['lat'] ) && is_numeric( $GeoPos['lat'] ) ) {
			?>
					<div style="width: <?php echo $config->googleMapsWidth; ?>px; height: <?php echo $config->googleMapsHeight; ?>px;" id="sobi2GoogleMaps"></div>
					<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
						<script type="text/javascript">
				//<![CDATA[
 
				function initialize() {
					var myLatlng = new google.maps.LatLng(<?php echo $GeoPos['lat']; ?>, <?php echo $GeoPos['long']; ?>);					
 
					var myOptions = {
						zoom: <?php echo $config->googleMapsZoom; ?>,
						center: myLatlng,
						mapTypeControl: false,
						navigationControl: true,
						navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
						mapTypeId: google.maps.MapTypeId.ROADMAP      
					}
					var map = new google.maps.Map(document.getElementById("sobi2GoogleMaps"), myOptions);
 
					// Задаем слой с OSM
 
		var openStreet = new google.maps.ImageMapType({
		  getTileUrl: function(ll, z) {
			var X = ll.x % (1 << z);  // wrap
			return "http://tile.openstreetmap.org/" + z + "/" + X + "/" + ll.y + ".png";
		  },
		  tileSize: new google.maps.Size(256, 256),
		  isPng: true,
		  maxZoom: 18,
		  name: "OSM",
		  alt: "Слой с Open Streetmap"
		}); 
 
		//Добавляем слои к карте
 
		map.mapTypes.set('osm', openStreet);
		map.setMapTypeId('osm');
 
		map.setOptions({
		  mapTypeControlOptions: {
			mapTypeIds: [
			  'osm',
			  google.maps.MapTypeId.ROADMAP,
			  google.maps.MapTypeId.TERRAIN,
			  google.maps.MapTypeId.SATELLITE,
			  google.maps.MapTypeId.HYBRID
			],
			style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
		  }
		});
 
					var marker = new google.maps.Marker({
					position: myLatlng, 
					map: map,
					title:"<?php echo _SOBI2_GOOGLEMAPS_LABEL; ?>"
					}); 
 
 
				}
 
                 google.maps.event.addDomListener(window,'load', initialize);
 
				//]]>
						</script>
<?php
		}
		elseif ((strlen(trim($GeoPos['lat'])) && strlen(trim($GeoPos['long']))) && (!is_numeric($GeoPos['lat']) || !is_numeric($GeoPos['lat']))) {
			trigger_error("HTML_SOBI::showGoogleMaps(): Given cooordinates ({$GeoPos['lat']}, {$GeoPos['long']}) are not correct. Please enter float values");
		}
    }

Посмотрим страницу записи справочника в браузере

  • Гость: Скажите, а нельзя ли прикрутить карту OpenStreetMap к компоненту Mosets Tree для Joomla 1.5?
  • Гость: А зачем ее прикручивать? там есть свой собственный модуль для гугл карт.
  • Гость: Я бы тоже хотел узнать как прикрутить OpenStreetMap к компоненту Mosets Tree
  • Гость: Постараюсь по возможности написать, а пока один совет. Нужно найти в файлах установленного компонента Mosets Tree, где формируется вывод карты и внести в этот код свои исправления.
  • Гость: Файл нашел но к сожалению я далек от php /components/com_mtree/templates/ m2/sub_map.tpl.php /components/com_mtree/Savant2/Savant2_Plugin_ahrefmap.php
  • Гость: Спасибо будем ждать =)
  • Гость: Уважаемый admin, и все-таки хотелось бы узнать как прикрутить OpenStreetMap к компоненту Mosets Tree