diff --git a/.classpath b/.classpath
index 18bef9fbae36b44b8666306ff38b40a8eb38ce76..0089bc9e4b96450df0e30611c4d29c34d13d461f 100644
--- a/.classpath
+++ b/.classpath
@@ -6,5 +6,6 @@
+
diff --git a/lib/vtd-xml_2_13_1.jar b/lib/vtd-xml_2_13_1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..1e021e5f680589442fc8a3bc478b7049c6f369d4
Binary files /dev/null and b/lib/vtd-xml_2_13_1.jar differ
diff --git a/src/eu/simstadt/regionchooser/RegionChooserBrowser.java b/src/eu/simstadt/regionchooser/RegionChooserBrowser.java
index 0bd52d2fb90b11f3e689eff569e06830190c0233..e7efcc364ae40c703ce6f15adb61681b884ad077 100644
--- a/src/eu/simstadt/regionchooser/RegionChooserBrowser.java
+++ b/src/eu/simstadt/regionchooser/RegionChooserBrowser.java
@@ -18,6 +18,9 @@
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
+import com.ximpleware.NavException;
+import com.ximpleware.XPathEvalException;
+import com.ximpleware.XPathParseException;
import eu.simstadt.nf4j.ExportJobFromJavaFXRegionChooser;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
@@ -94,7 +97,8 @@ public void extractZIPtoGML(String zipFilename) throws IOException {
public void downloadRegionFromCityGML(String wktPolygon, String project, String citygml, String srsName)
throws IOException,
- ParseException, SAXParseException, XMLStreamException {
+ ParseException, SAXParseException, XMLStreamException, NumberFormatException, XPathParseException,
+ NavException, XPathEvalException {
StringBuffer sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath(project, citygml), wktPolygon,
srsName);
diff --git a/src/eu/simstadt/regionchooser/RegionExtractor.java b/src/eu/simstadt/regionchooser/RegionExtractor.java
index 6ccdd19cc55f48bdba25627e2b7138d7eb9a77d1..f859ced2135771620ef1010200e4b9aa94daa483 100644
--- a/src/eu/simstadt/regionchooser/RegionExtractor.java
+++ b/src/eu/simstadt/regionchooser/RegionExtractor.java
@@ -1,11 +1,9 @@
package eu.simstadt.regionchooser;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.logging.Logger;
import javax.xml.stream.XMLStreamException;
import org.xml.sax.SAXParseException;
import com.vividsolutions.jts.geom.Coordinate;
@@ -14,95 +12,90 @@
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
-import de.hft.stuttgart.citydoctor.writer.CityDoctorModel;
-import eu.simstadt.geo.GeoCoordinatesAccessor;
+import com.ximpleware.AutoPilot;
+import com.ximpleware.NavException;
+import com.ximpleware.VTDGen;
+import com.ximpleware.VTDNav;
+import com.ximpleware.XPathEvalException;
+import com.ximpleware.XPathParseException;
+import sun.misc.Launcher;
public class RegionExtractor
{
static private WKTReader wktReader = new WKTReader();
+ private static final Logger LOGGER = Logger.getLogger(Launcher.class.getName());
+
static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, String wktPolygon, String srsName)
- throws IOException, ParseException, SAXParseException, XMLStreamException {
+ throws SAXParseException, XMLStreamException, ParseException, XPathParseException, NavException,
+ NumberFormatException, XPathEvalException, IOException {
Geometry poly = wktReader.read(wktPolygon);
-
final GeometryFactory gf = new GeometryFactory();
- //TODO: Don't read all the file. Not possible for 15GB gml files
- String s = new String(Files.readAllBytes(citygmlPath), Charset.defaultCharset());
+ StringBuffer sb = new StringBuffer();
- Pattern cityObjectPattern = Pattern
- .compile("(?s)<(core:)?cityObjectMember[^>]*>.*?<\\/(core:)?cityObjectMember>\\s*");
+ int foundBuildingsCount = 0;
+ int buildingsCount = 0;
+ long offsetAndLength;
+ int buildingOffset = 0;
+ int buildingLength = 0;
+ int coordinatesOffset = 0;
+ int coordinatesLength = 0;
+ VTDGen parser = new VTDGen();
+ if (parser.parseFile(citygmlPath.toString(), false)) {
- Pattern coordinatesPattern = null;
- switch (srsName) {
- case "EPSG:31467":
- coordinatesPattern = Pattern
- .compile("(?> 32);
+ String cityObject = navigator.toRawString(buildingOffset, buildingLength);
+ // Add header
+ if (buildingsCount == 0) {
+ sb.append(navigator.toRawString(0, buildingOffset));
+ }
+ buildingsCount += 1;
+ if (buildingsCount % 1000 == 0) {
+ LOGGER.info("1000 buildings parsed");
+ }
- throw new IllegalArgumentException("Sorry. " + srsName + " is not supported yet.");
- }
+ int coordinatesCount = 0;
+ double xTotal = 0;
+ double yTotal = 0;
- Matcher cityObjectMatcher = cityObjectPattern.matcher(s);
- StringBuffer sb = new StringBuffer();
- int i = 0;
- while (cityObjectMatcher.find())
+ while (coordinatesFinder.evalXPath() != -1) {
+ offsetAndLength = navigator.getContentFragment();
+ coordinatesOffset = (int) offsetAndLength;
+ coordinatesLength = (int) (offsetAndLength >> 32);
+ String posList = navigator.toRawString(coordinatesOffset, coordinatesLength);
+ String[] coordinates = posList.split(" ");
+ for (int k = 0; k < coordinates.length; k = k + 3) {
+ coordinatesCount++;
+ xTotal += Double.valueOf(coordinates[k]);
+ yTotal += Double.valueOf(coordinates[k + 1]);
+ }
+ }
- {
- cityObjectMatcher.appendReplacement(sb, "");
- String cityObject = cityObjectMatcher.group();
- Matcher coordinatesMatcher = coordinatesPattern.matcher(cityObject);
- int coordinatesCount = 0;
- double xTotal = 0;
- double yTotal = 0;
- while (coordinatesMatcher.find()) {
- coordinatesCount++;
- xTotal += Double.valueOf(coordinatesMatcher.group(1));
- yTotal += Double.valueOf(coordinatesMatcher.group(2));
- }
- double x = xTotal / coordinatesCount;
- double y = yTotal / coordinatesCount;
- Coordinate coord = new Coordinate(x, y);
- Point point = gf.createPoint(coord);
- if (point.within(poly)) {
- i++;
- sb.append(cityObject);
+ double x = xTotal / coordinatesCount;
+ double y = yTotal / coordinatesCount;
+ Coordinate coord = new Coordinate(x, y);
+ Point point = gf.createPoint(coord);
+ if (point.within(poly)) {
+ foundBuildingsCount++;
+ sb.append(cityObject);
+ }
}
+ LOGGER.info("Buildings found in selected region " + foundBuildingsCount);
+ int footerOffset = buildingOffset + buildingLength;
+ int footerLength = (int) (Files.size(citygmlPath) - footerOffset);
+ sb.append(navigator.toRawString(footerOffset, footerLength));
}
- System.out.println("Buildings found in selected region " + i);
- if (i > 0)
- {
- cityObjectMatcher.appendTail(sb);
- }
return sb;
}
-
}
diff --git a/src/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js b/src/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js
index 8c5dd114441b436215d4b73dd3c762b07b1fd944..c0c4d7855f4a420f3b6e75a95d6861b40e6e7a2b 100644
--- a/src/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js
+++ b/src/eu/simstadt/regionchooser/website/script/simstadt_openlayers.js
@@ -310,7 +310,7 @@ function downloadRegionFromNovaFACTORY(i) {
}
function sketchAsWKT(srsName) {
- console.log(srsName);
+ console.log(srsName); //TODO: Check if proj4 knows this coordinate system
srsName = (typeof srsName === 'undefined') ? 'EPSG:4326' : srsName;
var wktFormat = new ol.format.WKT();
return wktFormat.writeFeature(sketch, {
diff --git a/test/eu/simstadt/regionchooser/test/RegionExtractorTests.java b/test/eu/simstadt/regionchooser/test/RegionExtractorTests.java
index ab319cf9520e5cfbda45841725c696fdb641dffe..b75b2db6bc1c42c167e5f9a6da8dc60fdadc253b 100644
--- a/test/eu/simstadt/regionchooser/test/RegionExtractorTests.java
+++ b/test/eu/simstadt/regionchooser/test/RegionExtractorTests.java
@@ -35,6 +35,8 @@ public void testExtract3BuildingsFromGSK3Model() throws Throwable {
assertTrue(churchGMLString.contains("DEBW_LOD2_203056"));
assertTrue(churchGMLString.contains("DEBW_LOD2_2869"));
assertTrue(churchGMLString.contains("DEBW_LOD2_2909"));
+ assertTrue(churchGMLString.contains("