首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用坐标和方位角在PostGis中建立扇形楔(扇形)?

如何用坐标和方位角在PostGis中建立扇形楔(扇形)?
EN

Stack Overflow用户
提问于 2022-07-20 11:45:07
回答 2查看 185关注 0票数 2

我找不到正确的答案,试图在PostGis中创建函数,该函数返回几何类型的多边形。该函数可用于在地图上可视化蜂窝网络拓扑结构。下面你可以找到PostGis的这个函数,它有下一个输入参数: lon,lat,方位,距离,宽度。馅饼的距离长度;馅饼的宽度。

代码语言:javascript
复制
create or replace function sector_3(lon float, lat float, azimuth float, distance integer, width integer)
returns geometry
language plpgsql
as
$$
declare
   sector geometry;
begin
    sector = ST_MakePolygon(ST_MakeLine(ARRAY[ST_SetSRID(ST_MakePoint(lon,lat),4326),
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth-(width/2))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth-(width/2-1*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth-(width/2-2*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth-(width/2-3*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth-(width/2-4*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth)/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth+(width/2-4*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth+(width/2-3*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth+(width/2-2*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth+(width/2-1*(width/2/5)))/180.0)::geometry,
                ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, pi()*(azimuth+(width/2))/180.0)::geometry,                                   
                ST_SetSRID(ST_MakePoint(lon,lat),4326)  
                     ]));
   return sector;
end;
$$;

因此,您将看到扇区,它从给定的点(龙,lat)和给定的距离(长度)和宽度开始。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-22 12:29:55

您可以通过首先使用distancelonlat参数创建缓冲区来稍微简化一些事情,这样您就已经有了想要的内容。第二步是删除所需缓冲区的一部分,您可以使用ST_Split完成这一操作。函数ST_Split需要一个几何和一个刀片来切割几何,这个刀片可以根据缓冲区的中心点(参考坐标对)、azimuthdistance创建为一个LineString,使用ST_Project。此时,您有两个几何图形--您想要的区域和缓冲区的其余部分--因此您可以使用ST_GeometryN只返回您感兴趣的区域:

代码语言:javascript
复制
WITH j (geom,azimuth,distance,width) AS (
  VALUES (ST_SetSRID(ST_MakePoint(38.94,45.05),4326),90,120,40)
)
SELECT  
  ST_GeometryN(
    ST_Split(
      ST_Buffer(geom::geography,distance)::geometry,
      ST_MakeLine(ARRAY[
        ST_Project(geom,distance+1,radians(azimuth-(width/2)))::geometry, geom,
        ST_Project(geom,distance+1,radians(azimuth+(width/2)))::geometry]
      )
   ),2)
FROM j;

演示:db<>fiddle

为了更好地说明所提出的解决方案,下一个查询将在三个不同的CTE中描述缓冲区、投影点和基于它们创建的刀片。

代码语言:javascript
复制
WITH 
  original_values (geom,azimuth,distance,width) AS (
    VALUES (ST_SetSRID(ST_MakePoint(38.94,45.05),4326),90,120,40)), 
  points (array_points) AS (
    SELECT ARRAY[
      ST_Project(geom,distance+1,radians(azimuth-(width/2)))::geometry, geom,
      ST_Project(geom,distance+1,radians(azimuth+(width/2)))::geometry] 
    FROM original_values),
  line (blade) AS (
    SELECT ST_MakeLine(array_points) 
    FROM points),
  area (buffer) AS (
    SELECT ST_Buffer(geom::geography,distance) 
    FROM original_values   
  ) 
SELECT buffer FROM area
UNION
SELECT unnest(array_points) FROM points 
UNION 
SELECT blade FROM line;

票数 2
EN

Stack Overflow用户

发布于 2022-10-06 06:09:45

代码语言:javascript
复制
create or replace function sector_make(lon float, lat float, azimuth float, distance integer, width integer)
returns geometry
language plpgsql
as
$$
declare
   sector geometry;
   i integer;
 begin
  sector =  ST_SetSRID(ST_MakePoint(lon,lat),4326);  
    for i in  (select 0-width/2)..(select width/2) 
    loop
        sector=ST_UNION(sector,ST_Project(ST_SetSRID(ST_MakePoint(lon,lat),4326)::geography, distance, radians(azimuth+i))::geometry);
    end loop;    
 return ST_MakePolygon(ST_MakeLine(ARRAY[sector,ST_SetSRID(ST_MakePoint(lon,lat),4326)]));
end;
$$;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73051042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档