pcl_openmap_OpenMap教程第2部分–使用MapHandler构建基本地图应用程序–第1部分
pcl_openmap
1.簡(jiǎn)介
在第一個(gè)教程中,我們創(chuàng)建了一個(gè)基本的OpenMap GIS應(yīng)用程序,該應(yīng)用程序在JFrame中顯示一個(gè)從文件系統(tǒng)加載的具有一個(gè)形狀圖層的地圖。 該教程基于com.bbn.openmap.app.example.SimpleMap 。 在該教程中,我們使用了以下OpenMap類(lèi): MapBean, PropertyHandler, ShapeLayer, com.bbn.openmap.util.SwingWorker 。
我們向JFrame添加了MapBean 。 但是,OpenMap提供了自己的JFrame , OpenMapFrame ,它可以容納MapPanel 。 MapPanel是一個(gè)接口(參見(jiàn)圖1),描述了一個(gè)組件,該組件包含MapBean, MapHandler ,菜單小部件以及所有其他組成OpenMap地圖小部件的組件。 MapPanel是一個(gè)獨(dú)立的OpenMap Swing組件。 預(yù)期MapPanel將從java.awt.Container擴(kuò)展,否則,如果在OpenMapFrame中找到了它,它可能不會(huì)自動(dòng)添加到MapHandler (我們將在本文后面討論MapHandler )。
所述com.bbn.openmap.BufferedMapBean延伸MapBean通過(guò)迫使其層油漆他們的地圖特征為緩沖的圖像。 每當(dāng)調(diào)用Java AWT線程繪制圖層時(shí),都會(huì)渲染此繪制緩沖區(qū)。 由于它避免了(可能很昂貴的) Layer繪制過(guò)程,因此極大地提高了性能。 如果圖層請(qǐng)求繪制,則圖層將重新生成繪制緩沖區(qū)并將其繪制到地圖窗口中。
com.bbn.openmap.BufferedLayerMapBean用特殊的內(nèi)部圖像緩沖區(qū)擴(kuò)展了BufferedMapBean ,該緩沖區(qū)保存了所有被指定為“背景”層的層。 當(dāng)某些圖層為移動(dòng)的地圖要素設(shè)置動(dòng)畫(huà)并且地圖經(jīng)常被重新繪制時(shí),此緩沖區(qū)特別有用。 將單獨(dú)的緩沖圖像用于背景圖層可大大減少渲染地圖所需的時(shí)間和工作量,從而提高了地圖更新的速度。 默認(rèn)情況下,由于提高了性能,因此OpenMap應(yīng)用程序使用BufferedLayerMapBean而不是MapBean 。
2. OpenMapFrame和MapPanel
讓我們看看如何修改上一教程中的MapFram e,以利用上述OpenMap類(lèi):
結(jié)果如清單1所示(假設(shè)您選擇了教程1中的最后一個(gè)實(shí)現(xiàn))。
作為練習(xí),在上面的步驟5中用OverlayMapPanel替換BasicMapPanel 。 各種MapPanel (請(qǐng)參見(jiàn)圖1)包含一個(gè)BufferedLayerMapBean因此您無(wú)需執(zhí)行任何其他操作即可提高性能。
清單1:MapFrame Basic OpenMap應(yīng)用程序
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的主類(lèi)類(lèi)圖
3. MapHandler
MapHandler是一個(gè)java.beans.beancontext.BeanContext ,可以認(rèn)為是一個(gè)大型存儲(chǔ)桶,可以在其中添加或刪除對(duì)象。 將BeanContext對(duì)象作為體系結(jié)構(gòu)的中心的好處是,當(dāng)其對(duì)象成員身份更改時(shí),它將事件發(fā)送給偵聽(tīng)器。 添加到BeanContext任何java.beans.beancontext.BeanContextMembershipListener都將接收這些事件,并且可以使用這些事件來(lái)建立或提供與要添加或刪除的對(duì)象的連接。
可以將MapHandler視為一個(gè)地圖,其中包含MapBean , Layer以及其中包含的其他管理組件。 那些需要獲取其他對(duì)象和服務(wù)句柄的組件可以使用它。 它可用于在運(yùn)行時(shí)向應(yīng)用程序添加或刪除組件,并且添加到MapHandler所有其他對(duì)象會(huì)自動(dòng)收到添加/刪除的通知。
讓我們看看如何利用MapHandler 。 清單2顯示了修改后的initMap() 。 如前所述,您可以將MapHandler視為一個(gè)大型存儲(chǔ)桶,可以在其中添加對(duì)象或從中刪除對(duì)象。 我們拿到的MapHandler從MapPanel 。 為了能夠向其添加圖層,我們需要向LayerHandler添加一個(gè)MapHandler 。 我們將shapeLayer以及GraticuleLayer到其中。 順序很重要,即最后添加的層是顯示在最上面的層。 最后,我們需要將OpenMapFrame添加到MapHandler 。 MapHandler是將所有這些粘合在一起的實(shí)體。 com.bbn.openmap.app.example.SimpleMap2檢查com.bbn.openmap.app.example.SimpleMap2 。
與簡(jiǎn)單地使用BeanContext ,存在MapHandler的原因是它是擴(kuò)展的BeanContext ,可以跟蹤SoloMapComponent ( com.bbn.openmap.SoloMapComponents )。 SoloMapComponent是一個(gè)接口,可用于對(duì)象上,以指示BeanContext中一次僅存在該組件類(lèi)型的一個(gè)實(shí)例。 例如, MapBean是SoloMapComponent ,并且只能有一個(gè) MapBean在MapHandler在時(shí)間(漢蘭達(dá)!)。 MapHandler有一個(gè)com.bbn.openmap.SoloMapComponentPolicy ,它告訴它如果添加了SoloMapComponent的重復(fù)實(shí)例的情況該怎么辦。 根據(jù)政策, MapHandler將拒絕的第二個(gè)實(shí)例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.} }但是,此基本應(yīng)用程序缺少許多東西。 例如,無(wú)法在地圖上執(zhí)行任何操作,例如放大/縮小,平移等。 但是可以借助MapHandler輕松添加它們。 相關(guān)處理程序只需添加到MapHandler的try-catch塊內(nèi)initMap()如清單3所示。現(xiàn)在,您可以在輸入/輸出放大與鼠標(biāo)中間的滾輪和泛用鼠標(biāo)左鍵地圖。
清單3:帶有鼠標(biāo)事件的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());//... }到目前為止,我們已經(jīng)看到了如何使用: MapBean, MapHandler, LayerHandler, PropertyHandler, ShapeLayer, GraticuleLayer, OpenMapFrame 。
4. openmap.properties
但是,OpenMap的靈活性甚至更高。 借助BeanContext技術(shù),我們可以在屬性文件openmap.properties定義組成應(yīng)用程序的組件。 我們已經(jīng)在應(yīng)用程序中創(chuàng)建了一個(gè)openmap.properties ,其中包含ESRI形狀圖層的屬性。 屬性文件可以包含針對(duì)特定組件的范圍內(nèi)的屬性。 使用屬性前綴執(zhí)行作用域確定,因此可以將屬性定義為:
prefix.property=value
讓我們從為現(xiàn)有屬性添加前綴開(kāi)始,看看在我們的代碼中需要進(jìn)行哪些修改。
清單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中的粗體所示。在下一教程中,我們將看到屬性作用域的有用性。 由于下一部分內(nèi)容會(huì)很廣泛,因此最好在這里進(jìn)行介紹。
清單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.結(jié)論
在本教程中,我們學(xué)習(xí)了如何使用: MapBean, MapHandler, LayerHandler, PropertyHandler, ShapeLayer, GraticuleLayer, OpenMapFrame 。 我們還看到了openmap.properties文件提供的靈活性。 可以在那里重新配置新的應(yīng)用程序而無(wú)需重新編譯。 在下一個(gè)教程中,我們將看到如何執(zhí)行此操作而無(wú)需重新編譯我們的應(yīng)用程序。
參考資料
翻譯自: https://www.javacodegeeks.com/2015/11/openmap-tutorial-part-2-build-basic-map-application-using-maphandler-part-1.html
pcl_openmap
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的pcl_openmap_OpenMap教程第2部分–使用MapHandler构建基本地图应用程序–第1部分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微分的定义是什么 什么是微分
- 下一篇: 字符串url获取参数_如何从URL查询字