/* * <copyright> * Copyright 2011 BBN Technologies * </copyright> */ package com.bbn.openmap.layer.imageTile; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.HashMap; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import com.bbn.openmap.layer.OMGraphicHandlerLayer; import com.bbn.openmap.layer.policy.ListResetPCPolicy; import com.bbn.openmap.omGraphics.OMGraphicList; import com.bbn.openmap.omGraphics.OMWarpingImage; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.proj.coords.GeoCoordTransformation; import com.bbn.openmap.proj.coords.LatLonGCT; import com.bbn.openmap.proj.coords.MercatorUVGCT; import com.bbn.openmap.util.DataBounds; import com.bbn.openmap.util.propertyEditor.DirectoryPropertyEditor; /** * A layer to assist with creating map tiles, it creates an overlay that * represents tile coverage for different zoom levels. You could just view the * tiles, but then you are limited to looking at that coverage at the scale for * that zoom level. This tool lets you figure out what tiles you have and what * you may need to create. * * @author dietrick */ public class MapTileUtilLayer extends OMGraphicHandlerLayer implements ListSelectionListener { protected static Logger logger = Logger.getLogger("com.bbn.openmap.layer.imageTile.MapTileUtilLayer"); protected String tileRootDir; protected HashMap<String, BufferedImage> images; protected OMGraphicList omgraphics; public MapTileUtilLayer() { images = new HashMap<String, BufferedImage>(); omgraphics = new OMGraphicList(); coordTransform = LatLonGCT.INSTANCE; setProjectionChangePolicy(new ListResetPCPolicy(this)); } public String getTileRootDir() { return tileRootDir; } public void setTileRootDir(String tileRootDir) { this.tileRootDir = tileRootDir; if (generateButton != null) { generateButton.setEnabled(tileRootDir != null && tileRootDir.length() != 0); } } protected OMGraphicList getOMGraphics() { return omgraphics; } protected void setOMGraphics(OMGraphicList omgl) { omgraphics = omgl; } public synchronized OMGraphicList prepare() { OMGraphicList ret = new OMGraphicList(); OMGraphicList currentList = getOMGraphics(); if (currentList != null) { ret.addAll(currentList); } Projection proj = getProjection(); if (proj != null) { ret.generate(proj); } return ret; } protected BufferedImage getImageForZoomLevel(int zoomLevel) { int dimensionForZoom = (int) Math.pow(2, zoomLevel); return new BufferedImage(dimensionForZoom, dimensionForZoom, BufferedImage.TYPE_INT_ARGB); } protected OMWarpingImage getOMWarpingImage(BufferedImage bufImage, int zoomLevel) { GeoCoordTransformation gct = new MercatorUVGCT.TMS(zoomLevel); return new OMWarpingImage(bufImage, gct, new DataBounds(new Point2D.Double(0, 0), new Point2D.Double(bufImage.getWidth(), bufImage.getHeight()))); } protected void colorImage(File zoomLevelDir, BufferedImage bufImage, int rgb) { int width = bufImage.getWidth(); int height = bufImage.getHeight(); for (int x = 0; x < width; x++) { File rowDir = new File(zoomLevelDir, Integer.toString(x)); if (rowDir.exists()) { for (int y = 0; y < height; y++) { File colFile = new File(rowDir, Integer.toString(y) + ".png"); if (colFile.exists()) { bufImage.setRGB(x, y, rgb); } } } } } protected void generateMapTileImages() { if (imageList == null) { logger.info("imageList is null, something weird going on"); return; } if (images != null) { images.clear(); } if (tileRootDir != null) { File rootFile = new File(tileRootDir); if (rootFile.exists()) { for (int zoomLevel = 0; zoomLevel < 21; zoomLevel++) { BufferedImage buf = getImageForZoomLevel(zoomLevel); File levelDir = new File(rootFile, Integer.toString(zoomLevel)); if (levelDir.exists()) { colorImage(levelDir, buf, 0x77aaaa00); images.put(levelDir.getName(), buf); imageList.setListData(images.keySet().toArray()); } } } } } protected void clearMapTileImages() { if (images != null) { images.clear(); } if (imageList != null) { imageList.removeAll(); } } JPanel gui = null; DirectoryPropertyEditor dirEditor = null; JButton generateButton = null; JButton clearButton = null; JList imageList = null; public JComponent getGUI() { if (gui == null) { gui = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; c.gridheight = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(10, 10, 0, 10); JLabel label1 = new JLabel("Tile Root Directory:"); gui.add(label1, c); dirEditor = new DirectoryPropertyEditor(); dirEditor.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent pce) { DirectoryPropertyEditor de = (DirectoryPropertyEditor) pce.getSource(); setTileRootDir(de.getAsText()); } }); c.gridx = 1; c.gridwidth = 2; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0f; gui.add(dirEditor.getCustomEditor(), c); imageList = new JList(); imageList.addListSelectionListener(this); imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane scrollPane = new JScrollPane(imageList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); c.gridx = 0; c.gridy = 1; c.gridwidth = 3; c.fill = GridBagConstraints.BOTH; c.weighty = 1.0f; c.insets = new Insets(10, 10, 10, 10); gui.add(scrollPane, c); c.fill = GridBagConstraints.NONE; c.weightx = 0.0f; c.weighty = 0.0f; c.gridwidth = 1; c.gridy = 2; c.insets = new Insets(0, 10, 10, 10); clearButton = new JButton("Clear"); clearButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { clearMapTileImages(); } }); generateButton = new JButton("Generate"); generateButton.setEnabled(tileRootDir != null && tileRootDir.length() != 0); generateButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { generateMapTileImages(); } }); c.gridx = 0; gui.add(clearButton, c); c.gridx = 2; c.anchor = GridBagConstraints.NORTHEAST; gui.add(generateButton, c); } return gui; } public static void main(String[] args) { logger.info("for zoom level 17: " + Math.pow(2, 17)); JFrame frame = new JFrame("GUI"); MapTileUtilLayer layer = new MapTileUtilLayer(); frame.setContentPane(layer.getGUI()); frame.pack(); frame.setVisible(true); } /* * (non-Javadoc) * * @see * javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event * .ListSelectionEvent) */ public void valueChanged(ListSelectionEvent arg0) { if (arg0.getValueIsAdjusting()) { int firstIndex = arg0.getFirstIndex(); JList list = (JList) arg0.getSource(); String zoomLevel = list.getSelectedValue().toString(); if (images != null) { BufferedImage buf = images.get(zoomLevel); OMGraphicList omgl = new OMGraphicList(); OMWarpingImage omwiImage = getOMWarpingImage(buf, Integer.parseInt(zoomLevel)); omgl.add(omwiImage); setOMGraphics(omgl); doPrepare(); } clearButton.setEnabled(((JList)arg0.getSource()).getComponentCount() > 0); } } }