在 SQL Server 中存储坐标(经度/纬度,来自 Google 地图)的最佳方式是什么?

发布于 2024-07-13 21:03:34 字数 133 浏览 8 评论 0原文

我正在 SQL Server 2008 中设计一个表,它将存储用户列表和 Google 地图坐标(经度和纬度)。

我需要两个字段,还是可以用 1 个字段来完成?

用于存储此类数据的最佳(或最常见)数据类型是什么?

I'm designing a table in SQL Server 2008 that will store a list of users and a Google Maps co-ordinate (longitude & latitude).

Will I need two fields, or can it be done with 1?

What's the best (or most common) data-type to use for storing this kind of data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

未蓝澄海的烟 2024-07-20 21:03:34

公平警告! 在接受使用 GEOGRAPHY 类型的建议之前,请确保您不打算使用 Linq 或实体框架来访问数据,因为它不受支持(截至 2010 年 11 月),并且您将伤心!

2017 年 7 月更新

对于现在阅读此答案的人来说,它已经过时了,因为它指的是过时的技术堆栈。 请参阅评论了解更多详情。

Fair Warning! Before taking the advice to use the GEOGRAPHY type, make sure you are not planning on using Linq or Entity Framework to access the data because it's not supported (as of November 2010) and you will be sad!

Update Jul 2017

For those reading this answer now, it is obsolete as it refers to backdated technology stack. See comments for more details.

永言不败 2024-07-20 21:03:34

看一下 SQL Server 2008 中引入的新空间数据类型。它们是为此类任务而设计的,使索引和查询变得更加容易和高效。

更多信息:

Take a look at the new Spatial data-types that were introduced in SQL Server 2008. They are designed for this kind of task and make indexing and querying much easier and more efficient.

More information:

千仐 2024-07-20 21:03:34

我不知道 SQL Server 的答案,但是...

MySQL 中将其保存为 FLOAT( 10, 6 )< /strong>

这是 Google 开发者文档<的官方建议< /a>.

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;

I don't know the answer for SQL Server but...

In MySQL save it as FLOAT( 10, 6 )

This is the official recommendation from the Google developer documentation.

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
栖迟 2024-07-20 21:03:34

我这样做的方式:我存储纬度经度,然后我有第三列,它是第一两列的自动派生地理类型。 该表如下所示:

CREATE TABLE [dbo].[Geopoint]
(
    [GeopointId] BIGINT NOT NULL PRIMARY KEY IDENTITY, 
    [Latitude] float NOT NULL, 
    [Longitude] float NOT NULL, 
    [ts] ROWVERSION NOT NULL, 
    [GeographyPoint]  AS ([geography]::STGeomFromText(((('POINT('+CONVERT([varchar](20),[Longitude]))+' ')+CONVERT([varchar](20),[Latitude]))+')',(4326))) 
)

这使您可以灵活地在 geoPoint 列上进行空间查询,并且您还可以根据需要检索纬度和经度值以进行显示或提取以用于 csv 目的。

The way I do it: I store the latitude and longitude and then I have a third column which is a automatic derived geography type of the 1st two columns. The table looks like this:

CREATE TABLE [dbo].[Geopoint]
(
    [GeopointId] BIGINT NOT NULL PRIMARY KEY IDENTITY, 
    [Latitude] float NOT NULL, 
    [Longitude] float NOT NULL, 
    [ts] ROWVERSION NOT NULL, 
    [GeographyPoint]  AS ([geography]::STGeomFromText(((('POINT('+CONVERT([varchar](20),[Longitude]))+' ')+CONVERT([varchar](20),[Latitude]))+')',(4326))) 
)

This gives you the flexibility of spatial queries on the geoPoint column and you can also retrieve the latitude and longitude values as you need them for display or extracting for csv purposes.

宣告ˉ结束 2024-07-20 21:03:34

我讨厌成为那些说“这是一种新类型,让我们使用它”的人的逆向者。 新的 SQL Server 2008 空间类型有一些优点 - 即效率,但是您不能盲目地说始终使用该类型。 这实际上取决于一些更大的问题。

举个例子,整合。 这种类型在 .Net 中有一个等效的类型 - 但是互操作呢? 支持或扩展旧版本的 .Net 怎么样? 将这种类型跨服务层暴露给其他平台怎么样? 数据标准化怎么样——也许您对纬度或经度作为独立的信息感兴趣。 也许您已经编写了复杂的业务逻辑来处理经/纬度。

我并不是说您不应该使用空间类型 - 在很多情况下您应该使用。 我只是说在走这条路之前你应该问一些更关键的问题。 为了最准确地回答你的问题,我需要更多地了解你的具体情况。

单独存储长/纬度或以空间类型存储都是可行的解决方案,并且根据您自己的情况,其中一种可能优于另一种。

I hate to be a contrarian to those who said "here is a new type, let's use it". The new SQL Server 2008 spatial types have some pros to it - namely efficiency, however you can't blindly say always use that type. It really depends on some bigger picture issues.

As an example, integration. This type has an equivilent type in .Net - but what about interop? What about supporting or extending older versions of .Net? What about exposing this type across the service layer to other platforms? What about normalization of data - maybe you are interested in lat or long as standalone pieces of information. Perhaps you've already written complex business logic to handle long/lat.

I'm not saying that you shouldn't use the spatial type - in many cases you should. I'm just saying you should ask some more critical questions before going down that path. For me to answer your question most accurately I would need to know more about your specific situation.

Storing long/lat separately or in a spatial type are both viable solutions, and one may be preferable to the other depending on your own circumstances.

云醉月微眠 2024-07-20 21:03:34

您想要做的是将纬度和经度存储为新的 SQL2008 空间类型 -> 地理。

这是我拥有的表格的屏幕截图。

替代文本 http://img20.imageshack.us/img20/6839/zipcodetable.png

在此表中,我们有两个存储地理数据的字段。

  • 边界:这是邮政编码边界的多边形。
  • 中心点:这是代表该多边形视觉中点的纬度/经度点。

您想要将其作为 GEOGRAPHY 类型保存到数据库的主要原因是这样您就可以利用它的所有 SPATIAL 方法 -> 例如。 多边形中的点、两点之间的距离等。

顺便说一句,我们还使用 Google 的 Maps API 来检索纬度/经度数据并将其存储在我们的 Sql 2008 数据库中 - 所以这个方法确实有效。

What you want to do is store the Latitude and Longitude as the new SQL2008 Spatial type -> GEOGRAPHY.

Here's a screen shot of a table, which I have.

alt text http://img20.imageshack.us/img20/6839/zipcodetable.png

In this table, we have two fields that store geography data.

  • Boundary: this is the polygon that is the zip code boundary
  • CentrePoint: this is the Latitude / Longitude point that represents the visual middle point of this polygon.

The main reason why you want to save it to the database as a GEOGRAPHY type is so you can then leverage all the SPATIAL methods off it -> eg. Point in Poly, Distance between two points, etc.

BTW, we also use Google's Maps API to retrieve lat/long data and store that in our Sql 2008 DB -- so this method does work.

梦忆晨望 2024-07-20 21:03:34

SQL Server 支持空间相关信息。 您可以在 http://www.microsoft.com/ 查看更多信息sqlserver/2008/en/us/spatial-data.aspx

或者,您可以将信息存储为两个基本字段,通常浮点数是大多数设备报告的标准数据类型,并且在一两英寸内足够精确 - 对于 Google 地图来说绰绰有余。

SQL Server has support for spatial related information. You can see more at http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx.

Alternativly you can store the information as two basic fields, usually a float is the standard data type reported by most devices and is accurate enough for within an inch or two - more than adequate for Google Maps.

欲拥i 2024-07-20 21:03:34

注意:这是基于最近的 SQL Server、.NET 堆栈更新的最新答案

来自 google Maps 的纬度和经度应在 SQL Server 中以地理数据类型下的点(注意大写 P)数据存储。

假设您当前的数据以 varchar 形式存储在表 Sample 中的 latlon 列下,下面的查询将帮助您转换为地理

alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go

PS:下次当您使用地理数据对此表进行选择时,除了结果和消息选项卡之外,您还将获得如下所示的空间结果选项卡以进行可视化

SSMS 地理结果选项卡

NOTE: This is a recent answer based on recent SQL server, .NET stack updates

latitute and longitude from google Maps should be stored as Point(note capital P) data in SQL server under geography data type.

Assuming your current data is stored in a table Sample as varchar under columns lat and lon, below query will help you convert to geography

alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go

PS: Next time when you do a select on this table with geography data, apart from Results and Messages tab, you will also get Spatial results tab like below for visualization

SSMS geo results tab

撕心裂肺的伤痛 2024-07-20 21:03:34

如果您使用的是 Entity Framework 5 < 您可以使用DbGeography。 MSDN 中的示例:

public class University  
{ 
    public int UniversityID { get; set; } 
    public string Name { get; set; } 
    public DbGeography Location { get; set; } 
}

public partial class UniversityContext : DbContext 
{ 
    public DbSet<University> Universities { get; set; } 
}

using (var context = new UniversityContext ()) 
{ 
    context.Universities.Add(new University() 
        { 
            Name = "Graphic Design Institute", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
        }); 

    context. Universities.Add(new University() 
        { 
            Name = "School of Fine Art", 
            Location = DbGeography.FromText("POINT(-122.335197 47.646711)"), 
        }); 

    context.SaveChanges(); 

    var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)"); 

    var university = (from u in context.Universities 
                        orderby u.Location.Distance(myLocation) 
                        select u).FirstOrDefault(); 

    Console.WriteLine( 
        "The closest University to you is: {0}.", 
        university.Name); 
}

https://msdn.microsoft .com/en-us/library/hh859721(v=vs.113).aspx

当我开始使用DbGeography时,我遇到的一个问题是coordinateSystemId。 请参阅下面的答案,了解下面代码的精彩解释和来源。

public class GeoHelper
{
    public const int SridGoogleMaps = 4326;
    public const int SridCustomMap = 3857;

    public static DbGeography FromLatLng(double lat, double lng)
    {
        return DbGeography.PointFromText(
            "POINT("
            + lng.ToString() + " "
            + lat.ToString() + ")",
            SridGoogleMaps);
    }
}

https://stackoverflow.com/a/25563269/3850405

If you are using Entity Framework 5 < you can use DbGeography. Example from MSDN:

public class University  
{ 
    public int UniversityID { get; set; } 
    public string Name { get; set; } 
    public DbGeography Location { get; set; } 
}

public partial class UniversityContext : DbContext 
{ 
    public DbSet<University> Universities { get; set; } 
}

using (var context = new UniversityContext ()) 
{ 
    context.Universities.Add(new University() 
        { 
            Name = "Graphic Design Institute", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
        }); 

    context. Universities.Add(new University() 
        { 
            Name = "School of Fine Art", 
            Location = DbGeography.FromText("POINT(-122.335197 47.646711)"), 
        }); 

    context.SaveChanges(); 

    var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)"); 

    var university = (from u in context.Universities 
                        orderby u.Location.Distance(myLocation) 
                        select u).FirstOrDefault(); 

    Console.WriteLine( 
        "The closest University to you is: {0}.", 
        university.Name); 
}

https://msdn.microsoft.com/en-us/library/hh859721(v=vs.113).aspx

Something I struggled with then I started using DbGeography was the coordinateSystemId. See the answer below for an excellent explanation and source for the code below.

public class GeoHelper
{
    public const int SridGoogleMaps = 4326;
    public const int SridCustomMap = 3857;

    public static DbGeography FromLatLng(double lat, double lng)
    {
        return DbGeography.PointFromText(
            "POINT("
            + lng.ToString() + " "
            + lat.ToString() + ")",
            SridGoogleMaps);
    }
}

https://stackoverflow.com/a/25563269/3850405

べ映画 2024-07-20 21:03:34

如果你只是想把它替换成一个 URL,我想一个字段就可以了 - 所以你可以形成一个 URL,

http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6

但因为它是两条数据,所以我会将它们存储在单独的字段中

If you are just going to substitute it into a URL I suppose one field would do - so you can form a URL like

http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6

but as it is two pieces of data I would store them in separate fields

白昼 2024-07-20 21:03:34

将两者存储为浮点数,并在它们上使用唯一的关键字。i.em

create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);

Store both as float, and use unique key words on them.i.em

create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文