📄 zbamap.java
字号:
import java.util.*;
import java.awt.geom.*;
import java.awt.*;
import java.io.*;
public class ZbaMap implements IMap
{
private Zb1FileReader zbReader;
private Zj1FileReader zjReader;
//窗口矩形,像素
private Rectangle clientBound;
//窗口覆盖的实地矩形
private Rectangle2D.Double worldBound;
private Component ownerComponent;
private Image paintBuffer;
public ZbaMap()
{
zbReader = new Zb1FileReader();
zjReader = new Zj1FileReader();
clientBound = new Rectangle();
worldBound = new Rectangle2D.Double(0,0,100,200);
}
public void loadData(File file)
{
zbReader.readData(file);
}
//处理全图显示
public void reset()
{
// 处理worldBound
Rectangle2D.Double dataBound = zbReader.getBound () ;
double world_scale = 1.0 * dataBound.width / dataBound.height ;
double client_scale = 1.0 * clientBound.width / clientBound.height ;
if ( world_scale > client_scale )
{
double height = dataBound.width / client_scale ;
double y = dataBound.y + ( height - dataBound.height ) / 2.0 ;
worldBound.setRect ( dataBound.x, y, dataBound.width, height ) ;
}
else if ( world_scale < client_scale )
{
double width = dataBound.height * client_scale ;
double x = dataBound.x - ( width - dataBound.width ) / 2.0 ;
worldBound.setRect ( x, dataBound.y, width, dataBound.height ) ;
}
else worldBound.setRect ( dataBound ) ;
}
public void setOwnerComponent(Component owner)
{
ownerComponent = owner;
}
public Component getOwnerComponent()
{
return ownerComponent;
}
public Rectangle getClientBound()
{
return clientBound;
}
public void setClientBound(Rectangle bound)
{
if(clientBound.equals(bound)) return;
if(ownerComponent == null) return;
// 处理worldBound begin
//确保客户区大小改变后地图不变形
double offset_width = 0 ;
double offset_height = 0 ;
if ( clientBound.width != 0 && clientBound.height != 0 )
{
Point2D.Double originPoint = clientToWorld ( new Point(0,0) ) ;
Point offset = new Point();
offset.x = bound.width - clientBound.width;
offset.y = bound.height - clientBound.height ;
Point2D.Double destPoint = clientToWorld ( offset ) ;
offset_width = destPoint.x - originPoint.x ;
offset_height = destPoint.y - originPoint.y ;
}
clientBound.setRect( bound );
worldBound.width += offset_width ;
worldBound.height -= offset_height ;
// 处理worldBound end
paintBuffer = null ;
paintBuffer = ownerComponent.createImage(ownerComponent.getWidth(),ownerComponent.getHeight());
reDraw(null);
}
public Rectangle2D.Double getWorldBound()
{
return worldBound;
}
public void setWorldBound(Rectangle2D.Double bound)
{
if( bound == null ) return;
worldBound.setRect ( bound );
}
public Point2D.Double clientToWorld(Point p)
{
if ( p == null ) return null ;
if ( clientBound.width == 0 || clientBound.height == 0 ) return null ;
double x_scale = 1.0*( p.x - clientBound.x ) / clientBound.width ;
double y_scale = 1.0*( p.y - clientBound.y ) / clientBound.height ;
double x = worldBound.x + x_scale * worldBound.width ;
double y = worldBound.y - y_scale * worldBound.height ;
Point2D.Double tempPoint = new Point2D.Double ( x, y ) ;
return tempPoint ;
}
public Point worldToClient(Point2D.Double p)
{
if ( p == null ) return null ;
if ( worldBound.width == 0 || worldBound.height == 0 ) return null ;
double x_scale = 1.0*( p.x - worldBound.x ) / worldBound.width ;
double y_scale = 1.0*( p.y - worldBound.y ) / worldBound.height ;
double x = clientBound.x + x_scale * clientBound.width ;
double y = clientBound.y - y_scale * clientBound.height;
Point tempPoint = new Point ( (int)x, (int)y ) ;
return tempPoint ;
}
//
public void reDraw(Rectangle invalideRect)
{
if (paintBuffer == null) return;
if(invalideRect == null)
{
System.out.println("redraw all");
Graphics g = paintBuffer.getGraphics();
g.setColor(Color.white);
//世界坐标系是右手系
Rectangle2D.Double containBound = new Rectangle2D.Double( );
containBound.setRect( worldBound);
containBound.y -= worldBound.height ;
g.clearRect(0,0,clientBound.width,clientBound.height);
ArrayList dataList = zbReader.getGeomData() ;
ZbaFeature feature;
int i,j,pointNum;
Point2D.Double dp1,dp2;
Point ip1, ip2;
for(i = 0; i < dataList.size(); i++)
{
feature = (ZbaFeature)dataList.get(i);
pointNum = feature.getPointNum();
if(pointNum == 1)
{
dp1 = (Point2D.Double)(feature.getPoints()).get(0);
if( containBound.contains( dp1.x, dp1.y ) )
{
ip1 = worldToClient (dp1);
g.drawOval(ip1.x - 1, ip1.y - 1, 2, 2);
}
}
else
{
for( j = 0; j < pointNum - 1; j++ )
{
dp1 = (Point2D.Double)(feature.getPoints()).get(j);
dp2 = (Point2D.Double)(feature.getPoints()).get(j + 1);
if(containBound.intersectsLine(dp1.x, dp1.y, dp2.x, dp2.y))
{
ip1 = worldToClient(dp1);
ip2 = worldToClient(dp2);
g.drawLine( ip1.x, ip1.y, ip2.x, ip2.y );
}
}
}
}
g.dispose () ;
}
else
{
if ( invalideRect.width == 0 || invalideRect.height == 0 )
return ;
Point point = new Point();
point.x = invalideRect.x ; point.y = invalideRect.y ;
Point2D.Double originPoint = clientToWorld ( point ) ;
point.x = invalideRect.x + invalideRect.width ;
point.y = invalideRect.y + invalideRect.height ;
Point2D.Double destPoint = clientToWorld ( point ) ;
//世界坐标系是右手系
Rectangle2D.Double containBound = new Rectangle2D.Double( );
containBound.setRect( originPoint.x, destPoint.y, destPoint.x - originPoint.x, originPoint.y - destPoint.y );
Graphics g = paintBuffer.getGraphics();
g.setColor(Color.white);
g.clearRect(invalideRect.x,invalideRect.y,invalideRect.width,invalideRect.height);
ArrayList dataList = zbReader.getGeomData() ;
ZbaFeature feature;
int i,j,pointNum;
Point2D.Double dp1,dp2;
Point ip1, ip2;
for(i = 0; i < dataList.size(); i++)
{
feature = (ZbaFeature)dataList.get(i);
pointNum = feature.getPointNum();
if(pointNum == 1)
{
dp1 = (Point2D.Double)(feature.getPoints()).get(0);
if( containBound.contains( dp1.x, dp1.y ) )
{
ip1 = worldToClient (dp1);
g.drawOval(ip1.x - 1, ip1.y - 1, 2, 2);
}
}
else
{
for( j = 0; j < pointNum - 1; j++ )
{
dp1 = (Point2D.Double)(feature.getPoints()).get(j);
dp2 = (Point2D.Double)(feature.getPoints()).get(j + 1);
if(containBound.intersectsLine(dp1.x, dp1.y, dp2.x, dp2.y))
{
ip1 = worldToClient(dp1);
ip2 = worldToClient(dp2);
g.drawLine( ip1.x, ip1.y, ip2.x, ip2.y );
}
}
}
}
g.dispose () ;
}
}
public void drawMap(Graphics g, int x, int y)
{
if(paintBuffer == null || ownerComponent == null)
return;
// 填补空白 begin
Rectangle invalidateBound1 = new Rectangle () ;
Rectangle invalidateBound2 = new Rectangle () ;
if ( x != 0 || y != 0 )
{
if ( x >= 0 )
{
if ( y >= 0 )
{
invalidateBound1.setRect ( 0, 0, clientBound.width, y ) ;
invalidateBound2.setRect ( 0, y , x, clientBound.height - y ) ;
}
else
{
invalidateBound1.setRect ( 0, 0, x, clientBound.height + y ) ;
invalidateBound2.setRect ( 0, clientBound.height + y , clientBound.width, -y ) ;
}
}
else
{
if ( y >= 0 )
{
invalidateBound1.setRect ( 0, 0, clientBound.width, y ) ;
invalidateBound2.setRect ( clientBound.width+x, y , -x, clientBound.height - y ) ;
}
else
{
invalidateBound1.setRect ( clientBound.width + x, 0, -x, clientBound.height+y ) ;
invalidateBound2.setRect ( 0, clientBound.height + y , clientBound.width, -y ) ;
}
}
g.clearRect(invalidateBound1.x,invalidateBound1.y,invalidateBound1.width,invalidateBound1.height);
g.clearRect(invalidateBound2.x,invalidateBound2.y,invalidateBound2.width,invalidateBound2.height);
}
// 填补空白 end
g.drawImage(paintBuffer, x, y, ownerComponent);
}
public void scroll(int dx, int dy)
{
if ( paintBuffer == null || ownerComponent == null ) return ;
Point point = new Point();
point.x = 0 ; point.y = 0 ;
Point2D.Double originPoint = clientToWorld ( point ) ;
point.x = dx ;
point.y = dy ;
Point2D.Double destPoint = clientToWorld ( point ) ;
double offset_x = destPoint.x - originPoint.x ;
double offset_y = destPoint.y - originPoint.y ;
worldBound.x -= offset_x ;
worldBound.y -= offset_y ;
Graphics buffer_g = paintBuffer.getGraphics();
buffer_g.copyArea(0,0,clientBound.width,clientBound.height, dx, dy);
// 填补空白 begin
Rectangle invalidateBound1 = new Rectangle () ;
Rectangle invalidateBound2 = new Rectangle () ;
if ( dx >= 0 )
{
if ( dy >= 0 )
{
invalidateBound1.setRect ( 0, 0, clientBound.width, dy ) ;
invalidateBound2.setRect ( 0, dy , dx, clientBound.height - dy ) ;
}
else
{
invalidateBound1.setRect ( 0, 0, dx, clientBound.height + dy ) ;
invalidateBound2.setRect ( 0, clientBound.height + dy , clientBound.width, -dy ) ;
}
}
else
{
if ( dy >= 0 )
{
invalidateBound1.setRect ( 0, 0, clientBound.width, dy ) ;
invalidateBound2.setRect ( clientBound.width+dx, dy , -dx, clientBound.height - dy ) ;
}
else
{
invalidateBound1.setRect ( clientBound.width+dx, 0, -dx, clientBound.height+dy ) ;
invalidateBound2.setRect ( 0, clientBound.height+dy , clientBound.width, -dy ) ;
}
}
reDraw ( invalidateBound1 ) ;
reDraw ( invalidateBound2 ) ;
// 填补空白 end
Graphics g = ownerComponent.getGraphics () ;
g.drawImage(paintBuffer, 0, 0, ownerComponent);
g.dispose () ;
}
public void zoomIn(Rectangle rect)
{
Point centre = new Point();
centre.x = rect.x + rect.width/2;
centre.y = rect.y + rect.height/2;
if ( rect.width < 5 || rect.height < 5 )
{
rect.width = ownerComponent.getWidth()/2;
rect.height = ownerComponent.getHeight()/2;
rect.x = centre.x + rect.width/2;
rect.y = centre.y + rect.height/2;
}
double scale = 1.0 * worldBound.width/worldBound.height;
Point leftTop = new Point(rect.x,rect.y );
//世界坐标中的左上角点,右下角点
Point2D.Double lf, rb, centreWorld;
lf = clientToWorld(leftTop);
Point rightBottom = new Point(rect.x + rect.width, rect.y + rect.height);
rb = clientToWorld(rightBottom);
double width = Math.abs(rb.x - lf.x);
double height = Math.abs(rb.y - lf.y);
if( ( 1.0 * width / height ) > scale )
height = width / scale;
else width = height * scale;
centreWorld = clientToWorld(centre);
Rectangle2D.Double bound = new Rectangle2D.Double(centreWorld.x - width/2, centreWorld.y + height/2, width, height);
setWorldBound(bound);
reDraw(null);
}
public void zoomOut(Rectangle rect)
{
double scale = 2.0;
Point centre = new Point();
centre.x = rect.x + rect.width/2;
centre.y = rect.y + rect.height/2;
double width, height;
Point leftTop = new Point(rect.x,rect.y );
//世界坐标中的左上角点,右下角点
Point2D.Double lf, rb, centreWorld;
lf = clientToWorld(leftTop);
Point rightBottom = new Point(rect.x + rect.width, rect.y + rect.height);
rb = clientToWorld(rightBottom);
width = Math.abs(rb.x - lf.x);
height = Math.abs(rb.y - lf.y);
if( rect.width > 5 && rect.height > 5 )
{
double scaleX, scaleY;
scaleX = worldBound.width/width;
scaleY = worldBound.height/height;
if(scaleX > scaleY)
scale = scaleX;
else
scale = scaleY;
}
width = scale * worldBound.width;
height = scale * worldBound.height;
centreWorld = clientToWorld(centre);
Rectangle2D.Double bound = new Rectangle2D.Double(centreWorld.x - width/2, centreWorld.y + height/2, width, height);
setWorldBound(bound);
reDraw(null);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -