我正在尝试为我正在处理的数据集选择一个不错的SQL Server 2008空间索引设置.
数据集是多边形,表示整个地球的轮廓.表中有106,000行,多边形存储在几何字段中.
我的问题是许多多边形覆盖了地球的很大一部分.这似乎很难获得一个空间索引,它将消除主过滤器中的许多行.例如,查看以下查询:
SELECT "ID","CODE","geom".STAsBinary() as "geom" FROM "dbo"."ContA"
WHERE "geom".Filter(
geometry::STGeomFromText('POLYGON ((-142.03193662573682 59.53396984952896,
-142.03193662573682 59.88928136451884,
-141.32743833481925 59.88928136451884,
-141.32743833481925 59.53396984952896,
-142.03193662573682 59.53396984952896))', 4326)
) = 1
Run Code Online (Sandbox Code Playgroud)
这是查询与表中只有两个多边形相交的区域.无论我选择何种空间索引设置组合,Filter()总是返回大约60,000行.
用STIntersects()替换Filter()当然只返回我想要的两个多边形,但当然需要更长的时间(Filter()为6秒,STIntersects()为12秒).
任何人都可以给我任何关于是否存在可能在60,000行上改进的空间索引设置或者我的数据集是否与SQL Server的空间索引不匹配的提示?
更多信息:
正如所建议的那样,我在地球上使用4x4网格分割多边形.我无法用QGIS看到这样的方法,所以我编写了自己的查询来做到这一点.首先我定义了16个边界框,第一个看起来像这样:
declare @box1 geometry = geometry::STGeomFromText('POLYGON ((
-180 90,
-90 90,
-90 45,
-180 45,
-180 90))', 4326)
Run Code Online (Sandbox Code Playgroud)
然后我使用每个边界框来选择和截断与该框相交的多边形:
insert ContASplit
select CODE, geom.STIntersection(@box1), CODE_DESC from ContA
where geom.STIntersects(@box1) = 1
Run Code Online (Sandbox Code Playgroud)
我显然为4x4网格中的所有16个边界框做了这个.最终结果是我有一个新表~107,000行(这证实我实际上没有很多巨大的多边形).
我添加了一个空间索引,每个对象有1024个单元格,每个级别的单元格低,低,低,低.
然而,非常奇怪的是,这个具有分割多边形的新表仍然与旧表一样.执行上面列出的.Filter 仍然会返回~60,000行.我根本不理解这一点,显然我不明白空间索引实际上是如何工作的.
矛盾的是,虽然.Filter()仍然返回~60,000行,但它的性能有所提高..Filter()现在大约需要2秒而不是6秒,而.STIntersects()现在需要6秒而不是12秒.
这里要求的是索引的SQL示例:
CREATE SPATIAL INDEX [contasplit_sidx] ON [dbo].[ContASplit]
(
[geom]
)USING …
Run Code Online (Sandbox Code Playgroud) spatial geospatial spatial-query sql-server-2008 spatial-index
我目前正在为游戏编写插件,其中一个功能包括设置由2个二维坐标(矩形的左上角和右下角区域)定义的区域的能力.然后存储这些区域,并且将具有与每个区域相关联的各种其他数据.当玩家在世界各地移动时,我需要确定他何时只从玩家的坐标进入这些区域中的一个,并且这样做的方法必须是有效的,因为这最终会被称为每秒数百次.
是否有任何数据结构可以有效地支持这种搜索,如果是,我在哪里可以找到它的文档,找到要使用的java实现,或者如果有必要,自己实现它?
我还想注意,我发现了一些似乎只支持批量加载的树结构,但我必须能够实时添加和删除此结构中的值.
我正在尝试使用中心和半径的坐标在MySQL中创建圆几何.我到处搜索...我在网站上的MySQL文档中找到的所有内容都是多边形的.可能是我在找错了地方.任何人都可以帮助我使用适当的SQL来帮助我创建一个表,该表将这个Circle几何存储为表中的一列吗?另外,我甚至不确定在MySQL中是否有办法这样做?我正在使用的版本是 MySQL 5.6.
提前致谢.
我需要找到用户搜索位置中包含的所有属性; 一个位置可以是一个城市,县等.每个属性都有一个lat和long,可以用来在MySQL中创建一个POINT.位置是GEOMETRY类型,大多数是POLYGON和MULTIPOLYGONS.经过一周的搜索和故障排除后,我似乎无法让DB给我一个匹配.这就是场景.
SET @area = (SELECT area.polygon from area where area.city = 'Charlotte' and area.type = 'city');
SET @property = (SELECT property.point from property where id = 397315);
SELECT st_contains(@area, @property);
Run Code Online (Sandbox Code Playgroud)
@area获得夏洛特的POLYGON.
@property得到了一个属性的POINT,我100%肯定是在Charlotte里面或者POLYGON里面.我甚至用外部工具测试它以进行健全性检查.
每次都ST_CONTAINS
返回0!无论我做什么,它始终是0.
我尝试使用ST_WITHIN
失败.然后我确保SRID是相同的.首先两个都没有设置在4328,然后我将它们设置为0,再没有.我为多边形和点添加了空间索引,但仍然没有.
这是我要匹配的POINT POINT (35.086449 -80.741455)
.
为了完整性检查,我运行了这个查询:
select st_contains(
ST_GeomFromText('POLYGON (( 322 322, 322 513, 528 513, 528 322, 322 322 ))'),
ST_GeomFromText('POINT (418 411)'));
Run Code Online (Sandbox Code Playgroud)
这导致1匹配!
我到底失去了什么?谢谢.
我正在使用MySql处理Grails 1.3.2.我需要在数据库中存储某些位置的纬度和经度,然后根据用户的当前位置,我需要返回该位置特定半径范围内的项目.所以,我们基本上有以下要求:
我一直在研究我们在这里的各种选项,并想知道您对此有何看法/建议.我们这里有各种选择:
Lucene Spatial Search(http://wiki.apache.org/lucene-java/SpatialSearch)并研究如何使用它进行搜索
Grails Solr插件(http://www.grails.org/plugin/solr).但是这不会返回域对象.
Grails Stitches Plugin(http://www.grails.org/plugin/stitches).除了作者的网站(http://www.philliprhodes.com/content/stitches-30-seconds)之外,没有很多文档.
MySql空间扩展以及域类的所有字段上的全文索引.如果我们走这条路,那么我们就不会使用可搜索的了.
我相信这是与地图集成的任何应用程序中的一个非常基本的要求.
所以,我真的很想知道实现这个功能的最合适的方法.
谢谢
我精通SQL,但对使用SQL Geometry功能很新.我有一个非常基本的问题需要解决,但我没有在网上找到任何解释如何使用几何对象的好资源.(Technet是学习新事物的糟糕方式......)
我在笛卡尔平面上有一个2d点的集合,我试图找到半径集合内的所有点.
我使用如下语法创建并填充了一个表:
更新[Things] set [Location] = geometry :: Point(@ X,@ Y,0)
(@ X,@ Y只是x和y值,0是所有对象共享的任意数字,如果我理解正确,允许设置过滤)
这是我离开轨道的地方......我是否尝试使用它构建某种多边形集合和查询,或者是否有一些简单的方法来检查多个半径的交集而不构建一堆圆形多边形?
附录:如果没有人对多半径问题有答案,那么单半径解决方案是什么?
UPDATE
以下是我使用假想的星型数据库编写的一些示例,其中星星作为点存储在xy网格上:
选择框中的所有点:
DECLARE @polygon geometry = geometry::STGeomFromText('POLYGON(('
+ CAST(@MinX AS VARCHAR(10)) + ' ' + CAST(@MinY AS VARCHAR(10)) + ','
+ CAST(@MaxX AS VARCHAR(10)) + ' ' + CAST(@MinY AS VARCHAR(10)) + ', '
+ CAST(@MaxX AS VARCHAR(10)) + ' ' + CAST(@MaxY AS VARCHAR(10)) + ','
+ CAST(@MinX AS VARCHAR(10)) + ' ' + CAST(@MaxY AS VARCHAR(10)) + ','
+ …
Run Code Online (Sandbox Code Playgroud) 我有一个点列表 P=[p1,...pN] 其中 pi=(latitudeI,longitudeI)。
使用 Python 3,我想找到最小的集群集(P 的不相交子集),使得集群中的每个成员都在集群中每个其他成员的 20 公里以内。
使用Vincenty 方法计算两点之间的距离。
为了使这更具体一点,假设我有一组要点,例如
from numpy import *
points = array([[33. , 41. ],
[33.9693, 41.3923],
[33.6074, 41.277 ],
[34.4823, 41.919 ],
[34.3702, 41.1424],
[34.3931, 41.078 ],
[34.2377, 41.0576],
[34.2395, 41.0211],
[34.4443, 41.3499],
[34.3812, 40.9793]])
Run Code Online (Sandbox Code Playgroud)
然后我试图定义这个函数:
from geopy.distance import vincenty
def clusters(points, distance):
"""Returns smallest list of clusters [C1,C2...Cn] such that
for x,y in Ci, vincenty(x,y).km <= distance """
return [points] # Incorrect but gives the form of the …
Run Code Online (Sandbox Code Playgroud) 我正在尝试找出最有效的查询,以获得给定点半径内的点.结果不一定非常准确,所以我赞成速度超过准确性.
我们尝试使用where子句比较使用STDistance的点的距离,如下所示(其中@point和v.GeoPoint是地理类型):
WHERE v.GeoPoint.STDistance(@point) <= @radius
Run Code Online (Sandbox Code Playgroud)
还有一个使用与此类似的STIntersects:
WHERE @point.STBuffer(@radius).STIntersects(v.GeoPoint) = 1
Run Code Online (Sandbox Code Playgroud)
这些查询中的任何一个是首选还是我错过了另一个功能?
我正在使用下面的语句将名为'lattitude'和'longitude'的两个varChar格式化列写入名为'coordinate'的Point格式化列.
"UPDATE table_name SET coordinate = PointFromText(CONCAT('POINT(',table_name.longitude,' ',table_name.lattitude,')'))"
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下语句对坐标列执行空间查询.
SELECT id , coordinate FROM table_name WHERE MBRContains(GeomFromText('Polygon(-126.728566 49.226434, -123.652395 23.586457,-56.679738 23.908252,-53.076223 55.243002)'), coordinate)
Run Code Online (Sandbox Code Playgroud)
根据这个工具,我的查询中的多边形覆盖整个美国我知道我的表中有些点落在美国但我仍然没有得到任何结果(注意我得到的结果是空的而不是错误).关于我做错了什么的任何想法?
UPDATE.以下是根据以下建议执行查询的更新尝试.
SET @g1 = GeomFromText('Polygon((23.586457 -123.652395,23.908252 -56.679738,55.243002 -53.076223,55.243002 -53.076223,23.586457 -123.652395))');
SELECT id , coordinate FROM table_name WHERE MBRContains(@g1, coordinate)
Run Code Online (Sandbox Code Playgroud) 我有一个包含大约500个点的表,我正在寻找容差范围内的重复项.这需要不到一秒钟,给我500行.大多数的距离为零,因为它给出了相同的点(PointA = PointB)
DECLARE @TOL AS REAL
SET @TOL = 0.05
SELECT
PointA.ObjectId as ObjectIDa,
PointA.Name as PTNameA,
PointA.[Description] as PTdescA,
PointB.ObjectId as ObjectIDb,
PointB.Name as PTNameB,
PointB.[Description] as PTdescB,
ROUND(PointA.Geometry.STDistance(PointB.Geometry),3) DIST
FROM CadData.Survey.SurveyPoint PointA
JOIN [CadData].Survey.SurveyPoint PointB
ON PointA.Geometry.STDistance(PointB.Geometry) < @TOL
-- AND
-- PointA.ObjectId <> PointB.ObjectID
ORDER BY ObjectIDa
Run Code Online (Sandbox Code Playgroud)
如果我使用靠近底部的注释掉的行,我会得到14行,但执行时间最长可达14秒.在我的积分表扩大到数十万之前,这笔交易并不是那么大.
如果答案已经存在,我会提前道歉.我确实看了,但是新的我迷失了阅读的帖子,这些都是我的头脑.
ADDENDUM:ObjectID是一个bigint和表的PK,所以我意识到我可以将语句更改为
AND PointA.ObjectID > PointB.ObjectID
Run Code Online (Sandbox Code Playgroud)
现在这需要一半的时间,并给我一半的结果(7秒内7行).我现在不会重复(因为在第4点接近第8点,然后第8点接近第4点).然而,性能仍然令我担忧,因为该表将非常大,因此任何性能问题都将成为问题.
附录2:如下所示更改JOIN和AND(或建议的WHERE)的顺序也没有区别.
DECLARE @TOL AS REAL
SET @TOL = 0.05
SELECT
PointA.ObjectId as ObjectIDa,
PointA.Name as PTNameA,
PointA.[Description] as PTdescA,
PointB.ObjectId as …
Run Code Online (Sandbox Code Playgroud) spatial-query ×10
spatial ×4
geospatial ×3
mysql ×3
sql ×2
grails ×1
java ×1
polygon ×1
python ×1
sql-server ×1