From 2da5d31f455f34e01bf2f557c7d5b6415318d091 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Tue, 29 Oct 2019 22:22:59 +1300 Subject: [PATCH] fix(EpsgReference): complete methods for expected operation * This is now similar to the deprecated utils.reference.epsgRef class, removing '_remove_pyc' and 'make' methods, adding 'to_dict', 'get' and '_write' methods, and updating others to work as expected. * Change t032_test.py to replace epsgRef with EpsgReference, and ensure that all methods are tested. --- autotest/t032_test.py | 24 ++++++--- flopy/export/shapefile_utils.py | 96 ++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 50 deletions(-) diff --git a/autotest/t032_test.py b/autotest/t032_test.py index 3f4c5fe73f..0b30b24f1b 100644 --- a/autotest/t032_test.py +++ b/autotest/t032_test.py @@ -4,11 +4,12 @@ import os import shutil import numpy as np +import sys import flopy from flopy.utils.geometry import Polygon -from flopy.export.shapefile_utils import recarray2shp, shp2recarray +from flopy.export.shapefile_utils import recarray2shp, shp2recarray, \ + EpsgReference, CRS from flopy.export.netcdf import NetCdf -from flopy.utils.reference import getprj, epsgRef mpth = os.path.join('temp', 't032') # make the directory if it does not exist @@ -57,7 +58,7 @@ def test_polygon_from_ij(): assert np.abs(geoms[0].bounds[-1] - 5169292.893203464) < 1e-4 fpth = os.path.join(mpth, 'test.shp') recarray2shp(recarray, geoms, fpth, epsg=26715) - ep = epsgRef() + ep = EpsgReference() prj = ep.to_dict() assert 26715 in prj fpth = os.path.join(mpth, 'test.prj') @@ -76,25 +77,36 @@ def test_polygon_from_ij(): assert True -def test_epsgref(): - ep = epsgRef() +def test_epsgreference(): + ep = EpsgReference() ep.reset() + ep.show() - getprj(32614) # WGS 84 / UTM zone 14N + prjtxt = CRS.getprj(32614) # WGS 84 / UTM zone 14N + if sys.version_info[0] == 2: + prjtxt = prjtxt.encode('ascii') + assert isinstance(prjtxt, str) prj = ep.to_dict() assert 32614 in prj + ep.show() ep.add(9999, 'junk') prj = ep.to_dict() assert 9999 in prj + assert ep.get(9999) == 'junk' + ep.show() ep.remove(9999) prj = ep.to_dict() assert 9999 not in prj + ep.show() + + assert ep.get(9999) is None ep.reset() prj = ep.to_dict() assert len(prj) == 0 + ep.show() if __name__ == '__main__': diff --git a/flopy/export/shapefile_utils.py b/flopy/export/shapefile_utils.py index e8ee182aa9..9decf5a6b3 100755 --- a/flopy/export/shapefile_utils.py +++ b/flopy/export/shapefile_utils.py @@ -7,6 +7,8 @@ import numpy as np import os import warnings +from collections import OrderedDict + from ..datbase import DataType, DataInterface from ..utils import Util3d, SpatialReference @@ -872,7 +874,7 @@ def getprj(epsg, addlocalreference=True, text='esriwkt'): epsg code for coordinate system addlocalreference : boolean adds the projection file text associated with epsg to a local - database, epsgref.py, located in site-packages. + database, epsgref.json, located in the user's data directory. Returns ------- prj : str @@ -880,12 +882,7 @@ def getprj(epsg, addlocalreference=True, text='esriwkt'): """ epsgfile = EpsgReference() - wktstr = None - try: - from epsgref import prj - wktstr = prj.get(epsg) - except: - epsgfile.make() + wktstr = epsgfile.get(epsg) if wktstr is None: wktstr = CRS.get_spatialreference(epsg, text=text) if addlocalreference and wktstr is not None: @@ -954,9 +951,12 @@ def getproj4(epsg): class EpsgReference: """ - Sets up a local database of projection file text referenced by epsg code. - The database is located in the site packages folder in epsgref.py, which - contains a dictionary, prj, of projection file text keyed by epsg value. + Sets up a local database of text representations of coordinate reference + systems, keyed by EPSG code. + + The database is epsgref.json, located in the user's data directory. If + optional 'appdirs' package is available, this is in the platform-dependent + user directory, otherwise in the user's 'HOME/.flopy' directory. """ def __init__(self): @@ -974,54 +974,62 @@ def __init__(self): dbname = 'epsgref.json' self.location = os.path.join(datadir, dbname) - def _remove_pyc(self): - try: # get rid of pyc file - os.remove(self.location + 'c') - except: - msg = 'could not remove {}'.format(self.location + 'c') - print(msg) + def to_dict(self): + """ + returns dict with EPSG code integer key, and WKT CRS text + """ + data = OrderedDict() + if os.path.exists(self.location): + with open(self.location, 'r') as f: + loaded_data = json.load(f, object_pairs_hook=OrderedDict) + # convert JSON key from str to EPSG integer + for key, value in loaded_data.items(): + try: + data[int(key)] = value + except ValueError: + data[key] = value + return data - def make(self): - if not os.path.exists(self.location): - newfile = open(self.location, 'w') - newfile.write('prj = {}\n') - newfile.close() + def _write(self, data): + with open(self.location, 'w') as f: + json.dump(data, f, indent=0) + f.write('\n') def reset(self, verbose=True): if os.path.exists(self.location): + if verbose: + print('Resetting {}'.format(self.location)) os.remove(self.location) - self._remove_pyc() - self.make() - if verbose: - print('Resetting {}'.format(self.location)) + elif verbose: + print('{} does not exist, no reset required'.format(self.location)) def add(self, epsg, prj): - """add an epsg code to epsgref.py""" - data = {} + """ + add an epsg code to epsgref.json + """ + data = self.to_dict() data[epsg] = prj - with open(self.location, 'w') as epsgfile: - json.dump(data, epsgfile, indent=0) - epsgfile.write('\n') + self._write(data) + + def get(self, epsg): + """ + returns prj from a epsg code, otherwise None if not found + """ + data = self.to_dict() + return data.get(epsg) def remove(self, epsg): """ - removes an epsg entry from epsgref.py + removes an epsg entry from epsgref.json """ - from epsgref import prj - self.reset(verbose=False) - if epsg in prj.keys(): - del prj[epsg] - for epsg, prj in prj.items(): - self.add(epsg, prj) + data = self.to_dict() + if epsg in data: + del data[epsg] + self._write(data) @staticmethod def show(): - try: - from importlib import reload - except ImportError: - from imp import reload - import epsgref - from epsgref import prj - reload(epsgref) + ep = EpsgReference() + prj = ep.to_dict() for k, v in prj.items(): print('{}:\n{}\n'.format(k, v))