Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eric Duminil
RegionChooser
Commits
135d0bc4
Commit
135d0bc4
authored
2 years ago
by
Eric Duminil
Browse files
Options
Download
Email Patches
Plain Diff
Allow extractor to work on multiple CityGMLs.
parent
3a9b7c9d
Pipeline
#6952
failed with stage
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/main/java/eu/simstadt/regionchooser/RegionChooserBrowser.java
+1
-0
.../java/eu/simstadt/regionchooser/RegionChooserBrowser.java
src/main/java/eu/simstadt/regionchooser/RegionExtractor.java
+30
-20
src/main/java/eu/simstadt/regionchooser/RegionExtractor.java
src/test/java/eu/simstadt/regionchooser/RegionExtractorTests.java
+22
-9
.../java/eu/simstadt/regionchooser/RegionExtractorTests.java
with
53 additions
and
29 deletions
+53
-29
src/main/java/eu/simstadt/regionchooser/RegionChooserBrowser.java
+
1
-
0
View file @
135d0bc4
...
...
@@ -77,6 +77,7 @@ public void downloadRegionFromCityGML(String wktPolygon, String project, String
File
buildingIdsFile
=
selectSaveFileWithDialog
(
project
,
citygml
,
"selected_region"
);
if
(
buildingIdsFile
!=
null
)
{
try
(
BufferedWriter
writer
=
Files
.
newBufferedWriter
(
buildingIdsFile
.
toPath
()))
{
//NOTE: isn't there a better way??
writer
.
write
(
sb
.
toString
());
}
}
...
...
This diff is collapsed.
Click to expand it.
src/main/java/eu/simstadt/regionchooser/RegionExtractor.java
+
30
-
20
View file @
135d0bc4
...
...
@@ -27,13 +27,14 @@
private
static
final
GeometryFactory
gf
=
new
GeometryFactory
();
/**
* Main method behind RegionChooser. Given
a
CityGML (as Path) and a geometry (as Well-known text POLYGON, in the
* Main method behind RegionChooser. Given CityGML
s
(as Path
[]
) and a geometry (as Well-known text POLYGON, in the
* same coordinate system as the CityGML), it iterates over each Building and checks if the building is inside the
* geometry. It only works with CityGML files smaller than 2GB. It uses VTD-XML parser instead of a whole
* Simstadt/Citydoctor/Citygml model.
*
* @param wktPolygon
* @param
citygmlPath
* @param
string
* @param
srsName
* @param
citygmlPaths
*
*
* @return a StringBuffer, full with the extracted Citygml, including header, buildings and footer.
...
...
@@ -44,8 +45,7 @@
* @throws XPathParseException
* @throws NumberFormatException
*/
//TODO: Try with multiple paths
static
StringBuilder
selectRegionDirectlyFromCityGML
(
String
wktPolygon
,
String
srsName
,
Path
citygmlPath
)
static
StringBuilder
selectRegionDirectlyFromCityGML
(
String
wktPolygon
,
String
srsName
,
Path
...
citygmlPaths
)
throws
ParseException
,
XPathParseException
,
NavException
,
IOException
{
int
buildingsCount
=
0
;
...
...
@@ -53,23 +53,33 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s
StringBuilder
sb
=
new
StringBuilder
();
Geometry
poly
=
wktReader
.
read
(
wktPolygon
);
CityGmlIterator
citygml
=
new
CityGmlIterator
(
citygmlPath
);
for
(
BuildingXmlNode
buildingXmlNode
:
citygml
)
{
if
(
buildingsCount
==
0
)
{
sb
.
append
(
replaceEnvelopeInHeader
(
citygml
.
getHeader
(),
poly
.
getEnvelopeInternal
(),
srsName
));
}
buildingsCount
+=
1
;
if
(
buildingXmlNode
.
hasCoordinates
())
{
Coordinate
coord
=
new
Coordinate
(
buildingXmlNode
.
x
,
buildingXmlNode
.
y
);
Point
point
=
gf
.
createPoint
(
coord
);
if
(
point
.
within
(
poly
))
{
foundBuildingsCount
++;
sb
.
append
(
buildingXmlNode
.
toString
());
CityGmlIterator
citygml
=
null
;
for
(
int
i
=
0
;
i
<
citygmlPaths
.
length
;
i
++)
{
Path
citygmlPath
=
citygmlPaths
[
i
];
LOGGER
.
info
(
"Parsing "
+
citygmlPath
);
citygml
=
new
CityGmlIterator
(
citygmlPath
);
for
(
BuildingXmlNode
buildingXmlNode
:
citygml
)
{
if
(
buildingsCount
==
0
)
{
sb
.
append
(
replaceEnvelopeInHeader
(
citygml
.
getHeader
(),
poly
.
getEnvelopeInternal
(),
srsName
));
}
buildingsCount
+=
1
;
if
(
buildingXmlNode
.
hasCoordinates
())
{
Coordinate
coord
=
new
Coordinate
(
buildingXmlNode
.
x
,
buildingXmlNode
.
y
);
Point
point
=
gf
.
createPoint
(
coord
);
if
(
point
.
within
(
poly
))
{
foundBuildingsCount
++;
sb
.
append
(
buildingXmlNode
.
toString
());
}
}
if
(
buildingsCount
%
1000
==
0
)
{
LOGGER
.
info
(
"1000 buildings parsed"
);
}
}
if
(
buildingsCount
%
1000
==
0
)
{
LOGGER
.
info
(
"1000 buildings parsed"
);
}
}
if
(
citygml
==
null
)
{
throw
new
IllegalArgumentException
(
"There should be at least one citygml"
);
}
LOGGER
.
info
(
"Buildings found in selected region "
+
foundBuildingsCount
);
...
...
This diff is collapsed.
Click to expand it.
src/test/java/eu/simstadt/regionchooser/RegionExtractorTests.java
+
22
-
9
View file @
135d0bc4
...
...
@@ -10,7 +10,7 @@
import
org.junit.jupiter.api.Test
;
public
class
RegionExtractorTests
class
RegionExtractorTests
{
private
static
final
String
EPSG_32118
=
"EPSG:32118"
;
private
static
final
String
CITY_OBJECT_MEMBER_REGEX
=
"<(core:)?cityObjectMember"
;
...
...
@@ -20,7 +20,7 @@
private
static
final
String
CORE_CITY_MODEL_FOOTER
=
"</core:CityModel"
;
private
static
final
Path
TEST_REPOSITORY
=
Paths
.
get
(
"src/test/resources/testdata/"
);
public
static
int
countRegexMatches
(
String
str
,
String
subStr
)
{
static
int
countRegexMatches
(
String
str
,
String
subStr
)
{
Pattern
pattern
=
Pattern
.
compile
(
subStr
);
Matcher
matcher
=
pattern
.
matcher
(
str
);
int
count
=
0
;
...
...
@@ -31,7 +31,7 @@ public static int countRegexMatches(String str, String subStr) {
}
@Test
public
void
testExtract3BuildingsFromGSK3Model
()
throws
Throwable
{
void
testExtract3BuildingsFromGSK3Model
()
throws
Throwable
{
//NOTE: Small region around Martinskirche in Grünbühl
String
wktPolygon
=
"POLYGON((3515848.896028535 5415823.108586172,3515848.9512289143 5415803.590347393,3515829.0815150724 5415803.338023346,3515830.9784850604 5415793.437034622,3515842.0946056456 5415793.272282251,3515843.3515515197 5415766.204935087,3515864.1064344468 5415766.557899496,3515876.489172751 5415805.433782301,3515876.343844858 5415822.009293416,3515848.896028535 5415823.108586172))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"Gruenbuehl.proj/20140218_Gruenbuehl_LOD2.gml"
);
...
...
@@ -53,7 +53,7 @@ public void testExtract3BuildingsFromGSK3Model() throws Throwable {
}
@Test
public
void
testExtractBuildingsWithoutCommentsInBetween
()
throws
Throwable
{
void
testExtractBuildingsWithoutCommentsInBetween
()
throws
Throwable
{
//NOTE: Small region around WashingtonSquare
String
wktPolygon
=
"POLYGON((300259.78663489706 62835.835907766595,300230.33294975647 62792.0482567884,300213.5667431851 62770.83143720031,300183.6592861123 62730.20347659383,300252.9947486632 62676.938468840905,300273.3862256562 62701.767105345614,300257.5250407747 62715.760413539596,300308.2754543957 62805.14198211394,300259.78663489706 62835.835907766595))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"NewYork.proj/ManhattanSmall.gml"
);
...
...
@@ -72,7 +72,7 @@ public void testExtractBuildingsWithoutCommentsInBetween() throws Throwable {
}
@Test
public
void
testExtractBuildingsAndChangeEnvelope
()
throws
Throwable
{
void
testExtractBuildingsAndChangeEnvelope
()
throws
Throwable
{
String
wktPolygon
=
"POLYGON((299761.8123557725 61122.68126771413,299721.46983062755 61058.11626595352,299780.84627343423 61021.99295737501,299823.9079725632 61083.3979344517,299761.8123557725 61122.68126771413))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml"
);
String
familyCourtBuilding
=
RegionExtractor
...
...
@@ -96,7 +96,7 @@ public void testExtractBuildingsAndChangeEnvelope() throws Throwable {
}
@Test
public
void
testExtract0BuildingsWithWrongCoordinates
()
throws
Throwable
{
void
testExtract0BuildingsWithWrongCoordinates
()
throws
Throwable
{
//NOTE: Small region, far away from NYC
String
wktPolygon
=
"POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"NewYork.proj/ManhattanSmall.gml"
);
...
...
@@ -108,7 +108,7 @@ public void testExtract0BuildingsWithWrongCoordinates() throws Throwable {
}
@Test
public
void
testExtract0BuildingsFromEmptyGML
()
throws
Throwable
{
void
testExtract0BuildingsFromEmptyGML
()
throws
Throwable
{
//NOTE: Small region, with too many spaces between coordinates
String
wktPolygon
=
"POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"NewYork.proj/empty_model.gml"
);
...
...
@@ -120,7 +120,7 @@ public void testExtract0BuildingsFromEmptyGML() throws Throwable {
}
@Test
public
void
testExtract0BuildingsFromWeirdGML
()
throws
Throwable
{
void
testExtract0BuildingsFromWeirdGML
()
throws
Throwable
{
//NOTE: Small region, with too many spaces between coordinates
String
wktPolygon
=
"POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"NewYork.proj/broken_nyc_lod2.gml"
);
...
...
@@ -132,11 +132,24 @@ public void testExtract0BuildingsFromWeirdGML() throws Throwable {
}
@Test
public
void
testExtractBuildingsFromCitygmlWithoutZinEnvelope
()
throws
Throwable
{
void
testExtractBuildingsFromCitygmlWithoutZinEnvelope
()
throws
Throwable
{
String
wktPolygon
=
"POLYGON((3512683.1280912133 5404783.732132129,3512719.1608604863 5404714.627650777,3512831.40076119 5404768.344155442,3512790.239106708 5404838.614891164,3512683.1280912133 5404783.732132129))"
;
Path
citygmlPath
=
TEST_REPOSITORY
.
resolve
(
"Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml"
);
String
emptyGMLString
=
RegionExtractor
.
selectRegionDirectlyFromCityGML
(
wktPolygon
,
"EPSG:31463"
,
citygmlPath
)
.
toString
();
assertEquals
(
2
,
countRegexMatches
(
emptyGMLString
,
"<bldg:Building gml:id"
));
}
@Test
void
testExtractBuildingsFrom2Citygmls
()
throws
Throwable
{
String
wktPolygon
=
"POLYGON((3512984.7003764412 5405148.310572891,3513038.6360455155 5405010.072163861,3513142.7277745553 5405004.02571992,3514204.1661769524 5405563.192081669,3514399.2818417274 5405720.905457244,3514291.6158155007 5405896.706492759,3512984.7003764412 5405148.310572891))"
;
Path
citygml1
=
TEST_REPOSITORY
.
resolve
(
"Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml"
);
Path
citygml2
=
TEST_REPOSITORY
.
resolve
(
"Stuttgart.proj/Stöckach_überarbeitete GML-NoBuildingPart.gml"
);
String
emptyGMLString
=
RegionExtractor
.
selectRegionDirectlyFromCityGML
(
wktPolygon
,
"EPSG:31463"
,
citygml1
,
citygml2
).
toString
();
assertEquals
(
17
+
3
,
countRegexMatches
(
emptyGMLString
,
"<bldg:Building gml:id"
));
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets