Skip to content

Instantly share code, notes, and snippets.

@ognjenm
Forked from emxsys/feature_server.md
Created August 22, 2023 10:55
Show Gist options
  • Save ognjenm/4e7e9bfd5dd0968357135de7ba1d9e71 to your computer and use it in GitHub Desktop.
Save ognjenm/4e7e9bfd5dd0968357135de7ba1d9e71 to your computer and use it in GitHub Desktop.
How to setup a NASA feature server for place names

How to setup a NASA WorldWind feature server (WFS)

Ubuntu 18.04.4 LTS Initial Setup

Change root password

Changing password for root.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 

Add new user and set password

adduser xxx
chgpasswd 

Update the firewall

 $ ufw app list
Available applications:
  OpenSSH

$ sudo ufw allow OpenSSH
Rules update
Rules updated (v6)

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             

Install Tomcat Application Server

Install Java (for Tomcat and GeoServer)

sudo apt-get update
sudo apt-get install default-jdk

Install Tomcat

  • Create a tomcat group
  • Create a tomcat user
  • Download a Tomcat distribution to /tmp
  • Extract the distribution to /opt/tomcat
  • Adjust the permissions of /opt/tomcat

See: https://www.digitalocean.com/community/tutorials/install-tomcat-9-ubuntu-1804

sudo groupadd tomcat
sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat

cd /tmp
curl -O http://www-us.apache.org/dist/tomcat/tomcat-9/v9.0.17/bin/apache-tomcat-9.0.17.tar.gz
sudo mkdir /opt/tomcat
sudo tar xzvf apache-tomcat-9*tar.gz -C /opt/tomcat --strip-components=1

cd /opt/tomcat/
/opt/tomcat$ sudo chgrp -R tomcat /opt/tomcat
/opt/tomcat$ sudo chmod -R g+r conf
/opt/tomcat$ sudo chmod g+x conf
/opt/tomcat$ sudo chown  -R tomcat webapps/ work/ temp/ logs

Update Tomcat service

  • Get location of JAVA
  • Create tomcat.service file
  • Update service JAVA_HOME with JAVA location
  • Start Tomcat
  • Enable Tomcat service at startup

Get the path to Java

sudo update-java-alternatives -l

Example output

java-1.11.0-openjdk-amd64      1101       /usr/lib/jvm/java-1.11.0-openjdk-amd64
sudo nano /etc/systemd/system/tomcat.service

Paste the following into the tomcat.service file and edit the JAVA_HOME path:

[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Reload the service, start and enable the service.

sudo systemctl daemon-reload
sudo systemctl start tomcat
sudo systemctl status tomcat
sudo systemctl enable tomcat

Configure firewall to allow port 8080 (Tomcat)

$ sudo ufw allow 8080
Rule added
Rule added (v6)

Configure Tomcat users

$ sudo nano /opt/tomcat/webapps/host-manager/META-INF/context.xml
$ sudo nano /opt/tomcat/conf/tomcat-users.xml
$ sudo systemctl restart tomcat
$ sudo systemctl status tomcat

tomcat.users

<tomcat-users . . .>
    <user username="admin" password="password" roles="manager-gui,admin-gui"/>
</tomcat-users>

Allow manager app to be run by remote systems

  • Edit context.xml
  • Comment out default allow=ip-address or add remote ip address
sudo nano /opt/tomcat/webapps/manager/META-INF/context.xml

context.xml

<Context antiResourceLocking="false" privileged="true" >
  <!--
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
  -->
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?$
</Context>

Apache Web Server

Install Apache

sudo apt-get update
sudo apt-get install apache2

Setting ServerName

Add the server name to the configuration to avoid nuisance errors from apache2ctl.

sudo nano /etc/apache2/apache2.conf 

For example, setting the server name to "worldwind22"

...
ServerName "worldwind22"
...

Validate the change and restart.

sudo apache2ctl configtest
sudo systemctl restart apache2

Test http://localhost (or https://localhost) in your browser and validate the Apache2 default page is displayed.

Adjust the firewall to allow web traffic

sudo ufw app list
sudo ufw app info "Apache Full"
sudo ufw allow in "Apache Full"

Install Let's Encrypt

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache

Setup the SSL certificate

sudo certbot --apache -d emxsys.net
sudo certbot renew --dry-run

Install Apache module for reverse proxy for Tomcat

See: https://www.digitalocean.com/community/tutorials/how-to-encrypt-tomcat-8-connections-with-apache-or-nginx-on-ubuntu-16-04

sudo apt-get update
sudo apt-get install libapache2-mod-jk
sudo nano /etc/libapache2-mod-jk/workers.properties 

/etc/libapache2-mod-jk/workers.properties

...
workers.tomcat_home=/opt/tomcat
...

Adjust Apache virtual host to proxy with mod_jk

Edit your Apache site configuration file(s) and add the 'JKMount' directive.

sudo apache2ctl -S
sudo nano /etc/apache2/sites-available/000-default.conf 

Example: 000-default.conf

<VirtualHost *:80>
    . . .
    JKMount /* ajp13_worker
    . . .
</VirtualHost>

Restart Apache and then test http://localhost (or https://localhost) in your browser and validate the Tomcat home page is displayed.

sudo systemctl restart apache2

Adding CORS support: Header set Access-Control-Allow-Origin "*"

Edit your Apache configuration file(s) and add the Access-Control-Allow-Origin header

sudo nano /etc/apache2/sites-available/000-default-le-ssl.conf 
sudo nano /etc/apache2/sites-available/000-default.conf 

Example

<VirtualHost *:80>
    . . .
    Header set Access-Control-Allow-Origin "*"
    . . .
</VirtualHost>

Validate and restart.

sudo apache2ctl configtest
sudo systemctl restart apache2

Enable Apache modules

Enable the specified modules and restart Apache

sudo a2enmod headers
sudo systemctl restart apache2
sudo systemctl status apache2

Setup GeoServer

Download GeoServer

Visit the GeoServer (https://geoserver.org site and get the direct download link to the war servlet download for the latest release. Use this link to download the file with curl or simply download interactively via your browser.

cd \tmp
curl -O https://downloads.sourceforge.net/project/geoserver/GeoServer/2.15.0/geoserver-2.15.0-war.zip?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fgeoserver%2Ffiles%2FGeoServer%2F2.15.0%2Fgeoserver-2.15.0-war.zip%2Fdownload

Install GeoServer using the Tomcat Manager

  1. Extract the geoserver.war file from the downloaded release.
  2. Edit the webapps/manager/WEB-INF/web.xml to allow large .war files to be deployed. Otherwise the following error may occur: manager.log snippet
FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (102931473) exceeds the configured maximum (52428800)]

The original webapps/manager/WEB-INF/web.xml is constraned to 50MB

  <servlet>
    <servlet-name>HTMLManager</servlet-name>
    ...
    <multipart-config>
      <!-- 50MB max -->
      <max-file-size>52428800</max-file-size>
      <max-request-size>52428800</max-request-size>
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
  </servlet>

This webapps/manager/WEB-INF/web.xml snippet is large enough for geoserver.war

  <servlet>
    <servlet-name>HTMLManager</servlet-name>
    ...
    <multipart-config>
      <!-- 120MB max -->
      <max-file-size>1200000000</max-file-size>
      <max-request-size>1200000000</max-request-size>
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
  </servlet>
  1. Using a browser, access your Tomcat server's home page and log in to the Manager app.
    • Deploy the geoserver.war file

Configure GeoServer

  1. Change the admin password!

Setup PostGIS

See: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postgis-on-ubuntu-14-04

sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update

sudo apt-get install postgis

Success. You can now start the database server using:

/usr/lib/postgresql/10/bin/pg_ctl -D /var/lib/postgresql/10/main -l logfile start

The installation procedure created a user account called postgres that is associated with the default Postgres role. In order to use Postgres, we'll need to log into that account. You can do that by typing:

sudo -i -u postgres

Restore databases

1. Create the geonames and places PostGIS databases using psql.

First login as the postgres user.

sudo -i -u postgres

Now create the databases using psql with the PostGIS extension, as follows:

postgres:~$ psql
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1))
Type "help" for help.

Create the databases:

postgres=# create database geonames;
CREATE DATABASE
postgres=# create database places;
CREATE DATABASE 

Add the PostGIS extensions:

postgres=# \c geonames;
You are now connected to database "geonames" as user "postgres".
geonames=# create extension postgis;
CREATE EXTENSION
geonames=# \c places
You are now connected to database "places" as user "postgres".
places=# create extension postgis;
CREATE EXTENSION

Quite psql

places=# **\q**

2. Now we will restore the databases using `pg_restore'

We will restore the databases from a previous backup created with pg_dump. Numerous errors will be reported as the backups were created with earlier version of Postgres.

pg_restore -d places ww22dumpplaces 
pg_restore -d geonames  ww22dumpgeonames 

Validate the databases by comparing the content below with your \dt describe table output.

postgres=# \c geonames
You are now connected to database "geonames" as user "postgres".

geonames=# \dt
              List of relations
 Schema |      Name       | Type  |  Owner
--------+-----------------+-------+----------
 public | citiesover100k  | table | postgres
 public | citiesover10k   | table | postgres
 public | citiesover15k   | table | postgres
 public | citiesover1k    | table | postgres
 public | citiesover500k  | table | postgres
 public | citiesover50k   | table | postgres
 public | spatial_ref_sys | table | postgres
(7 rows)

geonames=# \c places
You are now connected to database "places" as user "postgres".

places=# \dt
                  List of relations
 Schema |           Name           | Type  |  Owner
--------+--------------------------+-------+----------
 public | cia                      | table | postgres
 public | cia2                     | table | postgres
 public | countries                | table | postgres
 public | geonet_20060905          | table | postgres
 public | geonet_20060905_adm1     | table | postgres
 public | geonet_20060905_adm2     | table | postgres
 public | geonet_20060905_capitals | table | postgres
 public | geonet_20060905_oceans   | table | postgres
 public | geonet_20060905_ppl      | table | postgres
 public | geonet_20060905_ppla     | table | postgres
 public | spatial_ref_sys          | table | postgres
 public | us_counties              | table | postgres
 public | wpl_continents           | table | postgres
 public | wpl_countries            | table | postgres
 public | wpl_desertsplains        | table | postgres
 public | wpl_geonet_a_adm1        | table | postgres
 public | wpl_geonet_a_adm2        | table | postgres
 public | wpl_geonet_a_adm3        | table | postgres
 public | wpl_geonet_p_ppl         | table | postgres
 public | wpl_geonet_p_ppla        | table | postgres
 public | wpl_geonet_p_pplc        | table | postgres
 public | wpl_lakesrivers          | table | postgres
 public | wpl_mountainsvalleys     | table | postgres
 public | wpl_oceans               | table | postgres
 public | wpl_trenchesridges       | table | postgres
 public | wpl_us_anthropogenic     | table | postgres
 public | wpl_us_terrain           | table | postgres
 public | wpl_us_water             | table | postgres
 public | wpl_uscities0            | table | postgres
 public | wpl_uscitiesover0        | table | postgres
 public | wpl_uscitiesover100k     | table | postgres
 public | wpl_uscitiesover10k      | table | postgres
 public | wpl_uscitiesover1k       | table | postgres
 public | wpl_uscitiesover500k     | table | postgres
 public | wpl_uscitiesover50k      | table | postgres
 public | wpl_waterbodies          | table | postgres
(36 rows)

places=#

Create users

You will need to create a database user for GeoServer to connect to Postgres.

psql
create user geoserver WITH PASSWORD 'password-string';
\q

Commands to start

psql
postgres=# **\c geonames** 
You are now connected to database "geonames" as user "postgres".
geonames=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public to geoserver;
GRANT
geonames=# \c places
You are now connected to database "places" as user "postgres".
places=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public to geoserver;
GRANT
places=# 
\q


This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wfs:WFS_Capabilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:tiger="http://www.census.gov" xmlns:sde="http://geoserver.sf.net" xmlns:topp="http://www.openplans.org/topp" xmlns:sf="http://www.openplans.org/spearfish" xmlns:nurc="http://www.nurc.nato.int" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://worldwind22.arc.nasa.gov:80/geoserver/schemas/wfs/1.1.0/wfs.xsd" updateSequence="38">
<ows:ServiceIdentification>
<ows:Title>NASA PlaceName WFS Server</ows:Title>
<ows:Abstract>
PlaceName WFS server for the NASA World Wind Project.
</ows:Abstract>
<ows:Keywords>
<ows:Keyword>WFS</ows:Keyword>
<ows:Keyword>GEOSERVER</ows:Keyword>
</ows:Keywords>
<ows:ServiceType>WFS</ows:ServiceType>
<ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion>
<ows:Fees>NONE</ows:Fees>
<ows:AccessConstraints>NONE</ows:AccessConstraints>
</ows:ServiceIdentification>
<ows:ServiceProvider>
<ows:ProviderName>NASA World Wind</ows:ProviderName>
<ows:ServiceContact>
<ows:IndividualName>Jay Parsons</ows:IndividualName>
<ows:PositionName/>
<ows:ContactInfo>
<ows:Phone>
<ows:Voice/>
<ows:Facsimile/>
</ows:Phone>
<ows:Address>
<ows:City/>
<ows:AdministrativeArea/>
<ows:PostalCode/>
<ows:Country/>
</ows:Address>
</ows:ContactInfo>
</ows:ServiceContact>
</ows:ServiceProvider>
<ows:OperationsMetadata>
<ows:Operation name="GetCapabilities">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="AcceptVersions">
<ows:Value>1.0.0</ows:Value>
<ows:Value>1.1.0</ows:Value>
</ows:Parameter>
<ows:Parameter name="AcceptFormats">
<ows:Value>text/xml</ows:Value>
</ows:Parameter>
</ows:Operation>
<ows:Operation name="DescribeFeatureType">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="outputFormat">
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
</ows:Operation>
<ows:Operation name="GetFeature">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="resultType">
<ows:Value>results</ows:Value>
<ows:Value>hits</ows:Value>
</ows:Parameter>
<ows:Parameter name="outputFormat">
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
<ows:Value>GML2</ows:Value>
<ows:Value>GML2-GZIP</ows:Value>
<ows:Value>SHAPE-ZIP</ows:Value>
<ows:Value>csv</ows:Value>
<ows:Value>gml3</ows:Value>
<ows:Value>json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
</ows:Parameter>
<ows:Constraint name="LocalTraverseXLinkScope">
<ows:Value>2</ows:Value>
</ows:Constraint>
</ows:Operation>
<ows:Operation name="GetGmlObject">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
<ows:Operation name="LockFeature">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="releaseAction">
<ows:Value>ALL</ows:Value>
<ows:Value>SOME</ows:Value>
</ows:Parameter>
</ows:Operation>
<ows:Operation name="GetFeatureWithLock">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="resultType">
<ows:Value>results</ows:Value>
<ows:Value>hits</ows:Value>
</ows:Parameter>
<ows:Parameter name="outputFormat">
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
<ows:Value>GML2</ows:Value>
<ows:Value>GML2-GZIP</ows:Value>
<ows:Value>SHAPE-ZIP</ows:Value>
<ows:Value>csv</ows:Value>
<ows:Value>gml3</ows:Value>
<ows:Value>json</ows:Value>
<ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
</ows:Parameter>
</ows:Operation>
<ows:Operation name="Transaction">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
<ows:Post xlink:href="http://worldwind22.arc.nasa.gov:80/geoserver/wfs?"/>
</ows:HTTP>
</ows:DCP>
<ows:Parameter name="inputFormat">
<ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
</ows:Parameter>
<ows:Parameter name="idgen">
<ows:Value>GenerateNew</ows:Value>
<ows:Value>UseExisting</ows:Value>
<ows:Value>ReplaceDuplicate</ows:Value>
</ows:Parameter>
<ows:Parameter name="releaseAction">
<ows:Value>ALL</ows:Value>
<ows:Value>SOME</ows:Value>
</ows:Parameter>
</ows:Operation>
</ows:OperationsMetadata>
<FeatureTypeList>
<Operations>
<Operation>Query</Operation>
<Operation>Insert</Operation>
<Operation>Update</Operation>
<Operation>Delete</Operation>
<Operation>Lock</Operation>
</Operations>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:cia</Name>
<Title>Country Boundaries</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>cia</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.999908447266 -89.9999008178711</ows:LowerCorner>
<ows:UpperCorner>179.999908447266 83.6274185180664</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:states</Name>
<Title>USA Population</Title>
<Abstract>This is some census data on the states.</Abstract>
<ows:Keywords>
<ows:Keyword>census</ows:Keyword>
<ows:Keyword>state</ows:Keyword>
<ows:Keyword>boundaries</ows:Keyword>
<ows:Keyword>united</ows:Keyword>
<ows:Keyword>states</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-124.731422 24.955967</ows:LowerCorner>
<ows:UpperCorner>-66.969849 49.371735</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:cia2</Name>
<Title>cia2_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>cia2</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.999908447266 -89.9999008178711</ows:LowerCorner>
<ows:UpperCorner>179.999908447266 83.6274185180664</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover100k</Name>
<Title>citiesover100k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>citiesover100k</ows:Keyword>
<ows:Keyword>geonames</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-157.85834724642817 -53.15001479517279</ows:LowerCorner>
<ows:UpperCorner>176.1666570407633 69.34056337939776</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover10k</Name>
<Title>citiesover10k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>citiesover10k</ows:Keyword>
<ows:Keyword>geonames</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.20002459201942 -46.400014998666585</ows:LowerCorner>
<ows:UpperCorner>179.99999093893337 70.16784668436131</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover15k</Name>
<Title>citiesover15k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>citiesover15k</ows:Keyword>
<ows:Keyword>geonames</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-171.73335484573312 -46.40001479986564</ows:LowerCorner>
<ows:UpperCorner>179.38332413655942 69.4136189795249</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover1k</Name>
<Title>citiesover1k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>citiesover1k</ows:Keyword>
<ows:Keyword>geonames</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.16670990584353 -77.8500138161935</ows:LowerCorner>
<ows:UpperCorner>179.30999090927148 78.21667681755594</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover500k</Name>
<Title>citiesover500k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>geonames</ows:Keyword>
<ows:Keyword>citiesover500k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-123.11933777650916 -38.00001481287081</ows:LowerCorner>
<ows:UpperCorner>153.0280802529173 60.175561938399134</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:citiesover50k</Name>
<Title>citiesover50k_Type</Title>
<Abstract>Generated from geonames</Abstract>
<ows:Keywords>
<ows:Keyword>geonames</ows:Keyword>
<ows:Keyword>citiesover50k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4269</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-123.9360102334934 -54.80001540044928</ows:LowerCorner>
<ows:UpperCorner>178.41665739437644 69.66667526228998</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:countries</Name>
<Title>countries_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>countries</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.200012207031 -90.0</ows:LowerCorner>
<ows:UpperCorner>178.00000000000003 78.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:geonet_20060905</Name>
<Title>geonet_20060905_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>geonet_20060905</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-175.200012207031 -51.7000007629395</ows:LowerCorner>
<ows:UpperCorner>179.216674804688 78.216667175293</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:geonet_20060905_capitals</Name>
<Title>geonet_20060905_capitals_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>geonet_20060905_capitals</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-175.200012207031 -51.7000007629395</ows:LowerCorner>
<ows:UpperCorner>179.216674804688 78.216667175293</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:us_counties</Name>
<Title>us_counties_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>us_counties</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.133392333984 17.6746921539307</ows:LowerCorner>
<ows:UpperCorner>179.788208007813 71.3980484008789</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_continents</Name>
<Title>wpl_continents_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_continents</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-102.0 -81.0</ows:LowerCorner>
<ows:UpperCorner>134.0 50.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_countries</Name>
<Title>wpl_countries_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_countries</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.0 -51.5</ows:LowerCorner>
<ows:UpperCorner>178.0 79.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_desertsplains</Name>
<Title>wpl_desertsplains_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_desertsplains</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-68.0 -54.5</ows:LowerCorner>
<ows:UpperCorner>129.0 42.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_a_adm1</Name>
<Title>wpl_geonet_a_adm1_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_geonet_a_adm1</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-115.0 -46.5</ows:LowerCorner>
<ows:UpperCorner>173.0 60.25</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_a_adm2</Name>
<Title>wpl_geonet_a_adm2_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_geonet_a_adm2</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-91.3000030517578 -40.75</ows:LowerCorner>
<ows:UpperCorner>144.25 57.16670227050781</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_a_adm3</Name>
<Title>wpl_geonet_a_adm3_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_geonet_a_adm3</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-89.8500061035156 -8.20000076293945</ows:LowerCorner>
<ows:UpperCorner>165.983001708984 72.5</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_p_ppl</Name>
<Title>wpl_geonet_p_ppl_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_geonet_p_ppl</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.983001708984 -54.9333000183105</ows:LowerCorner>
<ows:UpperCorner>179.98300170898406 82.4833068847656</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_p_ppla</Name>
<Title>wpl_geonet_p_ppla_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_geonet_p_ppla</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.133010864258 -54.8000030517578</ows:LowerCorner>
<ows:UpperCorner>177.48300170898406 70.0731048583984</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_geonet_p_pplc</Name>
<Title>wpl_geonet_p_pplc_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_geonet_p_pplc</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-175.200012207031 -51.7000007629395</ows:LowerCorner>
<ows:UpperCorner>179.21701049804702 78.2167053222656</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_lakesrivers</Name>
<Title>wpl_lakesrivers_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_lakesrivers</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-120.0 -16.0</ows:LowerCorner>
<ows:UpperCorner>76.0 66.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_mountainsvalleys</Name>
<Title>wpl_mountainsvalleys_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_mountainsvalleys</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-122.0 -45.0</ows:LowerCorner>
<ows:UpperCorner>146.0 58.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_oceans</Name>
<Title>wpl_oceans_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_oceans</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-150.0 -66.0</ows:LowerCorner>
<ows:UpperCorner>82.0 80.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_trenchesridges</Name>
<Title>wpl_trenchesridges_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_trenchesridges</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-140.0 -10.0</ows:LowerCorner>
<ows:UpperCorner>107.0 23.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_us_anthropogenic</Name>
<Title>wpl_us_anthropogenic_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_us_anthropogenic</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-178.333312988281 -42.4436111450195</ows:LowerCorner>
<ows:UpperCorner>179.291702270508 71.38556671142581</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_us_terrain</Name>
<Title>wpl_us_terrain_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_us_terrain</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-178.897201538086 -14.3713903427124</ows:LowerCorner>
<ows:UpperCorner>179.683303833008 71.1822204589844</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_us_water</Name>
<Title>wpl_us_water_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_us_water</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-179.468109130859 -14.5475006103516</ows:LowerCorner>
<ows:UpperCorner>179.983306884766 71.3883361816406</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscities0</Name>
<Title>wpl_uscities0_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_uscities0</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.654205322266 -14.3611106872559</ows:LowerCorner>
<ows:UpperCorner>178.877502441406 71.2980651855469</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover0</Name>
<Title>wpl_uscitiesover0_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_uscitiesover0</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-176.658111572266 17.9624996185303</ows:LowerCorner>
<ows:UpperCorner>-65.9091644287109 70.6369400024414</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover100k</Name>
<Title>wpl_uscitiesover100k_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>wpl_uscitiesover100k</ows:Keyword>
<ows:Keyword>postgres</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-157.858306884766 18.0130596160889</ows:LowerCorner>
<ows:UpperCorner>-65.9577789306641 61.2180633544922</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover10k</Name>
<Title>wpl_uscitiesover10k_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_uscitiesover10k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-158.190002441406 17.9861087799072</ows:LowerCorner>
<ows:UpperCorner>-65.6527786254883 64.8569412231445</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover1k</Name>
<Title>wpl_uscitiesover1k_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_uscitiesover1k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-166.536712646484 17.9555587768555</ows:LowerCorner>
<ows:UpperCorner>-65.301383972168 71.2905654907227</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover500k</Name>
<Title>wpl_uscitiesover500k_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_uscitiesover500k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-122.675003051758 29.4238891601563</ows:LowerCorner>
<ows:UpperCorner>-71.0602798461914 47.6063919067383</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_uscitiesover50k</Name>
<Title>wpl_uscitiesover50k_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_uscitiesover50k</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-123.020805358887 18.2030582427979</ows:LowerCorner>
<ows:UpperCorner>-66.0077743530273 48.7597236633301</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
<FeatureType xmlns:topp="http://www.openplans.org/topp">
<Name>topp:wpl_waterbodies</Name>
<Title>wpl_waterbodies_Type</Title>
<Abstract>Generated from postgres</Abstract>
<ows:Keywords>
<ows:Keyword>postgres</ows:Keyword>
<ows:Keyword>wpl_waterbodies</ows:Keyword>
</ows:Keywords>
<DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-169.0 -58.5800018310547</ows:LowerCorner>
<ows:UpperCorner>175.0 76.0</ows:UpperCorner>
</ows:WGS84BoundingBox>
</FeatureType>
</FeatureTypeList>
<ogc:Filter_Capabilities>
<ogc:Spatial_Capabilities>
<ogc:GeometryOperands>
<ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
<ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
<ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
<ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
</ogc:GeometryOperands>
<ogc:SpatialOperators>
<ogc:SpatialOperator name="Disjoint"/>
<ogc:SpatialOperator name="Equals"/>
<ogc:SpatialOperator name="DWithin"/>
<ogc:SpatialOperator name="Beyond"/>
<ogc:SpatialOperator name="Intersects"/>
<ogc:SpatialOperator name="Touches"/>
<ogc:SpatialOperator name="Crosses"/>
<ogc:SpatialOperator name="Contains"/>
<ogc:SpatialOperator name="Overlaps"/>
<ogc:SpatialOperator name="BBOX"/>
</ogc:SpatialOperators>
</ogc:Spatial_Capabilities>
<ogc:Scalar_Capabilities>
<ogc:LogicalOperators/>
<ogc:ComparisonOperators>
<ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
<ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
<ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
<ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
<ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
<ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
<ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
<ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
<ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
</ogc:ComparisonOperators>
<ogc:ArithmeticOperators>
<ogc:SimpleArithmetic/>
<ogc:Functions>
<ogc:FunctionNames>
<ogc:FunctionName nArgs="1">abs</ogc:FunctionName>
<ogc:FunctionName nArgs="1">abs_2</ogc:FunctionName>
<ogc:FunctionName nArgs="1">abs_3</ogc:FunctionName>
<ogc:FunctionName nArgs="1">abs_4</ogc:FunctionName>
<ogc:FunctionName nArgs="1">acos</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Area</ogc:FunctionName>
<ogc:FunctionName nArgs="1">asin</ogc:FunctionName>
<ogc:FunctionName nArgs="1">atan</ogc:FunctionName>
<ogc:FunctionName nArgs="2">atan2</ogc:FunctionName>
<ogc:FunctionName nArgs="3">between</ogc:FunctionName>
<ogc:FunctionName nArgs="1">boundary</ogc:FunctionName>
<ogc:FunctionName nArgs="1">boundaryDimension</ogc:FunctionName>
<ogc:FunctionName nArgs="2">buffer</ogc:FunctionName>
<ogc:FunctionName nArgs="3">bufferWithSegments</ogc:FunctionName>
<ogc:FunctionName nArgs="0">Categorize</ogc:FunctionName>
<ogc:FunctionName nArgs="1">ceil</ogc:FunctionName>
<ogc:FunctionName nArgs="1">centroid</ogc:FunctionName>
<ogc:FunctionName nArgs="2">classify</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Average</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Bounds</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Count</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Max</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Median</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Min</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Sum</ogc:FunctionName>
<ogc:FunctionName nArgs="1">Collection_Unique</ogc:FunctionName>
<ogc:FunctionName nArgs="2">Concatenate</ogc:FunctionName>
<ogc:FunctionName nArgs="2">contains</ogc:FunctionName>
<ogc:FunctionName nArgs="2">convert</ogc:FunctionName>
<ogc:FunctionName nArgs="1">convexHull</ogc:FunctionName>
<ogc:FunctionName nArgs="1">cos</ogc:FunctionName>
<ogc:FunctionName nArgs="2">crosses</ogc:FunctionName>
<ogc:FunctionName nArgs="2">dateFormat</ogc:FunctionName>
<ogc:FunctionName nArgs="2">dateParse</ogc:FunctionName>
<ogc:FunctionName nArgs="2">difference</ogc:FunctionName>
<ogc:FunctionName nArgs="1">dimension</ogc:FunctionName>
<ogc:FunctionName nArgs="2">disjoint</ogc:FunctionName>
<ogc:FunctionName nArgs="2">distance</ogc:FunctionName>
<ogc:FunctionName nArgs="1">double2bool</ogc:FunctionName>
<ogc:FunctionName nArgs="1">endPoint</ogc:FunctionName>
<ogc:FunctionName nArgs="1">envelope</ogc:FunctionName>
<ogc:FunctionName nArgs="2">EqualInterval</ogc:FunctionName>
<ogc:FunctionName nArgs="2">equalsExact</ogc:FunctionName>
<ogc:FunctionName nArgs="3">equalsExactTolerance</ogc:FunctionName>
<ogc:FunctionName nArgs="2">equalTo</ogc:FunctionName>
<ogc:FunctionName nArgs="1">exp</ogc:FunctionName>
<ogc:FunctionName nArgs="1">exteriorRing</ogc:FunctionName>
<ogc:FunctionName nArgs="1">floor</ogc:FunctionName>
<ogc:FunctionName nArgs="1">geometryType</ogc:FunctionName>
<ogc:FunctionName nArgs="1">geomFromWKT</ogc:FunctionName>
<ogc:FunctionName nArgs="1">geomLength</ogc:FunctionName>
<ogc:FunctionName nArgs="2">getGeometryN</ogc:FunctionName>
<ogc:FunctionName nArgs="1">getX</ogc:FunctionName>
<ogc:FunctionName nArgs="1">getY</ogc:FunctionName>
<ogc:FunctionName nArgs="1">getZ</ogc:FunctionName>
<ogc:FunctionName nArgs="2">greaterEqualThan</ogc:FunctionName>
<ogc:FunctionName nArgs="2">greaterThan</ogc:FunctionName>
<ogc:FunctionName nArgs="0">id</ogc:FunctionName>
<ogc:FunctionName nArgs="2">IEEEremainder</ogc:FunctionName>
<ogc:FunctionName nArgs="3">if_then_else</ogc:FunctionName>
<ogc:FunctionName nArgs="11">in10</ogc:FunctionName>
<ogc:FunctionName nArgs="3">in2</ogc:FunctionName>
<ogc:FunctionName nArgs="4">in3</ogc:FunctionName>
<ogc:FunctionName nArgs="5">in4</ogc:FunctionName>
<ogc:FunctionName nArgs="6">in5</ogc:FunctionName>
<ogc:FunctionName nArgs="7">in6</ogc:FunctionName>
<ogc:FunctionName nArgs="8">in7</ogc:FunctionName>
<ogc:FunctionName nArgs="9">in8</ogc:FunctionName>
<ogc:FunctionName nArgs="10">in9</ogc:FunctionName>
<ogc:FunctionName nArgs="1">int2bbool</ogc:FunctionName>
<ogc:FunctionName nArgs="1">int2ddouble</ogc:FunctionName>
<ogc:FunctionName nArgs="1">interiorPoint</ogc:FunctionName>
<ogc:FunctionName nArgs="2">interiorRingN</ogc:FunctionName>
<ogc:FunctionName nArgs="2">intersection</ogc:FunctionName>
<ogc:FunctionName nArgs="2">intersects</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isClosed</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isEmpty</ogc:FunctionName>
<ogc:FunctionName nArgs="2">isLike</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isNull</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isRing</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isSimple</ogc:FunctionName>
<ogc:FunctionName nArgs="1">isValid</ogc:FunctionName>
<ogc:FunctionName nArgs="3">isWithinDistance</ogc:FunctionName>
<ogc:FunctionName nArgs="1">length</ogc:FunctionName>
<ogc:FunctionName nArgs="2">lessEqualThan</ogc:FunctionName>
<ogc:FunctionName nArgs="2">lessThan</ogc:FunctionName>
<ogc:FunctionName nArgs="1">log</ogc:FunctionName>
<ogc:FunctionName nArgs="2">max</ogc:FunctionName>
<ogc:FunctionName nArgs="2">max_2</ogc:FunctionName>
<ogc:FunctionName nArgs="2">max_3</ogc:FunctionName>
<ogc:FunctionName nArgs="2">max_4</ogc:FunctionName>
<ogc:FunctionName nArgs="2">min</ogc:FunctionName>
<ogc:FunctionName nArgs="2">min_2</ogc:FunctionName>
<ogc:FunctionName nArgs="2">min_3</ogc:FunctionName>
<ogc:FunctionName nArgs="2">min_4</ogc:FunctionName>
<ogc:FunctionName nArgs="1">not</ogc:FunctionName>
<ogc:FunctionName nArgs="2">notEqualTo</ogc:FunctionName>
<ogc:FunctionName nArgs="2">numberFormat</ogc:FunctionName>
<ogc:FunctionName nArgs="1">numGeometries</ogc:FunctionName>
<ogc:FunctionName nArgs="1">numInteriorRing</ogc:FunctionName>
<ogc:FunctionName nArgs="1">numPoints</ogc:FunctionName>
<ogc:FunctionName nArgs="2">overlaps</ogc:FunctionName>
<ogc:FunctionName nArgs="1">parseBoolean</ogc:FunctionName>
<ogc:FunctionName nArgs="1">parseDouble</ogc:FunctionName>
<ogc:FunctionName nArgs="1">parseInt</ogc:FunctionName>
<ogc:FunctionName nArgs="1">parseLong</ogc:FunctionName>
<ogc:FunctionName nArgs="0">pi</ogc:FunctionName>
<ogc:FunctionName nArgs="2">pointN</ogc:FunctionName>
<ogc:FunctionName nArgs="2">pow</ogc:FunctionName>
<ogc:FunctionName nArgs="1">PropertyExists</ogc:FunctionName>
<ogc:FunctionName nArgs="2">Quantile</ogc:FunctionName>
<ogc:FunctionName nArgs="0">random</ogc:FunctionName>
<ogc:FunctionName nArgs="2">relate</ogc:FunctionName>
<ogc:FunctionName nArgs="3">relatePattern</ogc:FunctionName>
<ogc:FunctionName nArgs="1">rint</ogc:FunctionName>
<ogc:FunctionName nArgs="1">round</ogc:FunctionName>
<ogc:FunctionName nArgs="1">round_2</ogc:FunctionName>
<ogc:FunctionName nArgs="1">roundDouble</ogc:FunctionName>
<ogc:FunctionName nArgs="1">sin</ogc:FunctionName>
<ogc:FunctionName nArgs="1">sqrt</ogc:FunctionName>
<ogc:FunctionName nArgs="2">StandardDeviation</ogc:FunctionName>
<ogc:FunctionName nArgs="1">startPoint</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strConcat</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strEndsWith</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strEqualsIgnoreCase</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strIndexOf</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strLastIndexOf</ogc:FunctionName>
<ogc:FunctionName nArgs="1">strLength</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strMatches</ogc:FunctionName>
<ogc:FunctionName nArgs="4">strReplace</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strStartsWith</ogc:FunctionName>
<ogc:FunctionName nArgs="3">strSubstring</ogc:FunctionName>
<ogc:FunctionName nArgs="2">strSubstringStart</ogc:FunctionName>
<ogc:FunctionName nArgs="1">strToLowerCase</ogc:FunctionName>
<ogc:FunctionName nArgs="1">strToUpperCase</ogc:FunctionName>
<ogc:FunctionName nArgs="1">strTrim</ogc:FunctionName>
<ogc:FunctionName nArgs="2">symDifference</ogc:FunctionName>
<ogc:FunctionName nArgs="1">tan</ogc:FunctionName>
<ogc:FunctionName nArgs="1">toDegrees</ogc:FunctionName>
<ogc:FunctionName nArgs="1">toRadians</ogc:FunctionName>
<ogc:FunctionName nArgs="2">touches</ogc:FunctionName>
<ogc:FunctionName nArgs="1">toWKT</ogc:FunctionName>
<ogc:FunctionName nArgs="2">union</ogc:FunctionName>
<ogc:FunctionName nArgs="2">UniqueInterval</ogc:FunctionName>
<ogc:FunctionName nArgs="2">within</ogc:FunctionName>
</ogc:FunctionNames>
</ogc:Functions>
</ogc:ArithmeticOperators>
</ogc:Scalar_Capabilities>
<ogc:Id_Capabilities>
<ogc:FID/>
<ogc:EID/>
</ogc:Id_Capabilities>
</ogc:Filter_Capabilities>
</wfs:WFS_Capabilities>

public class NASAWFSPlaceNameLayer extends PlaceNameLayer {

    //String constants for name sets
    public static final String OCEANS="topp:wpl_oceans";
    public static final String CONTINENTS="topp:wpl_continents";
    public static final String WATERBODIES="topp:wpl_waterbodies";
    public static final String TRENCHESRIDGES="topp:wpl_trenchesridges";
    public static final String DESERTSPLAINS="topp:wpl_desertsplains";
    public static final String LAKESRIVERS="topp:wpl_lakesrivers";
    public static final String MOUNTAINSVALLEYS="topp:wpl_mountainsvalleys";
    public static final String COUNTRIES="topp:wpl_countries";
    public static final String GEONET_P_PPC="topp:wpl_geonet_p_pplc";
    public static final String CITIESOVER500K="topp:citiesover500k";
    public static final String CITIESOVER100K="topp:citiesover100k";
    public static final String CITIESOVER50K="topp:citiesover50k";
    public static final String CITIESOVER10K="topp:citiesover10k";
    public static final String CITIESOVER1K="topp:citiesover1k";
    public static final String USCITIESOVER0="topp:wpl_uscitiesover0";
    public static final String USCITIES0="topp:wpl_uscities0";
    public static final String US_ANTHROPOGENIC="topp:wpl_us_anthropogenic";
    public static final String US_WATER="topp:wpl_us_water";
    public static final String US_TERRAIN="topp:wpl_us_terrain";
    public static final String GEONET_A_ADM1="topp:wpl_geonet_a_adm1";
    public static final String GEONET_A_ADM2="topp:wpl_geonet_a_adm2";
    public static final String GEONET_P_PPLA="topp:wpl_geonet_p_ppla";
    public static final String GEONET_P_PPL="topp:wpl_geonet_p_ppl";
    public static final String GEONET_P_PPLC="topp:wpl_geonet_p_pplC";


    private static final String[] allNameSets={OCEANS, CONTINENTS, WATERBODIES, TRENCHESRIDGES, DESERTSPLAINS, LAKESRIVERS,
                                    MOUNTAINSVALLEYS, COUNTRIES, GEONET_P_PPC, CITIESOVER500K, CITIESOVER100K,
                                    CITIESOVER50K, CITIESOVER10K, CITIESOVER1K, USCITIESOVER0,USCITIES0,
                                    US_ANTHROPOGENIC, US_WATER, US_TERRAIN, GEONET_A_ADM1, GEONET_A_ADM2,
                                    GEONET_P_PPLA, GEONET_P_PPL};

    private static List activeNamesList = Arrays.asList(allNameSets);
    
    public NASAWFSPlaceNameLayer() {
        super(makePlaceNameServiceSet());
    }

    public void setPlaceNameSetsVisible(List names)
    {
        activeNamesList=names;
        makePlaceNameServiceSet();
    }

    private static PlaceNameServiceSet makePlaceNameServiceSet() {
        final String service = "https://worldwind22.arc.nasa.gov/geoserver/wfs";
        final String fileCachePath = "Earth/PlaceNames/WFSPlaceNamesVersion1.0";
        PlaceNameServiceSet placeNameServiceSet = new PlaceNameServiceSet();
        placeNameServiceSet.setExpiryTime(new GregorianCalendar(2008, 1, 11).getTimeInMillis());
        PlaceNameService placeNameService;
        final boolean addVersionTag=true;  //true if pointing to a new wfs server
        // Oceans
        if (activeNamesList.contains(OCEANS)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_oceans", fileCachePath, Sector.FULL_SPHERE, GRID_1x1,
                    java.awt.Font.decode("Arial-BOLDITALIC-12"), addVersionTag);
            placeNameService.setColor(new java.awt.Color(200, 200, 200));
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_A);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Continents
        if (activeNamesList.contains(CONTINENTS)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_continents", fileCachePath, Sector.FULL_SPHERE,
                    GRID_1x1, java.awt.Font.decode("Arial-BOLD-12"), addVersionTag);
            placeNameService.setColor(new java.awt.Color(255, 255, 240));
            placeNameService.setMinDisplayDistance(LEVEL_G);
            placeNameService.setMaxDisplayDistance(LEVEL_A);
            placeNameServiceSet.addService(placeNameService, false);
        }

         // Water Bodies
        if (activeNamesList.contains(WATERBODIES)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_waterbodies", fileCachePath, Sector.FULL_SPHERE,
                    GRID_4x8, java.awt.Font.decode("Arial-ITALIC-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.cyan);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_B);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Trenches & Ridges
        if (activeNamesList.contains(TRENCHESRIDGES)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_trenchesridges", fileCachePath, Sector.FULL_SPHERE,
                    GRID_4x8, java.awt.Font.decode("Arial-BOLDITALIC-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.cyan);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_B);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Deserts & Plains
        if (activeNamesList.contains(DESERTSPLAINS)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_desertsplains", fileCachePath, Sector.FULL_SPHERE,
                    GRID_4x8, java.awt.Font.decode("Arial-BOLDITALIC-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.orange);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_B);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Lakes & Rivers
        if (activeNamesList.contains(LAKESRIVERS)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_lakesrivers", fileCachePath, Sector.FULL_SPHERE,
                    GRID_8x16, java.awt.Font.decode("Arial-ITALIC-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.cyan);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_C);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Mountains & Valleys
        if (activeNamesList.contains(MOUNTAINSVALLEYS)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_mountainsvalleys", fileCachePath, Sector.FULL_SPHERE,
                    GRID_8x16, java.awt.Font.decode("Arial-BOLDITALIC-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.orange);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_C);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // Countries
        if (activeNamesList.contains(COUNTRIES)) {
            placeNameService = new PlaceNameService(service, "topp:countries", fileCachePath, Sector.FULL_SPHERE, GRID_4x8,
                    java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.white);
            placeNameService.setMinDisplayDistance(LEVEL_G);
            placeNameService.setMaxDisplayDistance(LEVEL_D);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // GeoNet World Capitals
        if (activeNamesList.contains(GEONET_P_PPLC)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_geonet_p_pplc", fileCachePath, Sector.FULL_SPHERE,
                    GRID_16x32,  java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_D);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // World Cities >= 500k
        if (activeNamesList.contains(CITIESOVER500K)) {
            placeNameService = new PlaceNameService(service, "topp:citiesover500k", fileCachePath, Sector.FULL_SPHERE,
                    GRID_8x16, java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0);
            placeNameService.setMaxDisplayDistance(LEVEL_D);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // World Cities >= 100k
        if (activeNamesList.contains(CITIESOVER100K)) {
            placeNameService = new PlaceNameService(service, "topp:citiesover100k", fileCachePath, Sector.FULL_SPHERE,
                    GRID_16x32, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(LEVEL_N);
            placeNameService.setMaxDisplayDistance(LEVEL_F);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // World Cities >= 50k and <100k
        if (activeNamesList.contains(CITIESOVER50K)) {
            placeNameService = new PlaceNameService(service, "topp:citiesover50k", fileCachePath, Sector.FULL_SPHERE,
                    GRID_16x32, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(LEVEL_N);
            placeNameService.setMaxDisplayDistance(LEVEL_H);
            placeNameServiceSet.addService(placeNameService, false);
        }

        // World Cities >= 10k and <50k
        if (activeNamesList.contains(CITIESOVER10K)) {
            placeNameService = new PlaceNameService(service, "topp:citiesover10k", fileCachePath, Sector.FULL_SPHERE,
                    GRID_36x72, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_I);
            placeNameServiceSet.addService(placeNameService, false);
        }

        // World Cities >= 1k and <10k
        if (activeNamesList.contains(CITIESOVER1K)) {
            placeNameService = new PlaceNameService(service, "topp:citiesover1k", fileCachePath, Sector.FULL_SPHERE,
                    GRID_36x72, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_K);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // US Cities (Population Over 0)
        if (activeNamesList.contains(USCITIESOVER0)) {
            //values for masking sector pulled from wfs capabilities request
            Sector maskingSector = new Sector(Angle.fromDegrees(18.0), Angle.fromDegrees(70.7), Angle.fromDegrees(-176.66), Angle.fromDegrees(-66.0));
            placeNameService = new PlaceNameService(service, "topp:wpl_uscitiesover0", fileCachePath, maskingSector,
                    GRID_36x72, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_N);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // US Cities (No Population)
        if (activeNamesList.contains(USCITIES0)) {
            //values for masking sector pulled from wfs capabilities request
            Sector maskingSector = new Sector(Angle.fromDegrees(-14.4), Angle.fromDegrees(71.3), Angle.fromDegrees(-176.66), Angle.fromDegrees(178.88));
            placeNameService = new PlaceNameService(service, "topp:wpl_uscities0", fileCachePath, maskingSector,
                    GRID_288x576, java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.orange);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_N);//M);
            placeNameServiceSet.addService(placeNameService, false);
        }

        // US Anthropogenic Features
        if (activeNamesList.contains(US_ANTHROPOGENIC)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_us_anthropogenic", fileCachePath, Sector.FULL_SPHERE, GRID_288x576,
                    java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.orange);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_P);
            placeNameServiceSet.addService(placeNameService, false);
        }

        // US Water Features
        if (activeNamesList.contains(US_WATER)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_us_water", fileCachePath, Sector.FULL_SPHERE, GRID_144x288,
                    java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.cyan);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_M);
            placeNameServiceSet.addService(placeNameService, false);
        }
       // US Terrain Features
        if (activeNamesList.contains(US_TERRAIN)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_us_terrain", fileCachePath, Sector.FULL_SPHERE, GRID_72x144,
                    java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.orange);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_O);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // GeoNET Administrative 1st Order
        if (activeNamesList.contains(GEONET_A_ADM1)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_geonet_a_adm1", fileCachePath, Sector.FULL_SPHERE, GRID_36x72,
                    java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_N);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // GeoNET Administrative 2nd Order
        if (activeNamesList.contains(GEONET_A_ADM2)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_geonet_a_adm2", fileCachePath, Sector.FULL_SPHERE, GRID_36x72,
                    java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.yellow);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_N);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // GeoNET Populated Place Administrative
        if (activeNamesList.contains(GEONET_P_PPLA)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_geonet_p_ppla", fileCachePath, Sector.FULL_SPHERE, GRID_36x72,
                    java.awt.Font.decode("Arial-BOLD-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.pink);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_N);
            placeNameServiceSet.addService(placeNameService, false);
        }
        // GeoNET Populated Place
        if (activeNamesList.contains(GEONET_P_PPL)) {
            placeNameService = new PlaceNameService(service, "topp:wpl_geonet_p_ppl", fileCachePath, Sector.FULL_SPHERE, GRID_36x72,
                    java.awt.Font.decode("Arial-PLAIN-10"), addVersionTag);
            placeNameService.setColor(java.awt.Color.pink);
            placeNameService.setMinDisplayDistance(0d);
            placeNameService.setMaxDisplayDistance(LEVEL_O);
            placeNameServiceSet.addService(placeNameService, false);
        }

        return placeNameServiceSet;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment