<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*
 * MapViewer.java
 *
 * Created on Jun 30, 2009, 4:14:25 PM
 */
package usda.weru.gis.gui;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.swing.JLabel;
import systems.uom.common.USCustomary;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.apache.log4j.Logger;
import org.geotools.data.DataStore;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.MapContent;

import org.geotools.ows.wms.Layer;
import org.geotools.ows.wms.WMSCapabilities;
import org.geotools.ows.wms.WebMapServer;
import org.geotools.ows.wms.map.WMSLayer;
import org.geotools.ows.ServiceException;
import org.geotools.ows.wms.WMSUtils;
import org.geotools.ows.wmts.WebMapTileServer;
import org.geotools.ows.wmts.client.WMTSTileService;
import org.geotools.ows.wmts.model.TileMatrixSet;
import org.geotools.ows.wmts.model.WMTSCapabilities;
import org.geotools.ows.wmts.model.WMTSLayer;
import org.geotools.ows.wmts.model.WMTSServiceType;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.styling.Style;
import org.geotools.tile.TileService;
import org.geotools.tile.util.TileLayer;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import org.opengis.geometry.primitive.Point;
import org.openide.util.Exceptions;
import usda.weru.gis.latlong.LatLong;
import usda.weru.gis.GISData;
import usda.weru.gis.GISLookup;
import usda.weru.gis.GISUtil;
import usda.weru.gis.MapData;
import usda.weru.gis.data.CropManagementZone;
import usda.weru.gis.data.Territory;
import usda.weru.gis.gui.tiles.OSMServiceWeps;
import usda.weru.gis.gui.tiles.debug.TileLayerWeps;
import usda.weru.util.About;
import usda.weru.util.ConfigData;
import usda.weru.weps.location.CligenDataModel;
import usda.weru.weps.location.Station;
import usda.weru.weps.location.WindgenDataModel;

/**
 *
 * @author Joseph A. Levin &lt;joelevin@weru.ksu.edu&gt;
 */

public class MapViewer extends javax.swing.JFrame {

    boolean initialized;
    private static final long serialVersionUID = 1L;
    public static final String WepsLayerOpacityKey = "WepsLayerOpacity";
    private boolean exit = false;
    private List&lt;Layer&gt; wmsLayers = null;
    private final MapController c_controller;
    private LatLong c_selectedLatLong;
    public static final String PROP_SELECTEDLATLONG = "MapViewerSelectedLatLong";
    public static final String PROP_RESETLATLONG = "MapViewerResetLatLong";
    private FeatureLayer layerCurrentLocationMarker;
    private static Rectangle c_restoreBounds;
    private int c_restoreState;    
    private LayerTableModel layerTableModel;
    private int currentZoomLevel;
    private Dimension viewerInitialSize;
    private Dimension viewerMaxSize;
    private Dimension viewerMaxSizeAlmost;
    LatLong currentLocation;
    LatLong initialLocation;
    private static final Logger logger = Logger.getLogger(MapViewer.class);
    
//    private MapContent contentImageryWms;
//    private MapContent contentImageryTiles;
//    private MapContent contentOsmTiles;    
//    private MapContent contentWmsOsm;
//    private MapContent contentShapesAboveImagery;
//    private MapContent contentShapesBelowImagery;
    
    public static final String prismDataLayerName = "Cached Prism Data";
    protected DefaultFeatureCollection prismLayerCollection;
    protected FeatureLayer prismLayer;
    
    private static enum WmsTypes {
        wmsImageryUSGS,
        wmsOsm
    }
    
    private static enum WmtsTypes {
        wmtsImageryNationalmap,
        wmtsImageryEarthdata,
    }
    
    private static enum OsmTilesTypes {
        osmTile
    }

    public MapViewer() {
        int w,h;
        w = ConfigData.getIntParm(ConfigData.viewerInitialSizeWidth, 900);
        h = ConfigData.getIntParm(ConfigData.viewerInitialSizeHeight, 600);
        viewerInitialSize = new Dimension (w,h);
//        w = ConfigData.getIntParm(ConfigData.viewerMaximumSizeWidth, 1400);
//        h = ConfigData.getIntParm(ConfigData.viewerMaximumSizeHeight, 800);
//        viewerMaxSize = new Dimension (w,h);
//        viewerMaxSizeAlmost = new Dimension (w-10,h-10);
        
        initialized = false;
        setIconImage (About.getWeruIconImage());
        initComponents();
        positionWingen.setVisible(false);
        demoWingenLabel.setVisible(false);
        positionCligen.setVisible(false);
        demoCligenLabel.setVisible(false);
        
        InternalZoomAction zoomAction = new InternalZoomAction();
        addMouseWheelListener(zoomAction);
        
        // loading, restore size and location if possible
        Rectangle bounds;
        int state;
        synchronized (MapViewer.class) {
            bounds = c_restoreBounds;
            state = c_restoreState;
        }
        if (bounds != null) {
            setBounds(bounds);
            setExtendedState(state);
        }

        // when a window is closing, save its state
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                c_restoreBounds = getBounds();
                c_restoreState = getExtendedState();
            }
        });

        c_controller = mapPane.getMapLayer();

        // selection handler
        MouseAdapter selection = new InternalSelectionHandler();
        c_controller.addMouseListener(selection);
        c_controller.addMouseMotionListener(selection);
        currentZoomLevel = ConfigData.getIntParm(ConfigData.viewerDefaultZoom, 4);
        c_controller.setZoom(currentZoomLevel);
        c_controller.setViewer(this);
        
        layerTableModel = null;
//        contentImageryWms = null;
//        contentImageryTiles = null;
//        contentOsmTiles = null;
//        contentWmsOsm = null;
//        contentShapesAboveImagery = null;
//        contentShapesBelowImagery = null;
        prismLayerCollection = null;
        prismLayer = null;
        
        initialLocation = null;
        initializeZoomBar();
        
        setSize(viewerInitialSize);
        showWindowSize(viewerInitialSize);
   }
    
    public void setZoomBarExternal(int newZoom) {
        if(newZoom != currentZoomLevel &amp;&amp;
           newZoom &gt;= jSzoomBar.getMinimum() &amp;&amp;
           newZoom &lt;= jSzoomBar.getMaximum()) {
            
            jSzoomBar.setValue(newZoom);
            jSzoomBar.repaint();
        }
    }
    
    private void initializeZoomBar() {
        jSzoomBar.setValue(currentZoomLevel);
        jSzoomBar.setLabelTable(jSzoomBar.createStandardLabels(10));
        jSzoomBar.setPaintLabels(true);
    }
    
    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        if (b) {
            if (!initialized) {
                initContent();
            }
            c_controller.setRenderEnabled(b);
            if (b) {
                initialLocation = currentLocation;
            }
        }
    }    
    
    public void initContent () {

        MapContent mapContent;
        
        setupLayerTable ();
        
        setContentImageryWms (createWmsContent(WmsTypes.wmsImageryUSGS, new MapContent()));
        setContentImageryWmsOsm (createWmsContent(WmsTypes.wmsOsm, new MapContent()));
       
        mapContent = new MapContent();
        mapContent = createWmtsContent(WmtsTypes.wmtsImageryNationalmap, mapContent);
        mapContent = createShapeContentBelowImagery(mapContent);
        setContentShapesBelowImagery (mapContent);
        
        mapContent = new MapContent();
        mapContent = createOsmTilesContent(OsmTilesTypes.osmTile, mapContent);
        mapContent = createShapeContentAboveImagery(mapContent);
        setContentShapesAboveImagery (mapContent);
        
//        setContentImageryTiles ();
//        setContentOsmTiles ();
//        setContentShapesBelowImagery ();
        
        initialized = true;
    }
    
    public boolean checkServerAccessibility () {
        return true;
    }
    
    private void setupLayerTable () {
        if (layerTableModel == null) {
            layerTableModel = new LayerTableModel(this);
            layerTable.setModel(layerTableModel);
            // size the left column
            layerTable.getColumnModel().getColumn(0).setMaxWidth(45);
        }
    }
    
    private void setContentImageryWms(MapContent map) {
//            contentImageryWms = map;
            mapPane.getMapLayer().setContentImageryWms(map);
            layerTableModel.setContentImageryWms(map);
            layerTable.setModel(layerTableModel);
    }
    
    private void setContentImageryWmsOsm(MapContent map) {
//            contentImageryWms = map;
            mapPane.getMapLayer().setContentImageryWmsOsm(map);
            layerTableModel.setContentImageryWmsOsm(map);
            layerTable.setModel(layerTableModel);
    }
    
//    private void setContentImageryTiles(MapContent map) {
//            contentImageryTiles = map;
//            mapPane.getMapLayer().setContentImageryWmts(map);
//            layerTableModel.setContentImageryWmts(map);
//            layerTable.setModel(layerTableModel);
//    }
    
//    private void setContentOsmTiles(MapContent map) {
//            contentOsmTiles = map;
//            mapPane.getMapLayer().setContentImageryOsmTiles(map);
//            layerTableModel.setContentImageryOsmTiles(map);
//            layerTable.setModel(layerTableModel);
//    }
    
//    private void setContentWmsOsm(MapContent map) {
//            contentWmsOsm = map;
//            mapPane.getMapLayer().setContentMap(map);
//            layerTableModel.addContentMap(map);
//            layerTable.setModel(layerTableModel);
//    }

    private void setContentShapesAboveImagery(MapContent map) {
//        if (contentOsmTiles != null) {
//            map.addLayers(contentOsmTiles.layers());
//            map.moveLayer(map.layers().size()-1, 0);
//        }
//                contentShapesAboveImagery = map;
                mapPane.getMapLayer().setContentShapesAboveImagery(map);
                layerTableModel.setContentShapesAboveImagery(map);
                layerTable.setModel(layerTableModel);
    }

    private void setContentShapesBelowImagery(MapContent map) {
//                contentShapesBelowImagery = map;
                mapPane.getMapLayer().setContentShapesBelowImagery(map);
                layerTableModel.setContentShapesBelowImagery(map);
                layerTable.setModel(layerTableModel);
    }

    private MapContent getContentShapesAboveImagery() {
        return mapPane.getMapLayer().getContentShapesAboveImagery();
    }


    /**
     * creates the red crosshairs at the center of the map view
     * @param location the center of the map viewer
     */
    public void setCurrentLocationMarker(final LatLong location) {
        currentLocation = location;
        if (initialLocation == null) {
            initialLocation = currentLocation;
        }
        FeatureLayer old = layerCurrentLocationMarker;
        layerCurrentLocationMarker = createLatLongMarkerLayer(location);
        if (old != null) {
            getContentShapesAboveImagery().removeLayer(old);
        }
        getContentShapesAboveImagery().addLayer(layerCurrentLocationMarker);
        
        ShowPositionData(location);
        
        updatePrismDataLocationLayer();
    }

    /*
     * returns a layer with one thing on it: the red crosshairs
     */
    private FeatureLayer createLatLongMarkerLayer(LatLong location) {

        Coordinate center = GISUtil.toCoordinate(location);

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("markerType");
        typeBuilder.setNamespaceURI("usda.weru.gis");

        typeBuilder.add("location", Point.class, DefaultGeographicCRS.WGS84);
        typeBuilder.setDefaultGeometry("location");
        typeBuilder.add("name", String.class);

        SimpleFeatureType markerType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(markerType);

        builder.add(new org.locationtech.jts.geom.GeometryFactory().createPoint(center));
        builder.add("Current LatLong");

        DefaultFeatureCollection collection = new DefaultFeatureCollection("latlongMarker", markerType);
        SimpleFeature marker = builder.buildFeature(null);
        collection.add(marker);

        Style style = GISGUIUtil.createCrossPointStyle(Color.RED, Color.PINK);

        FeatureLayer layer = new FeatureLayer(collection, style, "Current Location");

        return layer;
    }
    

    private FeatureLayer createWindgenStationLayer() {

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("windgenStation");
        typeBuilder.setNamespaceURI("usda.weru.gis");

        typeBuilder.add("location", Point.class, DefaultGeographicCRS.WGS84);
        typeBuilder.setDefaultGeometry("location");
        typeBuilder.add("name", String.class);

        SimpleFeatureType markerType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(markerType);
        DefaultFeatureCollection collection = new DefaultFeatureCollection("windgenStations", markerType);

        WindgenDataModel data = WindgenDataModel.getInstance();
        for (Station station : data.stations()) {
            builder.reset();
            builder.add(new org.locationtech.jts.geom.GeometryFactory().
                    createPoint(GISUtil.toCoordinate(station.getLatLong())));
            builder.add(station.getDisplayName());
            SimpleFeature marker = builder.buildFeature(null);
            collection.add(marker);
        }

        Style style = GISGUIUtil.createCirclePointStyle(5, Color.RED, Color.GRAY);

        FeatureLayer layer = new FeatureLayer(collection, style, "Windgen Stations");
        layer.setVisible(false);

        return layer;
    }

    private FeatureLayer createCligenStationLayer() {

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("cligenStation");
        typeBuilder.setNamespaceURI("usda.weru.gis");

        typeBuilder.add("location", Point.class, DefaultGeographicCRS.WGS84);
        typeBuilder.setDefaultGeometry("location");
        typeBuilder.add("name", String.class);

        SimpleFeatureType markerType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(markerType);
        DefaultFeatureCollection collection = new DefaultFeatureCollection("cligenStations", markerType);

        CligenDataModel data = CligenDataModel.getInstance();
        for (Station station : data.stations()) {
            builder.reset();
            builder.add(new org.locationtech.jts.geom.GeometryFactory()
                    .createPoint(GISUtil.toCoordinate(station.getLatLong())));
            builder.add(station.getDisplayName());
            SimpleFeature marker = builder.buildFeature(null);
            collection.add(marker);
        }

        Style style = GISGUIUtil.createCirclePointStyle(5, Color.BLUE, Color.GRAY);

        FeatureLayer layer = new FeatureLayer(collection, style, "Cligen Stations");
        layer.setVisible(false);

        return layer;
    }

    protected FeatureLayer createPrismDataLocationLayer() {

        DefaultFeatureCollection collection;
        collection = buildPrismLayerCollection(null, false);
        prismLayerCollection = collection;
        
        Style style = GISGUIUtil.createCirclePointStyle(5, Color.GREEN, Color.RED);

        FeatureLayer layer = new FeatureLayer(collection, style, prismDataLayerName);
        layer.setVisible(false);
        prismLayer = layer;

        return layer;
    }
    
    public void updatePrismDataLocationLayer() {
        if (prismLayer.isVisible()) {
            prismLayerCollection = buildPrismLayerCollection (prismLayerCollection);
            // MEH: ugly, but all I can find to force the layer to re-draw.
            prismLayer.setVisible(false);
            prismLayer.setVisible(true);
        }
    }
    
    protected DefaultFeatureCollection buildPrismLayerCollection (DefaultFeatureCollection collection) {
        return buildPrismLayerCollection (collection, true);
    }
    protected DefaultFeatureCollection buildPrismLayerCollection (DefaultFeatureCollection collection, boolean addData) {
        
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("prismDataLocation");
        typeBuilder.setNamespaceURI("usda.weru.gis");

        typeBuilder.add("location", Point.class, DefaultGeographicCRS.WGS84);
        typeBuilder.setDefaultGeometry("location");
        typeBuilder.add("name", String.class);
        
        SimpleFeatureType markerType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(markerType);
        
        if (collection == null) {
            collection = new DefaultFeatureCollection("prismDataLocations", markerType);
        } else {
            Collection&lt;SimpleFeature&gt; cTemp = new DefaultFeatureCollection(collection);
            collection.removeAll(cTemp);
        }
        
        if (addData) {
            File prismCacheDir = new File (About.getWepsCacheDir()+"/Prism");

            for (File f : prismCacheDir.listFiles()) {
                String name = f.getName();
                if (name.startsWith("prismCell")) {
                    //lon / lat separator in file name is 2nd period
                    int separator = name.indexOf('.',  name.indexOf('.')+1);
                    double lonFile = Double.valueOf(name.substring(9,separator));
                    double latFile = Double.valueOf(name.substring(separator+1, name.indexOf(".json")));
                    LatLong latlong = LatLong.valueOf(latFile, lonFile, USCustomary.DEGREE_ANGLE);

                    builder.reset();
                    builder.add(new org.locationtech.jts.geom.GeometryFactory()
                            .createPoint(GISUtil.toCoordinate(latlong)));
                    SimpleFeature marker = builder.buildFeature(null);
                    collection.add(marker);
                }
            }
        }
        return collection;
    }

    private FeatureLayer createCrLmodSoilDataLocationLayer() {

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("soilDataLocation");
        typeBuilder.setNamespaceURI("usda.weru.gis");

        typeBuilder.add("location", Point.class, DefaultGeographicCRS.WGS84);
        typeBuilder.setDefaultGeometry("location");
        typeBuilder.add("name", String.class);

        SimpleFeatureType polyType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(polyType);
        DefaultFeatureCollection collection = new DefaultFeatureCollection("prismDataLocations", polyType);
        
        File soilCacheDir = new File (About.getWepsCacheDir()+"/Soils");
        File soilFile = new File (soilCacheDir, "CSIP Soil Service.polygons");
        try {
            FileReader soilReader = new FileReader (soilFile);
            
            String s;
            while ((s = FileReadLine(soilReader)) != null) {
                s = s.replace("Polygon:", "");
                ArrayList&lt;LatLong&gt; points = new ArrayList&lt;&gt;();
                ArrayList&lt;Coordinate&gt; coords = new ArrayList&lt;&gt;();
                
                while (s.length() &gt; 1) {
                    int commaIdx = s.indexOf(',');
                    int semiIdx = s.indexOf(';');
                    double lonFile = Double.valueOf(s.substring(0,commaIdx));
                    double latFile = Double.valueOf(s.substring(commaIdx+1, semiIdx));
                    LatLong latlong = LatLong.valueOf(latFile, lonFile, USCustomary.DEGREE_ANGLE);
                    points.add(latlong);
                    coords.add(GISUtil.toCoordinate(latlong));
                    s = s.substring(semiIdx+1, s.length());
                }
                coords.add(coords.get(0));

                builder.reset();
                Coordinate carr[] = new Coordinate[0];
                carr = coords.toArray(carr);
                org.locationtech.jts.geom.GeometryFactory factory = new GeometryFactory();
                LinearRing ring = factory.createLinearRing(carr);
                org.locationtech.jts.geom.Polygon poly = new org.locationtech.jts.geom.Polygon(ring, null, factory);
                builder.add(poly);
                builder.set("name", "Soil data polygon");
                //builder.add("prism");
                SimpleFeature feature = builder.buildFeature(null);
                collection.add(feature);
            }
        } catch (FileNotFoundException ex) {
            Exceptions.printStackTrace(ex);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        
        Style style = GISGUIUtil.createShapeStyle(5, Color.CYAN, .5, Color.BLUE, 2);

        FeatureLayer layer = new FeatureLayer(collection, style, "Cached Soil Data");
        layer.setVisible(false);

        return layer;
    }
    
    
    private MapContent createWmsContent(WmsTypes type, MapContent content) {
        String urlStr;
        URL url;
        WebMapServer wms = null;
        WMSCapabilities wmsCapabilities = null;
        String titleStr = null;
        int layerNum = 0;
        
        int display = 0;
        float opacity = (float)1.;
        boolean visible = false;
        if (type == WmsTypes.wmsImageryUSGS) {
            visible = ConfigData.getIntParm(ConfigData.wmsUsgsImageryVisibleDefault, 0) &gt; 0;
            display = ConfigData.getIntParm(ConfigData.wmsImageryEnabled, 1);
            opacity = ConfigData.getFloatParm(ConfigData.wmsImageryOpacity, (float)1.);
        } else if (type == WmsTypes.wmsOsm) {
            visible = ConfigData.getIntParm(ConfigData.wmtsOsmOverlayVisibleDefault, 0) &gt; 0;
            display = ConfigData.getIntParm(ConfigData.wmtsOsmOverlayEnabled, 1);
            opacity = ConfigData.getFloatParm(ConfigData.wmtsOsmOverlayOpacity, (float)1.);
        }
        
        if(display == 1) {
            try {        
                switch (type) {
                    case wmsImageryUSGS:
                        urlStr = "https://basemap.nationalmap.gov/arcgis/services/USGSImageryOnly/MapServer/WMSServer?request=GetCapabilities&amp;service=WMS";
                        url = new URL (urlStr);
                        wms = new WebMapServer(url);
                        wmsCapabilities = wms.getCapabilities();
                        titleStr = "Imagery (WMS) - USGS";
                        layerNum = 0;
                        break;
                    case wmsOsm:
                        urlStr = "https://ows.terrestris.de/osm/service?";
                        url = new URL (urlStr);
                        wms = new WebMapServer(url);
                        wmsCapabilities = wms.getCapabilities();
                        titleStr = "Street Maps (overlay)";
                        layerNum = 1;
                        break;
                }

                if(wmsCapabilities!=null &amp;&amp; wms!=null){
                    Layer[] mapLayers = WMSUtils.getNamedLayers(wmsCapabilities);
                    Layer layer = mapLayers[layerNum];
                    Layer layer2 = wmsCapabilities.getLayerList().get(0);
                    WMSLayer wmsLayer = new WMSLayer(wms, layer);
                    wmsLayer.setTitle(titleStr);
                    wmsLayer.setVisible(visible);
                    content.addLayer(wmsLayer);
                    if (opacity &lt; 1.) {
                        content.getUserData().put(WepsLayerOpacityKey, opacity);
                    }
                }            
            } catch (MalformedURLException ex) {
                logger.error("MalformedURL in createWmsContent", ex);
            } catch (IOException ex) {
                logger.error("IOException in createWmsContent", ex);
            } catch (ServiceException ex) {
                logger.error("ServiceException in createWmsContent", ex);
            }
        }
        logger.info("createWmsContent completed");
        return content;
    }
    
    private MapContent createWmtsContent(WmtsTypes type, MapContent content) {
        String urlStr;
        URL url;
        WebMapTileServer wmts = null;
        WMTSCapabilities wmtsCapabilities = null;
        String titleStr = null;
        List&lt;WMTSLayer&gt; layers;
        WMTSLayer wmtsTileLayer = null;
        TileMatrixSet tileLayerMatSet = null;
        String tileUrlStr = null;
        
        int display = ConfigData.getIntParm(ConfigData.wmtsImageryEnabled, 1);
        float opacity = ConfigData.getFloatParm(ConfigData.wmtsImageryOpacity, (float)1.);
        boolean visible = false;
        if (type == WmtsTypes.wmtsImageryNationalmap &amp;&amp; 
            ConfigData.getIntParm(ConfigData.wmtsImageryNationalmapVisibleDefault, 1) &gt; 0) {
            visible = true;
//        } else if (type == WmtsTypes.wmtsImageryEarthdata &amp;&amp; 
//                   ConfigData.getIntParm(ConfigData.wmtsImageryEarthdataVisibleDefault, 0) &gt; 0) {
//            visible = true;
        }
        
        if(display == 1) {
            c_controller.setZoomMax(94);
            try {        
                switch (type) {
                    case wmtsImageryNationalmap:
                        urlStr = "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/WMTS";
                        url = new URL (urlStr);
                        wmts = new WebMapTileServer(url);
                        wmtsCapabilities = wmts.getCapabilities();
                        titleStr = "Imagery (tiles) - NationalMap";
                        layers = wmtsCapabilities.getLayerList();
                        wmtsTileLayer = getLayerByName (layers, "USGSImageryOnly");
                        tileLayerMatSet = getMatrixSetByName (wmtsTileLayer, 
                                wmtsCapabilities, "default028mm");
                        // doesn't work
                        //tileUrlStr = getUrlTemplateStr (wmtsTileLayer);
                        tileUrlStr = (tileUrlStr != null) ? tileUrlStr : 
                            "https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{TileMatrix}/{TileRow}/{TileCol}";
                        break;
//                    case wmtsImageryEarthdata:
//                        urlStr = "https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/wmts.cgi?VERSION=1.0.0&amp;Request=GetCapabilities&amp;Service=WMTS";
//                        url = new URL (urlStr);
//                        wmts = new WebMapTileServer(url);
//                        wmtsCapabilities = wmts.getCapabilities();
//                        titleStr = "Imagery (WMTS) - Earthdata";
//                        layers = wmtsCapabilities.getLayerList();
//                        wmtsTileLayer = getLayerByName (layers, "BlueMarble_NextGeneration");
//                        tileLayerMatSet = getMatrixSetByName (wmtsTileLayer, 
//                                wmtsCapabilities, "500m");
//                        tileUrlStr = getUrlTemplateStr (wmtsTileLayer);
//                        tileUrlStr = (tileUrlStr != null) ? tileUrlStr : 
//                            "https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/BlueMarble_NextGeneration/default/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg";
//                        break;
                }
                
                TileService service = null;
                if (tileLayerMatSet != null &amp;&amp; wmtsTileLayer != null) {        
                    try {
                       service = new WMTSTileService(tileUrlStr, WMTSServiceType.REST, wmtsTileLayer, "", tileLayerMatSet);
                    } catch (Exception ex) {
                        service = null;
                        System.err.println ("Failed to load from server:" + tileUrlStr.toString());
                    }

                    if(service != null){
                        TileLayer tileLayer = new TileLayer(service);
                        tileLayer.setTitle(titleStr);
                        tileLayer.setVisible(visible);
                        content.addLayer(tileLayer );
                        if (opacity &lt; 1.) {
                            content.getUserData().put(WepsLayerOpacityKey, opacity);
                        }
                    }
                }
            } catch (MalformedURLException ex) {
                logger.error("MalformedURL in createWmtsContent", ex);
            } catch (IOException ex) {
                logger.error("IOException in createWmtsContent", ex);
            } catch (ServiceException ex) {
                logger.error("ServiceException in createWmtsContent", ex);
            }
        }
        logger.info("createWmtsContent completed");
        return content;
    }
    
    private MapContent createOsmTilesContent(OsmTilesTypes type, MapContent content) {
        String urlStr = "";
        String titleStr = "";
        OSMServiceWeps service = null;

        int display = ConfigData.getIntParm(ConfigData.wmtsOsmEnabled, 1);
        float opacity = ConfigData.getFloatParm(ConfigData.wmtsOsmOpacity, (float)1.);
        boolean visible = false;
        if (type == OsmTilesTypes.osmTile &amp;&amp; 
            ConfigData.getIntParm(ConfigData.wmtsOsmVisibleDefault, 0) &gt; 0) {
            visible = true;
        }
        
        try {
            if(display == 1) {
                switch (type) {
                    case osmTile:
                        urlStr = "https://tile.openstreetmap.org/";
                        service = new OSMServiceWeps("OSM", urlStr);
                        titleStr = "Street Maps (filled)";
                        break;
                }
            }
        } catch (Exception ex) {
            service = null;
            System.err.println ("Failed to load from server:" + urlStr);
            logger.error("ServiceException in createOsmTilesContent", ex);
        }

        if(service != null){
            TileLayerWeps tileLayer = new TileLayerWeps(service);
            tileLayer.setTitle(titleStr);
            tileLayer.setVisible(visible);
            content.addLayer(tileLayer );
            if (opacity &lt; 1.) {
                content.getUserData().put(WepsLayerOpacityKey, opacity);
            }
        }
        logger.info("createOsmTilesContent completed");
        return content;
    }
    
    public WMTSLayer getLayerByName (List&lt;WMTSLayer&gt; layerList, String name) {
        for (WMTSLayer layer : layerList) {
           if (layer.getName().contentEquals(name)) {
               return layer;
           }
        }
        return null;
    }
    
    public TileMatrixSet getMatrixSetByName (WMTSLayer layer, 
                                WMTSCapabilities capabilities, String name) {
        for (String tileMatrixId : layer.getTileMatrixLinks().keySet()) {
            if (tileMatrixId.contentEquals(name)) {
                return capabilities.getMatrixSet(tileMatrixId);
            }
        }
        return null;
    }
    
    
    protected String FileReadLine (FileReader rdr) throws IOException {
        int c;
        String s = "";
        while ((c = rdr.read()) != -1) {
            s += (char)c;
            if ((char)c == '\n') {
                break;
            }
            if ((char)c == ';') {
                int i = 1;
            }
        }
        if (c == -1 &amp;&amp; s.length() == 0) {
            s = null;
        }
        return s;
    }
    
    public String getUrlTemplateStr (WMTSLayer layer) {
        String retStr = null;
        List&lt;String&gt; formats = layer.getFormats();
        for (String s : formats) {
            retStr = layer.getTemplate(s);
            if (retStr != null) {
                break;
            }
        }
        return retStr;
    }
    
    private MapContent createShapeContentAboveImagery(MapContent content) {

//        final MapContent content = new MapContent();
        GISData data = GISData.getInstance();

        //add shape layers
        for (Name name : data.getNames()) {
            DataStore store = data.dataStore(name);
            ArrayList&lt;FeatureLayer&gt; toAdd = getLayers(store);
            for (FeatureLayer l : toAdd) {
                if (!isLayerBelowImagery(l)) {
                    content.addLayer(l);
                }
            }                   
        }

        content.addLayer(createWindgenStationLayer());
        content.addLayer(createCligenStationLayer());
        content.addLayer(createPrismDataLocationLayer());
        content.addLayer(createCrLmodSoilDataLocationLayer());
        
        return content;
    }
     
    private MapContent createShapeContentBelowImagery(MapContent content) {

//        final MapContent content = new MapContent();
        GISData data = GISData.getInstance();

        //add shape layers
        for (Name name : data.getNames()) {
            DataStore store = data.dataStore(name);
            // hack for visibility
            ArrayList&lt;FeatureLayer&gt; toAdd = getLayers(store);
            for (FeatureLayer l : toAdd) {
                if (isLayerBelowImagery(l) &amp;&amp; isLayerEnabled(l)) {
                    l.setVisible(checkLayerVisible(l));
                    content.addLayer(l);
                }
            }                   
        }
        return content;
    }
    
    private boolean isLayerBelowImagery (FeatureLayer layer) {
        String nameStr = layer.getTitle().toString();
        if (nameStr.contains(ConfigData.worldBordersLayerName)
            || nameStr.startsWith(ConfigData.usStatesLayerName)
            || nameStr.startsWith(ConfigData.usCountiesLayerName)
            || nameStr.startsWith(ConfigData.chinaProvLayerName)
            ) {
            return true;
        }
        return false;
    }
    
    private boolean isLayerEnabled (FeatureLayer layer) {
        String nameStr = layer.getTitle().toString();
        if (nameStr.contains(ConfigData.worldBordersLayerName)) {
            String mode = ConfigData.getStringParm(ConfigData.worldBordersLayerMode, ConfigData.layersOutlineModeVal);
            boolean outline = mode.contentEquals("outline");
            if (nameStr.contains(ConfigData.layersOutlineName)) {
                return outline;
            } else {
                return !outline;
            }
        }
        if (nameStr.contains(ConfigData.usStatesLayerName)) {
            String mode = ConfigData.getStringParm(ConfigData.usStatesLayerMode, ConfigData.layersOutlineModeVal);
            boolean outline = mode.contentEquals("outline");
            if (nameStr.contains(ConfigData.layersOutlineName)) {
                return outline;
            } else {
                return !outline;
            }
        }
        if (nameStr.contains(ConfigData.chinaProvLayerName)) {
            String mode = ConfigData.getStringParm(ConfigData.chinaProvLayerMode, ConfigData.layersOutlineModeVal);
            boolean outline = mode.contentEquals("outline");
            if (nameStr.contains(ConfigData.layersOutlineName)) {
                return outline;
            } else {
                return !outline;
            }
        }
        return true;
    }
    
    private boolean checkLayerVisible (FeatureLayer layer) {
        String nameStr = layer.getTitle().toString();
        int lv = layer.isVisible() ? 1 : 0;
        if (nameStr.contains(ConfigData.worldBordersLayerName)) {
            int v = ConfigData.getIntParm(ConfigData.worldBordersVisible, lv);
            return v == 1;
        }
        if (nameStr.contains(ConfigData.usStatesLayerName)) {
            int v = ConfigData.getIntParm(ConfigData.usStatesLayerVisible, lv);
            return v == 1;
        }
        if (nameStr.contains(ConfigData.chinaProvLayerName)) {
            int v = ConfigData.getIntParm(ConfigData.chinaProvLayerVisible, lv);
            return v == 1;
        }
        return layer.isVisible();
    }
    
    private static ArrayList&lt;FeatureLayer&gt; getLayers(DataStore store) {
        MapData test = new MapData();
        ArrayList&lt;FeatureLayer&gt; layers = new ArrayList&lt;FeatureLayer&gt;();
        try {
            if(store == null || store.getTypeNames() == null) {
                System.err.println("DataStore has not been properly instantiated.");
                return layers;
            }
            for (int i = 0; i &lt; store.getTypeNames().length; i++) {
                String typeName = store.getTypeNames()[i];
                if(typeName != null) {
                    SimpleFeatureSource fs = store.getFeatureSource(typeName);

                    FeatureLayer fl = test.createLayer(fs);
                    layers.add(fl);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return layers;
    }

    public MapController getMapController() {
        return mapPane.getMapLayer();
    }

    public LatLong getSelectedLatLong() {
        return c_selectedLatLong;
    }

    private void setSelectedLatLong(LatLong latlong) {
        setSelectedLatLong (latlong, false);
    }

    private void setSelectedLatLong(LatLong latlong, boolean force) {
        LatLong old;
        if (force) {
            old = null;
        } else {
            old = c_selectedLatLong;
        }
        c_selectedLatLong = latlong;
        firePropertyChange(PROP_SELECTEDLATLONG, old, c_selectedLatLong);
    }

    public void setSelectedLatLongExternal(LatLong latlong) {
        if (latlong != c_selectedLatLong) {
//            LatLong old = c_selectedLatLong;
            c_selectedLatLong = latlong;
            initialLocation = latlong;
            c_controller.setCenter(GISUtil.toCoordinate(c_selectedLatLong));
        }
    }
    
    protected void setLoadingGraphicVisible (boolean enabled) {
        jLabelLoading.setVisible(enabled);
        jProgBarLoading.setVisible(enabled);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // &lt;editor-fold defaultstate="collapsed" desc="Generated Code"&gt;//GEN-BEGIN:initComponents
    private void initComponents() {

        jb_cancel = new javax.swing.JButton();
        jb_reset = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        jb_done = new javax.swing.JButton();
        tf_windowSize = new javax.swing.JFormattedTextField();
        splitPanel = new javax.swing.JSplitPane();
        sidePanel = new javax.swing.JPanel();
        tableScrollPanel = new javax.swing.JScrollPane();
        layerTable = new javax.swing.JTable();
        demoCountryLabel = new javax.swing.JLabel();
        demoStateLabel = new javax.swing.JLabel();
        demoCountyLabel = new javax.swing.JLabel();
        demoCMZLabel = new javax.swing.JLabel();
        demoWingenLabel = new javax.swing.JLabel();
        demoCligenLabel = new javax.swing.JLabel();
        positionCMZ = new javax.swing.JLabel();
        positionCountry = new javax.swing.JLabel();
        positionState = new javax.swing.JLabel();
        positionCounty = new javax.swing.JLabel();
        positionWingen = new javax.swing.JLabel();
        positionCligen = new javax.swing.JLabel();
        demoPositionLabel = new javax.swing.JLabel();
        positionLatLon = new javax.swing.JLabel();
        mainPanel = new javax.swing.JPanel();
        statusBar = new javax.swing.JPanel();
        latLonField = new javax.swing.JFormattedTextField();
        jLabel1 = new javax.swing.JLabel();
        zoomLabel = new javax.swing.JLabel();
        jSzoomBar = new javax.swing.JSlider();
        jProgBarLoading = new javax.swing.JProgressBar();
        jLabelLoading = new javax.swing.JLabel();
        jtfZoomVal = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        mapPane = new usda.weru.gis.gui.MapPane();

        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("usda/weru/gis/gui/Bundle"); // NOI18N
        setTitle(bundle.getString("MapViewer.title")); // NOI18N
        setPreferredSize(new java.awt.Dimension(900, 600));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                formMouseEntered(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addWindowStateListener(new java.awt.event.WindowStateListener() {
            public void windowStateChanged(java.awt.event.WindowEvent evt) {
                formWindowStateChanged(evt);
            }
        });

        jb_cancel.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jb_cancel.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jb_cancel.text")); // NOI18N
        jb_cancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_cancelActionPerformed(evt);
            }
        });

        jb_reset.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jb_reset.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jb_reset.text")); // NOI18N
        jb_reset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_resetActionPerformed(evt);
            }
        });

        jLabel3.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jLabel3.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jLabel3.text")); // NOI18N

        jb_done.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jb_done.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jb_done.text")); // NOI18N
        jb_done.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jb_doneActionPerformed(evt);
            }
        });

        tf_windowSize.setEditable(false);
        tf_windowSize.setFormatterFactory(new LatLonFormatterFactory());
        tf_windowSize.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        tf_windowSize.setText(bundle.getString("MapViewer.tf_windowSize.text")); // NOI18N
        tf_windowSize.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        tf_windowSize.setPreferredSize(new java.awt.Dimension(30, 20));

        splitPanel.setDividerLocation(200);

        tableScrollPanel.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        layerTable.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        layerTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        layerTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_LAST_COLUMN);
        layerTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                layerTableMouseClicked(evt);
            }
        });
        tableScrollPanel.setViewportView(layerTable);

        demoCountryLabel.setFont(demoCountryLabel.getFont().deriveFont(demoCountryLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoCountryLabel.setText(bundle.getString("MapViewer.demoCountryLabel.text")); // NOI18N

        demoStateLabel.setFont(demoStateLabel.getFont().deriveFont(demoStateLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoStateLabel.setText(bundle.getString("MapViewer.demoStateLabel.text")); // NOI18N

        demoCountyLabel.setFont(demoCountyLabel.getFont().deriveFont(demoCountyLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoCountyLabel.setText(bundle.getString("MapViewer.demoCountyLabel.text")); // NOI18N

        demoCMZLabel.setFont(demoCMZLabel.getFont().deriveFont(demoCMZLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoCMZLabel.setText(bundle.getString("MapViewer.demoCMZLabel.text")); // NOI18N

        demoWingenLabel.setFont(demoWingenLabel.getFont().deriveFont(demoWingenLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoWingenLabel.setText(bundle.getString("MapViewer.demoWingenLabel.text")); // NOI18N

        demoCligenLabel.setFont(demoCligenLabel.getFont().deriveFont(demoCligenLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoCligenLabel.setText(bundle.getString("MapViewer.demoCligenLabel.text")); // NOI18N

        positionCMZ.setFont(positionCMZ.getFont().deriveFont(positionCMZ.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionCMZ.setText(bundle.getString("MapViewer.positionCMZ.text")); // NOI18N

        positionCountry.setFont(positionCountry.getFont().deriveFont(positionCountry.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionCountry.setText(bundle.getString("MapViewer.positionCountry.text")); // NOI18N

        positionState.setFont(positionState.getFont().deriveFont(positionState.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionState.setText(bundle.getString("MapViewer.positionState.text")); // NOI18N

        positionCounty.setFont(positionCounty.getFont().deriveFont(positionCounty.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionCounty.setText(bundle.getString("MapViewer.positionCounty.text")); // NOI18N

        positionWingen.setFont(positionWingen.getFont().deriveFont(positionWingen.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionWingen.setText(bundle.getString("MapViewer.positionWingen.text")); // NOI18N

        positionCligen.setFont(positionCligen.getFont().deriveFont(positionCligen.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionCligen.setText(bundle.getString("MapViewer.positionCligen.text")); // NOI18N

        demoPositionLabel.setFont(demoPositionLabel.getFont().deriveFont(demoPositionLabel.getFont().getStyle() | java.awt.Font.BOLD));
        demoPositionLabel.setText(bundle.getString("MapViewer.demoPositionLabel.text")); // NOI18N

        positionLatLon.setFont(positionLatLon.getFont().deriveFont(positionLatLon.getFont().getStyle() &amp; ~java.awt.Font.BOLD));
        positionLatLon.setText(bundle.getString("MapViewer.positionLatLon.text")); // NOI18N

        javax.swing.GroupLayout sidePanelLayout = new javax.swing.GroupLayout(sidePanel);
        sidePanel.setLayout(sidePanelLayout);
        sidePanelLayout.setHorizontalGroup(
            sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sidePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(sidePanelLayout.createSequentialGroup()
                        .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(demoCountryLabel)
                            .addComponent(demoStateLabel)
                            .addComponent(demoCMZLabel)
                            .addComponent(demoCountyLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(positionCounty, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(positionCMZ, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(positionState, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(positionCountry, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(sidePanelLayout.createSequentialGroup()
                        .addComponent(demoPositionLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(positionLatLon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(sidePanelLayout.createSequentialGroup()
                        .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(demoWingenLabel)
                            .addComponent(demoCligenLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(positionCligen, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(positionWingen, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addComponent(tableScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addContainerGap())
        );
        sidePanelLayout.setVerticalGroup(
            sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sidePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoPositionLabel)
                    .addComponent(positionLatLon))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoCountryLabel)
                    .addComponent(positionCountry))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoStateLabel)
                    .addComponent(positionState))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoCountyLabel)
                    .addComponent(positionCounty))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoCMZLabel)
                    .addComponent(positionCMZ))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoWingenLabel)
                    .addComponent(positionWingen))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(sidePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(demoCligenLabel)
                    .addComponent(positionCligen))
                .addGap(18, 18, 18)
                .addComponent(tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)
                .addContainerGap())
        );

        splitPanel.setLeftComponent(sidePanel);

        statusBar.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        statusBar.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        statusBar.setFont(new java.awt.Font("Ubuntu", 0, 10)); // NOI18N

        latLonField.setEditable(false);
        latLonField.setFormatterFactory(new LatLonFormatterFactory());
        latLonField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        latLonField.setText(bundle.getString("MapViewer.latLonField.text")); // NOI18N
        latLonField.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        latLonField.setPreferredSize(new java.awt.Dimension(30, 20));

        jLabel1.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jLabel1.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jLabel1.text")); // NOI18N

        zoomLabel.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        zoomLabel.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.zoomLabel.text")); // NOI18N
        zoomLabel.setName(""); // NOI18N

        jSzoomBar.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        jSzoomBar.setMajorTickSpacing(10);
        jSzoomBar.setMinorTickSpacing(2);
        jSzoomBar.setPaintTicks(true);
        jSzoomBar.setSnapToTicks(true);
        jSzoomBar.setToolTipText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jSzoomBar.toolTipText")); // NOI18N
        jSzoomBar.setValue(0);
        jSzoomBar.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jSzoomBar.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSzoomBarStateChanged(evt);
            }
        });

        jProgBarLoading.setIndeterminate(true);
        jProgBarLoading.setName(""); // NOI18N

        jLabelLoading.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
        jLabelLoading.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jLabelLoading.text")); // NOI18N

        jtfZoomVal.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        jtfZoomVal.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        jtfZoomVal.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jtfZoomVal.text")); // NOI18N
        jtfZoomVal.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseExited(java.awt.event.MouseEvent evt) {
                jtfZoomValMouseExited(evt);
            }
        });
        jtfZoomVal.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jtfZoomValActionPerformed(evt);
            }
        });

        jLabel2.setFont(new java.awt.Font("Dialog", 0, 10)); // NOI18N
        jLabel2.setText(org.openide.util.NbBundle.getMessage(MapViewer.class, "MapViewer.jLabel2.text")); // NOI18N

        javax.swing.GroupLayout statusBarLayout = new javax.swing.GroupLayout(statusBar);
        statusBar.setLayout(statusBarLayout);
        statusBarLayout.setHorizontalGroup(
            statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusBarLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(statusBarLayout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(jtfZoomVal, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(1, 1, 1)
                        .addComponent(jLabel2))
                    .addComponent(zoomLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSzoomBar, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(32, 32, 32)
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(latLonField, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(statusBarLayout.createSequentialGroup()
                        .addComponent(jLabelLoading)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jProgBarLoading, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(161, Short.MAX_VALUE))
        );
        statusBarLayout.setVerticalGroup(
            statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusBarLayout.createSequentialGroup()
                .addGap(3, 3, 3)
                .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSzoomBar, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addGroup(statusBarLayout.createSequentialGroup()
                        .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(latLonField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel1)
                            .addComponent(zoomLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jtfZoomVal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel2))
                            .addComponent(jProgBarLoading, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabelLoading))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );

        mapPane.setBackground(new java.awt.Color(255, 255, 255));
        mapPane.setOpaque(true);

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGap(30, 30, 30)
                        .addComponent(mapPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(statusBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mapPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(statusBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        splitPanel.setRightComponent(mainPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(splitPanel)
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(223, 223, 223)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tf_windowSize, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(54, 54, 54)
                .addComponent(jb_reset)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jb_cancel)
                .addGap(18, 18, 18)
                .addComponent(jb_done)
                .addGap(25, 25, 25))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(splitPanel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jb_done)
                    .addComponent(jb_cancel)
                    .addComponent(jb_reset)
                    .addComponent(tf_windowSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addContainerGap())
        );

        pack();
    }// &lt;/editor-fold&gt;//GEN-END:initComponents

    private void jSzoomBarStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSzoomBarStateChanged
        int newZoomValue;
        newZoomValue = jSzoomBar.getValue();
        c_controller.setZoom(newZoomValue);
        currentZoomLevel = newZoomValue;
        jtfZoomVal.setText(Integer.toString(newZoomValue));
    }//GEN-LAST:event_jSzoomBarStateChanged

    private void layerTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_layerTableMouseClicked

    }//GEN-LAST:event_layerTableMouseClicked

    private void jtfZoomValActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtfZoomValActionPerformed
        String s = jtfZoomVal.getText();
        int newZoom = Integer.decode(s);
        setZoomBarExternal(newZoom);
        
    }//GEN-LAST:event_jtfZoomValActionPerformed

    private void jtfZoomValMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jtfZoomValMouseExited
        String s = jtfZoomVal.getText();
        int newZoom = Integer.decode(s);
        setZoomBarExternal(newZoom);
    }//GEN-LAST:event_jtfZoomValMouseExited

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        Dimension size = getSize();
//        Dimension maxSize = getMaximumSize();
//        int i = 1;
//        boolean change = false;
//        if (size.width &gt; viewerMaxSize.width) {
//            size.width = viewerMaxSize.width;
//            change = true;
//        }
//        if (size.height &gt; viewerMaxSize.height) {
//            size.height = viewerMaxSize.height;
//            change = true;
//        }
//        if (change) {
//            setSize(size);
//            setResizable(false);
//            // resizing re-enabled in mouseReleased event handler
//        }
//        setSize(size);
        showWindowSize(size);
    }//GEN-LAST:event_formComponentResized

    private void formWindowStateChanged(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowStateChanged
//        int i =1;
//        int state = getExtendedState();
//        if (state == MAXIMIZED_BOTH || state == MAXIMIZED_HORIZ || state == MAXIMIZED_VERT) {
//            setExtendedState (NORMAL);
//            setSize(viewerMaxSizeAlmost);
//        }
        int j = 1;
    }//GEN-LAST:event_formWindowStateChanged

    private void jb_resetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_resetActionPerformed
        setSelectedLatLong(initialLocation);
        c_controller.setCenter(GISUtil.toCoordinate(initialLocation));
        firePropertyChange(PROP_RESETLATLONG, null, c_selectedLatLong);
    }//GEN-LAST:event_jb_resetActionPerformed

    private void jb_cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_cancelActionPerformed
        setSelectedLatLong(initialLocation);
        c_controller.setCenter(GISUtil.toCoordinate(initialLocation));
        firePropertyChange(PROP_RESETLATLONG, null, c_selectedLatLong);
        
        setVisible(false);
    }//GEN-LAST:event_jb_cancelActionPerformed

    private void jb_doneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jb_doneActionPerformed
        
        setSelectedLatLong(c_selectedLatLong, true);
        setVisible(false);
    }//GEN-LAST:event_jb_doneActionPerformed

    private void formMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseEntered
//            setResizable(true);
    }//GEN-LAST:event_formMouseEntered

    private void showWindowSize (Dimension size) {
        String s = size.width + " , " + size.height;
        tf_windowSize.setText(s);
    }
    
    
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                
                new MapViewer().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel demoCMZLabel;
    private javax.swing.JLabel demoCligenLabel;
    private javax.swing.JLabel demoCountryLabel;
    private javax.swing.JLabel demoCountyLabel;
    private javax.swing.JLabel demoPositionLabel;
    private javax.swing.JLabel demoStateLabel;
    private javax.swing.JLabel demoWingenLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabelLoading;
    private javax.swing.JProgressBar jProgBarLoading;
    private javax.swing.JSlider jSzoomBar;
    private javax.swing.JButton jb_cancel;
    private javax.swing.JButton jb_done;
    private javax.swing.JButton jb_reset;
    private javax.swing.JTextField jtfZoomVal;
    private javax.swing.JFormattedTextField latLonField;
    private javax.swing.JTable layerTable;
    private javax.swing.JPanel mainPanel;
    private usda.weru.gis.gui.MapPane mapPane;
    private javax.swing.JLabel positionCMZ;
    private javax.swing.JLabel positionCligen;
    private javax.swing.JLabel positionCountry;
    private javax.swing.JLabel positionCounty;
    private javax.swing.JLabel positionLatLon;
    private javax.swing.JLabel positionState;
    private javax.swing.JLabel positionWingen;
    private javax.swing.JPanel sidePanel;
    private javax.swing.JSplitPane splitPanel;
    private javax.swing.JPanel statusBar;
    private javax.swing.JScrollPane tableScrollPanel;
    private javax.swing.JFormattedTextField tf_windowSize;
    private javax.swing.JLabel zoomLabel;
    // End of variables declaration//GEN-END:variables

    private class InternalSelectionHandler extends MouseAdapter {

        private Coordinate translate(MouseEvent e) {
            Coordinate center = c_controller.getCenter();
            double zoom = c_controller.getZoomFactor();
            double cx = e.getX() - (mapPane.getWidth() / 2);
            double cy = e.getY() - (mapPane.getHeight() / 2);
            double dx = cx / zoom;
            double dy = cy / zoom;
            return new Coordinate(center.x + dx, center.y - dy);
            
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e) &amp;&amp; e.getClickCount() == 2) {
                // getClickCount() == 1 was already called, so don't repeat what it did.
//                Coordinate select = translate(e);
//                c_controller.setCenter(select);
//                LatLong latlong = GISUtil.toLatLong(select);
//                setSelectedLatLong(latlong);
                
                setVisible(false);
            } else if (SwingUtilities.isLeftMouseButton(e) &amp;&amp; e.getClickCount() == 1) {
                Coordinate select = translate(e);
                c_controller.setCenter(select);
                LatLong latlong = GISUtil.toLatLong(select);
                setSelectedLatLong(latlong);
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            latLonField.setValue(c_controller.getCenter());
        }
        
        @Override
        public void mouseMoved(MouseEvent e) {
            Coordinate coord = translate(e);
            latLonField.setValue(coord);
        }
    }
    
    ShowPositionDataSwingWorker c_positionData;

    /**
     *
     * @param latlong
     */
    public synchronized void ShowPositionData(LatLong latlong) {
        if (c_positionData != null) {
            c_positionData.cancel(false);
        }

        c_positionData = new ShowPositionDataSwingWorker(latlong);
        c_positionData.execute();

    }
    
    private class InternalZoomAction extends MouseAdapter {
        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
           //change zoomStatus
        }
    }

    private class ShowPositionDataSwingWorker extends SwingWorker&lt;Object, Runnable&gt; {

        private final LatLong c_latlong;

        public ShowPositionDataSwingWorker(LatLong latlong) {
            c_latlong = latlong;
        }

        @Override
        protected Object doInBackground() throws Exception {
            if (isCancelled()) {
                return null;
            }
            publish(positionCountry, "");
            publish(positionState, "");
            publish(positionCounty, "");
            publish(positionCMZ, "");
            //publish(positionSoils, "");
            publish(positionWingen, "");
            publish(positionCligen, "");

            //position
            try {
                NumberFormat format = new DecimalFormat("0.00000");
                publish(positionLatLon, format.format(c_latlong.longitudeValue(USCustomary.DEGREE_ANGLE))
                        + ", " + format.format(c_latlong.latitudeValue(USCustomary.DEGREE_ANGLE)));
                if (isCancelled()) {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (isCancelled()) {
                return null;
            }
            //end position

            //territory
            List&lt;Territory&gt; territories = lookupValues(Territory.class);
            for (Territory territory : territories) {
                switch (territory.getType()) {
                    case Country:
                        publish(positionCountry, territory.getDisplayName());
                        break;
                    case State:
                        publish(positionState, territory.getDisplayName());
                        break;
                    case County:
                        publish(positionCounty, territory.getDisplayName());
                        publish(demoCountyLabel, territory.getTypeDescription() + ":");
                        break;
                }
            }
            if (isCancelled()) {
                return null;
            }
            //end territory

            //CMZ
            CropManagementZone cmz = lookupValue(CropManagementZone.class);
            if (cmz != null) {
                float cmzNum = cmz.getId();
                if (cmzNum - Math.floor(cmzNum) &lt; .08) {
                    publish(positionCMZ, Integer.toString((int)cmzNum));
                } else {
                    publish(positionCMZ, Float.toString(cmzNum));
                }
            } else {
                publish(positionCMZ, "");
            }
            if (isCancelled()) {
                return null;
            }
            //end cmz

            return null;
        }

        private &lt;T&gt; T lookupValue(Class&lt;T&gt; type) {
            GISData data = GISData.getInstance();
            GISLookup&lt;T&gt; lookup = data.getLookup(type);
            List&lt;T&gt; results = null;
            if (lookup != null) {
                results = lookup.lookup(c_latlong);
            }

            if (results != null &amp;&amp; !results.isEmpty()) {
                return results.get(0);
            } else {
                return null;
            }

        }

        private &lt;T&gt; List&lt;T&gt; lookupValues(Class&lt;T&gt; type) {
            GISData data = GISData.getInstance();
            GISLookup&lt;T&gt; lookup = data.getLookup(type);
            List&lt;T&gt; results = null;
            if (lookup != null) {
                results = lookup.lookup(c_latlong);
            }
            if (results != null) {
                return results;
            } else {
                return Collections.emptyList();
            }
        }

        private void publish(final JLabel label, final String text) {
            Runnable runnable = new Runnable() {

                @Override
                public void run() {
                    label.setText(text);
                }
            };
            publish(runnable);
        }

        @Override
        protected void process(List&lt;Runnable&gt; chunks) {
            
            for (Runnable runnable : chunks) {
                if (ShowPositionDataSwingWorker.this.isCancelled()) {
                    return;
                }
                runnable.run();
            }
        }
    }
}
</pre></body></html>