我有一个简单的PHP函数,它是距离给定纬度和经度最近的城市:
function findCity($lat, $lng, $username) {
$json_url = "http://api.geonames.org/findNearbyPlaceNameJSON?lat=" . $lat . "&lng=" . $lng . "&username=" . $username;
$json = file_get_contents($json_url);
$json = str_replace('},
]', "}
]", $json);
$data = json_decode($json);
echo "<pre>";
print_r($data);
echo "</pre>";
}
此方法使用lat返回以下内容:51.992和long:4.89
stdClass Object
(
[geonames] => Array
(
[0] => stdClass Object
(
[countryName] => Netherlands
[adminCode1] => 11
[fclName] => city, village,...
[countryCode] => NL
[lng] => 4.876389
[fcodeName] => populated place
[distance] => 1.42349
[toponymName] => Langerak
[fcl] => P
[name] => Langerak
[fcode] => PPL
[geonameId] => 2751924
[lat] => 51.931667
[adminName1] => South Holland
[population] => 0
)
)
)
这会返回最近的城市,但我正在寻找this之类的内容。只返回最近的大城市。这可能吗?或者还有其他替代方案来解决这个问题。我已经阅读了Google地理编码API,但我们无法使用它,因为我们没有使用Google地图来显示结果。 (注意:地理编码API只能与Google地图结合使用;不会在地图上显示地理编码结果。Source)
我知道这不是一个真正的程序员问题,但由于地理位置论坛并不是真正活跃的,我想我会在这里发布。
答案 0 :(得分:1)
您需要一份最大的城市名单。我没有找到关于geonames的api调用(也许尝试freebase api for sorting by city relevance)。因为您显示的示例列表是静态的,您可以硬编码吗?如果是这样,你可以使用下面显示的内容:
/*
* Haversine formula
* from: http://rosettacode.org/wiki/Haversine_formula#PHP
*/
class POI {
private $latitude;
private $longitude;
public function __construct($latitude, $longitude) {
$this->latitude = deg2rad($latitude);
$this->longitude = deg2rad($longitude);
}
public function getLatitude() {return $this->latitude;}
public function getLongitude(){return $this->longitude;}
public function getDistanceInMetersTo(POI $other) {
$radiusOfEarth = 6371000;// Earth's radius in meters.
$diffLatitude = $other->getLatitude() - $this->latitude;
$diffLongitude = $other->getLongitude() - $this->longitude;
$a = sin($diffLatitude / 2) * sin($diffLatitude / 2) +
cos($this->latitude) * cos($other->getLatitude()) *
sin($diffLongitude / 2) * sin($diffLongitude / 2);
$c = 2 * asin(sqrt($a));
$distance = $radiusOfEarth * $c;
return $distance;
}
}
class bigcity
{
public $name;
public $lat;
public $long;
function __construct($name,$lat,$long)
{
$this->name=$name;
$this->lat=$lat;
$this->long=$long;
}
}
function getbigcities()
{
$bigcities = array();
$bigcities[] = new bigcity('Amsterdam',52.374 ,4.89);
$bigcities[] = new bigcity('Eindhoven',51.441 ,5.478);
$bigcities[] = new bigcity('Groningen',53.219 ,6.567);
return $bigcities;
}
function findCity($lat, $lng)
{
$userinput = new POI($lat,$lng);
$bigcities = getbigcities();
$distance = 1000000000;
$result = '';
foreach ($bigcities as $bigcity)
{
$delta = $userinput->getDistanceInMetersTo(new POI($bigcity->lat,$bigcity->long));
if($delta<$distance)
{
$result = $bigcity->name;
$distance = $delta;
}
}
return ($result);
}
echo findcity(51.556,5.091); //tilburg
echo findcity(52.55,6.15); //leeuwaarden
echo findcity(52.091,5.122); //utrecht
exit;
答案 1 :(得分:0)
对于那些在同样问题上苦苦挣扎的人,我制作了一些Java代码,用于从网站上删除各大洲,国家,城市,纬度和经度坐标。代码并不漂亮,因为我匆匆忙忙地完成了它,但它完成了它应该做的事情:
public class Main {
private static String title;
private static String land;
private static Document docu;
private static String continent = "Africa";
public static void main(String[] args) throws IOException {
String url = "http://www.timegenie.com/latitude_and_longitude/";
Document doc = Jsoup.connect(url).get();
Elements links = doc.select("a[href]");
//print("\nLinks: (%d)", links.size());
for (Element link : links) {
if (link.attr("abs:href").contains("country_coordinates")) {
try {
docu = Jsoup.connect(link.attr("abs:href")).get();
title = docu.title();
land = (trim(link.text(), 50));
if (land.equals("Algeria")) {
continent = "Africa";
} else if (land.equals("Antarctica")) {
continent = "Antarctica";
} else if (land.equals("Afghanistan")) {
continent = "Asia";
} else if (land.equals("Bouvet Island")) {
continent = "Antartica";
} else if (land.equals("Anguilla")) {
continent = "North America";
} else if (land.equals("Belize")) {
continent = "North America";
} else if (land.equals("Armenia")) {
continent = "Asia";
} else if (land.equals("Åland Islands") || land.equals("Aland Islands")) {
continent = "Europe";
} else if (land.equals("Bassas da India")) {
continent = "Africa";
} else if (land.equals("Akrotiri")) {
continent = "Asia";
} else if (land.equals("Bermuda")) {
continent = "North America";
} else if (land.equals("Clipperton Island")) {
continent = "North America";
} else if (land.equals("Argentina")) {
continent = "South America";
} else if (land.equals("American Samoa")) {
continent = "Oceania";
}
Element table = docu.select("table.times").get(0);
Elements trs = table.select("tr");
Iterator trIter = trs.iterator();
boolean firstRow = true;
while (trIter.hasNext()) {
Element tr = (Element) trIter.next();
if (firstRow) {
firstRow = false;
continue;
}
Elements tds = tr.select("td");
Iterator tdIter = tds.iterator();
int tdCount = 1;
String city = null;
String longgr = null;
String latgr= null;
while (tdIter.hasNext()) {
Element td = (Element) tdIter.next();
switch (tdCount++) {
case 1:
city = td.select("a").text();
break;
case 4:
latgr= td.text();
break;
case 6:
longgr = td.text();
break;
}
}
System.out.println(continent + "|" + land + "|" + city + "|" + latgr+ "|" + longgr+ "|");
}
} catch (Exception ex) {
Elements links2 = docu.select("a[href]");
for (Element link2 : links2) {
if (link2.attr("abs:href").contains("state_coordinates")) {
try {
try {
docu = Jsoup.connect(link2.attr("abs:href")).get();
title = docu.title();
Element table = docu.select("table.times").get(0);
Elements trs = table.select("tr");
Iterator trIter = trs.iterator();
boolean firstRow = true;
while (trIter.hasNext()) {
Element tr = (Element) trIter.next();
if (firstRow) {
firstRow = false;
continue;
}
Elements tds = tr.select("td");
Iterator tdIter = tds.iterator();
int tdCount = 1;
String city = null;
String longgr = null;
String latgr= null;
while (tdIter.hasNext()) {
Element td = (Element) tdIter.next();
switch (tdCount++) {
case 1:
city = td.select("a").text();
break;
case 4:
latgr= td.text();
break;
case 6:
longgr= td.text();
break;
}
}
System.out.println(continent + "|" + land + "|" + city + "|" + latgr+ "|" + longgr+ "|");
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception x) {
x.printStackTrace();
}
}
}
}
}
}
}
private static void print(String msg, Object... args) {
System.out.println(String.format(msg, args));
}
private static String trim(String s, int width) {
if (s.length() > width) {
return s.substring(0, width - 1) + ".";
} else {
return s;
}
}
}
我使用了Jsoup库。
运行此代码需要一段时间(大约3分钟),它会返回很多行(粘贴在单词:146页)格式为:continent|country|city|lat|long|
,因此很容易将它们插入数据库。
干杯