package com.esri.aims.mtier.model.util;

/**
 * <p>Title:SVG Generator </p>
 * <p>Description: Convert coordinations from ArcXML response to SVG
format</p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: ESRI </p>
 * @author unascribed
 * @version 1.0
 */

import java.util.Vector;
import java.lang.Math;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.File;
import com.esri.aims.mtier.io.ConnectionProxy;
import com.esri.aims.mtier.model.map.Map;
import com.esri.aims.mtier.model.map.layer.query.GeometryRecordset;
import com.esri.aims.mtier.model.acetate.Point;
import com.esri.aims.mtier.model.acetate.Points;
import com.esri.aims.mtier.model.acetate.Ring;
import com.esri.aims.mtier.model.acetate.Path;
import com.esri.aims.mtier.model.acetate.Polyline;
import com.esri.aims.mtier.model.acetate.Polygon;
import com.esri.aims.mtier.model.acetate.Line;
import com.esri.aims.mtier.model.acetate.Hole;
import com.esri.aims.mtier.model.map.layer.FeatureLayer;

import com.esri.aims.mtier.model.map.layer.query.Filter;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: </p>
 * @author unascribed
 * @version 1.0
 */

public class SVGGenerator {
  public final String POLYGON="polygon";
  public final String LINE="line";
  public final String POINT="point";

//connection to arcIMS app server
  private ConnectionProxy connection;
//array of the layer ID that the user wants to write into SVG
  private String[] layerList;
//the layer that is drawn if only one layer is drawn, or the layer that
has event if multiple layers are drawn
  private String activeLayer;
//whereexpression for the activelayer is a query is desired, "" is for
all the features in the layers
  private String whereExpression;
//how many digital after period are reserved, 10000 reserves 4
  private final double PRECISION=10000;
//the ratio between radius of a point circle/width of the viewbox
  private final double RATIO=0.01;
//coordinate from the map envelope
  private double minx, miny, maxx, maxy;
//style of the point
  private String pointStyle="fill=\"green\"";
  private String polygonStyle="fill=\"lightgray\" stroke=\"black\"
stroke-width=\"5\"";
  private String lineStyle="fill=\"none\" stroke=\"blue\"
stroke-width=\"800\"";

  public SVGGenerator(){
  }

  public SVGGenerator(ConnectionProxy con, String[] layerlist, String
activelayer, String where){
    connection=con;
    activeLayer=activelayer;
    whereExpression=where;
    layerList=layerlist;
  }

  public void setConnectionProxy(ConnectionProxy conn){
    connection=conn;
  }
  public void setLayerlist(String[] layers){
    layerList=layers;
  }

  public void setActiveLayer(String act){
    activeLayer=act;
  }

  public void setWhereExpression(String where){
    whereExpression=where;
  }

  private String buildRequest(String layerID){
    String returnfields="#SHAPE#";
    if (layerID.equalsIgnoreCase(activeLayer)) returnfields="#ALL#";

    StringBuffer arcXMLRequest=new StringBuffer("<?xml version=\"1.0\"
encoding=\"UTF-8\"?>");
    arcXMLRequest.append("<ARCXML version=\"1.1\">");
    arcXMLRequest.append("<REQUEST><GET_FEATURES outputmode=\"newxml\"
compact=\"false\">");
    arcXMLRequest.append("<LAYER id=\"");
    arcXMLRequest.append(layerID);
    arcXMLRequest.append("\"/>");
    arcXMLRequest.append("<SPATIALQUERY  subfields=\""+ returnfields
+"\" >");
    arcXMLRequest.append("<SPATIALFILTER relation =\"area_intersection\"
> ");
    arcXMLRequest.append("<ENVELOPE minx =\""+minx+ "\" miny=\""+ miny+
"\" ");
    arcXMLRequest.append(" maxx=\"" + maxx + "\" maxy=\"" +maxy + "\"
/>");
    arcXMLRequest.append("</SPATIALFILTER></SPATIALQUERY>");
    arcXMLRequest.append("</GET_FEATURES></REQUEST></ARCXML>");
    return arcXMLRequest.toString();
  }

  private void test(Map map){
    FeatureLayer fLayer = (FeatureLayer)map.getLayers().item(3);
    Filter filter = new Filter();
    filter.setWhereExpression(whereExpression);
    filter.setBoundingEnvelope(true);
    filter.setCheckesc(true);
    fLayer.setFilterObject(filter);
    System.out.println(fLayer.getRecordset().getEnvelopeCount());
  }
  private String getGeometry(){
    Map map = new Map();
    try {
      map.initMap(connection,0,false,false,false,false);
      }catch( Exception e){}

      //get the extent of the queried area, initialize minx,miny..
      getExtent(map);
//    map.getLayers().setGeometry(true);    //to get the geometry of the
features returned by the query
      GeometryRecordset geometry = new GeometryRecordset();
      String svgbody="";
      for (int i=0; i<layerList.length;i++){
        Vector v = new Vector();
        v =
geometry.getGeometry(connection,buildRequest(layerList[i]),null);
        FeatureLayer l=null;
       for(int j=0; j<map.getLayers().getCount();j++){
         if
(map.getLayers().item(j).getID().equalsIgnoreCase(layerList[i])){
           l=(FeatureLayer)map.getLayers().item(j);
           break;
         }
       }

       if (l!=null){
         if (l.getFeatureClass().equals(POLYGON)) {
           svgbody=svgbody+buildPolygonSVG(v);
         }else if (l.getFeatureClass().equals(LINE)) {
           svgbody=svgbody+buildLineSVG(v);
         }else if (l.getFeatureClass().equals(POINT)) {
           svgbody=svgbody+buildPointSVG(v);
         }
         //   System.out.println(svgbody);
         System.out.println(l.getFeatureClass() + v.size());
       }
      }
      return svgbody;
  }

  //get the extent of the queried area, initialize minx,miny..
  private void getExtent(Map map){
    /*this is the initial-extent, if the queried space is much small,
then there will be large empty space
    write a function to get the extent of the queried area
    minx=map.getEnvelope().getMinX();
    miny=map.getEnvelope().getMinY();
    maxx=map.getEnvelope().getMaxX();
    maxy=map.getEnvelope().getMaxY();
*/
    String request, response;
    request="<?xml version=\"1.0\" encoding=\"UTF-8\"?><ARCXML
version=\"1.1\">";
    request=request + "<REQUEST><GET_FEATURES attributes=\"false\"
geometry=\"false\" ";
    request=request+ " envelope=\"false\"  globalenvelope = \"true\"
outputmode=\"xml\">";
    request=request + "<LAYER id=\"";
    request=request + activeLayer;
    request=request + "\"/>";
    request=request + "<SPATIALQUERY  where=\"";
    request=request + whereExpression + "\"/>";
    request=request + "</GET_FEATURES></REQUEST></ARCXML>";
    response=map.sendArcXML(request,Map.GET_FEATURE);
 //   System.out.print("\n"+response+"\n");
    int ix=response.indexOf("minx");
    int iy=response.indexOf("miny");
    int ax=response.indexOf("maxx");
    int ay=response.indexOf("maxy");
    int f=response.indexOf("</FEAT");
    minx=Double.parseDouble(response.substring(ix+6,iy-2 ));
    miny=Double.parseDouble(response.substring(iy+6, ax-2));
    maxx=Double.parseDouble(response.substring(ax+6,ay-2));
    maxy=Double.parseDouble(response.substring(ay+6,f-5));
 //if only one point, then envelope is 0
    if (minx==maxx && miny==maxy){
      double
grow=(map.getEnvelope().getMaxX()-map.getEnvelope().getMinX())/1000;
      minx=minx-grow;
      maxx=maxx+grow;
      miny=miny-grow;
      maxy=maxy+grow;
    }
  }


//no hole yet
  private String buildPolygonSVG(Vector v){
    StringBuffer body=new StringBuffer("");
    for (int i=0; i<v.size(); i++){
      Polygon pol=(Polygon)v.get(i); //each polygon =ring group,=ploygon
group
      body.append(" <g id=\"" + i + "\" ");
      body.append(polygonStyle + ">");
      for (int j=0; j<pol.getRingsCount(); j++){ //for each ring
        Ring ring=pol.getRing(j);
        body.append("<polygon points=\"");
        Points ps=ring.getPoints();
  //      System.out.println("Ring "+ j +" count= "+ps.getCount());
 //       int step=Math.max(1,(int)ps.getCount()/100);
        int step=2;
        for (int k=0; k< ps.getCount(); k+=step){
          long x=convertX(ps.getPointObject(k).getX());
          long y=convertY(ps.getPointObject(k).getY());
          body.append(x+","+y+" ");
        }
        body.append("\"/>" );//end of <polygon>
      }
      body.append("</g>\n");
    }
    return body.toString();
  }

  private String buildLineSVG(Vector v){
    StringBuffer body=new StringBuffer("");
    for (int i=0; i<v.size();i++){
      Polyline pl=(Polyline)v.get(i);
      body.append(" <g id=\"" + i + "\" ");
      body.append(lineStyle + ">");
      for(int j=0;j<pl.getPathCount();j++){
        Path p= pl.getPath(j);
        body.append("<polyline points=\"");
        Points ps=p.getPoints();
        int step=Math.max(1,(int)ps.getCount()/100);
        for (int k=0;k<ps.getCount();k++){
          long x=convertX(ps.getPointObject(k).getX());
          long y=convertY(ps.getPointObject(k).getY());
          body.append(x+","+y+" ");
        }
        body.append("\" />");
      }
      body.append("</g>\n");
    }
    return body.toString();
  }

  private String buildPointSVG(Vector v){
    StringBuffer body=new StringBuffer("<g " + pointStyle + ">");
    long r=java.lang.Math.round((maxx-minx)*PRECISION*RATIO);
    if(r<=0) r=1;
    for (int i=0; i<v.size(); i++){
      Points ps=(Points)v.get(i);
      long x=  convertX(ps.getPointObject(0).getX());
      long y=  convertY(ps.getPointObject(0).getY());
      body.append("<circle cx=\"" + x + "\" cy=\"" + y +"\" r=\"" + r
+"\"/>");
    }
    body.append("</g>");
    return body.toString();
  }

  private long convertX(double x){
    return java.lang.Math.round((x-minx)*PRECISION);
  }

  private long convertY(double y){
    return java.lang.Math.round((maxy-y)*PRECISION);
  }

  public void writeSVGToFile(String filename){
    String str=getSVGString();
    writeFile(filename, str);
  }

   public String getSVGString() {
//check validity, eg. activelayer<0 or >map.getLayers().getCount(),
throw exception
    long start=System.currentTimeMillis();
    String svgBody=getGeometry();
    String str;
    long width= java.lang.Math.round((maxx-minx)*PRECISION);
    long height=java.lang.Math.round((maxy-miny)*PRECISION);

    str="<svg width=\"600\" height=\"400\" viewBox=\"0 0 "+width +" "+
height+"\">";
    str=str + "\n"+svgBody + "</svg>";

    return str;
 }

 private void writeFile(String filename, String svg){
   try{
     File f=new File(filename);
     FileOutputStream fw=new FileOutputStream(f);
     if (!f.exists()){
       f.createNewFile();
     }
     byte[] byt=svg.getBytes("UTF-8");
     fw.write(byt);

  }catch(Exception e){}
 }
 /* public static void main(String[] args) {
    SVGGenerator a =new SVGGenerator();
    System.out.println(a.getRequest());

  }*/
}

-----Original Message-----
From: svg-developers@yahoogroups.com
[mailto:[EMAIL PROTECTED] On Behalf Of Carroll, Brendan M.
Sent: Wednesday, April 20, 2005 8:57 AM
To: svg-developers@yahoogroups.com
Subject: RE: [svg-developers] Re: IBM DB2 Spatial and SVG?


If you're planning to pull directly from ArcIMS via SDE and ST_Geometry,
you could use something like this.

BC

-----Original Message-----
From: svg-developers@yahoogroups.com
[mailto:[EMAIL PROTECTED] On Behalf Of Andreas Neumann
Sent: Wednesday, April 20, 2005 6:12 AM
To: svg-developers@yahoogroups.com
Subject: [svg-developers] Re: IBM DB2 Spatial and SVG?



Hi Barend and Armin, 
 
thanks for your answers. 
 
The plan is to do a Arc/IMS alternative in SVG. I plan to use ArcIMS 
for the getting raster data but want to directly produce SVG from 
IBM DB2 or ArcSDE. To be honest, I don't have knowledge about 
ArcSDE. I just know that it is a database abstraction layer in ESRI. 
ArcGIS won't be involved. I already know how to output SVG from 
PostgreSQL, but unfortunately, in that project, I am forced to use 
DB2. 
 
The question was if someone already did a SVG export as an IBM DB2 
extension. If not, I would probably go through the WKT format that 
can be output by DB2, as Barend suggested. 
 
Thanks, 
Andreas 
 
--- In svg-developers@yahoogroups.com, "Armin Mueller" 
<[EMAIL PROTECTED]> wrote: 
> Andreas, 
>  
> Do you use ArcGIS to interact with SDE? If so it is no difference 
to convert 
> a shapefile or a SDE file. Otherwise it is not so easy or not at 
all 
> practicable because SDE writes ist information in several tables, 
the 
> structure of these handling is not known in detail. 
>  
> Armin 
>  
> -----Original Message----- 
> From: svg-developers@yahoogroups.com 
[mailto:[EMAIL PROTECTED] 
> On Behalf Of Andreas Neumann 
> Sent: Wednesday, April 20, 2005 9:57 AM 
> To: svg-developers@yahoogroups.com 
> Subject: [svg-developers] IBM DB2 Spatial and SVG? 
>  
>  
>  
> Hi all,  
>   
> Anyone knows resources on how to convert data from IBM DB2 spatial 
extension 
> or ESRI ARC SDE to SVG?  
>   
> I have to use DB2 and ArcSDE in one of my projects and am looking 
for a 
> solution how to convert the data to SVG.  
>   
> Thanks, 
> Andreas  
>  
>  
> 





-----
To unsubscribe send a message to:
[EMAIL PROTECTED]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my
membership"
---- 
Yahoo! Groups Links



 






[Non-text portions of this message have been removed]



-----
To unsubscribe send a message to:
[EMAIL PROTECTED]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my
membership"
---- 
Yahoo! Groups Links



 






-----
To unsubscribe send a message to: [EMAIL PROTECTED]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my 
membership"
---- 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/svg-developers/

<*> To unsubscribe from this group, send an email to:
    [EMAIL PROTECTED]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Reply via email to