B.1 空間プロバイダ・クラスの実装

空間プロバイダ・クラス・インタフェースを実装する必要があります。

このプロバイダには、「カスタム・ジオメトリ・テーマ」に示されているクラス・インタフェースを実装する必要があります。例B-1に、提供されているデモ内にある空間プロバイダのコードの抜粋を示します。このサンプル・コードは意図的に簡略化されており、最適化されたものではありません。このプロバイダではどのような空間索引メカニズムも作成されません。

プロバイダのコードを実装したら、コードをコンパイルしてコンパイル済クラスを含むjarファイルを生成します。demoディレクトリのspatialprovider.jarファイルに、このサンプル・コードのコンパイル済バージョンが含まれているので、それを直接使用できます。このjarファイルをマップ・ビジュアライゼーション・コンポーネントのCLASSPATH定義に指定されているディレクトリ(web/WB-INF/libなど)にコピーします。

例B-1 空間プロバイダ・クラスの実装

package spatialprovider.samples;
 
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.util.ArrayList;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import oracle.mapviewer.share.Field;
import oracle.mapviewer.share.ext.SDataProvider;
import oracle.mapviewer.share.ext.SDataSet;
import oracle.mapviewer.share.ext.SObject;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import oracle.spatial.geometry.JGeometry;
import oracle.spatial.util.GML;
 
public class CustomSpatialProviderSample implements SDataProvider
{
 ...
 
 /**
  * Constructor.
  */
 public CustomSpatialProviderSample()
 {
   ...
 }
 
 /**
  * Returns the initialization parameters for the provider.
  * The "datadir" parameter should be registered in the map visualization component
  * configuration file and can be used to access the data.
  * @return
  */
 public String[] getInitParameterNames()
 {
   return new String[]{ "datadir" };
 }
 
 /**
  * Returns runtime parameter names. Runtime parameters are additional parameters
  * that the provider may use when retrieving the data objects.
  * @return
  */
 public String[] getRuntimeParameterNames()
 {
   return new String[]{ "filename" };
 }
 
 /**
  * Initializes the provider
  * @param params  init properties
  * @return
  */
 public boolean init(Properties params)
 {
   dataDirectory = null;
     if(params == null)
     return true;
     dataDirectory = params.getProperty("datadir");
   if(dataDirectory == null || dataDirectory.trim().length() == 0)
   {
     // try upper case
     dataDirectory = params.getProperty("DATADIR");
     if(dataDirectory == null || dataDirectory.trim().length() == 0)
       System.out.println("FINE: Init properties does not define \"datadir\" parameter.");
   }
       return true;
 }
 
 /**
  * Returns the data set (geometries plus attributes) that intersects the
  * query window. In this sample the data is parsed just once and
  * there is no spatial index for searching. The search is sequential.
  * @param queryWin  search area
  * @param nonSpatialColumns   attribute columns
  * @param params      runtime properties
  * @return
  */
 public SDataSet buildDataSet(Rectangle2D queryWin,
                              String []nonSpatialColumns,
                              Properties params)
 {
   if(!dataParsed)
   {
     dataParsed = parseData(params);
     if(!dataParsed)
       return null;
   }
     if(geometries.size() == 0)
     return null;
 
   SDataSet dataset = new SDataSet();
     boolean fullExtent = isFullExtent(queryWin);
     if(fullExtent)
   {
     for(int i=0;i<geometries.size();i++)
     {
       JGeometry geom = (JGeometry)geometries.get(i);
       SObject obj = new SObject(geom,getGeometryAttributes(nonSpatialColumns,i));
       dataset.addObject(obj);      }
   }
   else
   {
     for(int i=0;i<geometries.size();i++)
     {
       JGeometry geom = (JGeometry)geometries.get(i);
       double []mbr = geom.getMBR();
       if(mbr == null)
         continue;
       Rectangle2D.Double rect = new Rectangle2D.Double(mbr[0],mbr[1],
                                   mbr[2]-mbr[0],
                                   mbr[3]-mbr[1]);
             if(rect.getWidth() == 0. && rect.getHeight() == 0.)
       {
         Point2D.Double pt = new Point2D.Double(mbr[0],mbr[1]);
         if(queryWin.contains(pt))
         {
           SObject obj = new SObject(geom,getGeometryAttributes(nonSpatialColumns,i));
           dataset.addObject(obj);                    }
       }
       else if(queryWin.contains(rect) || queryWin.intersects(rect))
       {
         SObject obj = new SObject(geom,getGeometryAttributes(nonSpatialColumns,i));
         dataset.addObject(obj);
       }
     }        }
     if(dataset.getSize() == 0)
     return null;
       return dataset;
 }
 
 /**
  * Returns the data provider attribute list.
  * @return
  */
 public Field[] getAttributeList(Properties params)
 {
   if(!dataParsed)
   {
     dataParsed = parseData(params);
     if(!dataParsed)
       return null;
   }
     if(attributes.size() == 0)
     return null;
 
   return (Field[])attributes.toArray(new Field[attributes.size()]);
 }
 
 /**
  * Returns the data extents.
  * @return
  */
 public Rectangle2D getDataExtents(Properties params)
 {
   if(!dataParsed)
   {
     dataParsed = parseData(params);
     if(!dataParsed)
       return null;
   }
     if(extents == null || extents.length < 4)
     return null;
   else
     return new Rectangle2D.Double(extents[0],extents[1],
                                   extents[2]-extents[0],
                                   extents[3]-extents[1]);
 }
 
 /**
  * Builds a spatial index for the data. In this sample there is no
  * spatial index. The data is loaded into memory when data is parsed.
  * @return
  */
 public boolean buildSpatialIndex(Properties params)
 {
   return true;
 }
 
}