用PHP, MySQL创建一个商店定位器谷歌地图有点不同


Creating a Store Locator with PHP, MySQL & Google Maps a little different

我想用Google Maps创建一个商店定位器。

我有一个数据库,其中包含一个旅游对象表(及其坐标)和一个酒店表(也包含其坐标)。

我希望用户在加载伦敦塔的页面后,有可能看到在10公里半径内的目标附近有哪些酒店,并将结果显示在带有标记的谷歌地图上。

到目前为止,我只使用haversin公式从数据库中获取了10公里范围内的酒店,并将它们显示为文本:
$result = mysql_query("SELECT  nume,  poze, descriere, link, (
(
    ACOS( SIN( 45.515038 * PI( ) /180 ) * SIN( latitudine * PI( ) /180 ) +
          COS( 45.515038 * PI( ) /180 ) * COS( latitudine * PI( ) /180 ) *
          COS( ( 25.366935 - longitudine ) * PI( ) /180 )
    ) *180 / PI( )
) *60 * 1.1515 * 1.609344
) AS distance
FROM `unitati`
HAVING distance <= '10'
ORDER BY distance ASC
LIMIT 0 , 30");

如何将它们显示为地图上的标记?

我发现了这个,我认为它可以帮助我:http://code.google.com/intl/ro-RO/apis/maps/articles/phpsqlsearch.html,但它有一个不同的逻辑:用户在地址类型。

这个示例接受您的查询(您需要为每个目标使用lat/lng编辑45.515038和25.366935)并将其输出为数组的JS数组(如果您喜欢,您可以使其更正式的JSON)

然后循环遍历该数组,为每个数组做标记并将它们放在地图上。最后,它为每个选项添加一个单击侦听器,以便显示相关信息。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<style>
#map_canvas{width:500px;height:500px;}
</style>
</head>
<body>
<div id="map_canvas"></div>
<script>
<?php
//you'll first need to connect to your db
//you also have to edit the lat/lng in your SELECT statement to be that of your objective
$result = mysql_query("SELECT  latitudine, longitudine, nume,  poze, descriere, link, (
(
    ACOS( SIN( 45.515038 * PI( ) /180 ) * SIN( latitudine * PI( ) /180 ) +
          COS( 45.515038 * PI( ) /180 ) * COS( latitudine * PI( ) /180 ) *
          COS( ( 25.366935 - longitudine ) * PI( ) /180 )
    ) *180 / PI( )
) *60 * 1.1515 * 1.609344
) AS distance
FROM `unitati`
HAVING distance <= '10'
ORDER BY distance ASC
LIMIT 0 , 30");
$c=0;
echo "var data=[";
while($markers=mysql_fetch_array($result)){
    if($c>0){echo ",";}
    echo "['".$markers[0]."','".$markers[1]."','".$markers[2]."','".$markers[3]."','".$markers[4]."','".$markers[5]."','".$markers[6]."'"."]";
    $c++;
}
echo "];";
?>
    //var data=[['45','-73','home','poz1','desc1','link1'],['43','-75','work','poz2','desc2','link2']];
    var places=new Array();
    var map;
    var MyInfoWindow = new google.maps.InfoWindow({content: 'Loading...'});
    var bounds = new google.maps.LatLngBounds();
    var myOptions = {
        zoom: 9,
        mapTypeControl: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'),myOptions);
    for(i=0;i<data.length;i++){
        var point=new google.maps.LatLng(data[i][0],data[i][1]);
        var a = new google.maps.Marker({position: point,map: map, icon:'someHotelIcon.png'});
        a.lat=data[i][0];
        a.lng=data[i][1];
        a.nume=data[i][2];
        a.poze=data[i][3];
        a.desc=data[i][4];
        a.url=data[i][5];
        places.push(a);
    }
    for(i=0;i<places.length;i++){
        var point2=new google.maps.LatLng(places[i].lat,places[i].lng);
        bounds.extend(point2);
    }
    map.fitBounds(bounds);
    var objLoc=new google.maps.LatLng(45.515038,26.366935);
    var objectiveMarker = new google.maps.Marker({position: objLoc,map: map, icon:'objectiveIcon.png'});    //---------------Marker for objective
    for (var i = 0; i < places.length; i++) {
        var marker = places[i];
        google.maps.event.addListener(marker, 'click', function () {
        MyInfoWindow.setContent(this.nume+'<br/>'+this.desc+'<br/><a href='"'+this.url+''">link</a>');
        MyInfoWindow.open(map, this);
        });
    }
</script>
</body>
</html>

如果你要做距离/地理位置为基础的搜索使用MySQL的地理空间的东西。它比直接的哈弗素配方有效得多。

这些只是一些片段,但它们应该会帮助你走上伟大的道路:

首先,你的表需要一个地理空间列来保存你的纬度/经线,我的被称为坐标,类型是point:

`coordinate` point NOT NULL,

接下来你需要添加一个地理空间索引:

SPATIAL KEY `coordinate` (`coordinate`)

(这两个都是我的表创建sql语法的一部分)。

这个位将帮助您将经纬度数据插入坐标列:

$data['coordinate'] = ("GeomFromText( 'POINT({$data['longitude']} {$data['latitude']})')");

这一小段将取代你的距离计算(作为一个更大的SQL查询的一部分):

$sql = str_replace(
            array('%LATITUDE%','%LONGITUDE%'), 
            array($latitude, $longitude),
            '(GLength( LineString( coordinate ,Point(%LONGITUDE%, %LATITUDE%)))) AS distance'
        );

上面的查询对欧几里得几何(即世界是平的)很好,但世界不是,所以你应该使用下面的查询来帮助缩小你的结果列表。为了获得真正的准确性和正确的排序,请使用haversine或更好的公式来处理从这两个SQL查询返回的结果。

这个位将作为一个边界矩形/框(任何不在框内的东西都不会返回-用它来代替HAVING distance <= '10',你会发现查询更快-特别是有很多数据)。我计算的最大/最小纬度/长度只是例子,你可以做得更好:-):

        $minLat = $latitude - 0.5;
        $maxLat = $latitude + 0.5;
        $minLon = $longitude - 0.5;
        $maxLon = $longitude + 0.5;
        $sql = str_replace(
            array('%MINLAT%', '%MAXLAT%','%MINLON%', '%MAXLON%'), 
            array($minLat, $maxLat, $minLon, $maxLon),
            "MBRCONTAINS(GeomFromText('POLYGON((%MINLON% %MAXLAT%,%MAXLON% %MAXLAT%,%MAXLON% %MINLAT%,%MINLON% %MINLAT%, %MINLON% %MAXLAT%))'), `coordinate`)"
        );