Привет, сообщество StackOverflow, в настоящее время я пытаюсь написать небольшой инструмент, который считывает геометрию шейп-файлов (мультиполигоны/многоугольники) и записывает их WKT-представления в текстовый файл. Для этого я использую GeoTools, и мне удалось заставить его работать нормально, из-за того, что я конвертирую файлы с примерно 5000000 полигонов / мультиполигонов, это занимает довольно много времени.
Итак, мой вопрос:
Можно ли прикрутить загрузку/запись файла? Поскольку я использую SimpleFeatureIterator, я не понял, как реализовать многопоточность.
Есть ли способ сделать это? Или кто-нибудь знает, как получить геометрию шейп-файлов без использования итератора?
Это мой код:
Этот метод просто устанавливает File Chooser и запускает поток для каждого выбранного файла.
protected static void printGeometriesToFile() {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"shape-files", "shp");
chooser.setFileFilter(filter);
chooser.setDialogTitle("Choose the file to be converted.");
chooser.setMultiSelectionEnabled(true);
File[] files = null;
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
files = chooser.getSelectedFiles();
}
for (int i = 0; i < files.length; i++) {
MultiThreadWriter writer = new MultiThreadWriter(files[i]);
writer.start();
}
}
Класс для многопоточности:
class MultiThreadWriter extends Thread {
private File threadFile;
MultiThreadWriter(File file) {
threadFile = file;
System.out.println("Starting Thread for " + file.getName());
}
public void run() {
try {
File outputFolder = new File(threadFile.getAbsolutePath() + ".txt");
FileOutputStream fos = new FileOutputStream(outputFolder);
System.out.println("Now writing data to file: " + outputFolder.getName());
FileDataStore store = FileDataStoreFinder.getDataStore(threadFile);
SimpleFeatureSource featureSource = store.getFeatureSource();
SimpleFeatureCollection featureCollection = featureSource.getFeatures();
SimpleFeatureIterator featureIterator = featureCollection.features();
int pos = 0;
while (featureIterator.hasNext()) {
fos.write((geometryToByteArray((Polygonal) featureIterator.next().getAttribute("the_geom"))));
pos++;
System.out.println("The file " + threadFile.getName() + "'s current positon is: " + pos);
}
fos.close();
System.out.println("Finished writing.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Это всего лишь вспомогательная функция, которая преобразует мультиполигоны в полигоны и возвращает их WKT-представление со знаком «|». как разделитель.
private byte[] geometryToByteArray(Polygonal polygonal) {
List<Polygon> polygonList;
String polygonString = "";
if (polygonal instanceof MultiPolygon) {
polygonList = GeometrieUtils.convertMultiPolygonToPolygonList((MultiPolygon) polygonal);
//The method above just converts a MultiPolygon into a list of Polygons
} else {
polygonList = new ArrayList<>(1);
polygonList.add((Polygon) polygonal);
}
for (int i = 0; i < polygonList.size(); i++) {
polygonString = polygonString + polygonList.get(i).toString() + "|";
}
return polygonString.getBytes();
}
}
Я знаю, что мой код не красивый и не хороший. Я только начал изучать Java и надеюсь, что скоро станет лучше.
искренне
я понятия не имею :)