A Guide for Developers Traveling Through OpenLayers - 7. How to Manage Geospatial Data: GeoServer
A Guide for Developers Traveling Through OpenLayers - 7. How to Manage Geospatial Data: GeoServer
In the previous chapter, we put geospatial data into a DB. Now, all that's left is to set up a proper way to communicate that data, and we'll be able to freely use the geospatial data stored in the DB from the web or from an app.
But as mentioned time and again, geospatial data has a clear distinction from other kinds of data: it's spatial data. Because geospatial data isn't ordinary text-based data, it's extremely fragile when it comes to CRUD. Even though we put it into a DB to enable freer communication, it gains no real advantage for CRUD at all.
In other words, whether it's MyBatis or JPA, ordinary DB communication makes it difficult to fully retrieve geospatial data.
This is where GeoServer comes in. GeoServer is a web server for sharing and editing GIS data. It's open software developed in JAVA.
It can communicate the GIS data you want in a variety of formats via APIs, and since it handles things like coordinate system conversion and tile rendering at the engine level, it dramatically reduces the amount of GIS computation logic developers have to implement themselves.
You can check installation details on the official GeoServer website. GeoServer files are provided in two forms.
- Stand-Alone: a standalone installer version. It includes its own WAS.
- Platform Independent Binary: a general-purpose binary file for any OS
- Windows Installer: a Windows-only exe file
- Web Archive: a WAR version. Can run on any WAS implementing JavaEE, such as Tomcat.
You can use whichever method you prefer.
If you're already running a separate Tomcat instance and also use GeoServer's standalone version, the ports will collide since both default to 8080. That's because the default port for GeoServer's standalone version is also 8080. You can change jetty.port=8080 in start.ini to whichever port you want.
With the default configuration, you can access GeoServer at https://example.com/geoserver.
If this page comes up, the installation was completed successfully.
Every GeoServer setting is managed through the web, so you can manage the settings you want right there.
The default account's ID/password is admin/geoserver.
GeoServer's server settings also include CORS. This is easy to miss on first install—if you forget to configure CORS and send a request, it may get rejected due to the CORS settings.
You'll need to modify web.xml, though the location of web.xml differs slightly between the binary and WAR files.
- Binary
- {ROOT}/webapps/geoserver/WEB-INF/web.xml
- WAR
- {ROOT}/WEB-INF/web.xml
- For WAR, Tomcat must be running so that it's been unpacked.
Either way, find and edit web.xml. You'll find the following entries in the file.
XML
<!-- Uncomment following filter to enable CORS in Jetty. Do not forget the second config block further down. <filter> <filter-name>cross-origin</filter-name> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> <init-param> <param-name>chainPreflight</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>allowedOrigins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>allowedMethods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>allowedHeaders</param-name> <param-value>*</param-value> </init-param> </filter> --> <!-- Uncomment following filter to enable CORS in Tomcat. Do not forget the second config block further down. <filter> <filter-name>cross-origin</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>*</param-value> </init-param> </filter> -->
Both blocks are commented out by default, and depending on which type of GeoServer you're running, you'll need to remove the comments from one of the two blocks to apply the CORS configuration. Use the filter-class to tell them apart.
XML
<filter> <filter-name>cross-origin</filter-name> <!-- Note this! 👇 --> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>*</param-value> </init-param> </filter>
For WAR, since it depends on the settings of the Tomcat that runs it, you should uncomment the config block where the filter-class value is org.apache.catalina.filters.CorsFilter.
XML
<filter> <filter-name>cross-origin</filter-name> <!-- Note this! 👇 --> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>*</param-value> </init-param> </filter>
For the non-WAR version, rather than running on top of Tomcat like WAR does, the program runs on its own, so it already has a web server called Jetty bundled inside it.
So you need to uncomment the config block where the filter-class value is org.eclipse.jetty.servlets.CrossOriginFilter.
XML
<!-- Uncomment following filter to enable CORS <filter-mapping> <filter-name>cross-origin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> -->
If you scroll down a bit further from the CORS settings in web.xml, you'll find the commented-out config shown above.
This enables the mapping for the cross-origin filter you just activated above, and by default it applies to every URL.
XML
<filter> <filter-name>cross-origin</filter-name> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <!-- Note this! 👇 --> <param-value>https://example1.com,https://example2.com</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>*</param-value> </init-param> </filter>
The default CORS filter setting is to open CORS access to every domain. If you leave it as-is, anyone can send requests to your GeoServer and receive responses.
If you want to allow requests only from specific domains, configure it as shown above. If there are multiple domains, separate them with commas.
If you keep using the default account as-is, you're exposed to a security risk. So it's safer to either change the password or create a brand new account to manage instead.
Click the [Users, Groups, Roles] menu in the side menu. Click the [Users/Groups] tab at the top to manage accounts. The admin account is the most basic account provided by default, so it's highly exposed. It's safer to either change its password appropriately or use an entirely different account instead.
Click the [Add new user] button among the buttons at the top.
Enter your desired account name and password. Enabling [ADMIN] in the roles section at the bottom grants the same permissions as the existing admin account.
It's safer to disable any account you're not using. From the same menu as before, click on the admin account to enter it.
Enable the [Disable] checkbox below the account name and save, and the account will be disabled.
Now that GeoServer is installed, we need a process to tell GeoServer which data it should serve. This process is called "adding a layer."
Layers are organized into the following categories:
- Layer: the smallest subdivision representing the data itself. This corresponds to a table in a DB.
- Layer Group: a grouping of multiple layers. When you need to call several layers at once, grouping them lets you simplify the layer call.
- Store: a mid-level category representing the data store. DBs and SHPs fall under this. It contains multiple layers and groups underneath it.
- Workspace: the top-level category for managing layers in GeoServer. It contains multiple stores underneath it.
A workspace contains stores, and a store contains layer groups and layers. In other words, to add a layer, you first create a workspace, then add a store, then create the layer, in that order.
Let's add a workspace, the top-level category for layers. Click the [Workspaces] menu in the left sidebar.
Click [Add new workspace] to add a workspace.
Specify a name and a URI. Since the URI will need to be entered together later when calling the layer, be sure to enter something appropriate.
Let's create a store that holds a layer. You can connect either an SHP or a DB.
For DBs, PostgreSQL is supported by default, and you can add connections to other DBs via separate plugins. The MariaDB (MySQL) we'll use in this chapter also requires adding a separate plugin.
Click [Add new Store] to create a store.
Choose the connection method you want. You can specify an SHP on the file system, or connect to a DB.
You can download the plugin corresponding to each version from the GeoServer download page.
Since it's best to grab the plugin matching the Stable version of your installed version from the linked site, be sure to check the version carefully.
For the MariaDB (MySQL) plugin, you can download it by clicking [Vector Formats - MySQL] at the bottom.
You can also find plugins for other DBs like Oracle and MongoDB there, so refer to them if needed. Click [Extensions - Extensions] to see the full list of available plugins.
Unzipping the downloaded plugin produces a jar file, and you just need to place this jar library into GeoServer's library folder. Place it in one of the paths below.
We'll refer to Tomcat's install path as CATALINA_HOME.
- Tomcat global library: CATALINA_HOME/lib
- GeoServer library: CATALINA_HOME/webapps/geoserver/WEB-INF/lib
After that, restarting will apply the change. Once the MySQL plugin is installed, you'll see that MySQL-related items have been added to the store list in the [Add new Store] menu.
If you'd rather not set up a separate DB, you can also build a layer from file-based SHP.
Click [Directory of Spatial files].
- Select the workspace to assign it to.
- Choose a name for the data store.
- Specify the SHP path.
- Specify the character set of the data.
Then click Save to create the SHP-based store.
If you have a DB managing GIS data, you can link it with GeoServer to build a layer.
Before proceeding, make sure the following two conditions are met:
- The GIS data must already be inserted into the DB.
- The MySQL plugin must be installed.
Click [MySQL].
- Select the workspace to assign it to.
- Choose a name for the data store.
- Enter the host. (IP or domain)
- Enter the port.
- Enter the database name.
- Enter the account name and password.
These are the required fields, and the remaining options below relate to Connection Pool settings, so feel free to adjust them separately if you'd like.
Then click Save to create the MySQL-based store.
Let's add the layer that forms the basis of the GIS data. A valid store must already have been added for the layer to be added successfully.
Click [Add a new layer].
- Select the target store. A list of layers available to add will be displayed.
- Click the [Publish] button next to the layer you want.
- Specify the coordinate system. You can search for and select the coordinate system you want.
- Specify the layer's bounding box. Clicking [Compute from data] and [Compute from native bounds] will calculate it automatically for each.
- Click [Publish] in the tab at the top.
- Specify the [Default Style] under [WMS Settings].
- This style is what gets applied by default for rendering when a WMS request comes in. (More details in a separate document later)
Then click Save to add the layer. Once you've gone this far, the layer becomes callable from GeoServer.
When calling a layer, you can identify it using the format {workspace URI name}:{layer name}. For example, if you named the workspace's URI storage and the layer name polygon, you could identify that layer using the format storage:polygon.
There are also many other settings related to map services, so be sure to explore them.
