将地理位置保存为纬度/经度或地址/地区名称?

时间:2013-05-14 20:05:49

标签: mysql database-design google-maps-api-3 geolocation

假设像Foursquare这样的服务,我想保存签到的位置。我应该将其保存为纬度 - 经度或地址/地区名称,例如123 Portmill St,NY 12345或SoHo,NY。 在第一种情况下,我可以让用户键入地址,我的服务查找并存储lat-long信息。通过这样做,我的服务可以在多边形边界内搜索签到。

在第二种情况下,我可以将位置存储为存储桶并避免冗余信息,例如(lat,long)=(100000.1,100000.1),(100000.2,100000.2),它们非常接近,甚至可以被认为是同一地点。

2 个答案:

答案 0 :(得分:0)

我认为我并不完全理解你要做的事情的细微差别,但计算机通常可以更好地处理纬度和经度等数字而不是人类可读的文本信息。例如,使用文本地址,您将如何确保一致性,例如处理额外的空间,ZIP + 4代码,而不仅仅是更短的邮政编码等。

我想这只是我的本能,纬度和经度可能比文字好。我住在英国的地方有很多例子,城镇有两条同名的道路,所以我认为存储文本而不是纬度/经度可能会有更多的陷阱。

答案 1 :(得分:0)

这个怎么样?我在数据库中存储3列,即(Latitude,Longitude,TextLocation),但它是被视为表的键的对(纬度,经度)。当请求地理编码器对应于给定(纬度,经度)的文本时,TextLocation只是反向地理编码器的最后已知结果。

当新位置到达时,(New_Latitude,New_Longitude),我将搜索数据库以查找数据库中所有最接近的行。要计算(New_Latitude,New_Longitude)到(纬度,经度)的距离,我将使用以下代码

float LatDiff = New_Latitude - Latitude;
float LongDiff = New_Longitude - Longitude;
float CosNewLat = Math.cos(New_Latitude);
float ConversionFac = 6371000 * Math.PI / 180; // 6371000 is earth radius in metres
float Dist_metres = ConversionFac * Math.sqrt(LatDiff*LatDiff + LongDiff*LongDiff*CosNewLat*CosNewLat);

然后,对于每个最接近的点(New_Latitude,New_Longitude),我将使用反向地理编码更新数据库中的TextLocation。如果新位置与任何现有位置的当前反向地理编码不匹配,我会将其添加到数据库中。

我的部分想法是,即使存储包含一列文本的3列,与现代存储容量相比,数据库仍然很小。