ENVI/IDL——Java-IDL Export Bridge

任务:

要把一堆遥感图片每一个像素点所对应的波段值和经纬度等信息统一插入到数据库中,以方便查询管理。


技术试探:

上一篇博文http://blog.csdn.net/niaokedaoren/article/details/8881620,只是试探性的用代码读取波段值和经纬度。

但是要处理多幅图片,势必要在几个文件夹之间游走,IDL在这方面貌似比较乏力;同时IDL虽然支持数据库的链接,

貌似是ODBC,但是感觉不好用。于是尝试用IDL和Java混编的形式,来完成这个任务。在IDL的help文档里面确实

提到了这个技术。


又一个helloworld

最好在写之前去看看IDL的help文档,在IDL Programmers' Guides->IDL Connectivity Bridges这一节当中。

在干具体任务之前,我先试验了一下help文档中例子helloworld,貌似helloworld无处不在,呵呵。

1. 配置环境

我用的是win7, classpath变量中加上:ENVI_DIR\ENVI\IDL71\resource\bridges\export\java\javaidlb.jar


2. 编写procedure

一个小的类

function helloword::init
  return, 1
end

pro helloworld__define
  struct = {helloworld, $
    dummy:0b $
  }
end


3.包装成java类

在IDE的命令行下输入命令: ENVI> IDLEBR_ASSISTANT

就会出来一个叫Export Bridge Assistant的窗口

具体操作看help文档吧,很详细的。

生成的代码:

// This code has been generated by the code Wizard and should not be
// modified.  The recommended manner of changing the behavior is to
// implement a class that inherits from this generated class.

package helloworld;

import com.idl.javaidl.*;

public class helloworld extends JIDLObject
{
   // Constants set by Wizard
   private static String IDL_CLASS = "helloworld";
   private static String OPS_NAME  = "Default_Process_Name";

   // Constructor
   public helloworld() {
      super(IDL_CLASS, OPS_NAME);
   }

   // properties generated by Wizard

   // class methods generated by Wizard

}

4.用java调用

测试代码:

package helloworld; 
import com.idl.javaidl.*; 
public class helloworld_example extends helloworld 
implements JIDLOutputListener 
{ 
   private helloworld hwObj; 
 
   // Constructor 
   public helloworld_example() { 
      hwObj = new helloworld(); 
      hwObj.createObject(); 
      hwObj.addIDLOutputListener(this); 
      hwObj.executeString("print, 'Hello World'"); 
   } 
 
   // implement JIDLOutputListener 
   public void IDLoutput(JIDLObjectI obj, String sMessage) { 
      System.out.println("IDL: "+sMessage); 
   } 
 
   public static void main(String[] argv) { 
      helloworld_example example = new helloworld_example(); 
   } 
}

编译了一下,运行,直接报错:

Exception in thread "main" com.idl.javaidl.JIDLException[iErr=-999 sMsg=Attempt
to call undefined procedure/function: 'HELLOWORLD__DEFINE'.]
        at com.idl.javaidl.JIDLPAL.nativeThrowJIDLException(Native Method)
        at com.idl.javaidl.JIDLPAL.throwSpecificException(JIDLPAL.java:1073)
        at com.idl.javaidl.JIDLPAL.throwJIDLException(JIDLPAL.java:1102)
        at com.idl.javaidl.JIDLPAL.createObject(JIDLPAL.java:382)
        at com.idl.javaidl.JIDLPAL.createObject(JIDLPAL.java:318)
        at com.idl.javaidl.JIDLObject.createObject(JIDLObject.java:193)
        at com.idl.javaidl.JIDLObject.createObject(JIDLObject.java:103)
        at helloworld.helloworld_example.<init>(helloworld_example.java:11)
        at helloworld.helloworld_example.main(helloworld_example.java:22)

解决方案:

问题的原因是IDL的search PATH下根本找不到刚才编写的那个pro,要知道被包装成java类的东东是不干实事的,它是通过调用pro

来返回结果。我尝试用 > PREF_SET, 'IDL_PATH', 'ADD_DIR;<IDL_DEFAULT>', /COMMIT

没有加成,所以干脆简单暴力,直接将helloworld__define.pro文件拷贝到ENVI\IDL71\lib下面,当然可以在下面建一个local什么的文件夹,

统一放自己的pro。


Can't be resolved

做了几个例子的实验,心里开始有底了,就着手完成真正的任务。

但是有时候,现实往往比想象中更加残酷。

诸如ENVI_FILE_OPEN, ENVI_FILE_QUERY, ENVI_GET_SLICE等ENVI_*形式的routine报出:Warning ... can not be resolved

这显然很正常,因为这些是ENVI提供的,不是IDL提供的API。

是你逼我用绝招的,再次使用google大法,苍天不负有心人啊,

请看神作:http://www.exelisvis.com/Company/PressRoom/TabId/190/ArtMID/786/ArticleID/4302/4302.aspx

一切显得如此顺利,O(∩_∩)O哈哈~

function DataExtractor::init
  compile_opt STRICTARR
  pathInfo = routine_info('dataextractor__define', /SOURCE)
  sourceCodeDir = file_dirname(pathInfo.path)
  cd, sourceCodeDir
  ; Basic ENVI startup routines
  enviLogFile = filepath('DataExtractor.log', ROOT_DIR=sourceCodeDir)
  call_procedure, "ENVI", /RESTORE_BASE_SAVE_FILES
  call_procedure, "ENVI_BATCH_INIT", LOG_FILE=enviLogFile
  return, 1
end

function DataExtractor::openFile, filename
  if (n_elements(filename) ne 0) then begin
    call_procedure, "ENVI_OPEN_FILE", filename, r_fid=fid, $
      /no_realize, /no_interactive_query
  endif else begin
    call_procedure, "ENVI_BATCH_EXIT"
    return, -1
  endelse
  if (fid eq -1) then begin
    call_procedure, "ENVI_BATCH_EXIT"
    return, -1
  endif
  self.fid = fid
  return, self.fid
end

function DataExtractor::closeFile
  call_procedure, "ENVI_FILE_MNG", id=self.fid, /remove
end

function DataExtractor::getMapInfo
  call_procedure, "ENVI_FILE_QUERY", self.fid, nl=nl, ns=ns, nb=nb
  self.mapInfo[0] = nl
  self.mapInfo[1] = ns
  self.mapInfo[2] = nb
  return, self.mapInfo 
end


function DataExtractor::getBands, x, y
  pos = lindgen(self.mapInfo[2])
  data = call_function("ENVI_GET_SLICE", fid=self.fid, line=y, pos=pos, $
    xs=x, xe=x, /bip)
  return, data
end

function DataExtractor::getLocation, x, y
  iproj = call_function("ENVI_GET_PROJECTION", fid=self.fid)
  oproj = call_function("ENVI_PROJ_CREATE", /geographic)
  call_procedure, "ENVI_CONVERT_FILE_COORDINATES", $
    self.fid, x, y, xmap, ymap, /to_map
  call_procedure, "ENVI_CONVERT_PROJECTION_COORDINATES", $
    xmap, ymap, iproj, oxmap, oymap, oproj
  location = dblarr(2)
  location[0] = oxmap
  location[1] = oymap
  return, location
end

pro DataExtractor__define
  struct = { $
    DataExtractor, $
    mapInfo: intarr(3), $
    fid: 0 $
  }
end


数据库那一块就简单多了,那是熟悉的java干的事情,等明后天搞吧,呵呵,未完待续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值