我有一个数据库,该数据库有300,000个地址,将在地图上显示。我知道如果我对所有地址都进行地理编码,那对我来说太昂贵了。所以我想知道是否可以实时/实时地对地址进行地理编码,当用户选择一个地址(属性地址)时,它将搜索数据库,然后对该地址进行地理编码,然后使用其他属性。
如果您可以共享代码,概念或任何内容,那将是非常不错的。顺便说一下,我的后端在Joomla支持的mysql上。
我有一个数据库,该数据库有300,000个地址,将在地图上显示。我知道如果我对所有地址都进行地理编码,那对我来说太昂贵了。所以我想知道是否可以实时/实时地对地址进行地理编码,当用户选择一个地址(属性地址)时,它将搜索数据库,然后对该地址进行地理编码,然后使用其他属性。
如果您可以共享代码,概念或任何内容,那将是非常不错的。顺便说一下,我的后端在Joomla支持的mysql上。
Answers:
Mehul,我曾经在一家名为SmartyStreets的公司从事地址验证行业的工作。那里有很多地理编码服务,但是只有少数将支持所需数量的批处理。(Google和其他公司不允许大量使用其API或存储/缓存结果。)
如果您转到MySQL数据库并执行包含地址的表的导出,则将其另存为CSV文件。然后,您可以使用SmartyList Web工具或命令行工具对其进行处理。就像我说的那样,那里有几种服务,但是我想您还需要一些可以验证地址是否存在的地址(因此进行地址解析)-如果地址错误或不完整,则地址解析结果也是如此。只有少数服务可以做到这一点。
LiveAddress是一项由USPS 认可的CASS服务。您可以进行一些研究,但是您需要“即时” /快速且便宜的东西,因此我再次推荐LiveAddress。它不仅会验证地址,而且会根据您的要求进行操作(提供经纬度信息)以及地理编码结果的精度。都是基于Web的,将立即处理数千万条记录(请参阅此问题作为参考)。
如果您在用户交互时进一步需要对地址进行地理编码,则LiveAddress还具有一个API版本,可以插入几乎所有内容,并且还支持即时批处理,但是是作为订阅而非一次性支付的付款。
如果您喜欢Python,可以使用 GeoPy API与GDAL Python绑定或Fiona结合使用,并创建一个像这样的非常基本的脚本,用于将地址转换为点shapefile。
这将对名为“ addresses_to_geocode”的文件进行地理定位,在my_output文件夹中创建一个名为“ my_output.shp”的输出shapefile:
import os
from geopy import geocoders
from osgeo import ogr, osr
def geocode(address):
g = geocoders.GoogleV3()
place, (lat, lng) = g.geocode(address)
print '%s: %.5f, %.5f' % (place, lat, lng)
return place, lat, lng
def parse_file(filepath, output_shape):
# create the shapefile
drv = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists(output_shape):
drv.DeleteDataSource(output_shape)
ds = drv.CreateDataSource(output_shape)
# spatial reference
sr = osr.SpatialReference()
sr.ImportFromProj4('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
lyr = ds.CreateLayer(output_shape, sr, ogr.wkbPoint)
# fields
featDefn = lyr.GetLayerDefn()
fld_id = ogr.FieldDefn('id', ogr.OFTInteger)
fld_address = ogr.FieldDefn('ADDRESS', ogr.OFTString)
fld_address.SetWidth(255)
lyr.CreateField(fld_id)
lyr.CreateField(fld_address)
print 'Shapefile %s created...' % ds.name
# read text addresses file
i = 0
f = open(filepath, 'r')
for address in f:
try:
print 'Geocoding %s' % address
place, lat, lng = geocode(address)
point = ogr.Geometry(ogr.wkbPoint)
point.SetPoint(0, lng, lat)
feat = ogr.Feature(lyr.GetLayerDefn())
feat.SetGeometry(point)
feat.SetField('id', i)
feat.SetField('ADDRESS', address)
lyr.CreateFeature(feat)
feat.Destroy()
i = i + 1
except:
print 'Error, skipping address...'
parse_file('addresses_to_geocode', 'my_output')
该文件应该仅在一行中包含一个地址,例如:
Via Benedetto Croce 112, Rome, Italy
Via Aristide Leonori 46, Rome, Italy
Viale Marconi 197, Rome, Italy
在这里,我使用的是Google API,但使用GeoPy切换到其他API(例如Yahoo!,GeoNames或MapPoint)非常基础。
解决您的问题的另一种方法是将数据集导入融合表,并将地址字段设置为位置。然后它将自动对点进行地理编码。完成后,您可以将数据导出为KML。
或者..或者,您可以编写一个php脚本来使用yahoo地理编码器,该编码限制为5万条记录,因此迟早您将在数据库中对所有点进行地理编码。
希望对您有所帮助!
到目前为止,我使用过的最好,最简单的地址解析器https://pypi.python.org/pypi/geocoder/1.8.0 必应地图,谷歌地图,OSM等。
也许不是您问题的最佳答案,但您可以尝试BatchGeo。免费版本会让您遭受很多折磨,但对于我的工作来说仍然足够。不过,我们已经购买了专业版。
从KML文件获取坐标的技巧是稍后将其导入到ArcGIS。
Matej,那是因为Google API每天最多可以拉2千5百万。
关于Geo解决方案,尚未发现支持批处理,这是因为从我对geo python代码的审查来看,每次他请求新坐标时似乎都打开了连接,因此300k可能会永远卡住(可能出现错误400)。
与Poligons玩应该可以解决问题,但这取决于您的“游戏场地”区域是1个国家还是n个国家。
对于1个国家/地区,多边形应该可以正常工作。
对于n个国家/地区,该解决方案将无法正常工作,因为您每次添加其他国家/地区都会花费更长的时间。最好的方法是延迟加载。
=>从多边形的想法开始,在另一个国家的每件事,创建一个大数据库表来保存数据,最终您将保存我想要的数据。
如果您想使用PHP-MySQL,请使用以下解决方案:
<script type="text/javascript" charset="utf-8">
var customIcons = {
restaurant: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
},
bar: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
},
club:
{
icon: 'http://labs.google.com/ridefinder/images/mm_20_yellow.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
},
church:
{
icon: 'http://labs.google.com/ridefinder/images/mm_20_green.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
}
};
function initialize()
{
var mapOptions = {
center: new google.maps.LatLng(37.976178, 23.735881),
zoom: 7,
mapTypeId: google.maps.MapTypeId.roadmap
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
<?php header("content-type: text/html;charset=utf-8");
$getpoints = "SELECT lat, lng, name, address, type FROM markers";
$getpoints .= $filter;
if(!$result = $con->query($getpoints)){
die('There was an error running the query
[' . $con->error . ']');
}
else
{
while ($row = $result->fetch_assoc())
{
$thematic = "'$row[type]'";
$name = "'$row[name]'";
$map_address = "$row[address]";
$url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=".urlencode($map_address);
$lat_long = get_object_vars(json_decode(file_get_contents($url)));
// pick out what we need (lat,lng)
$lat_long = $lat_long['results'][0]->geometry->location->lat . "," . $lat_long['results'][0]->geometry->location->lng;
echo "var myLatlng1 = new google.maps.LatLng($lat_long);
var icon = customIcons[$thematic] || {};
var marker1 = new google.maps.Marker({
position: myLatlng1,
map: map,
icon: icon.icon,
title: '$map_address'
});";
}
}
?>
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
您可以将数据另存为文本文件(每行一条记录),然后使用以下服务对其进行批处理地理编码:http : //geocode.xyz/batch(适用于大多数欧洲国家/地区)
或者,您可以编写自己的代码来访问REST / JSON API:http : //geocode.xyz/api (无限制查找是免费的)
使用Mappointing工具(Map Pointing |批处理地理编码工具(http://www.mappointing.com/))在此工具中,您可以使用Google map free API密钥处理数据。而且该工具还提供了距离计算和位置搜索工具。