diff --git a/pycrs/elements/containers.py b/pycrs/elements/containers.py new file mode 100644 index 0000000..02cd48a --- /dev/null +++ b/pycrs/elements/containers.py @@ -0,0 +1,189 @@ + +from . import directions +from . import datums + +# the final CRS object which is instantiated with all of the below and parameters +# remember to use +no_defs when outputting to proj4 +# ... +class CRS: + def __init__(self, toplevel): + self.toplevel = toplevel + + def to_proj4(self): + if isinstance(self.toplevel, ProjCS): + return "%s +no_defs" % self.toplevel.to_proj4() + elif isinstance(self.toplevel, GeogCS): + return "+proj=longlat %s +no_defs" % self.toplevel.to_proj4() + + def to_ogc_wkt(self): + return "%s" % self.toplevel.to_ogc_wkt() + + def to_esri_wkt(self): + return "%s" % self.toplevel.to_esri_wkt() + +##+proj Projection name (see `proj -l`) +class Projection: + proj4 = "+proj" + ogc_wkt = "PROJECTION" + esri_wkt = "PROJECTION" + + def __init__(self, value): + self.value = value + + def to_proj4(self): + return "+proj=%s" %self.value.proj4 + + def to_ogc_wkt(self): + return 'PROJECTION["%s"]' %self.value.ogc_wkt + + def to_esri_wkt(self): + return 'PROJECTION["%s"]' %self.value.esri_wkt + +##+datum Datum name (see `proj -ld`) +class Datum: + proj4 = "+datum" + ogc_wkt = "DATUM" + esri_wkt = "DATUM" + + def __init__(self, name, ellipsoid, datumshift=None): + """ + Arguments: + + - **name**: Specific datum name instance. + - **ellipsoid**: Ellipsoid parameter instance. + """ + self.name = name + self.ellips = ellipsoid + self.datumshift = datumshift + + def to_proj4(self): + if self.datumshift: + return "%s %s" % (self.ellips.to_proj4(), self.datumshift.to_proj4()) + elif isinstance(self.name, datums.Unknown): + return "%s" % self.ellips.to_proj4() + else: + return "+datum=%s %s" % (self.name.proj4, self.ellips.to_proj4()) + + def to_ogc_wkt(self): + if self.datumshift: + return 'DATUM["%s", %s, %s]' % (self.name.ogc_wkt, self.ellips.to_ogc_wkt(), self.datumshift.to_ogc_wkt()) + else: + return 'DATUM["%s", %s]' % (self.name.ogc_wkt, self.ellips.to_ogc_wkt()) + + def to_esri_wkt(self): + if self.datumshift: + return 'DATUM["%s", %s, %s]' % (self.name.esri_wkt, self.ellips.to_esri_wkt(), self.datumshift.to_esri_wkt()) + else: + return 'DATUM["%s", %s]' % (self.name.esri_wkt, self.ellips.to_esri_wkt()) + + def to_geotiff(self): + pass + #return "GeogGeodeticDatum" + +##+ellps Ellipsoid name (see `proj -le`) +class Ellipsoid: + proj4 = "+ellps" + ogc_wkt = "SPHEROID" + esri_wkt = "SPHEROID" + + def __init__(self, name, semimaj_ax=None, inv_flat=None): + """ + Arguments: + + - **name**: Specific ellipsoid name instance. + """ + self.name = name + + # get default values if not specified + if semimaj_ax == None: + semimaj_ax = self.name.semimaj_ax + if inv_flat == None: + inv_flat = self.name.inv_flat + + self.semimaj_ax = semimaj_ax + self.inv_flat = inv_flat + + def to_proj4(self): + return "+ellps=%s +a=%s +f=%s" % (self.name.proj4, self.semimaj_ax, self.inv_flat) + + def to_ogc_wkt(self): + return 'SPHEROID["%s", %s, %s]' % (self.name.ogc_wkt, self.semimaj_ax, self.inv_flat) + + def to_esri_wkt(self): + return 'SPHEROID["%s", %s, %s]' % (self.name.esri_wkt, self.semimaj_ax, self.inv_flat) + + def to_geotiff(self): + pass + #return "GeogEllipsoid" + +#GEOGCS +class GeogCS: + ogc_wkt = "GEOGCS" + esri_wkt = "GEOGCS" + + def __init__(self, name, datum, prime_mer, angunit, twin_ax=None): + """ + Arguments: + + - **name**: Arbitrary name. + """ + self.name = name + self.datum = datum + self.prime_mer = prime_mer + self.angunit = angunit + if twin_ax == None: + # default axes + twin_ax = directions.East(), directions.North() + self.twin_ax = twin_ax + + def to_proj4(self): + # dont parse axis to proj4, because in proj4, axis only applies to the cs, ie the projcs (not the geogcs, where wkt can specify with axis) + return "%s %s %s" % (self.datum.to_proj4(), self.prime_mer.to_proj4(), self.angunit.to_proj4() ) + + def to_ogc_wkt(self): + return 'GEOGCS["%s", %s, %s, %s, AXIS["Lon", %s], AXIS["Lat", %s]]' % (self.name, self.datum.to_ogc_wkt(), self.prime_mer.to_ogc_wkt(), self.angunit.to_ogc_wkt(), self.twin_ax[0].ogc_wkt, self.twin_ax[1].ogc_wkt ) + + def to_esri_wkt(self): + return 'GEOGCS["%s", %s, %s, %s, AXIS["Lon", %s], AXIS["Lat", %s]]' % (self.name, self.datum.to_esri_wkt(), self.prime_mer.to_esri_wkt(), self.angunit.to_esri_wkt(), self.twin_ax[0].esri_wkt, self.twin_ax[1].esri_wkt ) + +#PROJCS +class ProjCS: + ogc_wkt = "PROJCS" + esri_wkt = "PROJCS" + + def __init__(self, name, geogcs, proj, params, unit, twin_ax=None): + """ + Arguments: + + - **name**: Arbitrary name. + """ + self.name = name + self.geogcs = geogcs + self.proj = proj + self.params = params + self.unit = unit + if twin_ax == None: + # default axes + twin_ax = directions.East(), directions.North() + self.twin_ax = twin_ax + + def to_proj4(self): + string = "%s %s " % (self.proj.to_proj4(), self.geogcs.to_proj4()) + string += " ".join(param.to_proj4() for param in self.params) + string += " %s" % self.unit.to_proj4() + string += " +axis=" + self.twin_ax[0].proj4 + self.twin_ax[1].proj4 + "u" # up set as default because only proj4 can set it I think... + return string + + def to_ogc_wkt(self): + string = 'PROJCS["%s", %s, %s, ' % (self.name, self.geogcs.to_ogc_wkt(), self.proj.to_ogc_wkt() ) + string += ", ".join(param.to_ogc_wkt() for param in self.params) + string += ', %s' % self.unit.to_ogc_wkt() + string += ', AXIS["X", %s], AXIS["Y", %s]]' % (self.twin_ax[0].ogc_wkt, self.twin_ax[1].ogc_wkt ) + return string + + def to_esri_wkt(self): + string = 'PROJCS["%s", %s, %s, ' % (self.name, self.geogcs.to_esri_wkt(), self.proj.to_esri_wkt() ) + string += ", ".join(param.to_esri_wkt() for param in self.params) + string += ', %s' % self.unit.to_esri_wkt() + string += ', AXIS["X", %s], AXIS["Y", %s]]' % (self.twin_ax[0].esri_wkt, self.twin_ax[1].esri_wkt ) + return string diff --git a/pycrs/elements/containers.pyc b/pycrs/elements/containers.pyc new file mode 100644 index 0000000..0d78aae Binary files /dev/null and b/pycrs/elements/containers.pyc differ diff --git a/pycrs/elements/parameters.py b/pycrs/elements/parameters.py index 11f98bc..15dfccd 100644 --- a/pycrs/elements/parameters.py +++ b/pycrs/elements/parameters.py @@ -83,155 +83,6 @@ class Azimuth: def to_esri_wkt(self): return 'PARAMETER["Azimuth",%s]' % self.value - -##+datum Datum name (see `proj -ld`) -class Datum: - proj4 = "+datum" - ogc_wkt = "DATUM" - esri_wkt = "DATUM" - - def __init__(self, name, ellipsoid, datumshift=None): - """ - Arguments: - - - **name**: Specific datum name instance. - - **ellipsoid**: Ellipsoid parameter instance. - """ - self.name = name - self.ellips = ellipsoid - self.datumshift = datumshift - - def to_proj4(self): - if self.datumshift: - return "%s %s" % (self.ellips.to_proj4(), self.datumshift.to_proj4()) - elif isinstance(self.name, datums.Unknown): - return "%s" % self.ellips.to_proj4() - else: - return "+datum=%s %s" % (self.name.proj4, self.ellips.to_proj4()) - - def to_ogc_wkt(self): - if self.datumshift: - return 'DATUM["%s", %s, %s]' % (self.name.ogc_wkt, self.ellips.to_ogc_wkt(), self.datumshift.to_ogc_wkt()) - else: - return 'DATUM["%s", %s]' % (self.name.ogc_wkt, self.ellips.to_ogc_wkt()) - - def to_esri_wkt(self): - if self.datumshift: - return 'DATUM["%s", %s, %s]' % (self.name.esri_wkt, self.ellips.to_esri_wkt(), self.datumshift.to_esri_wkt()) - else: - return 'DATUM["%s", %s]' % (self.name.esri_wkt, self.ellips.to_esri_wkt()) - - def to_geotiff(self): - pass - #return "GeogGeodeticDatum" - -##+ellps Ellipsoid name (see `proj -le`) -class Ellipsoid: - proj4 = "+ellps" - ogc_wkt = "SPHEROID" - esri_wkt = "SPHEROID" - - def __init__(self, name, semimaj_ax=None, inv_flat=None): - """ - Arguments: - - - **name**: Specific ellipsoid name instance. - """ - self.name = name - - # get default values if not specified - if semimaj_ax == None: - semimaj_ax = self.name.semimaj_ax - if inv_flat == None: - inv_flat = self.name.inv_flat - - self.semimaj_ax = semimaj_ax - self.inv_flat = inv_flat - - def to_proj4(self): - return "+ellps=%s +a=%s +f=%s" % (self.name.proj4, self.semimaj_ax, self.inv_flat) - - def to_ogc_wkt(self): - return 'SPHEROID["%s", %s, %s]' % (self.name.ogc_wkt, self.semimaj_ax, self.inv_flat) - - def to_esri_wkt(self): - return 'SPHEROID["%s", %s, %s]' % (self.name.esri_wkt, self.semimaj_ax, self.inv_flat) - - def to_geotiff(self): - pass - #return "GeogEllipsoid" - -#GEOGCS -class GeogCS: - ogc_wkt = "GEOGCS" - esri_wkt = "GEOGCS" - - def __init__(self, name, datum, prime_mer, angunit, twin_ax=None): - """ - Arguments: - - - **name**: Arbitrary name. - """ - self.name = name - self.datum = datum - self.prime_mer = prime_mer - self.angunit = angunit - if twin_ax == None: - # default axes - twin_ax = directions.East(), directions.North() - self.twin_ax = twin_ax - - def to_proj4(self): - # dont parse axis to proj4, because in proj4, axis only applies to the cs, ie the projcs (not the geogcs, where wkt can specify with axis) - return "%s %s %s" % (self.datum.to_proj4(), self.prime_mer.to_proj4(), self.angunit.to_proj4() ) - - def to_ogc_wkt(self): - return 'GEOGCS["%s", %s, %s, %s, AXIS["Lon", %s], AXIS["Lat", %s]]' % (self.name, self.datum.to_ogc_wkt(), self.prime_mer.to_ogc_wkt(), self.angunit.to_ogc_wkt(), self.twin_ax[0].ogc_wkt, self.twin_ax[1].ogc_wkt ) - - def to_esri_wkt(self): - return 'GEOGCS["%s", %s, %s, %s, AXIS["Lon", %s], AXIS["Lat", %s]]' % (self.name, self.datum.to_esri_wkt(), self.prime_mer.to_esri_wkt(), self.angunit.to_esri_wkt(), self.twin_ax[0].esri_wkt, self.twin_ax[1].esri_wkt ) - -#PROJCS -class ProjCS: - ogc_wkt = "PROJCS" - esri_wkt = "PROJCS" - - def __init__(self, name, geogcs, proj, params, unit, twin_ax=None): - """ - Arguments: - - - **name**: Arbitrary name. - """ - self.name = name - self.geogcs = geogcs - self.proj = proj - self.params = params - self.unit = unit - if twin_ax == None: - # default axes - twin_ax = directions.East(), directions.North() - self.twin_ax = twin_ax - - def to_proj4(self): - string = "%s %s " % (self.proj.to_proj4(), self.geogcs.to_proj4()) - string += " ".join(param.to_proj4() for param in self.params) - string += " %s" % self.unit.to_proj4() - string += " +axis=" + self.twin_ax[0].proj4 + self.twin_ax[1].proj4 + "u" # up set as default because only proj4 can set it I think... - return string - - def to_ogc_wkt(self): - string = 'PROJCS["%s", %s, %s, ' % (self.name, self.geogcs.to_ogc_wkt(), self.proj.to_ogc_wkt() ) - string += ", ".join(param.to_ogc_wkt() for param in self.params) - string += ', %s' % self.unit.to_ogc_wkt() - string += ', AXIS["X", %s], AXIS["Y", %s]]' % (self.twin_ax[0].ogc_wkt, self.twin_ax[1].ogc_wkt ) - return string - - def to_esri_wkt(self): - string = 'PROJCS["%s", %s, %s, ' % (self.name, self.geogcs.to_esri_wkt(), self.proj.to_esri_wkt() ) - string += ", ".join(param.to_esri_wkt() for param in self.params) - string += ', %s' % self.unit.to_esri_wkt() - string += ', AXIS["X", %s], AXIS["Y", %s]]' % (self.twin_ax[0].esri_wkt, self.twin_ax[1].esri_wkt ) - return string ##+k Scaling factor (old name) ##+k_0 Scaling factor (new name) @@ -412,24 +263,6 @@ class PrimeMeridian: def to_esri_wkt(self): return 'PRIMEM["Greenwich", %s]' %self.value -##+proj Projection name (see `proj -l`) -class Projection: - proj4 = "+proj" - ogc_wkt = "PROJECTION" - esri_wkt = "PROJECTION" - - def __init__(self, value): - self.value = value - - def to_proj4(self): - return "+proj=%s" %self.value.proj4 - - def to_ogc_wkt(self): - return 'PROJECTION["%s"]' %self.value.ogc_wkt - - def to_esri_wkt(self): - return 'PROJECTION["%s"]' %self.value.esri_wkt - ##+zone UTM zone ##+south Denotes southern hemisphere UTM zone @@ -599,24 +432,4 @@ class TiltAngle: def to_esri_wkt(self): raise Exception("Parameter not supported by ESRI WKT") - -# then the final CRS object which is instantiated with all of these? -# remember to use +no_defs when outputting to proj4 -# ... -class CRS: - def __init__(self, toplevel): - self.toplevel = toplevel - - def to_proj4(self): - if isinstance(self.toplevel, ProjCS): - return "%s +no_defs" % self.toplevel.to_proj4() - elif isinstance(self.toplevel, GeogCS): - return "+proj=longlat %s +no_defs" % self.toplevel.to_proj4() - - def to_ogc_wkt(self): - return "%s" % self.toplevel.to_ogc_wkt() - - def to_esri_wkt(self): - return "%s" % self.toplevel.to_esri_wkt() - diff --git a/pycrs/elements/parameters.pyc b/pycrs/elements/parameters.pyc index 9da5b5e..4d5c027 100644 Binary files a/pycrs/elements/parameters.pyc and b/pycrs/elements/parameters.pyc differ diff --git a/pycrs/parser.py b/pycrs/parser.py index 3d418ec..faff913 100644 --- a/pycrs/parser.py +++ b/pycrs/parser.py @@ -9,6 +9,7 @@ from .elements import datums from .elements import ellipsoids from .elements import parameters +from .elements import containers from .elements import units from .elements import projections from . import utils @@ -274,7 +275,7 @@ def _from_wkt(string, wkttype, strict=False): projclass = projections.find(projname, "%s_wkt" % wkttype, strict) if projclass: projdef = projclass() - proj = parameters.Projection(projdef) + proj = containers.Projection(projdef) else: raise Exception("The specified projection name could not be found") @@ -314,7 +315,7 @@ def _from_wkt(string, wkttype, strict=False): ## twinax = None # put it all together - projcs = parameters.ProjCS("Unknown", geogcs, proj, params, linunit) #, twinax) + projcs = containers.ProjCS("Unknown", geogcs, proj, params, linunit) #, twinax) return projcs elif header.upper() == "GEOGCS": @@ -341,7 +342,7 @@ def _from_wkt(string, wkttype, strict=False): else: raise Exception("The specified ellipsoid name could not be found") - ellipsoid = parameters.Ellipsoid(ellipsdef, subsubcontent[1], subsubcontent[2]) + ellipsoid = containers.Ellipsoid(ellipsdef, subsubcontent[1], subsubcontent[2]) ## datum shift if wkttype == "ogc": @@ -355,7 +356,7 @@ def _from_wkt(string, wkttype, strict=False): datumshift = None ## put it all togehter - datum = parameters.Datum(datumdef, ellipsoid, datumshift) + datum = containers.Datum(datumdef, ellipsoid, datumshift) # prime mer subheader, subcontent = content[2] @@ -377,13 +378,13 @@ def _from_wkt(string, wkttype, strict=False): # ... # put it all together - geogcs = parameters.GeogCS(name, datum, prime_mer, angunit, twin_ax=None) + geogcs = containers.GeogCS(name, datum, prime_mer, angunit, twin_ax=None) return geogcs # toplevel collection header, content = crstuples[0] toplevel = _parse_top(header, content) - crs = parameters.CRS(toplevel) + crs = containers.CRS(toplevel) # use args to create crs return crs @@ -476,17 +477,17 @@ def from_proj4(string, strict=False): # COMBINE DATUM AND ELLIPS ## create datum and ellips param objs - ellips = parameters.Ellipsoid(ellipsdef, + ellips = containers.Ellipsoid(ellipsdef, semimaj_ax=partdict.get("+a"), inv_flat=partdict.get("+f")) if "+datum" in partdict: - datum = parameters.Datum(datumdef, ellips) + datum = containers.Datum(datumdef, ellips) elif "+towgs84" in partdict: - datum = parameters.Datum(datumdef, ellips, datumshift) + datum = containers.Datum(datumdef, ellips, datumshift) else: - datum = parameters.Datum(datumdef, ellips) + datum = containers.Datum(datumdef, ellips) # PRIME MERIDIAN @@ -520,7 +521,7 @@ def from_proj4(string, strict=False): # GEOGCS (note, currently does not load axes) - geogcs = parameters.GeogCS("Unknown", datum, prime_mer, angunit) #, twin_ax) + geogcs = containers.GeogCS("Unknown", datum, prime_mer, angunit) #, twin_ax) # PROJECTION @@ -543,7 +544,7 @@ def from_proj4(string, strict=False): if projdef: # create proj param obj - proj = parameters.Projection(projdef) + proj = containers.Projection(projdef) # Because proj4 has no element hierarchy, using automatic element find() would # ...would not be very effective, as that would need a try-fail approach for each @@ -656,15 +657,15 @@ def from_proj4(string, strict=False): # PROJCS - projcs = parameters.ProjCS("Unknown", geogcs, proj, params, unit) + projcs = containers.ProjCS("Unknown", geogcs, proj, params, unit) # CRS - crs = parameters.CRS(projcs) + crs = containers.CRS(projcs) else: # means projdef was None, ie unprojected longlat geogcs - crs = parameters.CRS(geogcs) + crs = containers.CRS(geogcs) # FINISHED diff --git a/pycrs/parser.pyc b/pycrs/parser.pyc index 6441d4a..eeef61f 100644 Binary files a/pycrs/parser.pyc and b/pycrs/parser.pyc differ