我听说 SQL Server 现在支持地理之类的东西。是否可以从经度/纬度获得城市?我搜索了很多但找不到任何东西?
3 回答
您需要加载一些带有城市位置的数据——地名(您可能想要cities15000.zip
)或自然地球(人口稠密的地方)可能是开始的好地方。
CREATE TABLE cities (
name VARCHAR(200) PRIMARY KEY,
location GEOGRAPHY,
);
CREATE SPATIAL INDEX idx_cities_location ON cities(location);
INSERT INTO cities (name, location) VALUES
('Auckland', geography::STGeomFromText('POINT(174.7833 -36.85)', 4326)),
('London', geography::STGeomFromText('POINT(-0.1062 51.5171)', 4326))
;
- 注意所有坐标的顺序是
(Longitude Latitude)
- 空间索引使其快速。
- 4326 是基本经度/纬度的坐标系统代码。
然后要找到离给定位置最近的城市,您需要这样的查询:
DECLARE @g geography = 'POINT(103.75 1.3667)';
SELECT TOP(1) name FROM cities
WHERE location.STDistance(@g) IS NOT NULL
ORDER BY location.STDistance(@g);
SQL Server 文档中的更多示例:
您描述的功能称为“反向地理编码” - 采用纬度/经度坐标,并返回离该位置最近的地点的名称。(地理编码是相反的——提供地名以检索相关的纬度/经度坐标)。
您当然可以构建一个使用 SQL Server 作为后端数据库的反向地理编码服务,但没有任何内置功能可提供此类功能。
如果您只是想对一组现有数据进行反向地理编码,而不是在 SQL Server 中创建此功能,您可能会发现使用现有 Web 服务更容易。例如,地名 findNearbyPlaceName 有一个 REST 接口,您可以通过以下 URL 模板访问该接口:
http://api.geonames.org/findNearbyPlaceName?lat=52.62&lng=1.28&username=demo
此示例从 geonames 数据库返回与请求的 lat/lng 坐标 (52.62,1.28) 最接近的已知实体的信息,如下所示:
<geonames>
<geoname>
<toponymName>Norwich</toponymName>
<name>Norwich</name>
<lat>52.62783</lat>
<lng>1.29834</lng>
<geonameId>2641181</geonameId>
<countryCode>GB</countryCode>
<countryName>United Kingdom</countryName>
<fcl>P</fcl>
<fcode>PPLA2</fcode>
<distance>1.51318</distance>
</geoname>
</geonames>
对于空间函数,您需要 SQL 2008 或更高版本。
要做的第一件事是获取书籍/电子书:Alastair Aitchison 的 SQL Server 开始空间。他有一个 SQL 2008 和 2012 版本。他是那里的顶级大师之一。另一个是“空间戴夫”。披露:不,我没有得到一毛钱推荐阿利斯泰尔的书。我在 GreatData.com 工作并使用了 2008 年的书,当时我对 SQL 知之甚少,对映射一无所知,并且能够在短时间内变得相当精通,因为这本书非常好。
接下来,您需要加载城市边界。这些是 ESRI Shapefile 格式,您可以在 NationalAtlas.gov(免费地图文件的重要来源)上免费找到它们。
您需要了解只有较大的城市才有地图边界文件。有了边界,您可以使用 STIntersects() 或其他方法来确定您拥有的纬度/经度坐标是否在城市范围内。
对于较小的城镇,您只会得到一个纬度/经度点。您可以使用“最近邻居”逻辑(也在书中)来确定最近的城市或城镇,但无法确定它是否在城镇范围内。