Rasters, Pixels and Code Oh My!<\/A> j'ai étendu un déclencheur d'automatisation pour remplir un champ d'attribut en fonction de sa position dans un pixel raster. Mais je veux encore plus d'automatisation des données. Je veux tout !<\/P>
Nous ne voulons pas seulement connaître certains attributs administratifs des nouveaux points de données (dans quel comté, état se trouve-t-il ? : Spatial Intersect), à quelle hauteur il se trouve, mais à une époque où les points de données ne sont pas très précis, qu'est-ce qui est le plus proche de ce point ?<\/P>
<\/P>
Dans cette application particulière, un ensemble de données de surveillance de la qualité de l'eau, je veux aussi connaître le nom du cours d'eau sur lequel ce point se trouve, ainsi que l'ordre du cours d'eau. J'utilise NHD Stream Lines qui ont été traitées avec Arc Hydro pour ajouter l'attribut Strahler Stream Order.<\/P>
<\/P>
En utilisant une requête Nearest Neighbor, je peux accomplir cela, bien que cela soit un peu plus complexe car maintenant je demande à SQL de chercher la caractéristique "Nearest", et non une simple intersection de deux objets géographiques. Le bloc de code commence à la ligne 48.<\/P>
<\/P>
<\/P>
<\/P>
ALTER TRIGGER [dbo].[TEST_GEOGRAPHY]
ON [dbo].[TEST]
\/****** déclencher lors des insertions et mises à jour ******\/
\/****** désactiver le déclencheur lorsque la réplication ou le mirroring SQL est activé ******\/
après INSERT,UPDATE NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
UPDATE p SET
\/****** hypothétiquement nous pourrions entrer la lat\/lon en texte et créer un objet 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,
\/****** cas habituel où le point est créé avec ARC et convertit la LAT\/LON en texte ******\/
\/****** à partir de l'objet 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
\/****** permettre la mise à jour de lat\/lon lors de la mise à jour ******\/
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 ; 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
\/****** forcer l'indice spatial ******\/
WITH(index ([S208_idx])) & nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;
WHERE NHDFLOWLINE.Shape.STDistance(i.Shape) IS NOT NULL
& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& nbsp ;& 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;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;;
FROM dbo.NHDFLOWLINE
\/****** forcer l'indice spatial ******\/
WITH(index ([S208_idx])) & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & nb sp;; & 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;; ORDER BY NHDFLOWLINE.Shape.STDistance(i.Shape) ASC) as h
& nbsp ;;
END
GO<\/PRE><\/P>Notez l'utilisation d'un indice ici. Dans SQL 2008, l'utilisation de l'indice spatial n'est pas prise en compte et en fait ne fonctionne pas sans beaucoup d'ajustements. Ici, nous lui disons de trouver le nom du cours d'eau le plus proche et son ordre, mais d'utiliser l'indice spatial de la classe d'entités NHD Flowline pour optimiser la requête. Sans cet indice, cette requête prend une éternité !<\/P><\/P>Si le nom du cours d'eau est nul (comme c'est souvent le cas), les instructions crossapply et order by arrêtent la recherche au cours d'eau le plus proche au lieu de chercher le cours d'eau nommé le plus proche.<\/P><\/P>J'ai constaté que cela fonctionne mieux lorsque j'applique certaines règles de saisie des données : ajouter un nouveau point uniquement en utilisant le snapping (à la couche NHD dans l'interface cartographique). Il y a un risque que quelqu'un ajoute par erreur un nouveau point qui est "un peu" entre deux cours d'eau, et que le mauvais nom et ordre soient attribués au point.<\/P><\/P>Dans cette application particulière, nous l'utilisons conjointement avec les outils USGS HEM, qui gèrent le snapping, l'attribution et la population du reachcode aux données ponctuelles, donc nous ne sommes pas trop inquiets du scénario du mauvais point au mauvais endroit.<\/P><\/P>Ceci est un blog personnel et ne recommande pas, n'endosse pas et ne soutient pas les méthodes décrites ci-dessus. La modification des données en utilisant SQL en dehors de la suite logicielle ESRI n'est bien sûr pas prise en charge et ne doit pas être appliquée à une base de données de production sans une compréhension approfondie et un plan de reprise après sinistre.<\/EM><\/P><\/BODY><\/HTML>