Asymptote pour réaliser des projections cartographiques

Règles du forum
ATTENTION ! Il est demandé de ne déposer dans ce forum que des exemples en langage Asymptote
  • finalisés
  • que l'on pense intéressants et optimisés
  • et qui se rapportent au thème du forum.
Si certains exemples déposés donnent lieu à de nombreuses modifications, ils seront déplacés et remplacés par un nouveau sujet dans ce forum avec la ou les meilleures propositions.
Pour les demandes d'aide ... il y a un forum spécifique !
Avatar du membre
GM
Administrateur du site
Administrateur du site
Messages : 1364
Enregistré le : dim. 7 mars 2010, 14:50

Asymptote pour réaliser des projections cartographiques

Message non lu par GM » mer. 4 août 2010, 11:26

Cela ne surprendra personne : à l'instar d'autres langages, Asymptote peut permettre de réaliser des projections cartographiques...
... et il y a nul doute que quelqu'un finira tôt ou tard par développer une extension sur ce thème.

En attendant, deux exemples :

  • Un exemple compliqué, issu de la galerie officielle, et que l'on doit à Jens Schwaiger : la projection de Mollweide.
    Sur Wikipedia, quelqu'un a écrit :La projection de Mollweide est une projection cartographique pseudo-cylindrique employée le plus souvent pour les planisphères de la Terre (ou du ciel). Connue aussi sous le nom de projection de Babinet ou projection elliptique, le qualificatif de projection équivalente de Mollweide indique qu'elle privilégie la conservation des surfaces à la conservation des angles (projection conforme) : c'est pourquoi on y recourt principalement pour les cartes de l'ensemble de la sphère reproduites sur une surface réduite.

    Cette projection fut publiée pour la première fois en 1805 par le mathématicien et astronome prussien Karl (ou Carl) Brandan Mollweide (1774 – 1825) de Leipzig, en tant qu’alternative à la Projection de Mercator. Jacques Babinet en vulgarisa l’emploi en 1857, sous le nom de projection homolographique[1].

    Figure asymptote 721b749ff138d7e00cf1a4c9bc402f29
    *** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

    CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
    1. size(300);
    2. real findtheta(real phi, real epsilon=realEpsilon) {
    3. real nwtn(real x, real y) {return x-(2x+sin(2x)-y)/(2+2*cos(2x));};
    4. real y=pi*sin(phi);
    5. if(y == 0) return 0.0;
    6. if(abs(y) == 1) return pi/2;
    7. real startv=y/4;
    8. real endv=nwtn(startv,y);
    9. if(epsilon < 500*realEpsilon) epsilon=500*realEpsilon;
    10. while(abs(endv-startv) > epsilon) {startv=endv; endv=nwtn(startv,y);};
    11. return endv;
    12. }
    13. pair mollweide(real lambda, real phi, real lambda0=0){
    14. static real c1=2*sqrt(2)/pi;
    15. static real c2=sqrt(2);
    16. real theta=findtheta(phi);
    17. return(c1*(lambda-lambda0)*cos(theta), c2*sin(theta));
    18. }
    19. guide gfrompairs(pair[] data){
    20. guide gtmp;
    21. for(int i=0; i < data.length; ++i) {
    22. pair tmp=mollweide(radians(data[i].y),radians(data[i].x));
    23. gtmp=gtmp--tmp;
    24. }
    25. return gtmp;
    26. }
    27. string datafile="../data/worldmap.dat";
    28. file in=input(datafile,comment="/").line();
    29. pair[][] arrarrpair=new pair[][] ;
    30. int cnt=-1;
    31. bool newseg=false;
    32. while(true) {
    33. if(eof(in)) break;
    34. string str=in;
    35. string[] spstr=split(str,"");
    36. if(spstr[0] == "#") {++cnt; arrarrpair[cnt]=new pair[] ; newseg=true;}
    37. if(spstr[0] != "#" && newseg) {
    38. string[] spstr1=split(str,'\t'); // separator is TAB not SPACE
    39. pair tmp=((real) spstr1[1],(real) spstr1[0]);
    40. arrarrpair[cnt].push(tmp);
    41. }
    42. }
    43. for(int i=0; i < arrarrpair.length; ++i)
    44. draw(gfrompairs(arrarrpair[i]),1bp+black);
    45. pair[] constlong(real lambda, int np=100) {
    46. pair[] tmp;
    47. for(int i=0; i <= np; ++i) tmp.push((-90+i*180/np,lambda));
    48. return tmp;
    49. }
    50. pair[] constlat(real phi, int np=100) {
    51. pair[] tmp;
    52. for(int i=0; i <= 2*np; ++i) tmp.push((phi,-180+i*180/np));
    53. return tmp;
    54. }
    55. for(int j=1; j <= 5; ++j) draw(gfrompairs(constlong(-180+j/6*360)),white);
    56. draw(gfrompairs(constlong(-180)),1.5bp+white);
    57. draw(gfrompairs(constlong(180)),1.5bp+white);
    58. for(int j=0; j <= 12; ++j) draw(gfrompairs(constlat(-90+j/6*180)),white);
    59. close(in);


    Retrouver le code complet de Jens, avec ses commentaires, dans le fichier examples/worldmap.asy du dossier d'installation d'Asymptote 2.03 ou supérieure.

  • Un exemple plus simple de mon cru : une carte classique de mon département : 59, le Nord. :mrgreen:

    Figure asymptote 6520dcd46f928d823ec4b4dfa533c99b
    *** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

    CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
    1. size(200);
    2.  
    3. file fich=input("../data/59-Nord.txt");
    4.  
    5. string ligne;
    6.  
    7. while((find(ligne,"[Limites XY]")==-1)&&eof(fich)!=true) ligne=fich;
    8.  
    9. while(eof(fich)!=true){
    10. ligne=fich;
    11. string[] coor=split(ligne);
    12.  
    13. path p;
    14. for(int k=0; k<coor.length; ++k)
    15. {
    16. real[] coor0=(real[]) split(coor[k],",");
    17. p=p--(coor0[0],coor0[1]);
    18. }
    19. draw(p,.5bp+blue);
    20. }
    21.  
Index des fonctions - Exemple de lien donnant le résultat d'une recherche sur les mots 'arc' et 'triple' : http://asy.marris.fr/indexasy/?filtre=arc triple
Mes configurations (le 10/10/17) :
PC n°1 :Windows 10 - Asymptote(2.41)+MikTeX2.9 - Editeurs : Notepad++ et TeXworks.
Mes autres PC :Ubuntu 16.04LTS - Asymptote(2.42 git) + TexLive2017 - Editeur : TeXworks.
Merci de préciser la votre pour faciliter l'aide des autres !

Avatar du membre
GM
Administrateur du site
Administrateur du site
Messages : 1364
Enregistré le : dim. 7 mars 2010, 14:50

Re: Asymptote pour réaliser des projections cartographiques

Message non lu par GM » mer. 4 août 2010, 11:38

Pour vous éviter de vous prendre la tête à retrouver le chemin, je précise que les données sont ici : http://asy.gmaths.net/forum/illustrender/data/.
Index des fonctions - Exemple de lien donnant le résultat d'une recherche sur les mots 'arc' et 'triple' : http://asy.marris.fr/indexasy/?filtre=arc triple
Mes configurations (le 10/10/17) :
PC n°1 :Windows 10 - Asymptote(2.41)+MikTeX2.9 - Editeurs : Notepad++ et TeXworks.
Mes autres PC :Ubuntu 16.04LTS - Asymptote(2.42 git) + TexLive2017 - Editeur : TeXworks.
Merci de préciser la votre pour faciliter l'aide des autres !

Avatar du membre
GM
Administrateur du site
Administrateur du site
Messages : 1364
Enregistré le : dim. 7 mars 2010, 14:50

Re: Asymptote pour réaliser des projections cartographiques

Message non lu par GM » mer. 4 août 2010, 15:32

Figure asymptote af906ee2c058b6667dfda5bb60cff2e0
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1.  
  2. size(300);
  3. string[] listedep={"59-Nord",
  4. "62-PasDeCalais",
  5. "80-Somme",
  6. "60-Oise",
  7. "02-Aisne"};
  8. for(string dep : listedep){
  9. file fich=input("../data/"+dep+".txt");
  10. string ligne=fich, nomdep=fich;
  11. while((find(ligne,"[Limites XY]")==-1)&&eof(fich)!=true) ligne=fich;
  12. int c=0;
  13. while((ligne=fich)!=""){
  14. string[] coor=split(ligne);
  15. path p;
  16. for(int k=0; k<coor.length; ++k)
  17. {
  18. real[] coor0=(real[]) split(coor[k],",");
  19. p=p--(coor0[0],coor0[1]);
  20. }
  21. draw(p,.5bp+blue);
  22. if(c==0) label(scale(.8)*nomdep,(min(p)+max(p))/2,red);
  23. ++c;
  24. }
  25. }
  26.  
Index des fonctions - Exemple de lien donnant le résultat d'une recherche sur les mots 'arc' et 'triple' : http://asy.marris.fr/indexasy/?filtre=arc triple
Mes configurations (le 10/10/17) :
PC n°1 :Windows 10 - Asymptote(2.41)+MikTeX2.9 - Editeurs : Notepad++ et TeXworks.
Mes autres PC :Ubuntu 16.04LTS - Asymptote(2.42 git) + TexLive2017 - Editeur : TeXworks.
Merci de préciser la votre pour faciliter l'aide des autres !

Avatar du membre
GM
Administrateur du site
Administrateur du site
Messages : 1364
Enregistré le : dim. 7 mars 2010, 14:50

Re: Asymptote pour réaliser des projections cartographiques

Message non lu par GM » jeu. 19 août 2010, 16:50

Nouveau message de Jens Schwaiger sur le forum officiel, où il explique que sa version initiale de la projection ci-dessous a quelques défauts
et il en propose une nouvelle avec un nouveau fichier de données dont il donne le lien.

Figure asymptote a1d672b34b19efc9174375a222e03b28
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1. size(400);
  2. real findtheta(real phi, real epsilon=realEpsilon) {
  3. // Determines for given phi the unique solution -pi/2<=theta<=pi/2 off
  4. // 2*theta+sin(2*theta)=pi*sin(phi)
  5. // in the non-trivial cases by Newton iteration;
  6. // theoretically the initial guess pi*sin(phi)/4 always works.
  7. real nwtn(real x, real y) {return x-(2x+sin(2x)-y)/(2+2*cos(2x));};
  8. real y=pi*sin(phi);
  9. if(y==0) return 0.0;
  10. if(abs(y)==1) return pi/2;
  11. real startv=y/4;
  12. real endv=nwtn(startv,y);
  13. if(epsilon<500*realEpsilon) epsilon=500*realEpsilon;
  14. while(abs(endv-startv)>epsilon) {startv=endv; endv=nwtn(startv,y);};
  15. return endv;
  16. };
  17. pair mollweide(real lambda, real phi, real lambda0=0){
  18. // calculates the Mollweide projection centered at lambda0 for the poin with coordinates (phi,lambda)
  19. static real c1=2*sqrt(2)/pi;
  20. static real c2=sqrt(2);
  21. real theta=findtheta(phi);
  22. return (c1*(lambda-lambda0)*cos(theta), c2*sin(theta));
  23. };
  24.  
  25. guide gfrompairs(pair[] data){
  26. guide gtmp;
  27. for(int i=0;i<data.length;++i) { pair tmp=mollweide(radians(data[i].y),radians(data[i].x));gtmp=gtmp--tmp;};
  28. return gtmp;
  29. };
  30.  
  31. guide borderline(string coodstr, bool plain=true) {
  32. string[] cood=split(coodstr,";");
  33. guide bdl;
  34. pair tmp;
  35. for(int i=0;i<cood.length-1;++i) {
  36. string[] strpr=split(cood[i],",");
  37. if(plain) {tmp=(radians((real) strpr[0]),radians((real) strpr[1]));} else
  38. { tmp=mollweide(radians((real) strpr[0]),radians((real) strpr[1]));}
  39. bdl=bdl--tmp;
  40. }
  41. return bdl--cycle;
  42. }
  43. string datafile="../data/mapdata1.csv";
  44. file in=input(datafile).line();
  45. string[] splt;
  46. int brdrcnt;
  47. int cnt=0;
  48. guide bdl;
  49. real hue;
  50. real sq=sqrt(3);
  51. while(true) {
  52. if(eof(in)) break;
  53. splt=split(in,'\t');
  54. brdrcnt=(int) splt[3];
  55. hue=cnt*sq;
  56. hue=hue-floor(hue);// in[0,1[
  57. // For irrational alpha the numbers n*alpha-floor(n*alpha) are equidistributed mod 1
  58. hue=150*hue-45;
  59. write(hue);
  60. for(int i=0;i<brdrcnt;++i){
  61. bdl=borderline(splt[4+i],plain=false);
  62. fill(bdl,hsv(hue,0.8,1));
  63. draw(bdl,black+0.25bp);
  64. };
  65. splt.delete();
  66. write(cnt);++cnt;
  67. };
  68.  
  69. close(in);
  70. pair[] constlong(real lambda, int np=100) {
  71. pair[] tmp;
  72. for(int i=0;i<=np;++i) tmp.push((-90+i*180/np,lambda));
  73. return tmp;
  74. };
  75. pair[] constlat(real phi, int np=100) {
  76. pair[] tmp;
  77. for(int i=0;i<=2*np;++i) tmp.push((phi,-180+i*180/np));
  78. return tmp;
  79. };
  80. for(int j=1;j<=5;++j) draw(gfrompairs(constlong(-180+j/6*360)),white);
  81. draw(gfrompairs(constlong(-180)),1.5bp+white);
  82. draw(gfrompairs(constlong(180)),1.5bp+white);
  83. for(int j=0;j<=12;++j) draw(gfrompairs(constlat(-90+j/6*180)),white);
  84. guide boundary=gfrompairs(constlong(-180))--reverse(gfrompairs(constlong(180)))--cycle;
  85. picture pic;
  86. add(pic,currentpicture);
  87. erase();
  88. fill(boundary,paleblue);
  89. add(pic);
  90.  
Index des fonctions - Exemple de lien donnant le résultat d'une recherche sur les mots 'arc' et 'triple' : http://asy.marris.fr/indexasy/?filtre=arc triple
Mes configurations (le 10/10/17) :
PC n°1 :Windows 10 - Asymptote(2.41)+MikTeX2.9 - Editeurs : Notepad++ et TeXworks.
Mes autres PC :Ubuntu 16.04LTS - Asymptote(2.42 git) + TexLive2017 - Editeur : TeXworks.
Merci de préciser la votre pour faciliter l'aide des autres !

Répondre