5

私は問題を抱えています。皆さんが私を解決するのを手伝ってくれることを願っています.

DbGeometry ポイント (または DbGeography、両方を使用できます) を取得しました。これが DbGeometry ポリゴン (または DbGeography) 内にあるかどうかを確認したいと思います。

私は現時点でこれをやっています:

var dbZones = new List<WasteManager.Database.Zone>();
foreach(var zone in zones)
        {
            var res = from z in DatabaseContext.Zones
                   let boundary =
                       !z.BoundaryGeometry.IsValid
                           ? SqlSpatialFunctions.MakeValid(z.BoundaryGeometry)
                           : z.BoundaryGeometry
                      where z.ID == zone.ID && point.Within(boundary)
                      select z;

            if(res.FirstOrDefault() != null) dbZones.Add(res.FirstOrDefault());

        }

したがって、ゾーン (db の EF エンティティ) を反復処理し、このポイントがこの境界内にあるかどうかを確認します。

問題は結果が返されないことですが、境界とその境界内にあるポイントを手動で作成したため、そのポイントがその境界内にあることがわかります。

私がやっていることが間違っているかどうか、これを行う別の方法があるかどうか、誰か教えてもらえますか?

とても感謝しています。

マヌエル

4

3 に答える 3

8

Nick Strupat にコメントを追加したいと思います。

リングの向きには注意が必要です。SQL Server では左利きの方向が使用されます。つまり、多角形の周囲に沿って歩く場合、左手が多角形の内側にあり、右手が外側にある必要があります (反時計回りまたは反時計回り)。ポリゴンを反対方向 (時計回りまたは右回り) に描画したため、「リングの向き」エラーが発生しました。これは、SQL Server がポリゴンを除いて地球の表面全体をポリゴンの領域として扱っていたことを意味します。

point.Intersects(polygon)ポイントがポリゴン内にあるかどうかを確認するには、ではなくを常に使用する必要があります!point.Intersects(polygon)

エリアのサイズを確認することで、ポリゴンが正常かどうかを確認する解決策があります。詳細については、次を参照してください。

https://blog.falafel.com/ring-orientation-sql-spatial/

ブログの説明に基づく私のコードは次のとおりです。

    private bool isInside(DbGeography polygon, double longitude, double latitude)
    {
        DbGeography point = DbGeography.FromText(string.Format("POINT({1} {0})", latitude.ToString().Replace(',', '.'), longitude.ToString().Replace(',','.')), DbGeography.DefaultCoordinateSystemId);

        // If the polygon area is larger than an earth hemisphere (510 Trillion m2 / 2), we know it needs to be fixed
        if (polygon.Area.HasValue && polygon.Area.Value > 255000000000000L)
        {
            // Convert our DbGeography polygon into a SqlGeography object for the ReorientObject() call
            SqlGeography sqlPolygon = SqlGeography.STGeomFromWKB(new System.Data.SqlTypes.SqlBytes(polygon.AsBinary()), DbGeography.DefaultCoordinateSystemId);

            // ReorientObject will flip the polygon so the outside becomes the inside
            sqlPolygon = sqlPolygon.ReorientObject();

            // Convert the SqlGeography object back into DbGeography
            polygon = DbGeography.FromBinary(sqlPolygon.STAsBinary().Value);

        }
        return point.Intersects(polygon);
    }
于 2017-06-22T09:58:08.480 に答える