diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58b34bd9d0a9a19288262c15eea8ee491ebe27ea..ab23f36f0fd60aa7f94bc0511818a1f3a90414fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,9 @@ release.
 ## [Unreleased]
 
 ### Fixed
+- Tests for gdal > 3 and pvl > 1.0. This includes fixing the `k` value on the MOLA polar stereographic test data and updating the proj string for GDAL > 3 (new fields are included).
+- Conditional GDAL import to support gdal > 3.0
+- `generate_isis_serial` to work on cubes that have been run through `jigsaw` by removing the custom `SerialNumberDecoder`. Fixes [#194](https://github.com/DOI-USGS/plio/issues/194)
 - Updated `create_pvl_header()` to add a newline (`\n`) character to the end of the pvl string. This ensures that the control networks can be written, then read back in using pvl 1.3.0 [#193](https://github.com/USGS-Astrogeology/plio/pull/193)
 
 ## [1.5.3]()
diff --git a/environment.yml b/environment.yml
index 37ea027dbec1bc9c58c16bdee3854cfb6a0c4b49..233b9ccab294e21cdb5acfbfb05c83e43aa36581 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,10 +1,8 @@
 name: plio
 channels:
   - conda-forge
-  - usgs-astrogeology
 dependencies:
-  - libgdal < 3 
-  - gdal < 3 
+  - gdal 
   - numpy 
   - pyproj 
   - h5py 
diff --git a/plio/examples/CTX/ctx.pvl b/plio/examples/CTX/ctx.pvl
index b062798ad7043009e8c98e607ea39122b6b80c18..a44e44c7fe911faead77e4570cb190b9c7d8d4d3 100644
--- a/plio/examples/CTX/ctx.pvl
+++ b/plio/examples/CTX/ctx.pvl
@@ -67,6 +67,8 @@ Object = IsisCube
   End_Group
 End_Object
 
+# Jigged
+
 Object = Label
   Bytes = 65536
 End_Object
diff --git a/plio/examples/Projections/Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif b/plio/examples/Projections/Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif
index e47b318148f7c268ebf1aa4e20ee7051695bf24c..eed8e641775cca2fcef4ab8dba81782982a2d73c 100644
Binary files a/plio/examples/Projections/Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif and b/plio/examples/Projections/Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif differ
diff --git a/plio/io/__init__.py b/plio/io/__init__.py
index 7c0f093a632bf35ac26b4a177185132733ec5727..b67fa436d6680e82b006dbb2b58874de3be9cbcf 100644
--- a/plio/io/__init__.py
+++ b/plio/io/__init__.py
@@ -1,25 +1,13 @@
 # Conditional imports for GDAL
 import importlib
 import warnings
-import sys
 
 try:
-    gdal = importlib.util.find_spec('gdal')
-    ogr = importlib.util.find_spec('osgeo.ogr')
-    osr = importlib.util.find_spec('osr')
-
-    gdal = gdal.loader.load_module()
-    ogr = ogr.loader.load_module()
-    osr = osr.loader.load_module()
-    gdal.UseExceptions() 
+    gdal = importlib.import_module('osgeo.gdal')
+    osr = importlib.import_module('osgeo.osr')
+    ogr = importlib.import_module('osgeo.ogr')
 except:
-    try:
-        gdal = importlib.util.find_spec('osgeo.gdal')
-        gdal = gdal.loader.load_module()
-    except:
-        gdal = None
-    ogr = None
-    osr = None
+    gdal = osr = ogr = None
 
 def conditional_gdal(func):
     def has_gdal(*args, **kwargs):
diff --git a/plio/io/extract_metadata.py b/plio/io/extract_metadata.py
index 6d94c2a4b2744c0dffacd7dfc6c484959a90877c..ea1e3706e385149828af42bc90a6363931909f08 100644
--- a/plio/io/extract_metadata.py
+++ b/plio/io/extract_metadata.py
@@ -1,5 +1,6 @@
-from plio.io import osr, conditional_gdal
-    
+
+from plio.io import conditional_gdal, osr
+
 import_options = ['ImportFromWkt', 'ImportFromProj4',
                   'ImportFromEPSG', 'ImportFromUSGS',
                   'ImportFromXML']
diff --git a/plio/io/io_db.py b/plio/io/io_db.py
index 988ec589fed803328d139a578fff260b7fc972d1..5903484017356fa4127e75c9911779b44ad1cb91 100644
--- a/plio/io/io_db.py
+++ b/plio/io/io_db.py
@@ -1,9 +1,10 @@
 from sqlalchemy import Column, Integer, String, create_engine, orm
-from sqlalchemy.ext import declarative
+from sqlalchemy.orm import declarative_base
+from sqlalchemy import MetaData
 
 from plio.sqlalchemy_json.alchemy import NestedJsonObject
 
-Base = declarative.declarative_base()
+Base = declarative_base()
 
 
 def setup_db_session(db):
@@ -21,8 +22,8 @@ def setup_db_session(db):
        A SQLAlchemy session object
     """
     engine = create_engine('sqlite:///{}'.format(db))
-    Base.metadata.bind = engine
-    Base.metadata.create_all()
+    meta = MetaData()
+    meta.create_all(engine)
     return orm.sessionmaker(bind=engine)()
 
 
diff --git a/plio/io/io_gdal.py b/plio/io/io_gdal.py
index fc4222a7c52f8821c66db9d8b68e034653c19fb0..749fa405ad5f2d7d7d2f4286053cc7ee61046d0e 100644
--- a/plio/io/io_gdal.py
+++ b/plio/io/io_gdal.py
@@ -7,11 +7,9 @@ import affine
 import numpy as np
 import pvl
 
-
-from plio.io import extract_metadata, conditional_gdal
 from plio.geofuncs import geofuncs
 from plio.utils.utils import find_in_dict
-from plio.io import gdal, ogr, osr
+from plio.io import gdal, ogr, osr, extract_metadata, conditional_gdal
 
 NP2GDAL_CONVERSION = {
   "byte": 1,
diff --git a/plio/io/isis_serial_number.py b/plio/io/isis_serial_number.py
index faba3bf52d9cd7b4b7e6293969f2199e61bb933e..725e9a184ce3f31f5eafcd87e77a9c4e136ff56e 100644
--- a/plio/io/isis_serial_number.py
+++ b/plio/io/isis_serial_number.py
@@ -1,3 +1,4 @@
+import datetime
 import warnings
 
 import pvl
@@ -71,7 +72,7 @@ def generate_serial_number(label):
        The ISIS compatible serial number
     """
     if not isinstance(label, PVLModule):
-        label = pvl.load(label, decoder=SerialNumberDecoder())
+        label = pvl.load(label)
     # Get the translation information
     translation = get_isis_translation(label)
 
@@ -97,82 +98,11 @@ def generate_serial_number(label):
                 serial_entry = search_translation[serial_entry]
             elif '*' in search_translation.keys() and search_translation['*'] != '*':
                 serial_entry = search_translation['*']
+            if isinstance(serial_entry, datetime.datetime):
+                # PVL returns datetime objects now. Convert these to string and strip trailing zeros on microseconds.
+                serial_entry = serial_entry.strftime('%Y-%m-%dT%H:%M:%S.%f').rstrip('0')                
             serial_number.append(serial_entry)
         except:
             pass
-
+    
     return '/'.join(serial_number)
-
-
-class SerialNumberDecoder(pvl.decoder.PVLDecoder):
-    """
-    A PVL Decoder class to handle cube label parsing for the purpose of creating a valid ISIS
-    serial number. Inherits from the PVLDecoder in planetarypy's pvl module.
-    """
-
-    def decode_simple_value(self, value: str):
-        """Returns a Python object based on *value*, assuming
-        that *value* can be decoded as a PVL Simple Value::
-
-         <Simple-Value> ::= (<Numeric> | <String>)
-
-         Modified from https://pvl.readthedocs.io/en/stable/_modules/pvl/decoder.html#PVLDecoder.decode_simple_value
-         Modification entails stripping datetime from list of functions.
-        """
-        for d in (
-            self.decode_quoted_string,
-            self.decode_non_decimal,
-            self.decode_decimal,
-        ):
-            try:
-                return d(value)
-            except ValueError:
-                pass
-
-        if value.casefold() == self.grammar.none_keyword.casefold():
-            return None
-
-        if value.casefold() == self.grammar.true_keyword.casefold():
-            return True
-
-        if value.casefold() == self.grammar.false_keyword.casefold():
-            return False
-
-        return self.decode_unquoted_string(value)
-
-    def decode_unquoted_string(self, value: str) -> str:
-        """Returns a Python ``str`` if *value* can be decoded
-        as an unquoted string, based on this decoder's grammar.
-        Raises a ValueError otherwise.
-
-        Modified from: https://pvl.readthedocs.io/en/stable/_modules/pvl/decoder.html#PVLDecoder.decode_unquoted_string
-        Modification entails removal of decode_datetime call
-        """
-        for coll in (
-            ("a comment", chain.from_iterable(self.grammar.comments)),
-            ("some whitespace", self.grammar.whitespace),
-            ("a special character", self.grammar.reserved_characters),
-        ):
-            for item in coll[1]:
-                if item in value:
-                    raise ValueError(
-                        "Expected a Simple Value, but encountered "
-                        f'{coll[0]} in "{self}": "{item}".'
-                    )
-
-        agg_keywords = self.grammar.aggregation_keywords.items()
-        for kw in chain.from_iterable(agg_keywords):
-            if kw.casefold() == value.casefold():
-                raise ValueError(
-                    "Expected a Simple Value, but encountered "
-                    f'an aggregation keyword: "{value}".'
-                )
-
-        for es in self.grammar.end_statements:
-            if es.casefold() == value.casefold():
-                raise ValueError(
-                    "Expected a Simple Value, but encountered "
-                    f'an End-Statement: "{value}".'
-                )
-
-        return str(value)
diff --git a/plio/io/tests/test_io_bae.py b/plio/io/tests/test_io_bae.py
index 4031703f49552e2799db35ed82fbad5bb0b9a9a6..11bffd98e5516ded0683824abb5879fedddb49d7 100644
--- a/plio/io/tests/test_io_bae.py
+++ b/plio/io/tests/test_io_bae.py
@@ -3,7 +3,7 @@ import os
 
 import numpy as np
 import pandas as pd
-from pandas.util.testing import assert_frame_equal
+from pandas.testing import assert_frame_equal
 
 from plio.io.io_bae import socetset_keywords_to_dict, read_gpf, save_gpf, read_ipf, save_ipf
 from plio.examples import get_path
diff --git a/plio/io/tests/test_io_gdal.py b/plio/io/tests/test_io_gdal.py
index 0423ca3f74d26d502c12162755f521eef5496200..a8bc23d04ad5934effd1c934ada79163e7b4e26a 100644
--- a/plio/io/tests/test_io_gdal.py
+++ b/plio/io/tests/test_io_gdal.py
@@ -39,7 +39,7 @@ class TestMercator(unittest.TestCase):
     """
 
     def test_scale(self):
-        self.assertEqual(self.dataset.scale, ('Meter', 1.0))
+        self.assertEqual(self.dataset.scale, ('metre', 1.0))
 
     def test_xy_extent(self):
         xy_extent = self.dataset.xy_extent
@@ -231,13 +231,17 @@ class TestWriter(unittest.TestCase):
         DATUM["Moon_2000",
             SPHEROID["Moon_2000_IAU_IAG",1737400,0]],
         PRIMEM["Reference_Meridian",0],
-        UNIT["Degree",0.017453292519943295]],
-    PROJECTION["Mercator_2SP"],
+        UNIT["degree",0.0174532925199433,
+            AUTHORITY["EPSG","9122"]]],
+    PROJECTION["Mercator_1SP"],
     PARAMETER["central_meridian",180],
+    PARAMETER["scale_factor",1],
     PARAMETER["false_easting",0],
     PARAMETER["false_northing",0],
-    PARAMETER["standard_parallel_1",0],
-    UNIT["Meter",1]]"""
+    UNIT["metre",1,
+        AUTHORITY["EPSG","9001"]],
+    AXIS["Easting",EAST],
+    AXIS["Northing",NORTH]]"""
         dataset = io_gdal.GeoDataset('test.tif')
         test_srs = dataset.spatial_reference.__str__()
         self.assertEqual(test_srs.split(), expected_srs.split())
diff --git a/plio/io/tests/test_metadata.py b/plio/io/tests/test_metadata.py
index 6eef483cd94b475aeb771033fd3c316731b4aa67..08d41a650dab7e8f9290d9752630a17372fb8f2e 100644
--- a/plio/io/tests/test_metadata.py
+++ b/plio/io/tests/test_metadata.py
@@ -1,7 +1,7 @@
 import pytest
 
 from plio.io import extract_metadata as em
-from plio.io import gdal
+from plio.io import gdal 
 
 @pytest.fixture
 def wkt_moon():
@@ -52,7 +52,7 @@ def test_export_to_proj4(srs_mars):
     Check that proj4 is not supporting Moon2000_Mercator
     """
     proj4 = srs_mars.ExportToProj4()
-    for element in '+proj=merc +lon_0=180 +lat_ts=0 +x_0=0 +y_0=0 +a=1737400 +b=1737400 +units=m +no_defs'.split():
+    for element in '+proj=merc +lon_0=180 +lat_ts=0 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs'.split():
         assert element in proj4
 
 @pytest.mark.skipif(gdal is None, reason="GDAL not installed")