Rasters, Pixels and Code Oh My!<\/A> jsem rozšířil spouštěč automatizace, aby vyplnil atributové pole na základě jeho umístění v rámci raster pixelu. Ale stále chci více automatizace dat. Chci to všechno!<\/P>
Nejenže chceme znát některé administrativní atributy nových datových bodů (v jakém okrese, státě se nachází?: Spatial Intersect), jak vysoko je, ale v době méně přesných datových bodů, co je nejblíže tomuto bodu?<\/P>
<\/P>
V této konkrétní aplikaci, datasetu monitorování kvality vody, také chci znát název potoka, na kterém se tento bod nachází, stejně jako pořadí potoka. Používám NHD Stream Lines, které byly zpracovány pomocí Arc Hydro pro přidání Strahler Stream Order jako atributu.<\/P>
<\/P>
Použitím Nearest Neighbor Query to mohu dosáhnout, byť s trochu větší složitostí, protože nyní žádám SQL, aby hledal "Nearest" prvek, a ne jednoduchý průnik dvou geografických objektů. Blok kódu začíná na řádku 48.<\/P>
<\/P>
<\/P>
<\/P>
ALTER TRIGGER [dbo].[TEST_GEOGRAPHY]
ON [dbo].[TEST]
\/****** spustit při vkládání a aktualizacích ******\/
\/****** deaktivovat spouštěč při povolené SQL replikaci nebo zrcadlení ******\/
after INSERT,UPDATE NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
UPDATE p SET
\/****** hypoteticky bychom mohli zadat lat\/lon jako text a vytvořit geografický objekt ******\/
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,
\/****** obvyklý případ bod je vytvořen ARC a převádí LAT\/LON jako text ******\/
\/****** z geografického objektu ******\/
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
\/****** povolit aktualizaci lat\/lon při aktualizaci ******\/
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 ; LEFT OUTER JOIN GRSM_States AS e
& nbsp ;& nbsp ; ON e.Shape.STIntersects(i.Shape) = 1
& nbsp ;& nbsp ; 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 & nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;
FROM dbo.NHDFLOWLINE
\/****** vynutit nápovědu prostorového indexu ******\/
WITH(index ([S208_idx])) & nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nb sp ; & nb sp ; & nb sp ; & nb sp;
WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& nb sp ; & nb sp ; & nb sp ; & nb sp ; & nb sp ; & nb sp ; & nb sp ; & nb sp;
ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as g
CROSS APPLY (SELECT TOP 1 RiverOrder, shape & nb sp;
FROM dbo.NHDFLOWLINE
\/****** vynutit nápovědu prostorového indexu ******\/
WITH(index ([S208_idx])) & nb sp;
WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& nb sp;
ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as h
& nb sp;;
END
GO<\/PRE><\/P>Poznámka k použití nápovědy indexu zde. V SQL 2008 není použití prostorového indexu respektováno a ve skutečnosti bez mnoha úprav nefunguje. Zde mu říkáme najít název nejbližšího potoka a jeho pořadí, ale použít prostorový index třídy prvků NHD Flowline k optimalizaci dotazu. Bez nápovědy indexu tento dotaz trvá věčnost!<\/P><\/P>Pokud je název potoka null (jako mnoho z nich), příkazy crossapply a order by zastaví hledání u nejbližšího potoka místo hledání nejbližšího pojmenovaného potoka.<\/P><\/P>Zjistil jsem, že to funguje nejlépe, když vynutím některá pravidla zadávání dat: přidat nový bod pouze pomocí přichytávání (k vrstvě NHD v mapovém rozhraní). Existuje nebezpečí, že někdo by mohl omylem přidat nový bod, který je "nějak" mezi dvěma potoky a nesprávný název a pořadí by mohly být přiřazeny k bodu.<\/P><\/P>V této konkrétní aplikaci jej používáme ve spojení s nástroji USGS HEM, které zajišťují přichytávání, přiřazení a vyplnění reachcode do datových bodů, takže se příliš nebojíme scénáře nesprávného bodu na nesprávném místě.<\/P><\/P>Toto je osobní blog a nedoporučuje, nepodporuje ani nepodporuje výše popsané metody. Úprava dat pomocí SQL mimo ESRI software samozřejmě není podporována a neměla by být aplikována na produkční databázi bez důkladného pochopení a plánu obnovy po havárii.<\/EM><\/P><\/BODY><\/HTML>