2013-11-28 3 views
2

В настоящее время у меня есть карта на моем веб-сайте, которая отображает 50 000 маркеров. Они были недоступны для пользователя из-за загромождения, поэтому я реализовал решение для кластеризации с помощью markkerlusterer google. Это работает нормально, но из-за количества маркеров это невероятно медленно загружается.php - Кластерная кластерная сторона сервера

Я хотел бы использовать решение на стороне сервера в форме php, но не могу найти лучший способ сделать это. Это моя текущая настройка

Внешние маркеры-xml.php PHP файла

<?php 
$SQL = "SELECT MarkerName, Lat, Lng FROM TableName WHERE MarkerName !=''"; 
$Query = mysql_query($SQL); 
$NumRows = mysql_num_rows($Query); 
?> 
<markers> 
<?php  
for($i = 0; $i < $NumRows; $i++) 
{ 
    $row = mysql_fetch_assoc($Query); 
    $Lat = $row['Lat']; 
    $Lng = $row['Lng']; 
    $MarkerName = $row['MarkerName']; 

    echo "<marker Lat='$Lat' Lng='$Lng' MarkerName='$MarkerName'> </marker>\n"; 
} 
?> 
</markers> 

Главной файл conataining Карты

function initialize(mapvars) { 
     var xmldata = "markers-xml.php"; 

     downloadUrl(xmldata, function(doc) { 
      var xml = xmlParse(doc); 
      var markersInfo = xml.documentElement.getElementsByTagName("marker"); 
      var markers = []; 
      var bounds = new google.maps.LatLngBounds(); 
      for (var i = 0; i < markersInfo.length; i++) { 
       var Lat = parseFloat(markersInfo[i].getAttribute("Lat")); 
       var Lng = parseFloat(markersInfo[i].getAttribute("Lng")); 
       var point = new google.maps.LatLng(Lat,Lng); 
       var MarkerName = markersInfo[i].getAttribute("MarkerName"); 

       var marker = new google.maps.Marker({ 
        position: point, 
        map: map, 
        title: MarkerName, 
        MarkerName: MarkerName 
       }); 

      markers.push(marker); 
      bounds.extend(point); 
     } 

     var markerCluster = new MarkerClusterer(map, markers); 
    } 
+0

Пожалуйста, используйте [ 'htmlspecialchars '] (http://php.net/htmlspecialchars) при выводе на HTML, чтобы предотвратить [XSS] (https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29). –

+0

Пожалуйста, не используйте функции 'mysql_ *' больше, они устарели. См. [Почему я не должен использовать функции mysql_ * в PHP?] (Http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php) для деталей. Вместо этого вы должны узнать о [подготовленных утверждениях] (http://bobby-tables.com/php.html) и использовать либо [PDO] (http://php.net/pdo), либо [MySQLi] (http: // php.net/mysqli). Если вы не можете решить, какая из них, [эта статья] (http://php.net/manual/en/mysqlinfo.api.choosing.php) поможет вам. Если вы выберете PDO, [вот хороший учебник] (http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers). –

+0

В настоящее время я должен использовать 'mysql' для этого, но скоро перейду к PDO –

ответ

1

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

Я думаю, что лучшим решением было бы использовать FusionTableLayer, он будет работать без проблем до 100000 маркеров.


возможный подход (относящиеся к комментариям):

, когда окно просмотра карты меняется, отправить за пределы окна просмотра и масштабирования уровня на сервер.

База-запрос должен

  1. фильтра результаты, основанные на данных границах
  2. вокруг широчайшей и LNG (точность округления должны быть связаны с зум-уровня)
  3. Group результаты по закругленной latlngs
  4. возврата закругленного LatLng и количество элементов для этого LatLng

себе Эти данные возвращаются клиенту и создают маркеры (вы можете использовать решение для серверов, чтобы динамически создавать изображения маркеров или использовать пользовательский оверлей).

+0

Вот пример кластеризации на стороне сервера http://jory.dk/AreaGMC/MapClustering.html Он имеет 150 000+ маркеров и загрузок моментально. Единственная проблема заключается в том, что это написано в 'C#', и я знаю только 'php' –

+0

Извините, я думал не в том направлении (все еще возвращаю одиночные маркеры, но отфильтровывая окно просмотра). Этого не должно быть трудно достичь, я обновил свой ответ. –

+0

Вы подходите к логическому смыслу. Я не совсем уверен, как это переводится на php. В тот день, когда мои навыки php продвигаются дальше, не может прийти достаточно скоро. –

1

сторона клиента: генерировать запрос на получение и передавать в пределах окно просмотр

getclusters.php?&lat2=62_676438&lon2=-63_2085681&lat1=10_6655205&lon1=-135_7183337 

сторона сервер: магазина ваших LAT данные LON в таблице с рк и структурой точки данных таким образом, что вы можете использовать пространственный индекс MySQL (который использует R-дерева, а не б-дерева так группировки 50K указывает на секунды, а не минуты):

CREATE TABLE location (
id int(11) unsigned NOT NULL 
, p POINT NOT NULL, PRIMARY KEY (id) 
, SPATIAL INDEX(p)) ENGINE=MyISAM; 

нагрузки из другой таблицы:

INSERT INTO location 
select id, PointFromWKB(Point(latitude, longitude)) 
from table_with_lat_long 

груз из CSV:

LOAD DATA LOCAL INFILE 'data.csv' 
INTO TABLE location 
COLUMNS TERMINATED BY ',' LINES TERMINATED BY '\r\n' 
(id, @dummy, ..., @dummy, @latitude, @longitude) 
set p = PointFromText(CONCAT('POINT(',@latitude,' ',@longitude,')')); 

записи соответствующие SQL-группе путем разделения окна просмотра на равные меньшие квадраты или некоторое минимальное расстояние между точками в зависимости от размера окна просмотра.до тех пор, как вы используете Пространственный индекс он должен работать быстро

клиентской стороны кластер маркера Javascript должен оказывать маркер, основанный на количестве (1 для индивидуальных маркеров 2 или более для кластера)

Смежные вопросы