Rasters, Pixels and Code Oh My!<\/A> heb ik een automatiseringstrigger uitgebreid om een attribuutveld te vullen op basis van de locatie binnen een rasterpixel. Maar ik wil nog meer data-automatisering. Ik wil het allemaal!<\/P>
We willen niet alleen enkele administratieve attributen van nieuwe datapunten weten (in welke county, staat bevindt het zich?: Spatial Intersect), hoe hoog het is, maar in een tijdperk van niet-zo-precieze datapunten, wat is het dichtstbijzijnde punt bij dit punt?<\/P>
<\/P>
In deze specifieke toepassing, een dataset voor waterkwaliteitsmonitoring, wil ik ook de naam weten van de stroom waarop dit punt zich bevindt, evenals de stroomorde. Ik gebruik NHD Stream Lines die door Arc Hydro zijn verwerkt om Strahler Stream Order als attribuut toe te voegen.<\/P>
<\/P>
Met behulp van een Nearest Neighbor Query kan ik dat bereiken, zij het met iets meer complexiteit omdat ik nu SQL vraag om naar het "Nearest" object te zoeken, en niet een eenvoudige intersectie van twee geografische objecten. Het codeblok begint op regel 48.<\/P>
<\/P>
<\/P>
<\/P>
ALTER TRIGGER [dbo].[TEST_GEOGRAPHY]
ON [dbo].[TEST]
\/****** trigger activeren bij inserts en updates ******\/
\/****** trigger uitschakelen wanneer SQL replicatie of mirroring is ingeschakeld ******\/
after INSERT,UPDATE NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
UPDATE p SET
\/****** hypothetisch zouden we de lat\/lon als tekst kunnen invoeren en een geography-object kunnen maken ******\/
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,
\/****** gebruikelijke situatie: punt wordt gemaakt met ARC en cast de LAT\/LON als tekst ******\/
\/****** vanuit het geography-object ******\/
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
\/****** lat\/lon bijwerken bij update toegestaan ******\/
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 ;lt;br /& ;gt;
FROM dbo.NHDFLOWLINE
\/****** force spatial index hint ******\/
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 ;lt;br />
WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& ;amp ;amp ;amp ;amp ;amp ;amp ;amp ;amp ;amp ;amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ; amp ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as g
CROSS APPLY (SELECT TOP 1 RiverOrder, shape& ;;lt;br />
FROM dbo.NHDFLOWLINE
\/****** force spatial index hint ******\/
WITH(index ([S208_idx]))<br />
WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as h
& ;;lt;br />
END
GO<\/PRE><\/P>Let op het gebruik van een indexhint hier. In SQL 2008 wordt het gebruik van de spatial index niet gerespecteerd en werkt het zelfs niet zonder veel aanpassingen. Hier vertellen we het om de naam van de dichtstbijzijnde stroom en de orde ervan te vinden, maar gebruik de spatial index van de NHD Flowline feature class om de query te optimaliseren. Zonder de indexhint duurt deze query eeuwig!<\/P><\/P>Als de stroomnaam null is (zoals bij velen het geval is), stoppen de crossapply- en order by-instructies de zoekopdracht bij de dichtstbijzijnde stroom in plaats van te zoeken naar de dichtstbijzijnde benoemde stroom.<\/P><\/P>Ik heb gemerkt dat dit het beste werkt wanneer ik enkele regels voor gegevensinvoer afdwing: voeg een nieuw punt alleen toe met behulp van snapping (aan de NHD-laag in de kaartinterface). Er bestaat het gevaar dat iemand per ongeluk een nieuw punt toevoegt dat "enigszins" tussen twee stromen ligt, en dat de verkeerde naam en orde aan het punt worden toegekend.<\/P><\/P>In deze specifieke toepassing gebruiken we het in combinatie met de USGS HEM-tools, die het snappen, toewijzen en vullen van reachcode aan de puntgegevens afhandelen, dus we maken ons niet zo druk over het scenario waarbij een punt op de verkeerde plaats staat.<\/P><\/P>Dit is een persoonlijke blog en beveelt de hierboven beschreven methoden niet aan, onderschrijft ze niet en ondersteunt ze niet. Het wijzigen van gegevens met SQL buiten de ESRI softwarestack wordt uiteraard niet ondersteund en mag niet worden toegepast op een productie-database zonder grondig begrip en een rampenherstelplan.<\/EM><\/P><\/BODY><\/HTML>