From ebccfc38dcae7e9a0b688f66791cb8d943c69fc0 Mon Sep 17 00:00:00 2001 From: Karim Bahgat Date: Sun, 5 Jul 2015 17:25:44 +0200 Subject: [PATCH] Wkt parsing into tuples and args now works for easier parsing. Next just need to make them into objs. --- pycrs/datums.py | 7 ++ pycrs/datums.pyc | Bin 1468 -> 1752 bytes pycrs/ellipsoids.py | 19 ++++ pycrs/ellipsoids.pyc | Bin 1350 -> 1950 bytes pycrs/parameters.py | 31 ++++++- pycrs/parameters.pyc | Bin 25122 -> 26015 bytes pycrs/parser.py | 206 ++++++++++++++++++++++++++++++++++-------- pycrs/parser.pyc | Bin 5079 -> 8334 bytes pycrs/projections.py | 111 +++++++++++++++++++++++ pycrs/projections.pyc | Bin 892 -> 6806 bytes pycrs/units.py | 5 + pycrs/units.pyc | Bin 655 -> 889 bytes tester.py | 37 ++++++-- 13 files changed, 369 insertions(+), 47 deletions(-) diff --git a/pycrs/datums.py b/pycrs/datums.py index ac77fee..20a1606 100644 --- a/pycrs/datums.py +++ b/pycrs/datums.py @@ -23,6 +23,13 @@ class NAD83: ellipsdef = "" # ellipsoids.WGS72() to_wgs84 = None +class NAD27: + proj4 = "NAD27" + ogc_wkt = "D_North_American_1927" + esri_wkt = "D_North_American_1927" + + ellipsdef = "" # ellipsoids... + to_wgs84 = None class Unknown: proj4 = "unknown" # no datum name, just ellips + towgs84 params... diff --git a/pycrs/datums.pyc b/pycrs/datums.pyc index bdf7a950f8eaadb39cf48bbdb9ff1c78b59359d7..cdade30cc9d9d6bf49e9ddab6e5325c296d1f3fb 100644 GIT binary patch delta 276 zcmdnPeS^22`7vJH9a+VhfRW#NMT_};bur-g$n_durZ|YFr=``Wx9~%Gw diff --git a/pycrs/ellipsoids.py b/pycrs/ellipsoids.py index 101bf89..37ad624 100644 --- a/pycrs/ellipsoids.py +++ b/pycrs/ellipsoids.py @@ -32,3 +32,22 @@ class GRS80: semimaj_ax = 6378137.0 inv_flat = 298.257222101 + +class Clarke1866: + proj4 = "clrk66" + ogc_wkt = "Clarke_1866" + esri_wkt = "Clarke_1866" + + semimaj_ax = 6378206.4 + inv_flat = 294.9786982 + +class Airy1830: + proj4 = "airy" + ogc_wkt = "Airy 1830" + esri_wkt = "Airy_1830" + + semimaj_ax = 6377563.396 + inv_flat = 299.3249646 + + + diff --git a/pycrs/ellipsoids.pyc b/pycrs/ellipsoids.pyc index 0249cb047d8719b0899ac0628c7b73682595752d..073532d4350cb53b6ceb3385ba82b524b1c8b86b 100644 GIT binary patch delta 399 zcmX@cHIKiZ`7a!i9iJ*ceg-7*g2bLd*;)91JOf3@My&A)qcUafTEjh7@kN7%M{x z4@0nq@WuiM7XA`0pc9;P5{t4^4K2*fChuo<)GlEIiY4b1Wt*9maKokJLGtOdX3m_s zJtV?0y?j>T{uTL?)tSqc1%PT)fVdcB78@fNGO;n1Z~(cEnMIX`7RHnJF>6h}$|zx4 z!U7ab1PT^&LS+?z(gr0k9?%wJgY+bUh?`;{TXs$r;WOR}vV~O`s9tCCJQj_~dsw*S pK~4+;Vum1)&LEI8gZMxM$T2~}ll_?eCu^|^@qwHq%qh$PfdD-HPMQD! delta 161 zcmbQoe~hc1`7RW#NMT_};bur-g$n_durZ|YFr=`%Y(t{-Mwzfg*_oEv^;4kiSf7j@AB z`vF}@c8>CQyzQcAGtYV7m&5t+JkNQ~%X#-vEv=}Mz3Hoa z@$k*1@?h9o&oc~*to2#z*C@O$Ob*&X|URmgw%j% zz*<8NSO-Q+px2nB)q^q6XQ&$70rrD_LsF>$JPW#pYQaYE92hVp#dm_|!6rjqa2GfL zHXEv!{da?dV2d#y*b2tMpdo1?1YQ9581jQ{;6-q+A?d0eyaaX_a>0GzWpKYCY4iX% z1a_9GRQZbm@E~{vJY>S8`7Ur6JZz{5JOW+?yA8>Cj)DpBn4xCyIG6-a7?KnAfY-pV zp%yR#UPpkv#^lr|G1_%w`L7zfqjRyB>Vsamzo74qg_ONKH`c4H6{VFYtk>Hey*@r| zecoC=x;L-B=ydG0`YH*F>XYu6Xl}BLez``YnPN7d&lR)7+1!JfqK;3@=_My^tyWS! zj)Zj2=y-I>TH7kN+UIX5Y$r|5RI(N$)9QO=gCAO@pSa)TY8GlF)uU?d@}r{@Z&gyq z+miZLYnAn@Tq>yhQ(?i`RLc6j4I!T;X`O|x@-&jv?qo{+sZ`#S%8#9d@K60T{Yt-2 dJ1VHXndjC>Lc4*RdM(qaB6=g!;{;^5{{Z#4ywd;x delta 708 zcmX}q%}Z2a6bA6;%$?D6oF*NeNt-^b%qcBrvhT7cGi|0IDlBFS(R|!wfiSx^gIEy} zQ5{-GEu)?PL0FrDphYVaMQ|BJ|3GI<&gEWS&hNg@d(V4$-+q<%3sMdK#u`7bz8amx z#ueC@x2Liw0PPms2ObE@0$~X32Ln6;=73V!>M(c&j5q~g9e5P1cd{v)z++&8Qv_@T zk5|E{o5h;I6JX4#9^4F`1mjM&(iZR(*zD8*wt%O>gp)1a3Z4PmoT6Y78~{^JP4@k* z;90QUEe3Xg=fG`F)IHE~O=w%zI*lj_FVLbosLSVc4q#E ze_Hspe9@UwO2YbK{EZZKC4N 0: + consumed += char + char = next(chars, None) + # update depth level + if char == "[": + depth += 1 + elif char == "]": + depth -= 1 + consumed += char # consume the last closing char too + return consumed + + def _consume_quote(chars, char, quotechar): + "char and quotechar must be the opening quote char" + consumed = "" + # consume the first opening char + consumed += char + char = next(chars, None) + # consume inside + while char and char != quotechar: + consumed += char + char = next(chars, None) + # consume the last closing char too + consumed += char + return consumed + + def _next_elem(chars, char): + "char can be any char" + header = "" + # skip until next header + while not char.isalpha(): + char = next(chars, None) + # first consume the element text header + while char.isalpha(): + header += char + char = next(chars, None) + # skip until next brackets (in case of spaces) + while char != "[": + char = next(chars, None) + # then consume the element bracket contents + if char == "[": + content = _consume_bracket(chars, char) + char = next(chars, None) + # split content into args list + content = content[1:-1] # remove enclosing brackets + content = _split_except(content) + # recursively load all subelems + for i,item in enumerate(content): + if isinstance(item, str) and "[" in item: + chars = (char for char in item) + char = next(chars) + item = _next_elem(chars, char) + content[i] = item + return header, content + + def _clean_value(string): + string = string.strip() + try: string = float(string) + except: pass + return string + + def _split_except(string): + chars = (char for char in string) + char = next(chars) + items = [] + consumed = "" + while char: + # dont split on quotes, just consume it + if char in ("'", '"'): + consumed += _consume_quote(chars, char, char) + # dont split inside brackets, just consume it + elif char == "[": + consumed += _consume_bracket(chars, char) + # make new splititem + elif char == ",": + consumed = _clean_value(consumed) + items.append(consumed) + consumed = "" + # consume normal char + elif char: + consumed += char + # next + char = next(chars, None) + # append last item too + consumed = _clean_value(consumed) + items.append(consumed) + return items + + # load into nested tuples and arglists + crstuples = [] + chars = (char for char in string) + char = next(chars) + while char: + header,content = _next_elem(chars, char) + crstuples.append((header, content)) + char = next(chars, None) + + # parse into actual crs objects + for header, content in crstuples: + # toplevel collection + if header.upper() == "PROJCS": + # find name + # find geogcs elem + # find projection elem + # find params + # find unit + pass + #projcs = parameters.ProjCS("Unknown", geogcs, proj, params, unit) + + elif header.upper() == "GEOGCS": + pass + + + + + # use args to create crs + return crstuples + ##def from_unknown_wkt(string): ## # detect if ogc wkt or esri wkt ## # TIPS: esri wkt datums all use "D_" before the datum name @@ -61,6 +183,13 @@ def from_proj4(string): # INIT CODES...? # eg, +init=epsg code...? + if "+init" in partdict: + + codetype, code = partdict["+init"].split(":") + if codetype == "EPSG": + crs = from_epsg_code(code) + # need to get individual elements from crs + # maybe from web... # DATUM @@ -68,11 +197,15 @@ def from_proj4(string): if "+datum" in partdict: # get predefined datum def - if partdict["+datum"] == "WGS84": - datumdef = datums.WGS84() - - elif partdict["+datum"] == "NAD83": - datumdef = datums.NAD83() + for itemname in dir(datums): + item = getattr(datums, itemname) + try: + item = item() + if hasattr(item, "proj4") and partdict["+datum"] == item.proj4: + datumdef = item + break + except: + pass else: datumdef = datums.Unknown() @@ -86,17 +219,15 @@ def from_proj4(string): if "+ellps" in partdict: # get predefined ellips def - if partdict["+ellps"] == "WGS84": - ellipsdef = ellipsoids.WGS84() - - elif partdict["+ellps"] == "WGS72": - ellipsdef = ellipsoids.WGS72() - - elif partdict["+ellps"] == "intl": - ellipsdef = ellipsoids.International() - - elif partdict["+ellps"] == "GRS80": - ellipsdef = ellipsoids.GRS80() + for itemname in dir(ellipsoids): + item = getattr(ellipsoids, itemname) + try: + item = item() + if hasattr(item, "proj4") and partdict["+ellps"] == item.proj4: + ellipsdef = item + break + except: + pass else: raise Exception("Could not find required +ellps element") @@ -163,22 +294,15 @@ def from_proj4(string): if "+proj" in partdict: # get predefined proj def - if partdict["+proj"] == "robin": - projdef = projections.Robinson() - - elif partdict["+proj"] == "omerc": - projdef = projections.ObliqueMercator() - - 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... - # ... + for itemname in dir(projections): + item = getattr(projections, itemname) + try: + item = item() + if hasattr(item, "proj4") and partdict["+proj"] == item.proj4: + projdef = item + break + except: + pass else: projdef = None @@ -278,6 +402,12 @@ def from_proj4(string): ## create unitobj unit = parameters.Unit(unittype, metmulti) + # SATELLITE HEIGHT + if "+h" in partdict: + val = partdict["+h"] + obj = parameters.SatelliteHeight(val) + params.append(obj) + # PROJCS projcs = parameters.ProjCS("Unknown", geogcs, proj, params, unit) diff --git a/pycrs/parser.pyc b/pycrs/parser.pyc index ca4af7889853556105edb7ec0b232117b8643c86..4a3a41468e4147ebe25d194d5a89ec9ca950cf78 100644 GIT binary patch literal 8334 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 diff --git a/pycrs/units.py b/pycrs/units.py index 6b2a174..6c2cb18 100644 --- a/pycrs/units.py +++ b/pycrs/units.py @@ -9,3 +9,8 @@ class Degree: proj4 = "degrees" ogc_wkt = "degree" esri_wkt = "Degree" + +class Feet: + proj4 = "..." + ogc_wkt = "Foot_US" + esri_wkt = "Foot_US" diff --git a/pycrs/units.pyc b/pycrs/units.pyc index 1220c6e2d81aa72eaf0feafa865d0c07e94e57bf..189d3bfff12ece26432bae5234df8e69ae16c7c2 100644 GIT binary patch delta 219 zcmeBY{mB-~{F#?4=Fh~?WCkc;2GR~dTx<&@Qh