📄 waddata.java
字号:
package org.placelab.demo.mapview;//import java.io.FileOutputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.util.Enumeration;import java.util.Hashtable;import java.util.NoSuchElementException;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;import org.eclipse.swt.SWT;import org.eclipse.swt.SWTException;import org.eclipse.swt.graphics.ImageData;import org.eclipse.swt.graphics.ImageLoader;import org.placelab.core.PlacelabProperties;import org.placelab.mapper.JDBMMapper;import org.placelab.mapper.MapLoader;import org.placelab.util.StringUtil;import org.placelab.util.ZipUtil;/** * This class reads a map wad and gets out all the maps and allows * accessing of all the maps and places in it. Alternatively, it can * write a map wad. * * <pre> * Wads are zip files with the following structure: * + map.wad * - apcache.txt (a text file of the aps like from placelab.org) * - defaults.txt (a SectionedFile described below) * + maps * - maps.index (a SectionedFile described below) * - mapname.jpg/gif/png/png OR mapname.tiger.zip (us census tiger format data) * - mapname.meta (a SectionedFile described below) * + places * - places.index (a SectionedFile described below) * - place-set-name.txt (a SectionedFile described below) * - icons * - beer-icon.jpg/gif/png * * maps.index has the following structure * [Maps] * mapname=mapname.meta * * * mapname.meta has the following structure * [Map] * # origin_lat and origin_lon are lower left corner values * origin_lat=47.349829 * origin_lon=-122.98327 * pixels_per_lat=100.01 * pixels_per_lon=9994.39828 * # OR you may specify the upper right corner's lat and lon * upper_right_lat=47.449829 * upper_right_lon=-122.99327 * * image=images/mapimage1.jpg/gif/png * * NEW: alternatively you can specify the following structure * for us census tiger data embedded in a mapwad: * [TigerMap] * data=maps/mapname.tiger.txt * * The Tiger data is the type 1 and type 2 record files * concatenated together in that order. This is likely * to change in the future. * * * places.index has the following structure * [Places] * place-set-name=place-set-name.txt * * * place-set-name.txt has the following structure * [place name] * # image references are relative to the root of the wad * icon_file=places/icons/beer_icon.jpg * lat=46.19829 * lon=-122.8132 * text=Some descriptive text * url=http://www.whitehouse.gov * type=radical/AP/etc * * [other place name] * etc ... * * NEW: Regions can specify rectangular areas on the map. * They do not have types like places do * In a directory called regions ... * * regions.index has the following structure * [Regions] * region_name=region_name.meta * * region.meta has the following structure * [Region] * origin_lat=47.1 * origin_lon=-122.1 * upper_right_lat=47.8 * upper_right_lon=-122.0 * text=Some descriptive text * url=http://www.whitehouse.gov * * defaults.txt has the following structure * [Map] * mapname=1 * * [Places] * placeset1=1 * placeset2=1 * placeset3=1 * # ... and as many place sets as you would like to specify * </pre> * * the defaults file specifies what the wad author thinks should * be the first set of things that people might want to see. There * is no guarantee that they will be the first things displayed, it * is only a suggestion. Also note that while you must specify * a map if you have a defaults file, you needn't specify any place * sets. Defaults files are not required. * <p> * Note that while place set definition file references in places.index * are relative references, the image file references actually in the place * set files are relative to the root of the wad. This is done so that people * can put their images wherever they want in the wad, since ../ type * references are not allowed. * */public class WadData { // this is a Hashtable of maps protected Hashtable maps; // this is a Hashtable of Hashtables of places // where <place set name> => <place set> and a <place set> is // a hashtable where <place name> => <PlaceBacking object> protected Hashtable places; // region name => regions protected Hashtable regions; // I only want to have at most 1 copy of each image in memory at // once protected Hashtable imageResources; protected String defaultMap; protected Hashtable defaultPlaces; private static final String mapsDirKey = "maps/"; private static final String placesDirKey = "places/"; private static final String mapsIndexKey = "maps/maps.index"; private static final String placesIndexKey = "places/places.index"; private static final String apCacheKey = "apcache.txt"; private static final String defaultsKey = "defaults.txt"; private static final String regionsIndexKey = "regions/regions.index"; private static final String regionsDirKey = "regions/"; private String myApCacheKey = apCacheKey; protected ZipFile wad; protected String wadPath; /* Load all the map data out of a given wad and into memory */ public WadData(String pathToWad) throws IOException, WadDataFormatException { this(); wad = new ZipFile(normalizePath(pathToWad)); wadPath = wad.getName(); String s = (String)PlacelabProperties.get("placelab.apcache"); if ((s != null) && (s.length() > 0)) { myApCacheKey = s; } this.loadMaps(); this.loadPlaces(); this.loadRegions(); this.loadDefaults(); } // this does some business so that // a) wads in the placelab.mapwaddir are found // b) directories structured in the form of a wad // can be read private String normalizePath(String path) throws IOException { File file = new File(path); if(file.exists()) { if(file.isDirectory()) { return fromDir(path); } else { return file.getAbsolutePath(); } } else { // try to construct a file relative to the mapwad dir if(file.isAbsolute()) { throw new FileNotFoundException(path); } else { String path2 = PlacelabProperties.get("placelab.mapwaddir") + File.separator + path; file = new File(path2); if(file.exists()) { if(file.isDirectory()) { return fromDir(path2); } else { return file.getAbsolutePath(); } } else { throw new FileNotFoundException("neither " + path2 + " nor " + path + "exists"); } } } } private String fromDir(String path) throws IOException { File file = new File(path); File tmp = File.createTempFile(file.getName(), ".zip"); ZipUtil.dirToZip(new File(path), tmp); return tmp.getAbsolutePath(); } /* create a new wad to be loaded for writing */ public WadData() { maps = new Hashtable(); places = new Hashtable(); imageResources = new Hashtable(); regions = new Hashtable(); } /* methods related to reading map wads */ private void loadDefaults() throws IOException, WadDataFormatException { ZipEntry defaultsEntry = wad.getEntry(defaultsKey); if(defaultsEntry == null || defaultsEntry.isDirectory()) { // its ok not to have any defaults defaultMap = null; defaultPlaces = null; return; } InputStream defStream = wad.getInputStream(defaultsEntry); SectionedFileParser defParser = null; try { defParser = new SectionedFileParser(defStream); } catch (SectionedFileFormatException sffe) { throw new WadDataFormatException(defaultsKey, WadDataFormatException.BAD_RESOURCE_ERROR, sffe, ""); } try { defaultMap = (String)defParser.getSection("Map").keys().nextElement(); } catch (NoSuchElementException nsee) { throw new WadDataFormatException(defaultsKey, WadDataFormatException.BAD_RESOURCE_ERROR, nsee, "defaults.txt must specify a default map"); } if(getMap(defaultMap) == null) { throw new WadDataFormatException(defaultsKey, WadDataFormatException.BAD_RESOURCE_ERROR, "defaults.txt specified a map that doesn't exist" + " in the map wad"); } Hashtable defPlaceNames = defParser.getSection("Places"); if(defPlaceNames != null) { defaultPlaces = new Hashtable(); Enumeration e = defPlaceNames.keys(); while(e.hasMoreElements()) { String placeName = (String)e.nextElement(); Hashtable placeSet = this.getPlaceSet(placeName); if(placeSet == null) { throw new WadDataFormatException(defaultsKey, WadDataFormatException.BAD_RESOURCE_ERROR, "defaults.txt specified a place set that doesn't" + " exist in the map wad"); } defaultPlaces.put(placeName, placeSet); } } else { // there is no requirement to specify default places // a default map is sufficient defaultPlaces = null; } } private void loadMaps() throws IOException, WadDataFormatException { ZipEntry mapIndexEntry = wad.getEntry(mapsIndexKey); if(mapIndexEntry == null || mapIndexEntry.isDirectory()) { // it is not an error to not have any maps in a wad return; } InputStream mapIndexStream = wad.getInputStream(mapIndexEntry); SectionedFileParser indexParser = null; try { indexParser = new SectionedFileParser(mapIndexStream); } catch(SectionedFileFormatException sffe) { throw new WadDataFormatException(mapsIndexKey, WadDataFormatException.BAD_RESOURCE_ERROR,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -