如何在MS SQL Server 2008中将某些几何数据转换为地理数据?
我编写了一些包含嵌套循环的代码,其中内循环执行大约150万次.我在这个循环中有一个函数,我正在尝试优化.我做了一些工作,并得到了一些结果,但我需要一些输入来检查我所做的事情是否合情合理.
一些背景:
我有两个地理点集合(纬度,经度),一个相对较小的集合和一个相对庞大的集合.对于小集合中的每个点,我需要找到大集合中的最近点.
显而易见的方法是使用hasrsine公式.这里的好处是距离绝对准确.
from math import radians, sin, cos, asin, sqrt
def haversine(point1, point2):
"""Gives the distance between two points on earth.
"""
earth_radius_miles = 3956
lat1, lon1 = (radians(coord) for coord in point1)
lat2, lon2 = (radians(coord) for coord in point2)
dlat, dlon = (lat2 - lat1, lon2 - lon1)
a = sin(dlat/2.0)**2 + cos(lat1) * cos(lat2) * sin(dlon/2.0)**2
great_circle_distance = 2 * asin(min(1,sqrt(a)))
d = earth_radius_miles * great_circle_distance
return d
Run Code Online (Sandbox Code Playgroud)
但是,在我的机器上运行这150万次大约需要9秒(根据时间).由于准确的距离并不重要,我只需要找到最近的点,我决定尝试其他一些功能.
毕达哥拉斯定理的简单实现给了我大约30%的加速.考虑到我可以做得更好,我写了以下内容:
def dumb(point1, point2):
lat1, lon1 …Run Code Online (Sandbox Code Playgroud) 我正在处理由纬度/经度对表示的大量点(这些点不一定是唯一的,集合中可能有多个点位于同一位置).这些点存储在数据库中.
我需要做的是找出一种有效执行搜索的方法,以获得位于任意点的给定半径(例如,25英里)内的点数.计数不需要100%准确 - 更重要的是,它必须快速,并且合理地接近正确的计数.通过在WHERE子句中使用带有一些三角函数的查询来过滤点到参考点的距离,可以使用SQL执行此操作.不幸的是,这个查询非常非常昂贵,并且缓存不太可能提供很多帮助,因为位置将非常分散.
我最终希望构建某种内存结构,能够有效地处理这种操作 - 牺牲一些数据的准确性和活力(可能每天仅重建一次)以换取速度.我一直在研究kd-tree,但我还不清楚这可以应用于纬度/经度数据(与2d平面中的x,y数据相对).
如果有人有任何想法或解决方案我应该调查,我真的很感激 - 所以提前谢谢.
algorithm geography geospatial latitude-longitude data-structures
我正在使用Dundas Maps并尝试绘制世界地图,其中国家/地区被分组到特定于业务实现的区域.
我有世界上每个国家的形状数据(点和段).通过将区域内的所有国家/地区的所有点和细分添加到新的区域形状,我可以将国家/地区组合到一起.
foreach(var region in GetAllRegions()){
var regionShape = new Shape { Name = region.Name };
foreach(var country in GetCountriesInRegion(region.Id)){
var countryShape = GetCountryShape(country.Id);
regionShape.AddSegments(countryShape.ShapeData.Points, countryShape.ShapeData.Segments);
}
map.Shapes.Add(regionShape);
}
Run Code Online (Sandbox Code Playgroud)
问题是国家边界线仍然出现在一个区域内,我想删除它们,以便只显示区域边界.
Dundas多边形必须在同一点开始和结束.所有国家形状都是如此.现在我需要一个能够:
以下是我到目前为止使用地图的地方.您可以看到仍需要删除国家/地区边界.例如,蒙古和中国之间的边界应该被丢弃,而蒙古和俄罗斯之间的边界应该保留.
我需要保留区域边界的原因是区域颜色在传达信息方面很重要,但相邻区域可能是相同的颜色.这些地区可以改变以包括或排除国家,这就是区域塑造必须是动态的原因.
编辑: 我现在知道我正在寻找的是一个多边形联盟.David Lean 解释了如何使用SQL Server 2008中的空间函数来执行此操作,这可能是一个选项,但我的努力已经停止,因为生成的多边形联合非常复杂,以至于SQL将其截断为43,480个字符.我现在正在尝试为此找到解决方法或找到在代码中进行联合的方法.

我尝试使用时遇到了很多问题Microsoft.SqlServer.Types.SqlGeography.我完全知道在Linq to Sql中对此的支持并不是很好.我尝试了很多方法,从预期的方式(数据库类型geography,CLR类型SqlGeography)开始.这产生了NotSupportedException,这通过博客广泛讨论.
然后我走了将geography列视为一个路径varbinary(max),就像geography存储为二进制的UDT一样.这似乎工作正常(使用一些二进制读取和写入扩展方法).
但是,我现在遇到了一个相当模糊的问题,这似乎并没有发生在许多其他人身上.
System.InvalidCastException:无法将类型为"Microsoft.SqlServer.Types.SqlGeography"的对象强制转换为"System.Byte []".
ObjectMaterializer在迭代查询时抛出此错误.它似乎只有在包含地理列的表隐式包含在查询中时(即使用EntityRef<>属性进行连接)才会出现.
System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
我的问题:如果我正在检索geography列varbinary(max),我可能会发现反向错误:无法转换byte[]为SqlGeography.我明白了.我没有.我对部分LINQ to SQL类有一些隐藏二进制转换的特性......那可能是问题吗?
任何帮助表示赞赏,我知道可能没有足够的信息.
附加功能:
geography在Visual Studio DBML"服务器数据类型" =设计师列geography生成此错误:The specified type 'geography' is not a valid provider type.geography在Visual Studio DBML没有"服务器数据类型"列设计师生成此错误:Could not format node 'Value' for execution as SQL.您需要使用命令行参数BCP将其原始(本机)格式的数据转储到二进制文件.然后在另一台服务器上,您可以将此二进制数据批量插入到同一结构的表中.
这是一些代码.
Command Line: bcp "geodata.dbo.GeographyData" out "C:\GeoData.bin" -T -n -S <servername>
Run Code Online (Sandbox Code Playgroud)
T-SQL: bulk insert GeographyData from 'C:\GeoData.bin' with (dataFileType='Native')
Run Code Online (Sandbox Code Playgroud)
我学会了这一切,通过空间大师艾萨克Kunen和的帮助下肯特Tegels,在这个讨论帖在这里.
Isaac在此引文中强调了BCP方法的原因:
值得指出的是,WKB是一种有损格式,因为它不存储SRID.因此,如果您提取并插入WKB,则必须自己携带SRID.我们的内部二进制格式确实存储了SRID,因此像这样的BCP应该不那么麻烦.
HTH.
编辑:将整个帖子问题替换为社区维基..这篇文章是一个答案.
你知道一些实用工具或网站,我可以用英里作为输入给美国城市,州和径向距离,它会让我回到那个半径范围内的所有城市吗?
谢谢!
为确定特定字符串是否属于某个地理位置,我们做了哪些工作?例如:
'troy, ny'
'austin, texas'
'hotels in las vegas, nv'
Run Code Online (Sandbox Code Playgroud)
我想我有点期待的是一种统计方法,它给出了前两个是位置的一定程度的信心.最后一个可能需要一个启发式来抓取"%s,%s",然后使用相同的技术.我特意寻找那些不太依赖命题'in'的方法,因为它不是一个完全明确或一致的位置指示器.
有人能指出方法,论文或现有的公用事业吗?谢谢!
我正在使用lat/long处理地理点,并且需要在该点的5英里范围内找到我们数据库中的其他点.但是,我似乎无法找出STBuffer的"单位",它似乎不符合英尺,英里,米,公里等.文档仅将它们称为"单位",任何建议?谢谢
[...]来自geography :: STGeomFromText('POINT(xy)',4326).STBuffer(z).STIntersects(geography :: STGeomFromText('POINT('+ CAST(v.Longitude as varchar(max))+ ''+ CAST(v.Latitude as varchar(max))+')',4326))= 1
我有表与GPS数据,如:Latitude,Longitude,Time,UserId
如何聚合指定时间范围内的总距离,按所有点(按时间排序)和用户分组数据对所有距离求和?
谢谢
geography ×10
distance ×3
sql-server ×3
algorithm ×2
c# ×2
geometry ×2
bcp ×1
dundas ×1
export ×1
geospatial ×1
linq-to-sql ×1
measurement ×1
nlp ×1
optimization ×1
python ×1
sql ×1
sqlgeography ×1
web-services ×1