joindre des tables en fonction de l'emplacement<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Salut à tous
JMP peut-il joindre (mettre à jour) des tables en fonction de l'emplacement?
J'ai un ensemble de données de points avec des coordonnées et un fichier de formes de polygones. J'aimerais mettre à jour le tableau de données des points avec les informations du fichier de formes basé sur l'emplacement. Ainsi, si un point se trouve dans un polygone particulier, il mettra à jour la table avec les attributs du polygone.
Merci!
Ron
Re: joindre des tables en fonction de l'emplacementPour accélérer encore le script, vous pouvez vérifier si le point est en premier dans le carré "Amérique". Ajouter au script de Ian
inAmericaRect =
Fonction ({pMat, x, y}, {Local par défaut},
maxX = maximum (pMat [0, 3]);
minX = minimum (pMat [0, 3]);
maxY = maximum (pMat [0, 4]);
minY = minimum (pMat [0, 4]);
si ((x <= maxX) et (x> = minX) et (y <= maxY) et (y> = minY), 1, 0);
)
...
// Le point est-il à l'intérieur du Square of America?
si (inAmericaRect (pMat, x, y),
Bien sûr, étant donné Porto Rico, cela pourrait potentiellement ralentir le script en ajoutant une instruction if supplémentaire. Je pense toujours qu'il y a suffisamment de données à l'extérieur pour le justifier. Mais pour résoudre ce problème, vous pouvez simplement séparer Porto Rico ou d’autres îles et ajouter une fonction supplémentaire inPuertoRicoRect. Vous pouvez effectuer un filtrage supplémentaire pour d'autres pays en utilisant world-name.jmp et world-xy.jmp. Vous pouvez également utiliser les noms coastline-Name.jmp et coastline-xy.jmp pour déterminer d'abord si c'est à terre. Mais, je suis sûr qu'à ce stade, votre script sortira du cadre du projet.
Re: joindre des tables en fonction de l'emplacementJe vous remercie Ian @ JMP ,
c'est bien mieux que mon approche et beaucoup plus rapide.
Tout en produisant les boucles dans mon script, j’ai remarqué que la table XY n’était pas parfaitement propre et que votre approche était également robuste face à celle-ci (la forme ID 10 a une ID pièce 1,3,4,5 - en sautant 2).
Ron
Re: joindre des tables en fonction de l'emplacement8 heures et demie plus tard, le dossier complet des ouragans a été joint. comme la plupart des points sont dans la mer, le script a pris un certain temps pour vérifier que chacun d'entre eux ne se trouvait dans aucun des 52 États (84 polygones).

Re: joindre des tables en fonction de l'emplacementPar coïncidence, je viens de trouver le temps de jeter un coup d'œil. Je ne prétends pas à une efficacité améliorée, mais je ne l'offre que pour la comparaison. Je n'ai pas vérifié ou testé. Pour le sous-ensemble que vous utilisez, il s'exécute presque instantanément. Remarque la Chemins OS / X.
NamesDefaultToHere ( 1 ) ;
ClearLog () ;
// Ouvrir le fichier de points - cela inclut l'observation que nous voulons mettre à jour
des points = Ouvrir ( "$ SAMPLE_DATA / Hurricanes.jmp" ) ;
des points << supprimer des lignes ( des points << obtenir des rangées où ( : prénom ( "Nom et ID" ) ! = "NOTNAMED_675" ) ) ;
// Ouvrir la source d'un polygone
des polygones = Ouvrir ( "/ Bibliothèque / Application Support / JMP / 12 / Maps / US-State-XY.jmp" ) ;
// Open data source - Celui-ci contient les informations à mettre à jour.
des noms = Ouvrir ( "/ Bibliothèque / Application Support / JMP / 12 / Maps / US-State-Name.jmp" ) ;
// Étant donné un pMat 'matrice de polygones', ainsi qu'un identifiant de forme et un identifiant de pièce, détermine si le point (x, y) se trouve dans le polygone défini par cette forme et cette partie
inShapePart =
Une fonction ({ pMat , ID de forme , partID , X , y } , { Local par défaut } ,
r = Loc ( pMat [ 0 , 1 ] == ID de forme Et pMat [ 0 , 2 ] == partID ) ;
InPolygon ( X , y , pMat [ r , 3 ] , pMat [ r , 4 ]) ;
) ;
// Étant donné un pMat 'matrice polygonale', ainsi qu'un identifiant de forme et un identifiant de pièce, détermine si le point (x, y) se situe dans le rectangle inscrit par cette forme et cette partie
inShapePartRect =
Une fonction ({ pMat , ID de forme , partID , X , y } , { Local par défaut } ,
r = Loc ( pMat [ 0 , 1 ] == ID de forme Et pMat [ 0 , 2 ] == partID ) ;
maxX = Maximum ( pMat [ r , 3 ]) ;
friponne = Le minimum ( pMat [ r , 3 ]) ;
maxY = Maximum ( pMat [ r , 4 ]) ;
minY = Le minimum ( pMat [ r , 4 ]) ;
si ( ( X <= maxX ) Et ( X > = friponne ) Et ( y <= maxY ) Et ( y > = minY ) , 1 , 0 ) ;
) ;
pMat = des polygones << getAsMatrix ; // 'matrice polygonale'
X = Colonne ( des points , "Longitude" ) << getValues ; // x valeurs
y = Colonne ( des points , "Latitude" ) << getValues ; // y valeurs
loopLimits = des polygones << Résumé ( Groupe ( : ID de forme , : Partie ID ) , Invisible ) ;
ns = Maximum ( Colonne ( loopLimits , "ID de forme" ) << getValues ) ; // Nombre de formes
np = Colonne ( loopLimits , "Partie ID" ) << getValues ; // Nombre de pièces dans chaque forme
Fermer ( loopLimits , NoSave ) ;
Pour ( s = 1 , s <= ns , s ++, // Boucle sur les formes
Pour ( p = 1 , p <= np [ s ] , p ++, // Boucle sur les pièces
Pour ( ré = NRow ( X ) , ré > = 1 , ré - // Boucle sur les points
// Le point à l'intérieur du carré qui inscrit le polygone? (Relativement peu cher!)
si ( inShapePartRect ( pMat , s , p , X [ ré ] , y [ ré ]) ,
// Si c'est le cas, voyez si c'est réellement dans le polygone (relativement cher!)
si ( inShapePart ( pMat , s , p , X [ ré ] , y [ ré ]) ,
nom de la forme = Colonne ( des noms , "Prénom" ) [ s ] ;
Impression ( "Point (" || Carboniser ( X [ ré ]) || "," || Carboniser ( y [ ré ]) || ") trouvé en forme" || Carboniser ( s ) || ", Partie " || Carboniser ( p ) || ", avec nom" || nom de la forme || "." ) ;
// NB: Comme chaque point est "trouvé", supprimez les entrées correspondantes dans "x" et "y" pour essayer d'accélérer les choses
X [ ré ] = [] ; y [ ré ] = []
) ;
) ;
) ;
) ;
) ;
Fermer ( des points , NoSave ) ;
Fermer ( des polygones , NoSave ) ;
Fermer ( des noms , NoSave ) ;
Re: joindre des tables en fonction de l'emplacementSalut à tous,
J'ai réussi à faire fonctionner le script. Il prend chaque point et le met en correspondance avec le polygone par lequel il est entouré pour rejoindre les tables. Dans ce cas, il ajoute le nom de l'état à chaque point.
Le script fait son travail mais peut-être pas de la manière la plus efficace. Toutes les idées pour améliorer l'efficacité sont les bienvenues.
Si vous pouvez l'utiliser, partagez votre expérience.
Effacer les globes () ;
Noms par défaut jusqu'ici ( 1 ) ;
// fichier de points ouverts - ceci inclut l'observation que nous voulons mettre à jour
des points = Ouvrir ( "C: \ Fichiers de programme (x86) \ SAS \ JMPSW \ 11 \ Samples \ Data \ Hurricanes.jmp" ) ;
// réduire la taille des données pour l'illustration
des points << supprimer des lignes ( des points << obtenir des rangées où ( : prénom ( "Nom et ID" ) ! = "NOTNAMED_675" ) ) ;
// source polygone ouverte
des polygones = Ouvrir ( "C: \ Fichiers de programme (x86) \ SAS \ JMPSW \ 11 \ Maps \ US-State-XY.jmp" , Privé ) ;
// source de données ouverte - celle-ci contient les informations à mettre à jour
Les données = Ouvrir ( "C: \ Fichiers de programme (x86) \ SAS \ JMPSW \ 11 \ Maps \ US-State-Name.jmp" , Privé ) ;
// introduit la colonne avec les attributs à mettre à jour dans la table des points
des points << Nouvelle colonne ( "Etat" , Personnage , Nominal ) ;
des points << Définir les colonnes d'étiquette ( : Etat ) ;
Attendre ( 1 ) ;
// extrait les polygones dans des matrices pour améliorer l'efficacité
XMATRIX = des polygones : X << obtenir comme matrice ; // x valeurs de polygones
YMATRIX = des polygones : Y << obtenir comme matrice ; // y valeur des polygones
Début = Tick secondes () ;
// parcourt les points à travers les polygones et vérifie les correspondances.
Pour ( je = 1 , je <= N lignes ( des points ) , je ++, // pour chaque point
Pour ( ii = 1 , ii <= Col Max ( des polygones : ID de forme ) , ii ++, // pour chaque ID de forme
ROWLISTII = des polygones << obtenir des rangées où ( des polygones : ID de forme == ii ) ; // récupère les lignes pour chaque identifiant de forme
Pour ( iii = 1 , iii <= Max ( Des polygones : Partie ID [ ROWLISTII ] ) , iii ++, // pour chaque identifiant de pièce en fonction du nombre d'identifiants de pièce pour chaque identifiant de forme
// récupère les lignes pour chaque polygone
rangéesii = des polygones << obtenir des rangées où ( Et ( des polygones : ID de forme == ii , des polygones : Partie ID == iii ) ) ;
// récupère les valeurs X pour chaque polygone
XMATRIXROWSII = XMATRIX [ rangéesii ] ;
// obtient les valeurs Y pour chaque polygone
YMATRIXROWSII = YMATRIX [ rangéesii ] ;
// compare l'emplacement du point avec le polygone
résultat = En polygone ( des points : longitude [ je ] , des points : Latitude [ je ] , XMATRIXROWSII , YMATRIXROWSII ) ;
Si ( résultat == 1 , Spectacle ( je , ii , Les données : prénom [ ii ] ) ) ; // ceci enverra la liste des paires correspondantes au journal
Si ( résultat == 1 ,
des points : Etat [ je ] = Les données : prénom [ ii ] ; // cela rendra la mise à jour de l'attribut de l'information de polygone (data) au point (dots)
Pause () ; // cela fera que la troisième boucle (iii) cesse de vérifier plus de polygones du même identifiant de forme.
) ;
) ;
Si ( résultat == 1 , Pause () ) ; // cela fera que la seconde boucle (ii) cessera de rechercher plus d'identifiants de forme pour le même point et passera au point suivant dans la liste.
)
) ;
Fin = Tick secondes () ;
Runtime = Fin - Début ;
Spectacle ( runtime ) ;
// Wait (1);
des points << Bivarié (
Y ( : Latitude ) ,
X ( : Longitude ) ,
SendToReport (
Envoi ( {} , "1" , ScaleBox , { Échelle ( "Géodésique" ) , Min ( - 94.0515072337543 ) , Max ( - 60.9484927662457 ) , Inc ( 5 ) , Tiques mineures ( 1 )} ) ,
Envoi ( {} , "2" , ScaleBox , { Échelle ( "Géodésique" ) , Min ( 7.96034811422145 ) , Max ( 49.6893151267156 ) , Inc ( 5 ) , Tiques mineures ( 1 )} ) ,
Envoi (
{} ,
"Parcelle Bivar" ,
FrameBox ,
{ Taille du cadre ( 449 , 566 ) , Carte de fond ( Limites ( "États américains" ) ) , Ordre de la grille ( 3 ) , Commande de ligne de référence ( 4 ) ,
Rangée légende (
Etat ,
Couleur ( 1 ) ,
Thème de couleur ( "JMP Default" ) ,
Marqueur ( 0 ) ,
Thème de marqueur ( "" ) ,
Échelle continue ( 0 ) ,
Échelle Inversée ( 0 ) ,
Lignes exclues ( 0 )
)}
)
)
) ;
Re: joindre des tables en fonction de l'emplacementJ'aimerais voir un exemple de code si vous le faites fonctionner.
Re: joindre des tables en fonction de l'emplacementMerci Ian @ JMP
Cela semble prometteur. passera par ce que j'ai besoin de faire et voir si cela fonctionne.
Ron
Re: joindre des tables en fonction de l'emplacementJe pense que vous aurez besoin de scripts. La fonction JSL 'InPolygon ()' devrait être utile.