Tôi đang sử dụng các geotools để trích xuất dữ liệu từ shapefile và lưu chúng vào mysql. ứng dụng của tôi làm việc tất cả các thời gian nhưng tôi nhận được khóa này cũng thường mà tôi không thể hiểu tại sao, vì nó vẫn hoạt độnggeotools SEVERE: Tủ khóa sau vẫn có khóa đọc trên hồ sơ
[[email protected] filespool]# /usr/bin/java -jar /opt/mcmap/library/Application/geotools/mcgeotools.jar -t publisher -i 1/194/Namibia_SCLB12.shp -rid 12 -s
app get cmd option cast to int: 12
app passing region id to runconvert: 12
runconvert rid passed: 12
Jul 9, 2012 4:23:48 PM org.geotools.data.db2.DB2DataStoreFactory isAvailable
INFO: DB2 driver found: true
Database connection acquired
Coordinates length: 5390
Coordinates length: 5358
Coordinates length: 9932
Jul 9, 2012 4:28:14 PM org.geotools.data.shapefile.ShpFiles logCurrentLockers
SEVERE: The following locker still has a lock� read on file:/opt/mcmap/public/filespool/1/194/Namibia_SCLB12.prj by org.geotools.data.shapefile.prj.PrjFileReader
it was created with the following stack trace
org.geotools.data.shapefile.ShpFilesLocker$Trace: Locking file:/opt/mcmap/public/filespool/1/194/Namibia_SCLB12.prj for read by org.geotools.data.shapefile.prj.PrjFileReader in thread main
at org.geotools.data.shapefile.ShpFilesLocker.setTraceException(ShpFilesLocker.java:72)
at org.geotools.data.shapefile.ShpFilesLocker.<init>(ShpFilesLocker.java:36)
at org.geotools.data.shapefile.ShpFiles.acquireRead(ShpFiles.java:365)
at org.geotools.data.shapefile.ShpFiles.getReadChannel(ShpFiles.java:813)
at org.geotools.data.shapefile.prj.PrjFileReader.<init>(PrjFileReader.java:66)
at com.domain.mcgeotools.convert.Converter.getCoordinateSystem(Converter.java:521)
at com.domain.mcgeotools.convert.Converter.runConvert(Converter.java:106)
at com.domain.mcgeotools.App.main(App.java:158)
Coordinates length: 5741
Coordinates length: 5374
Coordinates length: 4193
Coordinates length: 14161
Coordinates length: 5375
Coordinates length: 4212
dưới đây là mã ứng dụng của tôi
package com.domain.mcgeotools.convert;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.File;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.*;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.*;
import org.geotools.data.shapefile.prj.PrjFileReader;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureImpl;
import org.opengis.feature.Property;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
public class Converter {
protected String filePath = null;
private Properties configFile = null;
private String[] acceptedCoordinateSytems = {
"Lat Long for MAPINFO type 0 Datum",
"GCS_WGS_1984"
};
private HashMap sqlStatements = new HashMap();
private int sqlCounter = 0;
public Converter() throws IOException {
/**
* We load the configuration details from the properties file and use the config. The config property
* item stores things such as database connection details etc.
*/
this.configFile = new Properties();
this.configFile.load(this.getClass().getClassLoader().getResourceAsStream("mcgeotools-config.properties"));
}
protected void setFilePath(String filePath) {
this.filePath = filePath;
}
protected String getFilePath() {
return this.filePath;
}
/**
* Converts the passed shape files and place the data into the RDBMS
*
* @param filePath
* @param verbose
* @param shrink
* @return
* @throws Exception
*/
public int runConvert(String filePath, int regionId, boolean verbose, boolean shrink, String type) throws Exception {
System.out.println("runconvert rid passed: " + regionId);
ShapeFile shapeFile = new ShapeFile();
if (!shapeFile.isShapeFile(filePath)) {
System.out.println(filePath);
throw new Exception("Not a shape file");
}
//we get the coordinate type from the shape file
String coordinateSystem = null;
try {
coordinateSystem = this.getCoordinateSystem(filePath);
if (verbose) {
//Print to console.
System.out.println("Coordinate System: " + coordinateSystem + " for " + filePath);
}
} catch (Exception cse) {
Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, null, cse);
}
boolean acceptedSystem = false;
for (int i = 0; i < this.acceptedCoordinateSytems.length; i++) {
if (this.acceptedCoordinateSytems[i].equalsIgnoreCase(coordinateSystem)) {
acceptedSystem = true;
}
}
if (!acceptedSystem) {
throw new Exception("Not an excepted Coordinate System.");
}
//we now load the shapefile into the application
File file = new File(filePath);
if (file == null) {
throw new Exception("Failed to open " + filePath);
}
Map connect = new HashMap();
connect.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(connect);
String[] typeNames = dataStore.getTypeNames();
String typeName = typeNames[0];
FeatureSource featureSource = dataStore.getFeatureSource(typeName);
FeatureCollection collection = featureSource.getFeatures();
FeatureIterator iterator = collection.features();
//database connection
Connection dbConn = null;
int surveyDbId = 0;
String localhostname = java.net.InetAddress.getLocalHost().getHostName();
try {
String dbUser = "", dbPwd = "", dbUrl = "";
dbUser = this.configFile.getProperty("DB_USER");
dbPwd = this.configFile.getProperty("DB_PASSWORD");
dbUrl = "jdbc:" + this.configFile.getProperty("DB_CONNSTR");
dbUrl = "jdbc:mysql://"+ localhostname +"/mcdatabase";
// If publishing overite connection strings
if(type.equals("publish")){
dbUser = this.configFile.getProperty("DB_PB_USER");
dbPwd = this.configFile.getProperty("DB_PB_PASSWORD");
dbUrl = "jdbc:" + this.configFile.getProperty("DB_PB_CONNSTR");
}
Class.forName("com.mysql.jdbc.Driver").newInstance();
dbConn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);
System.out.println("Database connection acquired");
//switch off auto commits so that we run this as one transaction.
dbConn.setAutoCommit(false);
this.sqlStatements.put(this.sqlCounter, "START TRANSACTION");
this.sqlCounter++;
PreparedStatement surveyStmt = null;
ResultSet rs = null;
if(type.equals("convert")){
//insert data in to the survey table and get the last row ID.
surveyStmt = dbConn.prepareStatement("INSERT INTO surveys (name, guid, date_added, region_id, shrink) VALUES(?, md5(now()), now(), ?, ?)");
surveyStmt.setString(1, typeName.replaceAll("%20", " "));
surveyStmt.setInt(2, regionId);
surveyStmt.setBoolean(3, shrink);
surveyStmt.executeUpdate();
rs = surveyStmt.getGeneratedKeys();
rs.first();
surveyDbId = rs.getInt(1);
this.sqlStatements.put(this.sqlCounter, "INSERT INTO surveys (name, guid, date_added, region_id, shrink) VALUES('"+ typeName.replaceAll("%20", " ") +"', md5(now()), now(), "+ regionId +", "+ shrink +")");
}else if(type.equals("publish")){
//insert data in to the survey table and get the last row ID.
surveyStmt = dbConn.prepareStatement("INSERT INTO surveys (name, guid, published, date_added, region_id, shrink) VALUES(?, md5(now()), 1, now(), ?, ?)");
surveyStmt.setString(1, typeName.replaceAll("%20", " "));
surveyStmt.setInt(2, regionId);
surveyStmt.setBoolean(3, shrink);
surveyStmt.executeUpdate();
rs = surveyStmt.getGeneratedKeys();
rs.first();
surveyDbId = rs.getInt(1);
this.sqlStatements.put(this.sqlCounter, "INSERT INTO surveys (name, guid, published, date_added, region_id, shrink) VALUES('"+ typeName.replaceAll("%20", " ") +"', md5(now()), 1, now(), "+ regionId +", "+ shrink +")");
}
this.sqlCounter++;
rs.close();
surveyStmt.close();
//Total lat/long values to work center point.
double totalLat = 0.0;
double totalLong = 0.0;
int totalLongLats = 0;
while (iterator.hasNext()) {
SimpleFeatureImpl feature = (SimpleFeatureImpl) iterator.next();
Geometry sourceGeometry = (Geometry) feature.getDefaultGeometry();
//we now need to enter a link between the survey and the line data.
PreparedStatement lineStmt = null;
String lineStmtSQL = "INSERT INTO `lines` (guid, date_added, survey_id) VALUES (md5(now()), now(), ?)";
lineStmt = dbConn.prepareCall(lineStmtSQL);
lineStmt.setInt(1, surveyDbId);
lineStmt.executeUpdate();
ResultSet lineRS = lineStmt.getGeneratedKeys();
lineRS.first();
int lineDbId = lineRS.getInt(1);
this.sqlStatements.put(this.sqlCounter, "INSERT INTO `lines` (guid, date_added, survey_id) VALUES (md5(now()), now(), " +
surveyDbId +")");
this.sqlCounter++;
lineRS.close();
lineStmt.close();
//we now look for the properties of the line that we are about to process.
Collection<Property> coll = feature.getProperties();
Iterator colIterator = coll.iterator();
//we now look at inserting the line properties into the database.
PreparedStatement linePropStmt = null;
String linePropSQL = "INSERT INTO line_properties(`key`, `value`, `line_id`) VALUES(?, ?, ?)";
linePropStmt = dbConn.prepareStatement(linePropSQL);
while (colIterator.hasNext()) {
Property geoProp = (Property) colIterator.next();
if (verbose) {
System.out.println("prop name: " + geoProp.getName() + " Value: " + geoProp.getValue());
}
if (geoProp.getValue() != null && !geoProp.getName().toString().equals("the_geom")) {
//we then prepare the statment and execute for each property.
linePropStmt.setString(1, geoProp.getName().toString());
linePropStmt.setString(2, geoProp.getValue().toString());
linePropStmt.setInt(3, lineDbId);
linePropStmt.executeUpdate();
//add to sql command hashmap
this.sqlStatements.put(this.sqlCounter, "INSERT INTO line_properties(`key`, `value`, `line_id`) VALUES('" +
geoProp.getName().toString()+"', '"+
geoProp.getValue().toString()+"', "+lineDbId+")");
this.sqlCounter++;
}
}
//close the prepared statement now that we've finished with it.
linePropStmt.close();
//finally we populate the line coordinates into the database.
Coordinate[] coordinates = sourceGeometry.getCoordinates();
String lineName = feature.getID();
if (verbose) {
System.out.println(lineName);
}
PreparedStatement coordStmt = null;
String coordSQL = "INSERT INTO coordinates(`x`, `y`, line_id, sequence) VALUES(?, ?, ?, ?)";
coordStmt = dbConn.prepareStatement(coordSQL);
PreparedStatement lineStringStmt = null;
String longLatSQL = "UPDATE `lines` SET longlat_string = ? WHERE line_id = ?";
lineStringStmt = dbConn.prepareStatement(longLatSQL);
/**
* Used to build a full long lat string for fast lookups
* when being used in KML/Google Maps
*/
String longLatString = "";
boolean first = true;
int shotCount = 0;
System.out.println("Coordinates length: "+ coordinates.length);
for (int i = 0; i < coordinates.length; i++) {
if (verbose) {
System.out.println("x: " + coordinates[i].x + " - Y: " + coordinates[i].y);
}
//add to the long lat counter to find center point
totalLat += coordinates[i].x;
totalLong += coordinates[i].y;
totalLongLats++;
coordStmt.setString(1, Double.toString(coordinates[i].x));
coordStmt.setString(2, Double.toString(coordinates[i].y));
coordStmt.setInt(3, lineDbId);
coordStmt.setInt(4, i);
coordStmt.executeUpdate();
this.sqlStatements.put(this.sqlCounter, "INSERT INTO coordinates(`x`, `y`, line_id, sequence) VALUES('"+
Double.toString(coordinates[i].x) +"', '"+
Double.toString(coordinates[i].y) +"', "+lineDbId+", "+i+")");
this.sqlCounter++;
//now we build/update a string for the full coordinates.
if (first) {
longLatString = Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
first = false;
} else {
// Not implemented function fully, to strip long lats to start and end points only
if(shrink){
if(i == (coordinates.length -1)){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
}
}else{
/* // testing this if
if(coordinates.length < 10 && shotCount == 2){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}else */
//if(coordinates.length >= 10 && coordinates.length < 30 && shotCount == 4){
if(coordinates.length < 30 && shotCount == 4){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}else if(coordinates.length >= 30 && coordinates.length < 100 && shotCount == 9){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}else if(coordinates.length >= 100 && coordinates.length < 1000 && shotCount == 49){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}else if(coordinates.length >= 1000 && coordinates.length < 10000 && shotCount == 99){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}else if(coordinates.length >= 10000 && shotCount == 199){
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
shotCount = 0;
}
// Make sure to get last co-ordinate of line
if(i == (coordinates.length-1)){ // -1 since coutn starts from zero
longLatString += ",0 " + Double.toString(coordinates[i].x) + "," + Double.toString(coordinates[i].y);
System.out.println("Last coordinate stored: " + longLatString);
shotCount = 0;
}
}
}
shotCount ++;
}
/**
* Update the line table to include the precreated line string.
*/
lineStringStmt.setString(1, longLatString);
lineStringStmt.setInt(2, lineDbId);
lineStringStmt.executeUpdate();
this.sqlStatements.put(this.sqlCounter, "UPDATE `lines` SET longlat_string = '"+longLatString+"' WHERE line_id = " + lineDbId);
this.sqlCounter++;
lineStringStmt.close();
coordStmt.close();
}
//finally we update the center point
PreparedStatement centerPointStmt = null;
String centerPointSQL = "UPDATE `surveys` SET center_point = ? WHERE survey_id = ?";
centerPointStmt = dbConn.prepareStatement(centerPointSQL);
double centerLat = totalLat/totalLongLats;
double centerLong = totalLong/totalLongLats;
String centerPoint = Double.toString(centerLat) + ", " + Double.toString(centerLong);
centerPointStmt.setString(1, centerPoint);
centerPointStmt.setInt(2, surveyDbId);
centerPointStmt.executeUpdate();
centerPointStmt.close();
this.sqlStatements.put(this.sqlCounter, "UPDATE `surveys` SET center_point = '"+centerPoint+"' WHERE survey_id = "+surveyDbId);
this.sqlCounter++;
//we now commit the transaction
dbConn.commit();
//now we can close the database connection.
dbConn.close();
this.sqlStatements.put(this.sqlCounter,"COMMIT");
this.sqlCounter++;
BufferedWriter out = new BufferedWriter(new java.io.FileWriter(this.configFile.getProperty("SQL_FILE").toString()));
for(int i = 0; i < this.sqlStatements.size(); i++){
out.write(this.sqlStatements.get(i) + ";" + "\n");
}
//close file connection
out.close();
System.out.println("End transaction");
} catch (Exception ex) {
System.out.println();
System.out.println("Message: "+ex.getMessage());
if(ex.getMessage().trim().contains("Communications link failure")){
System.out.println("Check there is a mysql connection and retry");
System.out.println();
System.exit(0);
}else{
Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, null, ex);
//we've errored so we need to toll back the connection.
dbConn.rollback();
//we now insert a message into the audit log.
String auditSQL = "INSERT INTO auditlog (username, date_added, message, guid, type)" + "VALUES('mcgeotools', now(), ?, md5(now()), ?)";
PreparedStatement auditStmt = dbConn.prepareStatement(auditSQL);
//we want to know which survey failed to import and we need the stacktrace message.
String auditMessage = "Error whilst populating Survey " + typeName + " with error message : " + ex.getMessage();
auditStmt.setString(1, auditMessage);
auditStmt.setString(2, "error"); //error
auditStmt.execute();
dbConn.commit();
}
} finally {
//close the iterator
iterator.close();
//commit any transaction and close the connection to the database if it is open.
if (dbConn != null && !dbConn.isClosed()) {
try {
dbConn.commit();
dbConn.close();
} catch (Exception dbex) {
System.out.println("Communications failure, check there is a connection to mysql");
Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, null, dbex);
}
}
//close file connection
}
return surveyDbId;
}
/**
* Get the coordinate system that is used in the shape file
*
* @param String shpFilePath
* @return String
*/
private String getCoordinateSystem(String shpFilePath) throws MalformedURLException, IOException {
String coordType = null;
ShpFiles shapeFiles = new ShpFiles(shpFilePath);
PrjFileReader fileReader = new PrjFileReader(shapeFiles);
CoordinateReferenceSystem coordSystem = fileReader.getCoodinateSystem();
coordType = coordSystem.getName().toString();
return coordType;
}
}
@Andre lỗi
Feb 22, 2013 12:03:54 PM org.geotools.data.shapefile.ng.files.ShpFiles logCurrentLockers
SEVERE: The following locker still has a lock: read on file:/tmp/24/FozDoAmazonasPhase2.shp by org.geotools.data.shapefile.ng.shp.ShapefileReader
Feb 22, 2013 12:03:54 PM org.geotools.data.shapefile.ng.files.ShpFiles logCurrentLockers
SEVERE: The following locker still has a lock: read on file:/tmp/24/FozDoAmazonasPhase2.shx by org.geotools.data.shapefile.ng.shp.IndexFile
Feb 22, 2013 12:03:54 PM org.geotools.data.shapefile.ng.files.ShpFiles logCurrentLockers
SEVERE: The following locker still has a lock: read on file:/tmp/24/FozDoAmazonasPhase2.dbf by org.geotools.data.shapefile.ng.dbf.DbaseFileReader
Feb 22, 2013 12:04:39 PM com.spectrumasa.mcgeotools.App main
SEVERE: null
java.lang.IllegalArgumentException: Expected requestor [email protected] to have locked the url but it does not hold the lock for the URL
at org.geotools.data.shapefile.ng.files.ShpFiles.unlockRead(ShpFiles.java:433)
at org.geotools.data.shapefile.ng.files.FileChannelDecorator.implCloseChannel(FileChannelDecorator.java:149)
at java.nio.channels.spi.AbstractInterruptibleChannel.close(AbstractInterruptibleChannel.java:114)
at org.geotools.data.shapefile.ng.dbf.DbaseFileReader.close(DbaseFileReader.java:279)
at org.geotools.data.shapefile.ng.ShapefileFeatureReader.close(ShapefileFeatureReader.java:248)
at org.geotools.data.store.ContentFeatureCollection$WrappingFeatureIterator.close(ContentFeatureCollection.java:227)
at com.spectrumasa.mcgeotools.convert.Converter.runConvert(Converter.java:487)
at com.spectrumasa.mcgeotools.App.main(App.java:100)
bạn có đóng FileReader để giải phóng tệp không? – Hekmatof
ý của bạn là gì? Tôi chưa mở tập tin. Tôi chạy lệnh trong cli – shorif2000
Tôi cũng nghĩ bạn đã đóng các tệp của mình? – AlexWien