1.简介
欢迎使用OpenMap系列教程的第5个教程。 OpenMap是一个免费的开源Java GIS库。
这是以前的教程列表:
- 在第一个教程中,我们创建了一个基本的OpenMap GIS应用程序,该应用程序在
JFrame
中显示一个从文件系统加载的具有一个形状图层的地图。 该教程基于com.bbn.openmap.app.example.SimpleMap
。 - 在第二个教程中,我们扩展了基本应用程序以使用
MapHandler
。 - 在第三个教程中,我们看到了如何利用
BeanContext
技术在openmap.properties
文件中声明我们的类并以声明方式构建整个应用程序。 - 第四个教程介绍了地图图层。
在本教程中,我们将讨论如何基于OpenMap构建3层GIS应用程序。 我们将在探索新的OpenMap功能方面稍作休息,并将主要回顾我们在先前教程中学到的内容。
2.需求和架构概述
您的老板或客户有一些要求。 在第一个冲刺(例如Scrum)中,应用程序应该能够:
- 从数据库读取数据/向数据库写入数据
- 在GIS地图上显示数据
- 与数据交互并显示其属性
- 将地理数据移动到其他位置并将其保存回数据库
- 创建/更新/删除地图数据
您可能会说得很简单,然后继续草绘应用程序的3层架构草案:
3层架构遵循模型-视图-控制器(MVC)架构模式。 从数据库(后端)创建模型 。 我们的View是我们在之前的教程中构建的OpenMap GIS应用程序,能够将数据显示为点,线,多边形等。并且Controller将所有内容连接起来。
类似的架构是Model-View-ViewModel(MVVM) ,我们还将对其进行简要讨论。
3.技术
3.1后端
后端主要是数据库,或更准确地说,是数据库管理系统(DBMS) 。 在这里,您可以选择:
*具有或不具有地理空间扩展的关系数据库 (Oracle,MySQL,Postgresql,MS SQL Server,Sqlite,Hsqldb,JavaDB等)。 地理空间扩展存在于MySQL , Postgresql , Oracle , SQLite ; MS SQL Server 2008附带内置的空间扩展。
* 基于对象的空间数据库
*具有空间支持的No-SQL数据库(例如CassandraDB, CouchDB , MongoDB , Neo4j等)
优化了空间数据库或地理数据库,以存储和查询表示几何空间中定义的对象的数据。 大多数空间数据库都允许根据OpenGIS规范来表示简单的几何对象,例如点,线和面以及空间索引。 但是,您无需具有GeoSpatial数据库即可构建GIS应用程序,但是使用它会带来好处。
3.2模型
您如何访问数据库以检索要用于Java应用程序的数据? 这是您可以使用的可能技术的列表:
- SQL查询数据库,即Java Database Connectivity或JDBC 。 这是传统方式(但是我们在2016年!)。 您需要“讲” SQL来查询数据库并在
ResultSets
检索数据,当您的应用程序遵循面向对象模型时(除非您的数据库也是面向对象的或与对象相关的),也不太方便。 - 对象关系映射,例如Java Persistence API(JPA) 。 这是将数据库表映射到Java对象的现代方法。 NetBeans为您提供了一个不错的JPA映射向导。
- 功能映射。 如果您是Java 8的人,并且喜欢lambda,那么为什么不使用λ表达式和Stream API代替SQL查询或JPA? Speedment是一个Java库,使这个梦想成为现实。 这是SQL和Stream API之间的比较,以便查询数据。
3.3控制器
最后一个问题是如何将视图连接到模型? 此处的关键问题是各个组件之间的松耦合。 松散耦合使您可以用另一种技术替换应用程序的任何层,而又不影响其他层(或进行有限的更改)。 有许多解决方案,例如:
- Java 6
ServiceLoader
- NetBeans查找API
- Dukescript(MVVM) 。 将DukeScript用于客户端-服务器应用程序的好处之一是代码重用。 您可以在客户端和服务器上使用相同的模型类。 这是映射JPA和Dukescript的教程 。
4.构建我们的应用程序
我不会在这里探索所有这些技术。 随意查看本文结尾处的参考。
在本文中,我们将看到如何使用模型的JPA和控制器的NetBeans Lookup API来构建MVC GIS应用程序。 在以后的文章中,我们将看到替代技术,例如用Speedment代替JPA和用Dukescript用MVVM代替MVC。
4.1我们的观点
在之前的文章中,我们已经创建了一个OpenMap应用程序。 让我们回顾一下并重构它。
我们的OpenMap应用程序包含以下文件层次结构:
-
openmap
-
DMSCoordInfoFormatter
-
DemoLayer
-
MyDrawingTool
-
OpenMap
-
-
openmap.properties
让我们像这样重构它:
-
openmap
-
OpenMap.java
-
openmap.controller
-
openmap.model
-
openmap.view
-
DMSCoordInfoFormatter.java
-
DemoLayer.java
-
MyDrawingTool.java
-
-
-
openmap.properties
也不要忘记更新openmap.properties
的路径。 上面的包结构描述了Model-View-Controller(MVC)设计模式。
在NetBeans中(而且在其他IDE),你可以很容易地应用重构(如移动一个文件或文件夹到另一个文件夹或重命名文件/文件夹)上的文件/文件夹,右键单击并选择子菜单重构下一个重构。
添加一个城市图层(来自OpenMap的原始openmap.properties
):
清单1 – openmap.properties –城市层
# These layers are turned on when the map is first started. Order
# does not matter here...
openmap.startUpLayers=demo cities graticule shapePolitical
# Layers listed here appear on the Map in the order of their names.
openmap.layers=demo cities graticule shapePolitical
...
###
# LocationLayer that holds cities. The palette for this layer lets
# you turn on the names and declutter matrix, if you want. The
# declutter matrix can get expensive at small scales.
cities.class=com.bbn.openmap.layer.location.LocationLayer
cities.prettyName=World Cities
cities.locationHandlers=csvcities
cities.useDeclutter=false
cities.declutterMatrix=com.bbn.openmap.layer.DeclutterMatrix
csvcities.class=com.bbn.openmap.layer.location.csv.CSVLocationHandler
csvcities.prettyName=World Cities
csvcities.locationFile=resources/map/cities.csv
csvcities.csvFileHasHeader=true
csvcities.locationColor=FF0000
csvcities.nameColor=008C54
csvcities.showNames=false
csvcities.showLocations=true
csvcities.nameIndex=0
csvcities.latIndex=5
csvcities.lonIndex=4
csvcities.csvFileHasHeader=true
并且不要忘记将cities.csv
复制到resources/map
。
再次运行该应用程序以查看新层。
4.2我们的数据库架构
下面的清单显示了我们的数据库模式。 它主要由一个Supplier
表组成。 我们想在地图上将我们的供应商显示为GeoPoint
。
以下是在NetBeans中创建SQLite数据库的步骤(您可以选择任何喜欢的DBMS):
- 右键单击
Libraries
- 从弹出菜单中选择添加JAR /文件夹...
- 导航到您从中下载SQLite的文件夹,然后选择
sqlite-jdbc-xxx.jar
- 选择复制到库文件夹 ,然后单击打开 。 驱动程序应显示在“ 库”下。
- 单击窗口→服务菜单以显示服务选项卡。
- 展开数据库节点
- 右键单击“ 驱动程序”节点,然后选择“ 新驱动程序”
- 点击添加
- 导航到从SQLite网站下载
sqlite-jdbc-xxxx.jar
文件的位置 ; 驱动程序类应为org.sqlite.JDBC
和Name →SQLite
- 单击确定 。
SQLite
应该在Drivers
- 右键单击数据库,然后选择
New Connection…
- 选择
SQLite
驱动程序,然后单击下一步 - 提供一个JDBC URL,例如
jdbc:sqlite:C:\db\suppliers.sqlite-3
并单击Finish 。 您的连接应显示在“ 数据库”下。 - 右键单击它,然后选择
Connect…
- 右键单击表,然后选择
Execute Command…
- 输入以下SQL语句,然后单击“
Run