Читатели моего блога задали мне вопрос, а как можно использовать карту 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&v=<?php echo $map_api_version?>&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&v=<?php echo $map_api_version?>&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