Revision: 6500 http://sourceforge.net/p/jump-pilot/code/6500 Author: edso Date: 2020-09-20 18:57:11 +0000 (Sun, 20 Sep 2020) Log Message: ----------- implement Taskmonitor and Cancelling in ShapeFileReader
Modified Paths: -------------- core/trunk/src/com/vividsolutions/jump/io/ShapefileReader.java core/trunk/src/com/vividsolutions/jump/io/datasource/ReaderWriterFileDataSource.java core/trunk/src/org/geotools/shapefile/Shapefile.java Added Paths: ----------- core/trunk/src/com/vividsolutions/jump/task/TaskCancelledException.java Modified: core/trunk/src/com/vividsolutions/jump/io/ShapefileReader.java =================================================================== --- core/trunk/src/com/vividsolutions/jump/io/ShapefileReader.java 2020-09-20 18:51:52 UTC (rev 6499) +++ core/trunk/src/com/vividsolutions/jump/io/ShapefileReader.java 2020-09-20 18:57:11 UTC (rev 6500) @@ -132,8 +132,10 @@ throw new IllegalParametersException(I18N.get("io.ShapefileReader.no-file-property-specified")); } - //okay, we have .shp and .dbf file paths, lets create Shapefile and DbfFile + // okay, we have .shp and .dbf file paths, lets create Shapefile and DbfFile Shapefile myshape = getShapefile(shpFileName, dp.getProperty(DataSource.COMPRESSED_KEY)); + // attach task monitor + myshape.setTaskMonitor(getTaskMonitor()); // charset used to read dbf (one charset defined by cpg file, // charset defined in dp or default platform charset) @@ -147,7 +149,7 @@ GeometryFactory factory = new GeometryFactory(); GeometryCollection collection; // Read the shapefile either from shx (if provided) or directly from shp - collection = shx == null ? myshape.read(factory) : myshape.readFromIndex(factory, shx); + collection = shx == null ? myshape.read(factory) : myshape.readFromIndex(factory, shx); // Minimal schema for FeatureCollection (if no dbf is provided) FeatureSchema fs = new FeatureSchema(); Modified: core/trunk/src/com/vividsolutions/jump/io/datasource/ReaderWriterFileDataSource.java =================================================================== --- core/trunk/src/com/vividsolutions/jump/io/datasource/ReaderWriterFileDataSource.java 2020-09-20 18:51:52 UTC (rev 6499) +++ core/trunk/src/com/vividsolutions/jump/io/datasource/ReaderWriterFileDataSource.java 2020-09-20 18:57:11 UTC (rev 6500) @@ -45,6 +45,7 @@ import com.vividsolutions.jump.io.DriverProperties; import com.vividsolutions.jump.io.JUMPReader; import com.vividsolutions.jump.io.JUMPWriter; +import com.vividsolutions.jump.task.TaskCancelledException; import com.vividsolutions.jump.task.TaskMonitor; import com.vividsolutions.jump.task.TaskMonitorSupport; import com.vividsolutions.jump.task.TaskMonitorUtil; @@ -107,7 +108,13 @@ exceptions.addAll(reader.getExceptions()); return fc; - } catch (Exception e) { + } + // we were cancelled + catch (TaskCancelledException e) { + // "nothing to see here. please disperse!" + return null; + } + catch (Exception e) { exceptions.add(e); return null; // <<TODO>> Modify Readers and Writers to store exceptions and Added: core/trunk/src/com/vividsolutions/jump/task/TaskCancelledException.java =================================================================== --- core/trunk/src/com/vividsolutions/jump/task/TaskCancelledException.java (rev 0) +++ core/trunk/src/com/vividsolutions/jump/task/TaskCancelledException.java 2020-09-20 18:57:11 UTC (rev 6500) @@ -0,0 +1,13 @@ +package com.vividsolutions.jump.task; + +import com.vividsolutions.jump.JUMPException; + +/** + * a simple way to signal whatever was done down the line + * was cancelled whereever this was thrown + */ +public class TaskCancelledException extends JUMPException { + public TaskCancelledException() { + super(""); + } +} Property changes on: core/trunk/src/com/vividsolutions/jump/task/TaskCancelledException.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: core/trunk/src/org/geotools/shapefile/Shapefile.java =================================================================== --- core/trunk/src/org/geotools/shapefile/Shapefile.java 2020-09-20 18:51:52 UTC (rev 6499) +++ core/trunk/src/org/geotools/shapefile/Shapefile.java 2020-09-20 18:57:11 UTC (rev 6500) @@ -7,8 +7,11 @@ import java.util.ArrayList; import com.vividsolutions.jts.geom.*; +import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.io.EndianDataInputStream; import com.vividsolutions.jump.io.EndianDataOutputStream; +import com.vividsolutions.jump.task.*; +import com.vividsolutions.jump.util.Timer; import com.vividsolutions.jump.workbench.Logger; /** @@ -28,7 +31,7 @@ * * <a href="mailto:j.macg...@geog.leeds.ac.uk">Mail the Author</a> */ -public class Shapefile { +public class Shapefile implements TaskMonitorSupport { static final int SHAPEFILE_ID = 9994; static final int VERSION = 1000; @@ -131,7 +134,7 @@ errors = 0; int count = 1; - + Reporter r = new Reporter(); while(true){ int recordNumber=file.readIntBE(); pos+=2; if (recordNumber != count) { @@ -143,6 +146,7 @@ Logger.warn("found a negative content length (" + contentLength + ")"); continue; } + long lastUpdatedAt = 0L; try{ body = handler.read(file,geometryFactory,contentLength); Logger.debug("" + recordNumber + " : from " + (pos-4) + " for " + contentLength + " (" + body.getNumPoints() + " pts)"); @@ -149,8 +153,18 @@ pos += contentLength; list.add(body); count++; + // report to gui + r.report(count); + // cancel if needed + if (getTaskMonitor().isCancelRequested()) + throw new TaskCancelledException(); if (body.getUserData() != null) errors++; - } catch(Exception e) { + } + // we're cancelled + catch (TaskCancelledException e) { + throw e; + } + catch(Exception e) { Logger.warn("Error processing record " +recordNumber + " : " + e.getMessage(), e); errors++; } @@ -393,6 +407,7 @@ if(handler==null) throw new ShapeTypeNotSupportedException("Unsupported shape type:" + type); int recordNumber = 0; + Reporter r = new Reporter(); while (true) { long offset = shx.readIntBE() & 0x00000000ffffffffL; int length = shx.readIntBE(); @@ -405,8 +420,18 @@ body = handler.read(shp, geometryFactory, length); Logger.trace("" + recordNumber + " : from " + offset + " for " + length + " (" + body.getNumPoints() + " pts)"); list.add(body); + // report to gui + r.report(recordNumber); + // cancel if needed + if (getTaskMonitor().isCancelRequested()) + throw new TaskCancelledException(); if (body.getUserData() != null) errors++; - } catch(Exception e) { + } + // we're cancelled + catch (TaskCancelledException e) { + throw e; + } + catch(Exception e) { Logger.warn("Error processing record " + recordNumber + ": " + e.getMessage(), e); Logger.warn("an empty Geometry has been returned"); list.add(handler.getEmptyGeometry(geometryFactory)); @@ -426,5 +451,61 @@ return geometryFactory.createGeometryCollection(list.toArray(new Geometry[]{})); } + + private TaskMonitor taskMonitor = new DummyTaskMonitor(); + + public void setTaskMonitor(TaskMonitor taskMonitor) { + this.taskMonitor = taskMonitor; + } + + public TaskMonitor getTaskMonitor() { + return taskMonitor; + } + + /** + * this class autotunes actual reporting to the samplePeriod given. + * turns out calling Timer.now() on every count slows down reading, + * who would have guessed ;) + * + * TODO: this probably needs to be made a generic class to be usable + * in other readers/writers as well. + * + * @author ed + */ + private class Reporter { + long init = Timer.now(); + int sampleSize = -1; + long samplePeriod = 500; //ms + int lastUpdateCount = 0; + long lastUpdateTime = init; + + public void report(int count) { + // show status every sampleSize calculated by the samplePeriod given + if (sampleSize < 0 && (init + samplePeriod) <= Timer.now()) { + // init a senseful samplesize (number of records counted in samplePeriod) + sampleSize = count; + print(count); + } + else if (sampleSize >= 0 && lastUpdateCount + sampleSize <= count ) { + long msSince = Timer.milliSecondsSince(lastUpdateTime); + // double sample size if passed time since last update is zero somehow + double factor = msSince>0 ? samplePeriod/(double)msSince : 2.0; + // update samplesize, make sure it'll never be zero + int newSampleSize = (int)(factor*sampleSize); + sampleSize = newSampleSize>0?newSampleSize:1; + print(count); + } + return; + } + + private void print(int count) { + lastUpdateTime = Timer.now(); + lastUpdateCount = count; + TaskMonitorUtil.report(getTaskMonitor(), + I18N.getMessage("Reader.parsed-{0}-features", String.format("%,10d", count))); + } + + } + } _______________________________________________ Jump-pilot-devel mailing list Jump-pilot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel