我是使用Geography数据类型的新手,但我已经想出如何使用它从一个点获取一个zipcodes列表(在存储过程中我只是将点作为varchar而我提供了它“经度纬度”)这样很棒。
然而,我需要展示的下一件事就是距离这一点大约几英里。我看了几个答案,找不到任何答案。
这是我的存储过程:
ALTER PROCEDURE [dbo].[GetZipCodesByDistance]
@point varchar(500),
@distance int
AS
BEGIN
SET NOCOUNT ON;
declare @geoPoint geography
set @geoPoint = geography::STGeomFromText('POINT (' + @point + ')', 4326)
.STBuffer(@distance / 0.0006213712)
SELECT zc.zip_id AS ZipId
,zc.zip_code AS ZipCodeId
,zc.zip_type AS ZipType
,zc.zip_city AS ZipCity
,zc.zip_utc AS ZipUtc
,zc.zip_dst AS ZipDst
,zc.zip_latitude AS ZipLatitude
,zc.zip_longitude AS ZipLongitude,
(Geo.MakeValid()).STDistance(@geoPoint)
FROM zip_code zc
WHERE zc.Geo.STIntersects(@geoPoint) = 1
所以,我的问题是......如何让它从这一点返回里程?我试图添加列“(Geo.MakeValid())。STDistance(@geoPoint)”但它返回全零。
感谢您的帮助!
AJ
答案 0 :(得分:1)
试试这个
SELECT geography::STGeomFromText('POINT(' + zc.zip_latitude
+ ' ' + zc.zip_longitude + ')'
, 4326).STDistance(@geoPoint);
答案 1 :(得分:1)
我仍然不明白你的要求究竟是什么。我们有类似的要求来查找邮政编码之间的距离。查看执行工作的示例函数
CREATE FUNCTION Wrk.ZipDistance
(
@Zip1 VARCHAR(20)
,@Zip2 VARCHAR(20)
)
RETURNS FLOAT
AS
BEGIN
DECLARE @LatLong1 GEOGRAPHY
DECLARE @LatLong2 GEOGRAPHY
DECLARE @Result FLOAT
SELECT
@LatLong1 = LatLong
FROM
PostalCode
WHERE
PostalCode = @Zip1
SELECT
@LatLong2 = LatLong
FROM
PostalCode
WHERE
PostalCode = @Zip2
SELECT @Result = @Lat1.STDistance(@Lat2)
RETURN @Result/1000
END
希望这有帮助
答案 2 :(得分:0)
我建议引入一个单独的变量来保存点与缓冲区域的对比:
ALTER PROCEDURE [dbo].[GetZipCodesByDistance]
@point varchar(500),
@distance int
AS
BEGIN
SET NOCOUNT ON;
declare @geoPoint geography
set @geoPoint = geography::STGeomFromText('POINT (' + @point + ')', 4326);
declare @searchArea geography
set @searchArea = @geoPoint.STBuffer(@distance / 0.0006213712)
select zc.zip_id AS ZipId
,zc.zip_code AS ZipCodeId
,zc.zip_type AS ZipType
,zc.zip_city AS ZipCity
,zc.zip_utc AS ZipUtc
,zc.zip_dst AS ZipDst
,zc.zip_latitude AS ZipLatitude
,zc.zip_longitude AS ZipLongitude,
(Geo.MakeValid()).STDistance(@geoPoint)
FROM zip_code zc
where zc.Geo.STIntersects(@searchArea) = 1
我尝试添加列"(Geo.MakeValid())。STDistance(@geoPoint)"但它返回全零。
之前您正在计算找到的点与搜索区域之间的距离 - 当然我们已经建立(通过STIntersects
)他们&#39 ;在该地区内。所以我改变了一些事情,以便STDistance
调用使用的是点而不是区域。
(当然,我还建议,如果可能的话,更改存储过程的参数,以便您传递已经构造的geography
而不是字符串。但是这可能并不总是可能的)
答案 3 :(得分:0)
好吧,想办法让这项工作成功。
存储过程如下所示:
ALTER PROCEDURE [dbo].[GetZipCodesByDistance] @point VARCHAR(500),
@distance INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @geoPoint GEOGRAPHY
SET @geoPoint = GEOGRAPHY::STGeomFromText('POINT (' + @point + ')', 4326);
DECLARE @searchArea GEOGRAPHY
SET @searchArea = @geoPoint.STBuffer(@distance / 0.0006213712)
DECLARE @ZipDistance TABLE(
ZipCode VARCHAR(5),
ZipLatitude DECIMAL(9,6),
ZipLongitude DECIMAL(9,6),
Distance DECIMAL(9,2)
)
INSERT INTO @ZipDistance
SELECT
zc.zip_code AS ZipCode
,zc.zip_latitude AS ZipLatitude
,zc.zip_longitude AS ZipLongitude
,CAST((((Geo.MakeValid()).STDistance(@geoPoint))/1609.34) AS DECIMAL(9,2)) AS Distance
FROM zip_code zc
WHERE zc.Geo.STIntersects(@searchArea) = 1
SELECT * FROM @ZipDistance
END
然后我创建了一个模型:
public class ZipCodeWithDistance
{
public string ZipCode { get; set; }
public decimal ZipLatitude { get; set; }
public decimal ZipLongitude { get; set; }
public decimal Distance { get; set; }
}
在DbContext中,我有以下内容:
public List<ZipCodeWithDistance> GetZipCodes(string point, int distance)
{
var zipCodes = this.Database.SqlQuery<ZipCodeWithDistance>(
"GetZipCodesByDistance @point, @distance",
new SqlParameter("point", point),
new SqlParameter("distance", distance)
).ToList();
return zipCodes;
}
在FacilityModel中,我有:
[NotMapped]
public decimal Distance { get; set; }
最后,在服务中,我有以下内容:
public IQueryable<Facility>GetFacilitiesByZipCodes(List<ZipCodeWithDistance> zipCodes)
{
var zipCodeName = zipCodes.Select(x => x.ZipCode).ToList();
var facilities = oandpDbContext.Facilities.Where(x => zipCodeName.Contains(x.ZipCode.Substring(0, 5))).ToList();
facilities.ForEach(x =>
{
var zip = zipCodes.FirstOrDefault(y => y.ZipCode == x.ZipCode.Substring(0, 5));
if (zip != null)
{
x.Distance = zip.Distance;
}
});
return facilities.AsQueryable();
}
不确定它是否是完成此操作的最佳/最有效方式,但它确实有效。欢迎任何想法或意见!谢谢,AJ