OpenMap教程第2部分–使用MapHandler构建基本地图应用程序–第1部分
1.簡介
在第一個教程中,我們創建了一個基本的OpenMap GIS應用程序,該應用程序在JFrame中顯示一個從文件系統加載的具有一個形狀圖層的地圖。 該教程基于com.bbn.openmap.app.example.SimpleMap 。 在該教程中,我們使用了以下OpenMap類: MapBean, PropertyHandler, ShapeLayer, com.bbn.openmap.util.SwingWorker 。
我們向JFrame添加了MapBean 。 但是,OpenMap提供了自己的JFrame , OpenMapFrame ,它可以容納MapPanel 。 MapPanel是一個接口(請參見圖1),描述了一個組件,該組件包含MapBean, MapHandler ,菜單小部件以及所有其他組成OpenMap地圖小部件的組件。 MapPanel是一個獨立的OpenMap Swing組件。 預期MapPanel將從java.awt.Container擴展,否則如果在OpenMapFrame中找到它,它可能不會自動添加到MapHandler (我們將在本文后面討論MapHandler )。
所述com.bbn.openmap.BufferedMapBean延伸MapBean通過迫使其層油漆他們的地圖特征為緩沖的圖像。 每當調用Java AWT線程繪制圖層時,都會渲染此繪制緩沖區。 由于它避免了(可能很昂貴的) Layer繪制過程,因此極大地提高了性能。 如果圖層請求繪制,則圖層將重新生成繪制緩沖區并將其繪制到地圖窗口中。
com.bbn.openmap.BufferedLayerMapBean用特殊的內部圖像緩沖區擴展了BufferedMapBean ,該緩沖區保存了所有被指定為“背景”層的層。 當某些圖層為移動的地圖要素設置動畫并且地圖經常被重新繪制時,此緩沖區特別有用。 將單獨的緩沖圖像用于背景圖層可大大減少渲染地圖所需的時間和工作量,從而提高了地圖更新的速度。 默認情況下,由于提高了性能,因此OpenMap應用程序使用BufferedLayerMapBean而不是MapBean 。
2. OpenMapFrame和MapPanel
讓我們看看如何修改上一個教程中的MapFram e,以利用上述OpenMap類:
結果如清單1所示(假設您選擇了教程1中的最后一個實現)。
作為練習,在上面的步驟5中用OverlayMapPanel替換BasicMapPanel 。 各種MapPanel (請參見圖1)包含BufferedLayerMapBean因此您無需執行其他任何操作即可提高性能。
清單1:MapFrame Basic OpenMap應用程序
public class MapFrame extends OpenMapFrame {/** Creates new form MapFrame */public MapFrame() {super("Simple Map");initComponents();initMap();}@SuppressWarnings("unchecked") private void initComponents() {mapPanel = new com.bbn.openmap.gui.BasicMapPanel();setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);getContentPane().add(mapPanel, java.awt.BorderLayout.PAGE_END);pack();} /** @param args the command line arguments */public static void main(String args[]) {/* Create and display the form */java.awt.EventQueue.invokeLater(() -> new MapFrame().setVisible(true));}// Variables declaration - do not modify private com.bbn.openmap.gui.BasicMapPanel mapPanel;// End of variables declaration private void initMap() {CompletableFuture.supplyAsync(() -> getShapeLayer()).thenAcceptAsync(shapeLayer -> {// Add the political layer to the mapmapPanel.getMapBean().add(shapeLayer);MapFrame.this.revalidate();});}// ... }圖1:OpenMap的主類類圖
3. MapHandler
MapHandler是一個java.beans.beancontext.BeanContext ,可以認為是一個大型存儲桶,可以在其中添加或刪除對象。 將BeanContext對象作為體系結構的中心的好處是,當其對象成員身份更改時,它將事件發送給偵聽器。 添加到BeanContext任何java.beans.beancontext.BeanContextMembershipListener都將接收這些事件,并且可以使用這些事件來建立或提供與要添加或刪除的對象的連接。
可以將MapHandler視為一個地圖,其中包含MapBean , Layer以及其中包含的其他管理組件。 那些需要獲取其他對象和服務句柄的組件可以使用它。 它可用于在運行時向應用程序添加或刪除組件,并且添加到MapHandler所有其他對象會自動收到添加/刪除的通知。
讓我們看看如何利用MapHandler 。 修改后的initMap()如清單2所示。 如前所述,您可以將MapHandler視為一個大型存儲桶,可以在其中添加對象或從中刪除對象。 我們拿到的MapHandler從MapPanel 。 為了能夠向其添加圖層,我們需要向LayerHandler添加一個MapHandler 。 我們向它添加shapeLayer和GraticuleLayer 。 順序很重要,即最后添加的層是顯示在頂部的層。 最后,我們需要將OpenMapFrame添加到MapHandler 。 MapHandler是將所有這些粘合在一起的實體。 com.bbn.openmap.app.example.SimpleMap2檢查com.bbn.openmap.app.example.SimpleMap2 。
與簡單地使用BeanContext ,存在MapHandler的原因是它是擴展的BeanContext ,可以跟蹤SoloMapComponent ( com.bbn.openmap.SoloMapComponents )。 SoloMapComponent是一個接口,可用于對象上,以指示BeanContext中一次僅存在該組件類型的一個實例。 例如, MapBean是SoloMapComponent ,并且只能有一個 MapBean在MapHandler在時間(漢蘭達!)。 MapHandler有一個com.bbn.openmap.SoloMapComponentPolicy ,它告訴它如果遇到添加SoloMapComponent的重復實例的情況該怎么辦。 根據政策, MapHandler將拒絕的第二個實例SoloMapComponent ( com.bbn.openmap.SoloMapComponentRejectPolicy )或替換以前的組件( com.bbn.openmap.SoloMapComponentReplacePolicy )。
清單2:使用MapHandler的initMap()
private void initMap() {try {// Get the default MapHandler the BasicMapPanel created.MapHandler mapHandler = mapPanel.getMapHandler();// Set the map's centermapPanel.getMapBean().setCenter(new LatLonPoint.Double(38.0, 24.5));// Set the map's scale 1:120 millionmapPanel.getMapBean().setScale(120000000f);/** Create and add a LayerHandler to the MapHandler. The LayerHandler* manages Layers, whether they are part of the map or not.* layer.setVisible(true) will add it to the map. The LayerHandler* has methods to do this, too. The LayerHandler will find the* MapBean in the MapHandler.*/mapHandler.add(new LayerHandler());CompletableFuture.supplyAsync(() -> getShapeLayer()).thenAcceptAsync(shapeLayer -> {// Add the political layer to the mapmapHandler.add(shapeLayer);mapHandler.add(new GraticuleLayer());MapFrame.this.revalidate();});// Add the map to the framemapHandler.add(this);} catch (MultipleSoloMapComponentException msmce) {// The MapHandler is only allowed to have one of certain// items. These items implement the SoloMapComponent// interface. The MapHandler can have a policy that// determines what to do when duplicate instances of the// same type of object are added - replace or ignore.// In this example, this will never happen, since we are// controlling that one MapBean, LayerHandler,// MouseDelegator, etc is being added to the MapHandler.} }但是,此基本應用程序缺少許多東西。 例如,無法在地圖上執行任何操作,例如放大/縮小,平移等。 但是可以借助MapHandler輕松添加它們。 相關處理程序只需添加到MapHandler的try-catch塊內initMap()如清單3所示。現在,您可以在輸入/輸出放大與鼠標中間的滾輪和泛用鼠標左鍵地圖。
清單3:帶有鼠標事件的initMap()
private void initMap() {//...// Add MouseDelegator, which handles mouse modes (managing mouse// events)mapHandler.add(new MouseDelegator()); // Add OMMouseMode, which handles how the map reacts to mouse// movementsmapHandler.add(new OMMouseMode());//... }到目前為止,我們已經看到了如何使用: MapBean, MapHandler, LayerHandler, PropertyHandler, ShapeLayer, GraticuleLayer, OpenMapFrame 。
4. openmap.properties
但是,OpenMap比這更靈活。 借助BeanContext技術,我們可以在屬性文件openmap.properties定義組成應用程序的組件。 我們已經在應用程序中創建了一個openmap.properties ,其中包含ESRI形狀圖層的屬性。 屬性文件可以包含針對特定組件的范圍內的屬性。 使用屬性前綴執行作用域確定,因此可以將屬性定義為:
prefix.property=value
讓我們從為現有屬性添加前綴開始,看看在我們的代碼中需要進行哪些修改。
清單4:openmap.properties
shapePolitical.prettyName=Political Solid shapePolitical.lineColor=000000 shapePolitical.fillColor=BDDE83 shapePolitical.shapeFile=resources/map/shape/dcwpo-browse.shp shapePolitical.spatialIndex=resources/map/shape/dcwpo-browse.ssxPropertyHandler支持前綴,如清單5中的粗體所示。在下一個教程中,我們將看到屬性作用域的有用性。 由于下一部分內容會很廣泛,因此最好在此處進行介紹。
清單5:具有前綴支持的PropertyHandler
private ShapeLayer getShapeLayer() {PropertyHandler propertyHandler = null;try {propertyHandler = new PropertyHandler.Builder().setPropertiesFile("./openmap.properties").setPropertyPrefix("shapePolitical").build();} catch (IOException ex) {Logger.getLogger(MapFrame.class.getName()).log(Level.SEVERE, null, ex);}//ShapeLayer: ShapeLayer shapeLayer = new ShapeLayer(); if (propertyHandler != null) {shapeLayer.setProperties(propertyHandler.getPropertyPrefix(), propertyHandler.getProperties(propertyHandler.getPropertyPrefix()));}return shapeLayer; }5.結論
在本教程中,我們學習了如何使用: MapBean, MapHandler, LayerHandler, PropertyHandler, ShapeLayer, GraticuleLayer, OpenMapFrame 。 我們還看到了openmap.properties文件提供的靈活性。 可以在那里重新配置新的應用程序,而無需重新編譯。 在下一個教程中,我們將看到如何執行此操作而無需重新編譯我們的應用程序。
參考文獻
翻譯自: https://www.javacodegeeks.com/2015/11/openmap-tutorial-part-2-build-basic-map-application-using-maphandler-part-1.html
總結
以上是生活随笔為你收集整理的OpenMap教程第2部分–使用MapHandler构建基本地图应用程序–第1部分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在OpenShift上扩展Java EE
- 下一篇: 笔记本电脑怎么安装软件(笔记本电脑怎么安