我有一个城市白名单。比方说,西雅图,波特兰,塞勒姆。使用GeoIP,我会检测用户城市。我们称之为 $ user_city 。根据$ user_city,我想在140英里的白名单(西雅图|| Portland || Salem)中显示距离最近城市的分类列表。如果城市未列入140英里,我只会显示一个下拉菜单,并要求用户手动选择一个城市。
有几种方法可以做到这一点:
创建一个名为regions
的表
地区将有
城市1 |城市2 |距离(最远140英里)
city 1 =来自白名单的城市 city 2 =距离城市140英里内的任何城市
这将创建一个合理大小的表。如果我的白名单有200个城市,并且每个城市140英里内有40个城市(或城镇)。这将创建8000行。
Now, when a user comes to my site:
1) I check if user is from whitelist city already (city 1 column). If so, display that city
2). If not, check if $user_city is in "city 2" column
2a) if it is, get whitelist city with lowest distance
2b) if it is not, display drop-down for manual input
最终约束:无论我们选择哪种方法,都必须在iFrame中使用。我的意思是,我可以在我的mysite1.com上创建此页面并将此页面嵌入到iframe内的someothersite2.com中吗?它仍然可以获得user_city并找到最近的白名单城市吗?我知道有一些跨域脚本规则,所以我不确定iFrame是否能够获取用户IP地址,将其传递给GeoIP,并将其解析为$ user_city
如何做到最好?如果很多人将我的页面嵌入他们的页面(使用iframe),那么我的服务器每秒会被强烈<10000> 次(一厢情愿的想法,但让我们假设是这种情况)。我不知道DB是否能够处理如此多的冲击。我不想为更多的数据库服务器或网络服务器付费。我想尽量减少我的资源需求。所以,我不介意通过JavaScript将一些工作卸载到用户的浏览器。
有些答案建议存储lat,long然后再进行数学运算。我建议创建“区域”表的原因是这样所有数学都是预计算的。如果我有一个城市的“白名单”,并且如果我为每个列入白名单的城市预先计算所有可能的附近城市。然后我不必每次都计算距离(例如使用Haversine算法)。
是否可以通过一些狡猾的Java Script使用来将所有这些内容卸载到用户的浏览器中?我不想让我的服务器超载免费服务。它可能会赚钱,但我非常接近破产,我担心在我赚足够的钱来支付升级费用之前我的服务器会崩溃。
所以,这个问题的三个约束是1)应该从iframe内部工作(我希望这将成为病毒,每个博客都希望将我的网站嵌入到他们的页面的iframe中。)2)应该非常快3)应该最小化我的服务器上的负载
答案 0 :(得分:1)
City
并为每个查询执行mysql数学计算,并添加缓存层,例如memcache。公平的表现和非常灵活!City (id,lat,lng,name)
和Distance (city_id1,city_id2,dist)
,按传统JOIN
获取结果。 (也可以使用缓存层。)不是很灵活。CityObj (id,lat,lng,data[blob])
只是序列化并压缩城市的php数组并存储它。这可能会引起你的注意,但正如我们所知,瓶颈永远不是CPU或内存,而是盘IO。这是从INT的索引读取的,与使用tmp表的JOIN
相关联。这不是很灵活,但速度快且可扩展。易于分片和集群。答案 1 :(得分:1)
是否可以通过一些狡猾的Java Script使用来将所有这些内容卸载到用户的浏览器中?我不想让我的服务器超载免费服务。它可能会赚钱,但我非常接近破产,我担心在我赚足够的钱来支付升级费用之前我的服务器会崩溃。
是的,有可能......使用Google Maps API和geometry library。您正在寻找的功能是google.maps.geometry.spherical.computeDistanceBetween
。我之前做过的Here is an example可能会帮助你开始。我在这里使用jQuery。查看源代码,了解正在发生的事情并根据需要进行修改。简言之:
supplierZips
是一个与您的城市白名单相当的邮政编码数组。computeDistanceBetween
计算该zip与白名单中每个位置之间的位置。希望这有助于您入门。
答案 2 :(得分:0)
您只需获取每个城市的lat
和long
,然后将其添加到数据库中。
所以每个城市只有1条记录。地球上的位置没有存储距离。
完成后,您可以使用半正式公式(http://en.wikipedia.org/wiki/Haversine_formula)轻松进行查询,以获取范围内最近的城市。
知道有一些跨域脚本规则,所以我不确定iFrame是否能够获取用户IP地址
如果您只是从嵌入页面获取信息,则可以获取用户ip或其他任何内容。
我不知道数据库是否能够处理如此多的重击
如果您有那么多请求,那么您应该找到一种方法来获取它:-)您可以用于升级:D
答案 3 :(得分:0)
您的算法似乎通常是正确的。我要做的是使用PostGIS(一个postgresql插件,比看起来更容易设置:-D)。我相信额外的学习曲线是完全值得的,它是地理数据的标准。
如果您将白名单城市作为POINTs,具有纬度和经度,您实际上可以要求PostGIS按距离到给定的纬度/经度进行排序。它应该比自己做得更有效(PostGIS非常优化)。
您可以使用Yahoo Placefinder或Google Maps等地理编码API来获取您的用户城市(以及白名单城市)。我会做的是拥有一个存储城市名称,lat和lon的表(或者与白名单城市相同),并对其进行查找。如果找不到城市名称,请点击您正在使用的API,并将结果缓存到表格中。通过这种方式,除了模糊的地方之外,您很快就不需要访问API。 API也很快。
如果你真的要看到那种服务器负载,你可能想要考虑使用PHP以外的东西(例如node.js)。顺便说一下,从服务器的角度来看,从iframe进行地理编码不会有任何问题,就像浏览器“正常”访问该页面一样。