source: greenstone3/trunk/src/java/org/greenstone/gsdl3/service/MapRetrieve.java@ 14225

Last change on this file since 14225 was 14225, checked in by xiao, 17 years ago

change getFirstChild() to getFirstElementChild() in case an extra line break or white space added before the first element child which might cause a cast exception.

  • Property svn:keywords set to Author Date Id Revision
File size: 35.4 KB
Line 
1package org.greenstone.gsdl3.service;
2
3// Greenstone classes
4import org.greenstone.gsdl3.util.*;
5
6// XML classes
7import org.w3c.dom.Document;
8import org.w3c.dom.Element;
9import org.w3c.dom.NodeList;
10
11// General Java classes
12import java.io.File;
13import java.io.*;
14import java.util.StringTokenizer;
15import java.util.Vector;
16import java.util.Set;
17import java.util.Iterator;
18import java.lang.reflect.Array;
19import java.util.Arrays;
20import java.util.ArrayList;
21import java.util.LinkedList;
22import javax.swing.tree.DefaultMutableTreeNode;
23
24import org.apache.log4j.*;
25
26public class MapRetrieve
27 extends ServiceRack {
28
29 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.MapRetrieve.class.getName());
30
31 // the services on offer
32 protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve";
33 protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve";
34 protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve";
35
36 protected static final int DOCUMENT=1;
37
38 protected ArrayList index_name_list = null;
39 protected ArrayList index_display_list = null;
40 protected String files_home_dir = null;
41 protected String temp_files_dir = null;
42 //protected String temp_image_file = null;
43 //protected String temp_image_file2 = null;
44 protected final String jpg_ext = ".jpg";
45 protected String http_image_dir = null;
46 protected String http_temp_image_dir = null;
47 private LinkedList namesInList = new LinkedList();
48
49 private DefaultMutableTreeNode tree;
50
51 /** constructor */
52 public MapRetrieve() {}
53
54
55 /** configure this service */
56 public boolean configure(Element info, Element extra_info)
57 {
58 if (!super.configure(info, extra_info)){
59 return false;
60 }
61
62 logger.info("Configuring MapRetrieve...");
63 this.config_info = info;
64
65 // set up short_service_info_ - for now just has name and type
66 Element dmr_service = doc.createElement(GSXML.SERVICE_ELEM);
67 dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
68 dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
69 short_service_info.appendChild(dmr_service);
70
71 Element dcr_service = doc.createElement(GSXML.SERVICE_ELEM);
72 dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
73 dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
74 short_service_info.appendChild(dcr_service);
75
76 Element dsr_service = doc.createElement(GSXML.SERVICE_ELEM);
77 dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
78 dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
79 short_service_info.appendChild(dsr_service);
80
81 // set the files_home variable for this collection
82 this.files_home_dir = GSFile.collectionIndexDir(this.site_home, this.cluster_name)+ File.separator+"assoc"+File.separator;
83 this.temp_files_dir = GSFile.collectionBaseDir(this.site_home, this.cluster_name) + File.separator + "temp"+File.separator;
84
85 //this.files_home_dir + "maps" + File.separator + "temp" + File.separator;
86 //this.temp_image_file = this.temp_files_dir+"temp_";
87 //this.temp_image_file2 = this.temp_files_dir+"temp2_";
88
89
90 this.http_image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/index/assoc/maps/";
91 this.http_temp_image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/temp/";
92
93 this.index_name_list = new ArrayList();
94 this.index_display_list = new ArrayList();
95 Element index_list = (Element)GSXML.getChildByTagName(this.config_info, GSXML.INDEX_ELEM+GSXML.LIST_MODIFIER);
96 Element display_index_list = (Element)GSXML.getChildByTagName(extra_info, "search");
97 if (index_list != null && display_index_list != null) {
98 NodeList indexes = index_list.getElementsByTagName(GSXML.INDEX_ELEM);
99 for (int i=0; i<indexes.getLength(); i++) {
100 String name = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
101 // add the index name
102 this.index_name_list.add(name);
103 // now look for the display name
104 Element this_index = GSXML.getNamedElement(display_index_list, "index", "name", name);
105 if (this_index != null) {
106 Element disp = GSXML.getNamedElement(this_index, "displayItem", "name", "name");
107 if (disp != null) {
108 String display = GSXML.getNodeText(disp);
109 if (!display.equals("")) {
110 this.index_display_list.add(display);
111 continue;
112 }
113
114 }
115 }
116 // add the id as default text
117 this.index_display_list.add(name);
118
119 }
120 }
121
122 // look for document display format
123 String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
124 Element display_format = (Element)GSXML.getNodeByPath(extra_info, path);
125 if (display_format != null) {
126 this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true));
127 // shoudl we make a copy?
128 }
129
130 // load the 2-dimensional tree for searching
131 try{
132 ObjectInputStream objectin = new ObjectInputStream(new FileInputStream(this.files_home_dir+"nametree.dat"));
133 tree = (DefaultMutableTreeNode)objectin.readObject();
134 objectin.close();
135 }catch(IOException ioe){
136 ioe.printStackTrace();
137 }catch(ClassNotFoundException cnfe){
138 cnfe.printStackTrace();
139 }
140
141
142 return true;
143 }
144
145 /** */
146 protected Element getServiceDescription(String service, String lang, String subset)
147 {
148 if (service.equals(DOCUMENT_STRUCTURE_RETRIEVE_SERVICE)) {
149
150 Element tq_service = doc.createElement(GSXML.SERVICE_ELEM);
151 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
152 tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
153 return tq_service;
154 }
155 else if (service.equals(DOCUMENT_METADATA_RETRIEVE_SERVICE)) {
156
157 Element tq_service = doc.createElement(GSXML.SERVICE_ELEM);
158 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
159 tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
160 return tq_service;
161 }
162 else if (service.equals(DOCUMENT_CONTENT_RETRIEVE_SERVICE)) {
163
164 Element tq_service = doc.createElement(GSXML.SERVICE_ELEM);
165 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
166 tq_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
167 return tq_service;
168 }
169
170 return null;
171
172 }
173
174 /** Retrieve the structure of a document */
175 protected Element processDocumentStructureRetrieve(Element request)
176 {
177 // Create a new (empty) result message
178 Element result = doc.createElement(GSXML.RESPONSE_ELEM);
179 return result;
180 }
181
182 protected Element processDocumentMetadataRetrieve(Element request) {
183 // Create a new (empty) result message
184 try{
185 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
186
187 String uid = request.getAttribute(GSXML.USER_ID_ATT);
188 if (uid.equals("")) {
189 logger.info("in metadata retrieve, uid = ''\n"+converter.getPrettyString(request));
190 }
191 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
192 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
193
194 // Get the parameters of the request
195 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
196 if (param_list == null) {
197 logger.error("missing paramList.\n");
198 return result; // Return the empty result
199 }
200
201 // The metadata information required
202 Vector metadata_list = new Vector();
203 boolean all_metadata = false;
204 // Process the request parameters
205 Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild();
206
207 while (param != null) {
208 // Identify the metadata information desired
209 if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) {
210 String metadata = GSXML.getValue(param);
211 if (metadata.equals("all")) {
212 all_metadata = true;
213 break;
214 }
215 metadata_list.add(metadata);
216 }
217 param = (Element) param.getNextSibling();
218 }
219
220 Element node_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
221 result.appendChild(node_list);
222
223 // Get the documents
224 Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
225 if (request_node_list == null) {
226 logger.error(" DocumentMetadataRetrieve request had no "+GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
227 return result;
228 }
229
230 NodeList request_nodes = request_node_list.getChildNodes();
231
232 try{
233 //used just to ensure outfile is initialised
234 BufferedWriter outfile = new BufferedWriter(new FileWriter(this.temp_files_dir+"emptynothingness"));
235
236 for (int i = 0; i < request_nodes.getLength(); i++) {
237 Element request_node = (Element) request_nodes.item(i);
238 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
239 String place_data = "";
240 String year = "";
241 String coOrdinates = "";
242 String thumb = "";
243 String link = "";
244 int mapFreq = 0;
245 LinkedList place_data_list = new LinkedList();
246 LinkedList coOrdinates_list = new LinkedList();
247
248 //if this is a first displaying of the map
249 if(node_id.indexOf("```") != -1 && node_id.indexOf("imageChooser") == -1){
250 //get the number of query terms on this map
251 mapFreq = Integer.parseInt(node_id.substring(node_id.lastIndexOf('`',node_id.indexOf("```")-1)+1,node_id.indexOf("```")));
252 //get the place names on this map
253 place_data = node_id.substring(node_id.indexOf("```")+3,node_id.length());
254 //get the map metadata
255 node_id = node_id.substring(0,node_id.indexOf('`',node_id.indexOf("```")));
256
257 try{
258 // loop for each query term on the map
259 for(int r=0; r<mapFreq; r++){
260 // get title, type, location, and the string for creating the hyperlink for this query term
261 String title = place_data.substring(0,place_data.indexOf('`'));
262 String type = place_data.substring(place_data.indexOf('`')+1,place_data.indexOf('`',place_data.indexOf('`')+1));
263 String location = place_data.substring(place_data.indexOf('`',place_data.indexOf('`')+1)+1, place_data.indexOf('`',place_data.indexOf('`',place_data.indexOf('`')+1)+1));
264 if(place_data.indexOf("```") != -1)
265 link=place_data.substring(0,place_data.indexOf("```"));
266 else
267 link=place_data;
268 // resolve the type and location
269 type = getType(type);
270 location = getLocation(location);
271 // remove this query term from the string
272 if(place_data.indexOf("```") != -1)
273 place_data = place_data.substring(place_data.indexOf("```")+3,place_data.length());
274
275 //add the co-ordinates of this query term to the co-ordinates list
276 coOrdinates_list.add("`"+link.substring(link.lastIndexOf('`')+1,link.length())+"`"+link.substring(link.lastIndexOf('`',link.lastIndexOf('`')-1)+2,link.lastIndexOf('`')));
277
278 // add the title, type and location to the places list
279 place_data_list.add(title + ", " + type + ", " + location + ";");
280 }
281 }catch(StringIndexOutOfBoundsException sioobe){sioobe.printStackTrace();}
282 }
283
284 // Add the document to the list
285 Element new_node = (Element)this.doc.importNode(request_node, false);
286 node_list.appendChild(new_node);
287
288 // Add the requested metadata information
289 Element node_meta_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
290 new_node.appendChild(node_meta_list);
291
292 // create the navigation thumbnails. This doesn't seem to work most of the time ???????
293 for (int m = 0; m < metadata_list.size(); m++) {
294 String metadata = (String) metadata_list.get(m);
295 thumb = "";
296 String value = "";
297 if(node_id.indexOf('.') != -1)
298 thumb = node_id.substring(0,node_id.indexOf('.'));
299 if(node_id.indexOf('`') != -1)
300 value = node_id.substring(node_id.lastIndexOf('`',node_id.lastIndexOf('`')-1)+1,node_id.lastIndexOf('`',node_id.lastIndexOf('`')-1)+5);
301 year = value;
302
303 place_data="";
304 if(place_data_list.size() != 0)
305 for(int q=0; q<mapFreq; q++){
306 link = (String)place_data_list.get(q);
307 if(q!=0){
308 place_data = place_data + "<br>" + link;
309 }
310 else{
311 place_data = link;
312 coOrdinates = "``";
313 }
314 coOrdinates = coOrdinates+(String)coOrdinates_list.get(q);
315 }
316
317 link = "<a href=\"?a=d&c="+this.cluster_name+"&d="+node_id+coOrdinates+"&dt=map\">";
318 thumb = "<img src=\""+this.http_image_dir + thumb + "thumb.jpg\" border=0>";
319 value = "<table><tr><td>"+link+"<p>"+place_data+"<br>"+value+"</a></td><td>"+link+thumb+"</a></td></tr></table>";
320 if(metadata.equals("Title"))
321 if(!(place_data.equals("")) && place_data.indexOf(", , ;")==-1 && node_id.indexOf("```")==-1)
322 GSXML.addMetadata(this.doc, node_meta_list, "Title", value);//metadata, value);
323 else
324 GSXML.addMetadata(this.doc, node_meta_list, metadata, "");
325
326 if(place_data.indexOf(", , ;")==-1){
327 if(i==0)
328 if(!(mapFreq==0)){
329 outfile = new BufferedWriter(new FileWriter(this.temp_files_dir+"links"+uid));
330 outfile.write("<table align=\"center\"><tr>");
331 }
332
333 if(!(mapFreq==0)){
334 if(i%7 == 0)
335 outfile.write("</tr><tr>");
336 outfile.write("<td align=\"center\">"+link+thumb+"</a><br>"+link+year+"</a></td>");
337 }
338
339 if(i == request_nodes.getLength()-1){
340 outfile.write("</tr></table><p>");
341 outfile.flush();
342 outfile.close();
343 }
344 }
345 }
346
347 }
348 }catch(IOException ioe){ioe.printStackTrace();}
349
350 return result;
351 }catch(Exception excep){excep.printStackTrace();}
352 return null;
353
354 }
355
356 protected Element processDocumentContentRetrieve(Element request){
357 // Create a new (empty) result message
358 Element result = doc.createElement(GSXML.RESPONSE_ELEM);
359 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
360 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
361
362 String uid = request.getAttribute(GSXML.USER_ID_ATT);
363 String temp_image_file = this.temp_files_dir+"temp_"+uid+".jpg";
364 String temp_image_file2 = this.temp_files_dir+"temp_"+uid+"_2.jpg";
365
366 Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
367 if (query_doc_list == null) {
368 logger.error("DocumentContentRetrieve request specified no doc nodes.\n");
369 return result;
370 }
371
372 String legend_file = this.temp_files_dir+"legend_"+uid+".jpg";
373 String blank_file = this.files_home_dir + "blank.jpg";
374 Element doc_list = doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
375 result.appendChild(doc_list);
376
377 // Get the documents
378 String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list,
379 GSXML.NODE_ID_ATT);
380
381 for (int i = 0; i < doc_ids.length; i++) {
382 String doc_id = doc_ids[i];
383 // img_num is the name of the map file eg. 072.jpg
384 String img_num = doc_id.substring(0,doc_id.indexOf('.'));
385 // strings for inserting image in html
386 String img_left = "<img border=0 src=\""+this.http_temp_image_dir;
387 String doc_content = "";
388 String co_ordinates = "";
389 String img_size = "";
390 int height = 0;
391 int width = 0;
392 // the number for the legend image if adding locations to the map
393 int leg_num = 0;
394 double ratio = 0;
395
396 // if user has clicked on the map. This does not resolve maps that are not North oriented.
397 if(doc_id.indexOf("imageChooser")==0){
398 try{
399 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length());
400 img_num = doc_id.substring(0,doc_id.indexOf('.'));
401
402 // get the map size
403 String get_size[] = {"identify","-size","10000", temp_image_file};
404 Process proc;
405 proc = Runtime.getRuntime().exec(get_size);
406 BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
407 img_size = br.readLine();
408 proc.waitFor();
409 img_size = img_size.substring(img_size.indexOf("JPEG")+5,img_size.indexOf(" ",img_size.indexOf("JPEG")+5));
410 width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x")));
411 height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length()));
412
413 // scale image size according to the ratio
414 ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`',doc_id.indexOf("```")-1)+1,doc_id.indexOf("```")));
415 width = (int)(width*ratio);
416 height = (int)(height*ratio);
417
418 // get the position of the mouse click on the image
419 int xclick = Integer.parseInt(doc_id.substring(doc_id.indexOf("```")+3,doc_id.lastIndexOf('`')));
420 int yclick = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length()));
421 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.indexOf("```"));
422
423 // convert click position to percentage distance accross and down the image.
424 double xpercent = (xclick*1.0)/width;
425 double ypercent = (yclick*1.0)/height;
426
427 // get the top left and bottom right co-ordinates of the map
428 double ytop = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')))*-1;
429 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length());
430 double xleft = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')));
431 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length());
432 double ybot = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')))*-1;
433 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length());
434 double xright = Double.parseDouble(doc_id.substring(0,doc_id.indexOf('`')));
435 doc_id = doc_id.substring(doc_id.indexOf('`')+1,doc_id.length());
436
437 // calculate the map co-ordinates of the mouse click
438 xpercent = ((xright-xleft)*xpercent)+xleft;
439 ypercent = ((ybot-ytop)*ypercent)+ytop;
440
441 // search the tree for nearby place names
442 namesInList.clear();
443 findName(xpercent, ypercent, 0.1, 0.1, tree, true);
444
445 int namesInArraySize = namesInList.size();
446 String returnNames[]=new String[namesInArraySize];
447
448 //put the names in an array
449 for(int ri=0; namesInList.size()>0; ri++){
450 returnNames[ri]=(String)namesInList.getFirst();
451 returnNames[ri] = returnNames[ri].substring(0,returnNames[ri].indexOf('`'));
452 namesInList.removeFirst();
453 }
454
455 //sort the names
456 Arrays.sort(returnNames);
457 doc_content = "\n<script>\nfunction openIt(loc){\n\topener.location=loc;\n\tself.close();\n}\n</script>";
458 for(int nameIndex=0; nameIndex < namesInArraySize; nameIndex++){
459 String tempName = returnNames[nameIndex];
460 //convert names with spaces for hyperlinks
461 if(returnNames[nameIndex].indexOf(' ') != -1){
462 returnNames[nameIndex] = returnNames[nameIndex].replaceAll(" ","+");
463 returnNames[nameIndex] = "%22"+returnNames[nameIndex]+"%22";
464 }
465 // add the place name to the html
466 doc_content = doc_content+"<a href=\"\" onClick=openIt('?a=q&sa=&rt=r&s=MapQuery&c="+this.cluster_name+"&startPage=1&s1.index=none&s1.maxDocs=10&s1.query="+returnNames[nameIndex]+"')>"+tempName+"</a><br>";
467 }
468
469 }catch(Exception ioexception){ioexception.printStackTrace();}
470 }
471 else{
472
473 try{
474 //file for converting image
475 BufferedWriter bw = new BufferedWriter(new FileWriter(this.temp_files_dir + "add_x_"+uid));;
476 Process proc;
477
478 // if a new search
479 if(doc_id.indexOf("```") != -1){
480 // copy requested map to temp.jpg
481 proc = Runtime.getRuntime().exec("cp "+this.files_home_dir+"maps"+File.separator+img_num+".jpg "+temp_image_file);
482 proc.waitFor();
483 }
484
485 //get the image size
486 String get_size[] = {"identify","-size","10000", temp_image_file};
487 proc = Runtime.getRuntime().exec(get_size);
488 BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
489 img_size = br.readLine();
490 proc.waitFor();
491 img_size = img_size.substring(img_size.indexOf("JPEG")+5,img_size.indexOf(" ",img_size.indexOf("JPEG")+5));
492 if (img_size.indexOf("+")!=-1) {
493 img_size = img_size.substring(0, img_size.indexOf("+"));
494 }
495 width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x")));
496 height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length()));
497
498 // if a new search
499 if(doc_id.indexOf("```") != -1){
500 co_ordinates = doc_id.substring(doc_id.indexOf("```")+2, doc_id.length());
501 // get the number of places to mark on the map
502 int x_number = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`',doc_id.indexOf("```")-1)+1,doc_id.indexOf("```")));
503
504 //write the convert command
505 bw.write("convert -font helvetica -fill red -pointsize 48 ");
506
507 for(int xi=0; xi<x_number; xi++){
508
509 // get the co-ordinates of the place name
510 double xco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1)+1,co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1)+7));
511 double yco = Double.parseDouble(co_ordinates.substring(co_ordinates.lastIndexOf('`')+1,co_ordinates.length()));
512 if(xi != x_number-1)
513 co_ordinates = co_ordinates.substring(0,co_ordinates.lastIndexOf('`',co_ordinates.lastIndexOf('`')-1));
514
515 int index = 0;
516 index = doc_id.indexOf('`')+2;
517
518 // get the zoom ratio and the top left and bottom right co-ordinates of the map
519 ratio = 0.4;
520 double tly = Double.parseDouble(doc_id.substring(index,index+5));
521 index = doc_id.indexOf('`',index)+1;
522 double tlx = Double.parseDouble(doc_id.substring(index,index+6));
523 index = doc_id.indexOf('`',index)+2;
524 double bry = Double.parseDouble(doc_id.substring(index,index+5));
525 index = doc_id.indexOf('`',index)+1;
526 double brx = Double.parseDouble(doc_id.substring(index,index+6));
527 index = doc_id.indexOf('`',index)+1;
528 double orient = Double.parseDouble(doc_id.substring(index,doc_id.indexOf('`',index)));
529
530 // find the centre of the map
531 double xcent = ((brx-tlx)/2)+tlx;
532 double ycent = ((bry-tly)/2)+tly;
533
534 // get the orientation of the map
535 orient = Math.toRadians(orient);
536
537 // rotate the co-ordinates around the centre of the map
538 xco=xco-xcent;
539 yco=yco-ycent;
540 double oldx=xco;
541 xco=xco*Math.cos(orient)-yco*Math.sin(orient);
542 yco=oldx*Math.sin(orient)+yco*Math.cos(orient);
543 xco=xco+xcent;
544 yco=yco+ycent;
545 xco = (xco-tlx)/(brx-tlx);
546 yco = (yco-tly)/(bry-tly);
547
548 // calculate the pixels for placing the mark
549 width = (int)(xco*width)-5;
550 height = (int)(yco*height)-5;
551
552 // write the options for convert
553 bw.write("-draw 'text "+width+","+height+" \"x\"' ");
554 bw.flush();
555
556 // reset the width and height variables for the image
557 width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x")));
558 height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length()));
559 }
560 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`',doc_id.indexOf("```")-1));
561
562 // write the end of the convert command, then command for zooming image to the right level, then command to copy the blank image over legend.jpg
563 bw.write(temp_image_file+" "+temp_image_file+";convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2+";cp "+blank_file +" "+legend_file);
564
565 // reset legend number
566 leg_num = 0;
567 }
568
569 else
570 // if changing zoom level
571 if(doc_id.substring(doc_id.lastIndexOf('`'),doc_id.length()).indexOf('.')!=-1){
572 // get the ratio
573 ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length()));
574 // write the command for scaling image
575 bw.write("convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2);
576 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`'));
577 }
578
579 // if adding locations to map
580 else{
581
582 // get the location type to add
583 String restricter= doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length());
584 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`'));
585
586 // get the number for the legend image
587 leg_num = Integer.parseInt(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length()));
588 doc_id = doc_id.substring(0,doc_id.lastIndexOf('`'));
589
590 //open file for location type
591 BufferedReader inType = new BufferedReader(new FileReader(this.files_home_dir + "place_types"+File.separator + restricter + ".txt"));
592
593 //check through the file and add any places that are in the bounds of this map.
594
595 // check value. set to true if a place to add is found
596 boolean add_place_type = false;
597
598 int index = 0;
599 index = doc_id.indexOf('`')+2;
600 // get zoom ratio
601 ratio = Double.parseDouble(doc_id.substring(doc_id.lastIndexOf('`')+1,doc_id.length()));
602 // get top left and bottom right co-ordinates of the map
603 double tly = Double.parseDouble(doc_id.substring(index,index+5));
604 index = doc_id.indexOf('`',index)+1;
605 double tlx = Double.parseDouble(doc_id.substring(index,index+6));
606 index = doc_id.indexOf('`',index)+2;
607 double bry = Double.parseDouble(doc_id.substring(index,index+5));
608 index = doc_id.indexOf('`',index)+1;
609 double brx = Double.parseDouble(doc_id.substring(index,index+6));
610 index = doc_id.indexOf('`',index)+1;
611 // get orientation of the map
612 double orient = Double.parseDouble(doc_id.substring(index,doc_id.indexOf('`',index)));
613 // calculate centre of map
614 double xcent = ((brx-tlx)/2)+tlx;
615 double ycent = ((bry-tly)/2)+tly;
616 orient = Math.toRadians(orient);
617
618 String type_point = "";
619 double xco = 0.0;
620 double yco = 0.0;
621
622 // read the file
623 while(inType.ready()){
624 //read a line
625 type_point = inType.readLine();
626
627 // get the co-ordinates of the point
628 xco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`')+1,type_point.length()));
629 yco = Double.parseDouble(type_point.substring(type_point.lastIndexOf('`',type_point.lastIndexOf('`')-1)+2,type_point.lastIndexOf('`')));
630
631 // if it is within the co-ordinates of the map
632 if(xco >= tlx && xco < brx && yco >= tly && yco < bry){
633 // rotate the point around the centre according to map orientation
634 xco=xco-xcent;
635 yco=yco-ycent;
636 double oldx=xco;
637 xco=xco*Math.cos(orient)-yco*Math.sin(orient);
638 yco=oldx*Math.sin(orient)+yco*Math.cos(orient);
639 xco=xco+xcent;
640 yco=yco+ycent;
641 // get the pixels for where to place the mark
642 xco = (xco-tlx)/(brx-tlx);
643 yco = (yco-tly)/(bry-tly);
644 width = (int)(xco*width)-5;
645 height = (int)(yco*height)-5;
646
647 //if this is the first point to be added
648 if(!add_place_type){
649 // write the initial convert command
650 bw.write("convert -font helvetica -fill red -pointsize 36 ");
651 // toggle check value
652 add_place_type = true;
653 }
654
655 // write the options for the convert command
656 bw.write("-draw 'text "+width+","+height+" \""+leg_num+"\"' ");
657 bw.flush();
658
659 // reset width and height variables for the image
660 width = Integer.parseInt(img_size.substring(0,img_size.indexOf("x")));
661 height = Integer.parseInt(img_size.substring(img_size.indexOf("x")+1,img_size.length()));
662 }
663 }
664
665 //if there are places to mark on the map
666 if(add_place_type){
667 // finish the convert command and write command for scaling image
668 bw.write(temp_image_file+" "+temp_image_file+";convert -scale "+((int)(ratio*width))+"x"+((int)(ratio*height))+" "+temp_image_file+" "+temp_image_file2);
669
670 // open file for converting the legend command
671 BufferedWriter buf = new BufferedWriter(new FileWriter(this.temp_files_dir+"add_l_"+uid));
672 if(leg_num == 1)
673 buf.write("cp "+blank_file +" "+legend_file+";");
674 // write the command for adding to the legend
675 buf.write("convert -font helvetica -fill red -pointsize 12 -draw 'text 15,"+(leg_num*15+20)+" \""+leg_num+" "+getType(restricter)+"\"' "+legend_file+" "+legend_file);
676 buf.flush();
677 buf.close();
678 // execute the command for the legend image
679 proc = Runtime.getRuntime().exec("sh "+this.temp_files_dir+"add_l_"+uid);
680 proc.waitFor();
681 }
682 inType.close();
683 }
684 bw.flush();
685 bw.close();
686
687 // execute the convert commands etc.
688 proc = Runtime.getRuntime().exec("sh "+this.temp_files_dir+"add_x_"+uid);
689 proc.waitFor();
690
691 }catch(Exception ioe){ioe.printStackTrace();}
692
693 //write the html for the document
694
695 String doc_content_head = "?a=d&c="+this.cluster_name+"&dt=map&d=";
696 doc_content = "<td valign=\"top\"><script>document.write('"+img_left+"legend_"+uid+".jpg"+"?'+new Date().getTime())</script>\"></td>";
697 doc_content = doc_content+"<td><script>document.write('"+img_left+"temp_"+uid+"_2.jpg?'+new Date().getTime())</script>\" onclick=\"imgClickHandler(event, this, '"+img_num+"')\"></td>";
698
699 // replace _httpimg_ with the correct address
700 doc_content = "<table><tr>"+doc_content+"</tr></table>";
701
702 String javascript = getJavascript(ratio, doc_id, leg_num);
703
704 doc_content = "<center>You are currently viewing the map at "+(int)(ratio*100)+"%<br>Select a radio button for a new zoom level.</center>"+javascript+doc_content;
705 doc_content = doc_content.replaceAll("zoomhead", doc_content_head);
706 doc_content = doc_content.replaceAll("placeChooserImage", doc_content_head+"imageChooser`"+doc_id+"`"+ratio);
707
708 // read the file for the navigation thumbnails
709 try{
710 BufferedReader infile = new BufferedReader(new FileReader(this.temp_files_dir+"links"+uid));
711 doc_content = doc_content + infile.readLine();
712 infile.close();
713 }catch(Exception ioexc){ioexc.printStackTrace();}
714 }
715
716 // put the html in a text node
717 Element text_doc = doc.createElement(GSXML.DOC_NODE_ELEM);
718 text_doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
719 GSXML.addDocText(doc, text_doc, doc_content);
720 doc_list.appendChild(text_doc);
721
722 }
723 return result;
724 }
725
726 // resolves location codes for places from LINZ database
727 private String getLocation(String location){
728 String read;
729 try{
730 BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir+"files"+File.separator+"landdist.txt"));
731 in.readLine();
732 while(in.ready()){
733 read = in.readLine();
734 if(read.substring(0,2).equals(location)){
735 in.close();
736 return read.substring(3, read.length());
737 }
738 }
739 }catch(Exception e){}
740 return "";
741 }
742
743 // resolves type codes for the LINZ database
744 private String getType(String type){
745 String read;
746 try{
747 BufferedReader in = new BufferedReader(new FileReader(this.files_home_dir+"files"+File.separator+"pointdes.txt"));
748 in.readLine();
749 while(in.ready()){
750 read = in.readLine();
751 if(read.substring(0,read.indexOf('`')).toLowerCase().equals(type.toLowerCase())){
752 in.close();
753 return read.substring(read.indexOf('`')+1, read.indexOf(':'));
754 }
755 }
756 }catch(Exception e){}
757 return "";
758 }
759
760 //recursive pre-order traversal of the 2-dimensional tree
761 // x & y are co-ordinates of mouse click, xoff & yoff are the distance in degrees away from x & y to search,
762 // d is the current node of the tree, xcomp controls whether searching is by x co-ordinate or y co-ordinate.
763 private void findName(double x, double y, double xoff, double yoff, DefaultMutableTreeNode d, boolean xcomp){
764 //if a leaf node return. All leaf nodes are empty
765 if(d.isLeaf())
766 return;
767 //get coordinates of the current node
768 double xco = Double.parseDouble(((String)d.getUserObject()).substring(((String)d.getUserObject()).length()-6,((String)d.getUserObject()).length()));
769 double yco = Double.parseDouble(((String)d.getUserObject()).substring(((String)d.getUserObject()).length()-12,((String)d.getUserObject()).length()-7));
770 //if in range
771 if((x-xoff)<xco && (x+xoff)>xco && (y-yoff)<yco && (y+yoff)>yco){
772 //add to list
773 namesInList.addFirst((String)d.getUserObject());
774 }
775 //if comparing the x axis
776 if(xcomp){
777 //if need to search left subtree
778 if((x-xoff)<xco)
779 findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(0),!xcomp);
780 //if need to search right subtree
781 if((x+xoff)>xco)
782 findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(1),!xcomp);
783 }
784 else{
785 //if need to search left subtree
786 if((y-yoff)<yco)
787 findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(0),!xcomp);
788 //if need to search right subtree
789 if((y+yoff)>yco)
790 findName(x,y,xoff,yoff,(DefaultMutableTreeNode)d.getChildAt(1),!xcomp);
791 }
792 }
793
794 // a whole lot of stuff for the html that is hidden at the bottom here because it clutters more than I already have further up!
795 private String getJavascript(double ratio, String doc_id, int leg_num)
796 {
797 String javascript = "\n<script>\nfunction imgClickHandler (evt, img, num) {\n\tif (window.event){\n\t\tvar chooserString = 'placeChooserImage' + '```' + window.event.offsetX + '`' + window.event.offsetY\n\t\tmywindow = window.open(chooserString,'Choose','width=600, height=500, scrollbars=yes, resizable=yes, toolbar=no, location=no, status=yes, menubar=no');\n\t\t//alert(window.event.offsetX + ':' + window.event.offsetY + ':' + num);\n\t}\n\telse if (evt.target) {\n\t\tvar coords = {x: 0, y: 0 };\n\t\tvar el = evt.target;\n\t\tdo {\n\t\t\tcoords.x += el.offsetLeft;\n\t\t\tcoords.y += el.offsetTop;\n\t\t}\n\t\twhile ((el = el.offsetParent));\n\t\tvar offsetX = evt.clientX - coords.x;\n\t\tvar offsetY = evt.clientY - coords.y;\n\t\talert(offsetX + ':' + offsetY + ':' + num);\n\t}\n}\nfunction leapTo (link)\n{\n\tvar new_url=link;\n\tif ( (new_url != \"\") && (new_url != null) ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}\nfunction jumpTo (front,link,back)\n{\n\tvar new_url=front+link+back;\n\tif ( (new_url != \"\") && (new_url != null) ) \n\t\twindow.location=new_url;\n\telse \n\t\talert(\"You must make a selection.\");\n}// Deactivate Cloaking -->\n</script>";
798
799 String radioButtons = "\n<center><FORM>";
800 if(ratio != 0.4)
801 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.4')\">40%";
802 if(ratio != 0.5)
803 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.5')\">50%";
804 if(ratio != 0.6)
805 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.6')\">60%";
806 if(ratio != 0.7)
807 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.7')\">70%";
808 if(ratio != 0.8)
809 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.8')\">80%";
810 if(ratio != 0.9)
811 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`0.9')\">90%";
812 if(ratio != 1.0)
813 radioButtons = radioButtons + "\n\t<INPUT TYPE=\"radio\" NAME=\"buttons1\" onClick=\"leapTo('zoomhead"+doc_id+"`1.0')\">100%";
814 radioButtons = radioButtons + "\n</FORM></center>";
815
816 leg_num = leg_num+1;
817
818 String doc_link = "?a=d&c="+this.cluster_name+"&dt=map&d="+doc_id+"`"+ratio+"`"+leg_num+"`";
819
820 StringBuffer dropDownBox = new StringBuffer();
821
822 dropDownBox.append("Add Locations Of Type: <form name=\"myForm\"><select name=\"s1index\" onChange=\"jumpTo('");
823 dropDownBox.append(doc_link);
824 dropDownBox.append("',document.myForm.s1index.options[document.myForm.s1index.selectedIndex].value,'')\">\n");
825
826 for (int i=0; i<this.index_name_list.size(); i++) {
827 String name = (String)this.index_name_list.get(i);
828 dropDownBox.append("<option value=\"");
829 dropDownBox.append(name);
830 dropDownBox.append("\">");
831 String display = (String)this.index_display_list.get(i);
832 dropDownBox.append(display);
833 dropDownBox.append("\n");
834 }
835 // for each option, Malcolm had onClick=\"leapTo('"+doc_link+name+"')\" - dont seem to need this
836 dropDownBox.append("</select></form>\n");
837
838 return javascript + radioButtons + dropDownBox;
839 }
840}
Note: See TracBrowser for help on using the repository browser.