首页 文章

寻找附近有大地名字的大城市

提问于
浏览
0

我有一个简单的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这样的东西 . 只返回最近的大城市 . 这可能吗?或者还有其他替代方案来解决这个问题 . 我使用它,因为我们没有使用谷歌 Map 来显示结果 . (注意:地理编码API只能与Google Map 结合使用;禁止在 Map 上显示地理编码结果.Source

我知道这不是一个真正的程序员问题,但由于地理位置论坛并不是真正活跃的,我想我会在这里发布 .

2 回答

  • 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;
    
  • 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| ,因此很容易将它们插入数据库中 .

    干杯

相关问题