diff --git a/pycrs/loader.py b/pycrs/loader.py index 725cebf..f161271 100644 --- a/pycrs/loader.py +++ b/pycrs/loader.py @@ -16,7 +16,7 @@ def from_url(url, format=None): Arguments: - *url*: The url where the crs string is to be read from. - - *format*: Which format to parse the crs string as. One of "ogcwkt", "esriwkt", or "proj4", but also several others... + - *format*: Which format to parse the crs string as. One of "ogc wkt", "esri wkt", or "proj4". Returns: - CRS object. diff --git a/pycrs/loader.pyc b/pycrs/loader.pyc index 6290500..3b408f5 100644 Binary files a/pycrs/loader.pyc and b/pycrs/loader.pyc differ diff --git a/pycrs/parser.py b/pycrs/parser.py index 87ded17..b94176e 100644 --- a/pycrs/parser.py +++ b/pycrs/parser.py @@ -95,14 +95,30 @@ def from_esri_wkt(string, strict=False): # parse arguments into components # use args to create crs return _from_wkt(string, "esri", strict) - + +def from_unknown_wkt(string, strict=False): + """ + Given an unknown wkt string, detect if uses ogc or esri flavor, and parse the crs accordingly. + + Arguments: + - *string*: The unknown WKT representation as a string. + - *strict* (optional): When True, the parser is strict about names having to match + exactly with upper and lowercases. Default is not strict (False). + + Returns: + - CRS object. + """ + # parse arguments into components + # use args to create crs + return _from_wkt(string, None, strict) + def _from_wkt(string, wkttype, strict=False): """ Internal method for parsing wkt, with minor differences depending on ogc or esri style. Arguments: - *string*: The OGC or ESRI WKT representation as a string. - - *wkttype*: How to parse the WKT string, as either 'ogc' or 'esri'. + - *wkttype* (optional): How to parse the WKT string, as either 'ogc', 'esri', or None. If None, tries to autodetect the wkt type before parsing (default). - *strict* (optional): When True, the parser is strict about names having to match exactly with upper and lowercases. Default is not strict (False). @@ -114,8 +130,8 @@ def _from_wkt(string, wkttype, strict=False): # - Maybe verify elem arg name # make sure valid wkttype - wkttype = wkttype.lower() - assert wkttype in ("ogc","esri") + if wkttype: wkttype = wkttype.lower() + assert wkttype in ("ogc","esri",None) # remove newlines and multi spaces string = " ".join(string.split()) @@ -212,7 +228,7 @@ def _from_wkt(string, wkttype, strict=False): consumed = _clean_value(consumed) items.append(consumed) return items - + # load into nested tuples and arglists crstuples = [] chars = (char for char in string) @@ -222,6 +238,24 @@ def _from_wkt(string, wkttype, strict=False): crstuples.append((header, content)) char = next(chars, None) + # autodetect wkttype if not specified + if not wkttype: + topheader,topcontent = crstuples[0] + if topheader == "PROJCS": + geogcsheader,geogcscontent = topcontent[1] + elif topheader == "GEOGCS": + geogcsheader,geogcscontent = topheader,topcontent + + # datum elem should be second under geogcs + datumheader, datumcontent = geogcscontent[1] + datumname = datumcontent[0].upper().strip('"') + + # esri wkt datums all use "D_" before the datum name + if datumname.startswith("D_"): + wkttype = "esri" + else: + wkttype = "ogc" + # parse into actual crs objects def _parse_top(header, content): "procedure for parsing the toplevel crs element and all its children" @@ -396,12 +430,6 @@ def _from_wkt(string, wkttype, strict=False): # use args to create crs return crs -##def from_unknown_wkt(string, strict=False): -## # 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, strict=False): """ Parse crs as proj4 formatted string and return the resulting crs object. @@ -717,23 +745,23 @@ def from_unknown_text(text, strict=False): Detect crs string format and parse into crs object with appropriate function. Arguments: - - *string*: The crs text representation of unknown type. + - *string*: The crs text representation of unknown type. - *strict* (optional): When True, the parser is strict about names having to match exactly with upper and lowercases. Default is not strict (False). Returns: - CRS object. """ - - if string.startswith("urn:"): - from_ogc_urn(string, strict) - elif string.startswith("+"): + if string.startswith("+"): from_proj4(string, strict) elif string.startswith(("PROJCS[","GEOGCS[")): from_unknown_wkt(string, strict) + #elif string.startswith("urn:"): + # from_ogc_urn(string, strict) + elif string.startswith("EPSG:"): from_epsg_code(string.split(":")[1]) diff --git a/pycrs/parser.pyc b/pycrs/parser.pyc index e4a9cf5..eb1c1cf 100644 Binary files a/pycrs/parser.pyc and b/pycrs/parser.pyc differ diff --git a/pycrs/webscrape.pyc b/pycrs/webscrape.pyc index d87b7f2..79bc856 100644 Binary files a/pycrs/webscrape.pyc and b/pycrs/webscrape.pyc differ diff --git a/tester.py b/tester.py index d0c4402..66ad539 100644 --- a/tester.py +++ b/tester.py @@ -1,5 +1,5 @@ import pycrs - +import traceback @@ -84,15 +84,15 @@ def sourcestrings(format): def testoutputs(crs): print("To:\n") try: result = crs.to_ogc_wkt() - except: result = "Fail" + except: result = traceback.format_exc() print("ogc_wkt: %s \n" % result) try: result = crs.to_esri_wkt() - except: result = "Fail" + except: result = traceback.format_exc() print("esri_wkt: %s \n" % result) try: result = crs.to_proj4() - except: result = "Fail" + except: result = traceback.format_exc() print("proj4: %s \n" % result) @@ -129,8 +129,8 @@ for wkt in sourcestrings("ogcwkt"): # test outputs testoutputs(crs) - except Exception as err: - print(err) + except: + print(traceback.format_exc()+"\n") #render_world(crs)