📄 mapview.java
字号:
package org.placelab.demo.mapview;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.eclipse.swt.SWT;import org.eclipse.swt.SWTException;import org.eclipse.swt.events.ControlAdapter;import org.eclipse.swt.events.ControlEvent;import org.eclipse.swt.events.DisposeEvent;import org.eclipse.swt.events.DisposeListener;import org.eclipse.swt.events.KeyAdapter;import org.eclipse.swt.events.KeyEvent;import org.eclipse.swt.events.MouseEvent;import org.eclipse.swt.events.SelectionEvent;import org.eclipse.swt.events.SelectionListener;import org.eclipse.swt.graphics.Color;import org.eclipse.swt.graphics.Cursor;import org.eclipse.swt.graphics.Image;import org.eclipse.swt.graphics.ImageData;import org.eclipse.swt.graphics.ImageLoader;import org.eclipse.swt.graphics.Point;import org.eclipse.swt.graphics.Rectangle;import org.eclipse.swt.layout.FillLayout;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Control;import org.eclipse.swt.widgets.Decorations;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Menu;import org.eclipse.swt.widgets.MenuItem;import org.eclipse.swt.widgets.Widget;import org.placelab.core.TwoDCoordinate;import org.placelab.util.swt.Glyph;import org.placelab.util.swt.GlyphHolder;import org.placelab.util.swt.GlyphImage;import org.placelab.util.swt.GlyphRectangle;import org.placelab.util.swt.SwtScrolledComposite;public class MapView extends SwtScrolledComposite { protected GlyphHolder holder; // this is only used when in bitmap mode. it is null in tiger mode protected GlyphImage mapImageGlyph = null; protected Image mapImage; // this is an instance of BitmapMapBacking when in bitmap mode, and // TigerMapBacking when in tiger mode protected MapBacking mapData; // this is the history for the map zooming when in tiger mode // since it is all vector data, any size we choose is just arbitrary anyway // so the concept of a zoom level doesn't apply in tiger mode // instead, users may "zoom" by choosing a rectangle that they wish to see in // detail and the view will then do what is effectively a map change to highlight // that area. So with the mapHistory we store the map backings for all of those // areas and that way when the user zooms out the history of regions highlighted // is reversed. protected Vector mapHistory = null; // the tiger drawing code is implemented as an overlay for the sake of convenience // it is null when the mapview is not in tiger mode//ALM protected TigerOverlay tigerOverlay = null; //ALM protected boolean tigerMode = false; // a Hashtable of PlaceBackings => MapIcons protected Hashtable places; protected Vector placeIcons; public Vector overlays; protected Cursor iconCursor; protected Color iconTextBg; protected MouseEvent dragBegin = null; protected GlyphRectangle dragOutline = null; // used to work around too many resize messages protected Rectangle oldBounds = null; //protected int zoomIndex = 3; // the zoom values only apply to bitmap mode protected double[] zoomValues = new double[]{0.25, 0.5, 0.75, 1.0, 1.5, 2.0}; protected double zoom; //private static final double ZOOM_STEP = 1.25; protected static final int SHIFT = 20; protected static final double SMALL_DEVICE_SIZE = 5.0; // inches public static boolean drawBorder = true; public boolean isVisible() { return true; } protected static boolean getUseScrollBars(Display display) { Point dpi = display.getDPI(); Rectangle bounds = display.getBounds(); double width = ((double)bounds.width )/dpi.x; double height = ((double)bounds.height)/dpi.y; /*System.out.println("Screen size is "+width+"\" x "+height+ "\"");*/ /* don't use scrollbars if our device is too small */ if (width < SMALL_DEVICE_SIZE) return false; if (height < SMALL_DEVICE_SIZE) return false; return true; } private static int checkStyle(int style, boolean useScrollBars) { if (useScrollBars) style |= SWT.H_SCROLL | SWT.V_SCROLL; if (drawBorder) { style |= SWT.BORDER; } return style; } Cursor getIconCursor() { return iconCursor; } public MapView(Composite parent, int style) { this(parent, style, getUseScrollBars(parent.getDisplay())); } public MapView(Composite parent, int style, boolean useScrollBars) { super(parent, checkStyle(style, useScrollBars)); setAlwaysShowScrollBars(false); setLayout(new FillLayout()); holder = new GlyphHolder(this, SWT.NONE); holder.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { handleKeyPress(e); } }); setContent(holder); //mapImageGlyph = new GlyphImage(holder, SWT.NONE); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { ((MapView)e.widget).onDispose(); } }); addControlListener(new ControlAdapter() { public void controlResized(ControlEvent e) { // there is a tendency to get controlResized events way too many times // only actually do something about it if there really is a change if(oldBounds != null && (oldBounds.x != getBounds().x || oldBounds.y != getBounds().y || oldBounds.width != getBounds().width || oldBounds.height != getBounds().height)) {//ALM if(tigerMode) {// System.out.println("resized");// holder.setSize(getBounds().width, getBounds().height);// setMapData(mapData);// } else { Rectangle r = getBounds(); if (getVerticalBar() != null) getVerticalBar(). setPageIncrement (r.height-10); if (getHorizontalBar() != null) getHorizontalBar(). setPageIncrement (r.width-10);// } } oldBounds = new Rectangle(getBounds().x, getBounds().y, getBounds().width, getBounds().height); } }); addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { handleKeyPress(e); } }); // these only make sense for tiger mode, which is disabled /* holder.addMouseListener(new MouseAdapter() { public void mouseDown(MouseEvent e) { dragBegin = e; } public void mouseDoubleClick(MouseEvent e) { dragBegin = null; } public void mouseUp(MouseEvent e) { if(dragBegin != null && e.x != dragBegin.x && e.y != dragBegin.y) { // the user has dragged out a rectangle // zoom to it Rectangle area = new Rectangle(Math.min(dragBegin.x, e.x), Math.min(dragBegin.y, dragBegin.x), Math.abs(dragBegin.x - e.x), Math.abs(dragBegin.y - e.y)); dragOutline.dispose(); dragOutline = null; zoomForRectangle(area); } dragBegin = null; } }); holder.addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { //System.out.println("mouse moved"); if(dragBegin != null) { if(dragOutline == null) { dragOutline = new GlyphRectangle(holder, 0); dragOutline.setThickness(1); dragOutline.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); // too bad swt sucks and doesn't support alpha or we could do something really cool // looking here dragOutline.setBackground(null); } Rectangle area = new Rectangle(Math.min(dragBegin.x, e.x), Math.min(dragBegin.y, dragBegin.x), Math.abs(dragBegin.x - e.x), Math.abs(dragBegin.y - e.y)); dragOutline.set(area); } } }); */ //allGlyphs = new HashtableSet(); //currentGlyphs = new HashtableSet(); placeIcons = new Vector(); places = new Hashtable(); iconCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); iconTextBg = new Color(getDisplay(), 255, 255, 180); overlays = new Vector(); mapHistory = new Vector(); } public void zoomForRectangle(Rectangle area) {//ALM if(tigerMode) {// double lat1 = this.pixelsToLatitude(area.y);// double lat2 = this.pixelsToLatitude(area.y + area.height);// double lon1 = this.pixelsToLongitude(area.x);// double lon2 = this.pixelsToLongitude(area.x + area.width);// TwoDCoordinate one = new TwoDCoordinate(lat1, lon1);// TwoDCoordinate two = new TwoDCoordinate(lat2, lon2);// try {// TigerLineData subData = ((TigerMapBacking)mapData).getTigerLineData().getSubset(// new LocationFilter(one, two));// MapBacking subBacking = new TigerMapBacking(mapData.getName(), subData);// mapHistory.addFirst(mapData);// this.setMapData(subBacking);// } catch (IOException e) {// // TODO Auto-generated catch block// e.printStackTrace();// } catch (InvalidRecordException e) {// // TODO Auto-generated catch block// e.printStackTrace();// }// } } /** * Adds an overlay to the mapview. * MapViewOverlays call this themselves when they are created, * so you should never have to call it yourself */ public void addOverlay(MapViewOverlay overlay) { overlays.addElement(overlay); } public void removeOverlay(MapViewOverlay overlay) { overlays.removeElement(overlay); this.redraw(); } public void overlayHasNewTopGlyph(MapViewOverlay overlay) { int index = overlays.indexOf(overlay); if(index == -1 || index + 1 >= overlays.size()) return; MapViewOverlay last = overlay; for(int i = index + 1; i < overlays.size(); i++) { MapViewOverlay o = (MapViewOverlay)overlays.get(i); Glyph lastTop = last.getTopGlyph(); last = o; if(lastTop == null) continue; o.moveAbove(lastTop); } } /** * Gets an menu containing all of the overlays loaded for the mapview. * The menu items toggle the visibility of the overlays. */ public Menu getOverlaysMenu(Widget parent) { Menu menu = null; if(parent instanceof Control) { menu = new Menu((Control)parent); } else if(parent instanceof Decorations) { menu = new Menu((Decorations)parent, SWT.CASCADE); } else if(parent instanceof Menu) { menu = new Menu((Menu)parent); } else if(parent instanceof MenuItem) { menu = new Menu((MenuItem)parent); } MenuItem item = null; Enumeration i = overlays.elements(); while(i.hasMoreElements()) { final MapViewOverlay overlay = (MapViewOverlay)i.nextElement(); item = new MenuItem(menu, SWT.CHECK); item.setText("Show " + overlay.getName()); item.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { overlay.setVisible(!overlay.isVisible()); } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); item.setSelection(overlay.isVisible()); } return menu; } public void zoomIn() {//ALM if(tigerMode) {// zoomForRectangle(new Rectangle(getBounds().x + getBounds().width / 2,// getBounds().y + getBounds().height / 2,// getBounds().width / 2,// getBounds().height / 2));// } else { int i; for(i=0;i<zoomValues.length;i++) { if(zoomValues[i] > zoom) { setZoom(zoomValues[i]); return; } } //if(zoomIndex < zoomValues.length - 1) // setZoom(zoomValues[++zoomIndex]);// } } public void zoomOut() {//ALM if(tigerMode) {// if(mapHistory.size() > 0) {// this.setMapData((TigerMapBacking)mapHistory.removeFirst());// }// } else { int i; for(i=zoomValues.length-1;i>=0;i--) { if(zoomValues[i] < zoom) { setZoom(zoomValues[i]); return; } }// } //if(zoomIndex > 0) // setZoom(zoomValues[--zoomIndex]); } public double getZoom() { return zoom; } public void setZoom(double zoom) { if(this.mapData == null) return;//ALM if(!tigerMode) { this.zoom = zoom; holder.freeze(); holder.getChild().setZoom(zoom); this.resizeHolder(); Enumeration i = overlays.elements(); while(i.hasMoreElements()) { MapViewOverlay overlay = (MapViewOverlay)i.nextElement(); overlay.mapZoomed(zoom); } holder.thaw(); System.gc();// } else {// if(zoom > 1.0) zoomIn();// else if(zoom < 1.0) zoomOut();// } } public void handleKeyPress(KeyEvent e) { if (e.keyCode==SWT.ARROW_RIGHT) { shift(SHIFT, 0); } else if (e.keyCode==SWT.ARROW_LEFT) { shift(-SHIFT, 0); } else if (e.keyCode==SWT.ARROW_UP) { shift(0, -SHIFT); } else if (e.keyCode==SWT.ARROW_DOWN) { shift(0, SHIFT); } else if(e.character == 'z') { zoomIn(); } else if(e.character == 'x') { zoomOut(); } } protected void shift(int x, int y) {//ALM if(tigerMode) {// // shifting in tigermode is a little trickier since the idea is to convert// // number of pixels given to lat and lon, then get a new TigerLineData from// // the one this one zoomed out of containing the amount shifted// if(mapHistory.size() == 0) {// // then there is no parent map and so the entire map displayable is onscreen// return;// }// double shiftLat = pixelsToLatitude(getBounds().height - y);// double shiftLon = pixelsToLongitude(x);// // these will hold the new coordinates// double oLat, oLon, maxLat, maxLon;// if(shiftLat < getOriginLat()) {// oLat = shiftLat;// maxLat = mapData.getMaxLat() - shiftLat;// } else {// oLat = getOriginLat() + shiftLat;// maxLat = mapData.getMaxLat() + shiftLat;// }// if(shiftLon < getOriginLon()) {// oLon = shiftLon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -