geodetic buffers with geotools

sometimes you need a sphere or even better an ellipsoid…

Clipboard01

the above images shows several point buffers all with a radius of 500 km… web mercator at it’s best…

Following two quick hacks for a Maven/geotools environment. For more details on setting up geotools with maven look at this tutorial…

simple java application producing GeoJSON polygon using geotools JSON encoder

this example produces a point buffer, but you can use the built in line-buffer as well. A sample linestring (line) is included… Note that the linebuffer- implementation is just a draft… far from correct, but it delivers robust results for straight lines.

import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;

import javax.xml.transform.TransformerException;

import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.xml.sax.SAXException;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;

public class TestGeodetic {

 public static Geometry getGeodeticPointBuf(Double lon, Double lat, int rad)
 {
 //calculate on WGS84 ellipsoid
 GeodeticCalculator calc = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
 calc.setStartingGeographicPoint(lon, lat);
 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null );
 ArrayList<Coordinate> coords = new ArrayList<Coordinate>();

 //create 50 points with polar coordinates (angle+distance) and add to ArrayList - TODO increase point amount when radius increases...
 for (int i = 0; i < 50; i++)
 {
 int angle = (i * 360 / 50);
 if (angle>=180){angle = angle-360;}
 calc.setDirection(angle, rad);
 Point2D dest = calc.getDestinationGeographicPoint();
 coords.add(new Coordinate(dest.getX(),dest.getY(),0));

 }
 coords.add(coords.get(0)); //close ring

 Coordinate[] coords1 = new Coordinate[coords.size()];
 coords1 = coords.toArray(coords1);

 LinearRing ring = geometryFactory.createLinearRing( coords1 );
 LinearRing holes[] = null; // use LinearRing[] to represent holes
 Polygon polygon = geometryFactory.createPolygon(ring, holes );

 return polygon;
 }

 public static Geometry getGeodeticLineBuf(Geometry inline, int dist)
 {
 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null );
 GeodeticCalculator calc = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
 Coordinate[] subsat_points = inline.getCoordinates();

 ArrayList<Coordinate> hull_right = new ArrayList<Coordinate>();
 ArrayList<Coordinate> hull_left = new ArrayList<Coordinate>();
 for (int i = 0; i < subsat_points.length-1; i++)
 {

 calc.setStartingGeographicPoint(subsat_points[i].x,subsat_points[i].y);
 calc.setDestinationGeographicPoint(subsat_points[i+1].x,subsat_points[i+1].y);
 double angle = calc.getAzimuth();

 if (angle<=-90 ){angle = angle+180;}
 if (angle>=90 ){angle = angle-180;}
 calc.setStartingGeographicPoint(subsat_points[i].x,subsat_points[i].y);
 calc.setDirection(angle+90,dist);
 Point2D dest1 = calc.getDestinationGeographicPoint();
 hull_right.add(new Coordinate(dest1.getX(),dest1.getY(),0));
 calc.setDirection(angle-90, dist);
 Point2D dest2 = calc.getDestinationGeographicPoint();
 hull_left.add(new Coordinate(dest2.getX(),dest2.getY(),0));

 }
 Collections.reverse(hull_left);

 ArrayList<Coordinate> hull = new ArrayList<Coordinate>();
 hull.addAll(hull_right);
 hull.addAll(hull_left);
 hull.add(hull_right.get(0)); //close ring
 Coordinate[] hull1 = new Coordinate[hull.size()];
 hull1 = hull.toArray(hull1);

 LinearRing ring = geometryFactory.createLinearRing( hull1 );

 LinearRing holes[] = null; // use LinearRing[] to represent holes
 Polygon polygon = geometryFactory.createPolygon(ring, holes );

 return polygon;

 }

public static void main(String[] args) throws IOException, SAXException, TransformerException
{

 //create test-line... for linebuffers
 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );

Coordinate[] coords =
 new Coordinate[] {new Coordinate(-71, 52.6), new Coordinate(-56, 66), new Coordinate(-49, 73),new Coordinate(-40, 75), new Coordinate(-35, 85) };
 @SuppressWarnings("unused")
 LineString line = geometryFactory.createLineString(coords);

 SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

//set the name
 b.setName( "geodetic-buffer" );

//add some properties - just a template
 //b.add( "a", String.class );
 //b.add( "b", String.class );
 //b.add( "c", String.class );
 //b.add( "d", String.class );

 //add a geometry property
 b.setCRS( DefaultGeographicCRS.WGS84 ); // set crs first
 b.add( "geom", Polygon.class ); // then add geometry

//build the type
 final SimpleFeatureType FLAG = b.buildFeatureType();
 //
 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(FLAG);

DefaultFeatureCollection poly_out = new DefaultFeatureCollection("internal",FLAG);
 //Line buffer
 //builder.add(getGeodeticLineBuf(line, 200000));

 //point buffer with 500000 meters
 builder.add(getGeodeticPointBuf(-50.3333, 66.5, 500000));

 SimpleFeature feature_out = builder.buildFeature(null);
 poly_out.add(feature_out);

 FeatureJSON fjson = new FeatureJSON();
 fjson.isEncodeFeatureCollectionCRS();
 StringWriter writer = new StringWriter();
 fjson.writeFeatureCollection(poly_out, writer);

 System.out.println(writer.toString().replace("\"properties\":", "\"properties\":{")); //tweak to produce valid geoJSON

}

}

geodetic point buffer as servlet without geotools JSON encoder (faster)

this servlet produces some GeoJSON for usage in a webapp e.g. ol3… Your request could look like http://yourdomain.com/GeodeticCircle?&lon=50.05257&lat=%20-27.91024&dist=500

response:


{
 "type" : "Polygon",
 "coordinates" : [[[50.05257, -23.39691514099216], [50.81729625396115, -23.450400161188764], [51.565142999703205, -23.60966376988598], [52.27950095965239, -23.87115272264491], [52.94430066379978, -24.22901487736714], [53.54428141982014, -24.675202669272224], [54.065260902584455, -25.19961551117886], [54.49440783160426, -25.790279456676938], [54.82052095616245, -26.433562922038107], [55.03431721008193, -27.114428081084437], [55.12872984685988, -27.816718485923438], [55.099213192896336, -28.523484166216896], [54.94404424451737, -29.217345478220302], [54.664603059566836, -29.880895852665123], [54.265604801971044, -30.497140951777368], [53.75524819424773, -31.04996743309319], [53.1452404735973, -31.524628742137907], [52.45066039974901, -31.908228813772958], [51.68963051111196, -32.19017844843427], [50.882788164856144, -32.362594977801486], [50.05257, -32.42061515391178], [49.222351835143854, -32.362594977801486], [48.415509488888034, -32.19017844843427], [47.654479600250994, -31.908228813772958], [46.95989952640271, -31.524628742137907], [46.34989180575228, -31.04996743309319], [45.839535198028955, -30.497140951777368], [45.44053694043317, -29.880895852665123], [45.161095755482634, -29.217345478220302], [45.005926807103656, -28.523484166216896], [44.97641015314012, -27.816718485923438], [45.070822789918076, -27.114428081084437], [45.28461904383756, -26.433562922038107], [45.61073216839574, -25.790279456676938], [46.03987909741554, -25.19961551117886], [46.56085858017986, -24.675202669272224], [47.16083933620022, -24.22901487736714], [47.82563904034762, -23.87115272264491], [48.53999700029679, -23.60966376988598], [49.28784374603885, -23.450400161188764], [50.05257, -23.39691514099216]]],
 "crs" : {
 "type" : "name",
 "properties" : {
 "name" : "urn:ogc:def:crs:OGC:1.3:CRS84"
 }
 }
}

import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.crs.DefaultGeographicCRS;
public class GeodeticCircle extends HttpServlet {
 private static final long serialVersionUID = 1L;
 public GeodeticCircle() {super();}

&nbsp;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/plain");
 response.setCharacterEncoding("UTF-8");
 PrintWriter printWriter = response.getWriter();

 Double lon = Double.parseDouble(request.getParameter("lon"));
 Double lat = Double.parseDouble(request.getParameter("lat"));
 int distance = Integer.parseInt(request.getParameter("dist"))*1000;

 GeodeticCalculator calc = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
 calc.setStartingGeographicPoint(lon, lat);

 ArrayList<String> coords = new ArrayList<String>();

 for (int i = 0; i < 40; i++)
 {
 int angle = (i * 360 / 40);
 if (angle>=180){angle = angle-360;}
 calc.setDirection(angle /* azimuth */, distance/* distance */);
 Point2D dest = calc.getDestinationGeographicPoint();
 coords.add("["+Double.toString(dest.getX())+","+Double.toString(dest.getY())+"]");
 }
 coords.add(coords.get(0)); //close ring

 printWriter.println("{\"type\":\"Polygon\",\"coordinates\":["+coords+"],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}");
 }

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 doGet(request, response);
 }

}

Register ArcSDE Layers to GeoServer using ArcGIS 10

Recently i gave the geoserver REST-API a try to manage the layer registration process directly from ArcGIS 10…

SDE-layers&styles -> geoserver

My situation:

-Debian 6 64bit
-Postgres 8.4 (without PostGIS)
-ArcSDE 10 for Postgres 8.4
-GeoServer 2.1.2 with SDE-extension
-one vector store for SDE
-SDE Raster and Vector all managed from ArcGIS 10 client

My needs:

  1. register SDE raster&vector to geoserver using arcpy and ArcGIS toolbox capabilities
  2. assign Styles to newly registered Geoserver-Layers using arcpy

My solution

for need (1) I implemented two simple python scripts… note that only input datasets with epsg:4326 are supported… In geoserver all registerd datasets are published as epsg:900913–you can change this setting, to fit to your needs… (add some tool-param for proj inside the xml or json body)

one for vector:

#Register SDE Vector Layer to GeoServer
#author: Hubert Asamer 2012
import arcpy, os, sys, string
import subprocess

inputFeatures = string.split(string.replace(arcpy.GetParameterAsText(0),"\'",""), ";")
sld_file = arcpy.GetParameterAsText(1)
gs_host = arcpy.GetParameterAsText(2)
gs_user = arcpy.GetParameterAsText(3)
gs_pw = arcpy.GetParameterAsText(4)
gs_workspace = arcpy.GetParameterAsText(5)
gs_store =arcpy.GetParameterAsText(6)

for name in inputFeatures:
featureClassName = name.upper()
arcpy.AddMessage(featureClassName)
p = subprocess.Popen(['curl',
'-XPOST','-u',''+gs_user+':'+gs_pw+'', '-d',
'{"featureType":{"name":"'+featureClassName+'","nativeCRS":"EPSG:4326","srs":"EPSG:900913","projectionPolicy":"REPROJECT_TO_DECLARED"}}',
'-H', 'Content-Type:application/json',
'http://'+gs_host+'/rest/workspaces/'+gs_workspace+'/datastores/'+gs_store+'/featuretypes'],
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
arcpy.AddMessage(line),
retval = p.wait()

one for raster: note that there will be created a store called as the input-grid and a corresponding layer

#Register SDE Raster Layer to GeoServer
#author: Hubert Asamer 2012
import arcpy, os, sys, string
import subprocess

inputFeatures = string.split(string.replace(arcpy.GetParameterAsText(0),"\'",""), ";")
sld_file = arcpy.GetParameterAsText(1)
gs_host = arcpy.GetParameterAsText(2)
gs_user = arcpy.GetParameterAsText(3)
gs_pw = arcpy.GetParameterAsText(4)
gs_workspace = arcpy.GetParameterAsText(5)
sdeusername=arcpy.GetParameterAsText(6)
sdepassword=arcpy.GetParameterAsText(7)
sdehost=arcpy.GetParameterAsText(8)
sdeport=arcpy.GetParameterAsText(9)

for name in inputFeatures:
featureClassName = name.upper()
arcpy.AddMessage(featureClassName)
p = subprocess.Popen(['curl', '-XPOST', '-u', ''+gs_user+':'+gs_pw+'', '-H', 'Content-Type:text/xml', '-d', '<coverageStore><name>'+featureClassName+'</name><type>ArcSDE Raster</type><enabled>true</enabled><url>sde://'+sdeusername+':'+sdepassword+'@'+sdehost+':'+sdeport+'/#'+featureClassName+'</url></coverageStore>', 'http://'+gs_host+'/rest/workspaces/'+gs_workspace+'/coveragestores'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
arcpy.AddMessage(line),
retval = p.wait()
q = subprocess.Popen(['curl', '-XPOST', '-u', ''+gs_user+':'+gs_pw+'', '-H', 'Content-Type:text/xml', '-d', '<coverage><name>'+featureClassName+'</name><nativeFormat>ArcSDE Raster</nativeFormat><nativeCRS>EPSG:4326</nativeCRS><srs>EPSG:900913</srs><parameters><entry><string>OVERVIEW_POLICY</string><string>QUALITY</string></entry></parameters></coverage>', 'http://'+gs_host+'/rest/workspaces/'+gs_workspace+'/coveragestores/'+featureClassName+'/coverages'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line1 in q.stdout.readlines():
arcpy.AddMessage(line1),
retval = q.wait()

for need (2) check this out:

#Register SLD to GeoServer-Layer
#author: Hubert Asamer 2012
import arcpy, os, sys, string
import subprocess

inputFeatures = string.split(string.replace(arcpy.GetParameterAsText(0),"\'",""), ";")
sld_file = os.path.abspath(arcpy.GetParameterAsText(1))
gs_host = arcpy.GetParameterAsText(2)
gs_user = arcpy.GetParameterAsText(3)
gs_pw = arcpy.GetParameterAsText(4)
gs_workspace = arcpy.GetParameterAsText(5)

for name in inputFeatures:
featureClassName = name.upper()
arcpy.AddMessage(featureClassName)
arcpy.AddMessage(sld_file)
p = subprocess.Popen(['curl','-XPOST','-u',''+gs_user+':'+gs_pw+'','-d','<style><name>'+featureClassName+'</name><filename>'+featureClassName+''+'.'+'sld</filename></style> ','-H','Content-Type: text/xml',
'http://'+gs_host+'/rest/styles'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
arcpy.AddMessage(line),
retval = p.wait()
arcpy.AddMessage('Style created!')
q = subprocess.Popen(['curl', '-XPUT', '-u', ''+gs_user+':'+gs_pw+'', '-d', '@'+sld_file, '-H', 'Content-Type:application/vnd.ogc.sld+xml', 'http://'+gs_host+'/rest/styles/'+string.replace(featureClassName,".","%2E")+''], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line1 in q.stdout.readlines():
arcpy.AddMessage(line1),
retval = q.wait()
arcpy.AddMessage('SLD-File uploaded!')
r = subprocess.Popen(['curl','-XPUT','-u',''+gs_user+':'+gs_pw+'','-d','<layer><defaultStyle><name>'+featureClassName+'</name></defaultStyle><enabled>true</enabled></layer> ','-H','Content-Type: text/xml',
'http://'+gs_host+'/rest/layers/'+gs_workspace+':'+string.replace(featureClassName,".","%2E")], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line2 in r.stdout.readlines():
arcpy.AddMessage(line2),
retval = r.wait()
arcpy.AddMessage('Style linked with layer!')

here my tbx-files (ArcGIS 10) and python code all in one file…

Note that you can produce your sld-files with any tool you like…it must be valid and all attribute matches inside the sld must be correct… I prefer arc2earth community edition to produce sld’s for single vector layers… Also qgis 1.8 offers sld import/export…

GeoServer REST API vs. SDE-Layers

Yesterday i gave the GeoServer REST API a try to register approx. 250 Raster and vector layers all coming from an SDE-Database. My debian6 server hosts postgres 8.4 with SDE 10.0 and Geoserver 2.1.2 (tomcat6)…Previously I installed the sde- extension for geoserver

From my experience the most important issue on publishing hundreds of layers from an GDB is a 100 percent consistent naming convention. Note that in ArcGIS SDE-GDB the cool feature-dataset structure is not represented through the JAVA sde-driver, meaning that the ability to group layers must be possible trough their names…

My aim was to do all basic geoserver-gui tasks in a simple batch file from my win7 client:

  • create raster stores
  • register raster layers
  • register vector layers from existing store

The geoserver doc has some examples on how to interact with the REST API. I also found this project site (opengeoportal wiki)  very useful. My example uses curl…

Raster-Registration based on textfile containing sde layer names (newLayerListRaster.txt):

Result is:

  • raster store (as named in textfile)
  • raster layer with default style (as named in textfile)
@echo off
 SET username="????"
 SET password="????"
 SET sdeusername="????"
 SET sdepassword="????"
 SET sdehost="127.0.0.1"
 SET sdeport="????"
 SET geoserverhostandpath="????/geoserver"
 SET workspace="sde"
 SET list=%1
 echo ---GeoServer Raster Registration ArcSDE---
 echo REQUEST...
 echo arg1=NewStoreName: --from list--
 echo arg2=SDE-RasterTableName(DB.SCHEMA.TABLENAME): --from list--
 echo.
 echo RESPONSE...
 FOR /F %%i in (%list%) do curl -XPOST -u %username%:%password% -H "Content-Type:text/xml" -d "<coverageStore><name>%%i</name><type>ArcSDE Raster</type><enabled>true</enabled><url>sde://%sdeusername%:%sdepassword%@%sdehost%:%sdeport%/#%%i</url></coverageStore>" http://%geoserverhostandpath%/rest/workspaces/%workspace%/coveragestores
 FOR /F %%i in (%list%) do curl -XPOST -u %username%:%password% -H "Content-Type:text/xml" -d "<coverage><name>%%i</name><nativeFormat>ArcSDE Raster</nativeFormat><requestSRS><string>EPSG:4326</string></requestSRS><responseSRS><string>EPSG:4326</string></responseSRS><parameters><entry><string>OVERVIEW_POLICY</string><string>QUALITY</string></entry></parameters></coverage>" http://%geoserverhostandpath%/rest/workspaces/%workspace%/coveragestores/%%i/coverages
 echo.

 

Vector Registration (store must exist):

Result is:

  • vector layer (as named in textfile)
@echo off
 SET username=????
 SET password=????
 SET geoserverhostandpath=????/geoserver
 SET workspacename=????
 SET datastoreName=????
 SET list=%1
 echo ---GeoServer Vector-Layer Registration in existing Store for ArcSDE ---
 echo REQUEST...
 echo arg1=SDE-VectorTableName(DB.SCHEMA.TABLENAME): --from list--
 echo arg2=newStyleName: --from list--
 echo.
 echo RESPONSE...
 @echo on
 FOR /F %%i in (%list%) do curl -XPOST -u %username%:%password% -d {"featureType":{"name":"%%i"}} -H "Content-Type:application/json" http://%geoserverhostandpath%/rest/workspaces/%workspacename%/datastores/%datastoreName%/featuretypes
 @echo off
 echo.
 rem curl -XPOST -u %username%:%password% -H "Content-type: text/xml" -d "<style><name>%stylename%</name><filename>%styleName%.sld</filename></style>" http://%geoserverhostandpath%/rest/styles
 echo.

These two examples can easily be adopted to define projection settings and other layer settings. Just edit the xml or json part of the XPOST request. A good starting point is to define a layer fully by hand in the geoserver gui and look into the resulting layer.xml or coverage.xml in the geoserver data dir. The structure of these xml’s is quite straightforward. Then try to place the tags you want into the batch request…

The next thing i want to automate is style handling and assigning specific styles to layers… One approach is to extend the layerlist from our batch routine with a second or third attribute delimited by e.g. semicolon, holding style info…

Single commands: create style > upload sld file for style > assign style to layer

  • curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' -d '<style><name>newStyleName</name><filename>newStyleName.sld</filename></style>' http://?????/geoserver/rest/styles
    
  • curl -u admin:geoserver -XPUT -H 'Content-type: application/vnd.ogc.sld+xml'-d '@newStyleName.sld' http://?????/geoserver/rest/styles/schwemmland
    
  • curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -d '<layer><defaultStyle><name>newStyleName</name></defaultStyle></layer>' http://?????/geoserver/rest/layers/LayerName
    

Conclusion:

Depending on the amount of layers the REST API can save a lot of time.

Another setup of a geo-aware application server

Requirements:

  • Traditional webGIS functions
  • Spatial DB
  • Vector and Raster Data Storage
  • Geodata Integration via web Interface
  • Open source software

Solution:

  • Use openlayers for frontend functions, add value with some magic JS (jquery or extJS)
  • Use tomcat & geoserver as server backend
  • Use Postgresql & postgis as a spatial datawarehouse
  • Use geowebcache for serving cached basemaps and overlays
  • Alternatively use ArcSDE with postgres if your customer wants to manage all geodata with ArcGIS  -> licence issues
  • Hold data in DB and on file system
  • Use JSP and J2EE Servlets with tomcat for building the webGIS app
  • Rely on well-established GIS frameworks like geotools, gdal/ogr or JTS for doing GIS jobs over the web
  • Use Debian as OS

As of July 2012 the following versions of software tools are available:

Server-software:

  • Tomcat7
  • Geoserver 2.1.4
  • Postgres 9.1.4
  • Postgis 2.0
  • ArcSDE 10.1
  • JDK 7
  • Gdal 1.9
  • Geowebcache 1.3

Frontend tools:

  • OpenLayers 2.12
  • Jquery 1.7.2
  • extJS 4.1

Think of all the requirements each piece of software has against any other underlying software…

Step1

Debian 6 (squeeze) 64bit, minimal system

–No X server running, disable ipv6

–Use hardening-tools and security updates

Step2

Install JDK 64bit delivered by apt (non-free)

Step3

Install Postgres 9.0 if you plan to use ArcSDE 10.1

Step4

Install Postgres 9.1 if plan to use PostGIS

Step5

Install tomcat6 delivered by apt

–Look at http://sebthom.de/142-installing-tomcat-6-debian-squeeze/

–Set tomcat to Port 80 by using iptables

—-iptables -A INPUT -i eth0 -p tcp –dport 80 -j ACCEPT

—-iptables -A INPUT -i eth0 -p tcp –dport 8080 -j ACCEPT

—-iptables -A PREROUTING -t nat -i eth0 -p tcp –dport 80 -j REDIRECT –to-port 8080

–set JAVA options according to your amount of RAM

Step6

Install geoserver 2.1.3

–Use war file

–Deploy with tomcat

Step7

Install geowebcache 1.3

–Use war file

–Deploy with tomcat

Step8

Install ArcSDE 10.1 via network using ArcGIS Desktop toolbox

–Look at esri-docs

–Choose whether you want to go completely esri, by using the esri geometry type (and raster type) exclusively inside Postgres, OR if you plan to use both: PostGIS geometry and esri geometry datatypes

Step9

Install GDAL 1.9

–Compile from source

–Choose your needed format drivers

–Install and choose your preferred bindings (JAVA, Python,…)

Step10

Configure your system

–Bring in your data

–Configure geoserver (e.g. install sde-plugin)

—-Style layers

–Configure geowebcache (register pre-cached tilesets from ArcGIS server, or create new ones)

–Configure postgres

—-Setup user management schema for webapp

—-Setup essential app config tables (layer related to app)

—-Setup multiple viewer configurations

—-Implement a web admin tool for controlling the webGIS app

–Develop JSP’s and J2EE servlets for app logic (Eclipse)

–Develop frontend client and connect to servlets