Coğrafi Lokasyon Arama

by admin on Kasım 13, 2010

Bu yazımda sizlere coğrafi lokasyon aramadan bahsedeceğim.Verilen enlem ve boylam bilgisi ile bu lokasyona ait belirli bir uzaklıkta bulunan yerleri bulmak.Tabi bulunacak bu yerlerin bir yerlerde tutulduğunu düşünüyorum.Bunun için ihtiyacımız olan şeyler Mysql Sphinx ve PHP.

Mysql için şöyle basit bir tablonuz olsun

CREATE TABLE IF NOT EXISTS `location` (
 `locationId` int(11) NOT NULL AUTO_INCREMENT,
 `locationName` varchar(255) NOT NULL,
 `locationType` tinyint(4) NOT NULL,
 `locationLat` decimal(10,8) NOT NULL,
 `locationLon` decimal(10,8) NOT NULL,
 PRIMARY KEY (`locationId`),
 KEY `locationType` (`locationType`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=80908 ;

Evet tablomuzu oluşturduktan sonra gelelim sphinx olayına.Sphinx bir açık kaynaklı arama sunucusudur.Detaylı bilgi için bkz : http://sphinxsearch.com/

Ben Sphinx i Ubuntu 10.10 üzerine şöyle kurdum.

sudo apt-get install sphinxsearch

Sonrasında /etc/default/sphinxsearch te otomatik başlatma parametresini yes olarak ayarladım.Gelelim veri indexlemeye.

Bunun için /etc/sphinxsearch/sphinxsearch.conf u biraz kurcalamanız gerekir.İşte source ve indexleri ayarlamanız icab edecek.Detayları sphinx in sayfasında bulabilirsiniz.Ben conf dosyamı şu şekilde oluşturdum.


source geo
{
 type                 = mysql
 sql_host             = 127.0.0.1
 sql_user             = root
 sql_pass    = root
 sql_db        = test
 sql_port    = 3306
 sql_query_pre    = set names utf8
 sql_query_pre    = set session query_cache_type=OFF
 sql_query    = SELECT l.locationType, RADIANS(l.locationLon) AS longitude, RADIANS(l.locationLat) AS latitude FROM location l
 sql_attr_float           = longitude
 sql_attr_float          = latitude
 sql_attr_uint        = locationType
 sql_ranged_throttle      = 0
 sql_query_info           = select * from location where locationId = $id
}

index geo
{
 source                  = geo
 path                    = /etc/sphinxsearch/data/geo/geo
 docinfo                 = extern
 mlock                   = 0
 morphology              = none
 min_word_len            = 1
 charset_type            = utf-8
 charset_table           = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
 ignore_chars            = U+00AD
 html_strip              = 0
 enable_star             = 0
}

indexer
{
 mem_limit            = 512M
}

searchd
{
 listen                = 127.0.0.1
 listen                = 3312
 listen                = /var/run/searchd.sock
 log                    = /var/log/sphinxsearch/searchd.log
 query_log            = /var/log/sphinxsearch/query.log
 read_timeout        = 5
 client_timeout        = 300
 max_children        = 30
 pid_file            = /var/run/searchd.pid
 max_matches            = 1000
 seamless_rotate        = 1
 preopen_indexes        = 0
 unlink_old            = 1
 mva_updates_pool    = 1M
 max_packet_size        = 8M
 max_filters            = 256
 max_filter_values    = 4096
}

bunu oluşturduktan sonra indexer ı çalıştırıyoruz ki datamız indexlensin.İlk başta hata alabilirsiniz.Sebebi indexlenecek datanın olmaması.Datanızı oluşturup

indexer –rotate geo şeklinde geo adlı kaynağı indexleyebilirsiniz.Gelelim sorgumuzu çalıştırmaya:

<?php
require_once 'sphinxapi.php';

$lat = $_GET['lat'];
$lon = $_GET['lon'];
$_radius = $_GET['r'];
 $search = new SphinxClient();
 $search->SetServer("localhost", 3312);
 $search->SetMatchMode(SPH_MATCH_ALL);
 $search->SetArrayResult(true);
 $search->SetLimits(0, 100);
 $search->SetGeoAnchor('latitude', 'longitude', (float) deg2rad($lat), (float) deg2rad($lon));
 $circle = (float) $_radius;
 $search->SetFilterFloatRange('@geodist', 0.0, $circle);

 $search->SetFilter('locationType', array(10));    
 $result = $search->Query('', 'geo');

Şeklinde kullanmanız mümkün.İndireceğiniz sphinxapi.php nin sürümüne dikkat etmeniz gerekir.Çünkü cilent ve sunucu arasında versiyon farklılığı yaşayabilirsiniz. Evet kabaca bu şekilde gerçekleştirmeniz mümkün.

One comment

Örnek yaptım http://cevremdenevar.com ama işte burada bişeyler yazabilmek için daha fazla vakite ihtiyacım var :)

by Mustafa İleri on 23 Haziran 2011 at 23:08. Cevapla #

Leave your comment

Required.

Required. Not published.

If you have one.