Netbeans Quickstart

Welcome NetBeans Developers

Welcome to Geospatial for Java. This workbook is aimed at Java developers who are new to geospatial and would like to get started.

We are going to start out carefully with the steps needed to set up your Netbeans IDE. This workbook is also available for Eclipse or Maven command line use. The build tool Maven (http://maven.apache.org/) is our preferred option for downloading and managing jars. GeoTools projects tend to use a large number of jars and an automated solution is preferable.

If you are already familiar with Maven that is an advantage but if not, don’t worry, we will be explaining things step by step and we will also document how to set up things by hand as an alternative to using Maven.

These are visual tutorials that allows you to see what you are working with while you learn. These examples make use of Swing; be assured that this is only to make the examples easy and fun to use. These sessions are applicable to both server side and client side development.

We would like thank members of the GeoTools users list for their feedback while were preparing the course material, with special thanks to Tom Williamson for reviewing early drafts.

Java Install

We are going to be making use of Java so if you don’t have a Java Development Kit installed now is the time to do so. Even if you have Java installed already check out the optional Java Advanced Imaging and Java Image IO section – both of these libraries are used by GeoTools.

  1. Download the latest JDK from the java.sun.com website:

    https://adoptium.net/

  2. At the time of writing the latest JDK was:

    OpenJDK11U-jdk_x64_windows_hotspot_11.0.17_8.msi

  3. Click through the installer you will need to set an acceptance a license agreement and so forth. By default this will install to:

    C:\\Program Files\\Eclipse Adoptium\\jdk-11.0.17.8-hotspot

NetBeans Install

The NetBeans IDE is a popular choice for Java development and features excellent Maven integration.

  1. Download NetBeans (The Java SE download will be fine).

  2. At the time of netbeans-7.0.1-ml-javase-windows.exe was the latest installer.

  3. Click through the steps of the installer. You will notice it will pick up on the JDK you installed earlier.

    ../../_images/netbeansInstall.png

Quickstart

The GeoTools development community uses the build tool Maven which is integrated into the latest releases of NetBeans.

The advantages of using Maven are:

  • You only download as much of GeoTools as your application requires

  • Jars are downloaded to a single location in your home directory (in a hidden folder called .m2/repository)

  • Source code and javadocs are automatically downloaded and hooked up

Although Maven is a build tool it works by describing the contents of a project. This is a different approach then used by the Make or Ant tools which list the steps required to build.

The description of a project includes the required jars (called dependencies) and a repository on the internet where the jars can be downloaded. We will be using these facilities to bring GeoTools jars into our project as needed.

Creating the Project

Let’s get started:

  1. Start with File ‣ New Project to open the New Project wizard

  2. Select the Maven category; choose Maven Project and press Next.

    ../../_images/nbNewProject.png
  3. On the Maven Archetype page select “Maven Quickstart Archetype” and press Next.

    ../../_images/nbNewProjectArchetype.png
  4. We can now fill in the blanks

    • Project name: tutorial

    • GroupId: org.geotools

    ../../_images/nbNameAndLocation.png
  5. Click on the Finish button and the new project will be created.

  6. If this is your first time using Maven with NetBeans it will want to confirm that it is okay to use the copy of Maven included with NetBeans (it is also possible to use an external Maven executable from within Netbeans which is convenient if, for instance, you want to work with the same version of Maven within the IDE and from the command line).

Adding Jars to Your Project

The pom.xml file is used to describe the care and feeding of your maven project; we are going to focus on the dependencies needed for your project

When downloading jars maven makes use of a “local repository” to store jars.

PLATFORM

LOCAL REPOSITORY

Windows XP:

C:\Documents and Settings\You\.m2\repository

Windows:

C:\Users\You\.m2\repository

Linux and Mac:

~/.m2/repository

When downloading jars maven makes use of public maven repositories on the internet where projects such as GeoTools publish their work.

  1. The next step is for us to make it a GeoTools project by adding information to Maven’s project description file (“project object model” in Maven-speak) - pom.xml

    In the Projects panel open up the Project Files folder and double click on pom.xml to open it.

  2. We are going to start by defining the version number of GeoTools we wish to use. This workbook was written for 32-SNAPSHOT although you may wish to try a different version.

    For production a stable release of 32 should be used for geotools.version:

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <geotools.version>32-SNAPSHOT</geotools.version>
        <maven.deploy.skip>true</maven.deploy.skip>
      </properties>
    

    To make use of a nightly build set the geotools.version property to 32-SNAPSHOT .

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <geotools.version>27-SNAPSHOT</geotools.version>
        </properties>
    

    If you make any mistakes when editing the xml file you’ll see that your project will be renamed “<Badly formed Maven project>” in the Projects window. You can choose “Format” as a quick way to check if the tags line up. Or just hit undo and try again.

  3. Next we add two GeoTools modules to the dependencies section: gt-shapefile and gt-swing.

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.1</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-shapefile</artifactId>
                <version>${geotools.version}</version>
            </dependency>
            <dependency>
                <groupId>org.geotools</groupId>
                <artifactId>gt-swing</artifactId>
                <version>${geotools.version}</version>
            </dependency>
        </dependencies>
    
  4. And the repositories where these jars can be downloaded from:

        <repositories>
          <repository>
            <id>osgeo</id>
            <name>OSGeo Release Repository</name>
            <url>https://repo.osgeo.org/repository/release/</url>
            <snapshots><enabled>false</enabled></snapshots>
            <releases><enabled>true</enabled></releases>
          </repository>
          <repository>
            <id>osgeo-snapshot</id>
            <name>OSGeo Snapshot Repository</name>
            <url>https://repo.osgeo.org/repository/snapshot/</url>
            <snapshots><enabled>true</enabled></snapshots>
            <releases><enabled>false</enabled></releases>
          </repository>
        </repositories>
    

    Note

    Note the snapshot repository above is only required if you are using a nightly build (such as 32-SNAPSHOT)

  5. GeoTools requires Java 11, you need to tell Maven to use the 11 source level

      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.10.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    
  6. You can now right click on Libraries in the Projects window, then Download missing Dependencies from the pop-up menu. When downloading it will check the repositories we have listed above.

  7. We will continue to add dependencies on different parts of the GeoTools library as we work through these exercises; this fine grain control and the ability to download exactly what is needed is one of the advantages of using Maven.

  8. Here is what the completed pom.xml looks like:

    <project
      xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.geotools.tutorial</groupId>
      <artifactId>quickstart</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
      <name>GeoTools Quickstart</name>
      <url>http://maven.apache.org</url>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <geotools.version>32-SNAPSHOT</geotools.version>
        <maven.deploy.skip>true</maven.deploy.skip>
      </properties>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.2</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.geotools</groupId>
          <artifactId>gt-shapefile</artifactId>
          <version>${geotools.version}</version>
        </dependency>
        <dependency>
          <groupId>org.geotools</groupId>
          <artifactId>gt-swing</artifactId>
          <version>${geotools.version}</version>
        </dependency>
      </dependencies>
      <repositories>
        <repository>
        <id>osgeo</id>
        <name>OSGeo Release Repository</name>
        <url>https://repo.osgeo.org/repository/release/</url>
        <snapshots><enabled>false</enabled></snapshots>
        <releases><enabled>true</enabled></releases>
        </repository>
        <repository>
        <id>osgeo-snapshot</id>
        <name>OSGeo Snapshot Repository</name>
        <url>https://repo.osgeo.org/repository/snapshot/</url>
        <snapshots><enabled>true</enabled></snapshots>
        <releases><enabled>false</enabled></releases>
        </repository>
      </repositories>
      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.10.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
    • Recommend cutting and pasting the above to avoid mistakes when typing

    • You may also download pom.xml, if this opens in your browser use Save As to save to disk.

      The download has an optional quality assurance profile you can safely ignore.

Quickstart Application

Now that your environment is setup we can put together a simple Quickstart. This example will display a shapefile on screen.

  1. Create the package org.geotools.tutorial.quickstart.

  2. Create the org.geotools.tutorial.quickstart.Quickstart class using your IDE.

  3. Fill in the following code Quickstart.java:

    /*
     *    GeoTools Sample code and Tutorials by Open Source Geospatial Foundation, and others
     *    https://docs.geotools.org
     *
     *    To the extent possible under law, the author(s) have dedicated all copyright
     *    and related and neighboring rights to this software to the public domain worldwide.
     *    This software is distributed without any warranty.
     * 
     *    You should have received a copy of the CC0 Public Domain Dedication along with this
     *    software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
     */
     package org.geotools.tutorial.quickstart;
    
    import java.io.File;
    import java.util.logging.Logger;
    
    import org.geotools.api.data.FileDataStore;
    import org.geotools.api.data.FileDataStoreFinder;
    import org.geotools.api.data.SimpleFeatureSource;
    import org.geotools.map.FeatureLayer;
    import org.geotools.map.Layer;
    import org.geotools.map.MapContent;
    import org.geotools.styling.SLD;
    import org.geotools.api.style.Style;
    import org.geotools.swing.JMapFrame;
    import org.geotools.swing.data.JFileDataStoreChooser;
    
    /**
     * Prompts the user for a shapefile and displays the contents on the screen in a map frame.
     *
     * <p>This is the GeoTools Quickstart application used in documentationa and tutorials. *
     */
    public class Quickstart {
    
        private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(Quickstart.class);
        /**
         * GeoTools Quickstart demo application. Prompts the user for a shapefile and displays its
         * contents on the screen in a map frame
         */
        public static void main(String[] args) throws Exception {
            // display a data store file chooser dialog for shapefiles
            LOGGER.info( "Quickstart");
            LOGGER.config( "Welcome Developers");
            LOGGER.info("java.util.logging.config.file="+System.getProperty("java.util.logging.config.file"));
            File file = JFileDataStoreChooser.showOpenFile("shp", null);
            if (file == null) {
                return;
            }
            LOGGER.config("File selected "+file);
    
            FileDataStore store = FileDataStoreFinder.getDataStore(file);
            SimpleFeatureSource featureSource = store.getFeatureSource();
    
            // Create a map content and add our shapefile to it
            MapContent map = new MapContent();
            map.setTitle("Quickstart");
    
            Style style = SLD.createSimpleStyle(featureSource.getSchema());
            Layer layer = new FeatureLayer(featureSource, style);
            map.addLayer(layer);
    
            // Now display the map
            JMapFrame.showMap(map);
        }
    }
    
    • You may find cutting and pasting from the documentation to be easier then typing.

    • You may also download Quickstart.java

  4. Build the application and check that all is well in the Output window.

    ../../_images/nbQuickstart.png

    A fair bit of time will be spent downloading the libraries required.

Running the Application

  1. We need to download some sample data to work with. The http://www.naturalearthdata.com/ project is a great project supported by the North American Cartographic Information Society. Head to the link below and download some cultural vectors. You can use the ‘Download all 50m cultural themes’ at top.

    Please unzip the above data into a location you can find easily such as the desktop.

  2. Run the application to open a file chooser. Choose a shapefile from the example data set.

    ../../_images/QuickstartOpen.jpg
  3. The application will connect to your shapefile, 1.produce a map context and display the shapefile.

    ../../_images/QuickstartMap.jpg
  4. A couple of things to note about the code example:

    • The shapefile is not loaded into memory – instead it is read from disk each and every time it is needed This approach allows you to work with data sets larger then available memory.

    • We are using a very basic display style here that just shows feature outlines. In the examples that follow we will see how to specify more sophisticated styles.

Things to Try

Each tutorial consists of very detailed steps followed by a series of extra questions. If you get stuck at any point please ask your instructor; or sign up to the geotools-users email list.

Here are some additional challenges for you to try:

  • Try out the different sample data sets.

  • Zoom in, zoom out and show the full extent and use the info tool to examine individual countries in the sample countries.shp file.

  • Download the largest shapefile you can find and see how quickly it can be rendered. You should find that the very first time it will take a while as a spatial index is generated. After that rendering will become much faster.

  • Fast: We know that one of the ways people select a spatial library is based on speed. By design GeoTools does not load the above shapefile into memory (instead it streams it off of disk each time it is drawn using a spatial index to only bring the content required for display).

    If you would like to ask GeoTools to cache the shapefile in memory try the following code:

        /**
         * This method demonstrates using a memory-based cache to speed up the display (e.g. when
         * zooming in and out).
         *
         * <p>There is just one line extra compared to the main method, where we create an instance of
         * CachingFeatureStore.
         */
        public static void main(String[] args) throws Exception {
            // display a data store file chooser dialog for shapefiles
            File file = JFileDataStoreChooser.showOpenFile("shp", null);
            if (file == null) {
                return;
            }
    
            FileDataStore store = FileDataStoreFinder.getDataStore(file);
            SimpleFeatureSource featureSource = store.getFeatureSource();
            SimpleFeatureSource cachedSource =
                    DataUtilities.source(
                            new SpatialIndexFeatureCollection(featureSource.getFeatures()));
    
            // Create a map content and add our shapefile to it
            MapContent map = new MapContent();
            map.setTitle("Using cached features");
            Style style = SLD.createSimpleStyle(featureSource.getSchema());
            Layer layer = new FeatureLayer(cachedSource, style);
            map.addLayer(layer);
    
            // Now display the map
            JMapFrame.showMap(map);
        }
    

    For the above example to compile you will need to add the necessary imports.

    Note

    When building you may see a message that CachingFeatureSource is deprecated. It’s OK to ignore it, it’s just a warning. The class is still under test but usable.

  • Try and sort out what all the different “side car” files are – and what they are for. The sample data set includes shp, dbf and shx. How many other side car files are there?

  • Advanced: The use of FileDataStoreFinder allows us to work easily with files. The other way to do things is with a map of connection parameters. This techniques gives us a little more control over how we work with a shapefile and also allows us to connect to databases and web feature servers.

            File file = JFileDataStoreChooser.showOpenFile("shp", null);
    
            Map<String, Object> params = new HashMap<>();
            params.put("url", file.toURI().toURL());
            params.put("create spatial index", false);
            params.put("memory mapped buffer", false);
            params.put("charset", "ISO-8859-1");
    
            DataStore store = DataStoreFinder.getDataStore(params);
            SimpleFeatureSource featureSource = store.getFeatureSource(store.getTypeNames()[0]);
    
  • Important: GeoTools is an active open source project – you can quickly use maven to try out the latest nightly build by changing your pom.xml file to use a SNAPSHOT release.

    At the time of writing 32-SNAPSHOT is under active development.

    <properties>
    &nbsp;&nbsp;<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    &nbsp;&nbsp;<geotools.version>|branch|-SNAPSHOT</geotools.version>
    </properties>

    Double check your pom.xml file to include the OSGeo snapshot repository:

      <repositories>
        <repository>
        <id>osgeo</id>
        <name>OSGeo Release Repository</name>
        <url>https://repo.osgeo.org/repository/release/</url>
        <snapshots><enabled>false</enabled></snapshots>
        <releases><enabled>true</enabled></releases>
        </repository>
        <repository>
        <id>osgeo-snapshot</id>
        <name>OSGeo Snapshot Repository</name>
        <url>https://repo.osgeo.org/repository/snapshot/</url>
        <snapshots><enabled>true</enabled></snapshots>
        <releases><enabled>false</enabled></releases>
        </repository>
      </repositories>
      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.10.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
      <profiles>
        <profile>
          <id>qa</id>
          <activation>
            <property>
              <name>qa</name>
            </property>
          </activation>
          <properties>
            <maven.pmd.plugin.version>3.20.0</maven.pmd.plugin.version>
            <pmd.version>6.55.0</pmd.version>
            <pom.fmt.action>sort</pom.fmt.action>
          </properties>
          <build>
            <plugins>
              <plugin>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>3.14.0</version>
                <executions>
                  <execution>
                    <goals>
                      <goal>check</goal>
                    </goals>
                  </execution>
                </executions>
                <dependencies>
                  <dependency>
                    <groupId>net.sourceforge.pmd</groupId>
                    <artifactId>pmd-core</artifactId>
                    <version>${pmd.version}</version>
                  </dependency>
                  <dependency>
                    <groupId>net.sourceforge.pmd</groupId>
                    <artifactId>pmd-java</artifactId>
                    <version>${pmd.version}</version>
                  </dependency>
                </dependencies>
                <configuration>
                  <linkXRef>false</linkXRef>
                  <rulesets>
                    <ruleset>${project.basedir}/../../build/qa/pmd-ruleset.xml</ruleset>
                    <ruleset>${project.basedir}/../../build/qa/pmd-junit-ruleset.xml</ruleset>
                  </rulesets>
                  <failurePriority>3</failurePriority>
                  <minimumPriority>3</minimumPriority>
                  <verbose>true</verbose>
                  <printFailingErrors>true</printFailingErrors>
                  <includeTests>true</includeTests>
                </configuration>
              </plugin>
              <plugin>
                <groupId>com.github.spotbugs</groupId>
                <artifactId>spotbugs-maven-plugin</artifactId>
                <version>4.0.0</version>
                <executions>
                  <execution>
                    <goals>
                      <goal>check</goal>
                    </goals>
                  </execution>
                </executions>
                <configuration>
                  <effort>More</effort>
                  <!-- threshold>High</threshold -->
                  <xmlOutput>true</xmlOutput>
                  <maxRank>15</maxRank>
                  <excludeFilterFile>${project.basedir}/../../build/qa/spotbugs-exclude.xml</excludeFilterFile>
                  <jvmArgs>-XX:+TieredCompilation -XX:TieredStopAtLevel=1</jvmArgs>
                  <compilerArgs combine.children="append">
                    <arg>-Xlint:${lint}</arg>
                  </compilerArgs>
                </configuration>
              </plugin>
              <plugin>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>3.1.2</version>
                <executions>
                  <execution>
                    <goals>
                      <goal>check</goal>
                    </goals>
                  </execution>
                </executions>
                <dependencies>
                  <dependency>
                    <groupId>com.puppycrawl.tools</groupId>
                    <artifactId>checkstyle</artifactId>
                    <version>9.3</version>
                  </dependency>
                </dependencies>
                <configuration>
                  <logViolationsToConsole>true</logViolationsToConsole>
                  <configLocation>${project.basedir}/../..//build/qa/checkstyle-cc0.xml</configLocation>
                </configuration>
              </plugin>
              <plugin>
                <groupId>com.github.ekryd.sortpom</groupId>
                <artifactId>sortpom-maven-plugin</artifactId>
                <version>2.15.0</version>
                <executions>
                  <execution>
                    <phase>verify</phase>
                    <goals>
                      <goal>${pom.fmt.action}</goal>
                    </goals>
                  </execution>
                </executions>
                <configuration>
                  <skip>true</skip>
                </configuration>
              </plugin>
            </plugins>
          </build>
        </profile>
      </profiles>
    

    You can check the status of the build server producing current 32-SNAPSHOT here:

  • NetBeans has an interesting feature to show how the dependency system works - Right click on Libraries and choose Show Dependency

    ../../_images/nbGraph.png

    We will be making use of some of the project is greater depth in the remaining tutorials.

Maven Alternative

The alternative to using Maven to download and manage jars for you is to manually install them. To start with we will obtain GeoTools from the website:

  1. Download the GeoTools binary release from http://sourceforge.net/projects/geotools/files

  2. Extract the geotools-2.6.0-bin.zip file to C:\java\geotools-2.6.0 folder.

  3. If you open up the folder and have a look you will see GeoTools and all of the other jars that it uses including those from other libraries such as GeoAPI and JTS.

    ../../_images/gtunzipped.jpg
  4. We can now set up GeoTools as a library in NetBeans:

    From the menu bar choose Tools > Libraries to open the Library Manager.

  5. From the Library Manager press the New Library button.

  6. Enter “GeoTools” for the Library Name and press OK

  7. You can now press the Add JAR/Folder button and add in all the jars from C:\java\GeoTools-32-SNAPSHOT

  8. GeoTools includes a copy of the “EPSG” map projections database; but also allows you to hook up your own copy of the EPSG database as an option. However, only one copy can be used at a time so we will need to remove the following jars from the Library Manager:

  1. GeoTools allows you to work with many different databases; however to make them work you will need to download jdbc drivers from the manufacturer.

    For now remove the following plugins from the Library Manager:

    • gt-db2

    • gt-jdbc-db2

    • gt-oracle-spatial

    • gt-jdbc-oracle

  2. We are now ready to proceed with creating an example project. Select File > New Project

  3. Choose the default “Java Application”

  4. Fill in “Tutorial” as the project name; and our initial Main class will be called “Quickstart”.

  5. Open up Example in the Projects window, right click on Libraries and select Add Libraries. Choose GeoTools from the Add Library dialog.

  6. Congratulations ! You can now return to Quickstart or any of the other tutorials