Details
-
Type:
Wish
-
Status:
Closed
-
Priority:
Minor
-
Resolution: Fixed
-
Affects Version/s: 2.0-b5
-
Fix Version/s: None
-
Component/s: docs
-
Labels:None
Description
A number of users recently have been asking how to adapt the spearfish sample to use a PostGIS data store. I'm hoping that I can provide a few hints here and some one will pick up this issue and and test out the suggestions, and then modify the wiki to use postgis instead of shapefile.
I believe the first step would be to change the creation of the Shapefile DataStore from instantiating directly to using the DataStoreFinder class. Instead of:
URL roadsURL = getResource("org/geotools/sampleData/roads.shp");
ShapefileDataStore dsRoads = new ShapefileDataStore(roadsURL);
It should be:
URL roadsURL = getResource("org/geotools/sampleData/roads.shp");
Map params = new HashMap().add("url", roadsURL);
DataStore dsRoads = DataStoreFinder.getDataStore(params);
Yes, this is an extra step, but it makes use of the interface for pluggable datastores, so we can easily use postgis. To use postgis you need to use the postgis params. The appropriate params to initiate a postgis DataStore are: dbtype (which must always be 'postgis'), host, port, database, user, passwd.
host is the name of the computer the db is stored on, localhost if on the same computer.
port is generally 5432 (postgis must be run with -i for gt2 to connect)
database is the name of the db to connect to.
user and passwd are pretty self explanatory - passwd is optional.
So to instantiate a postgis datastore the code would look like:
Map params = new HashMap();
params.add("dbtype", "postgis");
params.add("host", "localhost");
params.add("port", "5432");
params.add("user", "cholmes");
DataStore pgDatastore = DataStoreFinder.getDataStore(params);
This should give you the datastore. Then you need to select the FeatureSources. PostGIS DataStore represents the whole database, so it should contain all the feature sources, so you just need to say:
FeatureSource fsRoads = pgDatastore.getFeatureSource("roads");
FeatureSource fsStreams = pgDatastore.getFeatureSource("streams");
ect.
To ensure success with the spearfish sample the shapefiles should be converted to a tables in the same database using shp2pgsql. If someone makes the sql file it would be nice to post it for other users.
The created featureSources should be added directly as layers, just as with shapefile, no need to extract points from them.
I'm sure there will be more questions, as I haven't actually set this up myself. But ask them as comments on this issue, and I should be able to answer. And please document the results of this issue on the wiki.
I leave this open for someone to help out on, just assign it to yourself and close then done - doing so would be a great way to help out the geotools project.
-
- spearfish_data_pg.sql
- 28/Jun/04 8:51 PM
- 392 kB
- Chris Holmes
Activity
I think that the how-to should start be an extention of the "Data access basic tutorial" and start by just showing how to access postgis. It could then be expanded to include a modified version of the SpearfishSample (and data and instructions).
I may have time to work on this thursday night, but don't let this stop anyone else from starting this before then.
This is what i did:
1. Got a shapefile: "rails.shp"
2. used the shp2pgsql to upload this to the database "raildb" and created a table rail.
3. Then connected to the database and got the feature source from the table.
4. Then added this to layer and did the same set of steps, but couldn't draw the map because of some errors in setMapContext(mapContext) method.
PostgisConnectionFactory con = new PostgisConnectionFactory("plundar.cs.uno.edu", 9011, "raildb");
ConnectionPool cpl= con.getConnectionPool();
Connection c= cpl.getConnection();
PostgisDataStore ds = new PostgisDataStore(cpl);
System.out.println(ds.allowTable("rail"));
String str = ds.getTypeNames()[0];
FeatureSource fsRails = ds.getFeatureSource(str);
StyleBuilder sb = new StyleBuilder();
LineSymbolizer lsRail = sb.createLineSymbolizer(Color.BLUE, 3);
Style railsStyle = sb.createStyle(lsRail);
MapContext map = new DefaultMapContext();
map.addLayer(fsRails, railsStyle);
StyledMapPane mapPane = new StyledMapPane();
mapPane.setMapContext(map);
mapPane.getRenderer().addLayer(new RenderedMapScale());
JFrame frame = new JFrame();
frame.setTitle("Rail map");
frame.setContentPane(mapPane.createScrollPane());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.show();
I tried to draw the map using shapefile, i could but when i tried to do it using postGIS it doesn't work.
I have working rendering of PostGIS (int GeoServer), but I don't use StyledMapPane - I just return the image to the user.
These are the errors I get:
Jun 1, 2004 10:49:21 PM org.geotools.data.jdbc.JDBCDataStore executeQuery
SEVERE: Error Performing SQL query
This method is not yet implemented.
at org.postgresql.Driver.notImplemented(Driver.java:388)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.setFetchSize(AbstractJdbc2Statement.java:156)
at
org.geotools.data.jdbc.JDBCDataStore.executeQuery(JDBCDataStore.java:797)
at
org.geotools.data.jdbc.JDBCDataStore.getFeatureReader(JDBCDataStore.java:563)
at
org.geotools.data.jdbc.JDBCFeatureSource$1.reader(JDBCFeatureSource.java:202)
at
org.geotools.renderer.j2d.RenderedLayerFactory.create(RenderedLayerFactory.java:214)
at
org.geotools.renderer.j2d.StyledMapRenderer.addLayer(StyledMapRenderer.java:207)
at
org.geotools.renderer.j2d.StyledMapRenderer.setMapContext(StyledMapRenderer.java:154)
at
org.geotools.gui.swing.StyledMapPane.setMapContext(StyledMapPane.java:114)
at RailSampledb.main(RailSampledb.java:84)
Exception in thread "main" org.geotools.data.DataSourceException: Error
Performing SQL query
at
org.geotools.data.jdbc.JDBCDataStore.executeQuery(JDBCDataStore.java:815)
at
org.geotools.data.jdbc.JDBCDataStore.getFeatureReader(JDBCDataStore.java:563)
at
org.geotools.data.jdbc.JDBCFeatureSource$1.reader(JDBCFeatureSource.java:202)
at
org.geotools.renderer.j2d.RenderedLayerFactory.create(RenderedLayerFactory.java:214)
at
org.geotools.renderer.j2d.StyledMapRenderer.addLayer(StyledMapRenderer.java:207)
at
org.geotools.renderer.j2d.StyledMapRenderer.setMapContext(StyledMapRenderer.java:154)
at
org.geotools.gui.swing.StyledMapPane.setMapContext(StyledMapPane.java:114)
at RailSampledb.main(RailSampledb.java:84)
Caused by: This method is not yet implemented.
at org.postgresql.Driver.notImplemented(Driver.java:388)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.setFetchSize(AbstractJdbc2Statement.java:156)
at
org.geotools.data.jdbc.JDBCDataStore.executeQuery(JDBCDataStore.java:797)
... 7 more
Now i am trying a different approach: I am retrieving points from multilinestring and storing them in Point objects and atlast storing them in fature objects and I created a FeatureCollection of these fatures and tried adding it to the layer, but this too doesn't work.
I am actually trying to see if I can add the layer whether points or lines that are being added doesn't matter.
This is my program:
public class RailSamplejdb{
public static void main(String[] args) throws Exception
{
System.out.println("hello");
try
{
PostgisConnectionFactory con = new
PostgisConnectionFactory("plundar.cs.uno.edu", 9011, "raildb");
con.setLogin("gayatri","gayatri123");
ConnectionPool cpl= con.getConnectionPool();
Connection conn= cpl.getConnection();
ArrayList arr = new ArrayList();
Statement s = conn.createStatement();
ResultSet r = s.executeQuery("select the_geom from rail");
while( r.next() )
{
arr.add(r.getString("the_geom"));
}
StringTokenizer str,str1,str2,str3,str4;
ArrayList geo= new ArrayList();
for(int i=0;i<arr.size();i++){
String s1=(String)(arr.get(i));
str = new StringTokenizer(s1,";");
str.nextToken();
geo.add(str.nextToken());
}
ArrayList geo1=new ArrayList();
for(int j=0;j<geo.size();j++){
String s1=(String)(geo.get(j));
str1 = new StringTokenizer(s1,"((");
str1.nextToken();
geo1.add(str1.nextToken());
}
ArrayList linestring = new ArrayList();
for(int k=0;k<geo1.size();k++){
String s1 =(String)(geo1.get(k));
str2 = new StringTokenizer(s1,"))");
linestring.add(str2.nextToken());
}
System.out.println(linestring.get(0));
ArrayList points = new ArrayList();
for(int l=0;l<linestring.size();l++){
String s1=(String)(linestring.get(l));
str3 = new StringTokenizer(s1,",");
while(str3.hasMoreTokens())
{
points.add(str3.nextToken());
}
}
ArrayList xPoints = new ArrayList();
ArrayList yPoints = new ArrayList();
for(int m=0;m<points.size();m++)
{
String s1=(String)(points.get(m));
str4 = new StringTokenizer(s1," ");
xPoints.add(str4.nextToken());
yPoints.add(str4.nextToken());
}
System.out.println(xPoints.get(0));
System.out.println(yPoints.get(0));
try{
BufferedWriter bw = new BufferedWriter(new FileWriter("file.txt"));
for(int m=0;m<points.size();m++){
bw.write((String)(points.get(m)));
bw.write("\r\n");
}
bw.close();
}
catch(Exception e){
System.out.println(e);
}
System.out.println(xPoints.size());
Coordinate[] c=new Coordinate[xPoints.size()];
for(int n=0;n<xPoints.size();n++){
c[n] = new Coordinate(Double.parseDouble((String)xPoints.get(n)),
Double.parseDouble((String)yPoints.get(n)));
}
Point[] pt = new Point[xPoints.size()];
for(int p=0;p<xPoints.size();p++){
pt[p] = new Point(c[p], Geometry.DEFAULT_COORDINATE_SYSTEM);
}
System.out.println(pt[0].getX());
AttributeType geom = AttributeTypeFactory.newAttributeType("the_geom", Point.class);
FeatureType ftRail = FeatureTypeFactory.newFeatureType(new AttributeType[] {geom}, "rail");
//Geometry g = (Geometry)pt[1];
Feature[] theRail = new Feature[xPoints.size()];
for(int q=0;q<xPoints.size();q++){
theRail[q]= ((DefaultFeatureType)ftRail).create(new Object[] {pt[q]}, "rails");
}
System.out.println(theRail[1].toString());
StyleBuilder sb = new StyleBuilder();
Mark redCircle = sb.createMark(StyleBuilder.MARK_CIRCLE, Color.RED, Color.BLACK, 0);
Graphic gr = sb.createGraphic(null, redCircle, null);
PointSymbolizer ps = sb.createPointSymbolizer(gr);
Style pointStyle = sb.createStyle(ps);
Collection col = new ArrayList();;
for(int q=0;q<xPoints.size();q++){
col.add(theRail[q]);
}
FeatureCollection fc = DefaultFeatureCollections.newCollection();
fc.addAll(col);
MapLayer myLayer = new DefaultMapLayer(fc,pointStyle);
MapContext map = new DefaultMapContext();
for(int i=0;i<xPoints.size();i++){
map.setAreaOfInterest(new Envelope(c[i]));
}
map.addLayer(myLayer);
StyledMapPane mapPane = new StyledMapPane();
mapPane.setMapContext(map);
s.close();
conn.close();
}
catch( Exception e )
{
e.printStackTrace();
}
}
}
These are the errors:
java.lang.NullPointerException
> at
> org.geotools.renderer.j2d.RenderedLayerFactory.findGeometry(RenderedLayerFactory.java:668)
> at
> org.geotools.renderer.j2d.RenderedLayerFactory.processSymbolizers(RenderedLayerFactory.java:472)
> at
> org.geotools.renderer.j2d.RenderedLayerFactory.create(RenderedLayerFactory.java:252)
> at
> org.geotools.renderer.j2d.StyledMapRenderer.addLayer(StyledMapRenderer.java:207)
> at
> org.geotools.renderer.j2d.StyledMapRenderer.setMapContext(StyledMapRenderer.java:154)
> at
> org.geotools.gui.swing.StyledMapPane.setMapContext(StyledMapPane.java:114)
> at RailSamplejdb.main(RailSamplejdb.java:177)
What do u mean by returning the image to the user? Don't you try to draw the image and have a look at the map?
Anyways, my work is to draw the map, I am almost done, if somebody could hep me, it would be really nice.
Thanx.
But I think all you need to do is update your postgres driver. Your error is because you are using an old one. You can get it at: http://jdbc.postgresql.org/download.html Get the jdbc3 one for 7.4 - it'll work with earlier versions of postgres too.
I got the new driver, I replaced the new jar file in place of the old postgresql.jar file, but i am not sure if i have to change any path settings to point out at this new one? Can you help me with this.
sorry again,
When i actually installed postgres and postgis, I never checked where the classpath was being set to point out at postgresql.jar.
But when i see one of the make file's in postgis.0.8.0/java/Makefile: I see one entry like this:
CLASSPATH = /home/pramsey/geotools/extbin/postgis/lib/postgresql.jar:
So i changed this to point out to my directory. and when i run the makefile, i get errors like this:
org/postgis/PGgeometry.java:20: error:Cannot find class "Geometry" [JLS 8]
org/postgis/PGgeometry.java:55: error:Cannot find class "Geometry" [JLS 8]
org/postgis/PGbox3d.java:28: error:Cannot find class "Point" [JLS 8]
org/postgis/PGbox3d.java:28: error:Cannot find class "Point" [JLS 8]
org/postgis/PGbox3d.java:64: error:Cannot find class "Point" [JLS 8]
make: *** [pgobjs] Error 1
Could you help me with this?
I think i am almost done if this is setup.
Many thanx,
gayatri.
ok i tried to include the new jar file which i have downloaded in my classpath when i actually compile the program. But it gives me same errors.
gayatri.
I tried to include the new jar file in my classpath when i compile the program, but i get the same errors with jdbc driver.
Could you tell me y this is happening even though i included the jdbc3 jar in my classpath?
Thanks.
Chris
When I run using java -verbose classname:
These are the classes loaded from postgresql jar file. I never used to include postgresql.jar file in my classpath before. But when i included it now, its gives me same set of errors, nothing really changes.
[Loaded org.postgresql.jdbc2.optional.BaseDataSource]
[Loaded org.postgresql.jdbc2.optional.ConnectionPool]
[Loaded org.postgresql.Driver]
[Loaded org.postgresql.util.PSQLException]
[Loaded org.postgresql.jdbc2.optional.PooledConnectionImpl]
[Loaded org.postgresql.PGConnection]
[Loaded org.postgresql.jdbc1.AbstractJdbc1Connection]
[Loaded org.postgresql.jdbc2.AbstractJdbc2Connection]
[Loaded org.postgresql.jdbc3.AbstractJdbc3Connection]
[Loaded org.postgresql.jdbc3.Jdbc3Connection]
[Loaded org.postgresql.core.Encoding]
[Loaded org.postgresql.core.StartupPacket]
[Loaded org.postgresql.core.QueryExecutor]
[Loaded org.postgresql.PGNotification]
[Loaded org.postgresql.Field]
[Loaded org.postgresql.jdbc1.AbstractJdbc1ResultSet]
[Loaded org.postgresql.jdbc2.AbstractJdbc2ResultSet]
[Loaded org.postgresql.jdbc3.AbstractJdbc3ResultSet]
[Loaded org.postgresql.jdbc3.Jdbc3ResultSet]
[Loaded org.postgresql.jdbc2.optional.PooledConnectionImpl$ConnectionHandler]
[Loaded org.postgresql.jdbc1.AbstractJdbc1DatabaseMetaData]
[Loaded org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData]
[Loaded org.postgresql.jdbc3.AbstractJdbc3DatabaseMetaData]
[Loaded org.postgresql.jdbc3.Jdbc3DatabaseMetaData]
[Loaded org.postgresql.PGStatement]
[Loaded org.postgresql.jdbc1.AbstractJdbc1Statement]
[Loaded org.postgresql.jdbc2.AbstractJdbc2Statement]
[Loaded org.postgresql.jdbc3.AbstractJdbc3Statement]
[Loaded org.postgresql.jdbc3.Jdbc3Statement]
Thanks for your help.
Opened c:\j2sdk1.4\jre\lib\rt.jar
Opened...
That way you can be sure that you don't have both postgres jars on your classpath.
You should have only the pg74.214.jdbc3.jar downloaded from http://jdbc.postgresql.org on the path, and not the oldpostgresql jar from geotools2 or where ever you got it.
[Opened /export/local/j2sdk1.4.2_02/jre/lib/rt.jar]
[Opened /export/local/j2sdk1.4.2_02/jre/lib/sunrsasign.jar]
[Opened /export/local/j2sdk1.4.2_02/jre/lib/jsse.jar]
[Opened /export/local/j2sdk1.4.2_02/jre/lib/jce.jar]
[Opened /export/local/j2sdk1.4.2_02/jre/lib/charsets.jar]
I do not see the new jar file opened or the old one.
I don't think I can help you anymore. I'm 95% sure this is just a classpath issue, as my jar has the setFetchSize method implemented, and works completely fine. It should not be throwing an error, and is not a problem with geotools. I hope you can figure it out, but I really don't know what more to say. Classpaths can be quite confusing. You could trying making a little ant file to run it or something...
http://docs.codehaus.org/display/GEOTOOLS/How+to+use+a+PostGISDataStore
Can other people please test this when they have time. Also we need a page showing available params for the different DataStores. I will start one tomorrow.
Thanx a lot, It was just a classpath problem, because i was including both of them in my classpath. Bcause I was including all the jar files I couldn't figure that out. But it did work finally.
I could draw the map.
Thank you,
gayatri.
I did test the spearfish example too and it worked, I could see the map.
When i installed geotools the jar files too be included were in jars and lib directories. While running my program I always used to set my classpath to all the jar files given, I could not realize tat I was including the old postgresql.jar file too there. I really had tough time, because the postgresql.jar file came along with geotools installation and it really created problems for me, could you modify that or write a comment in the example about this issue. I really had tough time figuring this out.
Thanks,
gayatri.
Also, if you have a bit could you check over the http://docs.codehaus.org/display/GEOTOOLS/How%2Bto%2Buse%2Ba%2BPostGISDataStore
If you find it sufficient then we can close this issue. Actually it would probably be good if you added the note about your experience, to tell users to be sure not to include the jar in the lib/ directory.
I checked the document I think that is fine, those who use PostGIS should not have a problem of creating the database at all. All the steps though are provided. And after creating the feature source the next set of steps are same as of drawing a map from shapefile. So, I think that would be it. But I had to to install JAI to draw the map, but its not mentioned in the tutorial. I do not know if others have to install JAI, but I am running my prgorams in Linux, so my platform requires this. So, when I compile my programs I inlude the jars of JAI too.
I would certainly like to include that note in the example. So, I think you modify that, because I do not know how to add a note, you could just mention in the tutorial that before running the program its better to make sure not to include the old postgresql.jar from the lib in classpath.
I am going to work on geotools further, so I would be in constant touch with you. Anyways, thanks for your help.
Thanks,
gayatri.
Other cool thing to add would be a dialog box or command line option to select a different datastore, to input the appropriate params or something.