Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
1fbe16e1
Commit
1fbe16e1
authored
Dec 12, 2025
by
Matthias Betz
Browse files
add xml validation to streaming processing
parent
82888d4b
Pipeline
#12286
passed with stage
in 2 minutes and 15 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorCheckResult/src/main/java/de/hft/stuttgart/citydoctor2/checkresult/CheckReport.java
View file @
1fbe16e1
...
@@ -22,6 +22,7 @@ import java.io.BufferedReader;
...
@@ -22,6 +22,7 @@ import java.io.BufferedReader;
import
java.io.FileReader
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.nio.file.Path
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -65,7 +66,11 @@ public class CheckReport {
...
@@ -65,7 +66,11 @@ public class CheckReport {
private
Map
<
String
,
FeatureReport
>
featureReports
;
private
Map
<
String
,
FeatureReport
>
featureReports
;
public
static
CheckReport
load
(
String
file
)
throws
CheckReportParseException
{
public
static
CheckReport
load
(
String
file
)
throws
CheckReportParseException
{
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
FileReader
(
file
)))
{
return
load
(
Path
.
of
(
file
));
}
public
static
CheckReport
load
(
Path
path
)
throws
CheckReportParseException
{
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
FileReader
(
path
.
toFile
())))
{
CheckReport
report
=
(
CheckReport
)
getContext
().
createUnmarshaller
().
unmarshal
(
new
InputSource
(
reader
));
CheckReport
report
=
(
CheckReport
)
getContext
().
createUnmarshaller
().
unmarshal
(
new
InputSource
(
reader
));
enrichReportStructure
(
report
);
enrichReportStructure
(
report
);
return
report
;
return
report
;
...
...
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlConsumer.java
View file @
1fbe16e1
...
@@ -32,6 +32,5 @@ public interface CityGmlConsumer {
...
@@ -32,6 +32,5 @@ public interface CityGmlConsumer {
}
}
// public void endOfFile();
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
View file @
1fbe16e1
...
@@ -102,618 +102,629 @@ import de.hft.stuttgart.quality.QualityADEModule;
...
@@ -102,618 +102,629 @@ import de.hft.stuttgart.quality.QualityADEModule;
*/
*/
public
class
CityGmlParser
{
public
class
CityGmlParser
{
private
static
final
String
CITY_OBJECT_MEMBER
=
"cityObjectMember"
;
private
static
final
String
CITY_OBJECT_MEMBER
=
"cityObjectMember"
;
private
static
final
String
WGS_84
=
"EPSG:4326"
;
private
static
final
String
WGS_84
=
"EPSG:4326"
;
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
CityGmlParser
.
class
);
private
static
final
Logger
logger
=
LogManager
.
getLogger
(
CityGmlParser
.
class
);
private
static
final
CRSFactory
CRS_FACTORY
=
new
CRSFactory
();
private
static
final
CRSFactory
CRS_FACTORY
=
new
CRSFactory
();
// EPSG:31467
// EPSG:31467
private
static
final
Pattern
P_EPSG
=
Pattern
.
compile
(
"^(EPSG:\\d+)$"
);
private
static
final
Pattern
P_EPSG
=
Pattern
.
compile
(
"^(EPSG:\\d+)$"
);
// urn:ogc:def:crs,crs:EPSG:6.12:31467,crs:EPSG:6.12:5783
// urn:ogc:def:crs,crs:EPSG:6.12:31467,crs:EPSG:6.12:5783
// or
// or
// urn:ogc:def:crs,crs:EPSG::28992
// urn:ogc:def:crs,crs:EPSG::28992
private
static
final
Pattern
P_OGC
=
Pattern
.
compile
(
"urn:ogc:def:crs,crs:EPSG:[\\d\\.]*:([\\d]+)\\D*"
);
private
static
final
Pattern
P_OGC
=
Pattern
.
compile
(
"urn:ogc:def:crs,crs:EPSG:[\\d\\.]*:([\\d]+)\\D*"
);
private
static
final
Pattern
P_OGC2
=
Pattern
.
compile
(
"urn:ogc:def:crs:EPSG:[\\d\\.]*:([\\d]+)\\D*"
);
private
static
final
Pattern
P_OGC2
=
Pattern
.
compile
(
"urn:ogc:def:crs:EPSG:[\\d\\.]*:([\\d]+)\\D*"
);
// urn:adv:crs:DE_DHDN_3GK3*DE_DHHN92_NH
// urn:adv:crs:DE_DHDN_3GK3*DE_DHHN92_NH
// urn:adv:crs:ETRS89_UTM32*DE_DHHN92_NH
// urn:adv:crs:ETRS89_UTM32*DE_DHHN92_NH
private
static
final
Pattern
P_URN
=
Pattern
.
compile
(
"urn:adv:crs:([^\\*]+)"
);
private
static
final
Pattern
P_URN
=
Pattern
.
compile
(
"urn:adv:crs:([^\\*]+)"
);
private
static
final
SAXParserFactory
FACTORY
;
private
static
final
SAXParserFactory
FACTORY
;
private
static
Proj4FileReader
csReader
=
new
Proj4FileReader
();
private
static
Proj4FileReader
csReader
=
new
Proj4FileReader
();
private
static
final
Pattern
P_VUNITS
=
Pattern
.
compile
(
"^\\+vunits=.+"
);
private
static
final
Pattern
P_VUNITS
=
Pattern
.
compile
(
"^\\+vunits=.+"
);
private
static
final
Pattern
P_GEOIDGRID
=
Pattern
.
compile
(
"^\\+geoidgrid=.+"
);
private
static
final
Pattern
P_GEOIDGRID
=
Pattern
.
compile
(
"^\\+geoidgrid=.+"
);
private
static
CityGMLContext
context
;
private
static
CityGMLContext
context
;
private
static
List
<
QName
>
chunkProperties
=
new
ArrayList
<>();
private
static
List
<
QName
>
chunkProperties
=
new
ArrayList
<>();
static
{
static
{
System
.
setProperty
(
"javax.xml.transform.TransformerFactory"
,
System
.
setProperty
(
"javax.xml.transform.TransformerFactory"
,
"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"
);
"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"
);
FACTORY
=
SAXParserFactory
.
newInstance
();
FACTORY
=
SAXParserFactory
.
newInstance
();
try
{
try
{
FACTORY
.
setFeature
(
XMLConstants
.
FEATURE_SECURE_PROCESSING
,
false
);
FACTORY
.
setFeature
(
XMLConstants
.
FEATURE_SECURE_PROCESSING
,
false
);
}
catch
(
SAXNotRecognizedException
|
SAXNotSupportedException
|
ParserConfigurationException
e
)
{
}
catch
(
SAXNotRecognizedException
|
SAXNotSupportedException
|
ParserConfigurationException
e
)
{
logger
.
catching
(
e
);
logger
.
catching
(
e
);
}
}
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_1_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_1_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_2_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_2_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_3_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
chunkProperties
.
add
(
new
QName
(
CityGMLConstants
.
CITYGML_3_0_CORE_NAMESPACE
,
CITY_OBJECT_MEMBER
));
}
}
private
CityGmlParser
()
{
private
CityGmlParser
()
{
}
}
public
static
synchronized
CityGMLContext
getContext
()
{
public
static
synchronized
CityGMLContext
setupContext
()
{
if
(
context
==
null
)
{
if
(
context
==
null
)
{
try
{
try
{
context
=
CityGMLContext
.
newInstance
(
CityGmlParser
.
class
.
getClassLoader
());
context
=
CityGMLContext
.
newInstance
(
CityGmlParser
.
class
.
getClassLoader
());
// also setup ades
// also setup ades
ADERegistry
adeRegistry
=
ADERegistry
.
getInstance
();
ADERegistry
adeRegistry
=
ADERegistry
.
getInstance
();
adeRegistry
.
loadADE
(
new
QualityADEContext
());
adeRegistry
.
loadADE
(
new
QualityADEContext
());
}
catch
(
CityGMLContextException
e
)
{
}
catch
(
CityGMLContextException
e
)
{
logger
.
fatal
(
Localization
.
getText
(
"CityGmlParser.creating4jContextFailed"
),
e
);
logger
.
fatal
(
Localization
.
getText
(
"CityGmlParser.creating4jContextFailed"
),
e
);
throw
new
IllegalStateException
(
"Unable to create citygml4j context"
);
throw
new
IllegalStateException
(
"Unable to create citygml4j context"
);
}
catch
(
ADEException
e
)
{
}
catch
(
ADEException
e
)
{
logger
.
fatal
(
Localization
.
getText
(
"CityGmlParser.creatingAdePluginsFailed"
),
e
);
logger
.
fatal
(
Localization
.
getText
(
"CityGmlParser.creatingAdePluginsFailed"
),
e
);
throw
new
IllegalStateException
(
"Unable to add ADE plugins to citygml4j"
);
throw
new
IllegalStateException
(
"Unable to add ADE plugins to citygml4j"
);
}
}
}
}
return
context
;
return
context
;
}
}
/**
/**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
* Parses a given CityGML file and collects the contained CityObject Features in
* <p/>
* a {@link CityDoctorModel}.
* The nested parse uses an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache}, which
* <p/>
* is not connected to the database.
* The nested parse uses an
* <p/>
* {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache
* Nested parsing should only be used for accessing Features in auxiliary, small CityGML files, e.g. parsing of
* UnconnectedCache}, which is not connected to the database.
* {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject} files.
* <p/>
*
* Nested parsing should only be used for accessing Features in auxiliary, small
* @param filePath String path to the file
* CityGML files, e.g. parsing of
* @param config Configuration of the parser
* {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject
* @return A {@link CityDoctorModel} object with the parsed Features
* LibraryObject} files.
* @throws CityGmlParseException if parsing of the CityGML-file failed
*
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* @param filePath String path to the file
*/
* @param config Configuration of the parser
public
static
CityDoctorModel
nestedCityGmlFileParse
(
String
filePath
,
ParserConfiguration
config
)
* @return A {@link CityDoctorModel} object with the parsed Features
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @throws CityGmlParseException if parsing of the CityGML-file failed
return
parseCityGmlFile
(
filePath
,
config
,
null
,
null
,
false
,
true
);
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
}
*/
public
static
CityDoctorModel
nestedCityGmlFileParse
(
String
filePath
,
ParserConfiguration
config
)
/**
throws
CityGmlParseException
,
InvalidGmlFileException
{
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
return
parseCityGmlFile
(
filePath
,
config
,
null
,
null
,
false
,
true
);
* <p/>
}
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
/**
*
* Parses a given CityGML file and collects the contained CityObject Features in
* @param filePath String path to the file
* a {@link CityDoctorModel}.
* @param config Configuration of the parser
* <p/>
* @return A {@link CityDoctorModel} object with the parsed Features
* Features are held in a non-persistent, embedded Database with an in-memory
* @throws CityGmlParseException if parsing of the CityGML-file failed
* upstream cache. Thus, strong references to {@link CityObject} are to be
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* avoided, to allow for the memory management of the cache.
*/
*
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
)
* @param filePath String path to the file
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @param config Configuration of the parser
return
parseCityGmlFile
(
filePath
,
config
,
null
,
null
);
* @return A {@link CityDoctorModel} object with the parsed Features
}
* @throws CityGmlParseException if parsing of the CityGML-file failed
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
*/
/**
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
)
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
throws
CityGmlParseException
,
InvalidGmlFileException
{
* <p/>
return
parseCityGmlFile
(
filePath
,
config
,
null
,
null
);
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
}
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
*
/**
* @param filePath String path to the file
* Parses a given CityGML file and collects the contained CityObject Features in
* @param config Configuration of the parser
* a {@link CityDoctorModel}.
* @param l Listener hook for tracking of parsing progress
* <p/>
* @return A {@link CityDoctorModel} object with the parsed Features
* Features are held in a non-persistent, embedded Database with an in-memory
* @throws CityGmlParseException if parsing of the CityGML-file failed
* upstream cache. Thus, strong references to {@link CityObject} are to be
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* avoided, to allow for the memory management of the cache.
*/
*
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
)
* @param filePath String path to the file
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @param config Configuration of the parser
return
parseCityGmlFile
(
filePath
,
config
,
l
,
null
);
* @param l Listener hook for tracking of parsing progress
}
* @return A {@link CityDoctorModel} object with the parsed Features
* @throws CityGmlParseException if parsing of the CityGML-file failed
/**
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
*/
* <p/>
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
)
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
throws
CityGmlParseException
,
InvalidGmlFileException
{
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
return
parseCityGmlFile
(
filePath
,
config
,
l
,
null
);
*
}
* @param filePath String path to the file
* @param config Configuration of the parser
/**
* @param l Listener hook for tracking of parsing progress
* Parses a given CityGML file and collects the contained CityObject Features in
* @param handler Validation handler for GML-file validation
* a {@link CityDoctorModel}.
* @return A {@link CityDoctorModel} object with the parsed Features
* <p/>
* @throws CityGmlParseException if parsing of the CityGML-file failed
* Features are held in a non-persistent, embedded Database with an in-memory
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* upstream cache. Thus, strong references to {@link CityObject} are to be
*/
* avoided, to allow for the memory management of the cache.
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
,
*
GMLValidationHandler
handler
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @param filePath String path to the file
return
parseCityGmlFile
(
filePath
,
config
,
l
,
handler
,
true
,
false
);
* @param config Configuration of the parser
}
* @param l Listener hook for tracking of parsing progress
* @param handler Validation handler for GML-file validation
/**
* @return A {@link CityDoctorModel} object with the parsed Features
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
* @throws CityGmlParseException if parsing of the CityGML-file failed
* <p/>
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
*/
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
public
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
,
*
GMLValidationHandler
handler
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @param filePath String path to the file
return
parseCityGmlFile
(
filePath
,
config
,
l
,
handler
,
true
,
false
);
* @param config Configuration of the parser
}
* @param l Listener hook for tracking of parsing progress
* @param handler Validation handler for GML-file validation
/**
* @param verbose If verbosity is enabled the parser will write info logs to the logger
* Parses a given CityGML file and collects the contained CityObject Features in
* @param unconnected If true the parser will use an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache}
* a {@link CityDoctorModel}.
* to collect the parsed CityObjects
* <p/>
* @return A {@link CityDoctorModel} object with the parsed Features
* Features are held in a non-persistent, embedded Database with an in-memory
* @throws CityGmlParseException if parsing of the CityGML-file failed
* upstream cache. Thus, strong references to {@link CityObject} are to be
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
* avoided, to allow for the memory management of the cache.
*/
*
private
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
,
* @param filePath String path to the file
GMLValidationHandler
handler
,
boolean
verbose
,
boolean
unconnected
)
* @param config Configuration of the parser
throws
CityGmlParseException
,
InvalidGmlFileException
{
* @param l Listener hook for tracking of parsing progress
CityGMLContext
context
=
getContext
();
* @param handler Validation handler for GML-file validation
Path
file
=
Paths
.
get
(
filePath
);
* @param verbose If verbosity is enabled the parser will write info logs to
List
<
String
>
validationIssues
=
Collections
.
emptyList
();
* the logger
if
(
config
.
getValidate
())
{
* @param unconnected If true the parser will use an
validationIssues
=
validateFile
(
context
,
handler
,
file
);
* {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache
}
* UnconnectedCache} to collect the parsed CityObjects
* @return A {@link CityDoctorModel} object with the parsed Features
try
{
* @throws CityGmlParseException if parsing of the CityGML-file failed
parseEpsgCodeFromFile
(
file
,
config
,
verbose
);
* @throws InvalidGmlFileException if the GMLValidationHandler found an error
CityGMLInputFactory
in
=
context
.
createCityGMLInputFactory
()
*/
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
private
static
CityDoctorModel
parseCityGmlFile
(
String
filePath
,
ParserConfiguration
config
,
ProgressListener
l
,
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
GMLValidationHandler
handler
,
boolean
verbose
,
boolean
unconnected
)
if
(
l
!=
null
)
{
throws
CityGmlParseException
,
InvalidGmlFileException
{
ois
.
addListener
(
l:
:
updateProgress
);
CityGMLContext
context
=
setupContext
();
}
Path
file
=
Paths
.
get
(
filePath
);
CityDoctorModel
model
=
readAndKeepFeatures
(
config
,
file
,
in
,
ois
,
verbose
,
unconnected
);
List
<
String
>
validationIssues
=
Collections
.
emptyList
();
for
(
String
xmlError
:
validationIssues
)
{
if
(
config
.
getValidate
())
{
model
.
addGlobalError
(
new
XMLValidationError
(
xmlError
));
validationIssues
=
validateFile
(
handler
,
file
);
}
}
return
model
;
try
{
}
parseEpsgCodeFromFile
(
file
,
config
,
verbose
);
}
catch
(
CityGMLReadException
|
IOException
e
)
{
CityGMLInputFactory
in
=
context
.
createCityGMLInputFactory
()
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
}
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
}
if
(
l
!=
null
)
{
ois
.
addListener
(
l:
:
updateProgress
);
}
CityDoctorModel
model
=
readAndKeepFeatures
(
config
,
file
,
in
,
ois
,
verbose
,
unconnected
);
public
static
void
streamCityGml
(
String
file
,
ParserConfiguration
config
,
CityGmlConsumer
cityObjectConsumer
,
for
(
String
xmlError
:
validationIssues
)
{
String
outputFile
)
throws
CityGmlParseException
{
model
.
addGlobalError
(
new
XMLValidationError
(
xmlError
));
Path
f
=
Paths
.
get
(
file
);
}
streamCityGml
(
f
,
config
,
null
,
cityObjectConsumer
,
outputFile
);
return
model
;
}
}
}
catch
(
CityGMLReadException
|
IOException
e
)
{
public
static
void
streamCityGml
(
File
file
,
ParserConfiguration
parserConfig
,
CityGmlConsumer
cityObjectConsumer
,
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
String
outputFile
)
throws
CityGmlParseException
{
}
streamCityGml
(
file
.
toPath
(),
parserConfig
,
null
,
cityObjectConsumer
,
outputFile
);
}
}
public
static
void
streamCityGml
(
String
file
,
ParserConfiguration
config
,
CityGmlConsumer
cityObjectConsumer
,
public
static
void
streamCityGml
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
String
outputFile
)
throws
CityGmlParseException
{
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
Path
f
=
Paths
.
get
(
file
);
parseEpsgCodeFromFile
(
file
,
config
,
true
);
streamCityGml
(
f
,
config
,
null
,
cityObjectConsumer
,
outputFile
);
startReadingCityGmlFile
(
file
,
config
,
l
,
cityObjectConsumer
,
outputFile
);
}
}
public
static
void
streamCityGml
(
File
file
,
ParserConfiguration
parserConfig
,
CityGmlConsumer
cityObjectConsumer
,
public
static
CityModel
parseOnlyCityModel
(
File
inputFile
)
throws
CityGmlParseException
{
String
outputFile
)
throws
CityGmlParseException
{
try
{
streamCityGml
(
file
.
toPath
(),
parserConfig
,
null
,
cityObjectConsumer
,
outputFile
);
CityGMLInputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
}
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
inputFile
))
{
public
static
void
streamCityGml
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
while
(
reader
.
hasNext
())
{
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGmlParseException
{
AbstractFeature
chunk
=
reader
.
next
();
parseEpsgCodeFromFile
(
file
,
config
,
true
);
if
(
chunk
instanceof
CityModel
cModel
)
{
startReadingCityGmlFile
(
file
,
config
,
l
,
cityObjectConsumer
,
outputFile
);
cModel
.
setCityObjectMembers
(
null
);
}
return
cModel
;
}
public
static
CityModel
parseOnlyCityModel
(
File
inputFile
)
throws
CityGmlParseException
{
}
try
{
}
CityGMLInputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
}
catch
(
CityGMLReadException
e
)
{
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
throw
new
CityGmlParseException
(
e
);
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
inputFile
))
{
}
while
(
reader
.
hasNext
())
{
throw
new
CityGmlParseException
(
"Did not find any CityModel in CityGML file"
);
AbstractFeature
chunk
=
reader
.
next
();
}
if
(
chunk
instanceof
CityModel
cModel
)
{
cModel
.
setCityObjectMembers
(
null
);
private
static
void
startReadingCityGmlFile
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
return
cModel
;
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
{
}
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
}
if
(
l
!=
null
)
{
}
ois
.
addListener
(
l:
:
updateProgress
);
}
catch
(
CityGMLReadException
e
)
{
}
throw
new
CityGmlParseException
(
e
);
readAndDiscardFeatures
(
file
,
config
,
ois
,
cityObjectConsumer
,
outputFile
);
}
}
catch
(
IOException
|
CityGMLReadException
e
)
{
throw
new
CityGmlParseException
(
"Did not find any CityModel in CityGML file"
);
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
());
}
logger
.
catching
(
Level
.
ERROR
,
e
);
}
private
static
void
startReadingCityGmlFile
(
Path
file
,
ParserConfiguration
config
,
ProgressListener
l
,
}
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
{
try
(
ObservedInputStream
ois
=
new
ObservedInputStream
(
file
.
toFile
()))
{
private
static
void
readAndDiscardFeatures
(
Path
file
,
ParserConfiguration
config
,
ObservedInputStream
ois
,
if
(
l
!=
null
)
{
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGMLReadException
{
ois
.
addListener
(
l:
:
updateProgress
);
Citygml3FeatureMapper
mapper
=
new
Citygml3FeatureMapper
(
config
,
file
,
false
);
}
readAndDiscardModel
(
mapper
,
ois
,
cityObjectConsumer
,
outputFile
);
readAndDiscardFeatures
(
file
,
config
,
ois
,
cityObjectConsumer
,
outputFile
);
}
catch
(
IOException
|
CityGMLReadException
e
)
{
}
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
());
logger
.
catching
(
Level
.
ERROR
,
e
);
private
static
void
readAndDiscardModel
(
Citygml3FeatureMapper
mapper
,
ObservedInputStream
ois
,
}
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGMLReadException
{
}
getContext
();
CityGMLInputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
private
static
void
readAndDiscardFeatures
(
Path
file
,
ParserConfiguration
config
,
ObservedInputStream
ois
,
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
)
throws
CityGMLReadException
{
CityGMLChunkWriter
writer
=
null
;
Citygml3FeatureMapper
mapper
=
new
Citygml3FeatureMapper
(
config
,
file
,
false
);
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
readAndDiscardModel
(
mapper
,
ois
,
cityObjectConsumer
,
outputFile
,
config
,
file
);
CityDoctorModel
model
=
mapper
.
getModel
();
}
boolean
isInitialized
=
false
;
while
(
reader
.
hasNext
())
{
private
static
void
readAndDiscardModel
(
Citygml3FeatureMapper
mapper
,
ObservedInputStream
ois
,
AbstractFeature
chunk
=
reader
.
next
();
CityGmlConsumer
cityObjectConsumer
,
String
outputFile
,
ParserConfiguration
config
,
Path
file
)
if
(
writer
==
null
)
{
throws
CityGMLReadException
{
writer
=
createCityModelWriter
(
outputFile
,
reader
);
setupContext
();
}
CityGMLInputFactory
inputFactory
=
context
.
createCityGMLInputFactory
()
if
(!
isInitialized
&&
writer
!=
null
&&
reader
.
getParentInfo
()
!=
null
.
withChunking
(
ChunkOptions
.
chunkByProperties
(
chunkProperties
).
skipCityModel
(
false
));
&&
reader
.
getParentInfo
().
getTypeName
().
getLocalPart
().
equals
(
"CityModel"
))
{
CityGMLChunkWriter
writer
=
null
;
FeatureInfo
parentInfo
=
reader
.
getParentInfo
();
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
writer
.
withCityModelInfo
(
parentInfo
);
CityDoctorModel
model
=
mapper
.
getModel
();
isInitialized
=
true
;
boolean
isInitialized
=
false
;
}
while
(
reader
.
hasNext
())
{
if
(
chunk
instanceof
AbstractCityObject
ag
)
{
AbstractFeature
chunk
=
reader
.
next
();
ag
.
accept
(
mapper
);
if
(
writer
==
null
)
{
drainCityModel
(
model
,
cityObjectConsumer
);
writer
=
createCityModelWriter
(
outputFile
,
reader
);
writeAbstractCityObject
(
writer
,
ag
);
}
}
else
if
(
chunk
instanceof
CityModel
cModel
)
{
if
(!
isInitialized
&&
writer
!=
null
&&
reader
.
getParentInfo
()
!=
null
cModel
.
setCityObjectMembers
(
null
);
&&
reader
.
getParentInfo
().
getTypeName
().
getLocalPart
().
equals
(
"CityModel"
))
{
mapper
.
setCityModel
(
cModel
);
FeatureInfo
parentInfo
=
reader
.
getParentInfo
();
cityObjectConsumer
.
accept
(
cModel
);
writer
.
withCityModelInfo
(
parentInfo
);
writeCityModel
(
writer
,
cModel
);
isInitialized
=
true
;
}
else
if
(
writer
!=
null
)
{
}
writer
.
writeMember
(
chunk
);
if
(
chunk
instanceof
AbstractCityObject
ag
)
{
}
ag
.
accept
(
mapper
);
}
drainCityModel
(
model
,
cityObjectConsumer
);
writeAbstractCityObject
(
writer
,
ag
);
// end of stream
}
else
if
(
chunk
instanceof
CityModel
cModel
)
{
logger
.
debug
(
"End of gml file stream"
);
cModel
.
setCityObjectMembers
(
null
);
}
catch
(
CityGMLReadException
e
)
{
mapper
.
setCityModel
(
cModel
);
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
(),
e
);
cityObjectConsumer
.
accept
(
cModel
);
}
catch
(
CityGMLWriteException
e
)
{
writeCityModel
(
writer
,
cModel
);
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorWritingGmlFile"
),
e
.
getMessage
(),
e
);
}
else
if
(
writer
!=
null
)
{
}
finally
{
writer
.
writeMember
(
chunk
);
if
(
writer
!=
null
)
{
}
try
{
}
writer
.
close
();
}
catch
(
CityGMLWriteException
e
)
{
// end of stream
// ignore
logger
.
debug
(
"End of gml file stream"
);
}
}
catch
(
CityGMLReadException
e
)
{
}
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorReadingGmlFile"
),
e
.
getMessage
(),
e
);
}
}
catch
(
CityGMLWriteException
e
)
{
}
logger
.
error
(
Localization
.
getText
(
"CityGmlParser.errorWritingGmlFile"
),
e
.
getMessage
(),
e
);
}
finally
{
private
static
void
writeCityModel
(
CityGMLChunkWriter
writer
,
CityModel
cModel
)
throws
CityGMLWriteException
{
if
(
writer
!=
null
)
{
if
(
writer
!=
null
)
{
try
{
for
(
AbstractFeatureProperty
featureProp
:
cModel
.
getFeatureMembers
())
{
writer
.
close
();
writer
.
writeMember
(
featureProp
.
getObject
());
}
catch
(
CityGMLWriteException
e
)
{
}
// ignore
}
}
}
}
}
private
static
void
writeAbstractCityObject
(
CityGMLChunkWriter
writer
,
AbstractCityObject
ag
)
}
throws
CityGMLWriteException
{
if
(
writer
!=
null
)
{
private
static
void
writeCityModel
(
CityGMLChunkWriter
writer
,
CityModel
cModel
)
throws
CityGMLWriteException
{
writer
.
writeMember
(
ag
);
if
(
writer
!=
null
)
{
}
for
(
AbstractFeatureProperty
featureProp
:
cModel
.
getFeatureMembers
())
{
}
writer
.
writeMember
(
featureProp
.
getObject
());
}
private
static
CityGMLChunkWriter
createCityModelWriter
(
String
outputFile
,
CityGMLReader
reader
)
}
throws
CityGMLWriteException
{
}
if
(
outputFile
==
null
)
{
return
null
;
private
static
void
writeAbstractCityObject
(
CityGMLChunkWriter
writer
,
AbstractCityObject
ag
)
}
throws
CityGMLWriteException
{
CityGMLContext
gmlContext
=
CityGmlParser
.
getContext
();
if
(
writer
!=
null
)
{
CityGMLVersion
version
=
CityGMLModules
.
getCityGMLVersion
(
reader
.
getName
().
getNamespaceURI
());
writer
.
writeMember
(
ag
);
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
version
);
}
CityGMLChunkWriter
writer
=
factory
.
createCityGMLChunkWriter
(
new
File
(
outputFile
),
}
StandardCharsets
.
UTF_8
.
name
());
writer
.
withPrefix
(
"qual"
,
QualityADEModule
.
NAMESPACE_URI
);
private
static
CityGMLChunkWriter
createCityModelWriter
(
String
outputFile
,
CityGMLReader
reader
)
writer
.
withSchemaLocation
(
QualityADEModule
.
NAMESPACE_URI
,
QualityADEModule
.
NAMESPACE_URI
+
"/qualityAde.xsd"
);
throws
CityGMLWriteException
{
writer
.
withIndent
(
" "
);
if
(
outputFile
==
null
)
{
writer
.
withDefaultPrefixes
();
return
null
;
writer
.
withDefaultSchemaLocations
();
}
return
writer
;
CityGMLContext
gmlContext
=
CityGmlParser
.
setupContext
();
}
CityGMLVersion
version
=
CityGMLModules
.
getCityGMLVersion
(
reader
.
getName
().
getNamespaceURI
());
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
version
);
private
static
CityDoctorModel
readAndKeepFeatures
(
ParserConfiguration
config
,
Path
file
,
CityGMLChunkWriter
writer
=
factory
.
createCityGMLChunkWriter
(
new
File
(
outputFile
),
CityGMLInputFactory
inputFactory
,
ObservedInputStream
ois
,
StandardCharsets
.
UTF_8
.
name
());
boolean
verbose
,
boolean
unconnected
)
throws
CityGMLReadException
{
writer
.
withPrefix
(
"qual"
,
QualityADEModule
.
NAMESPACE_URI
);
return
readAndKeepModel
(
new
Citygml3FeatureMapper
(
config
,
file
,
unconnected
),
inputFactory
,
ois
,
verbose
);
writer
.
withSchemaLocation
(
QualityADEModule
.
NAMESPACE_URI
,
QualityADEModule
.
NAMESPACE_URI
+
"/qualityAde.xsd"
);
}
writer
.
withIndent
(
" "
);
writer
.
withDefaultPrefixes
();
private
static
CityDoctorModel
readAndKeepModel
(
Citygml3FeatureMapper
mapper
,
CityGMLInputFactory
inputFactory
,
writer
.
withDefaultSchemaLocations
();
ObservedInputStream
ois
,
boolean
verbose
)
throws
CityGMLReadException
{
return
writer
;
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
}
CityGMLVersion
version
=
null
;
// model is read in chunked mode
private
static
CityDoctorModel
readAndKeepFeatures
(
ParserConfiguration
config
,
Path
file
,
// object members are replaced by href in model
CityGMLInputFactory
inputFactory
,
ObservedInputStream
ois
,
boolean
verbose
,
boolean
unconnected
)
// need to remove the refs and re-add unparsed objects
throws
CityGMLReadException
{
List
<
AbstractCityObject
>
acos
=
new
ArrayList
<>();
return
readAndKeepModel
(
new
Citygml3FeatureMapper
(
config
,
file
,
unconnected
),
inputFactory
,
ois
,
verbose
);
CityModel
cgmlModel
=
null
;
}
CityDoctorModel
cdModel
=
mapper
.
getModel
();
AutoCloseable
parsingContext
=
cdModel
.
getCache
().
startParsingMode
();
private
static
CityDoctorModel
readAndKeepModel
(
Citygml3FeatureMapper
mapper
,
CityGMLInputFactory
inputFactory
,
try
(
parsingContext
){
ObservedInputStream
ois
,
boolean
verbose
)
throws
CityGMLReadException
{
List
<
AbstractCityObject
>
queuedObjects
=
new
ArrayList
<>();
try
(
CityGMLReader
reader
=
inputFactory
.
createCityGMLReader
(
ois
))
{
while
(
reader
.
hasNext
())
{
CityGMLVersion
version
=
null
;
AbstractFeature
chunk
=
reader
.
next
();
// model is read in chunked mode
version
=
CityGMLModules
.
getCityGMLVersion
(
reader
.
getName
().
getNamespaceURI
());
// object members are replaced by href in model
if
(
chunk
instanceof
CityModel
cModel
)
{
// need to remove the refs and re-add unparsed objects
cModel
.
setCityObjectMembers
(
null
);
List
<
AbstractCityObject
>
acos
=
new
ArrayList
<>();
mapper
.
setCityModel
(
cModel
);
CityModel
cgmlModel
=
null
;
mapper
.
setCityGMLVersion
(
version
);
CityDoctorModel
cdModel
=
mapper
.
getModel
();
cgmlModel
=
cModel
;
AutoCloseable
parsingContext
=
cdModel
.
getCache
().
startParsingMode
();
try
(
parsingContext
)
{
if
(!
queuedObjects
.
isEmpty
())
{
List
<
AbstractCityObject
>
queuedObjects
=
new
ArrayList
<>();
for
(
AbstractCityObject
aco
:
queuedObjects
)
{
while
(
reader
.
hasNext
())
{
if
(!
cdModel
.
containsGmlId
(
aco
.
getId
()))
{
AbstractFeature
chunk
=
reader
.
next
();
cgmlModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
version
=
CityGMLModules
.
getCityGMLVersion
(
reader
.
getName
().
getNamespaceURI
());
}
if
(
chunk
instanceof
CityModel
cModel
)
{
}
cModel
.
setCityObjectMembers
(
null
);
}
mapper
.
setCityModel
(
cModel
);
}
else
if
(
chunk
instanceof
AbstractCityObject
aco
)
{
mapper
.
setCityGMLVersion
(
version
);
acos
.
add
(
aco
);
// getid
cgmlModel
=
cModel
;
String
id
=
aco
.
getId
();
aco
.
accept
(
mapper
);
if
(!
queuedObjects
.
isEmpty
())
{
if
(
cgmlModel
==
null
)
{
for
(
AbstractCityObject
aco
:
queuedObjects
)
{
// Add object to queue till the CityModel has been parsed
if
(!
cdModel
.
containsGmlId
(
aco
.
getId
()))
{
queuedObjects
.
add
(
aco
);
cgmlModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
}
else
if
(!
cdModel
.
containsGmlId
(
id
)){
}
cgmlModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
}
}
}
}
}
else
if
(
chunk
instanceof
AbstractCityObject
aco
)
{
}
acos
.
add
(
aco
);
// getid
String
id
=
aco
.
getId
();
if
(
mapper
.
getModel
().
getCityModel
()
==
null
)
{
aco
.
accept
(
mapper
);
// file does not contain a city model?
if
(
cgmlModel
==
null
)
{
// create it for now
// Add object to queue till the CityModel has been parsed
logger
.
warn
(
Localization
.
getText
(
"CityGmlParser.missingCityModel"
));
queuedObjects
.
add
(
aco
);
mapper
.
setCityModel
(
new
CityModel
());
}
else
if
(!
cdModel
.
containsGmlId
(
id
))
{
for
(
AbstractCityObject
aco
:
queuedObjects
)
{
cgmlModel
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
if
(!
cdModel
.
containsGmlId
(
aco
.
getId
()))
{
}
mapper
.
getModel
().
getCityModel
().
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
}
}
}
}
}
if
(
mapper
.
getModel
().
getCityModel
()
==
null
)
{
// file does not contain a city model?
ImplicitGeometryHolder
.
resolveDeferredObjects
(
mapper
.
getModel
().
getCache
());
// create it for now
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
logger
.
warn
(
Localization
.
getText
(
"CityGmlParser.missingCityModel"
));
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.parsedObjects"
),
mapper
.
setCityModel
(
new
CityModel
());
mapper
.
getModel
().
getNumberOfFeatures
());
for
(
AbstractCityObject
aco
:
queuedObjects
)
{
}
if
(!
cdModel
.
containsGmlId
(
aco
.
getId
()))
{
mapper
.
checkUnresolvedReferences
();
mapper
.
getModel
().
getCityModel
().
getCityObjectMembers
()
mapper
.
setCityGMLVersion
(
version
);
.
add
(
new
AbstractCityObjectProperty
(
aco
));
return
mapper
.
getModel
();
}
}
catch
(
Exception
e
)
{
}
throw
new
CityGMLReadException
(
e
);
}
}
ImplicitGeometryHolder
.
resolveDeferredObjects
(
mapper
.
getModel
().
getCache
());
}
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
}
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.parsedObjects"
),
mapper
.
getModel
().
getNumberOfFeatures
());
private
static
void
parseEpsgCodeFromFile
(
Path
file
,
ParserConfiguration
config
,
boolean
verbose
)
throws
CityGmlParseException
{
}
try
(
BufferedInputStream
bis
=
new
BufferedInputStream
(
new
FileInputStream
(
file
.
toFile
())))
{
mapper
.
checkUnresolvedReferences
();
parseEpsgCodeFromStream
(
bis
,
config
,
verbose
);
mapper
.
setCityGMLVersion
(
version
);
}
catch
(
ParserConfigurationException
|
SAXException
|
IOException
e
)
{
return
mapper
.
getModel
();
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
}
catch
(
Exception
e
)
{
}
throw
new
CityGMLReadException
(
e
);
}
}
private
static
void
parseEpsgCodeFromStream
(
InputStream
is
,
ParserConfiguration
config
,
boolean
verbose
)
}
throws
ParserConfigurationException
,
SAXException
{
}
SAXParser
parser
=
FACTORY
.
newSAXParser
();
CityGmlHandler
handler
=
new
CityGmlHandler
();
private
static
void
parseEpsgCodeFromFile
(
Path
file
,
ParserConfiguration
config
,
boolean
verbose
)
try
{
throws
CityGmlParseException
{
parser
.
parse
(
new
InputSource
(
is
),
handler
);
try
(
BufferedInputStream
bis
=
new
BufferedInputStream
(
new
FileInputStream
(
file
.
toFile
())))
{
}
catch
(
EnvelopeFoundException
e
)
{
parseEpsgCodeFromStream
(
bis
,
config
,
verbose
);
try
{
}
catch
(
ParserConfigurationException
|
SAXException
|
IOException
e
)
{
parseCoordinateSystem
(
config
,
handler
,
verbose
);
throw
new
CityGmlParseException
(
"Failed to read CityGML file"
,
e
);
}
catch
(
Exception
e2
)
{
}
logEpsgParseError
(
e2
);
}
}
}
catch
(
Exception
e
)
{
private
static
void
parseEpsgCodeFromStream
(
InputStream
is
,
ParserConfiguration
config
,
boolean
verbose
)
logEpsgParseError
(
e
);
throws
ParserConfigurationException
,
SAXException
{
}
SAXParser
parser
=
FACTORY
.
newSAXParser
();
if
(
handler
.
getEpsg
()
==
null
&&
logger
.
isInfoEnabled
()
&&
verbose
)
{
CityGmlHandler
handler
=
new
CityGmlHandler
();
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.missingEPSGCode"
));
try
{
}
parser
.
parse
(
new
InputSource
(
is
),
handler
);
}
catch
(
EnvelopeFoundException
e
)
{
}
try
{
parseCoordinateSystem
(
config
,
handler
,
verbose
);
private
static
void
logEpsgParseError
(
Exception
e
)
{
}
catch
(
Exception
e2
)
{
logger
.
debug
(
"Exception while parsing for EPSG code"
,
e
);
logEpsgParseError
(
e2
);
if
(
logger
.
isWarnEnabled
())
{
}
logger
.
warn
(
Localization
.
getText
(
"CityGmlParser.failedEPSGParse"
));
}
catch
(
Exception
e
)
{
}
logEpsgParseError
(
e
);
}
}
if
(
handler
.
getEpsg
()
==
null
&&
logger
.
isInfoEnabled
()
&&
verbose
)
{
private
static
void
parseCoordinateSystem
(
ParserConfiguration
config
,
CityGmlHandler
handler
,
boolean
verbose
)
{
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.missingEPSGCode"
));
if
(
handler
.
getEpsg
()
==
null
)
{
}
return
;
}
}
CoordinateReferenceSystem
crs
=
crsFromSrsName
(
handler
.
getEpsg
());
if
(
crs
==
null
)
{
private
static
void
logEpsgParseError
(
Exception
e
)
{
// could not find a coordinate system for srsName
logger
.
debug
(
"Exception while parsing for EPSG code"
,
e
);
// assuming metric system
if
(
logger
.
isWarnEnabled
())
{
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
logger
.
warn
(
Localization
.
getText
(
"CityGmlParser.failedEPSGParse"
));
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.missingEPSGCode"
));
}
}
}
return
;
}
private
static
void
parseCoordinateSystem
(
ParserConfiguration
config
,
CityGmlHandler
handler
,
boolean
verbose
)
{
if
(
crs
.
getProjection
().
getUnits
()
==
Units
.
METRES
)
{
if
(
handler
.
getEpsg
()
==
null
)
{
// coordinate system is in meters, do not convert
return
;
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
}
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.noConversionNeeded"
));
CoordinateReferenceSystem
crs
=
crsFromSrsName
(
handler
.
getEpsg
());
}
if
(
crs
==
null
)
{
return
;
// could not find a coordinate system for srsName
}
// assuming metric system
parseMeterConversion
(
config
,
crs
);
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
Vector3d
low
=
handler
.
getLowerCorner
();
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.missingEPSGCode"
));
Vector3d
up
=
handler
.
getUpperCorner
();
}
double
centerLong
=
low
.
getX
()
+
((
up
.
getX
()
-
low
.
getX
())
/
2
);
return
;
double
centerLat
=
low
.
getY
()
+
((
up
.
getY
()
-
low
.
getY
())
/
2
);
}
if
(!
crs
.
getName
().
equals
(
WGS_84
))
{
if
(
crs
.
getProjection
().
getUnits
()
==
Units
.
METRES
)
{
// need to convert coordinates first to WGS84, then find UTM Zone
// coordinate system is in meters, do not convert
CoordinateReferenceSystem
wgs84
=
crsFromSrsName
(
WGS_84
);
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
ProjCoordinate
p1
=
new
ProjCoordinate
();
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.noConversionNeeded"
));
p1
.
setValue
(
centerLong
,
centerLat
);
}
ProjCoordinate
p2
=
new
ProjCoordinate
();
return
;
BasicCoordinateTransform
bct
=
new
BasicCoordinateTransform
(
crs
,
wgs84
);
}
bct
.
transform
(
p1
,
p2
);
parseMeterConversion
(
config
,
crs
);
centerLong
=
p2
.
x
;
Vector3d
low
=
handler
.
getLowerCorner
();
centerLat
=
p2
.
y
;
Vector3d
up
=
handler
.
getUpperCorner
();
}
double
centerLong
=
low
.
getX
()
+
((
up
.
getX
()
-
low
.
getX
())
/
2
);
int
zone
=
(
int
)
(
31
+
Math
.
round
(
centerLong
/
6
));
double
centerLat
=
low
.
getY
()
+
((
up
.
getY
()
-
low
.
getY
())
/
2
);
CoordinateReferenceSystem
utm
;
if
(!
crs
.
getName
().
equals
(
WGS_84
))
{
if
(
centerLat
<
0
)
{
// need to convert coordinates first to WGS84, then find UTM Zone
// south
CoordinateReferenceSystem
wgs84
=
crsFromSrsName
(
WGS_84
);
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
ProjCoordinate
p1
=
new
ProjCoordinate
();
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.convertCrsToUtmZoneS"
),
zone
);
p1
.
setValue
(
centerLong
,
centerLat
);
}
ProjCoordinate
p2
=
new
ProjCoordinate
();
utm
=
CRS_FACTORY
.
createFromParameters
(
"UTM"
,
"+proj=utm +ellps=WGS84 +units=m +zone="
+
zone
+
" +south"
);
BasicCoordinateTransform
bct
=
new
BasicCoordinateTransform
(
crs
,
wgs84
);
}
else
{
bct
.
transform
(
p1
,
p2
);
// north
centerLong
=
p2
.
x
;
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
centerLat
=
p2
.
y
;
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.convertCrsToUtmZoneN"
),
zone
);
}
}
int
zone
=
(
int
)
(
31
+
Math
.
round
(
centerLong
/
6
));
utm
=
CRS_FACTORY
.
createFromParameters
(
"UTM"
,
"+proj=utm +ellps=WGS84 +units=m +zone="
+
zone
);
CoordinateReferenceSystem
utm
;
}
if
(
centerLat
<
0
)
{
config
.
setCoordinateSystem
(
crs
,
utm
);
// south
}
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.convertCrsToUtmZoneS"
),
zone
);
private
static
void
parseMeterConversion
(
ParserConfiguration
config
,
CoordinateReferenceSystem
crs
)
{
}
Projection
projection
=
crs
.
getProjection
();
utm
=
CRS_FACTORY
.
createFromParameters
(
"UTM"
,
"+proj=utm +ellps=WGS84 +units=m +zone="
+
zone
+
" +south"
);
double
fromMetres
=
projection
.
getFromMetres
();
}
else
{
if
(
fromMetres
>
0
)
{
// north
// also transform height information
if
(
logger
.
isInfoEnabled
()
&&
verbose
)
{
config
.
setFromMeters
(
fromMetres
);
logger
.
info
(
Localization
.
getText
(
"CityGmlParser.convertCrsToUtmZoneN"
),
zone
);
}
else
{
}
config
.
setFromMeters
(
1.0
);
utm
=
CRS_FACTORY
.
createFromParameters
(
"UTM"
,
"+proj=utm +ellps=WGS84 +units=m +zone="
+
zone
);
}
}
}
config
.
setCoordinateSystem
(
crs
,
utm
);
}
/**
* The srsName (The name by which this reference system is identified) inside
private
static
void
parseMeterConversion
(
ParserConfiguration
config
,
CoordinateReferenceSystem
crs
)
{
* the CityGML file can have multiple formats. This method tries to parse the
Projection
projection
=
crs
.
getProjection
();
* string and detect the corresponding reference system. If it is found, it
double
fromMetres
=
projection
.
getFromMetres
();
* returns a proj4j.CoordinateReferenceSystem. It throws an
if
(
fromMetres
>
0
)
{
* IllegalArgumentException otherwise.
// also transform height information
* <p>
config
.
setFromMeters
(
fromMetres
);
* This method should be able to parse any EPSG id : e.g. "EPSG:1234". German
}
else
{
* Citygmls might also have "DE_DHDN_3GK3" or "ETRS89_UTM32" as srsName, so
config
.
setFromMeters
(
1.0
);
* those are also included. It isn't guaranteed that those formats are correctly
}
* parsed, though.
}
* <p>
* The EPSG ids and parameters are defined in resources ('nad/epsg') inside
/**
* proj4j-0.1.0.jar. Some EPSG ids are missing though, e.g. 7415
* The srsName (The name by which this reference system is identified) inside
*
* the CityGML file can have multiple formats. This method tries to parse the
* @param srsName
* string and detect the corresponding reference system. If it is found, it
* @return CoordinateReferenceSystem
* returns a proj4j.CoordinateReferenceSystem. It throws an
*/
* IllegalArgumentException otherwise.
private
static
CoordinateReferenceSystem
crsFromSrsName
(
String
srsName
)
{
* <p>
srsName
=
srsName
.
trim
();
* This method should be able to parse any EPSG id : e.g. "EPSG:1234". German
Matcher
mEPSG
=
P_EPSG
.
matcher
(
srsName
);
* Citygmls might also have "DE_DHDN_3GK3" or "ETRS89_UTM32" as srsName, so
if
(
mEPSG
.
find
())
{
* those are also included. It isn't guaranteed that those formats are correctly
if
(
"EPSG:4979"
.
contentEquals
(
srsName
))
{
* parsed, though.
srsName
=
"EPSG:4236"
;
* <p>
}
else
if
(
"EPSG:7415"
.
contentEquals
(
srsName
))
{
* The EPSG ids and parameters are defined in resources ('nad/epsg') inside
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:7415"
,
* proj4j-0.1.0.jar. Some EPSG ids are missing though, e.g. 7415
"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725 +units=m +no_defs"
);
*
}
* @param srsName
return
CRS_FACTORY
.
createFromName
(
srsName
);
* @return CoordinateReferenceSystem
}
*/
private
static
CoordinateReferenceSystem
crsFromSrsName
(
String
srsName
)
{
Matcher
mOGC
=
P_OGC
.
matcher
(
srsName
);
srsName
=
srsName
.
trim
();
if
(
mOGC
.
find
())
{
Matcher
mEPSG
=
P_EPSG
.
matcher
(
srsName
);
return
getCrsFromOGCSrsCode
(
mOGC
.
group
(
1
));
if
(
mEPSG
.
find
())
{
}
if
(
"EPSG:4979"
.
contentEquals
(
srsName
))
{
Matcher
mOGC2
=
P_OGC2
.
matcher
(
srsName
);
srsName
=
"EPSG:4236"
;
if
(
mOGC2
.
find
())
{
}
else
if
(
"EPSG:7415"
.
contentEquals
(
srsName
))
{
return
getCrsFromOGCSrsCode
(
mOGC2
.
group
(
1
));
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:7415"
,
"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725 +units=m +no_defs"
);
}
}
Matcher
mURN
=
P_URN
.
matcher
(
srsName
);
return
CRS_FACTORY
.
createFromName
(
srsName
);
// NOTE: Could use a HashMap if the switch/case becomes too long.
}
if
(
mURN
.
find
())
{
return
switch
(
mURN
.
group
(
1
))
{
Matcher
mOGC
=
P_OGC
.
matcher
(
srsName
);
case
"DE_DHDN_3GK2"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31466"
);
if
(
mOGC
.
find
())
{
case
"DE_DHDN_3GK3"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31467"
);
return
getCrsFromOGCSrsCode
(
mOGC
.
group
(
1
));
case
"DE_DHDN_3GK4"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31468"
);
}
case
"DE_DHDN_3GK5"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31469"
);
Matcher
mOGC2
=
P_OGC2
.
matcher
(
srsName
);
case
"ETRS89_UTM32"
->
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
if
(
mOGC2
.
find
())
{
default
->
null
;
return
getCrsFromOGCSrsCode
(
mOGC2
.
group
(
1
));
};
}
}
if
(
srsName
.
equals
(
"http://www.opengis.net/def/crs/EPSG/0/6697"
))
{
Matcher
mURN
=
P_URN
.
matcher
(
srsName
);
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:6697"
,
"+proj=longlat +ellps=GRS80 +no_defs +axis=neu"
);
// NOTE: Could use a HashMap if the switch/case becomes too long.
}
if
(
mURN
.
find
())
{
return
null
;
return
switch
(
mURN
.
group
(
1
))
{
}
case
"DE_DHDN_3GK2"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31466"
);
case
"DE_DHDN_3GK3"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31467"
);
private
static
CoordinateReferenceSystem
getCrsFromOGCSrsCode
(
String
srsCode
)
{
case
"DE_DHDN_3GK4"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31468"
);
String
crsName
=
"EPSG:"
+
srsCode
;
case
"DE_DHDN_3GK5"
->
CRS_FACTORY
.
createFromName
(
"EPSG:31469"
);
List
<
String
>
params
=
new
ArrayList
<>(
Arrays
.
stream
(
csReader
.
getParameters
(
crsName
)).
toList
());
case
"ETRS89_UTM32"
->
CRS_FACTORY
.
createFromName
(
"EPSG:25832"
);
params
.
removeIf
(
P_VUNITS
.
asPredicate
());
default
->
null
;
params
.
removeIf
(
P_GEOIDGRID
.
asPredicate
());
};
return
CRS_FACTORY
.
createFromParameters
(
crsName
,
params
.
toArray
(
new
String
[
0
]));
}
}
if
(
srsName
.
equals
(
"http://www.opengis.net/def/crs/EPSG/0/6697"
))
{
return
CRS_FACTORY
.
createFromParameters
(
"EPSG:6697"
,
"+proj=longlat +ellps=GRS80 +no_defs +axis=neu"
);
private
static
List
<
String
>
validateFile
(
CityGMLContext
context
,
GMLValidationHandler
handler
,
Path
file
)
}
throws
CityGmlParseException
{
return
null
;
if
(
handler
==
null
)
{
}
handler
=
new
GMLValidationHandler
();
}
private
static
CoordinateReferenceSystem
getCrsFromOGCSrsCode
(
String
srsCode
)
{
try
{
String
crsName
=
"EPSG:"
+
srsCode
;
SchemaHandler
schemaHandler
=
new
ValidationSchemaHandler
(
context
.
getDefaultSchemaHandler
());
List
<
String
>
params
=
new
ArrayList
<>(
Arrays
.
stream
(
csReader
.
getParameters
(
crsName
)).
toList
());
readAdditionalSchemaDefinitions
(
context
,
file
,
schemaHandler
);
params
.
removeIf
(
P_VUNITS
.
asPredicate
());
Source
[]
schemas
=
schemaHandler
.
getSchemas
();
params
.
removeIf
(
P_GEOIDGRID
.
asPredicate
());
SchemaFactory
schemaFactory
=
SchemaFactory
.
newInstance
(
XMLConstants
.
W3C_XML_SCHEMA_NS_URI
);
return
CRS_FACTORY
.
createFromParameters
(
crsName
,
params
.
toArray
(
new
String
[
0
]));
schemaFactory
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
}
Schema
schema
=
schemaFactory
.
newSchema
(
schemas
);
Validator
validator
=
schema
.
newValidator
();
public
static
List
<
String
>
validateFile
(
GMLValidationHandler
handler
,
Path
file
)
validator
.
setErrorHandler
(
handler
);
throws
CityGmlParseException
{
validator
.
validate
(
new
StreamSource
(
file
.
toFile
()));
if
(
handler
==
null
)
{
return
handler
.
getMessages
();
handler
=
new
GMLValidationHandler
();
}
catch
(
SchemaHandlerException
|
SAXException
|
IOException
e
)
{
}
throw
new
CityGmlParseException
(
"Failed to validate CityGML file"
,
e
);
setupContext
();
}
try
{
}
SchemaHandler
schemaHandler
=
new
ValidationSchemaHandler
(
context
.
getDefaultSchemaHandler
());
readAdditionalSchemaDefinitions
(
context
,
file
,
schemaHandler
);
private
static
void
readAdditionalSchemaDefinitions
(
CityGMLContext
context
,
Path
file
,
SchemaHandler
schemaHandler
)
Source
[]
schemas
=
schemaHandler
.
getSchemas
();
throws
CityGmlParseException
{
SchemaFactory
schemaFactory
=
SchemaFactory
.
newInstance
(
XMLConstants
.
W3C_XML_SCHEMA_NS_URI
);
try
(
XMLReader
reader
=
XMLReaderFactory
.
newInstance
(
context
.
getXMLObjects
())
schemaFactory
.
setFeature
(
"http://apache.org/xml/features/disallow-doctype-decl"
,
true
);
.
withSchemaHandler
(
schemaHandler
)
Schema
schema
=
schemaFactory
.
newSchema
(
schemas
);
.
createReader
(
file
))
{
Validator
validator
=
schema
.
newValidator
();
reader
.
nextTag
();
validator
.
setErrorHandler
(
handler
);
}
catch
(
Exception
e
)
{
validator
.
validate
(
new
StreamSource
(
file
.
toFile
()));
throw
new
CityGmlParseException
(
"Failed to read file "
+
file
.
toAbsolutePath
()
+
"."
,
e
);
return
handler
.
getMessages
();
}
}
catch
(
SchemaHandlerException
|
SAXException
|
IOException
e
)
{
}
throw
new
CityGmlParseException
(
"Failed to validate CityGML file"
,
e
);
}
private
static
void
drainCityModel
(
CityDoctorModel
model
,
CityGmlConsumer
cityObjectConsumer
)
{
}
List
<
GmlId
>
id
=
new
ArrayList
<>();
model
.
createFeatureStream
().
forEach
(
co
->
{
private
static
void
readAdditionalSchemaDefinitions
(
CityGMLContext
context
,
Path
file
,
SchemaHandler
schemaHandler
)
cityObjectConsumer
.
accept
(
co
);
throws
CityGmlParseException
{
id
.
add
(
co
.
getGmlId
());
try
(
XMLReader
reader
=
XMLReaderFactory
.
newInstance
(
context
.
getXMLObjects
()).
withSchemaHandler
(
schemaHandler
)
});
.
createReader
(
file
))
{
id
.
forEach
(
model:
:
removeFeature
);
reader
.
nextTag
();
}
catch
(
Exception
e
)
{
}
throw
new
CityGmlParseException
(
"Failed to read file "
+
file
.
toAbsolutePath
()
+
"."
,
e
);
}
}
private
static
void
drainCityModel
(
CityDoctorModel
model
,
CityGmlConsumer
cityObjectConsumer
)
{
List
<
GmlId
>
id
=
new
ArrayList
<>();
model
.
createFeatureStream
().
forEach
(
co
->
{
cityObjectConsumer
.
accept
(
co
);
id
.
add
(
co
.
getGmlId
());
});
id
.
forEach
(
model:
:
removeFeature
);
}
}
}
CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java
View file @
1fbe16e1
...
@@ -65,7 +65,7 @@ public class CityGMLWriterUtils {
...
@@ -65,7 +65,7 @@ public class CityGMLWriterUtils {
}
}
public
static
void
writeCityModel
(
String
file
,
CityDoctorModel
model
)
throws
CityDoctorWriteException
{
public
static
void
writeCityModel
(
String
file
,
CityDoctorModel
model
)
throws
CityDoctorWriteException
{
CityGMLContext
gmlContext
=
CityGmlParser
.
g
etContext
();
CityGMLContext
gmlContext
=
CityGmlParser
.
s
et
up
Context
();
CityModel
cModel
=
model
.
getCityModel
();
CityModel
cModel
=
model
.
getCityModel
();
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
model
.
getCityGMLVersion
());
CityGMLOutputFactory
factory
=
gmlContext
.
createCityGMLOutputFactory
(
model
.
getCityGMLVersion
());
try
(
CityGMLWriter
writer
=
factory
.
createCityGMLWriter
(
new
File
(
file
)))
{
try
(
CityGMLWriter
writer
=
factory
.
createCityGMLWriter
(
new
File
(
file
)))
{
...
...
CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/parser/CityGml3ParserTest.java
View file @
1fbe16e1
...
@@ -37,7 +37,7 @@ public class CityGml3ParserTest {
...
@@ -37,7 +37,7 @@ public class CityGml3ParserTest {
@Test
@Test
public
void
testGetContext
()
{
public
void
testGetContext
()
{
CityGMLContext
context
=
CityGmlParser
.
g
etContext
();
CityGMLContext
context
=
CityGmlParser
.
s
et
up
Context
();
List
<
ADE
>
ades
=
ADERegistry
.
getInstance
().
getADEs
();
List
<
ADE
>
ades
=
ADERegistry
.
getInstance
().
getADEs
();
ADE
ade
=
ades
.
get
(
0
);
ADE
ade
=
ades
.
get
(
0
);
assertEquals
(
QualityADEContext
.
class
,
ade
.
getClass
());
assertEquals
(
QualityADEContext
.
class
,
ade
.
getClass
());
...
...
CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
View file @
1fbe16e1
...
@@ -65,6 +65,7 @@ import de.hft.stuttgart.citydoctor2.check.error.AttributeInvalidError;
...
@@ -65,6 +65,7 @@ import de.hft.stuttgart.citydoctor2.check.error.AttributeInvalidError;
import
de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError
;
import
de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError
;
import
de.hft.stuttgart.citydoctor2.check.error.AttributeValueWrongError
;
import
de.hft.stuttgart.citydoctor2.check.error.AttributeValueWrongError
;
import
de.hft.stuttgart.citydoctor2.check.error.SchematronError
;
import
de.hft.stuttgart.citydoctor2.check.error.SchematronError
;
import
de.hft.stuttgart.citydoctor2.check.error.XMLValidationError
;
import
de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportWriteException
;
import
de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportWriteException
;
import
de.hft.stuttgart.citydoctor2.checks.CheckContainer
;
import
de.hft.stuttgart.citydoctor2.checks.CheckContainer
;
import
de.hft.stuttgart.citydoctor2.checks.CheckPrototype
;
import
de.hft.stuttgart.citydoctor2.checks.CheckPrototype
;
...
@@ -918,6 +919,20 @@ public class Checker {
...
@@ -918,6 +919,20 @@ public class Checker {
// create reporter if available
// create reporter if available
XmlStreamReporter
xmlReporter
=
getXmlReporter
(
config
,
xmlBos
,
fileName
);
XmlStreamReporter
xmlReporter
=
getXmlReporter
(
config
,
xmlBos
,
fileName
);
PdfStreamReporter
pdfReporter
=
getPdfReporter
(
config
,
pdfBos
,
fileName
);
PdfStreamReporter
pdfReporter
=
getPdfReporter
(
config
,
pdfBos
,
fileName
);
// XML validation
if
(
config
.
isUseStreaming
()
&&
(
xmlReporter
!=
null
||
pdfReporter
!=
null
))
{
List
<
String
>
validationIssues
=
CityGmlParser
.
validateFile
(
null
,
inputFile
.
toPath
());
for
(
String
xmlError
:
validationIssues
)
{
XMLValidationError
validationError
=
new
XMLValidationError
(
xmlError
);
if
(
xmlReporter
!=
null
)
{
xmlReporter
.
reportGlobalError
(
validationError
);
}
if
(
pdfReporter
!=
null
)
{
pdfReporter
.
reportGlobalError
(
validationError
);
}
}
}
// execute schematron first
// execute schematron first
SvrlContentHandler
handler
=
executeSchematronValidationIfAvailable
(
config
,
inputFile
);
SvrlContentHandler
handler
=
executeSchematronValidationIfAvailable
(
config
,
inputFile
);
...
...
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
View file @
1fbe16e1
...
@@ -18,6 +18,22 @@
...
@@ -18,6 +18,22 @@
*/
*/
package
de.hft.stuttgart.citydoctor2.check
;
package
de.hft.stuttgart.citydoctor2.check
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
org.apache.commons.io.FileUtils
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.TemporaryFolder
;
import
de.hft.stuttgart.citydoctor2.CityDoctorValidation
;
import
de.hft.stuttgart.citydoctor2.CityDoctorValidation
;
import
de.hft.stuttgart.citydoctor2.checkresult.CheckReport
;
import
de.hft.stuttgart.citydoctor2.checkresult.CheckReport
;
import
de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics
;
import
de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics
;
...
@@ -31,160 +47,165 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
...
@@ -31,160 +47,165 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
org.apache.commons.io.FileUtils
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.TemporaryFolder
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
/**
/**
* @author Matthias Betz
* @author Matthias Betz
*/
*/
public
class
CheckerTest
{
public
class
CheckerTest
{
@Rule
@Rule
public
TemporaryFolder
folder
=
new
TemporaryFolder
();
public
TemporaryFolder
folder
=
new
TemporaryFolder
();
@Test
@Test
public
void
testSchematron
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
public
void
testSchematron
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
config
.
getRequirements
().
get
(
Requirement
.
R_SE_BS_ROOF_UNFRAGMENTED
.
toString
()).
setEnabled
(
false
);
config
.
getRequirements
().
get
(
Requirement
.
R_SE_BS_ROOF_UNFRAGMENTED
.
toString
()).
setEnabled
(
false
);
config
.
setSchematronFilePathInGlobalParameters
(
"src/test/resources/schematronTest.xml"
);
config
.
setSchematronFilePathInGlobalParameters
(
"src/test/resources/schematronTest.xml"
);
CityDoctorModel
model
=
CityGmlParser
.
parseCityGmlFile
(
CityDoctorModel
model
=
CityGmlParser
.
parseCityGmlFile
(
"src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml"
,
config
.
getParserConfiguration
());
"src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml"
,
config
.
getParserConfiguration
());
Checker
checker
=
new
Checker
(
config
,
model
);
Checker
checker
=
new
Checker
(
config
,
model
);
checker
.
runChecks
();
checker
.
runChecks
();
for
(
Building
b
:
model
.
getBuildings
().
toList
())
{
for
(
Building
b
:
model
.
getBuildings
().
toList
())
{
if
(
b
.
getGmlId
().
getGmlString
().
equals
(
"_Simple_BD.1"
))
{
if
(
b
.
getGmlId
().
getGmlString
().
equals
(
"_Simple_BD.1"
))
{
assertTrue
(
b
.
containsAnyError
());
assertTrue
(
b
.
containsAnyError
());
}
else
{
}
else
{
assertFalse
(
b
.
containsAnyError
());
assertFalse
(
b
.
containsAnyError
());
}
}
}
}
assertFalse
(
model
.
getGlobalErrors
().
isEmpty
());
assertFalse
(
model
.
getGlobalErrors
().
isEmpty
());
}
}
@Test
@Test
public
void
testChecker
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
,
CityDoctorWriteException
{
public
void
testChecker
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
,
CityDoctorWriteException
{
File
f
=
folder
.
newFile
();
File
f2
=
folder
.
newFile
();
File
f
=
folder
.
newFile
();
try
{
File
f2
=
folder
.
newFile
();
String
[]
args
=
new
String
[
6
];
try
{
args
[
0
]
=
"-in"
;
String
[]
args
=
new
String
[
6
];
args
[
1
]
=
"src/test/resources/QA-CS-CONCOMP.gml"
;
args
[
0
]
=
"-in"
;
args
[
2
]
=
"-xmlReport"
;
args
[
1
]
=
"src/test/resources/QA-CS-CONCOMP.gml"
;
args
[
3
]
=
f
.
getAbsolutePath
();
args
[
2
]
=
"-xmlReport"
;
args
[
4
]
=
"-pdfReport"
;
args
[
3
]
=
f
.
getAbsolutePath
();
args
[
5
]
=
f2
.
getAbsolutePath
();
args
[
4
]
=
"-pdfReport"
;
CityDoctorValidation
.
main
(
args
);
args
[
5
]
=
f2
.
getAbsolutePath
();
assertTrue
(
f
.
exists
());
CityDoctorValidation
.
main
(
args
);
assertTrue
(
f2
.
exists
());
assertTrue
(
f
.
exists
());
}
finally
{
assertTrue
(
f2
.
exists
());
f
.
delete
();
}
finally
{
f2
.
delete
();
f
.
delete
();
}
f2
.
delete
();
}
}
}
@Test
public
void
testStreaming
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
,
CityDoctorWriteException
{
@Test
File
f
=
folder
.
newFile
();
public
void
testStreaming
()
File
f2
=
folder
.
newFile
();
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
,
CityDoctorWriteException
{
File
f3
=
folder
.
newFile
();
File
f
=
folder
.
newFile
();
try
{
File
f2
=
folder
.
newFile
();
String
[]
args
=
new
String
[
10
];
File
f3
=
folder
.
newFile
();
args
[
0
]
=
"-in"
;
try
{
args
[
1
]
=
"src/test/resources/testarea.gml"
;
String
[]
args
=
new
String
[
10
];
args
[
2
]
=
"-config"
;
args
[
0
]
=
"-in"
;
args
[
3
]
=
"src/test/resources/testConfigWithStreaming.yml"
;
args
[
1
]
=
"src/test/resources/testarea.gml"
;
args
[
4
]
=
"-pdfReport"
;
args
[
2
]
=
"-config"
;
args
[
5
]
=
f
.
getAbsolutePath
();
args
[
3
]
=
"src/test/resources/testConfigWithStreaming.yml"
;
args
[
6
]
=
"-xmlReport"
;
args
[
4
]
=
"-pdfReport"
;
args
[
7
]
=
f2
.
getAbsolutePath
();
args
[
5
]
=
f
.
getAbsolutePath
();
args
[
8
]
=
"-out"
;
args
[
6
]
=
"-xmlReport"
;
args
[
9
]
=
f3
.
getAbsolutePath
();
args
[
7
]
=
f2
.
getAbsolutePath
();
CityDoctorValidation
.
main
(
args
);
args
[
8
]
=
"-out"
;
assertTrue
(
f
.
exists
());
args
[
9
]
=
f3
.
getAbsolutePath
();
assertTrue
(
f2
.
exists
());
CityDoctorValidation
.
main
(
args
);
assertTrue
(
f3
.
exists
());
assertTrue
(
f
.
exists
());
}
finally
{
assertTrue
(
f2
.
exists
());
f
.
delete
();
assertTrue
(
f3
.
exists
());
f2
.
delete
();
}
finally
{
f3
.
delete
();
f
.
delete
();
}
f2
.
delete
();
}
f3
.
delete
();
}
@Test
}
public
void
testReportCreation
()
throws
IOException
,
CityGmlParseException
,
InvalidGmlFileException
{
Path
tmpDir
=
null
;
@Test
try
{
public
void
testStreamingWithXMLValidation
()
throws
CityGmlParseException
,
IOException
,
InvalidGmlFileException
,
tmpDir
=
Files
.
createTempDirectory
(
"testTmp"
);
CityDoctorWriteException
,
CheckReportParseException
{
tmpDir
.
toFile
().
deleteOnExit
();
File
f2
=
folder
.
newFile
();
Path
xmlPath
=
tmpDir
.
resolve
(
"report.xml"
);
try
{
Path
pdfPath
=
tmpDir
.
resolve
(
"report.pdf"
);
String
[]
args
=
new
String
[
6
];
File
features
=
new
File
(
"src/test/resources/feature_types.gml"
);
args
[
0
]
=
"-in"
;
CityDoctorModel
model
=
CityGmlParser
.
nestedCityGmlFileParse
(
args
[
1
]
=
"src/test/resources/SimpleSolid_SrefBS_XMLInvalid.gml"
;
features
.
toString
(),
new
ParserConfiguration
(
8
,
false
));
args
[
2
]
=
"-config"
;
assertNotNull
(
model
);
args
[
3
]
=
"src/test/resources/testConfigWithStreamingWithValidation.yml"
;
Checker
checker
=
new
Checker
(
model
);
args
[
4
]
=
"-xmlReport"
;
checker
.
runChecks
();
args
[
5
]
=
f2
.
getAbsolutePath
();
checker
.
writeXmlReport
(
xmlPath
.
toString
());
CityDoctorValidation
.
main
(
args
);
checker
.
writePdfReport
(
pdfPath
.
toString
());
assertTrue
(
f2
.
exists
());
assertTrue
(
Files
.
exists
(
xmlPath
));
CheckReport
checkReport
=
CheckReport
.
load
(
f2
.
toPath
());
assertTrue
(
Files
.
exists
(
pdfPath
));
assertEquals
(
1
,
checkReport
.
getValidationResults
().
getGlobalErrors
().
size
());
try
{
}
finally
{
CheckReport
report
=
CheckReport
.
load
(
xmlPath
.
toString
());
f2
.
delete
();
assertNotNull
(
report
);
}
}
GlobalStatistics
globalStatistics
=
report
.
getGlobalStatistics
();
assertNotNull
(
globalStatistics
);
@Test
public
void
testReportCreation
()
throws
IOException
,
CityGmlParseException
,
InvalidGmlFileException
{
ModelStatistics
modelStats
=
globalStatistics
.
getModelStats
();
Path
tmpDir
=
null
;
assertNotNull
(
modelStats
);
try
{
assertEquals
(
1
,
modelStats
.
getNumBuildings
());
tmpDir
=
Files
.
createTempDirectory
(
"testTmp"
);
assertEquals
(
1
,
modelStats
.
getNumVegetation
());
tmpDir
.
toFile
().
deleteOnExit
();
assertEquals
(
1
,
modelStats
.
getNumTransportation
());
Path
xmlPath
=
tmpDir
.
resolve
(
"report.xml"
);
assertEquals
(
1
,
modelStats
.
getNumTunnelObjects
());
Path
pdfPath
=
tmpDir
.
resolve
(
"report.pdf"
);
assertEquals
(
1
,
modelStats
.
getNumBridgeObjects
());
File
features
=
new
File
(
"src/test/resources/feature_types.gml"
);
assertEquals
(
1
,
modelStats
.
getNumWaterObjects
());
CityDoctorModel
model
=
CityGmlParser
.
nestedCityGmlFileParse
(
features
.
toString
(),
assertEquals
(
1
,
modelStats
.
getNumLandObjects
());
new
ParserConfiguration
(
8
,
false
));
assertEquals
(
1
,
modelStats
.
getNumCityFurniture
());
assertNotNull
(
model
);
assertEquals
(
1
,
modelStats
.
getNumGenericCityObjects
());
Checker
checker
=
new
Checker
(
model
);
checker
.
runChecks
();
GlobalErrorStatistics
globError
=
globalStatistics
.
getGlobalErrorStats
();
checker
.
writeXmlReport
(
xmlPath
.
toString
());
assertNotNull
(
globError
);
checker
.
writePdfReport
(
pdfPath
.
toString
());
assertEquals
(
0
,
globError
.
getNumErrorBuildings
());
assertTrue
(
Files
.
exists
(
xmlPath
));
assertEquals
(
0
,
globError
.
getNumErrorVegetation
());
assertTrue
(
Files
.
exists
(
pdfPath
));
assertEquals
(
0
,
globError
.
getNumErrorTransportation
());
try
{
assertEquals
(
0
,
globError
.
getNumErrorTunnelObjects
());
CheckReport
report
=
CheckReport
.
load
(
xmlPath
.
toString
());
assertEquals
(
0
,
globError
.
getNumErrorBridgeObjects
());
assertNotNull
(
report
);
assertEquals
(
0
,
globError
.
getNumErrorWaterObjects
());
assertEquals
(
0
,
globError
.
getNumErrorLandObjects
());
GlobalStatistics
globalStatistics
=
report
.
getGlobalStatistics
();
assertEquals
(
1
,
globError
.
getNumErrorCityFurniture
());
assertNotNull
(
globalStatistics
);
assertEquals
(
1
,
globError
.
getNumErrorGenericCityObjects
());
ModelStatistics
modelStats
=
globalStatistics
.
getModelStats
();
assertNotNull
(
modelStats
);
}
catch
(
CheckReportParseException
e
)
{
assertEquals
(
1
,
modelStats
.
getNumBuildings
());
fail
(
"Report should be valid file"
);
assertEquals
(
1
,
modelStats
.
getNumVegetation
());
}
assertEquals
(
1
,
modelStats
.
getNumTransportation
());
assertEquals
(
1
,
modelStats
.
getNumTunnelObjects
());
assertEquals
(
1
,
modelStats
.
getNumBridgeObjects
());
}
finally
{
assertEquals
(
1
,
modelStats
.
getNumWaterObjects
());
if
(
tmpDir
!=
null
)
{
assertEquals
(
1
,
modelStats
.
getNumLandObjects
());
FileUtils
.
deleteDirectory
(
tmpDir
.
toFile
());
assertEquals
(
1
,
modelStats
.
getNumCityFurniture
());
}
assertEquals
(
1
,
modelStats
.
getNumGenericCityObjects
());
}
}
GlobalErrorStatistics
globError
=
globalStatistics
.
getGlobalErrorStats
();
assertNotNull
(
globError
);
assertEquals
(
0
,
globError
.
getNumErrorBuildings
());
assertEquals
(
0
,
globError
.
getNumErrorVegetation
());
assertEquals
(
0
,
globError
.
getNumErrorTransportation
());
assertEquals
(
0
,
globError
.
getNumErrorTunnelObjects
());
assertEquals
(
0
,
globError
.
getNumErrorBridgeObjects
());
assertEquals
(
0
,
globError
.
getNumErrorWaterObjects
());
assertEquals
(
0
,
globError
.
getNumErrorLandObjects
());
assertEquals
(
1
,
globError
.
getNumErrorCityFurniture
());
assertEquals
(
1
,
globError
.
getNumErrorGenericCityObjects
());
}
catch
(
CheckReportParseException
e
)
{
fail
(
"Report should be valid file"
);
}
}
finally
{
if
(
tmpDir
!=
null
)
{
FileUtils
.
deleteDirectory
(
tmpDir
.
toFile
());
}
}
}
}
}
CityDoctorParent/CityDoctorValidation/src/test/resources/SimpleSolid_SrefBS_XMLInvalid.gml
0 → 100644
View file @
1fbe16e1
<?xml version="1.0" encoding="utf-8"?>
<core:CityModel
xmlns:core=
"http://www.opengis.net/citygml/2.0"
xmlns:gen=
"http://www.opengis.net/citygml/generics/2.0"
xmlns:bldg=
"http://www.opengis.net/citygml/building/2.0"
xmlns:app=
"http://www.opengis.net/citygml/appearance/2.0"
xmlns:dem=
"http://www.opengis.net/citygml/relief/2.0"
xmlns:gml=
"http://www.opengis.net/gml"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/2.0 http://schemas.opengis.net/citygml/2.0/cityGMLBase.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd"
>
<!--
Einfaches Gebäude mit Grundriss 3m x 5m und Satteldach, Traufhöhe 3m, Firsthöhe 4,5m
Modelliert mit Begrenzungsflächen (eine Dachfläche, 4 Wandflächen, 1 Grundfläche),
die Gebäudegeometrie als Solid, der auf die Polygone der Begrenzungsflächen referenziert.
Fehler in der Reihenfolge der Attribute.
CityGML 2.0
Gebäudevolumen: 56,25 m3
12.12.2025
Author: V. Coors, HFT Stuttgart
Lizenz:
-->
<core:cityObjectMember>
<bldg:Building
gml:id=
"_Simple_BD.1"
>
<gen:stringAttribute
name=
"averageStoreyHeight"
>
<gen:value>
2.5
</gen:value>
</gen:stringAttribute>
<gml:name>
falsche Reihenfolge
</gml:name>
<bldg:lod2Solid>
<gml:Solid>
<gml:exterior>
<gml:CompositeSurface>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.1"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.2"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.3"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.4"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.5"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.6"
/>
<gml:surfaceMember
xlink:href=
"#_Simple_BD.1_PG.7"
/>
</gml:CompositeSurface>
</gml:exterior>
</gml:Solid>
</bldg:lod2Solid>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.2"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.2_LR.1"
>
<gml:posList
srsDimension=
"3"
>
13.0 15.0 0.0
13.0 15.0 3.0
13.0 10.0 3.0
13.0 10.0 0.0
13.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_2"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.3"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.3_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 15.0 0.0
10.0 15.0 3.0
11.5 15.0 4.5
13.0 15.0 3.0
13.0 15.0 0.0
10.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_3"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.4"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.4_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 3.0
10.0 15.0 3.0
10.0 15.0 0.0
10.0 10.0 0.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface
gml:id=
"_Simple_BD.1_WallSurface_4"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.5"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.5_LR.1"
>
<gml:posList
srsDimension=
"3"
>
13.0 10.0 0.0
13.0 10.0 3.0
11.5 10.0 4.5
10.0 10.0 3.0
10.0 10.0 0.0
13.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:RoofSurface
gml:id=
"_Simple_BD.1_RoofSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.6"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.6_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 3.0
11.5 10.0 4.5
11.5 15.0 4.5
10.0 15.0 3.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.7"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.7_LR.1"
>
<gml:posList
srsDimension=
"3"
>
11.5 10.0 4.5
13.0 10.0 3.0
13.0 15.0 3.0
11.5 15.0 4.5
11.5 10.0 4.5
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:RoofSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:GroundSurface
gml:id=
"_Simple_BD.1_GroundSurface_1"
>
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon
gml:id=
"_Simple_BD.1_PG.1"
>
<gml:exterior>
<gml:LinearRing
gml:id=
"_Simple_BD.1_PG.1_LR.1"
>
<gml:posList
srsDimension=
"3"
>
10.0 10.0 0.0
10.0 15.0 0.0
13.0 15.0 0.0
13.0 10.0 0.0
10.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:GroundSurface>
</bldg:boundedBy>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithStreamingWithValidation.yml
0 → 100644
View file @
1fbe16e1
globalParameters
:
numberOfRoundingPlaces
:
8
schematronFilePath
:
src/test/resources/schematronTest.xml
useStreaming
:
true
requirements
:
R_GE_R_TOO_FEW_POINTS
:
enabled
:
true
R_GE_R_NOT_CLOSED
:
enabled
:
true
R_GE_R_CONSECUTIVE_POINTS_SAME
:
enabled
:
true
R_GE_R_SELF_INTERSECTION
:
enabled
:
true
R_GE_S_MULTIPLE_CONNECTED_COMPONENTS
:
enabled
:
true
R_GE_P_INTERIOR_DISCONNECTED
:
enabled
:
true
R_GE_P_INTERSECTING_RINGS
:
enabled
:
true
R_GE_P_NON_PLANAR
:
enabled
:
false
parameters
:
# one of ("distance", "angle", "both")
type
:
distance
distanceTolerance
:
0.01
angleTolerance
:
0.1
R_GE_P_HOLE_OUTSIDE
:
enabled
:
true
R_GE_P_ORIENTATION_RINGS_SAME
:
enabled
:
true
R_GE_P_INNER_RINGS_NESTED
:
enabled
:
true
R_GE_S_TOO_FEW_POLYGONS
:
enabled
:
true
R_GE_S_NOT_CLOSED
:
enabled
:
true
R_GE_S_NON_MANIFOLD_EDGE
:
enabled
:
true
R_GE_S_POLYGON_WRONG_ORIENTATION
:
enabled
:
true
R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION
:
enabled
:
true
R_GE_S_NON_MANIFOLD_VERTEX
:
enabled
:
true
R_GE_S_SELF_INTERSECTION
:
enabled
:
true
\ No newline at end of file
CityDoctorParent/Extensions/CityDoctorHealer/src/main/java/de/hft/stuttgart/citydoctor2/healer/Healer.java
View file @
1fbe16e1
...
@@ -289,7 +289,7 @@ public class Healer {
...
@@ -289,7 +289,7 @@ public class Healer {
private
byte
[]
writeCityGml
(
AbstractCityObject
aco
)
throws
CityGMLWriteException
{
private
byte
[]
writeCityGml
(
AbstractCityObject
aco
)
throws
CityGMLWriteException
{
CityModel
model
=
new
CityModel
();
CityModel
model
=
new
CityModel
();
model
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
model
.
getCityObjectMembers
().
add
(
new
AbstractCityObjectProperty
(
aco
));
CityGMLContext
context
=
CityGmlParser
.
g
etContext
();
CityGMLContext
context
=
CityGmlParser
.
s
et
up
Context
();
CityGMLOutputFactory
outputFactory
=
context
.
createCityGMLOutputFactory
(
CityGMLVersion
.
v2_0
);
CityGMLOutputFactory
outputFactory
=
context
.
createCityGMLOutputFactory
(
CityGMLVersion
.
v2_0
);
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
try
(
CityGMLWriter
writer
=
outputFactory
.
createCityGMLWriter
(
out
))
{
try
(
CityGMLWriter
writer
=
outputFactory
.
createCityGMLWriter
(
out
))
{
...
...
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