3

どこかからpostgisデータベースのラインストリングフィールドに〜1000個のパスをインポートしました。

編集)私のテーブルはこのようなものです

+---------+---------------+------------------+
| id(int) | name(varchar) | path(LINESTRING) |
+---------+---------------+------------------+
| 123     | foo           | 000002...        |
| 124     | bar           | 000002...        |

各パスがチャンクに分割され、場合によってはそれらのチャンクが混在するという問題がありました。

ポイント番号 50 と 70 で分割された線ストリングを想定します。

  1. チャンク A: ポイント 1 ~ 50
  2. チャンク B: ポイント 51 ~ 70
  3. チャンク C: ポイント 71-100

それをデータベースに移行したところ、それらが混在したため、結果の折れ線は次のようになります。

  1. チャンク A: ポイント 1 ~ 50
  2. チャンク C: ポイント 71-100
  3. チャンク B: ポイント 51 ~ 70

これにより、50 から 71 へのジャンプと、100 から 51 へのジャンプが生成されます。

(編集) これらのパスをチャンクに分割してインポートしたとき、それらは順序付けられていると思いましたが、実際にはいくつかが混在していたため、2 番目の例のようにポイントが順序付けられた線ストリングがいくつか作成されました。

これらのチャンク (ポイントの) を並べ替えられるようにしたいので、ポイントが混在しているパスを検出する SQL クエリを作成し、手動で (openlayers を使用して作成されたツールを使用して) それらを並べ替えることができます。

この問題を解決するには、SQL 更新クエリを使用することが望ましいですが、検出はより簡単だと思います (エラーのあるパスは ~5% 以下であると推測されます)。

EDIT3:パスにあまりにも離れた連続したポイントのペアが含まれているかどうかを検出用のスクリプトで確認できると思います。おそらく、最長のセグメントを含むパスからパスを並べ替える SQL が良いでしょう。

ラインストリングの最大セグメントの長さを取得する関数を作成するにはどうすればよいですか?

ここに例を示します。これはデータベース内の様子です 悪い方法

こうやって直してほしい 良い(固定された)方法

EDIT4 : EDIT3 で計画したように、 ST_NPoints()ST_PointN( )を使用して線ストリングのポイントを反復処理する線ストリング内の 2 つの連続するポイント間の最長距離を見つける関数を作成し、パスを並べ替えるクエリを作成できます。その最長距離で。この距離が長すぎる線ストリングが、説明されている問題を引き起こす可能性が非常に高くなります。そうすれば、それらを検出して手動で修正できます。

検出 SQL の結果は次のようになります。

                                             |ordered by this|
+---------+---------------+------------------+---------------+
| id(int) | name(varchar) | path(LINESTRING) |  msbtcp(int)  |
+---------+---------------+------------------+---------------+
| 123     | foo           | 000002...        | 1000          |
| 124     | bar           | 000002...        | 800           |

*msbtcp は次の関数の結果です。max_separation_between_two_consecutive_points(path)

4

2 に答える 2

3

これは少し複雑に聞こえますが、線ストリング内の 2 つの連続するポイント間の最大距離の直後にいる場合は、次のようになります。

CREATE OR REPLACE FUNCTION max_distance_in_linestring(line geometry) RETURNS float as $BODY$
DECLARE
    i integer;
    n integer;
    d float;
    m float;
BEGIN
    d := 0;
    n := ST_NPoints(line);
    i := 2;
    LOOP
        EXIT WHEN i >= n;
        m := ST_Distance(ST_PointN(line,i-1),ST_PointN(line,i));
        -- use for lon,lats:
        -- m := ST_Distance(ST_PointN(line,i-1)::geography,ST_PointN(line,i)::geography);
        IF m > d THEN
            d := m;
        END IF;
        i := i + 1;
    END LOOP;
    RETURN d;
END;
$BODY$
LANGUAGE plpgsql;

SELECT max_distance_in_linestring('LINESTRING(0 0, 1 1, 2 2)'::geometry);
SELECT max_distance_in_linestring('LINESTRING(0 0, 4 3, 2 2)'::geometry);

距離をメートル単位で取得するために、ST_PointN 呼び出しを ::geography に再キャストすることをお勧めします。

SQL は次のようになります。

SELECT
  name, path 
FROM
  paths
ORDER BY
  max_distance_in_linestring(path) DESC
于 2012-04-25T11:13:20.367 に答える
0

知りたいのは、セグメントがどのようにリンクされているかです。したがって、各セグメントの最初と最後のポイントを他のすべてのセグメントと比較する必要があります。

SELECT foo.gid as segment_a, bar.gid as segment_b
    FROM 
        segments AS foo, 
        (SELECT the_geom, gid FROM segments) AS bar
    WHERE 
        bar.gid != foo.gid AND ( -- avoid same segments  
        ST_DWithin( 
                ST_GeometryN(foo.the_geom,  ST_NumGeometries(foo.the_geom)) , -- last from foo
                ST_GeometryN(bar.the_geom,  ST_NumGeometries(bar.the_geom)) , -- last from bar
                0.00005 ) OR -- precision, depends of your SRID
        ST_DWithin( 
                ST_GeometryN(foo.the_geom,  1) , -- first from foo (start = 1 index)
                ST_GeometryN(bar.the_geom,  ST_NumGeometries(bar.the_geom)) , -- last from bar
                0.00005 ) OR -- precision, depends of your SRID
        ST_DWithin( 
                ST_GeometryN(foo.the_geom,  ST_NumGeometries(foo.the_geom)) , -- last from foo
                ST_GeometryN(bar.the_geom,  1) , -- first from bar
                0.00005 ) OR -- precision, depends of your SRID
        ST_DWithin( 
                ST_GeometryN(foo.the_geom,  1) , -- first from foo 
                ST_GeometryN(bar.the_geom,  1) , -- first from bar
                0.00005 ) ) -- precision, depends of your SRID

voilà...!このリンクを新しいテーブルに保存し、リンクされたセグメントをST_Unionで結合できます。

于 2012-04-18T15:56:57.073 に答える