]> www.wagner.pp.ru Git - oss/fgis.git/blob - dll/fgisPlanchet.c
First checked in version
[oss/fgis.git] / dll / fgisPlanchet.c
1 #include <tk.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "fgis.h"
5 /* 
6  * fgisPlanchet.c - coordinate recalculating commands for planchet widget,
7  * implemented in C
8  * Copyright (c) by softweyr
9  */
10
11 /* internal converting function */
12
13 /* 
14  *    Fills x1 y1 x2 y2 with limits of planchet coordinate system
15  *    Returns TCL_OK on success
16  */
17 int Fgis_GetPlanchetLimits(Tcl_Interp *interp,char *planchet,
18              double *x1,double *y1,double *x2, double *y2)
19 {
20  char *list;
21  list=Tcl_GetVar2(interp,planchet,"limits",TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
22  if (!list) return TCL_ERROR;
23  return Fgis_GetLimits(interp,list,x1,y1,x2,y2);
24 }
25
26 int Fgis_GetPlanchetWidth(Tcl_Interp *interp,char *planchet)
27 {
28   Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
29   if (p==NULL) return 0;
30  
31  return Tk_ReqWidth(p);
32 }
33 int Fgis_GetPlanchetHeight(Tcl_Interp *interp,char *planchet)
34 {
35   
36   Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
37   if (p==NULL) return 0;
38   return Tk_ReqHeight(p);
39 }
40
41
42 /* 
43  * Returns alternative (map) x, given planchet  x in pixels
44  * No error checking - fast, for internal use. In case of error returns 0
45  *
46  */
47 double Fgis_AltX(Tcl_Interp *interp,char *planchet,int x)
48 {double X1,Y1,X2,Y2,result;
49  int width=Fgis_GetPlanchetWidth(interp,planchet);
50  if (!width||Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
51    return 0.0;
52  result= (x*(X2-X1)/width+X1);
53  return result;
54 }
55
56 /* 
57  * Returns alternative (map) y, given planchet  y in pixels
58  * No error checking - fast, for internal use. In case of error returns 0
59  *
60  */
61 double Fgis_AltY(Tcl_Interp *interp,char *planchet,int y)
62 {double X1,Y1,X2,Y2,result;
63  int height=Fgis_GetPlanchetHeight(interp,planchet);
64  if (!height||Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)
65        ==TCL_ERROR)
66    return 0.0;
67  result= ((height-y)*(Y2-Y1)/height+Y1);
68  return result;
69 }
70
71 /*
72  * Returns planchet x coordinate in pixels, given alternative (map) coordinate
73  */
74 int Fgis_PlanchetX(Tcl_Interp *interp,char *planchet,double x)
75 {double X1,Y1,X2,Y2;
76  if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
77      return 0;
78  return floor((x-X1)/(X2-X1)*Fgis_GetPlanchetWidth(interp,planchet));
79 }
80
81
82 /*
83  * Returns planchet y coordinate in pixels, given alternative (map) coordinate
84  */
85 int Fgis_PlanchetY(Tcl_Interp *interp,char *planchet,double y)
86 {double X1,Y1,X2,Y2;
87  if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR) 
88   return 0;
89  return floor((y-Y2)/(Y1-Y2)*Fgis_GetPlanchetHeight(interp,planchet));
90 }
91
92 /*
93  * Tcl commands to deal with coordinates. These commands duplicates
94  * functionality of quick-and-dirty ones above, but adds more error-cheking
95  * and eliminates duplication in Tk data structures access
96  */
97
98 /* 
99  * Tcl command fgisPlanchet_mapx implementation
100  */
101 EXPORT (int, Fgis_MapX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
102 { char result [255];
103   int x,width;
104   double X1,Y1,X2,Y2; 
105   Tk_Window p;
106   if (argc!=3) {
107      sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
108      Tcl_SetResult(interp,result,TCL_VOLATILE);
109      return TCL_ERROR;
110   } 
111   p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
112   if (!p) return TCL_ERROR;
113   if (Tk_GetPixels(interp,p,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
114   if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
115     return TCL_ERROR;
116   width=Tk_ReqWidth(p);
117   if (width==0) {
118       sprintf(result,"Planchet %s is not mapped",argv[1]);
119       Tcl_SetResult(interp,result,TCL_VOLATILE);
120       return TCL_ERROR;
121   }
122   Tcl_PrintDouble(interp,(x*(X2-X1)/width+X1),result);
123   Tcl_SetResult(interp,result,TCL_VOLATILE);
124   return TCL_OK; 
125 }
126
127 /* 
128  * Tcl command fgisPlanchet_mapy implementation
129  */
130 EXPORT(int, Fgis_MapY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
131 { char result [255];
132   int y,height;
133   double X1,Y1,X2,Y2; 
134   Tk_Window p;
135   if (argc!=3) {
136      sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
137      Tcl_SetResult(interp,result,TCL_VOLATILE);
138      return TCL_ERROR;
139   } 
140   p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
141   if (!p) return TCL_ERROR;
142   if (Tk_GetPixels(interp,p,argv[2],&y)==TCL_ERROR) return TCL_ERROR;
143   if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
144     return TCL_ERROR;
145   height=Tk_ReqHeight(p);
146   if (height==0) {
147       sprintf(result,"Planchet %s is not mapped",argv[1]);
148       Tcl_SetResult(interp,result,TCL_VOLATILE);
149       return TCL_ERROR;
150   }
151   Tcl_PrintDouble(interp,((height-y)*(Y2-Y1)/height+Y1),result);
152   Tcl_SetResult(interp,result,TCL_VOLATILE);
153   return TCL_OK; 
154 }
155
156 /* 
157  * Tcl command fgisPlanchet_scrx implementation
158  */
159 EXPORT(int, Fgis_ScrX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
160 { char result [255];
161   int width;
162   double x,X1,Y1,X2,Y2; 
163   Tk_Window p;
164   if (argc!=3) {
165      sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
166      Tcl_SetResult(interp,result,TCL_VOLATILE);
167      return TCL_ERROR;
168   } 
169   p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
170   if (!p) return TCL_ERROR;
171   if (Tcl_GetDouble(interp,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
172   if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
173     return TCL_ERROR;
174   width=Tk_ReqWidth(p);
175   if (width==0) {
176       sprintf(result,"Planchet %s is not mapped",argv[1]);
177       Tcl_SetResult(interp,result,TCL_VOLATILE);
178       return TCL_ERROR;
179   }
180   sprintf(result,"%d",(int)floor((x-X1)/(X2-X1)*width));
181   Tcl_SetResult(interp,result,TCL_VOLATILE);
182   return TCL_OK; 
183 }
184
185 /* 
186  * Tcl command fgisPlanchet_scry implementation
187  */
188 EXPORT(int, Fgis_ScrY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
189 { char result [255];
190   int height;
191   double y,X1,Y1,X2,Y2; 
192   Tk_Window p;
193   if (argc!=3) {
194      sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
195      Tcl_SetResult(interp,result,TCL_VOLATILE);
196      return TCL_ERROR;
197   } 
198   p=Tk_NameToWindow(interp,argv[1],Tk_MainWindow(interp));
199   if (!p) return TCL_ERROR;
200   if (Tcl_GetDouble(interp,argv[2],&y)==TCL_ERROR) return TCL_ERROR;
201   if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
202     return TCL_ERROR;
203   height=Tk_ReqHeight(p);
204   if (height==0) {
205       sprintf(result,"Planchet %s is not mapped",argv[1]);
206       Tcl_SetResult(interp,result,TCL_VOLATILE);
207       return TCL_ERROR;
208   }
209   sprintf(result,"%d",(int)floor((y-Y2)/(Y1-Y2)*height));
210   Tcl_SetResult(interp,result,TCL_VOLATILE);
211   return TCL_OK; 
212 }
213
214 EXPORT(int, Fgis_Fit)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
215 { char result [255];
216   double xrel,yrel,x,y,X1,Y1,X2,Y2; 
217   if (argc!=4) {
218      sprintf(result,"Wrong # args. Should be %s planchet x y",argv[0]);
219      Tcl_SetResult(interp,result,TCL_VOLATILE);
220      return TCL_ERROR;
221   } 
222   if (Tcl_GetDouble(interp,argv[2],&x)==TCL_ERROR) return TCL_ERROR;
223   if (Tcl_GetDouble(interp,argv[3],&y)==TCL_ERROR) return TCL_ERROR;
224   if (Fgis_GetPlanchetLimits(interp,argv[1],&X1,&Y1,&X2,&Y2)==TCL_ERROR)
225     return TCL_ERROR;
226   xrel=(x-X1)/(X2-X1);
227   yrel=(y-Y1)/(Y2-Y1);
228   if (yrel>0.0 && yrel<1.0 && xrel>0.0 && yrel<1.0)  
229      Tcl_SetResult(interp,"1",TCL_STATIC);
230   else
231      Tcl_SetResult(interp,"0",TCL_STATIC);
232   return TCL_OK; 
233 }
234
235 /*
236  * Checks if given window is really planchet and coordinate system
237  * is defined. returns 0 on failure, 1 on success
238  */
239
240 int Fgis_ValidPlanchet(Tcl_Interp *interp,char *planchet)
241 { double a;
242     Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
243     if (!p) return 0;
244     if (Tk_GetUid("Canvas")!=Tk_Class(p)) {
245       Tcl_AppendResult(interp,planchet," is not Planchet window",NULL);
246       return 0;
247     }
248     if (Fgis_GetPlanchetLimits(interp,planchet,&a,&a,&a,&a)!=TCL_OK) {
249         Tcl_AppendResult(interp,planchet," has no coordinate system defined",
250                NULL);
251         return 0;
252     }
253     return 1;
254 }    
255