Suite

Attribuez la valeur Z au début et à la fin de la ligne PostGIS

Attribuez la valeur Z au début et à la fin de la ligne PostGIS


J'ai une table de lignes dans ma base de données PostGIS et une table avec des niveaux d'inversion pour le début et la fin de chaque ligne.

Mon objectif est de créer des lignes 3D dans ma table, à partir de mes données inversées. Je sais que je peux utiliser st_makeline pour recréer la ligne avec un point 3D au début et à la fin, mais j'espérais pouvoir exécuter une mise à jour uniquement sur la valeur Z pour le début et la fin.

Cela peut-il être fait ou est-il plus facile de simplement recréer la ligne.


-Vous pouvez mettre à jour un point dans une chaîne de lignes avec ST_SetPoint (chaîne de géométrie, position de base zéro entier, point de géométrie) et ST_Translate().
-Pour obtenir le premier et le dernier point, utilisez st_endpoint() et st_startpoint().
-Pour obtenir "l'index" du dernier point, utilisez ST_NumPoints(the_geom)-1.
-Le premier point "index" est 0.

Quelque chose comme ça pour le premier point :

MISE À JOUR de la table SET the_geom= st_setpoint(the_geom,0,st_translate(st_firstpoint(the_geom),0,0,Z)) FROM…

Comment attribuer votre échelle de couleurs sur les données brutes dans heatmap.2()

Notez que dans ces données (et la réelle) il n'y a pas de valeurs négatives et les valeurs positives peuvent atteindre 100 environ.

Ce que je veux faire, c'est tracer une carte thermique avec ma propre échelle de couleurs et mon propre schéma :

  1. Lorsque la valeur est 0, mettez-la en blanc.
  2. Lorsque la valeur est == 1, définissez-la en noir.
  3. Lorsque la valeur est > 1, définissez-la dans une nuance de rouge.
  4. Lorsque la valeur est < 1 et > 0, définissez-la en nuance de verts.

également sans utiliser de mise à l'échelle des données ou de transformation z-score intégrée. Comment puis-je y parvenir?

Ce qui produit le tracé suivant, où il utilise la mise à l'échelle des lignes de score z par défaut.


Avec sed standard, vous jamais voir une nouvelle ligne dans le texte lu à partir d'un fichier. C'est parce que sed lit ligne par ligne, et il n'y a donc pas de nouvelle ligne à la fin du texte de la ligne actuelle dans l'espace de motif de sed . En d'autres termes, sed lit les données délimitées par un saut de ligne et les délimiteurs ne font pas partie de ce que voit un script sed.

Les expressions régulières peuvent être ancré à la fin de la ligne en utilisant $ (ou au début, en utilisant ^ ). Ancrer une expression au début/à la fin d'une ligne la force à correspondre exactement là, et pas n'importe où sur la ligne.

Si vous souhaitez remplacer tout ce qui correspond au motif [A-Za-z]* à la fin de la ligne par quelque chose, ancrez le motif comme ceci :

. le forcera à correspondre à la fin de la ligne et nulle part ailleurs.

Cependant, comme [A-Za-z]*$ correspond également rien (par exemple, la chaîne vide présente à la fin de tous ligne), vous devez forcer la correspondance de quelque chose, par exemple. en précisant

Alors, votre sed la ligne de commande sera donc

Je n'ai pas utilisé le commutateur -E ici car ce n'est pas nécessaire. Avec ça, tu aurais pu écrire


Vous pouvez maintenant accéder aux solutions, de cette façon xx[[1]] , yy[[2]] .

Si vous préférez collecter des solutions dans Array , il existe un autre moyen :

maintenant X est équivalent à s[[All, 1, 2]] , tandis que Y à s[[All, 2, 2]] , par ex. :

Vous n'avez pas besoin d'utiliser ni même de définir des tableaux X et Y, par ex.

Nous avons utilisé Condition c'est-à-dire / pour assurer les définitions de x[i], y[i] uniquement pour i dans une plage appropriée déterminée par Length @ s , c'est-à-dire le nombre de solutions.

Habituellement, vous ne voulez pas réellement affecter de valeurs à x et y , et vous utiliseriez plutôt des règles de remplacement :

ou pour la deuxième solution :

Si tu vraiment voulez attribuer des valeurs à x et y globalement, vous pouvez utiliser :

mais toi doit effacez x et y avant d'utiliser un autre ensemble :

Si vous souhaitez attribuer des valeurs à x et y dans un bloc, vous pouvez faire quelque chose comme ceci :

Cela utilise ce que j'appelle le modèle d'injecteur pour obtenir les valeurs dans Block dans la bonne syntaxe sans évaluation prématurée.

Mettre à jour: La fonction intégrée Values ​​de la version 10 effectue une extraction de valeur commodément pour les règles apparaissant dans des listes de longueurs et de profondeurs arbitraires :

Message d'origine :

Si vous souhaitez vraiment affecter des solutions à des variables, vous pouvez faire quelque chose comme ceci :

Sortie[5]=

Indice[x,1]=(-11181-Sqrt[2242057])/74498
Indice[x,2]=(-11181+Sqrt[2242057])/74498
Indice[y,1]=1/386(13-Sqrt[2242057])
Indice[y,2]=1/386 (13+Sqrt[2242057])

Ensuite, vous pouvez utiliser les solutions à des fins de démonstration :

Voici une solution indolore :

Attribuez les quatre résultats de la solution s ci-dessus à une variable chacun, dans l'ordre

Ah, ils l'ont finalement implémenté en version 10, alors ! Voici une procédure que j'utilise depuis la version 5, elle pourrait fournir des fonctionnalités similaires dans les versions antérieures à l'introduction de Value. (Je ne suis pas sûr, mais peut-être que je l'ai posté sur le MathGroup. alors pardonnez-moi si ce n'est pas une nouvelle)

Je l'avais appelé "ToValues". Je lui ai donné deux options :

Le message d'aide est, espérons-le, auto-explicatif :

L'application de ToValues ​​à des listes de règles produit une liste de valeurs

Bien entendu l'affectation est immédiate, ici

Par défaut, ToValues ​​renvoie la liste de valeurs la plus simple possible, en supprimant la liste imbriquée. Si vous souhaitez conserver l'imbrication d'origine, voici ce que fait l'option Aplatissement :

Nous pouvons spécifier une fonction à appliquer aux valeurs renvoyées.

Nous pouvons également utiliser des fonctions qui utilisent les côtés droits des règles. Définissez-les simplement comme des fonctions avec une tête paramétrée et définissez IndexedFunction->True pour indiquer à ToValues ​​de l'utiliser. Dans ce cas, nous voulons retourner les listes sous la forme :

Applications du monde réel

ToValues ​​est normalement utilisé pour extraire des solutions des listes renvoyées par Solve, NSolve, DSolve, etc. Dans sa forme par défaut, il peut être appliqué de cette manière :

Cela donne une liste des solutions complexes

Cela utilise la fonction optionnelle pour calculer la partie réelle et imaginaire de chaque solution

Et cela pousse la fonction à créer des objets graphiques (Points) basés sur ces valeurs à l'intérieur de ToValues :


En ce qui concerne la syntaxe du shell, ( est un caractère spécial (comme , > , & etc.), il ne peut pas apparaître dans le cadre d'une valeur assignée sans être échappé ou entre guillemets. Il est utilisé par exemple pour démarrer des sous-shells, mais comme vous l'avez remarqué , dans la plupart des cas, cela provoque simplement une erreur de syntaxe. (Contrairement à, disons & , qui mettrait fin à la commande en silence.)

Cependant, les parenthèses ne sont pas votre seul problème, vous avez également des espaces dans le chemin. Ce n'est pas une erreur de syntaxe, mais cela change le sens de la commande. export PATH=/mnt/c/Program Files/Somepath signifie affecter /mnt/c/Program à PATH et exporter une variable appelée Files/Somepath , ce qui provoque également une erreur car la barre oblique n'est pas valide dans un nom de variable.

Vous devrez soit échapper toutes les parenthèses et tous les espaces, comme dans Program Files (x86) , soit simplement citer la chaîne entière :

ou juste des parties de celui-ci, bien que cela puisse être plus difficile à lire :

(Notez que vous ne pouvez pas faire les deux l'un dans l'autre, PATH='/mnt/c/Program Files (x86)/. ' affecterait une chaîne contenant des barres obliques inverses littérales.)


Débarrassez-vous de la fin avant le reste. Le compilateur ne sait pas où se termine le premier if.

  • always_comb ne permet pas aux processus externes d'écrire des variables de gauche (vs. always @ * , ce qui le fait)
  • Quoi qu'il en soit, plusieurs conducteurs du même type de fil ne sont pas autorisés. Le always_comb se résume à une affectation pour z , donc essayer de l'affecter à nouveau à l'extérieur entraîne une erreur multi-pilote.

Enfin, si votre intention est que z ait une valeur par défaut, un style de codage prudent l'inclurait dans le corps de l'instruction if-else comme final else . C'est plus clair pour quelqu'un d'autre qui lit votre code (ou vous-même, plus tard.)

Vous pouvez écrire une déclaration à l'intérieur du bloc combinatoire comme ceci :

Cette instruction avant l'instruction if s'exécute si aucune des instructions de l'instruction if n'est vraie. C'est une autre méthode pour écrire ceci :

Si vous écrivez des instructions à la fois dans le bloc else et avant l'instruction de condition if, la valeur attribuée dans le bloc else sera reflétée et l'autre valeur sera ignorée.

Remarque : assurez-vous que toutes les conditions possibles sont couvertes dans l'instruction if pour la logique combinatoire !

Si vous avez vraiment besoin d'un verrou, utilisez always_latch , pas always_comb !

En ce qui concerne le souci d'éviter les X dans la simulation, la meilleure option est de déclarer le type de données bit au lieu de logic . Cela l'initialisera à 0 puisque le bit est à 2 états.

Remarque : Bien que la simulation à 2 états soit plus rapide, elle n'est pas recommandée car elle peut masquer l'échec de l'initialisation du matériel au démarrage.


En supposant que vous vouliez le premier des deux blocs identiques :

Le /cell alatch / range est la plage de lignes que vous souhaitez obtenir en sortie.

Les expressions sed suppriment d'abord toutes les lignes ne pas dans cette plage, puis quitte dès qu'un > est trouvé en début de ligne. L'instruction q entraînera la fin de sed après avoir sorti la ligne actuelle, de sorte que le > final sera imprimé.

Exécuter l'instruction d immédiatement passe à la ligne d'entrée suivante et revient au début du script d'édition, de sorte que l'instruction q n'a aucun moyen de s'exécuter à moins qu'elle ne se trouve dans la plage qui ne provoque pas l'exécution de d.

Avec awk , obtenir le même effet avec un code qui devrait rappeler le code sed ci-dessus :


2 réponses 2

Edit : Donc ma solution n'est pas tout à fait exacte, car comme tu dis le gros câble et les tubes ne se rejoignent pas au même point de la prise.

*Créez un vide à l'extrémité du câble, sélectionnez le vide, décalez sélectionnez le câble, entrez Éditer mode, sélectionnez 3 sommets, appuyez sur Ctrl P :

Parentez le plug au vide :

Donnez au câble un Courbe modificateur, déplacez le câble le long de la courbe :

Le but est d'obtenir une animation comme sur l'image 1 de la question.

Nous pouvons connecter le câble principal au connecteur en utilisant la solution @moonboots. Mais nous devons d'abord couper la partie du câble principal qui va dans le connecteur. Ensuite, nous joignons cette pièce à l'objet-connecteur (comme vous pouvez le voir à gauche). De là, suivez la réponse @moonboots et vous aurez terminé avec le câble principal.

Il y avait un problème avec les tubes mal alignés avec les douilles sur le connecteur. La solution ici est d'utiliser Modificateur de crochet en plus de Modificateur de courbe mais en limitant chaque mod avec des groupes de sommets.

Parlons d'abord du crochet. Allez au Mode édition et sélectionnez les sommets inférieurs des tubes et placez un curseur 3D au centre (j'utilise un module complémentaire gratuit "MACHIN3tools").

Ensuite aller à Mode objet et ajouter un nouveau Objet vide. Ensuite, sélectionnez un connecteur vide, sélectionnez, appuyez sur Ctrl + P pour parent Vide à un connecteur.

Ensuite aller à Mode édition, appuyez sur Alt + Z pour activer le mode rayons X et sélectionnez plusieurs rangées de sommets à l'extrémité des tubes. Ensuite, allez dans l'onglet "Propriétés des données de l'objet" et créez un nouveau groupe de sommets (je l'ai appelé "Hook") et affectez-lui les sommets sélectionnés.

Maintenant, appuyez sur Ctrl + I pour inverser la sélection et créez un autre groupe de sommets (je l'ai appelé "Curve deform").

Parentez les tubes à un câble principal (assurez-vous de vérifier que les points d'origine de ces objets sont au même endroit), et ajoutez un modificateur de courbe aux tubes (avec les mêmes réglages que pour le câble principal). puis limite Courbe mod avec le groupe de sommets que nous avons créé plus tôt.

Ajoutons ensuite un Modificateur de crochet. Pour le Objet sélectionnez le vide que vous avez créé à la fin des tubes, et pour le Groupe de sommets sélectionnez le groupe "Hook".

Quatrième partie : la sauce secrète

Voyons maintenant comment tout cela se comporte. Je vais montrer la visibilité de la courbe mod et faites-le glisser le long de l'axe de transformation (Z dans mon cas). Et on peut voir que ça devient fou au point où 2 groupes de sommets se rencontrent.

Ajoutons maintenant aux tubes un autre mod qui corrige tout. Cela s'appelle "correctif en douceur". Les paramètres peuvent varier, vous pouvez voir les valeurs qui ont fonctionné pour moi sur l'image ci-dessous.


L'appel de n'importe quelle fonction en général vous donnera un petit (minuscule) impact sur les performances. Les fonctions récursives (AFAIK) ne peuvent pas être intégrées et ne peuvent donc pas être optimisées. LINQ tourne autour de l'appel d'autres fonctions, c'est donc le pire choix à faire si vous voulez écrire du code performant. Je l'ai déjà dit, LINQ n'est pas pour écrire du code rapide, c'est pour écrire du code concis. Il s'agit d'un algorithme simple qui n'a pas besoin de s'enliser.

* Cela n'aide pas si vous n'utilisez pas correctement LINQ, vous avez un certain nombre de non-non dans votre code.

Si vous voulez le le plus rapide approche (sans avoir recours à la cartographie de toutes les valeurs possibles en mémoire), vous vous en éloigneriez et feriez une conversion plus directe. Pour être le plus rapide, vous devez descendre à bas niveau et utiliser du code dangereux (non géré). Je n'irai pas là-bas. D'un autre côté, si vous voulez du code managé le plus rapide, vous devriez le faire de manière itérative. En tout cas, ma proposition ne prétend pas être la mise en œuvre la plus rapide, cela pourrait très bien ne pas l'être mais je ne sais pas, il faudrait la profiler pour le savoir.

Nous effectuons une conversion de base des nombres en base 10 en "nombres" en base 26. Je ne sais pas s'il existe un algorithme plus rapide pour le faire, mais voici une conversion directe utilisant un StringBuilder comme tampon.

D'un autre côté, étant donné que vos entrées sont limitées à 50'ish, vous pouvez simplement utiliser un tableau (et non un IEnumerable<> ) pour les recherches.


  1. Créez 2 chemins de courbe, créez une caméra et un objet cible et parent chacun d'une courbe ( CTRL-P , puis Suivre le chemin ).
  2. Ajouter une contrainte Track To à la caméra avec l'objet cible défini comme cible
  3. Définissez l'axe approprié sur la contrainte Suivre vers afin que la caméra pointe vers la cible. Vous devrez peut-être appliquer une échelle et une rotation à la caméra et/ou à l'objet cible pour que cela fonctionne.
  4. La rotation de la caméra correspondra à l'objet cible. Vous devrez peut-être faire pivoter l'objet cible pour que l'axe Z de la caméra pointe vers le haut. Commençant par -Z pour Vers l'axe et Oui pour le Axe haut vous amènera là où vous voulez être la plupart du temps.

Pour l'objet ajouter un Suivre la contrainte de chemin et sélectionnez la courbe que vous souhaitez que l'objet suive comme cible. Activez Suivre la courbe et Activer le chemin d'animation.

Votre objet suivra ce chemin :

Placez votre caméra au même point d'origine de votre deuxième courbe (celle que vous souhaitez utiliser comme chemin de déplacement) et ajoutez une contrainte Suivre le chemin avec la courbe comme cible et le chemin animé activé :

Votre appareil photo se déplacera sur ce chemin.

Sur l'appareil photo, ajoutez un Suivre jusqu'à contrainte avec l'objet comme Target, To -Z et Up Y.

Je l'ai résolu en utilisant des objets vides supplémentaires.

  1. Créer un chemin
  2. Créer un cube vide
  3. Définir le Cube comme objet parent de la Caméra : sélectionnez la Caméra et le Cube puis Ctrl-P "Objet"
  4. Ajouter une contrainte d'objet pour le Cube par la barre latérale droite "Follow Path"

  1. Ajouter une sphère vide
  2. Ajouter une contrainte d'objet pour la sphère par la barre latérale droite "Suivre le chemin" (facultatif)
  3. Ajoutez une contrainte d'objet pour la caméra "Track to" et sélectionnez la sphère (je l'ai appelée "Camera target"). En outre, vous devez avoir besoin d'utiliser Target Z

Résultat : vous pouvez animer la rotation de la caméra par Y utiliser la Sphère X et Z par le Cube

C'est un exemple de ce à quoi cela ressemble :

J'ai trouvé une solution, il suffit de prendre la caméra et de la mettre à la fin du chemin incurvé, puis de sélectionner à la fois la caméra et le chemin à l'aide de la touche Maj.

Une fois sélectionné, appuyez sur Ctrl + P et sélectionnez Suivre le chemin. Lorsque vous appuyez sur Entrée, la caméra suivra le chemin. Le problème est qu'il ne suit pas le chemin, donc vous faites une chose similaire à ce que nous avons fait auparavant, mais vous ajoutez un vide seulement cette fois-ci, vous le placez légèrement à l'intérieur du chemin.

Où, dans ce cas, la caméra est à la fin du chemin et le vide est légèrement à l'intérieur du chemin mais près de la caméra. Vous sélectionnez donc vide et chemin et cliquez sur Ctrl + P puis suivez le chemin. Avant de faire cela, assurez-vous que la chronologie est à zéro, ce qui place la caméra dans sa position d'origine et garantit que l'animation vide commence à partir de zéro.

Une fois fait cliquez sur la caméra puis sur la contrainte d'objet appelée Suivre jusqu'à puis définissez la cible sur vide, définissez des valeurs telles que En haut à Oui et à, à -Z


Voir la vidéo: PGConfRu2019 Дорофей Пролесковский - PostGIS от катастроф