update_links_reverse_cost.sh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/bin/bash
  2. # Lae keskkonnamuutujad
  3. source env.sh
  4. # --- Määrangud ---
  5. #CONNECTION_NAME="postgresql://osm@localhost:5432/data"
  6. BATCH_SIZE=10000
  7. # --- Lisa veerud kui neid ei ole ---
  8. echo "🧩 Kontrollin 'source', 'target', 'cost' olemasolu..."
  9. psql ${CONNECTION_NAME} <<EOF
  10. DO \$\$
  11. BEGIN
  12. IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = '${destination_schema}' AND table_name = 'links' AND column_name = 'source') THEN
  13. ALTER TABLE ${destination_schema}.links ADD COLUMN source bigint;
  14. END IF;
  15. IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = '${destination_schema}' AND table_name = 'links' AND column_name = 'target') THEN
  16. ALTER TABLE ${destination_schema}.links ADD COLUMN target bigint;
  17. END IF;
  18. IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = '${destination_schema}' AND table_name = 'links' AND column_name = 'cost') THEN
  19. ALTER TABLE ${destination_schema}.links ADD COLUMN cost double precision;
  20. END IF;
  21. IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = '${destination_schema}' AND table_name = 'links' AND column_name = 'reverse_cost') THEN
  22. ALTER TABLE ${destination_schema}.links ADD COLUMN reverse_cost double precision;
  23. END IF;
  24. END
  25. \$\$;
  26. EOF
  27. # --- Loo unlogged tabelid korraks ---
  28. echo "🔄 Valmistan ette punktide tabelid..."
  29. psql ${CONNECTION_NAME} <<EOF
  30. DROP TABLE IF EXISTS ${destination_schema}.tmp_nodes;
  31. CREATE UNLOGGED TABLE ${destination_schema}.tmp_nodes AS
  32. WITH all_points AS (
  33. SELECT ST_SnapToGrid(ST_StartPoint(geom), 0.01) AS geom FROM ${destination_schema}.links
  34. UNION
  35. SELECT ST_SnapToGrid(ST_EndPoint(geom), 0.01) AS geom FROM ${destination_schema}.links
  36. ),
  37. distinct_points AS (
  38. SELECT DISTINCT geom FROM all_points
  39. )
  40. SELECT ROW_NUMBER() OVER () AS id, geom FROM distinct_points;
  41. CREATE INDEX ON ${destination_schema}.tmp_nodes USING GIST (geom);
  42. DROP TABLE IF EXISTS ${destination_schema}.tmp_link_points;
  43. CREATE UNLOGGED TABLE ${destination_schema}.tmp_link_points AS
  44. SELECT
  45. id,
  46. ST_SnapToGrid(ST_StartPoint(geom), 0.01) AS pt_start,
  47. ST_SnapToGrid(ST_EndPoint(geom), 0.01) AS pt_end,
  48. geom
  49. FROM ${destination_schema}.links;
  50. CREATE INDEX ON ${destination_schema}.tmp_link_points USING GIST (pt_start);
  51. CREATE INDEX ON ${destination_schema}.tmp_link_points USING GIST (pt_end);
  52. EOF
  53. # --- Leia MAX_ID ---
  54. MAX_ID=$(psql ${CONNECTION_NAME} -tA -c "SELECT max(id) FROM ${destination_schema}.links;")
  55. echo "📏 MAX_ID = $MAX_ID"
  56. # --- Batch-töötlus ---
  57. i=1
  58. while [ "$i" -le "$MAX_ID" ]; do
  59. END=$((i + BATCH_SIZE - 1))
  60. echo "🚀 Töötlen batch: $i - $END"
  61. psql ${CONNECTION_NAME} -v schema="${destination_schema}" -v i="${i}" -v end="${END}" <<EOF
  62. WITH link_batch AS (
  63. SELECT * FROM :schema.tmp_link_points WHERE id BETWEEN :i AND :end
  64. ),
  65. link_data AS (
  66. SELECT
  67. l.id,
  68. n1.id AS source,
  69. n2.id AS target,
  70. ST_Length(l.geom) AS cost
  71. FROM link_batch l
  72. JOIN :schema.tmp_nodes n1
  73. ON ST_DWithin(l.pt_start, n1.geom, 0.01) AND ST_Distance(l.pt_start, n1.geom) = 0
  74. JOIN :schema.tmp_nodes n2
  75. ON ST_DWithin(l.pt_end, n2.geom, 0.01) AND ST_Distance(l.pt_end, n2.geom) = 0
  76. )
  77. UPDATE ${destination_schema}.links l
  78. SET source = d.source,
  79. target = d.target,
  80. cost = ROUND(d.cost::numeric, 1),
  81. reverse_cost = -1.0
  82. FROM link_data d
  83. WHERE l.id = d.id;
  84. EOF
  85. i=$((END + 1))
  86. done
  87. psql ${CONNECTION_NAME} -v schema="${destination_schema}" <<EOF
  88. -- Isolated lõikude eemaldamine
  89. DELETE FROM :schema.links l
  90. WHERE l.id IN (
  91. SELECT l1.id
  92. FROM :schema.links l1
  93. WHERE l1.source = l1.target
  94. OR l1.id IN (
  95. SELECT l2.id
  96. FROM :schema.links l2
  97. LEFT JOIN :schema.links_vertices_pgr v ON l2.source = v.id OR l2.target = v.id
  98. GROUP BY l2.id
  99. HAVING COUNT(DISTINCT v.id) = 1
  100. )
  101. );
  102. -- cost ja reverse_cost lisamine. Vajalik näiteks Dijkstra algoritmide jaoks.
  103. UPDATE :schema.links
  104. SET cost = ST_Length(geom),
  105. reverse_cost = CASE WHEN oneway = 1 THEN -1 ELSE ST_Length(geom) END;
  106. EOF
  107. echo "✅ Valmis!"