Rasters, Pixels and Code Oh My!<\/A> では、ラスターのピクセル内の位置に基づいて属性フィールドを自動的に入力するトリガーを拡張しました。しかし、私はもっと多くのデータ自動化を望んでいます。すべて欲しいのです!<\/P>
新しいデータポイントのいくつかの管理属性(どの郡、州にあるか?:Spatial Intersect)、標高だけでなく、あまり正確でないデータポイントの時代に、このポイントに最も近いものは何かを知りたいのです。<\/P>
<\/P>
この特定のアプリケーション、水質モニタリングデータセットでは、このポイントが存在する川の名前とストリームオーダーも知りたいです。私は Arc Hydro を通して Strahler Stream Order を属性として追加した NHD Stream Lines を使用しています。<\/P>
<\/P>
Nearest Neighbor Query を使ってそれを達成できますが、今度は SQL に「Nearest」機能を探すように頼んでいるため、2つの地理オブジェクトの単純な交差ではなく、少し複雑になります。コードブロックは48行目から始まります。<\/P>
<\/P>
<\/P>
<\/P>
ALTER TRIGGER [dbo].[TEST_GEOGRAPHY]
ON [dbo].[TEST]
\/****** 挿入および更新時に発火 ******\/
\/****** SQL レプリケーションまたはミラーリングが有効な場合はトリガーを無効化 ******\/
after INSERT,UPDATE NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
UPDATE p SET
\/****** 仮に緯度経度をテキストとして入力し、geography オブジェクトを作成可能 ******\/
SHAPE = CASE WHEN i.SHAPE IS NOT NULL
THEN p.SHAPE ELSE Geography::STPointFromText('POINT('
+ CAST(p.LON AS VARCHAR(20)) + ' '
+ CAST(p.LAT AS VARCHAR(20)) + ')', 4269) END,
\/****** 通常は ARC でポイントが作成され、緯度経度をテキストとしてキャスト ******\/
\/****** geography オブジェクトから ******\/
LON = CASE WHEN p.SHAPE IS NULL THEN p.LON ELSE p.SHAPE.Long END,
LAT = CASE WHEN p.SHAPE IS NULL THEN p.LAT ELSE p.SHAPE.Lat END,
QuadName = COALESCE(b.name, p.QuadName),
Watershed = COALESCE(c.HUC_12_Name, p.Watershed),
County = COALESCE(d.Name, p.County),
State= COALESCE(e.Name, p.State),
PARKDISTRICT = COALESCE(f.District, p.PARKDISTRICT),
ELEVATION = (SELECT
pdata.getValueByLoc(1,p.SHAPE.Long,p.SHAPE.Lat) FROM [dbo].[DEM10MP]),
StreamName = COALESCE(g.GNIS_Name, p.StreamName),
RiverOrder = COALESCE(h.RiverOrder, p.RiverOrder)
FROM TEST
AS p
\/****** 更新時に緯度経度の更新を許可 ******\/
INNER JOIN
inserted AS i
ON i.globalid = p.globalid
LEFT OUTER JOIN USGS_24K_TOPOMAP_BOUNDARIES AS b
ON b.Shape.STIntersects(i.Shape) = 1
LEFT OUTER JOIN WATERSHEDS AS c
ON c.Shape.STIntersects(i.Shape) = 1
LEFT OUTER JOIN GRSM_COUNTIES AS d
ON d.Shape.STIntersects(i.Shape) = 1
& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ; LEFT OUTER JOIN GRSM_States AS e
ON e.Shape.STIntersects(i.Shape) = 1
LEFT OUTER JOIN GRSM_SUB_RANGER_DISTRICTS AS f
ON f.Shape.STIntersects(i.Shape) = 1
\/****** Nearest Neighbor ******\/
CROSS APPLY (SELECT TOP 1 GNIS_Name, shape&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;amp;;; FROM dbo.NHDFLOWLINE
\/****** 空間インデックスヒントを強制 ******\/
WITH(index ([S208_idx]))& amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ;; WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as g
CROSS APPLY (SELECT TOP 1 RiverOrder, shape& FROM dbo.NHDFLOWLINE
\/****** 空間インデックスヒントを強制 ******\/
WITH(index ([S208_idx]))& amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & amp & WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as h
& ;
END
GO<\/PRE><\/P>ここでインデックスヒントが使われていることに注意してください。SQL 2008では空間インデックスの使用が尊重されず、多くの調整なしには機能しません。ここでは最も近い川の名前とその順序を見つけるよう指示していますが、NHD Flowline フィーチャクラスの空間インデックスを使ってクエリを最適化しています。インデックスヒントなしではこのクエリは非常に時間がかかります!<\/P><\/P>川の名前が null の場合(多くの場合そうです)、crossapply と order by 文は名前付きの最も近い川を探す代わりに最も近い川で検索を停止します。<\/P><\/P>私はこれが最もうまく機能するのは、いくつかのデータ入力ルールを強制した場合だとわかりました:新しいポイントはスナッピング(マップインターフェース内の NHD レイヤーへの)を使ってのみ追加します。誰かが誤って2つの川の「やや」間に新しいポイントを追加してしまう危険性があり、そのポイントに誤った名前と順序が割り当てられる可能性があります。<\/P><\/P>この特定のアプリケーションでは、USGS HEM ツールと連携して使用しており、それがスナッピング、割り当て、およびリーチコードのポイントデータへの入力処理を行うため、誤った場所への誤ったポイントシナリオについてあまり心配していません。<\/P><\/P>これは個人ブログであり、上記で説明した方法を推奨、支持、または保証するものではありません。ESRI ソフトウェアスタック外で SQL を使用してデータを変更することはサポートされておらず、生産データベースに適用する場合は十分な理解と災害復旧計画が必要です。<\/EM><\/P><\/BODY><\/HTML>