6 * fgisPlanchet.c - coordinate recalculating commands for planchet widget,
8 * Copyright (c) by softweyr
11 /* internal converting function */
14 * Fills x1 y1 x2 y2 with limits of planchet coordinate system
15 * Returns TCL_OK on success
17 int Fgis_GetPlanchetLimits(Tcl_Interp *interp,char *planchet,
18 double *x1,double *y1,double *x2, double *y2)
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);
26 int Fgis_GetPlanchetWidth(Tcl_Interp *interp,char *planchet)
28 Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
29 if (p==NULL) return 0;
31 return Tk_ReqWidth(p);
33 int Fgis_GetPlanchetHeight(Tcl_Interp *interp,char *planchet)
36 Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
37 if (p==NULL) return 0;
38 return Tk_ReqHeight(p);
43 * Returns alternative (map) x, given planchet x in pixels
44 * No error checking - fast, for internal use. In case of error returns 0
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)
52 result= (x*(X2-X1)/width+X1);
57 * Returns alternative (map) y, given planchet y in pixels
58 * No error checking - fast, for internal use. In case of error returns 0
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)
67 result= ((height-y)*(Y2-Y1)/height+Y1);
72 * Returns planchet x coordinate in pixels, given alternative (map) coordinate
74 int Fgis_PlanchetX(Tcl_Interp *interp,char *planchet,double x)
76 if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
78 return floor((x-X1)/(X2-X1)*Fgis_GetPlanchetWidth(interp,planchet));
83 * Returns planchet y coordinate in pixels, given alternative (map) coordinate
85 int Fgis_PlanchetY(Tcl_Interp *interp,char *planchet,double y)
87 if (Fgis_GetPlanchetLimits(interp,planchet,&X1,&Y1,&X2,&Y2)==TCL_ERROR)
89 return floor((y-Y2)/(Y1-Y2)*Fgis_GetPlanchetHeight(interp,planchet));
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
99 * Tcl command fgisPlanchet_mapx implementation
101 EXPORT (int, Fgis_MapX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
107 sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
108 Tcl_SetResult(interp,result,TCL_VOLATILE);
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)
116 width=Tk_ReqWidth(p);
118 sprintf(result,"Planchet %s is not mapped",argv[1]);
119 Tcl_SetResult(interp,result,TCL_VOLATILE);
122 Tcl_PrintDouble(interp,(x*(X2-X1)/width+X1),result);
123 Tcl_SetResult(interp,result,TCL_VOLATILE);
128 * Tcl command fgisPlanchet_mapy implementation
130 EXPORT(int, Fgis_MapY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
136 sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
137 Tcl_SetResult(interp,result,TCL_VOLATILE);
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)
145 height=Tk_ReqHeight(p);
147 sprintf(result,"Planchet %s is not mapped",argv[1]);
148 Tcl_SetResult(interp,result,TCL_VOLATILE);
151 Tcl_PrintDouble(interp,((height-y)*(Y2-Y1)/height+Y1),result);
152 Tcl_SetResult(interp,result,TCL_VOLATILE);
157 * Tcl command fgisPlanchet_scrx implementation
159 EXPORT(int, Fgis_ScrX)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
162 double x,X1,Y1,X2,Y2;
165 sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
166 Tcl_SetResult(interp,result,TCL_VOLATILE);
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)
174 width=Tk_ReqWidth(p);
176 sprintf(result,"Planchet %s is not mapped",argv[1]);
177 Tcl_SetResult(interp,result,TCL_VOLATILE);
180 sprintf(result,"%d",(int)floor((x-X1)/(X2-X1)*width));
181 Tcl_SetResult(interp,result,TCL_VOLATILE);
186 * Tcl command fgisPlanchet_scry implementation
188 EXPORT(int, Fgis_ScrY)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
191 double y,X1,Y1,X2,Y2;
194 sprintf(result,"Wrong # args. Should be %s planchet value",argv[0]);
195 Tcl_SetResult(interp,result,TCL_VOLATILE);
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)
203 height=Tk_ReqHeight(p);
205 sprintf(result,"Planchet %s is not mapped",argv[1]);
206 Tcl_SetResult(interp,result,TCL_VOLATILE);
209 sprintf(result,"%d",(int)floor((y-Y2)/(Y1-Y2)*height));
210 Tcl_SetResult(interp,result,TCL_VOLATILE);
214 EXPORT(int, Fgis_Fit)(ClientData data,Tcl_Interp* interp,int argc, char **argv)
216 double xrel,yrel,x,y,X1,Y1,X2,Y2;
218 sprintf(result,"Wrong # args. Should be %s planchet x y",argv[0]);
219 Tcl_SetResult(interp,result,TCL_VOLATILE);
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)
228 if (yrel>0.0 && yrel<1.0 && xrel>0.0 && yrel<1.0)
229 Tcl_SetResult(interp,"1",TCL_STATIC);
231 Tcl_SetResult(interp,"0",TCL_STATIC);
236 * Checks if given window is really planchet and coordinate system
237 * is defined. returns 0 on failure, 1 on success
240 int Fgis_ValidPlanchet(Tcl_Interp *interp,char *planchet)
242 Tk_Window p=Tk_NameToWindow(interp,planchet,Tk_MainWindow(interp));
244 if (Tk_GetUid("Canvas")!=Tk_Class(p)) {
245 Tcl_AppendResult(interp,planchet," is not Planchet window",NULL);
248 if (Fgis_GetPlanchetLimits(interp,planchet,&a,&a,&a,&a)!=TCL_OK) {
249 Tcl_AppendResult(interp,planchet," has no coordinate system defined",