/webportal/src/main/java/org/ala/spatial/wms/WMSService.java

http://alageospatialportal.googlecode.com/ · Java · 580 lines · 476 code · 59 blank · 45 comment · 121 complexity · 656de807df4a2a695bf66b2bf91339cf MD5 · raw file

  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package org.ala.spatial.wms;
  6. import au.org.emii.portal.config.ConfigurationLoaderStage1;
  7. import au.org.emii.portal.util.SessionPrint;
  8. import java.awt.AlphaComposite;
  9. import java.awt.BasicStroke;
  10. import java.awt.Color;
  11. import java.awt.Graphics2D;
  12. import java.awt.Image;
  13. import java.awt.RenderingHints;
  14. import java.awt.image.BufferedImage;
  15. import java.awt.image.BufferedImageOp;
  16. import java.io.BufferedReader;
  17. import java.io.FileInputStream;
  18. import java.io.IOException;
  19. import java.io.InputStreamReader;
  20. import java.io.OutputStream;
  21. import java.io.RandomAccessFile;
  22. import java.io.UnsupportedEncodingException;
  23. import java.net.URL;
  24. import java.net.URLDecoder;
  25. import java.util.ArrayList;
  26. import java.util.logging.Level;
  27. import java.util.logging.Logger;
  28. import javax.imageio.ImageIO;
  29. import javax.imageio.ImageReader;
  30. import javax.imageio.stream.ImageInputStream;
  31. import javax.inject.Inject;
  32. import javax.servlet.ServletOutputStream;
  33. import javax.servlet.http.HttpServletRequest;
  34. import javax.servlet.http.HttpServletResponse;
  35. import org.ala.spatial.data.Facet;
  36. import org.ala.spatial.data.FacetCache;
  37. import org.ala.spatial.data.Legend;
  38. import org.ala.spatial.data.QueryField;
  39. import org.ala.spatial.util.CommonData;
  40. import org.ala.spatial.util.Util;
  41. import org.springframework.stereotype.Controller;
  42. import org.springframework.web.bind.annotation.RequestMapping;
  43. import org.springframework.web.bind.annotation.RequestMethod;
  44. import org.springframework.web.bind.annotation.RequestParam;
  45. import org.springframework.web.bind.annotation.ResponseBody;
  46. /**
  47. *
  48. * @author Adam
  49. */
  50. @Controller
  51. public class WMSService {
  52. final static int HIGHLIGHT_RADIUS = 3;
  53. @Inject
  54. private FacetCache facetCache;
  55. /*
  56. http://spatial.ala.org.au/geoserver/wms/reflect?styles=&format=image/png&
  57. layers=ALA:occurrences&transparent=true&
  58. CQL_FILTER=speciesconceptid='urn:lsid:biodiversity.org.au:afd.taxon:cd149740-87b2-4da2-96dc-e1aa1f693438'&SRS=EPSG%3A900913&
  59. ENV=color%3A1dd183%3Bname%3Acircle%3Bsize%3A8%3Bopacity%3A0.8&
  60. VERSION=1.1.0&
  61. SERVICE=WMS&REQUEST=GetMap&
  62. EXCEPTIONS=application%2Fvnd.ogc.se_inimage&
  63. BBOX=15654303.7292,-1408886.9659,15810846.7631,-1252343.932&
  64. WIDTH=256&
  65. HEIGHT=256
  66. *
  67. */
  68. @RequestMapping(value = "/wms/reflect", method = RequestMethod.GET)
  69. public void getPointsMap(
  70. @RequestParam(value = "CQL_FILTER", required = false, defaultValue = "") String cql_filter,
  71. @RequestParam(value = "ENV", required = false, defaultValue = "") String env,
  72. @RequestParam(value = "BBOX", required = false, defaultValue = "") String bboxString,
  73. @RequestParam(value = "WIDTH", required = false, defaultValue = "") String widthString,
  74. @RequestParam(value = "HEIGHT", required = false, defaultValue = "") String heightString,
  75. HttpServletRequest request, HttpServletResponse response) {
  76. response.setHeader("Cache-Control", "max-age=86400"); //age == 1 day
  77. response.setContentType("image/png"); //only png images generated
  78. int width = 256, height = 256;
  79. try {
  80. width = Integer.parseInt(widthString);
  81. height = Integer.parseInt(heightString);
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. }
  85. try {
  86. env = URLDecoder.decode(env, "UTF-8");
  87. } catch (UnsupportedEncodingException ex) {
  88. Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex);
  89. }
  90. int red = 0, green = 0, blue = 0, alpha = 0;
  91. String name = "circle";
  92. int size = 4;
  93. boolean uncertainty = false;
  94. String highlight = null;
  95. String colourMode = null;
  96. for (String s : env.split(";")) {
  97. String[] pair = s.split(":");
  98. if (pair[0].equals("color")) {
  99. while (pair[1].length() < 6) {
  100. pair[1] = "0" + pair[1];
  101. }
  102. red = Integer.parseInt(pair[1].substring(0, 2), 16);
  103. green = Integer.parseInt(pair[1].substring(2, 4), 16);
  104. blue = Integer.parseInt(pair[1].substring(4), 16);
  105. } else if (pair[0].equals("name")) {
  106. name = pair[1];
  107. } else if (pair[0].equals("size")) {
  108. size = Integer.parseInt(pair[1]);
  109. } else if (pair[0].equals("opacity")) {
  110. alpha = (int) (255 * Double.parseDouble(pair[1]));
  111. // } else if (pair[0].equals("uncertainty")) {
  112. // uncertainty = true;
  113. } else if (pair[0].equals("sel")) {
  114. try {
  115. highlight = URLDecoder.decode(s.substring(4),"UTF-8").replace("%3B",";");
  116. } catch (Exception e) {}
  117. } else if (pair[0].equals("colormode")) {
  118. colourMode = pair[1];
  119. }
  120. }
  121. double[] bbox = new double[4];
  122. int i;
  123. i = 0;
  124. for (String s : bboxString.split(",")) {
  125. try {
  126. bbox[i] = Double.parseDouble(s);
  127. i++;
  128. } catch (Exception e) {
  129. e.printStackTrace();
  130. }
  131. }
  132. try {
  133. //adjust bbox extents with half pixel width/height
  134. double pixelWidth = (bbox[2] - bbox[0]) / width;
  135. double pixelHeight = (bbox[3] - bbox[1]) / height;
  136. bbox[0] += pixelWidth / 2;
  137. bbox[2] -= pixelWidth / 2;
  138. bbox[1] += pixelHeight / 2;
  139. bbox[3] -= pixelHeight / 2;
  140. //offset for points bounding box by size
  141. double xoffset = (bbox[2] - bbox[0]) / (double) width * (size + (highlight!=null?HIGHLIGHT_RADIUS*2 + size * 0.2:0) + 5);
  142. double yoffset = (bbox[3] - bbox[1]) / (double) height * (size + (highlight!=null?HIGHLIGHT_RADIUS*2 + size * 0.2:0) + 5);
  143. //check offset for points bb by maximum uncertainty (?? 30k ??)
  144. if (uncertainty) {
  145. double xuoffset = 30000;
  146. double yuoffset = 30000;
  147. if (xoffset < xuoffset) {
  148. xoffset = xuoffset;
  149. }
  150. if (yoffset < yuoffset) {
  151. yoffset = yuoffset;
  152. }
  153. }
  154. //adjust offset for pixel height/width
  155. xoffset += pixelWidth;
  156. yoffset += pixelHeight;
  157. double[][] bb = {{Utils.convertMetersToLng(bbox[0] - xoffset), Utils.convertMetersToLat(bbox[1] - yoffset)}, {Utils.convertMetersToLng(bbox[2] + xoffset), Utils.convertMetersToLat(bbox[3] + yoffset)}};
  158. double[] pbbox = new double[4]; //pixel bounding box
  159. pbbox[0] = Utils.convertLngToPixel(Utils.convertMetersToLng(bbox[0]));
  160. pbbox[1] = Utils.convertLatToPixel(Utils.convertMetersToLat(bbox[1]));
  161. pbbox[2] = Utils.convertLngToPixel(Utils.convertMetersToLng(bbox[2]));
  162. pbbox[3] = Utils.convertLatToPixel(Utils.convertMetersToLat(bbox[3]));
  163. String lsid = null;
  164. int p1 = 0;
  165. int p2 = cql_filter.indexOf('&', p1 + 1);
  166. if (p2 < 0) {
  167. p2 = cql_filter.indexOf(';', p1 + 1);
  168. }
  169. if (p2 < 0) {
  170. p2 = cql_filter.length();
  171. }
  172. if (p1 >= 0) {
  173. lsid = cql_filter.substring(0, p2);
  174. }
  175. double[] points = null;
  176. ArrayList<QueryField> listHighlight = null;
  177. QueryField colours = null;
  178. double[] pointsBB = null;
  179. Facet facet = null;
  180. String[] facetFields = null;
  181. if (highlight != null && !(colourMode != null && colourMode.equals("grid"))) {
  182. facet = Facet.parseFacet(highlight);
  183. facetFields = facet.getFields();
  184. listHighlight = new ArrayList<QueryField>();
  185. }
  186. if (lsid != null) {
  187. Object[] data = (Object[]) RecordsLookup.getData(lsid);
  188. points = (double[]) data[0];
  189. pointsBB = (double[]) data[2];
  190. if (points == null || points.length == 0
  191. || pointsBB[0] > bb[1][0] || pointsBB[2] < bb[0][0]
  192. || pointsBB[1] > bb[1][1] || pointsBB[3] < bb[0][1]) {
  193. setImageBlank(response);
  194. return;
  195. }
  196. ArrayList<QueryField> fields = (ArrayList<QueryField>) data[1];
  197. for (int j = 0; j < fields.size(); j++) {
  198. if (facet != null) {
  199. for (int k = 0; k < facetFields.length; k++) {
  200. if (facetFields[k].equals(fields.get(j).getName())) {
  201. listHighlight.add(fields.get(j));
  202. }
  203. }
  204. }
  205. if (colourMode != null) {
  206. if (fields.get(j).getName().equals(colourMode)) {
  207. colours = fields.get(j);
  208. }
  209. }
  210. }
  211. }
  212. /* TODO: make this a copy instead of create */
  213. BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  214. Graphics2D g = (Graphics2D) img.getGraphics();
  215. g.setColor(new Color(0, 0, 0, 0));
  216. g.fillRect(0, 0, width, height);
  217. g.setColor(new Color(red, green, blue, alpha));
  218. g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  219. int x, y;
  220. int pointWidth = size * 2 + 1;
  221. double width_mult = (width / (pbbox[2] - pbbox[0]));
  222. double height_mult = (height / (pbbox[1] - pbbox[3]));
  223. if (colourMode != null && colourMode.equals("grid")) {
  224. int divs = 16;
  225. double grid_width_mult = (width / (pbbox[2] - pbbox[0])) / (256 / divs);
  226. double grid_height_mult = (height / (pbbox[1] - pbbox[3])) / (256 / divs);
  227. int[][] gridCounts = new int[divs][divs];
  228. for (i = 0; i < points.length; i += 2) {
  229. x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * grid_width_mult);
  230. y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * grid_height_mult);
  231. if (x >= 0 && x < divs && y >= 0 && y < divs) {
  232. gridCounts[x][y]++;
  233. }
  234. }
  235. int xstep = 256 / divs;
  236. int ystep = 256 / divs;
  237. for (x = 0; x < divs; x++) {
  238. for (y = 0; y < divs; y++) {
  239. int v = gridCounts[x][y];
  240. if (v > 0) {
  241. if (v > 500) {
  242. v = 500;
  243. }
  244. int colour = Legend.getLinearColour(v, 0, 500, 0xFFFFFF00, 0xFFFF0000);
  245. g.setColor(new Color(colour));
  246. g.fillRect(x * xstep, y * ystep, xstep, ystep);
  247. }
  248. }
  249. }
  250. } else {
  251. //circle type
  252. if (name.equals("circle")) {
  253. if (colours == null) {
  254. for (i = 0; i < points.length; i += 2) {
  255. if (points[i] >= bb[0][0] && points[i] <= bb[1][0]
  256. && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) {
  257. x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult);
  258. y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult);
  259. g.fillOval(x - size, y - size, pointWidth, pointWidth);
  260. }
  261. }
  262. } else {
  263. int prevColour = -1; //!= colours[0]
  264. g.setColor(new Color(prevColour));
  265. for (i = 0; i < points.length; i += 2) {
  266. if (points[i] >= bb[0][0] && points[i] <= bb[1][0]
  267. && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) {
  268. int thisColour = colours.getColour(i / 2);
  269. if (thisColour != prevColour) {
  270. g.setColor(new Color(thisColour));
  271. prevColour = thisColour;
  272. }
  273. x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult);
  274. y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult);
  275. g.fillOval(x - size, y - size, pointWidth, pointWidth);
  276. }
  277. }
  278. }
  279. }
  280. if (highlight != null && facet != null) {
  281. g.setStroke(new BasicStroke(2));
  282. g.setColor(new Color(255, 0, 0, 255));
  283. int sz = size + HIGHLIGHT_RADIUS;
  284. int w = sz * 2 + 1;
  285. for (i = 0; i < points.length; i += 2) {
  286. if (points[i] >= bb[0][0] && points[i] <= bb[1][0]
  287. && points[i + 1] >= bb[0][1] && points[i + 1] <= bb[1][1]) {
  288. if (facet.isValid(listHighlight, i / 2)) {
  289. x = (int) ((Utils.convertLngToPixel(points[i]) - pbbox[0]) * width_mult);
  290. y = (int) ((Utils.convertLatToPixel(points[i + 1]) - pbbox[3]) * height_mult);
  291. g.drawOval(x - sz, y - sz, w, w);
  292. }
  293. }
  294. }
  295. }
  296. }
  297. g.dispose();
  298. try {
  299. OutputStream os = response.getOutputStream();
  300. ImageIO.write(img, "png", os);
  301. os.flush();
  302. os.close();
  303. } catch (IOException e) {
  304. e.printStackTrace();
  305. }
  306. } catch (Exception e) {
  307. e.printStackTrace();
  308. }
  309. //System.out.println("[wms tile: " + (System.currentTimeMillis() - start) + "ms]");
  310. }
  311. //256x256 transparent image
  312. static Object blankImageObject = new Object();
  313. static byte[] blankImageBytes = null;
  314. private void setImageBlank(HttpServletResponse response) {
  315. if (blankImageBytes == null && blankImageObject != null) {
  316. synchronized (blankImageObject) {
  317. if (blankImageBytes == null) {
  318. try {
  319. RandomAccessFile raf = new RandomAccessFile(WMSService.class.getResource("/blank.png").getFile(), "r");
  320. blankImageBytes = new byte[(int) raf.length()];
  321. raf.read(blankImageBytes);
  322. raf.close();
  323. } catch (IOException ex) {
  324. Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex);
  325. }
  326. }
  327. }
  328. }
  329. if (blankImageObject != null) {
  330. response.setContentType("image/png");
  331. try {
  332. ServletOutputStream outStream = response.getOutputStream();
  333. outStream.write(blankImageBytes);
  334. outStream.flush();
  335. outStream.close();
  336. } catch (IOException ex) {
  337. Logger.getLogger(WMSService.class.getName()).log(Level.SEVERE, null, ex);
  338. }
  339. }
  340. }
  341. @RequestMapping(value = "/occurrences", method = RequestMethod.GET)
  342. public
  343. @ResponseBody
  344. String getOccurrencesUploaded(HttpServletRequest request) {
  345. String q = request.getParameter("q");
  346. String box = request.getParameter("box");
  347. int start = Integer.parseInt(request.getParameter("start"));
  348. String[] bb = box.split(",");
  349. double long1 = Double.parseDouble(bb[0]);
  350. double lat1 = Double.parseDouble(bb[1]);
  351. double long2 = Double.parseDouble(bb[2]);
  352. double lat2 = Double.parseDouble(bb[3]);
  353. Object[] data = (Object[]) RecordsLookup.getData(q);
  354. int count = 0;
  355. String record = null;
  356. if (data != null) {
  357. double[] points = (double[]) data[0];
  358. ArrayList<QueryField> fields = (ArrayList<QueryField>) data[1];
  359. double[] pointsBB = (double[]) data[2];
  360. String metadata = (String) data[3];
  361. if (points == null || points.length == 0
  362. || pointsBB[0] > long2 || pointsBB[2] < long1
  363. || pointsBB[1] > lat2 || pointsBB[3] < lat1) {
  364. return null;
  365. } else {
  366. for (int i = 0; i < points.length; i += 2) {
  367. if (points[i] >= long1 && points[i] <= long2
  368. && points[i + 1] >= lat1 && points[i + 1] <= lat2) {
  369. if (count == start) {
  370. StringBuilder sb = new StringBuilder();
  371. for (QueryField qf : fields) {
  372. if (sb.length() == 0) {
  373. sb.append("{\"totalRecords\":<totalCount>,\"occurrences\":[{");
  374. } else {
  375. sb.append(",");
  376. }
  377. sb.append("\"").append(qf.getDisplayName()).append("\":\"");
  378. sb.append(qf.getAsString(i / 2).replace("\"", "\\\"")).append("\"");
  379. }
  380. sb.append("}]");
  381. sb.append(",\"metadata\":\"");
  382. sb.append(metadata);
  383. sb.append("\"");
  384. sb.append("}");
  385. record = sb.toString();
  386. }
  387. count++;
  388. }
  389. }
  390. }
  391. }
  392. if (record != null) {
  393. record = record.replace("<totalCount>", String.valueOf(count));
  394. }
  395. return record;
  396. }
  397. @RequestMapping(value = "/admin/reloadconfig", method = RequestMethod.GET)
  398. @ResponseBody
  399. public String reloadConfig() {
  400. //signal for reload
  401. ConfigurationLoaderStage1.loaders.get(0).interrupt();
  402. //reload the facet cache
  403. facetCache.reloadCache();
  404. //return summary
  405. StringBuilder html = new StringBuilder();
  406. //was it successful?
  407. return html.toString();
  408. }
  409. @RequestMapping(value = "/image2", method = RequestMethod.GET)
  410. public void image2(
  411. @RequestParam(value = "type", required = false, defaultValue = "jpg") String type,
  412. @RequestParam(value = "extents", required = true) String bbox,
  413. @RequestParam(value = "pixelwidth", required = false, defaultValue = "800") Integer width,
  414. @RequestParam(value = "psize", required = false, defaultValue = "3") Integer pointSize,
  415. @RequestParam(value = "pcolour", required = false, defaultValue = "FF0000") String pointColour,
  416. @RequestParam(value = "popacity", required = false, defaultValue = "0.6") Double pointOpacity,
  417. @RequestParam(value = "basemap", required = false, defaultValue = "world") String basemap,
  418. @RequestParam(value = "legend", required = false, defaultValue = "off") String legend,
  419. @RequestParam(value = "bs", required = false) String biocacheServer,
  420. HttpServletRequest request, HttpServletResponse response) throws Exception {
  421. try {
  422. String [] bb = bbox.split(",");
  423. int pminx = Utils.convertLngToPixel(Double.parseDouble(bb[0]));
  424. int pminy = Utils.convertLatToPixel(Double.parseDouble(bb[1]));
  425. int pmaxx = Utils.convertLngToPixel(Double.parseDouble(bb[2]));
  426. int pmaxy = Utils.convertLatToPixel(Double.parseDouble(bb[3]));
  427. int height = (int) Math.round(width * ((pminy - pmaxy) / (double)(pmaxx - pminx)));
  428. double [] extents = Util.transformBbox4326To900913(Double.parseDouble(bb[0]),Double.parseDouble(bb[1]),Double.parseDouble(bb[2]),Double.parseDouble(bb[3]));
  429. //"http://biocache.ala.org.au/ws/webportal/wms/reflect?
  430. //q=macropus&ENV=color%3Aff0000%3Bname%3Acircle%3Bsize%3A3%3Bopacity%3A1
  431. //&BBOX=12523443.0512,-2504688.2032,15028131.5936,0.33920000120997&WIDTH=256&HEIGHT=256");
  432. String speciesAddress = ((biocacheServer == null) ? CommonData.biocacheServer : biocacheServer)
  433. + "/webportal/wms/reflect?"
  434. + "ENV=color%3A" + pointColour
  435. + "%3Bname%3Acircle%3Bsize%3A" + pointSize
  436. + "%3Bopacity%3A" + pointOpacity
  437. + "&BBOX=" + extents[0] + "," + extents[1] + "," + extents[2] + "," + extents[3]
  438. + "&WIDTH=" + width + "&HEIGHT=" + height
  439. + "&" + request.getQueryString();
  440. System.out.println(speciesAddress);
  441. URL speciesURL = new URL(speciesAddress);
  442. BufferedImage speciesImage = ImageIO.read(speciesURL);
  443. //"http://spatial.ala.org.au/geoserver/wms/reflect?
  444. //LAYERS=ALA%3Aworld&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=
  445. //&FORMAT=image%2Fjpeg&SRS=EPSG%3A900913&BBOX=12523443.0512,-1252343.932,13775787.3224,0.33920000004582&WIDTH=256&HEIGHT=256"
  446. String basemapAddress = CommonData.geoServer + "/wms/reflect?"
  447. + "LAYERS=ALA%3A" + basemap
  448. + "&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES="
  449. + "&FORMAT=image%2Fjpeg&SRS=EPSG%3A900913"
  450. + "&BBOX=" + extents[0] + "," + extents[1] + "," + extents[2] + "," + extents[3]
  451. + "&WIDTH=" + width + "&HEIGHT=" + height
  452. + (!legend.equals("off")?"&format_options=layout:legend":"");
  453. System.out.println(basemapAddress);
  454. URL basemapURL = new URL(basemapAddress);
  455. BufferedImage basemapImage = ImageIO.read(basemapURL);
  456. BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  457. Graphics2D combined = (Graphics2D) img.getGraphics();
  458. combined.drawImage(basemapImage, 0, 0, Color.WHITE, null);
  459. combined.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
  460. combined.drawImage(speciesImage, null, 0, 0);
  461. combined.dispose();
  462. //response.setHeader("Cache-Control", "max-age=3600"); //age == 1hr
  463. if (type.equalsIgnoreCase("png")) {
  464. response.setContentType("image/png");
  465. OutputStream os = response.getOutputStream();
  466. ImageIO.write(img, type, os);
  467. os.close();
  468. } else {
  469. //handle jpeg + BufferedImage.TYPE_INT_ARGB
  470. BufferedImage img2;
  471. Graphics2D c2;
  472. (c2 = (Graphics2D) (img2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)).getGraphics()).drawImage(img, 0,0,Color.WHITE, null);
  473. c2.dispose();
  474. OutputStream os = response.getOutputStream();
  475. ImageIO.write(img2, type, os);
  476. os.close();
  477. response.setContentType("image/jpeg");
  478. }
  479. }catch (Exception e) {
  480. e.printStackTrace();
  481. }
  482. }
  483. @RequestMapping(value = "/image", method = RequestMethod.GET)
  484. public void image(
  485. @RequestParam(value = "type", required = false, defaultValue = "jpg") String type,
  486. @RequestParam(value = "bbox", required = false, defaultValue = "0,0,0,0") String bbox,
  487. @RequestParam(value = "width", required = false, defaultValue = "800") String width,
  488. @RequestParam(value = "height", required = false, defaultValue = "640") String height,
  489. @RequestParam(value = "basemap", required = false, defaultValue = "outline") String basemap,
  490. HttpServletRequest request, HttpServletResponse response) throws IOException {
  491. //zoom (minlong, minlat, maxlong, maxlat, lhs width, basemap
  492. String zoom = "n" + bbox + ",0," + basemap;
  493. //unique id
  494. String uid = String.valueOf(System.currentTimeMillis());
  495. String htmlpth = CommonData.print_output_path;
  496. String htmlurl = CommonData.print_output_url;
  497. SessionPrint sp = new SessionPrint(
  498. CommonData.webportalServer, "&" + request.getQueryString(),
  499. height, width,
  500. htmlpth, htmlurl, uid,
  501. zoom, "", 0, type);
  502. sp.print();
  503. response.setHeader("Cache-Control", "max-age=86400"); //age == 1 day
  504. if (type.equalsIgnoreCase("png")) {
  505. response.setContentType("image/png");
  506. } else if (type.equalsIgnoreCase("pdf")) {
  507. response.setContentType("application/pdf");
  508. } else {
  509. response.setContentType("image/jpeg");
  510. }
  511. OutputStream os = response.getOutputStream();
  512. FileInputStream fis = new FileInputStream(sp.getImageFilename());
  513. byte [] buffer = new byte[1024];
  514. int n;
  515. while((n = fis.read(buffer)) > 0) {
  516. os.write(buffer, 0, n);
  517. }
  518. fis.close();
  519. os.close();
  520. }
  521. }