Postgresql PostGIS:查找距离给定点最近的几何体

Postgresql PostGIS:查找距离给定点最近的几何体,postgresql,geolocation,openlayers,geospatial,postgis,Postgresql,Geolocation,Openlayers,Geospatial,Postgis,假设我的数据库中有很多几何图形。我想在PostgreSQL中创建一个函数,通过该函数,我可以传入一个lat/long,并让它返回给定半径下距离最近的几何体(线性和公路) 我是这方面的新手,所以任何建议都非常感谢 我正在运行以下版本: PostgreSQL:9.2 PostGIS:2.0 以下是模式: -- ---------------------------- -- Table structure for "cities-usa" -- -------------------------

假设我的数据库中有很多几何图形。我想在PostgreSQL中创建一个函数,通过该函数,我可以传入一个lat/long,并让它返回给定半径下距离最近的几何体(线性和公路)

我是这方面的新手,所以任何建议都非常感谢

我正在运行以下版本:

  • PostgreSQL:9.2
  • PostGIS:2.0
以下是模式:

-- ----------------------------
--  Table structure for "cities-usa"
-- ----------------------------
DROP TABLE IF EXISTS "cities-usa";
CREATE TABLE "cities-usa" (
"gid" int4 NOT NULL DEFAULT nextval('"cities-usa_gid_seq"'::regclass),
"st_fips" varchar(4),
"sfips" varchar(2),
"county_fip" varchar(4),
"cfips" varchar(4),
"pl_fips" varchar(7),
"id" varchar(20),
"name" varchar(39),
"elevation" varchar(60),
"pop_1990" numeric,
"population" varchar(30),
"st" varchar(6),
"state" varchar(16),
"warngenlev" varchar(16),
"warngentyp" varchar(16),
"watch_warn" varchar(3),
"zwatch_war" float8,
"prog_disc" int4,
"zprog_disc" float8,
"comboflag" float8,
"land_water" varchar(16),
"recnum" float8,
"lon" float8,
"lat" float8,
"geom" "geometry"
)
WITH (OIDS=FALSE);
ALTER TABLE "cities-usa" OWNER TO "postgres";

-- ----------------------------
--  Primary key structure for table "cities-usa"
-- ----------------------------
ALTER TABLE "cities-usa" ADD CONSTRAINT "cities-usa_pkey" PRIMARY KEY ("gid") NOT DEFERRABLE INITIALLY IMMEDIATE;

逻辑可以封装到函数中,但我建议使用查询来测试逻辑。您将遇到的困难是线性距离(英里)与角度坐标(纬度和经度)的结合。此外,上面指定的几何图形类型没有SRID或几何图形类型。我猜应该是
几何体(Point,4326)

您可以尝试一些策略,例如使用
地理
类型,该类型自动使用米来执行
ST_Distance
ST_DWithin
等功能。下面的示例只使用了
ST_Distance_Sphere
,并将英里转换为米,让您继续前进。或者,如果您需要性能,您可以尝试使用
功能进行测试

以下是您可以尝试的:

CREATE OR REPLACE FUNCTION WhatAmINear(lat float8, lon float8,
                                       radius_mi float8, num int DEFAULT 10)
    RETURNS SETOF "cities-usa" AS
$body$
SELECT *
FROM "cities-usa"
WHERE ST_Distance_Sphere(geom, ST_MakePoint(lon, lat)) <= radius_mi * 1609.34
LIMIT num;
$body$
LANGUAGE sql VOLATILE;

PostgreSQL和PostGIS版本?关于数据库模式的一些信息?请提供详细信息。对于模式,我有一个美国城市表,其中包括gid(int4)、st_fips(varchar(4)、county_fip(varchar)(varchar(4)、cfips varchar(4)、pl_fips varchar(7)、id varchar(20)、name varchar(39)、elevation varchar(60)、pop_1990数字、人口varchar(30)、st varchar(6)、州varchar(16)、warngenlev Vargenlev varchar(16)、warngentyp varchar(16),watch_warn varchar(3),zwatch_war float8,prog_disc int4,zprog_disc float8,comboflag float8,land_water varchar(16),recnum float8,lon float8,lat float8,geom geometry。@craig ringer,我想创建一个排序函数,我可以像WhatAmINear(lat,long,radius,num)那样调用它并让它返回给定半径内最近的num cities。例如,如果我将其称为WhatAmINear(lat1、lon1、100、5),它将返回半径为100英里内距离我所在位置最近的5个城市。如果在该范围内的城市少于5个,则仅返回这些城市。您似乎没有阅读我评论的第一部分。请编辑您的问题,并添加您在评论中添加的模式、您的版本以及任何其他您认为相关的信息。thanks,@craig ringer。我昨天确实输入了版本,但在保存时遇到问题。我一定是无意中删除了它们。版本和SQL都已发布。谢谢您的输入。
SELECT WhatAmINear(44.9, -93.1, 100);