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

Last change on this file since 31665 was 31665, checked in by ak19, 7 years ago

GS3 source code now updated to use SafeProcess instead of Process (calling Runtime.exec() directly). The use of SafeProcess in RunTarget and BrowserLauncher has been tested on Linux. GDBMWrapper, MapRetrieve and admin/guiext's Command.java are not tested. For GDBMWrapper, because it's in a bit of code that works with txtgz databases. MapRetrive.java and Command.java are untested because I don't know how to test them.

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