Читатели моего блога задали мне вопрос, а как можно использовать карту 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