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

Last change on this file since 28966 was 28966, checked in by kjdon, 10 years ago

Lots of changes. Mainly to do with removing this.doc from everywhere. Document is not thread safe. Now we tend to create a new Document everytime we are starting a new page/message etc. in service this.desc_doc is available as teh document to create service info stuff. But it should only be used for this and not for other messages. newDOM is now static for XMLConverter. method param changes for some GSXML methods.

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