def __init__(self, cs=None): self._dict = None self._gxapi_ipj = gxapi.GXIPJ.create() if cs: if isinstance(cs, str): self._from_str(cs) elif isinstance(cs, gxapi.GXIPJ): s1 = gxapi.str_ref() s2 = gxapi.str_ref() s3 = gxapi.str_ref() s4 = gxapi.str_ref() s5 = gxapi.str_ref() cs.get_gxf(s1, s2, s3, s4, s5) self._from_gxf((s1.value, s2.value, s3.value, s4.value, s5.value)) elif isinstance(cs, GXcs): self._from_gxf(cs.get_gxf()) elif isinstance(cs, dict): self._from_dict(cs) else: self._from_gxf(cs)
def gxf(self): """ The GXF string list from ipj. (http://www.geosoft.com/resources/goto/GXF-Grid-eXchange-File) The first string (gxf[0]) is the coordinate system name in the form: `datum / projection <x0,y0,z0,rx,ry,rz> [vcs]` The orientation parameters are between the '<>', and will be omitted if all 0. 'vcs' is the vertical coordinate system, and is omitted if the vcs is undefined. .. versionadded:: 9.2 """ s1 = gxapi.str_ref() s2 = gxapi.str_ref() s3 = gxapi.str_ref() s4 = gxapi.str_ref() s5 = gxapi.str_ref() self.gxipj.get_gxf(s1, s2, s3, s4, s5) lst = [ s1.value.replace('"', '').strip(), s2.value, s3.value, s4.value, s5.value ] return lst
def test_MAPINFO_cs(self): self.start(gsys.func_name()) stref1 = gxapi.str_ref() stref2 = gxapi.str_ref() #test IPJ creation using GXF strings cs = gxcs.GXcs(['', 'DHDN', 'Okarito 2000', '', '']) cs.gxipj.get_mi_coord_sys(stref1, stref2) self.assertEqual( stref1.value, 'CoordSys Earth Projection 8,1000,"m",170.2608333333,-43.1100000000,1,400000,800000' ) self.assertEqual(stref2.value, 'Units "m"') cs.gxipj.set_mi_coord_sys(stref1.value, stref2.value) gxfs = cs.get_gxf() self.assertEqual(gxfs[0], 'DHDN / Okarito 2000') self.assertEqual(gxfs[1], 'DHDN,6377397.155,0.0816968312225275,0') self.assertEqual( gxfs[2], '"Transverse Mercator",-43.11,170.2608333333,1,400000,800000') self.assertEqual(gxfs[3], 'm,1') self.assertEqual( gxfs[4], '"DHDN to WGS 84 (1)",582,105,414,1.04,0.35,-3.08,8.29999999996112' )
def get_parameters(group='_', parms=None, default=None): """ Get parameters from the Project Parameter Block. :param group: name in the parameter block group name :param parms: if specified only these keys are searched and the value is replaced by the found parameter. Parameter keys are not case sensitive, though if parms is not provided all returned keys will be upper-case. :param default: default value for parameters not found, ignored if parms is provided as a dict, in which case the current key:value settings will be unchanged. :returns: dictionary containing group parameters .. versionchanged:: 9.2.1 Now retains case on keys passed in to parms, which allows callers to maintain case. Note that if not specifying parms, the returned keys will always be upper-case. Fixed bug handling file name construction on Windows. .. versionadded:: 9.1 """ sv = gxapi.str_ref() p = {} if not (_validate_parameter(group)): raise UtilityException( _t('Group name \'{}\' contains invalid character \'.\''.format( group))) group = group.upper() if parms is not None: if not isinstance(parms, dict): for k in parms: p[k] = default parms = p for k, default in parms.items(): k_upper = k.upper() if gxapi.GXSYS.exist_string(group, k_upper): gxapi.GXSYS.gt_string(group, k_upper, sv) try: p[k] = json.loads(sv.value.replace('\\', '\\\\')) except ValueError: p[k] = sv.value else: p[k] = default else: h_reg = gxapi.GXREG.create(4096) gxapi.GXSYS.get_reg(h_reg, group) k = gxapi.str_ref() for i in range(h_reg.entries()): h_reg.get_one(i, k, sv) key = k.value.split('.')[1] try: p[key] = json.loads(sv.value) except ValueError: p[key] = sv.value return p
def get_gxf(self): """ Get GXF string list from ipj. Returns list of 5 GXF strings. .. versionadded:: 9.2 """ s1 = gxapi.str_ref() s2 = gxapi.str_ref() s3 = gxapi.str_ref() s4 = gxapi.str_ref() s5 = gxapi.str_ref() self.gxipj.get_gxf(s1, s2, s3, s4, s5) lst = [s1.value.replace('"', ' ').strip(), s2.value, s3.value, s4.value, s5.value] return lst
def vcs(self, vcs): """ Set the vertical coordinate system. :param vcs: vertical coordinate system name """ s1 = gxapi.str_ref() s2 = gxapi.str_ref() s3 = gxapi.str_ref() s4 = gxapi.str_ref() s5 = gxapi.str_ref() self.gxipj.get_gxf(s1, s2, s3, s4, s5) hcs, orient, current_vcs = hcs_orient_vcs_from_name(s1.value) if current_vcs != vcs: gxf_name = name_from_hcs_orient_vcs(name_from_hcs_orient_vcs(hcs, vcs=vcs), orient=orient) self.gxipj.set_gxf(gxf_name, s2.value, s3.value, s4.value, s5.value)
def get_attribute(self, attr_name): """ Retrieve an attribute setting. :param attr_name: attribute name (eg. '/my_metadata/parameters/frequency') :returns: attribute setting .. versionadded:: 9.3 """ if not self.has_attribute(attr_name): return None node, attr = self.node_attribute_token(attr_name) sr = gxapi.str_ref() self.gxmeta.get_attrib_string(node, attr, sr) try: i = int(sr.value) return i except ValueError: try: f = float(sr.value) return f except ValueError: if sr.value.startswith('__json__'): return json.loads(sr.value[8:]) return sr.value
def test_ESRI_cs(self): self.start(gsys.func_name()) stref = gxapi.str_ref() #test IPJ creation using GXF strings cs = gxcs.GXcs(['', 'DHDN', 'Okarito 2000', '', '']) cs.gxipj.get_esri(stref) self.assertTrue('PROJCS["Okari' in stref.value) self.assertTrue( 'GEOGCS["GCS_Deutsches_Hauptdreiecksnetz"' in stref.value) wkt = gxcs.Wkt(stref.value) self.assertEqual(wkt.name, 'Okarito_2000') cs = gxcs.GXcs(stref.value) gxfs = cs.get_gxf() self.assertEqual(gxfs[0], 'DHDN / *Okarito 2000') self.assertEqual(gxfs[1], 'DHDN,6377397.155,0.0816968312225274,0') self.assertEqual( gxfs[2], '"Transverse Mercator",-43.11,170.260833333333,1,400000,800000') self.assertEqual(gxfs[3], 'm,1') self.assertEqual( gxfs[4], '"DHDN to WGS 84 (1)",582,105,414,1.04,0.35,-3.08,8.29999999996112' ) gxcs.GXcs("WGS 84 / UTM zone 32N").gxipj.get_esri(stref) wkt = gxcs.Wkt(stref.value) self.assertEqual(wkt.name, 'WGS_1984_UTM_Zone_32N') gxcs.GXcs("WGS 84").gxipj.get_esri(stref) wkt = gxcs.Wkt(stref.value) self.assertEqual(wkt.name, 'GCS_WGS_1984')
def gxapi_gxvoxd(cls, gxapi_voxd, name=None): """ Create a VoxDisplay instance from a `geosoft.gxapi.GXVOXD` or a `geosoft.gxapi.GXVECTOR3D` instance. :param gxapi_voxd: `geosoft.gxapi.VOXD` or `geosoft.gxapi.GXVECTOR3D` instance :param name: name of the voxel, required for a vector voxel. .. versionadded 9.3.1 """ if isinstance(gxapi_voxd, gxapi.GXVOXD): if name is None: name = gxapi.str_ref() gxapi_voxd.get_name(name) name = name.value else: if not name: raise VoxDisplayException( _t('a name is required to open a GXVECTOR3D object')) try: vox = gxvox.Vox.open(name) except Exception: vox = None name = os.path.splitext(os.path.basename(name))[0] voxd = cls(vox, name=name) voxd._gxvoxd = gxapi_voxd return voxd
def get_plane_relief_surface_info(self, plane): """ Get relief surface parameters for a plane. :param plane: plane number or plane name :returns: relief surface properties :rtype: :class:`geosoft.gxpy.view.PlaneReliefSurfaceInfo` .. versionadded::9.2 """ if isinstance(plane, str): plane = self.plane_number(plane) surface_grid_name = gxapi.str_ref() sample = gxapi.int_ref() base = gxapi.float_ref() scale = gxapi.float_ref() min_ref = gxapi.float_ref() max_ref = gxapi.float_ref() self.gxview.get_plane_surface(plane, surface_grid_name) self.gxview.get_plane_surf_info(plane, sample, base, scale, min_ref, max_ref) refine = 1 + int(sample.value / 16) min_val = None if min_ref.value == gxapi.rDUMMY else min_ref.value max_val = None if max_ref.value == gxapi.rDUMMY else max_ref.value return PlaneReliefSurfaceInfo(surface_grid_name.value, refine, base.value, scale.value, min_val, max_val)
def run_gx(self, gx): """ Runs a GX. :param gx: GX name to run :returns: success, cancelled, exit_val, error_list, warning_list .. versionadded:: 9.6 """ exit_val = gxapi.int_ref() ret = gxapi.GXSYS.run_gx_ex(gx, exit_val) success = ret == 0 cancelled = ret == -1 error_list = [] warning_list = [] for i in range(0, gxapi.GXSYS.num_errors_ap()): err_no = gxapi.GXSYS.get_error_ap(i) err = gxapi.str_ref() gxapi.GXSYS.get_error_message_ap(i, err) if err_no < 0: warning_list.append(err.value) else: error_list.append(err.value) gxapi.GXSYS.clear_err_ap() return success, cancelled, exit_val.value, error_list, warning_list
def run_external_python(script, script_args='', python_args='', shared_dict=None, console=True, catcherr=True): """ Run a python script as an external program, returning results as a dictionary. External program calls gxpy.utility.get_shared_dict() to get the caller's dictionary, and gxpy.utility.set_shared_dict(return_dictionary) to return a dictionary back to caller. :param script: full path of the python script :param shared_dict: dictionary passed to the external script (get_shared_dict() to retrieve) :param script_args: command line arguments as a string :param python_args: command line arguments as a string :param console: True (default) will create a separate console for the process. :param catcherr: True (default) Catch and re-raise errors from the sub-process. :returns: dictionary passed back from caller via set_shared_dict(dict) .. versionadded:: 9.1 """ if not os.path.isfile(script): raise UtilityException(_t('Cannot find script: {}'.format(script))) py = sys.executable if not py.lower().endswith('python.exe'): s = gxapi.str_ref() gxapi.GXSYS.get_env('PYTHON_HOME', s) if not s.value: gxapi.GXSYS.get_directory(gxapi.SYS_DIR_GEOSOFT_PYTHON, s) py = os.path.join(s.value, 'python.exe') command = "\"{}\" {} \"{}\" {}".format(py, python_args, script, script_args) set_shared_dict(shared_dict) kwargs = {} if console: kwargs['creationflags'] = subprocess.CREATE_NEW_CONSOLE if hasattr(subprocess, 'run'): if catcherr: kwargs['stderr'] = subprocess.PIPE cp = subprocess.run(command, **kwargs) if catcherr and cp.returncode != 0: raise UtilityException( _t('\n\nExternal python error:\n\n{}').format( cp.stderr.decode("utf-8"))) else: # use call, python 3.4... err = subprocess.call(command, **kwargs) if catcherr and err != 0: raise UtilityException( _t('\n\nExternal python error({}) running: {}').format( err, command)) return get_shared_dict()
def _test_OBLIQUESTEREO_cs(self): self.start(gsys.func_name()) stref = gxapi.str_ref() cs = gxcs.GXcs( '{"type": "Geosoft", "datum":"NAD83,6378137,0.0818191910428158,0","projection":"\\"Oblique Stereographic\\",61.40.00,-128.10.00,1,0,0","units":"m,1","gxf5":"\\"NAD83 to WGS 84 (1)\\",0,0,0,0,0,0,0"}' ) cs.gxipj.get_display_name(stref) gxfs = cs.get_gxf() self.assertEqual(gxfs[0], 'NAD83 / *Oblique Stereographic') self.assertEqual(gxfs[1], 'NAD83,6378137,0.0818191910428158,0') self.assertEqual( gxfs[2], '"Oblique Stereographic",61.6666666666667,-128.166666666667,1,0,0') self.assertEqual(gxfs[3], 'm,1') self.assertEqual(gxfs[4], '"NAD83 to WGS 84 (1)",0,0,0,0,0,0,0') cs = gxcs.GXcs( '{"type": "Localgrid", "longitude":"-128.10.00","latitude":"61.40.00","azimuth":-15,"units":"ft"}' ) cs.gxipj.get_display_name(stref) gxfs = cs.get_gxf() self.assertEqual( gxfs[0], 'WGS 84 / *Local grid (61.40.00,-128.10.00) <0,0,0,0,0,-15>') self.assertEqual(gxfs[1], '"WGS 84",6378137,0.0818191908426215,0') self.assertEqual( gxfs[2], '"Oblique Stereographic",61.6666666666667,-128.166666666667,0.9996,0,0' ) self.assertEqual(gxfs[3], 'ft,0.3048') self.assertEqual(gxfs[4], '"WGS 84",0,0,0,0,0,0,0') cs = gxcs.GXcs( '{"type": "Localgrid", "longitude":"-128.10.00","latitude":"61.40.00","azimuth":-15,"units":"ft","elevation":133.1567}' ) cs.gxipj.get_display_name(stref) gxfs = cs.get_gxf() self.assertEqual( gxfs[0], 'WGS 84 / *Local grid [61.40.00,-128.10.00] <0,0,133.1567,0,0,-15>' ) self.assertEqual(gxfs[1], '"WGS 84",6378137,0.0818191908426215,0') self.assertEqual( gxfs[2], '"Oblique Stereographic",61.6666666666667,-128.166666666667,0.9996,0,0' ) self.assertEqual(gxfs[3], 'ft,0.3048') self.assertEqual(gxfs[4], '"WGS 84",0,0,0,0,0,0,0') cs = gxcs.GXcs('{"type": "Localgrid", "longitude":0,"latitude":0}') cs.gxipj.get_display_name(stref) gxfs = cs.get_gxf() self.assertEqual(gxfs[0], 'WGS 84 / *Local grid [0,0]') self.assertEqual(gxfs[1], '"WGS 84",6378137,0.0818191908426215,0') self.assertEqual(gxfs[2], '"Oblique Stereographic",0,0,0.9996,0,0') self.assertEqual(gxfs[3], 'm,1') self.assertEqual(gxfs[4], '"WGS 84",0,0,0,0,0,0,0')
def current_db_state(self): """ Return the state of the current database. :returns: dict of the current database state, {} if there is no current database. =================== ======================================================== 'disp_chan_list' list of displayed channels 'selection' current selection as (line, channel, start_fid, end_fid) =================== ======================================================== .. versionadded:: 9.2 """ sdb = {} if self.current_database: glst = gxapi.GXLST.create(4096) edb = gxapi.GXEDB.current_no_activate() n = edb.disp_chan_lst(glst) if n > 0: sdb['disp_chan_list'] = list(dict_from_lst(glst).keys()) else: sdb['disp_chan_list'] = [] s = gxapi.str_ref() sch = gxapi.str_ref() sln = gxapi.str_ref() sfd = gxapi.str_ref() edb.get_current_selection(s, sch, sln, sfd) if sch.value == '[All]': sch.value = '*' if sln.value == '[All]': sln.value = '*' if sfd.value == '[All]': fd = ('*', '*') elif sfd.value == "[None]": fd = ('', '') else: fd = sfd.value.split(' to ') fd = (fd[0], fd[1]) sdb['selection'] = (sln.value, sch.value, fd[0], fd[1]) return sdb
def orientation_name(self): """The name of an oriented section for display/reference purposes. .. versionadded:: 9.4 """ sr = gxapi.str_ref() self.gxipj.get_orientation_name(sr) return sr.value
def current_3d_drawing_plane(self): """Current drawing plane name in a 3D view, `None` if not defined. Can be set to a plane number or name.""" if len(self.plane_list): s = gxapi.str_ref() self.gxview.get_def_plane(s) return s.value else: return None
def trace_data_type(self): """ The data type of the trace data in the SEG-Y file. Specified using one of the constants defined in the `DataType` Enum. """ ref = gxapi.str_ref() self._gx_segy_reader.get_trace_data_type(ref) return DataType.from_str(ref.value)
def folder_workspace(): """ Return the Geosoft project folder name. .. versionadded:: 9.1 """ path = gxapi.str_ref() gxapi.GXSYS.get_path(gxapi.SYS_PATH_LOCAL, path) return path.value.replace('\\', os.sep)
def geosoft_version_micro(self): """ Geosoft micro version number. .. versionadded:: 9.3.2 """ i = gxapi.str_ref() gxapi.GXSYS.get_sys_info(gxapi.SYS_INFO_VERSION_SP, i) return int(i.value)
def geosoft_version_label(self): """ Geosoft version label. .. versionadded:: 9.3.2 """ i = gxapi.str_ref() gxapi.GXSYS.get_sys_info(gxapi.SYS_INFO_VERSION_LABEL, i) return i.value
def geosoft_build_number(self): """ Geosoft build numberl. .. versionadded:: 9.3.2 """ i = gxapi.str_ref() gxapi.GXSYS.get_sys_info(gxapi.SYS_INFO_BUILD_NUMBER, i) return int(i.value)
def geosoft_build_label(self): """ Geosoft build label. .. versionadded:: 9.3.2 """ i = gxapi.str_ref() gxapi.GXSYS.get_sys_info(gxapi.SYS_INFO_BUILD_LABEL, i) return i.value
def geosoft_name(self): """ Geosoft installed product name .. versionadded:: 9.3.2 """ i = gxapi.str_ref() gxapi.GXSYS.get_sys_info(gxapi.SYS_INFO_PRODUCTNAME, i) return i.value
def profile_url(self): """ Geosoft ID profile url in My Geosoft portal. .. versionadded:: 9.4 """ sr = gxapi.str_ref() gxapi.GXSYS.get_profile_url(sr) return sr.value
def profile_name(self): """ Geosoft ID profile use name. .. versionadded:: 9.4 """ sr = gxapi.str_ref() gxapi.GXSYS.get_profile_name(sr) return sr.value
def guid(self): """ The view GUID. .. versionadded:: 9.3 """ sr = gxapi.str_ref() self.gxview.get_guid(sr) return sr.value
def esri_wkt(self): """ ESRI Well-Known-Text (wkt) format coordinate string .. versionadded:: 9.3 """ sr = gxapi.str_ref() self._gxapi_ipj.get_esri(sr) return sr.value
def __init__(self, map, name="_unnamed_view", mode=WRITE_OLD, coordinate_system=None, map_location=(0, 0), area=(0, 0, 30, 20), scale=100, copy=None, gxmview=None, **kwargs): if not isinstance(map, geosoft.gxpy.map.Map): raise ViewException(_t('First argument must be a map.')) super().__init__(**kwargs) self._gx = gx.gx() self._map = map if gxmview is not None: name_ref = gxapi.str_ref() gxmview.get_name(name_ref) name = name_ref.value self._name = map.classview(name) self._gxview = gxmview else: self._name = map.classview(name) if mode == WRITE_OLD and not map.has_view(self._name): mode = WRITE_NEW self._gxview = gxapi.GXMVIEW.create(self._map.gxmap, self._name, mode) self._mode = mode self._lock = None self._open = True self._cs = None self._clip_mode = False if mode == WRITE_NEW: self.locate(coordinate_system, map_location, area, scale) if copy: with View(map, name=copy, mode=READ_ONLY) as v: v.gxview.mark_all_groups(1) v.gxview.copy_marked_groups(self.gxview) else: ipj = gxapi.GXIPJ.create() self.gxview.get_ipj(ipj) self._cs = gxcs.Coordinate_system(ipj) metres_per = self._cs.metres_per_unit self._uname = self._cs.units_name if metres_per <= 0.: raise ViewException( _t('Invalid units {}({})'.format(self._uname, metres_per))) self._metres_per_unit = 1.0 / metres_per
def folder_user(): """ Return the Geosoft user configurations folder name. .. versionadded:: 9.1 """ path = gxapi.str_ref() gxapi.GXSYS.get_path(gxapi.SYS_PATH_GEOSOFT_USER, path) return path.value.replace('\\', os.sep)
def cs_name(self, what=NAME): """ Return requested name. :param what: | NAME | NAME_HCS | NAME_VCS | NAME_HCS_VCS | NAME_PROJECTION | NAME_METHOD | NAME_DATUM | NAME_ELLIPSOID | NAME_LDATUM | NAME_UNIT | NAME_UNIT_FULL | NAME_TYPE | NAME_LLDATUM | NAME_METHOD_PARMS | NAME_METHOD_LABEL | NAME_DATUM_PARMS | NAME_LDATUM_PARMS | NAME_GEOID | NAME_LDATUMDESCRIPTION | NAME_METHOD_PARMS_NATIVE | NAME_ORIENTATION If 'what' is not specified, gxipj.NAME assumed, which returns the coordinate system display name. :return: The name requested .. versionadded:: 9.2 """ s = gxapi.str_ref() if what == NAME: self.gxipj.get_display_name(s) return s.value else: csname, *_ = self.get_gxf() hcs, orient, vcs = hcs_orient_vcs_from_name(csname) if what == NAME_HCS_VCS: return name_from_hcs_orient_vcs(hcs, orient, vcs) if what == NAME_HCS: return name_from_hcs_orient_vcs(hcs, orient, None) if what == NAME_VCS: return vcs if what == NAME_DATUM: return hcs.split('/')[0].strip() if what == NAME_PROJECTION: if '/' in hcs: return hcs.split('/')[1].strip() else: return '' self.gxipj.get_name(what, s) return s.value