PageRenderTime 136ms CodeModel.GetById 65ms app.highlight 63ms RepoModel.GetById 1ms app.codeStats 0ms

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