mirror of
https://github.com/wassname/PyCRS.git
synced 2026-08-01 12:10:27 +08:00
Basic fromproj4 works, except need better handle when unprojected (longlat and latlong)
Also just need to expand to more projection name, datum name, and ellipsoid name definitions, and also additional special parameters. After that, test, and move onto from_wkt()...
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
from . import loader
|
||||
from . import parser
|
||||
from . import webscrape
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
codetype code proj4 ogcwkt esriwkt
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
class WGS84:
|
||||
proj4 = "WGS84"
|
||||
ogc_wkt = "WGS_1984"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
|
||||
class North:
|
||||
proj4 = "n"
|
||||
ogc_wkt = "NORTH"
|
||||
esri_wkt = "NORTH"
|
||||
|
||||
class East:
|
||||
proj4 = "e"
|
||||
ogc_wkt = "EAST"
|
||||
esri_wkt = "EAST"
|
||||
|
||||
class South:
|
||||
proj4 = "s"
|
||||
ogc_wkt = "SOUTH"
|
||||
esri_wkt = "SOUTH"
|
||||
|
||||
class West:
|
||||
proj4 = "w"
|
||||
ogc_wkt = "WEST"
|
||||
esri_wkt = "WEST"
|
||||
|
||||
class Up:
|
||||
proj4 = "u"
|
||||
ogc_wkt = "UP"
|
||||
esri_wkt = "UP"
|
||||
|
||||
class Down:
|
||||
proj4 = "d"
|
||||
ogc_wkt = "DOWN"
|
||||
esri_wkt = "DOWN"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
class WGS84:
|
||||
proj4 = "WGS84"
|
||||
ogc_wkt = "WGS_1984"
|
||||
|
||||
semimaj_ax = 6378137
|
||||
inv_flat = 298.257223563
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,49 @@
|
||||
|
||||
import json
|
||||
|
||||
|
||||
#################
|
||||
# USER FUNCTIONS
|
||||
#################
|
||||
|
||||
# convenience methods for loading from different sources
|
||||
|
||||
def from_url(url, format=None):
|
||||
# first get string from url
|
||||
# ...
|
||||
|
||||
# then load
|
||||
if format:
|
||||
# load string using specified format
|
||||
pass
|
||||
else:
|
||||
from_unknown_text(string)
|
||||
|
||||
def from_file(filepath):
|
||||
if filepath.endswith(".prj"):
|
||||
string = open(filepath, "r").read()
|
||||
from_esri_wkt(string)
|
||||
|
||||
elif filepath.endswith((".geojson",".json")):
|
||||
crsinfo = json.load(filepath)["crs"]
|
||||
|
||||
if crsinfo["type"] == "name":
|
||||
string = crsinfo["properties"]["name"]
|
||||
from_unknown_text(string)
|
||||
|
||||
elif crsinfo["type"] == "link":
|
||||
url = crsinfo["properties"]["name"]
|
||||
type = crsinfo["properties"].get("type")
|
||||
from_url(url, format=type)
|
||||
|
||||
else: raise Exception("invalid geojson crs type: must be either name or link")
|
||||
|
||||
elif filepath.endswith((".tif",".tiff",".geotiff")):
|
||||
pass
|
||||
# ...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,437 @@
|
||||
|
||||
#################
|
||||
# CRS CLASSES
|
||||
#################
|
||||
|
||||
# first classes for each crs element, from the proj4 common paramter listing
|
||||
# https://trac.osgeo.org/proj/wiki/GenParms
|
||||
|
||||
# note also that in wkt the names of "PROJECTION", "DATUM", and "SPHEROID"
|
||||
# matter and seem to be interpreted and computed upon, ie they carry meaning
|
||||
# that is commonly understood by programs, so is not explicit in the crs specification.
|
||||
|
||||
# the paramters below simply modify certain aspects of the proj/datum/spheroids
|
||||
|
||||
# note that the names in wkt of "PROJCS" and "GEOGCS" seem to be purely
|
||||
# for identifying and branding and can be changed at will.
|
||||
# they do however act as shortcuts, so that proj4 can use +init=... to load
|
||||
# everything automatically
|
||||
|
||||
# some of these names imply certain combinations of datum and spheroid and paramters.
|
||||
# so in proj4 one simply needs to give that name, but in wkt one needs to spell it all out.
|
||||
|
||||
# +unit and +to_metre are what makes up 'UNIT["Meter",1.0]'
|
||||
|
||||
from . import directions
|
||||
|
||||
|
||||
|
||||
##+a Semimajor radius of the ellipsoid axis
|
||||
class SemiMajorRadius:
|
||||
proj4 = "+a"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+alpha ? Used with Oblique Mercator and possibly a few others
|
||||
class Azimuth:
|
||||
proj4 = "+alpha"
|
||||
esri_wkt = "azimuth"
|
||||
ogc_wkt = "azimuth"
|
||||
geotiff = "AzimuthAngle"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+b Semiminor radius of the ellipsoid axis
|
||||
class SemiMinorRadius:
|
||||
proj4 = "+b"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+datum Datum name (see `proj -ld`)
|
||||
class Datum:
|
||||
def __init__(self, name, ellipsoid):
|
||||
"""
|
||||
Arguments:
|
||||
|
||||
- **name**: Specific datum name instance.
|
||||
- **ellipsoid**: Ellipsoid parameter instance.
|
||||
"""
|
||||
self.name = name
|
||||
self.ellips = ellipsoid
|
||||
|
||||
def to_proj4(self):
|
||||
return "+datum=%s %s" % (self.name.proj4, self.ellips.to_proj4())
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'DATUM["%s", %s]' % (self.name.ogc_wkt, self.ellips.to_ogc_wkt())
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "GeogGeodeticDatum"
|
||||
|
||||
##+ellps Ellipsoid name (see `proj -le`)
|
||||
class Ellipsoid:
|
||||
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 self.to_ogc_wkt()
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "GeogEllipsoid"
|
||||
|
||||
#GEOGCS
|
||||
class 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):
|
||||
# axis excluded because not sure if should be set from geogcs or projcs
|
||||
return "%s %s %s" % (self.datum.to_proj4(), self.prime_mer.to_proj4(), self.angunit.to_proj4() ) #+axis= AND #, self.twin_ax[0].proj4, self.twin_ax[1].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 self.to_ogc_wkt()
|
||||
|
||||
#PROJCS
|
||||
class 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
|
||||
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)
|
||||
# axis excluded because not sure if should be set from geogcs or projcs
|
||||
#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 += ', 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):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
|
||||
##+k Scaling factor (old name)
|
||||
##+k_0 Scaling factor (new name)
|
||||
class ScalingFactor:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+k_0=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'PARAMETER["scale_factor", %s]' %self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
raise Exception("Paramater not supported by ESRI WKT")
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "ScaleAtNatOrigin" # or ScaleAtCenter?
|
||||
|
||||
##+lat_0 Latitude of origin
|
||||
class LatitudeOrigin:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+lat_0=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'PARAMETER["latitude_of_origin", %s]' %self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
raise Exception("Paramater not supported by ESRI WKT")
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "ProjCenterLat"
|
||||
|
||||
##+lat_1 Latitude of first standard parallel
|
||||
class LatitudeFirstStndParallel:
|
||||
proj4 = "+lat_1"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+lat_2 Latitude of second standard parallel
|
||||
class LatitudeSecondStndParallel:
|
||||
proj4 = "+lat_2"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+lat_ts Latitude of true scale
|
||||
class LatitudeTrueScale:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+lat_ts=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'PARAMETER["Standard_Parallel_1", %s]' %self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "ProjStdParallel1"
|
||||
|
||||
##+lon_0 Central meridian
|
||||
class CentralMeridian:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+lon_0=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'PARAMETER["Central_Meridian", %s]' %self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
def to_geotiff(self):
|
||||
pass
|
||||
#return "ProjCenterLong"
|
||||
|
||||
|
||||
##+lonc ? Longitude used with Oblique Mercator and possibly a few others
|
||||
class LongitudeSpecial:
|
||||
proj4 = "+lonc"
|
||||
def __init__(self, value):
|
||||
pass
|
||||
|
||||
##+lon_wrap Center longitude to use for wrapping (see below)
|
||||
|
||||
##+over Allow longitude output outside -180 to 180 range, disables wrapping (see below)
|
||||
|
||||
##+pm Alternate prime meridian (typically a city name, see below)
|
||||
class PrimeMeridian:
|
||||
def __init__(self, value):
|
||||
"""
|
||||
Arguments:
|
||||
|
||||
- **value**: Longitude value relative to Greenwich.
|
||||
"""
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+pm=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'PRIMEM["Greenwich", %s]' %self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
##+proj Projection name (see `proj -l`)
|
||||
class 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 self.to_ogc_wkt()
|
||||
|
||||
|
||||
##+south Denotes southern hemisphere UTM zone
|
||||
|
||||
##+towgs84 3 or 7 term datum transform parameters (see below)
|
||||
class DatumShift:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+towgs84=%s" %"".join((str(val) for val in self.value))
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return "TOWGS84[%s]" %"".join((str(val) for val in self.value))
|
||||
|
||||
def to_esri_wkt(self):
|
||||
raise Exception("Paramater not supported by ESRI WKT")
|
||||
|
||||
##+to_meter Multiplier to convert map units to 1.0m
|
||||
class MeterMultiplier:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+to_meter=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
# the stuff that comes after UNITS["meter", ... # must be combined with unittype in a unit class to make wkt
|
||||
return str(self.value)
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
##+units meters, US survey feet, etc.
|
||||
class UnitType:
|
||||
def __init__(self, value):
|
||||
"""
|
||||
Arguments:
|
||||
|
||||
- **value**: A specific unit type instance, eg Meter().
|
||||
"""
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+units=%s" %self.value.proj4
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
# the stuff that comes after UNITS[... # must be combined with metermultiplier in a unit class to make wkt
|
||||
return str(self.value.ogc_wkt)
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
# special...
|
||||
class Unit:
|
||||
def __init__(self, unittype, metermultiplier):
|
||||
self.unittype = unittype
|
||||
self.metermultiplier = metermultiplier
|
||||
|
||||
def to_proj4(self):
|
||||
return "%s %s" %(self.unittype.to_proj4(), self.metermultiplier.to_proj4())
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'UNIT["%s", %s]' %(self.unittype.to_ogc_wkt(), self.metermultiplier.to_ogc_wkt())
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
# angular unit
|
||||
class AngularUnit:
|
||||
def __init__(self, unittype, metermultiplier):
|
||||
self.unittype = unittype
|
||||
self.metermultiplier = metermultiplier
|
||||
|
||||
def to_proj4(self):
|
||||
# cannot be specified in proj4, so just return nothing
|
||||
return ""
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
return 'UNIT["%s", %s]' %(self.unittype.to_ogc_wkt(), self.metermultiplier.to_ogc_wkt())
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
##+x_0 False easting
|
||||
class FalseEasting:
|
||||
proj4 = "+x_0"
|
||||
esri_wkt = "False_Easting"
|
||||
ogc_wkt = "false_easting"
|
||||
geotiff = "FalseEasting"
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+x_0=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
# the stuff that comes after UNITS[... # must be combined with metermultiplier in a unit class to make wkt
|
||||
return 'PARAMETER["false_easting", %s]' % self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_wkt()
|
||||
|
||||
##+y_0 False northing
|
||||
class FalseNorthing:
|
||||
proj4 = "+y_0"
|
||||
esri_wkt = "False_Northing"
|
||||
ogc_wkt = "false_northing"
|
||||
geotiff = "FalseNorthing"
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def to_proj4(self):
|
||||
return "+y_0=%s" %self.value
|
||||
|
||||
def to_ogc_wkt(self):
|
||||
# the stuff that comes after UNITS[... # must be combined with metermultiplier in a unit class to make wkt
|
||||
return 'PARAMETER["false_northing", %s]' % self.value
|
||||
|
||||
def to_esri_wkt(self):
|
||||
return self.to_ogc_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):
|
||||
return "%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 self.to_ogc_wkt()
|
||||
|
||||
|
||||
Binary file not shown.
+260
@@ -0,0 +1,260 @@
|
||||
|
||||
# parse from text strings
|
||||
# possible use module: https://github.com/rockdoc/grabbag/wiki/CRS-WKT-Parser
|
||||
# also note some paramter descriptions: http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html
|
||||
# and see gdal source code: http://gis.stackexchange.com/questions/129764/how-are-esri-wkt-projections-different-from-ogc-wkt-projections
|
||||
|
||||
from . import datums
|
||||
from . import ellipsoids
|
||||
from . import parameters
|
||||
from . import units
|
||||
from . import projections
|
||||
|
||||
def from_epsg_code(string):
|
||||
# must go online (or look up local table) to get crs details
|
||||
pass
|
||||
|
||||
def from_esri_code(string):
|
||||
# must go online (or look up local table) to get crs details
|
||||
pass
|
||||
|
||||
def from_sr_code(string):
|
||||
# must go online (or look up local table) to get crs details
|
||||
pass
|
||||
|
||||
def from_esri_wkt(string):
|
||||
# parse arguments into components
|
||||
# use args to create crs
|
||||
pass
|
||||
|
||||
def from_ogc_wkt(string):
|
||||
# parse arguments into components
|
||||
# use args to create crs
|
||||
pass
|
||||
|
||||
def from_unknown_wkt(string):
|
||||
# detect if ogc wkt or esri wkt
|
||||
# TIPS: esri wkt datums all use "D_" before the datum name
|
||||
# then load with appropriate function
|
||||
pass
|
||||
|
||||
def from_proj4(string):
|
||||
# parse arguments into components
|
||||
# use args to create crs
|
||||
|
||||
## proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs
|
||||
##
|
||||
## PROJCS["World_Robinson",
|
||||
## GEOGCS["GCS_WGS_1984",
|
||||
## DATUM["WGS_1984",
|
||||
## SPHEROID["WGS_1984",6378137,298.257223563]],
|
||||
## PRIMEM["Greenwich",0],
|
||||
## UNIT["Degree",0.017453292519943295]],
|
||||
## PROJECTION["Robinson"],
|
||||
## PARAMETER["False_Easting",0],
|
||||
## PARAMETER["False_Northing",0],
|
||||
## PARAMETER["Central_Meridian",0],
|
||||
## UNIT["Meter",1],
|
||||
## AUTHORITY["EPSG","54030"]]
|
||||
|
||||
params = []
|
||||
|
||||
partdict = dict([part.split("=") for part in string.split()
|
||||
if not part.startswith("+no_defs")])
|
||||
|
||||
# DATUM
|
||||
|
||||
# datum param is required
|
||||
if "+datum" in partdict:
|
||||
|
||||
# get predefined datum def
|
||||
if partdict["+datum"] == "WGS84":
|
||||
datumdef = datums.WGS84()
|
||||
|
||||
# ELLIPS
|
||||
|
||||
# ellipse param is required
|
||||
if "+ellps" in partdict:
|
||||
|
||||
# get predefined ellips def
|
||||
if partdict["+ellps"] == "WGS84":
|
||||
ellipsdef = ellipsoids.WGS84()
|
||||
|
||||
else:
|
||||
raise Exception("Could not find required +ellps element")
|
||||
|
||||
## create datum and ellips param objs
|
||||
ellips = parameters.Ellipsoid(ellipsdef,
|
||||
semimaj_ax=partdict.get("+a"),
|
||||
inv_flat=partdict.get("+f"))
|
||||
datum = parameters.Datum(datumdef, ellips)
|
||||
|
||||
else:
|
||||
raise Exception("Could not find required +datum element")
|
||||
|
||||
# PRIME MERIDIAN
|
||||
|
||||
# set default
|
||||
prime_mer = parameters.PrimeMeridian(0)
|
||||
|
||||
# overwrite with user input
|
||||
if "+pm" in partdict:
|
||||
# for now only support longitude, later add name support:
|
||||
## greenwich 0dE
|
||||
## lisbon 9d07'54.862"W
|
||||
## paris 2d20'14.025"E
|
||||
## bogota 74d04'51.3"E
|
||||
## madrid 3d41'16.48"W
|
||||
## rome 12d27'8.4"E
|
||||
## bern 7d26'22.5"E
|
||||
## jakarta 106d48'27.79"E
|
||||
## ferro 17d40'W
|
||||
## brussels 4d22'4.71"E
|
||||
## stockholm 18d3'29.8"E
|
||||
## athens 23d42'58.815"E
|
||||
## oslo 10d43'22.5"E
|
||||
prime_mer = parameters.PrimeMeridian(partdict["+pm"])
|
||||
|
||||
# ANGULAR UNIT
|
||||
|
||||
## proj4 cannot set angular unit, so just set to default
|
||||
metmulti = parameters.MeterMultiplier(0.017453292519943295)
|
||||
unittype = parameters.UnitType(units.Degree())
|
||||
angunit = parameters.AngularUnit(unittype, metmulti)
|
||||
|
||||
# GEOGCS (note, currently does not load axes)
|
||||
|
||||
geogcs = parameters.GeogCS("Unknown", datum, prime_mer, angunit) #, twin_ax)
|
||||
|
||||
# PROJECTION
|
||||
|
||||
if "+proj" in partdict:
|
||||
|
||||
# get predefined proj def
|
||||
if partdict["+proj"] == "robin":
|
||||
projdef = projections.Robinson()
|
||||
|
||||
elif partdict["+proj"] == "longlat":
|
||||
projdef = None
|
||||
# set geogcs axis in correct order
|
||||
|
||||
elif partdict["+proj"] == "latlong":
|
||||
projdef = None
|
||||
# set geogcs axis in correct order
|
||||
|
||||
# ALSO SHOULDNT EXCLUDE +proj, NEED WAY TO INCLUDE IT...
|
||||
# ...
|
||||
|
||||
else:
|
||||
projdef = None
|
||||
|
||||
else:
|
||||
raise Exception("Could not find required +proj element")
|
||||
|
||||
if projdef:
|
||||
|
||||
# create proj param obj
|
||||
proj = parameters.Projection(projdef)
|
||||
|
||||
# CENTRAL MERIDIAN
|
||||
|
||||
if "+lon_0" in partdict:
|
||||
val = partdict["+lon_0"]
|
||||
obj = parameters.CentralMeridian(val)
|
||||
params.append(obj)
|
||||
|
||||
# FALSE EASTING
|
||||
|
||||
if "+x_0" in partdict:
|
||||
val = partdict["+x_0"]
|
||||
obj = parameters.FalseEasting(val)
|
||||
params.append(obj)
|
||||
|
||||
# FALSE NORTHING
|
||||
|
||||
if "+y_0" in partdict:
|
||||
val = partdict["+y_0"]
|
||||
obj = parameters.FalseNorthing(val)
|
||||
params.append(obj)
|
||||
|
||||
# UNIT
|
||||
|
||||
## set default
|
||||
metmulti = parameters.MeterMultiplier(1.0)
|
||||
unittype = parameters.UnitType(units.Meter())
|
||||
|
||||
## override with user input
|
||||
if "+to_meter" in partdict:
|
||||
metmulti = parameters.MeterMultiplier(partdict["+to_meter"])
|
||||
if "+units" in partdict:
|
||||
if partdict["+units"] == "m":
|
||||
unittype = parameters.UnitType(units.Meter())
|
||||
|
||||
## create unitobj
|
||||
unit = parameters.Unit(unittype, metmulti)
|
||||
|
||||
# PROJCS
|
||||
|
||||
projcs = parameters.ProjCS("Unknown", geogcs, proj, params, unit)
|
||||
|
||||
# CRS
|
||||
|
||||
crs = parameters.CRS(projcs)
|
||||
|
||||
else:
|
||||
crs = parameters.CRS(geogcs)
|
||||
|
||||
# FINISHED
|
||||
|
||||
return crs
|
||||
|
||||
def from_ogc_urn(string):
|
||||
# hmmm, seems like ogc urn could be anything incl online link, epsg, etc...
|
||||
# if necessary, must go online (or lookup local table) to get details
|
||||
# maybe test which of these and run their function?
|
||||
# examples urn:ogc:def:crs:OGC:1.3:CRS1
|
||||
# or with EPSG instead of OGC
|
||||
|
||||
# If OGC, 1.3 is pdf version, and after that is a name from list below
|
||||
# as found in pdf: "Definition identifier URNs in OGC namespace"
|
||||
# OGC crs definitions
|
||||
# URN | CRS name | Definition reference
|
||||
# urn:ogc:def:crs:OGC:1.3:CRS1 Map CS B.2 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:CRS84 WGS 84 longitude-latitude B.3 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:CRS83 NAD83 longitude-latitude B.4 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:CRS27 NAD27 longitude-latitude B.5 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:CRS88 NAVD 88 B.6 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:AUTO42001:99:8888 Auto universal transverse mercator B.7 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:AUTO42002:99:8888 Auto transverse mercator B.8 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:AUTO42003:99:8888 Auto orthographic B.9 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:AUTO42004:99:8888 Auto equirectangular B.10 in OGC 06-042
|
||||
# urn:ogc:def:crs:OGC:1.3:AUTO42005:99 Auto Mollweide B.11 in OGC 06-042
|
||||
|
||||
|
||||
pass
|
||||
|
||||
def from_unknown_text(text):
|
||||
# detect type and load with appropriate function
|
||||
|
||||
if string.startswith("urn:"):
|
||||
from_ogc_urn(string)
|
||||
|
||||
elif string.startswith("+proj="):
|
||||
from_proj4(string)
|
||||
|
||||
elif string.startswith("PROJCS["):
|
||||
from_unknown_wkt(string)
|
||||
|
||||
elif string.startswith("EPSG:"):
|
||||
from_epsg_code(string)
|
||||
|
||||
elif string.startswith("ESRI:"):
|
||||
from_esri_code(string)
|
||||
|
||||
elif string.startswith("SR-ORG:"):
|
||||
from_sr_code(string)
|
||||
|
||||
else: raise Exception("Could not detect which type of crs")
|
||||
|
||||
def from_geotiff_parameters(**params):
|
||||
pass
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
class Robinson:
|
||||
proj4 = "robin"
|
||||
ogc_wkt = "Robinson"
|
||||
|
||||
class UTM:
|
||||
proj4 = "utm"
|
||||
ogc_wkt = "Transverse_Mercator"
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
class Meter:
|
||||
proj4 = "m"
|
||||
ogc_wkt = "Meters" # or is it metre?? sometimes even Meter?
|
||||
esri_wkt = "Meter"
|
||||
|
||||
class Degree:
|
||||
proj4 = "degrees"
|
||||
ogc_wkt = "degree"
|
||||
esri_wkt = "Degree"
|
||||
Binary file not shown.
@@ -0,0 +1,77 @@
|
||||
import urllib2
|
||||
import re
|
||||
|
||||
def build_crs_table(savepath):
|
||||
|
||||
# create table
|
||||
outfile = open(savepath, "wb")
|
||||
|
||||
# create fields
|
||||
fields = ["codetype", "code", "proj4", "ogcwkt", "esriwkt"]
|
||||
outfile.write("\t".join(fields) + "\n")
|
||||
|
||||
# make table from url requests
|
||||
for codetype in ("epsg", "esri", "sr-org"):
|
||||
print(codetype)
|
||||
|
||||
# collect existing proj list
|
||||
print("fetching list of available codes")
|
||||
codelist = []
|
||||
page = 1
|
||||
while True:
|
||||
try:
|
||||
link = 'http://spatialreference.org/ref/%s/?page=%s' %(codetype,page)
|
||||
html = urllib2.urlopen(link).read()
|
||||
codes = [match.groups()[0] for match in re.finditer(r'/ref/'+codetype+'/(\d+)', html) ]
|
||||
if not codes: break
|
||||
print("page",page)
|
||||
codelist.extend(codes)
|
||||
page += 1
|
||||
except:
|
||||
break
|
||||
|
||||
print("fetching string formats for each projection")
|
||||
for i,code in enumerate(codelist):
|
||||
|
||||
# check if code exists
|
||||
link = 'http://spatialreference.org/ref/%s/%s/' %(codetype,code)
|
||||
urllib2.urlopen(link)
|
||||
|
||||
# collect each projection format in a table row
|
||||
row = [codetype, code]
|
||||
for resulttype in ("proj4", "ogcwkt", "esriwkt"):
|
||||
try:
|
||||
link = 'http://spatialreference.org/ref/%s/%s/%s/' %(codetype,code,resulttype)
|
||||
result = urllib2.urlopen(link).read()
|
||||
row.append(result)
|
||||
except:
|
||||
pass
|
||||
|
||||
print("projection %i of %i added" %(i,len(codelist)) )
|
||||
outfile.write("\t".join(row) + "\n")
|
||||
|
||||
# close the file
|
||||
outfile.close()
|
||||
|
||||
|
||||
def crscode_to_string(codetype, code, format):
|
||||
link = 'http://spatialreference.org/ref/%s/%s/%s/' %(codetype,code,format)
|
||||
result = urllib2.urlopen(link).read()
|
||||
return result
|
||||
|
||||
def crsstring_to_string(string, newformat):
|
||||
# search string, if string is correct there should only be one correct match
|
||||
link = 'http://spatialreference.org/ref/?search=%s' %string
|
||||
searchresults = urllib2.urlopen(link).read()
|
||||
# pick the first result
|
||||
# ...regex...
|
||||
# go to its url, with extension for the newformat
|
||||
link = 'http://spatialreference.org/ref/%s/%s/%s/' %(codetype,code,newformat)
|
||||
result = urllib2.urlopen(link).read()
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
build_crs_table("crstable.txt")
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user