จุดเชื่อมต่อ (ป้ายรถเมล์) ซึ่งไม่อยู่บนเส้น (LINESTRING) ไปยังเครือข่าย


9

ฉันต้องเชื่อมต่อป้ายรถเมล์ (คะแนน) กับเลเยอร์เครือข่าย (ข้อมูล OSM) ป้ายรถเมล์เหล่านี้ไม่ได้อยู่บนเส้นตรง (ดูภาพหน้าจอ) และไม่ควรย้ายตำแหน่งของพวกเขา ฉันใช้ PostGIS, pgrouting และ QGIS และเครือข่ายสามารถกำหนดเส้นทางได้ด้วยแหล่งที่มาและคอลัมน์เป้าหมายเป็นต้น

ป้อนคำอธิบายรูปภาพที่นี่

ส่วนใหญ่ฉันต้องการที่จะทำสองสิ่งหลังจากนั้น:

  1. การหาระยะทางระหว่างบัสหยุดโดยใช้การวิเคราะห์เส้นทางที่สั้นที่สุด
  2. การสร้าง isochrones ด้วยระยะทางเดินจากป้ายรถเมล์โดยใช้เครือข่าย OSM

เพื่อให้ได้ค่าที่แน่นอนจำเป็นต้องมีการกำหนดเส้นทาง 'เริ่มต้น' และ 'หยุด' ใกล้กับป้ายรถเมล์ ในหลายกรณีโหนดที่ใกล้เคียงที่สุดจะอยู่ไกลเกินกว่าจะรับค่าที่แน่นอนได้ แต่ไม่ควรมีการกำหนดเส้นทางไปยังตำแหน่งจุดที่แท้จริงของป้ายรถเมล์ ในตัวอย่างของฉันในภาพคุณสามารถดูว่าการกำหนดเส้นทางระหว่างหยุดควรมีลักษณะอย่างไร

มีความเป็นไปได้ที่จะแทรกโหนดใหม่โดยอัตโนมัติในเครือข่าย (LINESTRING) ซึ่งอยู่ใกล้กับป้ายรถเมล์มากที่สุดหรือเป็นไปได้หรือไม่ที่จะเริ่มต้นการกำหนดเส้นทางใน 'จุดจำลอง' ที่ตั้งค่าไว้สำหรับแบบสอบถาม (คล้ายกับถนน) ปลั๊กอินกราฟใน QGIS ทำ)?

คำตอบ:


5

ส่วนแรกของการแก้ปัญหาคือ:

SELECT a.id, ST_Closestpoint(ST_Collect(b.geom_way), a.geom) AS geom 
FROM point_table a, line_table b
GROUP BY a.id, a.geom;

สิ่งนี้จะจับภาพป้ายรถประจำทางตามแนวถนนของเครือข่ายตามที่คุณเห็นในภาพและใช้งานได้ง่าย

ป้อนคำอธิบายรูปภาพที่นี่

ต่อไปฉันจะพยายามแบ่งบรรทัดตามตำแหน่งของคะแนน หลังจากแยกเส้นฉันต้องการใช้ pgr_createTopology อีกครั้ง หลังจากนั้นควรสร้างแบบสอบถามเพื่อค้นหาโหนดที่ใกล้ที่สุดไปยัง busstops ซึ่งจะเป็นโหนดที่สร้างขึ้นใหม่ของฉันที่ 'จุดแยก'

ฉันจะขอบคุณถ้าใครมีคำแนะนำสำหรับฉันวิธีแยก linestring กับคุณสมบัติจุดใน postgis เนื่องจากหลังจากที่ฉันดูคำถามที่คล้ายกันดูเหมือนจะไม่เป็นทางออกที่ง่ายสำหรับที่ในขณะนี้


ST_Split (บางสิ่งบางอย่างใบมีด)
simplexio

1
กำลังเพิ่มความคิดเห็นเพราะฉันไม่ได้ทดสอบสิ่งนี้เลย syntac อาจผิด ... ... เลือก *, st_split (a.lg, a.pg) จาก (เลือก *, lines.g เป็น lg, points.geom เป็น pg จากคะแนน เข้าร่วมสายใน ST_intersect (p.geom, l.geom)) เป็นเพียงการแบ่งคอลเล็กชั่นย้อนกลับเพื่อให้คุณยังคงต้องได้รับทุกบรรทัดจาก ...
simplexio

2

นี่คือทางออกทั้งหมดของฉัน มันเกี่ยวข้องกับการแฮ็คเพื่อแยกออก: ฉันได้รับคะแนนในบรรทัด (วิธีการใช้คำศัพท์ OSM) โดยใช้ST_ClosestPointแล้วบัฟเฟอร์พวกเขาด้วยระยะทางที่เล็กมากเพื่อให้การแยกใช้งานได้จริง มิฉะนั้นข้อผิดพลาดที่ไม่แน่นอน / การปัดเศษได้ป้องกันการแยก

นี่เป็นปัญหาที่ทำให้เกิดการแยกสองครั้งในแต่ละบรรทัดต่อจุด (เนื่องจากการบัฟเฟอร์) สำหรับการใช้งานของฉันนี่เป็นสิ่งที่ดีหลังจากนั้นฉันกำหนดเส้นทางระหว่างจุดแยกใกล้กับจุดเดิมซึ่งอยู่นอกบรรทัดและอาจเป็นหนึ่งในสองจุดแยกของจุดแยกบัฟเฟอร์บรรทัด

ฉันเริ่มต้นด้วยการดาวน์โหลดข้อมูล OSM และกำหนดให้เป็น Postgres:

CITY="MY_CITY"
BBOX="-46.6003,-23.7362,-46.4806,-23.5965"
wget --progress=dot:mega -O "$CITY.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"

# create database
createdb my_database
# add extensions
psql -d my_database -c "CREATE EXTENSION postgis;"
psql -d my_database -c "CREATE EXTENSION pgrouting;"

# import osm data to postgres database
osm2pgrouting \
    -f MY_CITY.osm \
    -d my_database \
    -U user

# load points into db
shp2pgsql -I -s 4326 points_to_split_ways.shp public.points_to_split_ways | psql -d my_database

แยกวิธีโดยใช้บัฟเฟอร์:

WITH pts_ways AS (
  -- get nearest way for each point we want to split the ways by
  SELECT s.gid AS pt_id, ws.gid AS way_gid, s.geom AS pt_geom, ws.the_geom AS way_geom FROM points_to_split_ways s
  CROSS JOIN LATERAL
  (
    SELECT w.gid, w.the_geom
    FROM ways w
    ORDER BY s.geom <-> w.the_geom LIMIT 1
  ) AS ws
), pts_on_ways AS (
  -- "move" these points to be on top of the ways
  SELECT pt_id, way_gid, ST_ClosestPoint(way_geom, pt_geom) as geom
  FROM pts_ways
), ways_without_pts AS (
  -- get the ways that don't have any points on them
  SELECT the_geom as the_geom, gid as way_gid FROM ways
  WHERE gid NOT IN (SELECT way_gid FROM pts_ways)
)
SELECT
  way_gid as old_id,
  -- we need to build a new unique ID, because split ways will share the old ID
  row_number() over(order by way_gid) as gid,
  -- this is the split way geometry
  the_geom
FROM (
  SELECT 
    way_gid,
    -- split the ways and dump into indiviudal segments
    (ST_Dump(ST_Split(line_geom, pt_geom))).geom AS the_geom
  FROM (
    (SELECT the_geom as line_geom, gid FROM ways) AS lines
    LEFT JOIN
    -- HACK: use a buffer to fix imprecisions / rounding errors
    -- this will generate one extra splitting per point (each buffer will intersect each way twice)
    -- but it's ok for our purposes
    -- also, collect them grouped by the way to handle cases where there are multiple points on the same way
    (SELECT ST_Collect(ST_Buffer(geom, 0.000001)) as pt_geom, way_gid FROM pts_on_ways GROUP BY way_gid) AS pts
    ON lines.gid = pts.way_gid
  ) AS tmp1
  -- union the ways without points, otherwise you'd get only the ones that were split
  UNION ALL
  SELECT way_gid, the_geom FROM ways_without_pts
) AS tmp2;

สร้างทอพอโลยีที่จำเป็นสำหรับการเราต์ด้วยการ pgrouting:

SELECT UpdateGeometrySRID('ways_split','the_geom', 4326);
SELECT find_srid('public','ways_split','the_geom');
ALTER TABLE ways_split ADD COLUMN "source" integer;
ALTER TABLE ways_split ADD COLUMN "target" integer;
ALTER TABLE ways_split ADD PRIMARY KEY (gid);
ALTER TABLE ways_split ADD CONSTRAINT ways_source_fkey FOREIGN KEY (source) REFERENCES ways_split_vertices_pgr (id) MATCH FULL;
ALTER TABLE ways_split ADD CONSTRAINT ways_target_fkey FOREIGN KEY (target) REFERENCES ways_split_vertices_pgr (id) MATCH FULL;
SELECT pgr_createTopology('ways_split', 0.00001, 'the_geom', 'gid', clean := TRUE);
SELECT pgr_analyzeGraph('ways_split', 0.000001, the_geom := 'the_geom', id := 'gid');

ความคิดแรกของฉันคือบัฟเฟอร์เช่นกัน แต่ถ้าคุณสามารถได้ 'ระยะทางที่ใกล้ที่สุด' บัฟเฟอร์จำนวนนั้นสร้างจุดที่จุดตัดนั้น ... จากนั้นคุณสามารถสร้างเส้นที่มีจุดสิ้นสุดที่ประกอบด้วยจุดเดิมของคุณและจุดที่ใกล้ที่สุด
Mox

1

เนื่องจากฉันกำลังทำงานที่คล้ายกันฉันแค่อยากจะบอกเกี่ยวกับวิธีการที่ฉันใช้อยู่ในปัจจุบัน สิ่งนี้ใช้ประโยชน์จาก GRASS GIS แต่เท่าที่การทดลองของฉันกับ PostGIS ดำเนินไปมันค่อนข้างซับซ้อนในการเพิ่มจุดใหม่หลาย ๆ จุดลงใน LineStrings ที่มีอยู่โดยแยก LineStrings เหล่านั้นตามตำแหน่งต่าง ๆ - แม้ว่าฉันจะมั่นใจว่ามีทางออกที่สะดวก

ตอนนี้ผมได้ใช้ GRASS ระบบสารสนเทศภูมิศาสตร์ฟังก์ชั่นใช้ตัวเลือกv.net connectเพียงแค่เลือกและinput vector line layer points layerมีตัวเลือกในการ snap จุดไปยังจุดที่ใกล้ที่สุดบนเส้นหรือเพื่อสร้างการเชื่อมต่อใหม่ระหว่างจุดที่ใกล้ที่สุดบนเส้นและจุดใหม่

นี่คือภาพก่อนและหลัง ทางด้านขวามือสำหรับแต่ละจุดของเลเยอร์จุดโหนดบนถนนเครือข่ายถูกเพิ่ม: ป้อนคำอธิบายรูปภาพที่นี่

หลังจากนั้นใน PostGIS หลังจากสร้าง..._vertices_pgrตารางของคุณออกจากเครือข่ายถนนเพียงกำหนดคะแนนของคุณไปยังจุดที่ใกล้ที่สุดเพื่อให้คุณสามารถใช้พวกเขาในคำขอเส้นทางของคุณ สำหรับภารกิจนี้คุณสามารถใช้ST_ClosestPointฟังก์ชั่นที่ทำโดย @Setraworks ในคำตอบของเขา

ข้อเสียของวิธีนี้คือ:

  • การเชื่อมต่อจุดที่มีเส้นจะต้องทำใน GRASS GIS
  • เส้นทางที่มีการคำนวณอาจประกอบด้วยองค์ประกอบมากมาย (ขึ้นอยู่กับปริมาณของคะแนนที่เพิ่มใหม่)
  • ไม่สามารถเพิ่มคะแนนใหม่ได้แบบไดนามิก

วิธีการนี้ใช้งานได้ดีหากคุณมีจำนวนคะแนนที่กำหนดไว้ในเครือข่ายถนน (เช่นในตัวอย่างของคำถามที่มีป้ายรถเมล์)

หากใครสามารถให้ตัวอย่างการทำงานโดยใช้ PostGIS ฉันชอบที่จะอ่านเกี่ยวกับเรื่องนี้!


0

มีโพสต์ที่กล่าวถึงปัญหาที่คล้ายกันคุณสามารถดูโพสต์ได้ที่ตำแหน่งต่อไปนี้: http://osdir.com/ml/qgis-user-gis/2011-11/msg00220.html


นี่เป็นเพียงส่วนหนึ่งของวิธีแก้ปัญหาที่เป็นไปได้เพราะหลังจากหักคะแนนไปที่บรรทัดแล้วคะแนนจะอยู่บนเส้นตรง แต่ก็ยังไม่ได้เป็นส่วนหนึ่งของเครือข่าย
Setraworks

หากคุณคาดหวังว่าจะได้รับคำตอบที่ตรงกับความต้องการของคุณคุณอาจผิดหวัง สิ่งนี้อาจทำให้คุณได้ครึ่งทางจากนั้นคุณสามารถมุ่งเน้นไปที่ส่วนอื่น ๆ ที่คุณขาดหายไป
Ryan Garnett

ฉันคิดว่าคุณพูดถูกไรอัน ฉันจัดการเพื่อดึงคะแนนไปยังบรรทัดดังนั้นขั้นตอนต่อไปคือการค้นหาวิธีการแบ่งการใช้งานด้วยคะแนนใน postgis ขอบคุณสำหรับความช่วยเหลือของคุณจนถึงตอนนี้!
Setraworks

ดีใจที่ฉันสามารถช่วย มีเครื่องมือที่จะแบ่งบรรทัดด้วยจุด แต่ฉันจะมองหาตัวเลือกใน PostGIS ขอให้โชคดี
Ryan Garnett

@Setraworks คุณอาจต้องการที่จะดูต่อไปนี้ PostGIS ตัวเลือก (ST_Split) postgis.net/docs/ST_Split.html คุณสามารถแบ่งบรรทัดด้วยจุดนี่คือคำอธิบายจาก PostGIS: ฟังก์ชั่นรองรับการแยกทีละบรรทัดทีละบรรทัดรูปหลายเหลี่ยมทีละบรรทัด เรขาคณิตที่คืนมาเป็นคอลเล็กชันเสมอ
Ryan Garnett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.