USERCONTROL PERMETTANT D'AFFICHER UNE CARTE (OU N'IMPORTE QUELLE IMG) ET DE PLAC

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 10 août 2007 à 08:03
ppphil Messages postés 2 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 6 septembre 2007 - 6 sept. 2007 à 14:15
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/43725-usercontrol-permettant-d-afficher-une-carte-ou-n-importe-quelle-img-et-de-placer-des-points-d-interet-mobiles

ppphil Messages postés 2 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 6 septembre 2007
6 sept. 2007 à 14:15
Encore deux petites améliorations :
Lorsque tu commence de déplacer tes images elles sautent en positionnant leur centre sur la souris. Normal puisque
Top = Top + e.Y - Height / 2; //idem pour left
Si sur le MouseDown tu enregistre deux champs StartX et StartY avec e.X et e.Y et que tu modifie le code du MouseMove en :
Top = Top + e.Y - StartY; c'est beaucoup plus propre, surtout si tu as de grandes images.

Pour ce qui est du décalage des images lors du redimentionnement de l'image de fond, il ne s'agit pas du tout de l'arrondi entre double et int comme je l'ai dis dans le précédent commentaire. C'est simplement que le coin haut gauche reste toujours à la même place sur l'image mais que la taille de l'image ne suit pas celle du fond. Cela donne une impression de décalage. Pour palier à cela je définis deux champs supplémentaire à mon image soit fTopC et fLeftC. Je définis des propriétés TopC et LeftC sur le Set desquelles je recalcule de Top et le Left en fonction de la taille de l'image soit (bon c'est du C# mais ça ne doit pas être difficile à traduire...)
private int fTopC;
private int fLeftC;
public int TopC
{
get
{
return fTopC;
}
set
{
fTopC = value;
Top = Convert.ToInt32(fTopC - (Height / 2));
}
}
public int LeftC
{
get
{
return fLeftC;
}
set
{
fLeftC = value;
Left = Convert.ToInt32(fLeftC - (Width / 2));
}
}
puis tu modifie le code du MouseMove en :
TopC = TopC + e.Y - StartY;

le MouseUp :
VRate = (double)TopC / Parent.Height;
HRate = (double)LeftC / Parent.Width; //enregistrement des rapports en image de font et punaise (voir commentaire précédent)
BtnOn = false;
Cursor.Current = Cursors.Default;

et la fonction pour déplacer l'image de la punaise :
public void MoveOnResize()
{
TopC = Convert.ToInt32(Parent.Height * VRate);
LeftC = Convert.ToInt32(Parent.Width * HRate);
}
ppphil Messages postés 2 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 6 septembre 2007
4 sept. 2007 à 11:24
Pour faire suivre tes punaises lors du changement de dimension de ton image de base tu peux jouer sur les rapports entre le Top et Left de chaque punaise et le Heigth et Width de l'image de base.
Pour tester j'ai fait une classe dérivée de PictureBox à laquelle j'ai ajouté deux champs soit pCentH et pCentV de type double (pour les punaises).
Lors du déplacement d'une punaise, sur le MouseUp tu mets à jour ces champs en divisant le Top de la punaise par le Height de l'image de base et idem pour le Left avec le Width.
Lors du redimentionnement de l'image de base, tu reprends les Height et Width de l'image et tu les multiplie par les pCentV et pCentH pour obtenir les nouveaux Top et Left des punaises.
Ca joue pas mal sauf que l'on se retrouve avec un petit décalage du aux arrondissements entre les double (pCentV-H) et les entiers (Top-Left).
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
13 août 2007 à 15:17
Trimballer une instance de PictureBox pour chaque point... très mauvaise idée !
T'as meilleurs temps de définir toi-même ton object qui sera dessiner et qui représentera un tel point, sera bien plus performant (et plus modularisé par la même occasion).
anthonygego Messages postés 48 Date d'inscription lundi 1 août 2005 Statut Membre Dernière intervention 10 juillet 2008 1
11 août 2007 à 15:45
Je me disais bien que ça venais de l'image mais je n'avais pas pensé à ça ^^
preventionhs Messages postés 2 Date d'inscription mardi 22 juillet 2003 Statut Membre Dernière intervention 10 août 2007
10 août 2007 à 20:51
Merci pour vos commentaires.

Je me suis effectivement rapidement rendu compte du problème de la taille des images ... j'y travaille.

Pour ce qui est de mon problème, je viens de le résoudre avec la boucle suivante ... et ca marche !:

Dim aControl As Control
For Each aControl In Me.FondCarte.Controls
acontrol.Top .....
Next

Pour ce qui est du décalage, j'ai la solution :

aControl.Left = (aControl.Left + PointeurPicto_X) * 1.5 - PointeurPicto_X

où pointeurPicto_X = 4
et pointeurPicto_Y = 31

Ces valeurs correspondent aux coordonnées de la pointe représentée sur l'image.

Je mets à jour les sources ASAP.
anthonygego Messages postés 48 Date d'inscription lundi 1 août 2005 Statut Membre Dernière intervention 10 juillet 2008 1
10 août 2007 à 12:26
J'ai un peu ragrdé à ton problème.
D'abord je te conseille de faire une collection qui contiendrait les PictureBox.

--> Private Pts As New Collection(Of PictureBox)

De plus, ça te permettrais d'ajouter des points d'intérets pendant l'utilisation, ensuite, pour le zoom, tu fais :

For Each Pt As PictureBox In Pts
Pt.Left = Pt.Left * 1.5
Pt.Top = Pt.Top * 1.5
Next

Seulement, en le faisant, j'ai rencontré un petit problème de décalage de quelques pixels (beacoup moins important que la décalage actuel) dont je n'ai pas de solution à te proposer :s
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
10 août 2007 à 08:03
l'image m'a l'air fait d'un seul bloc, c'est contre-performant...

stockes là sous forme de petites images, que tu recolleras facon mosaique. ta RAM te remerciera, et le temps d'execution s'en ressentira pour des cartes rpidement trop grandes pour ton code actuel.
Rejoignez-nous